3 ms·
> Prolog-derived languages go even more nuts with ; and . than C-style terminators. What do you mean by this? In Prolog, (;)/2 is simply a binary infix operato
by zmonx 9y ago
> Prolog-derived languages go even more nuts with ; and . than C-style terminators.
What do you mean by this? In Prolog, (;)/2 is simply a binary infix operator, so that you can write a term of the form:
;(A, B)
i.e, a binary term whose primary functor is a semicolon, equivalently as:
( A ; B )
where the semicolon now occurs as infix operator instead of at its canonical position at the beginning of the term.
In Prolog, you can always use the predicate write_canonical/1 to obtain the canonical representation of any term, which is completely regular. In the case above, we get:
?- write_canonical( (a ; b) ).
;(a,b)
This confirms that (a;b) and ;(a,b) denote the exact same Prolog term which cannot be distinguished at the AST level.
We have also several other ways to inspect the term, such as functor/3:
?- functor((a;b), Functor, Arity).
Functor = (;),
Arity = 2.
As expected, this again confirms that the primary functor is the semicolon in this case.
Further, the period '.' has a dual role as the primary functor for non-empty lists, and also to mark the end of a term.
For example, in a Prolog fact of the form:
hello(world).
The period states that the term is complete. If it were not used, the term could have continued for example like this:
hello(world) + universe.
In that case, (+)/2 is the primary functor, as can be verified with:
?- write_canonical(hello(world) + universe).
+(hello(world),universe)
Thus, '.' is used to mark the end of clauses, since each clause is a valid Prolog term.
If you want, you can always use the canonical representation of Prolog terms in your code. However, this would make writing and reading Prolog at least as inconvenient as Lisp, because you then have to write everything in prefix notation instead of being able to benefit from infix operators too.
For example, using prefix syntax, you would define a Prolog rule as:
:-(Head, Body).
whereas with infix syntax, you can write the exact same term equivalently as:
Head :- Body.
Similarly, you would have to write:
#=(X,+(5,3))
instead of using the typical infix notation for arithmetic predicates and expressions:
X #= 5+3
Note that since the respective abstract syntax trees are completely the same, Prolog remains at least as amenable to metaprogramming as Lisp even though Prolog supports more flexible syntax!
- white-flame 9y agoYes, I do like the fact that Prolog infix operators are just optional sugar for standard prefix definitions. In talking against separators, in "Prolog-derived" languages like Erlang (and other custom derivations I've dealt with), separators are used even between clauses. Most other languages use separators just for fields, and use straight terminators for statements. Prolog itself gets a pass because these separators are literally ANDs and ORs which flow as logical expressions through the backtracking search. Even toplevel expressions defining different match parameters for the same head require differentiating separators from a final terminator for that head in Erlang, whereas Prolog just deals with independently terminated head matches just fine. The Erlang code is much more removed from a logical AND/OR flow into more standard programming models, yet is still separator-based. Instead of thinking of the logical, partial evaluation possibilities of x AND y AND z it's a more traditional statement 1, statement 2, statement 3. with inconsistent characters at the end of each statement, when looking at it from a statement-centric point of view. Editing such code always requires a scan of the context of inter-statement relationship (especially when nesting) instead of just treating & terminating statements independently.
- zmonx 9y agoI agree, thank you for the clarification and additional examples!