[erlang-questions] Parse-transforming !! to a function call

Joe Armstrong <>
Thu Aug 16 10:52:12 CEST 2007

On 8/16/07, Kenneth Lundin <> wrote:
> Sorry, I don't understand why you would ask for a !! operator at all.
> If you want to translate A !! B to myspecialrpc(A,B) why not just use
> the functioncall directly. I can not see that the !! offers any advantage
> more than it perhaps saves you a number of characters per call.

For things that are used a lot infix syntax is nice

     A + B is nicer than plus(A, B)

I use rpc's a lot

There is a second and more important reason.

Since we can *hide* rpcs through function abstraction, we cannot easily see
which function calls are "real function calls" and which are (disguised) rpcs.

suppse we write interface routines

someFunc(A, B) -> gen_server:call(abc, {glurk, A, B})


someOtherFunc(Pid, A) -> rpc(Pid, {glonk, A})

And export them from a module.

The user *cannot see* that someFunc(A, B) results in an rpc

If you write

     abc !! {glurk, A, B}
    Pid !! {glonk, A]

then this is apparent.

rpc's are places in the code that need to be starred at hard - they introduce
bottlenecks and are extremely inefficient when the occur over a
processor boundary

If the code says

   {node(), abc} !! message

We *know* that this will be extremely inefficient.

If we *hide* this in a function call we can't see this fact.

    if we write

     abc !! Q

 We know that we have to avoid a potential bottleneck in the
registered process abc

If we hide this in a function abstraction abc:foo(...) we cannot see
at a glance that this
is a potential dangerous operation.

We also don't need to write interface functions.

This programming style *exposes* the protocol between the client/server
which is also a good thing - many time the appropriate functional abstractions
do not exist and we have to write new interface routines to no good purpose.

Knowing the underlying protocol and using the two operators ! and !! makes life
much nicer.

Finally, on syntax, to my mind

   Pid ! A
   Pid !! B

have a beautiful symetry - Pid ! A says send A to Pid
Pid !! B says send B to Pid and wait for a reply

> It would on the other hand be a big disadvantage having code that
> can't be handled
> by the standard Erlang compiler at least if the source is to be distributed.
> Joe introduced the bang bang '!!' operator when he developed his ex11
> application
> and we did not like it better at that time either.
> I think Joe removed the use of !! from ex11 because of the many complaints about
> the source not beeing compilable by the standard compiler. So in fact
> the unnecessary (for the ex11 problem) introduction of the !! operator
> proved to be a
> disadvantage for the popularity of ex11.It was not easy enough  to test it.

I reissued it with rpc instead of !! and this had no effect on the popularity.

The code with rpc was far less beautiful than the code with !!

> I am in favour of a VERY VERY RESTRICTIVE approach when it comes to
> introduction of non standard language constructs by modifying the
> parser or by use of parse transforms since it will result in source
> code
> that is hard to understand and use if you don't have the full
> knowledge of the language additions and modifications. Parse
> transforms can be motivated if used with care and not spread out in
> many modules which then are distributed as source.

I agree - that's why I added a warning in my post

> If there are language improvements or extensions that are of general interest
> please write an Erlang Enhancement Proposal (EEP) about it and we will
> consider that.
> The !! operator as described by Joe is however something that we have
> no plans to introduce in the standard language since we think it has
> so many problems and questionmarks

I don't think so.

(Actually we dont use ? any more so we could say A ? B instead of A !! B
 this might be even better - it saves one character and the ? clearly
 indicates the intent)

> and does not offer anything but syntactic sugar. A !! B instead of rpc(A,B) .
> Example of problem is that a synchronous rpc can fail in various ways,
> for example
> if the server does not respond at all. For how long shall the client
> wait? If we want a timeout , how should that be specified with that
> syntax etc. etc.?

   A !! B is defined to expand to rpc(A, B) in the local module - *nothing else*

   suppose we have two modules a and b

   -import(lib1, [rpc/2]).

   f() ->
       abc !! def.

   -import(lib2, [rpc/2]).

   f() ->
       abc !! def.

In a !! means lib1:rpc - in b it means lib2:rpc

So we can customise the meaning to whatever we want. We could also add
a local definition - giving the timeout value etc. what you want.

I can only think of one reason not to add !! (or ?)

If people use !! in some new version of erlang and distribute their
code it will not
compile with old versions of Erlang. *worse* old versions of erlang will give
a bad error message.

We *need* to add a erlang version number to the modules.


This should have been added years ago.

Old versions of the compiler will ignore this. New versions 5,6,7 .. whatever
will recognise this.

So in the future when a version 5 compiler finds code like this


It can say *politely* please update your compiler to at least version 7

What I propose is:

Add code to recognise a version number ASAP
assume that no version number in the code means version 1.

Let this version propagate to all sites in the world (say one year)

*then bump the version number*

Then we can add !! in version 2 with no problems.

Alternativly - add "live upgrade" to the system. Erlang system could  (should?)
check back with the mothership every month for a new version.


> /Kenneth (Erlang/OTP team at Ericsson)
> On 8/15/07, Joel Reymont <> wrote:
> >
> > On Aug 15, 2007, at 1:50 PM, Joe Armstrong wrote:
> >
> > > Question (to Joel) can't the entire Obj c interface be made dynamic
> > > using
> > > obj_sendMsg???
> >
> > Sure. What is the question, though?
> >
> > The reason I asked for !! is to have shorten the code that would
> > otherwise need to be written. In absence of !! I would need to add a
> > receive loop after each obj ! ....
> >
> > --
> > http://wagerlabs.com
> >
> >
> >
> >
> >
> > _______________________________________________
> > erlang-questions mailing list
> > 
> > http://www.erlang.org/mailman/listinfo/erlang-questions
> >

More information about the erlang-questions mailing list