Discussion:
Parse-transforming !! to a function call
(too old to reply)
unknown
2007-08-11 23:15:30 UTC
Permalink
Folks,

Suppose I wanted !! to send a synchronous message via a function
call. How would I write a parse transform to do it?

I would like x !! y to be transformed into mod:func(x, y). Is this
possible?

Thanks in advance, Joel

--
http://wagerlabs.com
unknown
2007-08-11 23:41:34 UTC
Permalink
It doesnt even parse, so the parse-transform cant work on it.

{ok, Tokens, Lines} = erl_scan:string("foo(X) -> foo !! X.").
erl_parse:parse_form(Tokens).


It has been suggested before that the backtick or similar could be used
to create an infix operator out of an arity-two function, like in haskell.

X `add` Y vs add(X, Y)

or in your case

x `!!` y instead of '!!'(x, y)

http://www-users.cs.york.ac.uk/~mfn/hacle/issues/node2.html#SECTION00028000000000000000

I'm not all that crazy about the idea though. LispErlang would be cooler. :)
Post by unknown
Suppose I wanted !! to send a synchronous message via a function
call. How would I write a parse transform to do it?
I would like x !! y to be transformed into mod:func(x, y). Is this
possible?
Thanks in advance, Joel
unknown
2007-08-12 00:37:48 UTC
Permalink
Post by unknown
I'm not all that crazy about the idea though. LispErlang would be cooler. :)
I'm looking for a neat way to express a synchronous call for ObjC/
Cocoa. I'm not all that crazy about having (objc:send(objc:send
(objc:send(...), ...), ...). I would rather have a shortcut!

--
http://wagerlabs.com
unknown
2007-08-12 01:09:56 UTC
Permalink
Objective-C looks like this:

[[[object doStuffWith:foo and:bar] moreStuff] lastStuffUsing: baz];

Which is pretty close to something parsable in erlang. Using imagination.

The qlc module manages to use the LC syntax. How about you use nested
list syntax?
Imagine that objc:call is special like qlc:q and you implement this:

Value = objc:call([[[Object, do_stuff(Foo, Bar)], more_stuff()],
last_stuff(Baz)]).

where do_stuff(Foo, Bar) and friends implements optional sugar such as:

do_stuff(Foo, Bar) ->
{'doStuffWith:and:', Foo, Bar}.

But just chaining like this is probably sugar enough and skips all of
parse transforms:

objc:msgs([Object, do_stuff(Foo, Bar), more_stuff(), last_stuff(Baz)]).

where msgs sends messages like this:

msgs([Object |Methods]) ->
lists:foldl(fun(M, Object) -> objc:send(Object, M) end, Object, Methods).
Post by unknown
Post by unknown
I'm not all that crazy about the idea though. LispErlang would be cooler. :)
I'm looking for a neat way to express a synchronous call for ObjC/
Cocoa. I'm not all that crazy about having (objc:send(objc:send
(objc:send(...), ...), ...). I would rather have a shortcut!
--
http://wagerlabs.com
unknown
2007-08-12 01:57:58 UTC
Permalink
One weird thing is the "with" and "and" that you elide aren't really
semantic sugar or ignorable. They are a meaningful part of the
selector's name. Destroying objective c to fit with erlang fills me
with a special sad since the NS API is probably the best one I have
ever seen. Also practically there are many selectors that start with
the same prefix and differ only by the 2nd arguments. Your scheme
would create some confusion there too.

-ryan
Post by unknown
[[[object doStuffWith:foo and:bar] moreStuff] lastStuffUsing: baz];
Which is pretty close to something parsable in erlang. Using
imagination.
The qlc module manages to use the LC syntax. How about you use nested
list syntax?
Value = objc:call([[[Object, do_stuff(Foo, Bar)], more_stuff()],
last_stuff(Baz)]).
do_stuff(Foo, Bar) ->
{'doStuffWith:and:', Foo, Bar}.
But just chaining like this is probably sugar enough and skips all of
objc:msgs([Object, do_stuff(Foo, Bar), more_stuff(), last_stuff
(Baz)]).
msgs([Object |Methods]) ->
lists:foldl(fun(M, Object) -> objc:send(Object, M) end, Object, Methods).
Post by unknown
Post by unknown
I'm not all that crazy about the idea though. LispErlang would be cooler. :)
I'm looking for a neat way to express a synchronous call for ObjC/
Cocoa. I'm not all that crazy about having (objc:send(objc:send
(objc:send(...), ...), ...). I would rather have a shortcut!
--
http://wagerlabs.com
_______________________________________________
erlang-questions mailing list
erlang-questions
http://www.erlang.org/mailman/listinfo/erlang-questions
unknown
2007-08-12 02:36:02 UTC
Permalink
Post by unknown
One weird thing is the "with" and "and" that you elide aren't really
semantic sugar or ignorable. They are a meaningful part of the
selector's name. Destroying objective c to fit with erlang fills me
with a special sad since the NS API is probably the best one I have
ever seen. Also practically there are many selectors that start with
the same prefix and differ only by the 2nd arguments. Your scheme
would create some confusion there too.
-ryan
So you have issues with example names? Do you have anything to say
about Foo, Bar and Baz as variable names too?

