Guide to avoiding common Prolog antipatterns: cut (!/0), global state via assertz/retract, impure output, and low-level arithmetic predicates.
Key Takeaways
Using !/0, (->)/2, or var/1 causes lost solutions; the fix is dif/2, if_/3, and clean data structures.
assertz/1/retract/1 introduce implicit global state; thread state through predicate arguments or semicontext notation instead.
Printing inside solve predicates breaks relational reuse and testability; let the toplevel handle output.
Low-level arithmetic (is/2, =:=/2, >/2) should be replaced with CLP(FD) constraints (#=, #>) for generality.
The n_factorial example shows that removing !/0 and using CLP(FD) lets the most general query enumerate all solutions.
Hacker News Comment Review
Commenters largely treat Prolog as an academic curiosity, with real-world use cases narrowed to constraint satisfaction, test scenario generation, and policy engines like OPA/Datalog.
The Erlang-Prolog lineage sparked discussion: Erlang’s multi-clause functions mirror Prolog’s database predicates but discard backtracking and relational generality.
The framing that “wrong answers are recoverable, missing solutions are not” resonated with commenters drawing parallels to forecasting and NP verification problems.
Notable Comments
@xlii: Describes using Prolog to generate valid/invalid action-sequence test scenarios for an application, a concrete production-adjacent use case.
@mmastrac: Points to the four-port model as the essential mental model for understanding Prolog execution and solution-space navigation.