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

Nicolas Pierron nicolas.b.pierron at gmail.com
Sun Mar 25 06:38:06 CEST 2012


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.


> And while we're talking about making nix more lazy, could we make it so
> these terminate?
>
> let
>   f = list: number:
>     let newList = [number]; in list ++ (f newList (builtins.add number 1));
> in builtins.head (f [] 0)
>
> let
>   f = attrs: number:
>     let
>       newAttrs = builtins.listToAttrs [ { name = "a${number}"; value =
> number; } ];
>     in (f newAttrs (builtins.add number 1)) // attrs;
> in (f {} 0).a1

let
  f = list: num:
    let newList = { head = num; tail = {}; }; in
    list // { tail = f newList (builtins.add num 1); };

  head = list: list.head;
  tail = list: list.tail;
in
  head (f {} 0)

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


More information about the nix-dev mailing list