I'm having a bit of trouble parsing this. But as I write it out, I think I may have it.
let add = { __functor = self: x: x + self.x; };
inc = add // { x = 1; };
in inc 1
First, is self
a keyword like in many OO languages or is this just a regular name?
Secondly, I'm trying to understand what the multiple :
are doing in the definition of __functor
, but this is probably a failing of my basic familiarity with Nix expressions, but I guess what is happening is that both self
and x
are arguments to __functor
, i.e., it looks like it is probably a curried function.
So really, __functor
here is what fmap
would be in Haskell, I think, and self
(add
) is the functor itself, and x: x + self.x
is what the function mapped by fmap
would be in Haskell.
self
is not a keyword, just an ordinary parameter name. You are correct that the right-hand side of __functor
is a curried function of two arguments. The Nix interpreter ensures that __functor
is passed the appropriate value for self
, at the call site inc 1
; __functor
is handled specially, even though it's not a keyword per se.
Your example is nearly the same as:
let add = a: b: a + b
inc = add 1
in inc 1
In a larger program it might be useful to be able to override add.x
elsewhere.
As noted in the comments, Nix uses "functor" in the sense of an object (here, set) that can be used syntactically like a function.
Passing self
this way is Nix's version of "Objects are closures". The technique is used many places in Nixpkgs, with & without the __functor
feature, to get the usual benefits of Objects, including extension (~ structural subtyping) & late binding.