[Nix-dev] with, ++, //, and laziness

Nicolas Pierron nicolas.b.pierron at gmail.com
Mon Mar 26 00:44:12 CEST 2012


Hi Again,

On Sat, Mar 24, 2012 at 21:38, Nicolas Pierron
<nicolas.b.pierron at gmail.com> wrote:
> Hi Shea,
>
> On Fri, Mar 23, 2012 at 11:01, Shea Levy <shea at shealevy.com> wrote:
>> Based on my understanding of Nix semantics, I expected the following to
>> all evaluate to 2:
>>
>> let
>>   a = { c = 1; d = b.c; };
>>   b = a // { c = 2; };
>> in b.d
>
> a let is like a    rec { … }
>
> rec {
>  a = <LAZY> { c = 1; d = <LAZY> b.c; };
>  b = <LAZY> a // <LAZY> { c = 2; };
> }
> in b.d
>
>> let
>>   a = with b; { c = 1; d = c; };
>>   b = a // { c = 2; };
>> in b.d
>
> rec {
>  a = with <ATTRNAMES>; <LAZY> { c = 1; d = <LAZY> c; };
>  b = <LAZY> a // <LAZY> { c = 2; };
> }
> in b.d
>
> <ATTRNAMES> implies that we need to be able to iterate over the "with"
> clause attribute set to bind names such as "c".  I think the behaviour
> you expected was the case for the first versions of Nix where we had
> maximal laziness for caching binding rules. <ATTRNAMES> implies to
> solve b and the "extend" operator.

What you can do to get rid  of the__overrides and the weird recursions:

let
  # depends on b and copy b.c
  a = { c = with b; 1; d = with b; c; };
  # b.c depends  on a.c which needs to know the list of attribute names of b.
  b = a //  { c = builtins.add a.c 1; };
in
  b.d

Which means, you can almost do
  sed -i  's/callPackage/with pkgs; callPackage/' all-packages.nix

and remove the __overrides attribute.

-- 
Nicolas Pierron
http://www.linkedin.com/in/nicolasbpierron - http://nbp.name/


More information about the nix-dev mailing list