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

Shea Levy shea at shealevy.com
Mon Mar 26 05:18:54 CEST 2012


On 03/25/2012 12:38 AM, Nicolas Pierron wrote:
> rec {
>    a = with<ATTRNAMES>;<LAZY>  { c = 1; d =<LAZY>  c; };
>    b =<LAZY>  a //<LAZY>  { c = 2; };
> }
> in b.d
> oul
> <ATTRNAMES>  implies that we need to be able to iterate over the "with"
> clause attribute set to bind names such as "c".

Even accepting that for 'with b; { c = 1; d = c }' we have to be able to 
know that b is an attribute set and get all the attribute names for b, I 
still don't see why this should be an infinite recursion. We know all 
the attribute names for 'with b; { c = 1; d = c }': c and d (no matter 
what b is, the attribute names are c and d). Similarly, the attribute 
names for { c = 2 } are just c. So we know all the attribute names for 
b: c and d. Where does the infinite recursion come in?

> 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 does 'solve b' mean here? Surely we don't have to evaluate each 
attribute of b, and I already showed that we can determine the attribute 
names of b without any infinite recursion.

> 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)
>

Well, yes, but it would be nice if the builtin operators could already 
do this. Far from essential, but it would be nice.


More information about the nix-dev mailing list