Re: [Nix-dev] joining attribute sets recursively
On Mon, 16 Jan 2012 22:05:26 +0100, Nicolas Pierron nicolas.b.pier...@gmail.com wrote: (..) mkX [ { a = 1; b = 1; c.a = 1; } { b = 2; c.b = 2; d = 2; } ] possible results: - error because of colliding b - first value taken: { a = 1; b = 1; c = { a = 1; b = 2 }; d = 2} - last value taken: { a = 1; b = 2; c = { a = 1; b = 2 }; d = 2} - both values taken: { a = 1; b = [1 2]; c = { a = 1; b = 2 }; d = 2} - both values taken: { a = 1; b = mkX [1 2]; c = mkX [ { a = 1; } { b = 2; } ]; d = 2} +1 Currently the cleanest way to do so is to duplicate the condition on the attributes, such as: config = { boot = mkIf cfg.enable { … }; services = mkIf cfg.aggressive { … }; }; By the way, usually the enable condition is wrapping everything and what you want to do makes me wonder if the aggressive option does not deserve another name. I would wrap everything with enable and additionally with aggressive you can turn on more aggressive features. Open for better suggestions. -- Florian Friesdorf f...@chaoflow.net GPG FPR: 7A13 5EEE 1421 9FC2 108D BAAF 38F8 99A3 0C45 F083 Jabber/XMPP: f...@chaoflow.net IRC: chaoflow on freenode,ircnet,blafasel,OFTC pgpbfs7yFD6tv.pgp Description: PGP signature ___ nix-dev mailing list nix-dev@lists.science.uu.nl http://lists.science.uu.nl/mailman/listinfo/nix-dev
Re: [Nix-dev] joining attribute sets recursively
Now for one the syntax is incorrect try this: cfg.enable ({ ... } // (if cfg.aggressive then { .. } else { .. } )) will be overriden with the value from the second attribute set. there are merge functions defined in lib - but they are overkill. The solution is to move and duplicate the mkIf or use two different modules. I suggested to pierron adding a mkMerge function for exactly that reason - and because mkElse can be used in uncommen ways. I also rewrote the config system making this easy - but I have done no testing yet. Try this: config.powerManagement = { cpuFreqGovernor = ondemand; scsiLinkPolicy = if (cfg.aggressive) then min_power else mkNoDef; // or something similar, grep nixos code for its usages. } if mkNoDef doesn't work try the // trick shown above. [.. infinite recursion ] The problem is that cfg.aggressive can't be evaluated without evaluating the top level config attrs. But that contains the condition! Let me make it obvious: config = mkIf cfg.enable ({ aggressive = true; } // (if cfg.aggressive then { } else { })); in order to evaluate aggressive the module system has to evaluate the if branch.. but in order to know whether it should be evaluated it has to evaluate the condition .. in order to ... :-) You get the point. HTH Marc Weber ___ nix-dev mailing list nix-dev@lists.science.uu.nl http://lists.science.uu.nl/mailman/listinfo/nix-dev
Re: [Nix-dev] joining attribute sets recursively
On 16/01/12 15:37, Florian Friesdorf wrote: config = mkIf cfg.enable { ... powerManagement.cpuFreqGovernor = ondemand; } // cfg.aggressive ? { ... powerManagement.scsiLinkPolicy = min_power; } : {}; Indeed it would be good to have a way of writing this down in a nice way. (Using two different modules as Marc suggested isn't very elegant.) Maybe something like config = mkUnion [ (mkIf cfg.foo { ... attrs ... }) (mkIf cfg.bar { ... attrs ... }) ... ]; -- Eelco Dolstra | http://www.st.ewi.tudelft.nl/~dolstra/ ___ nix-dev mailing list nix-dev@lists.science.uu.nl http://lists.science.uu.nl/mailman/listinfo/nix-dev
Re: [Nix-dev] joining attribute sets recursively
Excerpts from Eelco Dolstra's message of Mon Jan 16 16:50:10 +0100 2012: config = mkUnion That mkUnion is exactly what mkMerge should be doing. Wait another week or two. I hope I have nixos running on my rewrite so that we can benchmark both memory consumption and speed. If there are no significant improvements in those two areas I'm likely to drop it again. You can see the draft implementation here: http://mawercer.de/~marc/config-eval-rewrite.patch The test.nix contains examples about how mkMerge can be used. Basically its still a { options = .. config = .. } declaration. I chose to make it explicit that required modules don't depend on options. Not sure whether its making everything less readable. Marc Weber ___ nix-dev mailing list nix-dev@lists.science.uu.nl http://lists.science.uu.nl/mailman/listinfo/nix-dev
Re: [Nix-dev] joining attribute sets recursively
On Mon, 16 Jan 2012 16:42:50 +0100, Marc Weber marco-owe...@gmx.de wrote: Now for one the syntax is incorrect try this: cfg.enable ({ ... } // (if cfg.aggressive then { .. } else { .. } )) I fail to see the difference to what I tried, which resulted in infinte recursion, which you also explain below. will be overriden with the value from the second attribute set. there are merge functions defined in lib - but they are overkill. The solution is to move and duplicate the mkIf or use two different modules. I suggested to pierron adding a mkMerge function for exactly that reason - and because mkElse can be used in uncommen ways. I also rewrote the config system making this easy - but I have done no testing yet. Try this: config.powerManagement = { cpuFreqGovernor = ondemand; scsiLinkPolicy = if (cfg.aggressive) then min_power else mkNoDef; // or something similar, grep nixos code for its usages. } It's not just the scsiLinkPolicy but also a jobs definition and eventually more. if mkNoDef doesn't work try the // trick shown above. [.. infinite recursion ] The problem is that cfg.aggressive can't be evaluated without evaluating the top level config attrs. But that contains the condition! Let me make it obvious: config = mkIf cfg.enable ({ aggressive = true; } // (if cfg.aggressive then { } else { })); in order to evaluate aggressive the module system has to evaluate the if branch.. but in order to know whether it should be evaluated it has to evaluate the condition .. in order to ... :-) You get the point. see above -- Florian Friesdorf f...@chaoflow.net GPG FPR: 7A13 5EEE 1421 9FC2 108D BAAF 38F8 99A3 0C45 F083 Jabber/XMPP: f...@chaoflow.net IRC: chaoflow on freenode,ircnet,blafasel,OFTC pgpj4WvJukhv7.pgp Description: PGP signature ___ nix-dev mailing list nix-dev@lists.science.uu.nl http://lists.science.uu.nl/mailman/listinfo/nix-dev
Re: [Nix-dev] joining attribute sets recursively
On Mon, 16 Jan 2012 16:50:10 +0100, Eelco Dolstra e.dols...@tudelft.nl wrote: On 16/01/12 15:37, Florian Friesdorf wrote: config = mkIf cfg.enable { ... powerManagement.cpuFreqGovernor = ondemand; } // cfg.aggressive ? { ... powerManagement.scsiLinkPolicy = min_power; } : {}; Indeed it would be good to have a way of writing this down in a nice way. (Using two different modules as Marc suggested isn't very elegant.) Maybe something like config = mkUnion [ (mkIf cfg.foo { ... attrs ... }) (mkIf cfg.bar { ... attrs ... }) ... ]; hmm - not sure whether mkUnion or mkMerge (as Marc suggests) cuts it. The term *merge* is pretty generic and it would depend on a merge algorithm what happens. A union for sets is defined as all elements without duplicates, with a quick search I could not find a definition for key/val pairs / associative arrays / attribute sets. Maybe looking at the possible behaviours helps finding a name: mkX [ { a = 1; b = 1; c.a = 1; } { b = 2; c.b = 2; d = 2; } ] possible results: - error because of colliding b - first value taken: { a = 1; b = 1; c = { a = 1; b = 2 }; d = 2} - last value taken: { a = 1; b = 2; c = { a = 1; b = 2 }; d = 2} - both values taken: { a = 1; b = [1 2]; c = { a = 1; b = 2 }; d = 2} -- Florian Friesdorf f...@chaoflow.net GPG FPR: 7A13 5EEE 1421 9FC2 108D BAAF 38F8 99A3 0C45 F083 Jabber/XMPP: f...@chaoflow.net IRC: chaoflow on freenode,ircnet,blafasel,OFTC pgpVss9v3soS0.pgp Description: PGP signature ___ nix-dev mailing list nix-dev@lists.science.uu.nl http://lists.science.uu.nl/mailman/listinfo/nix-dev
Re: [Nix-dev] joining attribute sets recursively
On Mon, Jan 16, 2012 at 18:28, Florian Friesdorf f...@chaoflow.net wrote: On Mon, 16 Jan 2012 16:50:10 +0100, Eelco Dolstra e.dols...@tudelft.nl wrote: On 16/01/12 15:37, Florian Friesdorf wrote: config = mkIf cfg.enable { ... powerManagement.cpuFreqGovernor = ondemand; } // cfg.aggressive ? { ... powerManagement.scsiLinkPolicy = min_power; } : {}; Indeed it would be good to have a way of writing this down in a nice way. (Using two different modules as Marc suggested isn't very elegant.) Maybe something like config = mkUnion [ (mkIf cfg.foo { ... attrs ... }) (mkIf cfg.bar { ... attrs ... }) ... ]; hmm - not sure whether mkUnion or mkMerge (as Marc suggests) cuts it. The term *merge* is pretty generic and it would depend on a merge algorithm what happens. A union for sets is defined as all elements without duplicates, with a quick search I could not find a definition for key/val pairs / associative arrays / attribute sets. Maybe looking at the possible behaviours helps finding a name: mkX [ { a = 1; b = 1; c.a = 1; } { b = 2; c.b = 2; d = 2; } ] possible results: - error because of colliding b - first value taken: { a = 1; b = 1; c = { a = 1; b = 2 }; d = 2} - last value taken: { a = 1; b = 2; c = { a = 1; b = 2 }; d = 2} - both values taken: { a = 1; b = [1 2]; c = { a = 1; b = 2 }; d = 2} - both values taken: { a = 1; b = mkX [1 2]; c = mkX [ { a = 1; } { b = 2; } ]; d = 2} Currently the cleanest way to do so is to duplicate the condition on the attributes, such as: config = { boot = mkIf cfg.enable { … }; services = mkIf cfg.aggressive { … }; }; By the way, usually the enable condition is wrapping everything and what you want to do makes me wonder if the aggressive option does not deserve another name. -- Nicolas Pierron http://www.linkedin.com/in/nicolasbpierron - http://nbp.name/ ___ nix-dev mailing list nix-dev@lists.science.uu.nl http://lists.science.uu.nl/mailman/listinfo/nix-dev