I’ll make this statement.
- Overlay is anonymous class.
- Overlay list is inheritance chain of anonymous classes.
selfreference is used to call virtual methods and virtual getters. It is calledthisin Java,selfin Python.superis reference to parent class. It is calledsuperin Java,basein 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)