I'm not writing the objc gateway. Joel is. He can preserve the
meaningful parts of selector names on the erlang side as he wishes.
Personally I think 'With' and 'and' are pretty meaningless parts of an
imaginary meaningless method name, which is why it would be silly with
a 'doStuffWith:and:'(Foo, Bar) function. It's very different if we
have things like drawCircle:at: and drawRectangle:at:. Then we have
information.
unknown
2007-08-12 02:45:13 UTC
Permalink
Hi. New to the language and just reading Joe Armstrong's book.

I was just wondering.. is there any facility in the language to allow
you to create mock processes, so that outgoing process calls can be
intercepted under test?

Michael
unknown
2007-08-12 04:37:37 UTC
Permalink
Hi, Michael, Glad to see you here.

I've tested processes behaviors in Erlang with a lot of ease. It's
really easy. All you have to do is pass around pid instead of global
reference, just like DIP in OOP.

Suppose process A should wait for msg1 from process C and then once it
receives, it should emit msg2 to process B.

You want to test the behavior of process A.

You first spawn a mock process MockB which just waits for msg2 and
then it sends you "test passed" back(I mean back to the testing
process). Now, you spawn process A with the pid of MockB. You also
need to spawn a stub process MockC(along with the pid of process A)
which just sends msg1 to process A.

You can easily build a mock framework, discovering and refactoring the
repeating patterns.

If you want more detail, I'll work on a concrete example code.

June
Post by unknown
Hi. New to the language and just reading Joe Armstrong's book.
I was just wondering.. is there any facility in the language to allow
you to create mock processes, so that outgoing process calls can be
intercepted under test?
Michael
_______________________________________________
erlang-questions mailing list
erlang-questions
http://www.erlang.org/mailman/listinfo/erlang-questions
unknown
2007-08-12 12:06:50 UTC
Permalink
Post by unknown
[[[object doStuffWith:foo and:bar] moreStuff] lastStuffUsing: baz];
I'm in favor of modifying the parser to add the !! notation (aliased
to !) and then doing

A = object !! [{dostuffWith, foo}, {and, bar}],
B = A !! [moreStuff],
C = B !! [{lastStuffUsing, baz}]

What do you think?

I also think that I would rather add the Obj-C runtime functions as
Erlang BIFs than to use the FFI. I definitely want the bridge to run
inside the Erlang VM so I'm still don't know how to best combine the
Erlang runtime with that of Obj-C. Cocoa wants its own run loop which
could be a problem.

Joel

--
http://wagerlabs.com
unknown
2007-08-12 13:55:48 UTC
Permalink
Post by unknown
Post by unknown
[[[object doStuffWith:foo and:bar] moreStuff] lastStuffUsing: baz];
I'm in favor of modifying the parser to add the !! notation (aliased
to !) and then doing
Are you going to make this objc-bridge open source? Because modifying
the scanner
and parser to make the syntax parsable will make it difficult to begin
using the code, it needing special compilation methods, which might be
more of a nuisance than the benefit of the syntax itself.
Post by unknown
A = object !! [{dostuffWith, foo}, {and, bar}],
B = A !! [moreStuff],
C = B !! [{lastStuffUsing, baz}]
What do you think?
It displays its sequential order very clearly, but dont you think it
is a bit verbose?

The reason I used do_stuff(Foo, Bar) for constructing something like
{'doStuffWith:and:', Foo, Bar} is that the more intelligent editors
can perform tab completion and pop up documentation for functions.
Dialyzer will perhaps be more practical too, and guards on the
do_stuff arguments can perform sanity checks. But the quick hack can
still spell out a selector name directly in the code (shell!) and
refactor it later.

Another idea, similar in verbosity to your bang-bang approach.
A = {Object, 'doStuffWith:and:', Foo, Bar},
B = {A, 'moreStuff'},
C = {B, 'lastStuffUsing:', Baz},
objc:eval(C).
%% Or objc:eval(Port, C) where Port is one of several separated objc
ports, or just
%% something to hang preregistered shortcut atom names on for
frequently used objects.

You would also get a way to get a bunch of methods happen atomically.
Now that we make such a big deal of concurrency in erlang. :)

