## DEV Community

Gilbert for The Clause

Posted on • Updated on

# A Nicer if-then-else Syntax in Prolog

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).
``````