Hacker News new | ask | show | jobs
by YeGoblynQueenne 33 days ago
Well, with respect to Markus Triska, I don't like purity. Prolog gives you plenty of "impure" constructs like the cut (!/0) and the assert/retract family of database manipulation predicates. It also gives you impure I/O and arithmetic functions that are quite separate from the otherwise logical, declarative-ish style of the language.

I'm fine with all that. The language gives you sensible tools to deal with edge cases that otherwise require you to jump through hoops or import libraries (like the constraint arithmetic libraries that Markus recommends... and that he had to mostly write himself before he could recommend). You can get into a spot of bother if you use those facilities without knowing why they are there and why you shouldn't just spam them in every case, but that's why good textbooks exist.

And more to the point, that's why Prolog Coding Guidelines are a thing, more precisely, a paper, which you can find here from the website of Michael Covington who's one of its (many) authors:

https://www.covingtoninnovations.com/mc/plcoding.pdf

Here's what the Guidelines has to say about assert/retract:

5.10 Avoid asserta/assertz and retract unless you actually need to preserve information through backtracking Although it depends on your compiler, asserta/assertz and retract are usually very slow. Their purpose is to store information that must survive backtracking. If you are merely passing intermediate results from one step of computation to the next, use arguments.

If you have a dynamic predicate, write interface predicates for changing it instead of using “bare” calls to asserta/assertz and retract, so that your interface predicates can check that the changes are logically correct, maintain mutexes for multiple threads, and so forth.

Sound advice. In fact that's what I've always done myself even before reading the Guidelines.

And here's some advice on using the "horror" of the cut without having to wake the Great Old Ones:

5.4 Use cuts sparingly but precisely First think through how to do the computation without a cut; then add cuts to save work. For further guidance see O’Keefe (1990, pp. 88–101). Concerning code layout, make sure cuts do not go unnoticed: if a green cut7 may be placed on the same line as the previous predicate call, red cuts definitely must be on their own line of code.

5.5 Never add a cut to correct an unknown problem A common type of Prolog programing error is manifested in a predicate that yields the right result on the first try but goes wrong upon backtracking. Rather than add a cut to eliminate the backtracking, investigate what went wrong with the logic. There is a real risk that if the problem is cured by adding the cut, the cut will be far away from the actual error (even in a different predicate), which will remain present to cause other problems later

Basically the message should be that we can help the novice to navigate the complexities of the language without underestimating or pataronising them. Cuts, asserts, and the lot, are just there to make things easier. They only make things harder when they're not explained properly. And telling everyone to just stay away from them is, I think, not the proper way to explain anything.

1 comments

I kind of agree with both of you. I would have become better at Prolog faster if I had stuck to the discipline Triska promotes early on, but I also think the guidelines you cite are reasonable once one is starting to do somewhat productive work where compromises and speed factors in.

Over the years I've come to a similar position in other languages as well. If a functional-ish solution fits performance constraints and is maintainable, don't mutate or reach for global state, things like that.