3 ms·
>I'm perplexed by your comment. Prolog is not a functional language. It's a logic programming language. It's my impression from its use of recursion for execut
by knome 4y ago
>I'm perplexed by your comment. Prolog is not a functional language. It's a logic programming language.
It's my impression from its use of recursion for execution flow alongside its assign-once variables, which feel a lot like haskell's lazy evaluation.
- knome 4y agoWanting to see what you saw wrong with my impression of prolog, I spent some time digging into the language. It does have an "if then else"-like statement via (->) and (;) `repeat/0` is incredibly gross looking. The examples use it like 'yield' to unify a name and let the rest of the clauses run. It appears to it creates infinite choice-points that must eventually be manually escaped from with a cut (!)? https://www.swi-prolog.org/pldoc/doc_for?object=repeat/0 https://www.swi-prolog.org/pldoc/doc_for?object=repeat/0
- YeGoblynQueenne 4y agoWhy is repeat/0 gross? It implements a failure-driven loop. If you want to force your code to backtrack over all choice points, that's what you need to do. You can't get the same result with recursion. For instance if you have a nondeterministic predicate (definition) and want to loop over all its results, if you try to do that with recursion you'll just generate the same result at every step of the recursion. Instead you want to iterate over all the choice points. To demonstrate its behaviour you can try that on the SWI-Prolog command line: ?- repeat, between(1,3,I). I = 1 ; I = 2 ; I = 3 ; I = 1 ; I = 2 ; I = 3 ; I = 1 . The ";" are where I ask for more results, the "." is where I said "stop". If you tried to recurse around between(1,3,I), you'd get I bound to "1" every step through the recursion- and still leave two choice points behind for every "1". It's been a while since I used repeat/0, but in general it's used to write generators. It usually makes more sense to use findall/3 and friends, which simply iterate over choice points without adding new ones. For example: ?- findall(I, between(1,3,I), Is). Is = [1, 2, 3]. People complain about dirty imperative constructs in Prolog like that all the time, but they are very useful to a pragmatic programmer and everytime anyone tries to "fix" Prolog by removing the impurities, they break it.
- deleted 4y ago[deleted]
- YeGoblynQueenne 4y agoI don't know Haskell but if I understand correctly it uses the Hindley-Milner type system, which itself uses unification as a type-checker? If so, maybe that's the similarity you see? As far as I understand a functional programming language is one where functions are first-class citizens and hopefully the lambada calculus is the top-level abstraction. That's not the case with Prolog, which doesn't even have functions but (like dreamcompiler says) relations which are generalisations of functions, that don't "evaluate" to anything but "relate" objects. I think you're trying to understand Prolog using the abstractions you already know which is, I guess, the way of science. But you have to be careful about applying the wrong abstractions. For example, a language can't be "functional" if it doesn't even have functions. In Prolog everything is a definite clause, and clauses are first-order logic formulae, not functions. The wikipedia article on definite clauses is I think clear and to the point: https://en.wikipedia.org/wiki/Horn_clause https://en.wikipedia.org/wiki/Horn_clause Actually that's the article on Horn clauses, of which definite clauses are a subset, but that's useful to understand, also. For me, a lot of confusion was cleared up when I found a good explanation of what is a definite clause.