I’m still working on my changes and don’t have an answer for you.
I don’t see any reason for changing a single-clause predicate :-
to =>
:
p(X, Y) :- q(a, X, Y).
vs
p(X, Y) => q(a, X, Y).
Here are some real-world examples … which is clearer?
A predicate used by convlist/3:
is_module_sym_type(Sym-Type, Sym-Type) :-
memberchk(module_type(_), Type).
vs
is_module_sym_type(Sym-Type, SymType) =>
SymType = Sym-Type,
memberchk(module_type(_), Type).
Making an output arg explicit and replacing :- !
with =>
:
%! remove_candidate(+Candidate:atom, +Seq:list(atom), -SeqOut:list(atom)) is det.
remove_candidate(Candidate, [Candidate|Seq], Seq) :- !.
remove_candidate(_, Seq, Seq).
vs
%! remove_candidate(+Candidate:atom, +Seq:list(atom), -SeqOut:list(atom)) is det.
remove_candidate(Candidate, [Candidate|Seq], SeqOut) => SeqOut = Seq.
remove_candidate(_, Seq, SeqOut) => SeqOut = Seq.
Replacing an exhaustive listing of patterns and making output args explicit:
add_up_dots([], Path, Path).
add_up_dots([_|Dots], Path, DotsPath) :-
add_up_dots(Dots, ['..'|Path], DotsPath).
vs
add_up_dots([], Path, DotsPath) => DotsPath = Path.
add_up_dots([_|Dots], Path, DotsPath) =>
add_up_dots(Dots, ['..'|Path], DotsPath).
Replacing an if-then-else:
simple_path_module_fqn(Path, ModuleFqn) :-
( var(ModuleFqn)
-> split_path_to_module_parts(Path, ModuleFqnParts),
join_fqn(ModuleFqnParts, ModuleFqn)
; split_module_atom(ModuleFqn, ModuleFqnParts),
join_path(ModuleFqnParts, Path)
).
vs
simple_path_module_fqn(Path, ModuleFqn), var(ModuleFqn) =>
split_path_to_module_parts(Path, ModuleFqnParts),
join_fqn(ModuleFqnParts, ModuleFqn).
simple_path_module_fqn(Path, ModuleFqn) =>
split_module_atom(ModuleFqn, ModuleFqnParts),
join_path(ModuleFqnParts, Path).
Replacing an if-then-else with a secondary predicate (this is a bit subtle: include(p, Seqs, [])
succeeds if p(X)
fails for all X
in Seqs
):
mro_merge_candidate(Seqs, Candidate) :-
Seqs = [[Candidate0|_]|SeqsTail],
( include(in_tail(Candidate0), Seqs, [])
-> Candidate = Candidate0
; mro_merge_candidate(SeqsTail, Candidate)
).
vs
mro_merge_candidate(Seqs, Candidate),
Seqs = [[Candidate0|_]|SeqsTail] =>
mro_merge_candidate2(Seqs, Candidate0, SeqsTail, Candidate).
mro_merge_candidate2(Seqs, Candidate0, _SeqsTail, Candidate),
include(in_tail(Candidate0), Seqs, []),
Candidate = Candidate0.
mro_merge_candidate2(_Seqs, _Candidate0, SeqsTail, Candidate) =>
mro_merge_candidate(SeqsTail, Candidate).