4 ms·
This is very nice! For reasoning about tree-based data such as HTML, I also highly recommend the declarative programming language Prolog. HTML documents map na
by triska 5y ago
This is very nice!
For reasoning about tree-based data such as HTML, I also highly recommend the declarative programming language Prolog. HTML documents map naturally to Prolog terms and can be readily reasoned about with built-in language mechanisms. For instance, here is the sample query from the htmlq README, fetching all elements with id get-help from https://www.rust-lang.org https://www.rust-lang.org, using Scryer Prolog and its SGML and HTTP libraries in combination with the XPath-inspired query language from library(xpath):
?- http_open("https://www.rust-lang.org", Stream, []),
load_html(stream(Stream), DOM, []),
xpath(DOM, //(*(@id="get-help")), E).
Yielding:
E = element(div,[class="flex flex-colum ...",id="get-help"],["\n ",element(h4,[],["Get help!"]),"\n ",element(ul,[],["\n ...",element(li,[],[element(a,[... = ...],[...])]),"\n ...",element(li,[],[...]),...|...]),"\n ...",element(div,[class="la ..."],["\n ...",element(label,[...],[...]),...|...]),"\n ..."])
; false.
The selector //(*(@id="get-help")) is used to obtain all HTML elements whose id attribute is get-help. On backtracking, all solutions are reported.
The other example from the README, extracting all links from the page, can be obtained with Scryer Prolog like this:
?- http_open("https://www.rust-lang.org", Stream, []),
load_html(stream(Stream), DOM, []),
xpath(DOM, //a(@href), Link),
portray_clause(Link),
false.
This query uses forced backtracking to write all links on standard output, yielding:
"/".
"/tools/install".
"/learn".
"https://play.rust-lang.org/".
"/tools".
"/governance".
"/community".
"https://blog.rust-lang.org/".
"/learn/get-started".
etc.
- chriswarbo 5y agoThanks, that's a rare example of something which is (a) simple enough to understand for a Prolog-newbie like me, and (b) more practical than ubiquitous family-tree example. I'm always looking for opportunities to dip my toes into Prolog; in hindsight it's clearly a good fit for tree-structured data structures.
- samhw 5y agoInterestingly, the only other context in which I've come across Prolog is from friends who studied at Cambridge, here in the UK. For some reason, the CS 'tripos' (course) there is really heavily focussed on Prolog, and everyone I know from there ended up a huge fan of the language. I'm not sure why that's the case, though, given that almost all other universities seem to use more common languages (Java, C++, etc).
- WickyNilliams 5y agoI studied CS at a different university in UK and we used Prolog for one module on AI or perhaps machine vision. I really enjoyed working with it. This was 15 years ago. Looking through their current curriculum I can't see prolog being mentioned anymore. Shame!
- zimpenfish 5y agocs.man.ac.uk, at least back in 1992, had a compulsory Prolog module in the first year. Don't know anyone from then who didn't hate that module with a burning passion. (There was no Java, C++, etc. either. It was SML, Pascal, 68000, and Oracle Pascal-Embedded-SQL.)
- ramses0 5y ago"Prolog as a library" => Given "functional" constraints => $CONSTRAINTS.prolog( "query..." ) => results ...many languages (similar to regex / state-machine) can benefit greatly from offloading a portion to something prolog-ish, but it's unfortunate that prolog knowledge isn't as widely distributed.
- okasaki 5y agoIt's pretty easy in Python too, eg.: >>> soup = BeautifulSoup(requests.get("https://www.rust-lang.org").text) >>> [x["href"] for x in soup.find_all("a")] ['/', '/tools/install', '/learn', 'https://play.rust-lang.org/', '/tools', '/governance', '/community', 'https://blog.rust-lang.org/',...
- triska 5y agoIn a certain sense (for example, when measuring brevity), it is indeed easy to write this example in Python. However, the Python version also illustrates that many different language constructs are needed to express the intended functionality. In comparison to Prolog, Python is a quite complex language with many different language constructs, including loops, objects, methods, assignment, dictionaries etc. all of which are used in this example. As I see it, a key attraction of Prolog is its simplicity: With a single language construct (Horn clauses), you are able to express all known computations, and the example queries I posted show that only a single language element, namely again Horn clauses to express a query, is needed to run the code. The Prolog query, and also every Prolog clause, is itself a Prolog term and can be inspected with built-in mechanisms. As a consequence, an immediate benefit of using Prolog for such use cases is that you can easily reason about user-specified queries in your applications, and for example easily allow only a safe subset of code to be run by users, or execute a user-specified query with different execution strategies etc. In comparison, Python code is much harder to analyze and restrict to a particular subset due to the language's comparatively high syntactic complexity.
- the_jeremy 5y agoThe benefit of Python is that developers already know about these language constructs, and that more developers know Python than Prolog.
- lostcolony 5y agoI don't think the op's point was "how easy it would be to hire developers", or even "taking all the considerations a business is under, I feel Prolog makes sense". He was just touting how easy Prolog's built in pattern matching and declarative style makes implementing and using selectors at a language level. Honestly, if we didn't talk about the benefits of a language irrespective of how easy it is to hire for it, we'd never have introduced anything beyond FORTRAN, if we even made it that far. Bringing "X is easier to hire for" into a conversation about the language is, at best, a non-sequitur.
- jfmc 5y agoAFAIK, this was first proposed and implemented in Ciao Prolog back in late 90s (modern versions here: https://ciao-lang.org/ciao/build/doc/ciao.html/html.html https://ciao-lang.org/ciao/build/doc/ciao.html/html.html). It was way before Python was popular and JavaScript ever existed.
- pandatigox 5y agoI tried to run this on my computer now, but as a complete Prolog noob, I'm having errors running the script? How do you load the http_open module/library in the first place? I tried following some Prolog tutorials in the past but I always get stuck trying to run something in the REPL. I'm using scryer-prolog. Thanks in advance!
- triska 5y agoThe libraries I mentioned can be loaded by invoking the use_module/1 predicate on the toplevel, here is the complete transcript that loads the SGML, HTTP and XPath libraries in Scryer Prolog: ?- use_module(library(sgml)). true. ?- use_module(library(http/http_open)). true. ?- use_module(library(xpath)). true. The second query also uses portray_clause/1 from library(format), which you can load with: ?- use_module(library(format)). true. After all these libraries are loaded, you can post the sample queries from above, and it should work. There are also other ways to load these libraries: A very common way to load a library is to use the use_module/1 directive in Prolog source files. In that case, you would put for example the following 4 directives in a Prolog source file, say sample.pl: :- use_module(library(sgml)). :- use_module(library(http/http_open)). :- use_module(library(xpath)). :- use_module(library(format)). And then run sample.pl with: $ scryer-prolog sample.pl You can then again post the goals from above on the toplevel, and it will work too. Another way is to put these directives in your ~/.scryerrc configuration file, which is automatically consulted when Scryer Prolog starts. I recommend to do this for libraries you frequently need. Common candidates for this are for example library(dcgs), library(lists) and library(reif). Personally, I start Scryer Prolog from within Emacs, and I have set up Emacs so that I can consult a buffer with Prolog code, and also post queries and interact with the Prolog toplevel from within Emacs.
- pandatigox 5y agoWow that works fantastically! Thank you for that. It almost seems like magic.