Prolog: "Mistakes were made"
As an avid Prolog fan, I would have to agree with a lot of Mr. Wayne's comments! There are some things about the language that are now part of the ISO standard that are a bit unergonomic.
On the other hand, you don't have to write Prolog like that! The only shame is that there are 10x more examples (at least) of bad Prolog on the internet than good Prolog.
If you want to see some really beautiful stuff, check out Power of Prolog[1] (which Mr. Wayne courteously links to in his article!)
If you are really wondering why Prolog, the thing about it that makes it special among all languages is metainterpretation. No, seriously, would strongly recommend you check it out[2]
This is all that it takes to write a metainterpreter in Prolog:
mi1(true).
mi1((A,B)) :-
mi1(A),
mi1(B).
mi1(Goal) :-
Goal \= true,
Goal \= (_,_),
clause(Goal, Body),
mi1(Body).
Writing your own Prolog-like language in Prolog is nearly as fundamental as for-loops in other language.[1] https://www.youtube.com/@ThePowerOfProlog
https://www.metalevel.at/prolog
I have to admit that writing Prolog sometimes makes me want to bash my my head against the wall, but sometimes the resulting code has a particular kind of beauty that's hard to explain. Anyways, Opus 4.5 is really good at Prolog, so my head feels much better now :-)
Anything you'd like to share? I did some research within the realm of classic robotic-like planning ([1]) and the results were impressive with local LLMs already a year ago, to the point that obtaining textual descriptions for complex enough problems became the bottleneck, suggesting that prompting is of limited use when you could describe the problem in Prolog concisely and directly already, given Prolog's NLP roots and one-to-one mapping of simple English sentences. Hence that report isn't updated to GLM 4.7, Claude whatever, or other "frontier" models yet.
I think much of the frustration with older tech like this comes from the fact that these things were mostly written(and rewritten till perfection) on paper first and only the near-end program was input into a computer with a keyboard.
Modern ways of carving out a program with 'Successive Approximations' with a keyboard and monitor until you get to something to work is mostly a recent phenomenon. Most of us are used to working like this. Which quite honestly is mostly trial and error. The frustration is understandable because you are basically throwing darts, most of the times in the dark.
I knew a programmer from the 1980s who(built medical electronics equipment) would tell me how even writing C worked back then. It was mostly writing a lot, on paper. You had to prove things on paper first.
I very much agree with this, especially since Prolog's execution model doesn't seem to go that well with the "successive approximations" method.
https://github.com/Seeker04/plwm
It actually has quite good UX affordances. More than that, however, I find the code imminently hackable, even as someone with very little Prolog experience. Reading through the plwm code really demystified the apparent gap between toy and practical Prolog for me. Heck, even the SWI-Prolog codbase itself is quite approachable!
I'm also mildly surprised at some of OG's gripes. A while back, I ran through Triska's The Power of Prolog[0], which crisply grounds Prolog's mental model and introduces standard conventions. In particular, it covers desugaring syntax into normal predicates, e.g. -/2 as pairs, [,]/2 as special syntax for ./2 cons cells, etc. Apparently, I just serendipitously stumbled into good pedagogical resources!
I'd be interested in ways that people utilize logical programming concepts and techniques into non-LP languages.
Prolog is also unusual in a sense that it is essential to understand what the interpreter does with your code in order to be able to write it well. For vanilla Prolog, that's not so hard. However, when constraint programming and other extensions are added, that becomes much harder to do.
There were only two prevalent attitudes, some of us really loved FP (me included), others hated it and could hardly wait to get it done.
Somehow there was a similar overlap with those of us that enjoyed going out of mainstream languages, and those that rather stay with Pascal and C.
My understanding is that they have very different evaluation strategies, bottom up vs top down. But with laziness and pruning you can still achieve the same goals in datalog with more ergonomics, right?
I think every language should have a prolog or datalog implementation, kind of like regex.
> Prolog is also unusual in a sense that it is essential to understand what the interpreter does with your code in order to be able to write it well.
100% this!
Coming from procedural/OO paradigms i did not understand how to think about Prolog until i read Robert Kowalski's paper Predicate Logic as a Programming Language - https://www.researchgate.net/publication/221330242_Predicate...
I still have a long way to go but at least i am on the right track.
> ISO "strings" are just atoms or lists of single-character atoms (or lists of integer character codes) [...]. Code written with strings in SWI-Prolog will not work in [other] Prolog.
That's because SWI isn't following ISO (and even moving away from ISO in other places eg. [1]).
ISO Prolog strings are lists of character codes period. It's just that there are convenient string manipulation-like predicates operating on atom names such as sub_atom, atom_concat, atom_length, etc ([2]). You'd use atom_codes to converse between atoms/strings or use appropriate list predicates.
[1]: https://www.reddit.com/r/prolog/comments/1089peh/can_someone...
[2]: https://quantumprolog.sgml.net/docs/libreference.html#string...
... we've disagreed about this before though :)
To me, it feels like a data description language that someone discovered could be tricked into performing computation.
Just kidding. Some of those are stylistic choices I don't have gripes but can understand the criticism. There is however one thing about "Non-cuts are confusing" I'd like to clarify:
In this example:
foo(A, B) :-
\+ (A = B),
A = 1,
B = 2.
It's very obvious why it fails and it has nothing to do with non-cut. Let's say A can be apple and B can be orange and now you're asking Prolog to compare apples to oranges! ;)In short one has to "hint" Prolog what A and B can be so then it can "figure out" whethever comparison can be made and what is its result. Assuming there exist is_number(X) clause that can instantiate X as a number following would work just fine:
foo(A, B) :-
is_number(A),
is_number(B),
\+ (A = B),
A = 1,
B = 2.
(note that this would be stupid and very slow clause. Instantiation in such clauses like is_number(X) usually starts with some defined bounds. For A = 10000, B = 10001 and lower bound of 1 pessimistic case this clause would require 100M checks!But, really, that's just not good style. It's bound to fail at some point. It's supposed to be a simple example, but it ends up not being simple at all because the author is confused about what's it supposed to behave like.
And once you've settled on one of these, which learning resource should one go with?
Then checkout the books recommended by user "YeGoblynQueenne" who knows this domain pretty well.
Scryer is a good start because it's ISO. Datalog is kind of a subset, MiniKanren is somewhat related but not Prolog, and Picat is kind of Prolog with an imperative language within it.
Although these days I'd recommend anyone interested in Prolog starts in at the deep end with "Foundations of Logic Programming" by George W. Lloyd, because I've learned the hard way that teaching Prolog as a mere programming language, without explaining the whole logic programming thing, fails.
| ?- findall(A, (tree(A, N), branch(N)), As).
As = [n,n1]
yes
See https://lpn.swi-prolog.org/lpnpage.php?pagetype=html&pageid=...