Is Erlang's `receive` more powerful/expressive than `thread_get_message`?

Speaking as a complete Erlang novice and an “intermediate” SWI Prologer, I’ve been mulling the pros and cons.

I’ve gradually been chopping back the examples I gave in Erlang "ping pong" concurrent programming example translated into SWI Prolog as I realised I didn’t need thread_self (-Pid) and thread_get_message (+Pid, ?Term) since both can be combined into thread_get_message (?Term) if I’m getting messages from the thread I’m in’s queue.

I like Erlang’s

receive
   pattern1 ->
       actions1;
   pattern2 ->
       actions2;
   ....
   patternN ->
       actionsN
end.

In Prolog, I can sometimes achieve the above with something like:

message_handler(pattern1, Result1) :-
    action1(pattern1, Result1), !.
message_handler(pattern2, Result2) :-
    action2(pattern2, Result2), !.
...
message_handler(patternN, ResultN) :-
    actionN(patternN, ResultN), !.
message_handler(_, false).
 
listener :-
    thread_get_message(Pattern),
    message_handler(Pattern, Result),
   (    Result
   ->  listener
   ;     % send finish or whatever to end
   ).

But I often find myself writing ugly

 (  case == pattern1 
-> action1
;    ( case == pattern2
    -> action2
     ; ...
     )
)

So some tips on how to do case statements nicely in Prolog would be welcome.

1 Like