The best approach is probably to write some code in erlang for the
various syntax suggestions, get a feel for how they're to work with
and how well they read. Then implement
the one you like best.
Post by unknown
I also think that I would rather add the Obj-C runtime functions as
Erlang BIFs than to use the FFI. I definitely want the bridge to run
inside the Erlang VM so I'm still don't know how to best combine the
Erlang runtime with that of Obj-C. Cocoa wants its own run loop which
could be a problem.
Conventional wisdom is to do this later, if at all, and start out with
an external port process since it is easier and find out if it would
be a good idea with closer interaction. Myself, I tend to always
underestimate the speed of computers with a factor of 100.

Memo to self: I need to look into how one gives linked in drivers
threads of their own and how to communicate with the erlang runtime.
unknown
2007-08-11 23:52:08 UTC
Permalink
Post by unknown
I would like x !! y to be transformed into mod:func(x, y). Is this
possible?
AFAIK a parse_transform can only work on a legal AST.

x !! y is not turned into a valid AST via c(module).


-module(show_ast).
-export([parse_transform/2]).
parse_transform(AST, _Options) ->
[io:format("~p~n", [Node]) || Node <- AST],
AST.


-module(test).
-compile([export_all]).
-compile({parse_transform, show_ast}).
test() -> x !! y.


1> c(show_ast), c(test).
{attribute,1,file,{"./test.erl",1}}
{attribute,1,module,test}
{attribute,2,compile,[export_all]}
{error,{5,erl_parse,["syntax error before: ",["'!'"]]}}
{eof,7}
./test.erl:5: syntax error before: '!'
error
2>

i.e.: An error is produced before show_ast can do anything about it.

I do not know if it would be possible to get around this by using any
of the various Erlang parse tools. (If you do find a way then please
let me know!)

Cheers,
Philip
unknown
2007-08-12 09:02:15 UTC
Permalink
This looks like Joe's "bang-bang" notation.
Joe made a small change to the parser to make this possible.
He first wrote about it in http://www.sics.se/~joe/nerl.html,
I think.

BR,
Ulf W
Post by unknown
Folks,
Suppose I wanted !! to send a synchronous message via a function
call. How would I write a parse transform to do it?
I would like x !! y to be transformed into mod:func(x, y). Is this
possible?
Thanks in advance, Joel
--
http://wagerlabs.com
_______________________________________________
erlang-questions mailing list
erlang-questions
http://www.erlang.org/mailman/listinfo/erlang-questions
unknown
2007-08-15 12:50:49 UTC
Permalink
yes indeed very easy !! needs a one line addition to erl_parse.yrl


Find erl_parse.yrl (in stdlib/src)

Look for a line like this:

expr_100 -> expr_150 '!' expr_100 : mkop('$1', '$2', '$3').

Then add the following

expr_100 -> expr_150 '!' '!' expr_100: {call, line('$1'),{atom,
line('$1'), rpc},['$1', '$4']}.

This turns all calls A !! B into rpc(A, B)

Build a new parser
erlc erl_parse.yrl
erlc erl_parse.erl
test with (for example)

-module(bang).

-compile(export_all).

test1() ->
a !! b.

rpc(A, B) ->
{hello, A, B}.

$erl
c(bang).
bang:test1()
{hello, a,b}

This way you can redefine !! as you please by using an appropriate
-import(xyz, [rpc/2]) in your code

*remember* !! is addictive - so don't forget to remove !! from programs you
distribute, since you need a non-standard parser to parse the sources.

(I guess we need a -use_parser(Mod) annotation in the code :-)

Question (to Joel) can't the entire Obj c interface be made dynamic using
obj_sendMsg???

The call [obj with:i str:@"abc"]

can be built dynamically using something like

int i;
NSString s;
i = 1234;
s = @"hello"
obj_sendMsg(obj, NSSelectorFromString(@"with:str:", &i, s)

and the type signature can be found introspectively - I think this is
how Fscript does it

Cheers

/Joe
This looks like Joe's "bang-bang" notation.
Joe made a small change to the parser to make this possible.
He first wrote about it in http://www.sics.se/~joe/nerl.html,
I think.
BR,
Ulf W
Post by unknown
Folks,
Suppose I wanted !! to send a synchronous message via a function
call. How would I write a parse transform to do it?
I would like x !! y to be transformed into mod:func(x, y). Is this
possible?
Thanks in advance, Joel
--
http://wagerlabs.com
_______________________________________________
erlang-questions mailing list
erlang-questions
http://www.erlang.org/mailman/listinfo/erlang-questions
_______________________________________________
erlang-questions mailing list
erlang-questions
http://www.erlang.org/mailman/listinfo/erlang-questions
unknown
2007-08-15 12:57:44 UTC
Permalink
Post by unknown
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
unknown
2007-08-16 08:03:11 UTC
Permalink
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.

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

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
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.?



/Kenneth (Erlang/OTP team at Ericsson)
Post by unknown
Post by unknown
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
erlang-questions
http://www.erlang.org/mailman/listinfo/erlang-questions
unknown
2007-08-16 08:52:12 UTC
Permalink
Post by unknown
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})

