geometric memory growth

Ulf Wiger ulf@REDACTED
Sat Nov 26 19:08:05 CET 2005


Den 2005-11-26 17:40:49 skrev Matthias Lang <matthias@REDACTED>:

> Ulf Wiger writes:
>
>  > Forgive me, but I can't help thinking that an exception
>  > when the fun is applied would be the wrong place, rather
>  > than when the fun is instantiated.
>
> This seems like madness.
>
> Do you think that f() should print "humpty":
>
>    f() ->
>      Y = atom,
>      F = fun(X) -> io:fwrite("humpty\n"), X#state.channel end,
>      F(Y).

Yes, I do.
X is not part of the fun's environment, but is passed
as an input argument at application time.

This is similar to writing

f1() ->
   Y = atom,
   Y#state.channel

The compiler would not complain, but you would
always get a runtime error, and Dialyzer would
be able to say "I told you so."


> Should g() _always_ cause an exception:
>
>    g() ->
>      Y = atom,
>      F = fun(X) ->
>            case mymod:myfunc() of
>               nice -> nice;
>               nasty -> X#state.channel
>            end,
>      F(Y).

Same here: X is an input argument, and has nothing
to do with binding the environment for fun.



> What about h():
>
>    h() ->
>      Y = atom,
>      F = fun(X) ->
>            case mymod:myfunc() of
>               nice -> nice;
>               nasty -> element(3, X)
>            end,
>      F(Y).

Again, same thing.

If, on the other hand, you wrote:

h() ->
   Y = atom,
   F = fun(P) ->
         element(P, Y)
       end.

you would have a situation where dialyzer should
be able to warn you that it's going to fail, but
the compiler would allow it. element/2, is a
normal function call.

However, X#state.channel is recognizable by the
compiler as a record attribute selection, and
if X is part of the fun's environment, the value
is bound when the fun is bound, so I think it's
a different case than all your examples.

/Uffe
-- 
Ulf Wiger



More information about the erlang-questions mailing list