[erlang-questions] Interesting style i haven't seen....

2 views
Skip to first unread message

Greg Smyth

unread,
Oct 30, 2009, 12:25:55 PM10/30/09
to erlang-q...@erlang.org
A friend just came up with this, and i thought it was pretty
interesting(arguments against doing this kind of thing in Erlang
aside...) as I'd never seen this type of thing done before...

Anyone care to shed some light on why/how this works:-

%%
-module(dog).
-export([new/1, woof/1]).

new(Name) -> {dog, Name}.

woof(Self) ->
{dog, Name} = Self,
io:format("~p says 'woof!'~n", [Name]).
%%

% 13> c(dog).
% {ok,dog}

% 14> Dog = dog:new("Fido").
% {dog,"Fido"}

% 15> Dog:woof().
% "Fido" says 'woof!'
% ok

Many thanks,
Greg

________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org

Dave Smith

unread,
Oct 30, 2009, 12:32:39 PM10/30/09
to Greg Smyth, erlang-q...@erlang.org
Is this a trick question? I feel like I'm missing something here... :)

If the confusion is re: the use of "new", remember that Erlang has no
concept of objects or explicit allocation (like that anyways).

D.

Adriano Bonat

unread,
Oct 30, 2009, 12:40:08 PM10/30/09
to Dave Smith, Greg Smyth, erlang-q...@erlang.org
IIRC this is called parameterized modules :)

Colm Dougan

unread,
Oct 30, 2009, 12:45:42 PM10/30/09
to Greg Smyth, erlang-q...@erlang.org
I think it works because

Dog:woof()

means the same thing as :

dog:woof(Dog)

.. by virtue of the fact that Dog is a tuple with a first element of
"dog". I seem to recall this is a consequence of the parametrized
modules feature.

Colm

Adriano Bonat

unread,
Oct 30, 2009, 12:53:10 PM10/30/09
to Colm Dougan, Greg Smyth, erlang-q...@erlang.org
Exactly,

9> Blah = {modname, "arg1", "arg2", 3}.
{modname,"arg1","arg2",3}
10> Blah:func().
** exception error: undefined function modname:func/1

Tony Arcieri

unread,
Oct 30, 2009, 1:15:04 PM10/30/09
to erlang-q...@erlang.org
On Fri, Oct 30, 2009 at 10:45 AM, Colm Dougan <colm....@gmail.com> wrote:

> .. by virtue of the fact that Dog is a tuple with a first element of
> "dog". I seem to recall this is a consequence of the parametrized
> modules feature.
>

Note that the paramaterized modules paper:

http://www.erlang.se/workshop/2003/paper/p29-carlsson.pdf

...specifies the value representing a paramaterized module is opaque. This
is a side-effect of the implementation.

That said, very interesting.

--
Tony Arcieri
Medioh/Nagravision

Dave Smith

unread,
Oct 30, 2009, 1:22:50 PM10/30/09
to Tony Arcieri, erlang-q...@erlang.org
I may be wrong, but I don't think this has anything to do with
parameterized modules, but is instead an old-school way of invoking
functions. From the reference manual:

"When applied to a number N of arguments, a tuple
{Module,FunctionName} is interpreted as a fun, referring to the
function FunctionName with arity N in the module Module. The function
must be exported. This usage is deprecated. See Function Calls for an
example."

D.

________________________________________________________________

Chris Tilt

unread,
Oct 30, 2009, 12:36:06 PM10/30/09
to Dave Smith, Greg Smyth, erlang-q...@erlang.org
It's the use of Dog:woof() that throws me. Dog is a variable and I don't understand the semantics of "Variable:function()".
Cheers, Chris

Bob Ippolito

unread,
Oct 30, 2009, 2:27:20 PM10/30/09
to Chris Tilt, Dave Smith, Greg Smyth, erlang-q...@erlang.org
That's how parameterized modules work. An instance of a parameterized
module is a variable.

This particular example is (ab)using an implementation detail of how
parameterized modules are currently implemented. You'd get the same
behavior with this module, which uses an actual parameterized module:

----

-module(dog, [Name]).
-export([woof/0]).

woof() ->


io:format("~p says 'woof!'~n", [Name]).

----

1> c(dog).
{ok,dog}
2> Fido = dog:new(fido).
{dog,fido}
3> Fido:woof().
fido says 'woof!'
ok

Mihai Balea

unread,
Oct 30, 2009, 2:31:04 PM10/30/09
to Dave Smith, erlang-questions Questions

On Oct 30, 2009, at 1:22 PM, Dave Smith wrote:

> "When applied to a number N of arguments, a tuple
> {Module,FunctionName} is interpreted as a fun, referring to the
> function FunctionName with arity N in the module Module. The function
> must be exported. This usage is deprecated. See Function Calls for an
> example."

I've always wondered why that particular syntax quirk is being
deprecated. I think it's neat.

Mihai

Greg Smyth

unread,
Oct 30, 2009, 12:40:42 PM10/30/09
to Chris Tilt, Dave Smith, erlang-q...@erlang.org
Yeah,

It certainly wasn't a trick question, unless the trick is on me... :)

I still dont get how:-

Variable = {atom, Value},
Variable:function/0.

then gets converted to a call to atom:function({atom, Value})

if that makes sense...?

Cheers,
Greg

Greg Smyth

unread,
Oct 30, 2009, 12:51:18 PM10/30/09
to Dale Harvey, Dave Smith, erlang-q...@erlang.org
Looking at your example, I don't think this is parameterised modules
(although that is also interesting, thanks!).

The confusing part (for me at least), is still the section:-

> % 14> Dog = dog:new("Fido").

> % ok


>
> % 15> Dog:woof().
> % "Fido" says 'woof!'

How does Value:function() - change into

module:function(Value)

when Value = {module, Something}) ?

Cheers,
Greg

On Fri, Oct 30, 2009 at 4:42 PM, Dale Harvey <har...@gmail.com> wrote:
> The syntax is a bit wrong,
> -module(dog, [Name]).
> -export([woof/1]).


> woof(Self) ->
>  {dog, Name} = Self,
>  io:format("~p says 'woof!'~n", [Name]).
>

> % 13> c(dog).
> % {ok,dog}
>
> % 14> Dog = dog:new("Fido").

> % ok


>
> % 15> Dog:woof().
> % "Fido" says 'woof!'
> % ok

> but erlang does support it, parameterised modules
> http://www.clickcaster.com/channel/tag/modules?channel=diveintoerlang
> 2009/10/30 Dave Smith <diz...@gmail.com>

Nick Gerakines

unread,
Oct 30, 2009, 4:05:19 PM10/30/09
to Greg Smyth, Dale Harvey, Dave Smith, erlang-q...@erlang.org
Yeah, not only can you have param'd modules but they can be extensions
of each other.

http://gist.github.com/149735

--- begin nick.erl
-module(nick, [City, State]).

-export([city/0, state/0]).

state() ->
io:format("nick:state/0 -> ~p~n", [State]).

city() ->
io:format("nick:city/0 -> ~p ~n", [City]).
--- end

--- begin vanessa.erl
-module(vanessa, [City, State]).
-extends(nick).
-export([city/0]).

city() ->
io:format("child:city/0 -> ~p ~n", [City]).
--- end
$ erlc nick.erl && erlc vanessa.erl

1> Me = nick:new("Mountain View", "CA").
{nick,"Mountain View","CA"}
2> Me:city().
nick:city/0 -> "Mountain View"
ok
3> Me:state().
nick:state/0 -> "CA"
ok
4> Vanessa = vanessa:new("Mountain View", "CA").
{vanessa,{nick,"Mountain View","CA"},"Mountain View","CA"}
5> Vanessa:city().
child:city/0 -> "Mountain View"
ok
6> Vanessa:state().
nick:state/0 -> "CA"
ok
7>

Bob Ippolito

unread,
Oct 30, 2009, 4:30:59 PM10/30/09
to Greg Smyth, Dale Harvey, Dave Smith, erlang-q...@erlang.org
It is parameterized modules, just not implemented correctly. The only
reason it behaves that way is because of how they happen to be
implemented in current versions of erlang's VM and compiler. In some
future version of erlang the example at the beginning of this thread
is expected to no longer work.

Robert Virding

unread,
Oct 30, 2009, 4:34:16 PM10/30/09
to Mihai Balea, Dave Smith, erlang-questions Questions
2009/10/30 Mihai Balea <mi...@hates.ms>

>
> On Oct 30, 2009, at 1:22 PM, Dave Smith wrote:
>
> "When applied to a number N of arguments, a tuple
>> {Module,FunctionName} is interpreted as a fun, referring to the
>> function FunctionName with arity N in the module Module. The function
>> must be exported. This usage is deprecated. See Function Calls for an
>> example."
>>
>
> I've always wondered why that particular syntax quirk is being deprecated.
> I think it's neat.


They are a remenent from the bad old days when erlang was less functional
than it is today and we didn't have funs This was a hack and has no reason
for existence now that we do have funs.

Robert

Tony Rogvall

unread,
Oct 31, 2009, 9:49:00 AM10/31/09
to Robert Virding, Mihai Balea, Dave Smith, erlang-questions Questions
As already pointed out, this is new stuff, that has to do with
"abstract" modules
(You can find it in beam_emu.c apply_last)

The call corresponds to:
apply({dog,"Fido"}, woof, []).

As you can see it is not {dog,woof} !

This feature is just an implementation detail and may change.

/Tony

Reply all
Reply to author
Forward
0 new messages