Sunday, March 26, 2006

More unfinished musings

So if a dispatch function/closure represents an object, then around-advice on the dispatch function is extending an object. Can a closure be cloned using primitives in Scheme? If so, then closures + aspect-oriented programming == prototype-based object system. The downside to the closure object system is that code is not shared. For cases where the clone dag is deep (large with a small branching factor), not sharing code is a good thing. For cases where the clone dag is wide (large with a large branching factor), sharing code is a good thing. How does one decide which slots will behave like class slots and which slots will behave like instance slots in the clone? Does the closure object necessarily need the concept of a slot at all? It could all be defined in terms of reactions to messages, some of which appear to cause state changes in the object. How does Prometheus handle this? Speaking of, a type could be defined either in terms of the clone dag, where children of a node are types; or type could be defined purely in terms of the interface supported by an object (if it looks like a duck, walks like a duck, quacks like a duck...). What kind of type safety optimizations can be made in a prototype-based language? Is it reasonable to be able to freeze changes to the clone dag in order to optimize method dispatch and slot mutation? Can freezing easily be undone, allowing the developer to resume modifying the objects in the dag interactively? Hmm...

Saturday, March 25, 2006

Unfinished thoughts on object systems

Prototype-based object systems, plus aspect-oriented programming, plus multiple dispatch generic functions... hmm... The naive way to implement method dispatch and slot access in prototype-based object systems is to chain-up to the original object when a clone doesn't understand a message. This means potentially several indirections if the clone-chain is deep. Some language I saw recently claimed to be able to do single-dispatch method invocations using a maximum of three indirections. Hygenic mix-ins require lexical closures. If you have a mix-in that modifies the behaviour of an object and requires keeping additional state, you need to be positive that your state-keeping slot doesn't clash with an existing slot. It seems like method invocation could be called "resume environment", where the object represents an environment, that is, a set of bindings. In the multiple-dispatch generic function case, method specializers are real, actual objects, specifying a node in the clone tree. All the progeny (objects created by cloning) of the specializer object are considered subclasses of the progeny. Some support should be built programmatically for moving methods and slots around in the tree. This implies that methods are first-class objects. This is also necessary because adding advice to a function requires having access to the function object. This implies that behaviour is somehow external to objects, which seems to contradict the prototype-based system; unless some provision for "cloning" methods exists, and this sounds a lot like aspect-orientation: orthogonal extensions to behavior. What if they're not orthogonal, but more like behavioral mixins? You'd like to be able to replace, not just augment behavior. It would be really nice to do this in scheme in 10 lines using closures. What does a MOP look like for prototype-based object system? Unfinishedness...