[Nix-dev] variable scope / recursion

Shea Levy shea at shealevy.com
Fri Jul 6 14:37:01 CEST 2012


For posterity, here's that link again hard-coded to the latest commit affecting eval.cc: https://github.com/NixOS/nix/blob/f491ae97d472bfd6305a8f3e8c58fac1fdc443a4/src/libexpr/eval.cc#L525

On Jul 6, 2012, at 8:23 AM, Shea Levy <shea at shealevy.com> wrote:

> Hi Mathijs,
> 
> I've not fully read the thread, but just so you know overrides are done with a special attribute called __overrides, which has a more confusing semantics than simply a rec. See https://github.com/NixOS/nix/blob/master/src/libexpr/eval.cc#L525 for some documentation, and the surrounding function has all the relevant code I think. Not sure if that particularly applies to your problem.
> 
> ~Shea
> 
> On Jul 6, 2012, at 8:04 AM, Mathijs Kwik <mathijs at bluescreen303.nl> wrote:
> 
>> On Fri, Jul 6, 2012 at 1:43 PM, Kirill Elagin <kirelagin at gmail.com> wrote:
>>> Yeah, now I get your problem.
>>> It think, it's clear from the source of `applyGlobalOverrides` and from
>>> comments, that your `packageOverrides` is called with _original,
>>> non-overriden_ pkgs. This way you can to refer to _original_ attributes when
>>> overriding them.
>> 
>> Yeah I saw those comments too, but I can't see how that would work.
>> Because the "original" (pkgsOrig) set is built by passing pkgs (the
>> final set) to pkgsFun.
>> In other words, the set references itself, which is perfectly normal
>> in a lazy setting.
>> The notion of "original" makes sense for the attributes that get
>> overwritten, but for the rest, I would expect a "shine through".
>> 
>>> 
>>> I think the only option is to manually simulate overriding process in
>>> `packageOverrides` to obtain overriden pkgs.
>> 
>> That would mean a modification to nixpks, and maintaining a separate
>> fork forever, which is what I want to avoid.
>> 
>>> 
>>> 
>>> --
>>> Кирилл Елагин
>>> 
>>> 
>>> 2012/7/6 Mathijs Kwik <mathijs at bluescreen303.nl>
>>>> 
>>>> Maybe I better explain what I'm trying to achieve.
>>>> 
>>>> I have a bunch of packages and overrides that aren't very useful for
>>>> others, so I can't commit them to nixpkgs.
>>>> I don't want to constantly maintain my own "fork" that I need to keep
>>>> up-to-date, but rather use the current "channels" functionality.
>>>> 
>>>> So I figured it's easiest to just use packageOverrides to apply the
>>>> modifications and to add the additional packages.
>>>> 
>>>> This works fine for almost everything, but I want to structure my
>>>> additional packages more like nixpkgs itself (use directories and
>>>> callPackage). Ideally, I don't want to distinguish between nixpkgs and
>>>> my own pkgs, so the scope for callPackage needs to be the composition
>>>> of nixpkgs with my own stuff.
>>>> 
>>>> But it seems I can't get a reference to the final nixpkgs attrset
>>>> within the overrides function...
>>>> 
>>>> Any hints?
>>>> 
>>>> Thanks,
>>>> Mathijs
>>>> 
>>>> 
>>>> 
>>>> On Fri, Jul 6, 2012 at 12:10 PM, Mathijs Kwik <mathijs at bluescreen303.nl>
>>>> wrote:
>>>>> On Fri, Jul 6, 2012 at 12:01 PM, Kirill Elagin <kirelagin at gmail.com>
>>>>> wrote:
>>>>>> rec is the answer (this is something like let/letrec in Lisp, if you
>>>>>> know
>>>>>> what I mean ;) ).
>>>>> 
>>>>> I don't see how rec would help here.
>>>>> As I understand it, rec helps when an attrset has attributes that
>>>>> refer to each other.
>>>>> But in this case, bar isn't referring to foo in the same object (the
>>>>> overrides object I'm creating, containing just foo and bar), but to
>>>>> pkgs.foo.
>>>>> 
>>>>> Anyway, I tried it anyway:
>>>>>  packageOverrides = pkgs:
>>>>>    rec { foo = "string";
>>>>>      bar = pkgs.foo + " concatenation";
>>>>>    };
>>>>> 
>>>>> But this does not help.
>>>>> Still "missing attribute foo".
>>>>> 
>>>>> 
>>>>>> 
>>>>>> --
>>>>>> Кирилл Елагин
>>>>>> 
>>>>>> 
>>>>>> 2012/7/6 Mathijs Kwik <mathijs at bluescreen303.nl>
>>>>>>> 
>>>>>>> Hi all,
>>>>>>> 
>>>>>>> I was reading this interesting piece of all-packages.nix
>>>>>>> (comments/whitespace removed):
>>>>>>> 
>>>>>>> applyGlobalOverrides = overrider:
>>>>>>>   let
>>>>>>>     overrides = overrider pkgsOrig //
>>>>>>>       (lib.optionalAttrs (pkgsOrig.stdenv ? overrides && crossSystem
>>>>>>> == null) (pkgsOrig.stdenv.overrides pkgsOrig));
>>>>>>>     pkgsOrig = pkgsFun pkgs {};
>>>>>>>     pkgs = pkgsFun pkgs overrides;
>>>>>>>   in pkgs;
>>>>>>> 
>>>>>>> I'm familiar with tying-the-knot lazy trickery in haskell.
>>>>>>> As pkgsOrig uses pkgs (the final end result including overrides), and
>>>>>>> the overrider function gets passed pkgsOrig, I would expect the
>>>>>>> following to work:
>>>>>>> 
>>>>>>> packageOverrides = pkgs:
>>>>>>>   { foo = "string";
>>>>>>>     bar = pkgs.foo + " concatenation";
>>>>>>>   };
>>>>>>> 
>>>>>>> However, it complains about foo missing.
>>>>>>> What am I missing?
>>>>>>> 
>>>>>>> Thanks,
>>>>>>> Mathijs
>>>>>>> _______________________________________________
>>>>>>> nix-dev mailing list
>>>>>>> nix-dev at lists.science.uu.nl
>>>>>>> http://lists.science.uu.nl/mailman/listinfo/nix-dev
>>>>>> 
>>>>>> 
>>>> _______________________________________________
>>>> nix-dev mailing list
>>>> nix-dev at lists.science.uu.nl
>>>> http://lists.science.uu.nl/mailman/listinfo/nix-dev
>>> 
>>> 
>> _______________________________________________
>> nix-dev mailing list
>> nix-dev at lists.science.uu.nl
>> http://lists.science.uu.nl/mailman/listinfo/nix-dev
> _______________________________________________
> nix-dev mailing list
> nix-dev at lists.science.uu.nl
> http://lists.science.uu.nl/mailman/listinfo/nix-dev


More information about the nix-dev mailing list