[Nix-dev] variable scope / recursion

Shea Levy shea at shealevy.com
Fri Jul 6 14:23:05 CEST 2012


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


More information about the nix-dev mailing list