Prolog has an amazing syntax, thanks to it both being homoiconic and supporting custom operators. However, writing conditionals in Prolog is often a drag.
Fortunately, we don't have to convince or wait for Prolog implementations to implement a nicer syntax. Instead, we can create our own if-else syntax today!
Example Usage
%%
%% Before
%%
foo(X) :-
(
X > 50 ->
Y is X * 2,
bar(X, blah)
; baz(10, 20)
),
last(X).
%%
%% After
%%
foo(X) :-
if (X > 50) then (
Y is X * 2,
bar(X, blah)
)
else (
baz(10, 20)
),
last(X).
%%
%% Before
%%
shorter_foo(X) :- (X > 10 -> bar(X); baz(X)).
%%
%% After
%%
shorter_foo(X) :- if X > 10 then bar(X) else baz(X).
Example Usage (or
operator)
I also threw in a bonus or
operator so you can do "or" logic without introducing additional choice points, and not have to worry about catching multiple terms (due to it having a stronger precedence than the comma ,
operator):
%%
%% Before
%%
multi_foo(X, Y) :- (foo(X), !; bar(Y)).
%%
%% After
%%
multi_foo(X) :- foo(X) or bar(Y).
%%
%% Before
%%
multi_foo(X, Y) :-
((foo(X), !; bar(X)) ->
Y = true
; Y = false
).
%%
%% After
%%
multi_foo(X) :-
if (foo(X) or bar(X)) then (
Y = true
)
else (
Y = false
).
The Code
Here's the code you can copy/paste into your own project to make use of this sweet, sweet syntax.
There may even be a better way using term_expansion
. If you find one, leave it in the comments!
:- op(990, fx, if).
:- op(985, yfx, then).
:- op(985, yfx, else).
:- op(985, yfx, elseif).
:- op(800, xfx, or).
if(X) :- (if_then(X, Then) -> call(Then); true).
if_then(then(elseif(Try, Cond), MaybeThen), Then) :-
!,
(if_then(Try, Then) -> true; call(Cond), Then = MaybeThen).
if_then(then(Cond, Then), Then) :-
!,
call(Cond).
if_then(else(Try, MaybeThen), Then) :-
!,
(if_then(Try, Then) -> true; Then = MaybeThen).
or(X,Y) :- call(X) -> true; call(Y).
Top comments (0)