Guard questions

Joe Armstrong <>
Wed Mar 31 09:33:41 CEST 1999


> (1) Why is there no way to express "or" in a list of guards? "f(x) when a,
> b" means "f(x) when a and b", but there seems to be no way to say "f(x) when
> a or b"; instead, you have to say "f(x) when a -> do_something; f(x) when
> b -> do_something." It's a mild annoyance at worst, but a curious one. It
> seems to me that it would have been more obvious to use "and" instead of the
> comma between guards, and allowed "or" and "xor" as well. I suspect there
> was a conscious intent behind this design, but the reasoning behind it is
> not obvious to me.
> 

    It's a feature :-) - I quite agree it's silly - this is one of the
things that will be fixed in Erlang 5.0.

    The reason why its like this is that compiling "and" guards was much 
easier. The origonal JAM was much like the prolog WAM so the compiler
turned this:

	Clause1 when Guard1 -> Body1
	Clause2 when Guard2 -> Body2
	...

into:

	tryMeElse L1
	 ... pattern match the head of the Clause 1 and get
	     things into registers 
	 ... testGuard1 
	     this has instructions like   
	     test(Var, int)
             which fail to the current "tryMeElse" label
	commit 
         ... compile Body2

    L1: tryMeElse L2
	 ...

    etc. - so compiling "and" guards was easy - if  any test fails you
just jump to a label at the start of  the next clause. Compiling "ors"
needed a slighty  different instruction set - and  didn't get  done in
the origonal JAM. After the JAM started spreading  it was too late and
"ors" in guards never got high priority.


> (2) Is there any behavioral or performance difference between the
> expressions 2a and 2b below? It seems to me that they ought to be
> equivalent. Are there technical or stylistic reasons to prefer one over the
> other? (I tend to prefer 2b except when I need to refer to the whole record
> in the function.)
> 
>     (2a) f(X) when record(X, x) -> X#x.field.
> 
>     (2b) f(#x{field = Field}) -> Field.

They should be equivalent.

As for performance I don't know - I'm alergic to performance
questions :-) I get a nasty red rash and come out in spots.

Even If I knew that 2a) was faster than 2b) for a particular compiler I
would never [1] use that information - 'cos in the next compiler it might
be the other way around.

Joe's law: Choose the most beautiful. 

In this case particular case I wonder why you
use a function to abstract out the record. 

If "x" was a car and "field" a wheel

At the site of the call you'd write

	W = wheel(C), or,
	W = C#car.wheel,

But [by extension] making lots of small selector functions would
clutter up the function namespace and be inefficient.

So the answer is neither 2a) or 2b) 

/Joe

[1] Except If I was really really really forced to do so - i.e. life and
death stuff - if you make the performace hack your product works,
otherwise it fails. Remember "every line of code you write will one day
have to be maintained by somebody" 





More information about the erlang-questions mailing list