[erlang-questions] module params not visible everywhere

Richard Carlsson richardc@REDACTED
Mon Mar 12 16:12:04 CET 2007

Ulf Wiger wrote:
> I ran into the following snag when generating code:
> -module('erlhive.ulf.epp', [___Env]).
> -record(epp, {file,
>               ...,
>               macs = .erlhive_call:call_own_module
>                          ({'erlhive.ulf.dict',
>                            setelement(2,___Env,<<117, 108, 102>>)},
>                           new,
>                           0,
>                           [],
>                           setelement(2,___Env,<<117, 108, 102>>)),
>               ...}).
> The compiler didn't accept this. Apparently, ___Env (the module parameter)
> is not bound at record definition time.

Variables in a record definition are not a good idea (currently).
Since the expressions that specify field defaults will be inline
expanded at the point where you create a new record, they may be
subject to name capture. E.g., in the following case:

     -module(foo, [X, Y]).
     -record(bar, {a = X, b = Y}).
     f() ->  fun (X) -> #bar{} end.

the record would probably not contain what you expected (well,
perhaps if you are used to programming Emacs Lisp...).

This could be solved if the compiler were to generate individual
initializer functions for record fields, so that the default for
a record field would not be expanded verbatim, but rather as:

     {bar, __init_bar_1(), __init_bar_2{}}
   __init_bar_1() -> X.
   __init_bar_2() -> Y.

This would work by default with parameterized modules, and the
normal inlining would remove the calls in most cases anyway
(and the inliner avoids the name capture problem).

For now, the easiest way to get this right is to write the field
initializer functions manually (in any case it's best not to put
anything more complicated than a function call in a record field
initializer; you'll get code duplication and whatnot).


More information about the erlang-questions mailing list