by sirwhinesalot | 2025-06-17 09:00:10+00:00
Sure, I like to think of the more philosophical aspects but I understand they're not something people necessarily care about. If you prefer just the practical side of things then that's a lot easier to explain: I didn't like working with Prolog.

So what follows is purely anecdotal of course, but it can't be anything else really. At my university we were exposed to all the 4 major paradigms: Procedural (C), OOP (Java), Functional (Haskell), Logic (Prolog).

When I first got exposed to Prolog, I was amazed. "Wow, you can just write the rules and it figures out the solution!". That didn't last long. It was slow and clunky, I had to be careful how I wrote the rules, and debugging was an exercise in frustration. Sometimes it ran forever, sometimes it gave repeated answers, sometimes it gave all the right answers and then ran forever.

Cuts were introduced as the solution to the performance issues, and to me they were witchcraft more than they were engineering. Something you threw around at random in the hopes of making it work. I tried to go all in with it, make the whole class project as much as possible in Prolog (it was a Java/Prolog mix).

My professor actually ended up giving me a bad grade because that's not how he wanted Prolog to have been used. He actually wanted us to use it more like one might use Datalog (with good reason, but Datalog was never explicitly mentioned).

At the time I didn't get it, the whole paradigm just felt like a complete joke to me. Something researchers liked to play with but unfit for any real work. That was also the perception of the vast majority of my colleagues.

Same was true of functional programming by the way, though to a lesser extent. I (and others) could definitely see the benefits of referential transparency, higher order functions and lazy evaluation. But I'd just apply them in whatever language I was already using. Same as how if I wanted to do search, I'd just write a depth first search algorithm myself, no reason to bother with Prolog.

All examples were either trivial nonsense, ridiculous contortions of the paradigm (a window manager? really?), or "irrelevant" research (research about Prolog using Prolog to do more Prolog).

But the problem is that my perception of Prolog extended to my perception of logic programming in general. I saw them as one and the same. The "best" and "most famous" logic programming language is jank, so the whole paradigm must be jank.

Only after I was later exposed to SMT solvers did it finally "click" that different programming paradigms can be truly transformative. That they can provide truly massive productivity boosts. Z3 added a Datalog mode at some point, which was when I realized my perception of the logic paradigm was clouded.

From Z3 Datalog I moved on to Souffle Datalog and Datomic (that syntax though, ugh), where I got to experience how poor SQL truly is. I already knew it was a poor showing of the relational paradigm, but I didn't realize the relational paradigm itself was so much weaker than the real deal: logic programming.

So that convinced me logic programming had value. Real, undeniable, practical value, not "parlor tricks". But that was still "the non-Turing-complete fragment of logic programming is useful", not "logic programming is useful". Because full logic programming still meant "Prolog" to me, the slow, janky language I used in university.

But then I got to experience Mercury and Curry. Full, Turing-complete logic programming languages with massively better performance than Prolog, that don't need cuts to perform well. Mercury has its determinism modes which make debugging the behavior of rules so much easier (much as how static typing in general makes everything easier to debug).

Curry's "needed narrowing" semantics also means if there is a solution, it will find it. This is true even though Curry is also a Turing-complete logic programming language. Prolog can get stuck in a branch of the search tree that cannot lead to a solution.

Mercury and Curry are both strong evidence to me that "every time anyone has tried to fix Prolog's not-fully-100%-declarativeness, they've just broken it." is not really accurate.

Can you give me a serious example that would not be expressible in either? Another commenter mentioned meta-interpreters but while they're incredibly cool, I'd still classify them more as a great research tool than a practical one. How often do you need one?