I’ll make this statement.
- Overlay is anonymous class.
- Overlay list is inheritance chain of anonymous classes.
-
self
reference is used to call virtual methods and virtual getters. It is calledthis
in Java,self
in Python. -
super
is reference to parent class. It is calledsuper
in Java,base
in C#
Is it? Am I missing something?
Details
The overlay list
[
(self: super: { callPackage = a: b: { _type = "derivation"; override = x: x; }; })
(self: super: { package1 = super.callPackage ./package1.nix {}; })
(self: super: { package2 = super.callPackage ./package2.nix {}; })
(self: super: { package1 = super.package1.override { inherit (self) package2; }; })
]
is translated into following Java code:
class Derivation { ... }
class Overlay1 {
public Derivation callPackage(.. a, ... b) {
return new Derivation(...);
}
}
class Overlay2 extends Overlay1 {
private Derivation package1 = null;
public Derivation getPackage1() {
if (package1 == null) {
package1 = super.callPackage(..., ...);
}
return package1;
}
}
class Overlay3 extends Overlay2 {
private Derivation package2 = null;
public Derivation getPackage2() {
if (package2 == null) {
package2 = super.callPackage(..., ...);
}
return package2;
}
}
class Overlay4 extends Overlay3 {
private Derivation package1;
public override Derivation getPackage1() {
if (package1 == null) {
Map<> overrides = new HashMap<String, Derivation>();
overrides.put("package2", this.getPackage2());
package1 = new Derivation(super.getPackage1(), overrides, ...);
}
return package1;
}
}
In Java case, the “overlay chain” is instantiated with new Overlay4()
, and for Nix it is simply
overlay_list: fix (self: foldl (acc: f: acc // f self acc) overlay_list)
Java is superior
Haha, but consider previous example with rows 3 and 4 flipped:
[
(self: super: { callPackage = a: b: { _type = "derivation"; override = x: x; }; })
(self: super: { package1 = super.callPackage ./package1.nix {}; })
(self: super: { package1 = super.package1.override { inherit (self) package2; }; })
(self: super: { package2 = super.callPackage ./package2.nix {}; })
]
It would be valid Nix overlays (and run well), but Java compiler will warn you about using getPackage2
before it is declared.
Java has to use reflection to overcome this compile-time restriction:
# call yet unknown virtual method
this.getClass().getMethod("getPackage2").invoke(this)