The message by Dan earlier today pushed me down a line of thinking I have visited many times before; this time I got further than ever. Please bear with me.
Hypothesis: the cut (!) was a hack that was so successful that it locked Prolog programmers into a local optimum. It is worth trying to find a Prolog subset or extension that doesn’t need cuts, ever (or at least 99.5% of the time).
Background: Things are better without cuts, everyone agrees, but we keep on using them. They are confusing. “Learn Prolog Now!” decided that the exclamation mark in the title is all they can afford, and do not discuss cuts at all. Both “The Art of Prolog” and “The Craft of Prolog” use a lot of emphasis when trying to explain what the cut does. Well-meaning people on Stackoverflow go into all kinds of acrobatics to avoid the cut or at least hide it very well. There is too much code floating around the internet where cuts lower the perceived subjective quality of the program. Finally, I suspect that once a programmer gets used to using cuts (and understands them well enough) they don’t have the motivation to find a better solution.
NB: by “a better solution” I mean something that is at least as readable, succinct, and efficient as the same code with the explicit cuts.
State-of-the-art: Depending on the situation, we already have a multitude of tools and techniques. In arbitrary order, certainly incomplete, and not properly classified:
- once/1
- the conditional ->/2 and the soft cut *->/2
- in some cases, coroutining as in dif/2
- (better and consistently improving) clause indexing
- in some cases, constraint logic programming
- using “non-defaulty” representation
- …
Question: If I were to systematically evaluate a large enough code base (Prolog’s standard library?) and classify the uses of cuts inside of it; could that serve as a starting point for figuring out whether a cut-free (99.5%-cut-free, that is) Prolog is possible or desirable?
Any comments are welcome. I am a bit ashamed of starting such a hollow topic, but I guess you can ignore me and no further harm is done
PS: One of the last places where I personally need a cut is when defining a predicate that need to check its arguments then cut, or continue with the next clause. Sometimes a cut is cleaner than if-then, for example (:<)/2. I did not fully understand yet the “Picat style matching” suggestion; does that apply in such cases?