Guard questions
Joe Armstrong
joe@REDACTED
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