Prolog Coding Horror

· coding · Source ↗

TLDR

  • 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.

Original | Discuss on HN