[Nix-dev] Scoping with, rec - shouldn't it be more intuitive?

Eelco Dolstra e.dolstra at tudelft.nl
Mon Aug 11 11:05:33 CEST 2008


Hi,

Marc Weber wrote:

> example:
> 
>         let pkgs = {
>           postfix = "postfix";
>         }; in
>         rec {
>           config = {
>             extraPackages = (with pkgs; [ postfix ]);
>           };
>           postfix = "dummy";
>         }.config
> 
> 
> results in
> || Attrs([Bind("extraPackages",List([Str("dummy",[])]),NoPos)])
> I would have expected postfix beeing taken from pkgs here!
> 
> the way it is just feels wrong to me.
> 
> Should we change this?

Whether this is wrong is debatable: by taking postfix from the rec at least the 
binding is clear from the lexical scope (you can see from the lexical scoping 
that postfix will be taken from the surrounding rec, instead of dependening on 
the runtime contents of the "with").

The implementation reason is that the rec substitutes its attributes in the 
bodies of each attribute.  Of course substitution of a variable doesn't recurse 
into a term that binds that variables (e.g. a function "postfix: ..."), but with 
"with" it has no way of knowing what variables are bound, since it would have to 
evaluate "pkgs" for that.

-- 
Eelco Dolstra | http://www.st.ewi.tudelft.nl/~dolstra/



More information about the nix-dev mailing list