Skip to content

Instantly share code, notes, and snippets.

@bennofs
Last active August 7, 2017 19:50
Show Gist options
  • Save bennofs/f9cffeb8f8320cd7a770d51e4a69e658 to your computer and use it in GitHub Desktop.
Save bennofs/f9cffeb8f8320cd7a770d51e4a69e658 to your computer and use it in GitHub Desktop.
Nix self/super override challenges. Solutions: https://gist.github.com/bennofs/65af82328bbd0c0e5db19d2a99070cc7
let
# Imports
nixpkgs = import <nixpkgs> {};
inherit (nixpkgs) lib;
inherit (lib) mapAttrs fix extends;
# Helpers
makeExtendable = base:
fix base // {
extend = f: makeExtendable (extends f base);
};
makeCalculated = description: expr: value:
"value of `${expr}` as observed by ${description} is: \n${value}";
# This is our base, it takes the role of `pkgs` in the following examples.
# `.extend` works the same as `.overridePackages` does for `pkgs`.
#
# The attributes of base are plain values instead of packages, since this is
# easier for illustration and you can better see what happens.
#
# `attr` represents a package without dependencies, while `calculated-attr` is
# like a package that depends on `attr`.
base = makeExtendable (self: {
attr = "base attribute";
calculated-attr = makeCalculated "base" "self.attr" self.attr;
_result = self.calculated-attr;
});
# Can you guess the value of the `._result` attribute for each of these sets without
# using a nix evaluator?
# (These are sorted alphabetically)
overridden = rec {
attr-base = base.extend (self: super: {
attr = makeCalculated "child" "base.attr" base.attr;
});
attr-base-calculated = base.extend (self: super: {
attr = "child attribute";
_result = makeCalculated "attr-base-calculated" "base.calculated-attr" base.calculated-attr;
});
attr-base-calculated-constant = attr-base-calculated.extend (self: super: {
calculated-attr = "grandchild calculated attribute";
});
attr-constant = base.extend (self: super: {
attr = "constant attribute value";
});
attr-self = base.extend (self: super: {
attr = makeCalculated "child" "self.attr" self.attr;
_result = "infinite recursion";
});
attr-self-calculated = base.extend (self: super: {
attr = "child attribute";
_result = makeCalculated "child" "self.calculated-attr" self.calculated-attr;
});
attr-self-calculated-constant = attr-self-calculated.extend (self: super: {
calculated-attr = "grandchild calculated attribute";
});
attr-self-constant = attr-self.extend (self: super: {
attr = "grandchild attribute";
_result = self.calculated-attr;
});
attr-super = base.extend (self: super: {
attr = makeCalculated "child" "super.attr" super.attr;
});
attr-super-calculated = base.extend (self: super: {
attr = "child attribute";
_result = makeCalculated "child" "super.calculated-attr" super.calculated-attr;
});
attr-super-calculated-constant = attr-super-calculated.extend (self: super: {
calculated-attr = "grandchild calculated attribute";
});
attr-union = base // { attr = "attr-union attribute"; };
};
# For each record, we get the value of the `value` attribute.
results = mapAttrs (key: s: s._result) overridden;
in results
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment