Open foxfriends opened 3 years ago
Better yet, stealing the templates/meta-predicates idea from Prolog but making the syntax more explicit gives a more powerful feature. The problem with Prolog's version is that there really isn't a way to syntactically differentiate a template passed to a higher-order function from a regular pattern. By either separating the template parameters into a separate parameter list, or using a different syntax for them, we could avoid this problem.
A few possibilities:
Put templates into their own arguments list, requiring to reference them with $
.
all<_, _>([]).
all<P, C>([X, ..Xs]) :- $P =:= X, $C -> all<$P, $C>(Xs).
allGt3(Xs) :- all<A, (A > 3)>(Xs).
Prefix the template pattern with $
, and require the template argument to also be prefixed (also with $
). Note that reusing a template argument requires two $
(one for the reference and one for the syntax).
all($_, $_, []).
all($P, $C, [X, ..Xs]) :- $P =:= X, $C -> all($$P, $$C, Xs).
allGt3(Xs) :- all($A, $A > 3, Xs).
Could use any separator here, not necessarily the ugly #
. Maybe remove named parameters (#31) and then use the :
, or use a |
instead (if that won't cause problems with expressions).
all(_, _ # []).
all(P, C # [X, ..Xs]) :- #P =:= X, #C -> all(#P, #C, Xs).
allGt3(Xs) :- all(A, A > 3 # Xs).
Might be a bit more difficult, but more powerful:
all($_, $_, []).
all($P, $C, [$P, ..Xs]) :- $C -> all($P, $C, Xs).
allGt3(Xs) :- all(A, A > 3, Xs).
Higher order predicates would help prevent unnecessary code duplication, the same way higher order functions are used in functional programming. For example, to check that all numbers in a list are greater than
n
, we need to write a specialized recursive predicate for eachn
:But with higher order predicates, a generic
all<1>/1
could be written: