Question about 'if'

Jay Nelson <>
Wed Jun 9 07:37:36 CEST 2004

 > why is
 >   if
 >     f(X) =:= 42 ->
 >   end
 > not allowed, but
 >   Y = f(X),
 >   if
 >     Y =:= 42 ->
 >   end

Functions can have side effects even if they fail.  Bad things
happen if a failing guard test changes the state.  Only the
guard bifs can apply ( == being one), so in this case you
can make it safe by generating the value and then testing
with a simple guard.

 > Is there some means to identify a function (compare it to
 > a given function) that gets passed as argument?

The natural erlang way (in my mind) was to do a parse
transformation to a record like this:

-record icode(linenum, label, opcode, args, original).

genCode(Text, LineNum) ->
	[Label, Operator | Args] = parseText(Text),
	ICode = #icode(linenum=LineNum, label=Label, opcode=opToken(Operator),
			args=Args, original=Text}.

opToken("Move") -> move;   % or even fun(Arglist) -> move(Arglist) end
opToken("Drop") -> drop;

Then you would define functions for move and drop and
use apply(ICode#icode.opcode, ICode#icode.args) or in
the case of the fun, just call ICode#icode.opcode(ICode#icode.args).

Pattern matching and tuples are half the battle in transforming
text to internal tokens, with debuggable code falling out of the
record constructs automatically.  I wrote lists of icode records
to files as if they were library.obj files, then used consult to
load up an obj file for execution or linking.  Apply and funs make
the records directly executable.  I used apply and was able to
run simulations in tens of seconds, but converting to funs
should speed things up nicely.


More information about the erlang-questions mailing list