DEV Community

Gilbert for The Clause

Posted on • Edited on

3 2

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).
Enter fullscreen mode Exit fullscreen mode

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
  ).
Enter fullscreen mode Exit fullscreen mode

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).
Enter fullscreen mode Exit fullscreen mode

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay