Question about fun's

Joe Armstrong joe@REDACTED
Thu Jan 28 10:51:51 CET 1999

Hi Shawn, let me comment on your program line by line ...

> Ok, we're looking at implementing a system in Erlang where it would be nice to
> have true object-oriented behavior.  The way this is typically done in scheme
> is to make each object a lambda and bind the object state to the lambda when
> you construct the object.  Thus you can do "(object print)" to make it print
> out stuff.
> I'm thinking that we'd do something similar in Erlang like so:
> -module(myclass).
> -export([new/0]).
> new() -> save_state([]).
> save_state(State) ->
> 	fun(Message) ->
> 		myclass:dispatch(State,Message)
  Better might be:

		?MODULE:dispatch(State, Message)

	?MODULE is a pre-defined macro whoes value is the current module
	If you do it this way and decide to change the name of the module
	then the program will still work! If you bake the name in and at a
	later state decide to change the module
	 name (which I'm always doing), you'll
	probably forget to change the call

> 	end.
> dispatch(State,{print}) -> io:format("Hi!");
> dispatch(State,{append,Item}) -> save_state([Item|State]);
> dispatch(State,{get}) -> State;
> dispatch(State,{empty}) -> save_state([]).

OOOps - Erlang is dynamically typed. But you should always "think types"

> dispatch(State,{print}) -> io:format("Hi!");

	The return value is the atom ok

> dispatch(State,{append,Item}) -> save_state([Item|State]);

	The return value is a Fun

> dispatch(State,{get}) -> State;

	The return value is a list of Items
> dispatch(State,{empty}) -> save_state([]).

	The Return value is a Fun.

Code like this might one day bite you in the tail.

	Also why use {get}, {print} etc. {..} is a tuple construtor
This is like building a C struct and putting ONE value in it. C structs
and Erlang tuples are designed as holders for multiple values, not singletons.
So always use X instead of {X}.

> Then I can work with the object like this:
> O=myclass:new().
> O1=O({append,TheThingy}).
> O1({print}).
> O2=O1({empty}).
> What are the drawbacks, ie is the fun going to cost me a large amount of RAM,
> or a large amount of processing overhead on each message?

	No. Funs involve very small overhead but they do make the program 
shorter and easier to read.

	Before hacking yourself to death I'd read the "design principles"
section in the on-line documentation. This is in:

	Or wherever you've installed it locally.

	(I'd recommend you take the *entire* documentation and install it

	This tells how to set up a client/server in the "Erlang way" which is
not OO :-)

	[BTW In making a system the tricky bit is concurrency/load balancing/
	 fault-tolerence/fail-over etc.]

	The generic methods in the OTP libraries do the tricky bits. All you
have to do is plug in the "semantics". These are small functions, like:

	Fun(State, Request} -> {reply, State', Reply}

	Then you get the tricky bits for free. If you do the
small functions in an OO style then you should make sure that
match up with the OTP libraries so you get the fault-tolerence for free.

Joe Armstrong  Computer Science Laboratory  +46 8 719 9452
AT2/ETX/DN/SU  Ericsson Telecom SE-126 25 Stockholm Sweden 

More information about the erlang-questions mailing list