I'm responding to the question, "So how do I code up addition, or anything where you want to take arguments other than this?", from http://calculist.blogspot.com/2005/06/classicjavascript.html --- with regard to Abadi and Cardelli's object calculi.
This is explained in a slightly different notation than Abadi and Cardelli use for their object calculus. I'm leaving out the syntactic sugar I usually use in order to keep this explanation simple for those who haven't read Abadi and Cardelli. {} is an object with no methods. self.foo = self.bar + 1 is a method whose definition is "call bar on the same object, then add 1." Abadi and Cardelli write this as "foo = sigma(self) self.bar + 1". x.foo = x.bar + 1 is the same method (or, if you prefer, another method that behaves identically.) This expression lexically binds the name 'x' within the method definition to the "self" parameter --- the object the method is called on. x{ self.foo = self.bar + 1 } is an override expression; it means "an object exactly like x, except that it has this new foo method," which is defined as above. I'll separate methods inside objects or override expressions with newlines or commas. I've also added new methods to objects in override expressions without restraint; you can rewrite this code so that it only ever overrides existing methods, as in Abadi and Cardelli's work, without much effort, simply by adding useless method definitions in objects whose descendants do this. So here are booleans: { booleans.true = { self.negated = booleans.false self.ifTrue = { x.then = 1, x.else = 0, x.val = x.then } self.ifFalse = self.negated.ifTrue } booleans.false = booleans.true { self.negated = booleans.true self.ifTrue = booleans.ifTrue { x.val = x.else } } } If "hungry" is a variable that might be one of booleans.true or booleans.false, we can say hungry.ifTrue{ x.then = "eat", x.else = "don't eat" }.val Suppose hungry is the above 'true'. This resolves to { self.negated = booleans.false self.ifTrue = { x.then = 1, x.else = 0, x.val = x.then } self.ifFalse = self.negated.ifTrue }.ifTrue{ x.then = "eat", x.else = "don't eat" }.val and then { x.then = 1, x.else = 0, x.val = x.then }{ x.then = "eat", x.else = "don't eat" }.val which reduces to { x.then = "eat", x.else = "don't eat", x.val = x.then }.val Which resolves to 'x.then', with 'x' being the above-constructed object whose 'then' is defined as "eat". Supposing instead that hungry were 'false'; instead we get booleans.true { self.negated = booleans.true self.ifTrue = booleans.ifTrue { x.val = x.else } }.ifTrue{ x.then = "eat", x.else = "don't eat" }.val If we expand out the booleans.true here, we get { self.negated = booleans.false self.ifTrue = { x.then = 1, x.else = 0, x.val = x.then } self.ifFalse = self.negated.ifTrue }{ self.negated = booleans.true self.ifTrue = booleans.ifTrue { x.val = x.else } }.ifTrue{ x.then = "eat", x.else = "don't eat" }.val And then if we evaluate the first override expression, we get { self.negated = booleans.true self.ifTrue = booleans.ifTrue { x.val = x.else } self.ifFalse = self.negated.ifTrue }.ifTrue{ x.then = "eat", x.else = "don't eat" }.val since the only method from 'true' not overridden in 'false' is ifFalse. Now we can evaluate the .ifTrue method call and get: booleans.ifTrue { x.val = x.else }{ x.then = "eat", x.else = "don't eat" }.val which expands out to { x.then = 1, x.else = 0, x.val = x.then }{ x.val = x.else }{ x.then = "eat", x.else = "don't eat" }.val We can collapse the first override and get { x.then = 1, x.else = 0, x.val = x.else }{ x.then = "eat", x.else = "don't eat" }.val and then the second, and get { x.then = "eat", x.else = "don't eat", x.val = x.else }.val And that reduces to just 'x.else', which is defined as "don't eat". This is exactly the same as the last reduction step for when hungry was 'true', except that we inherited a different definition for 'x.val'. Now, for numbers. A real implementation of this object-calculus on a computer would use the CPU's rapid number-handling machinery rather than implementing its own math primitives, and the method I am about to explain is a terribly inefficient way of implementing them anyway; its purpose is to demonstrate that the object-calculus can theoretically perform any computable computation on its own. The following technique is just a transliteration of the lambda-calculus's Church numerals. Here's an object containing numeric primitives; I assume the earlier booleans object is available under the name 'booleans'. { numbers.zero = { self.isZero = booleans.true self.plus = numbers.sum { x.firstArgument = self } self.succ = self { succ.isZero = booleans.false succ.pred = self } } numbers.lessThan = { self.firstArgument = numbers.zero self.secondArgument = numbers.zero.succ self.val = self.secondArgument.isZero.ifTrue { x.then = booleans.false x.else = self.firstArgument.isZero.ifTrue { x.then = booleans.true x.else = numbers.lessThan { child.firstArgument = self.firstArgument.pred child.secondArgument = self.secondArgument.pred }.val }.val }.val } numbers.sum = { self.firstArgument = numbers.zero.succ self.secondArgument = numbers.zero.succ self.val = self.firstArgument.isZero.ifTrue { x.then = self.secondArgument x.else = self { child.firstArgument = self.firstArgument.pred }.val.succ }.val } } The above definitions should evaluate numbers.zero.succ.succ.succ.plus { x.secondArgument = numbers.zero.succ.succ.succ.succ }.val to the same thing as numbers.zero.succ.succ.succ.succ.succ.succ.succ. But I may have made a mistake. So the short answer is that methods often return an object not derived from self, but some of whose method definitions are closed over self. As I've implied previously (in "functional programming for amateurs in an outliner", before I read Abadi and Cardelli's book --- thank you David Gibson!) I think this is the theoretical underpinning for dramatically more usable and productive programming environments. Links: > Abadi and Cardelli's object calculus is described in the first three pages of "A Theory of Primitive Objects" at http://research.microsoft.com/Users/luca/Papers/PrimObj1stOrder.pdf > "functional programming for amateurs in an outliner" is at http://lists.canonical.org/pipermail/kragen-tol/2002-May/000713.html > "towards a modern programming environment" is at http://lists.canonical.org/pipermail/kragen-tol/2003-May/000745.html > Also related is Jonathan Edwards' Subtext: http://subtextual.org/ > And Wouter van Oortmerssen wants "abstractionless programming", the same thing: http://lambda-the-ultimate.org/node/view/17 > And Dynamic Aspects' "domain/object" platform seems to be a larger idea including the same kernel: http://www.dynamicaspects.com/