[erlang-questions] Fwd: [erlang-bugs] Incorrect scope for a variable
Ola Andersson A
ola.a.andersson@REDACTED
Fri Feb 18 10:07:26 CET 2011
Very interesting indeed!
But that still leaves the question about why the compiler does not give a warning when the case statements are enclosed by a tuple.
If the evaluation order is always strictly left to right I should get a warning with or without the tuple.
Like this:
-module(a).
-compile([export_all]).
foo() -> {case 1 of X -> X end, case 2 of X -> X; _ -> 4 end}.
foo1() -> case 1 of X -> X end, case 2 of X -> X; _ -> 4 end.
Eshell V5.8.1 (abort with ^G)
1> c(a).
./a.erl:7: Warning: variable 'X' exported from 'case' (line 7)
{ok,a}
2>
The compiler only gives a warning about foo1.
It seems like the compiler also has problems with the tuple.
/OLA.
> -----Original Message-----
> From: Robert Virding [mailto:robert.virding@REDACTED]
> Sent: den 18 februari 2011 00:57
> To: Joe Armstrong
> Cc: Bengt Kleberg; erlang-questions@REDACTED; Ola Andersson A
> Subject: Re: [erlang-questions] Fwd: [erlang-bugs] Incorrect
> scope for a variable
>
> This is most definitely a bug in the interpreter, erl_eval!
> The compiler is doing the Right Thing.
>
> The compiler evaluates the code strictly left-to-right which
> it should do. When we finally got around to actually defining
> the language we decided define a strict left-to-right
> evaluation order in expressions. Not because it was
> necessarily the best, it can preclude compiler optimisations,
> but because then you would *know* exactly how expressions
> would be evaluated.
>
> And this is what the compiler does which explains the results
> from the compiled code.
>
> The interpreter does neither left-to-right nor right-to-left
> but does try to evaluate them in parallel. So in the case of
> the expression:
>
> {case 1 of X -> X end, case 2 of X -> X; _ -> 4 end}
>
> it evaluates each case separately with X unbound and then
> tries to merge the values X of from the two cases. It does
> something like:
>
> begin V1 = case 1 of X1 -> X1 end, V2 = case 2 of X2 -> X2; _
> -> 4 end, X1 = X2, {V1,V2} end
>
> Here X1 and X2 will have different values so the match/test
> X1 = X2 will fail and generate a 'badmatch' error. N.B. if
> you were to actually try and write this it would complain
> that variable X2 is 'unsafe' as it is not exported from both
> clauses but this rewrite is internal in the compiler.
>
> I personally agree that exporting values from if/case/receive
> is a Bad Thing (tm) but it does make some code a little more
> compact. The 'unsafe' error is there to help you detect cases
> which won't actually be wrong but could otherwise become
> silently different. Which I can explain in a future message.
>
> So the interpreter is wrong. The fix is actually quite simple.
>
> Robert
>
>
>
> ----- "Joe Armstrong" <erlang@REDACTED> wrote:
>
> > On Thu, Feb 17, 2011 at 3:59 PM, Ola Andersson A <
> > ola.a.andersson@REDACTED> wrote:
> >
> > > Yes, that is what I would have expected too until I read Joes
> > explanation
> > > below regarding the same statement in the shell.
> > >
> > > The question is why the same statement gives a different result in
> > the
> > > shell as compared to when used in a module:
> > >
> >
> > Very strange. Consider this module:
> >
> > -module(a).
> > -compile(export_all).
> >
> > foo() ->
> > {case 1 of X -> X end, case 2 of X -> X end}.
> >
> > foo1() ->
> > {case 1 of X -> X end, case 2 of X -> X; _ -> 4 end}.
> >
> > > a:foo().
> > ** exception error: no case clause matching 2
> > in function a:foo/0
> > > a:foo1().
> > {1,4}
> >
> > The second example shows that order of evaluation withing
> the tuple is
> > left-to-right, if it had been parallel then the result should have
> > been {1,2} (so my earlier explanation was wrong).
> >
> > In the shell - both expressions result in errors
> >
> > > f().
> > ok
> > > {case 1 of X -> X end, case 2 of X -> X end}.
> > ** exception error: no match of right hand side value 1
> > > f().
> > ok
> > > {case 1 of X -> X end, case 2 of X -> X; _ -> 4 end}.
> > ** exception error: no match of right hand side value 1
> >
> > There is no way I can explain this - the compiled version looks
> > correct and the version in the shell an error.
> >
> > /Joe
>
> --
> Robert Virding, Erlang Solutions Ltd.
>
>
More information about the erlang-questions
mailing list