or

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}
or
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
Post by unknown
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 !!
Post by unknown
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
Post by unknown
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)
Post by unknown
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.?
Easy.
A !! B is defined to expand to rpc(A, B) in the local module - *nothing else*

suppose we have two modules a and b

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

f() ->
abc !! def.

-module(b)
-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.

-module(foo).
-needs_erlang_version(5).

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

-module(foo)
-needs_erlang_version(7).

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.

/Joe
Post by unknown
/Kenneth (Erlang/OTP team at Ericsson)
Post by unknown
Post by unknown
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
erlang-questions
http://www.erlang.org/mailman/listinfo/erlang-questions
unknown
2007-08-16 09:46:30 UTC
Permalink
Hi,
Post by unknown
Since we can *hide* rpcs through function abstraction, we cannot easily see
which function calls are "real function calls" and which are (disguised) rpcs.
[snip]
If you write
abc !! {glurk, A, B}
or
Pid !! {glonk, A]
then this is apparent.
Well, this isn't quite true. Since !! would expand to calling rpc/2,
it all depends on what this function does -- it would do a rpc only by
convention.
Post by unknown
Post by unknown
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.?
Easy.
A !! B is defined to expand to rpc(A, B) in the local module - *nothing else*
-module(a)
-import(lib1, [rpc/2]).
f() ->
abc !! def.
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.
That would mean that you can't have two !! calls from the same module
that use different options, wouldn't it?

That said, I too think this kind of notation would help streamline not
only the code, but also the coder's thoughts. However, I think it
should be more than just a simple sugar coating on a local call to
rpc/2. [No, sorry, I don't have an answer to the follow up question,
it's just my feeling]

best regards,
Vlad
unknown
2007-08-16 16:10:21 UTC
Permalink
Post by unknown
For things that are used a lot infix syntax is nice
A + B is nicer than plus(A, B)
The problem with infix is formatting. How do you format in your editor a
long list of infix-separated expressions?

A
+ B
+ C
+ D

Loses the fact that A has an equivalent rank to B, C, D. If later, you
decide to reorder your expressions, A cannot be freely reordered like the
other lines because it lacks the infix operator. Of course you can move the
infix operator to the end (this is what is usually done when the infix
operator is a comma), but then expression D loses its free movement ability.
Keeping with infix, we could put the operator on its own line:

A
+
B
+
C
+
D
Or

A
+
B
+
C
+
D

Which enables you to move A around so long as you take its following
operator along with it and so long as it is not going at the end.

What I am getting at is that prefix operator make it much easier to format
your code. I'm not a Lisp programmer, but that is one of the first things I
noticed about Lisp, which I like. This is much easier to rearrange:

+
A
B
C
D

Even on a single line:

+ A B C D

Is easier to rearrange than its infix counterpart:

A + B + C + D

Since A cannot easily be moved to the end. One would have to move the "A +
" to the end, and then move the " + " between the "D" and "A".
Post by unknown
A + B is nicer than plus(A, B)
I would argue that you have simply exchanged one infix operator (plus) for a
another (comma) and added in a prefix ("plus(") and postfix (closing paren)
to boot, so, yes, you are right, one infix operator is better than an infix
operator that also requires a prefix and postfix.

Erlang is by no means the only language to have this problem. Indeed, I
think any non-Lisp language has this problem. However, in some languages
the problem is not quite so severe. Erlang's syntax, however, is as bad as
SQL's in terms of formatting, in my opinion: I never know exactly how to
format my Erlang consistently.

Example 1: Take a simple function definition:

f(...) -> ... .

Seems simple enough. If the body is long, we can format it like so:

f(...) ->
... ,
... ,
... .

Now let's add in a guard:

f(...) when ... ->
... ,
... ,
... .

How about a complicated guard:

f(...)
when
..., ..., ...;
..., ..., ...;
..., ..., ...;
->
... ,
... ,
... .

Now the body of our function has to be indented another level to show that
it is subordinate to the infix operator "->". But if we later decide to
change the function to eliminate the guard, we have to modify our
indentation, too.

Example 2: Multiple clauses in a function. They are separated by the infix
semicolon operator, but terminated by a postfix period. This arrangement
results in the ordering problems that was described earlier with our A + B +
C + D example: we cannot freely rearrange the order of the clauses without
making structural changes to our code. Note that this would not be a
problem if the semicolon were a postfix clause terminator, but since it is
infix, it is. If it were postfix, then this would be valid, and we wouldn't
have the clause reordering problem:

f(...) -> ...;
f(...) -> ...;
f(...) -> ...;
f(...) -> ...;
. % Postfix function terminator

Therefore, I would argue for infix operator reduction rather than expansion.
Post by unknown
For things that are used a lot infix syntax is nice
I don't find infix operators nice at all. I realize we are stuck, by and
large, with Erlang's infix-heavy syntax, however, so I'll go along with it.

Cheers,

David
unknown
2007-08-24 07:40:49 UTC
Permalink
Post by unknown
[...]
(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)
if only... but as far as i know '?' is munched by the preprocessor.

also, i think that if anything '?' should be used instead of
'receive' (the way God, or at least Tony Hoare, intended).

mats
unknown
2007-08-24 22:34:16 UTC
Permalink
Post by unknown
Post by unknown
[...]
(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)
if only... but as far as i know '?' is munched by the preprocessor.
also, i think that if anything '?' should be used instead of
'receive' (the way God, or at least Tony Hoare, intended).
mats
Could a parse transform recognize the case where the value A ! B is not
discarded and change those cases into some kind of synchronous call? So
that

A = spawn(...),
A ! whatever,
ok.

is a async call but

A = spawn(...),
B = A ! whatever,
B.

is a synchronous call. The return value of ! is normally just the value
that was sent, which doesn't seem very useful. The only places where it
would not be immediately evident if the return value is ignored is when
a function or Fun evaluates to a send. Even so, ! normally looks like
an imperative operator more than a functional one so this seems to make
it more functional (but also lazy in some respects, which is
anti-erlang/soft-rt)

-J
unknown
2007-08-24 23:32:48 UTC
Permalink
Post by unknown
Post by unknown
Post by unknown
[...]
(Actually we dont use ? any more so we could say A ? B instead of A !!
B
Post by unknown
Post by unknown
this might be even better - it saves one character and the ? clearly
indicates the intent)
if only... but as far as i know '?' is munched by the preprocessor.
also, i think that if anything '?' should be used instead of
'receive' (the way God, or at least Tony Hoare, intended).
mats
Could a parse transform recognize the case where the value A ! B is not
discarded and change those cases into some kind of synchronous call? So
that
A = spawn(...),
A ! whatever,
ok.
is a async call but
A = spawn(...),
B = A ! whatever,
B.
is a synchronous call. The return value of ! is normally just the value
that was sent, which doesn't seem very useful. The only places where it
would not be immediately evident if the return value is ignored is when
a function or Fun evaluates to a send. Even so, ! normally looks like
an imperative operator more than a functional one so this seems to make
it more functional (but also lazy in some respects, which is
anti-erlang/soft-rt)
That would result in forcing people to write some really weird code. I could
never for example just end a function with a normal async send as that would
be interpreted as sync send.

Generally the idea of having the semantics of something change depending on
what comes after seems a little off.

Robert
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20070825/361727e2/attachment.html>
unknown
2007-08-25 00:22:17 UTC
Permalink
Post by unknown
Post by unknown
Could a parse transform recognize the case where the value A ! B is not
discarded and change those cases into some kind of synchronous call? So
that
A = spawn(...),
A ! whatever,
ok.
is a async call but
A = spawn(...),
B = A ! whatever,
B.
is a synchronous call. The return value of ! is normally just the value
that was sent, which doesn't seem very useful. The only places where it
would not be immediately evident if the return value is ignored is when
a function or Fun evaluates to a send. Even so, ! normally looks like
an imperative operator more than a functional one so this seems to make
it more functional (but also lazy in some respects, which is
anti-erlang/soft-rt)
That would result in forcing people to write some really weird code. I could
never for example just end a function with a normal async send as that would
be interpreted as sync send.
I think the opposite would be true - since the compiler (or rather,
parse transformer) can only see the immediate surroundings it can make
no assumption about other scopes; since it would be new semantics the
safe assumption would always be that the old semantics are the default.
So you would not be able to end your function with a synchronous send
because it would be interpreted as async; you would need to jump
through a hoop to send with a sync call.

From my very limited understanding of how the AST works, it would need
a very simple transform like
{match,Ln,L0,{op,SLn,'!',L1,R1}} ->
{match,Ln,L0,{call,SLn,{atom,SLn,sync_send},[L1,R1]}}
to change "A = B ! C" into "A = sync_send(B,C)" and that wouldn't touch
any other syntax.
Post by unknown
Generally the idea of having the semantics of something change depending on
what comes after seems a little off.
It would be what comes before it, not after it. I would agree that
radically changing the semantics of the expression based on external
surrounding syntax is odd at best, but I think it could be useful and
not terribly confusing (other than the issues that have already been
raised about how to specify the behavior of the synchronous call) .

-J
unknown
2007-08-26 01:59:16 UTC
Permalink
Post by unknown
Post by unknown
Post by unknown
Could a parse transform recognize the case where the value A ! B is not
discarded and change those cases into some kind of synchronous
call? So
Post by unknown
Post by unknown
that
A = spawn(...),
A ! whatever,
ok.
is a async call but
A = spawn(...),
B = A ! whatever,
B.
is a synchronous call. The return value of ! is normally just the
value
Post by unknown
Post by unknown
that was sent, which doesn't seem very useful. The only places where
it
Post by unknown
Post by unknown
would not be immediately evident if the return value is ignored is when
a function or Fun evaluates to a send. Even so, ! normally looks like
an imperative operator more than a functional one so this seems to make
it more functional (but also lazy in some respects, which is
anti-erlang/soft-rt)
That would result in forcing people to write some really weird code. I
could
Post by unknown
never for example just end a function with a normal async send as that
would
Post by unknown
be interpreted as sync send.
I think the opposite would be true - since the compiler (or rather,
parse transformer) can only see the immediate surroundings it can make
no assumption about other scopes; since it would be new semantics the
safe assumption would always be that the old semantics are the default.
So you would not be able to end your function with a synchronous send
because it would be interpreted as async; you would need to jump
through a hoop to send with a sync call.
From my very limited understanding of how the AST works, it would need
a very simple transform like
{match,Ln,L0,{op,SLn,'!',L1,R1}} ->
{match,Ln,L0,{call,SLn,{atom,SLn,sync_send},[L1,R1]}}
to change "A = B ! C" into "A = sync_send(B,C)" and that wouldn't touch
any other syntax.
Generally the idea of having the semantics of something change depending on
Post by unknown
what comes after seems a little off.
It would be what comes before it, not after it. I would agree that
radically changing the semantics of the expression based on external
surrounding syntax is odd at best, but I think it could be useful and
not terribly confusing (other than the issues that have already been
raised about how to specify the behavior of the synchronous call) .
The problem is not whether it is difficult to do in the compiler but rather
if we want to do it. Having the semantics of :

A ! Msg

and

B = A ! Msg

being different would be a first in the language and I personally think
completely horrendous.
Also the semantic difference between sending an async message and doing a
sync rpc is VERY large.
Also if you were to add one end of a sync message passing then you should
also add the other end as well, both receiving the message and returning the
reply.
If instead it was defined to translate into a certain function call which
you yourself then had to provide then that would also be a first, and I
honestly don't see the benefit of it. Why not just write the function call
yourself?
Also there are people who use the return value of a send, not just as a
side-effect. They won't be happy.

Robert
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20070826/11282a67/attachment.html>
unknown
2007-08-26 22:13:04 UTC
Permalink
Post by unknown
The problem is not whether it is difficult to do in the compiler but
A ! Msg
and
B = A ! Msg
being different would be a first in the language and I personally think
completely horrendous.
I'm not suggesting this as a change to the language - that would require
*far* more thought than a 2-minute brainstorm. I was pondering the idea
as a parse-transform only, so that the programmer chooses when to use it
with a compiler directive. This thread started with a discussion about
how bad it was to need a different compiler to accept a new piece of
syntax and I had a thought about how to do it with the same compiler.
Post by unknown
Also the semantic difference between sending an async message and doing
a sync rpc is VERY large.
No argument here. I'm not saying it wouldn't be different. I am saying
it might be useful in some cases.
Post by unknown
Also if you were to add one end of a sync message passing then you
should also add the other end as well, both receiving the message and
returning the reply.
I could see some benefit to this too, but since in most cases you would
want to actually do something before sending the reply a compact
representation is tough to come up with. The potentially useful part
would be having the response operator implicitly know what process to
send the message to. So for example, where the sync-send hides "A !
{self(),B}" behind a simeple "A ! B", the sync receive hides "receive
{Pid,Msg} -> Pid ! Fun(Msg)" behind "receive! Msg -> Fun" or something
like that.
Post by unknown
If instead it was defined to translate into a certain function call
which you yourself then had to provide then that would also be a first,
and I honestly don't see the benefit of it. Why not just write the
function call yourself?
It's syntactic sugar, that's all, just like "A ! B" is syntactic sugar
for "erlang:send(A,B)".
Post by unknown
Also there are people who use the return value of a send, not just as a
side-effect. They won't be happy.
I can't claim alot of experience here, but it seems odd to use the
return value since it's essentially an identity. The return value of
"A ! B" is B, never anything else. The people who wouldn't be happy
about it could just not use the parse-transform module in their code.

-J

unknown
2007-08-16 09:07:11 UTC
Permalink
Post by unknown
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 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.?
Hear, hear! The !! syntax looks alluringly simple, but it is far from
clear what the details of its semantics ought to be. There are many
possible variations of RPC, in particular with respect to what it
guarantees in the presence of failure. Furthermore, it would be
necessary to standardize the format of messages, and that is another
area where that which is sufficient for some applications, e.g.
{ok, Value}, would be too brittle for other applications that might
want to include a special tag or a unique reference in requests, to be
part of the replies, e.g. {reply, From, MsgID, Value}.

I'm not saying that it's impossible to come up with a straightforward
behaviour that matches what most people need most of the time, but it
really needs to be worked out properly before a new operator is
dedicated to it. Meanwhile, stick to plain old function calls, please.

To end this on a more positive note, I'd like to encourage everyone on
this list to keep thinking about how Erlang process communication could
be made even simpler and more streamlined. Plain asynchronous message
passing (with selective receive) is a powerful yet simple building block
but it is still rather primitive, and often, Erlang programmers (myself
included) will neglect to think too far about what might happen if
messages are lost, timeouts occur, or messages arrive in an unexpected
order. We tend to go back and fix those bugs when they bite us, but it
would be better if we were using communication constructs that came with
certain guarantees to begin with; like the difference between goto-
programming and structured language constructs like while/for/case.

/Richard
unknown
2007-08-16 18:08:35 UTC
Permalink
Post by unknown
To end this on a more positive note, I'd like to encourage everyone on
this list to keep thinking about how Erlang process communication could
be made even simpler and more streamlined.
I quite like E's promise-passing RPC. It's sort of intermediate between
Erlang's async one-way messages and a synchronous RPC. The immediate
result of an RPC is a promise, and you can send messages to it on the
assumption that it will resolve into an object that can handle the
messages (in Erlang that would be a pid). For anything else you have to
wait for the promise to resolve or be broken; I think it would be
reasonable for the promise to provide standard ways of doing so while
handling errors and timeouts.

See erights.org for more. Their promises asynchronously morph into the
value they resolve to, which makes me worry - I prefer the idea of
promises that are more visibly proxies that must be unwrapped when they
are ready.

Tony.
--
f.a.n.finch <dot> http://dotat.at/
IRISH SEA: SOUTHERLY, BACKING NORTHEASTERLY FOR A TIME, 3 OR 4. SLIGHT OR
MODERATE. SHOWERS. MODERATE OR GOOD, OCCASIONALLY POOR.
unknown
2007-08-24 08:34:10 UTC
Permalink
Post by unknown
I'd like to encourage everyone on
this list to keep thinking about how Erlang process communication could
be made even simpler and more streamlined. Plain asynchronous message
passing (with selective receive) is a powerful yet simple building block
but it is still rather primitive, and often, Erlang programmers (myself
included) will neglect to think too far about what might happen if
messages are lost, timeouts occur, or messages arrive in an unexpected
order. We tend to go back and fix those bugs when they bite us, but it
would be better if we were using communication constructs that came with
certain guarantees to begin with; like the difference between goto-
programming and structured language constructs like while/for/case.
i read somewhere that "an idiom indicates a missing feature." (or
maybe i just made it up?)
in any case, i tend to use this idiom a lot, and i think it does
indeed indicate a missing language feature.

safe_send(Pid,Msg) ->
Ref = erlang:monitor(process,Pid),
Pid ! {Ref,self(),Msg},
receive
{'DOWN',Ref,_,_,R} ->
exit({no_receiver,R,Pid});
{Ref,Ans} ->
erlang:demonitor(Ref),
receive {_,Ref,_,_,_} -> ok after 0 -> ok end,
Ans
end.

the caller of safe_send/2 will receive either an answer from Pid, or
an exit(*).

i'm not proposing safe_send/2 to become part of OTP (i haven't even
compiled this particular version). my point is just that there is a need
for a version of '!' that guarantees that the message was delivered.

mats

(*)
of course, the code running in Pid must look something like this;

receive {Ref,Pid,Msg} -> Pid ! {Ref,handle(Msg)} end
unknown
2007-08-24 15:05:52 UTC
Permalink
Post by unknown
in any case, i tend to use this idiom a lot, and i think it does
indeed indicate a missing language feature.
safe_send(Pid,Msg) ->
Ref = erlang:monitor(process,Pid),
Pid ! {Ref,self(),Msg},
receive
{'DOWN',Ref,_,_,R} ->
exit({no_receiver,R,Pid});
{Ref,Ans} ->
erlang:demonitor(Ref),
receive {_,Ref,_,_,_} -> ok after 0 -> ok end,
Ans
end.
I like your use of Ref to identify which message is the reply to your
request. I was using make_ref/0 before for this, but your way is better.
Your demonitor-receive instructions can be condensed into one line:

erlang:demonitor(Ref, [flush])

Cheers,

David
unknown
2007-08-16 13:38:22 UTC
Permalink
On Thu, Aug 16, 2007 at 10:03:11AM +0200, Kenneth Lundin wrote:
} Sorry, I don't understand why you would ask for a !! operator at all.

Because it's so elegant, it makes for beautiful code. :)

... however I'm sure you're right.

-Vance


[Good code is prose.]
unknown
2007-08-15 22:24:43 UTC
Permalink
There is one small problem with this fix, as you have not modified the
tokeniser it will allow you to write things like:

test1() ->
A ! ! B.

test2() ->
A !

! B.

Which does look a little strange. :-)

Robert
Post by unknown
yes indeed very easy !! needs a one line addition to erl_parse.yrl
Find erl_parse.yrl (in stdlib/src)
expr_100 -> expr_150 '!' expr_100 : mkop('$1', '$2', '$3').
Then add the following
expr_100 -> expr_150 '!' '!' expr_100: {call, line('$1'),{atom,
line('$1'), rpc},['$1', '$4']}.
This turns all calls A !! B into rpc(A, B)
Build a new parser
erlc erl_parse.yrl
erlc erl_parse.erl
test with (for example)
-module(bang).
-compile(export_all).
test1() ->
a !! b.
rpc(A, B) ->
{hello, A, B}.
$erl
c(bang).
bang:test1()
{hello, a,b}
This way you can redefine !! as you please by using an appropriate
-import(xyz, [rpc/2]) in your code
*remember* !! is addictive - so don't forget to remove !! from programs you
distribute, since you need a non-standard parser to parse the sources.
(I guess we need a -use_parser(Mod) annotation in the code :-)
Question (to Joel) can't the entire Obj c interface be made dynamic using
obj_sendMsg???
can be built dynamically using something like
int i;
NSString s;
i = 1234;
and the type signature can be found introspectively - I think this is
how Fscript does it
Cheers
/Joe
This looks like Joe's "bang-bang" notation.
Joe made a small change to the parser to make this possible.
He first wrote about it in http://www.sics.se/~joe/nerl.html,
I think.
BR,
Ulf W
Post by unknown
Folks,
Suppose I wanted !! to send a synchronous message via a function
call. How would I write a parse transform to do it?
I would like x !! y to be transformed into mod:func(x, y). Is this
possible?
Thanks in advance, Joel
--
http://wagerlabs.com
_______________________________________________
erlang-questions mailing list
erlang-questions
http://www.erlang.org/mailman/listinfo/erlang-questions
_______________________________________________
erlang-questions mailing list
erlang-questions
http://www.erlang.org/mailman/listinfo/erlang-questions
_______________________________________________
erlang-questions mailing list
erlang-questions
http://www.erlang.org/mailman/listinfo/erlang-questions
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20070816/3651bc4f/attachment.html>
unknown
2007-08-16 06:42:39 UTC
Permalink
Post by unknown
test1() ->
A ! ! B.
test2() ->
A !
! B.
Which does look a little strange. :-)
Not as strange as
A !
%% hi, this is a comment
! B.

:-)

/Vlad
unknown
2007-08-12 22:36:59 UTC
Permalink
Michael

I have written a test library with facilities for creating mocks and stubs. I just wrote it for my own use and it needs some work before it's publishable, but I would be happy to share what I have with you.

It allows the creating of mock processes (which expect messages to be sent to them) and stub ones (which silently accept any message). Either type can be created as an anonymous or as a registered process.

Code that uses the library looks like this:

should_feed_marmosets_at_break_of_day() ->
stub(cat),
M = mock({expect, {food, weevil}}),
Keeper = keeper:new([M]),
Keeper ! wake_up.

should_kick_cat_at_break_of_day() ->
mock(cat, {expect, kick}),
Keeper = keeper:new([]),
Keeper ! wake_up.

Where the keeper's code contains something like this:

loop(Marmosets) ->
receive
wake_up ->
cat ! kick,
lists:foreach(fun(M) -> M ! weevil end, Marmosets),
loop(Marmosets)
% ...
end.

The cat is modeled as a registered process just to show what is possible. It is also possible to create expectations on existing mocks (by sending them messages) when dependencies are more complicated. It's not currently integrated with EUnit (or any other proper testing framework), but probably should be.

Let me know if you are interested. If several people would like to use it I'll publish it somewhere.

Ben
Continue reading on narkive:
Loading...