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