Erlang Mailing Lists

Author Message

<  Erlang questions mailing list  ~  Guard questions

crd at inversenet.com
Posted: Tue Mar 30, 1999 9:13 pm Reply with quote
Guest
(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.

(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.

Thanks,

Craig




Post generated using Mail2Forum (http://m2f.sourceforge.net)
joe at erix.ericsson.se
Posted: Wed Mar 31, 1999 7:34 am Reply with quote
Guest
> (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 Smile - 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 *beep* 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 Smile 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"




Post generated using Mail2Forum (http://m2f.sourceforge.net)
crd at inversenet.com
Posted: Wed Mar 31, 1999 1:26 pm Reply with quote
Guest
Joe Armstrong wrote:

> > (2a) f(X) when record(X, x) -> X#x.field.
> >
> > (2b) f(#x{field = Field}) -> Field.
>
> In this case particular case I wonder why you
> use a function to abstract out the record.

Oh, that was just to provide enough of an example to demonstrate the two
possible ways of expressing the idea that the function expected an x record
as its argument, but only really wanted a field or two from it. I wouldn't
really use a function just to pull a named field out of a record! But
sometimes I've had functions that took records, but didn't really need the
record as such, only the fields; in those cases, I considered it best just
to take the record as an argument, but declare names for the field values in
the function head, as in (2b). My question was really whether the two heads
will behave any differently; (2a) is clearly going to be bypassed if X is
not of type record(x), and I was pretty sure the same was true of (2b), but
I thought I might as well ask the experts even though it seems to be
working. (You never know -- there might be some non-obvious reason to prefer
(2a).)

Thanks for your reply!

Craig



Post generated using Mail2Forum (http://m2f.sourceforge.net)

Display posts from previous:  

All times are GMT
Page 1 of 1
This forum is locked: you cannot post, reply to, or edit topics.

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum