Nix could support evaluating attribute sets more lazily, such that e.g. the following works:
(throw "" // { x = 0; }).x
-> 0
Currently this doesn't work because attribute sets are evaluated strictly in all names, meaning all // operations and co. will have to be applied to figure out all names, making the above code throw in the current version.
Making attribute names lazy in that way has the potential to solve many existing problems:
.extend attributes of package scopes won't necessarily have to evaluate all package attributes. Similarly .override, etc. of packages won't have to call the derivation primop multiple times anymore
types.lazyAttrsOf might not be needed anymore
- In overlays you'll be able to use
self.lib for the attribute definitions if lib is added in a later overlay
lib.mkIf might not be necessary for the module system anymore
- Potentially more
However this also changes semantics, so this should be thought out well.
I have implemented an initial prototype that supports above evaluation in infinisil@afeda4f. I'll continue with this if I have time.
Ping @edolstra @Profpatsch
NOTE (@roberth): To manage expectations, querying a non-existing attribute fundamentally requires evaluation of all attribute names.
- e.g.
if attrs?attr then e_lazy else e_strict has to strictly evaluate the attrnames for e_strict.
{ foo, ...}: -style functions have to strictly evaluate all the attrnames in order to preserve their existing semantics.
Nix could support evaluating attribute sets more lazily, such that e.g. the following works:
Currently this doesn't work because attribute sets are evaluated strictly in all names, meaning all
//operations and co. will have to be applied to figure out all names, making the above code throw in the current version.Making attribute names lazy in that way has the potential to solve many existing problems:
.extendattributes of package scopes won't necessarily have to evaluate all package attributes. Similarly.override, etc. of packages won't have to call thederivationprimop multiple times anymoretypes.lazyAttrsOfmight not be needed anymoreself.libfor the attribute definitions iflibis added in a later overlaylib.mkIfmight not be necessary for the module system anymoreHowever this also changes semantics, so this should be thought out well.
I have implemented an initial prototype that supports above evaluation in infinisil@afeda4f. I'll continue with this if I have time.
Ping @edolstra @Profpatsch
NOTE (@roberth): To manage expectations, querying a non-existing attribute fundamentally requires evaluation of all attribute names.
if attrs?attr then e_lazy else e_stricthas to strictly evaluate the attrnames fore_strict.{ foo, ...}:-style functions have to strictly evaluate all the attrnames in order to preserve their existing semantics.