Closure/method discrepancy...

victor_yurkovsky 7dreamer at
Wed Dec 19 20:51:53 UTC 2001

Jecel, thank you for a quick response.  

Firstly, I have no problem with the cloning of the activation 
records, etc.  That makes total sense.
I do have issues with lexical scoping in interpreted environments 
generally, and especially with pure object-oriented languages.  Other 
than the lexical issues, self is a clear gem.

My problem starts with self curtailing the lifespan of closures to 
the enclosing method.  Although it saves the implementation from 
dealing with moving activation records off the stack, it cripples the 
language.  I very much like the idea of passing closures around and 
sticking them into slots.

Also, at the risk of getting off-topic, I need to get to the bottom 
of the closure/method issue.  Once again, apologies for not being up 
on self.  This is the way I envision the ideal OO language (and self 
is really close...)

1) There is an environment supporting objects.
2) Objects contain slots and a piece of code.
3) Each slot consists of a name and a pointer to another object.  The 
name dynamically binds the referenced object and allows code to refer 
to it.
4) The code is in some manner human-modifiable and executable by the 
machine (ignore implementation details here).
5) Through code, the environment can modify both the shape of an 
object (number and naming of slots) as well as the contents of the 
6) Object visibility: The topology of an object, at run-time, defines 
the visibility of objects other than those referenced by its own 
slots (dynamic scoping of objects).  The name-binding process is 
equivalent to a search of named slots, starting at the object in 
question, followed by objects referred to by its slots, etc (somehow 
avoiding loops).

This seems to roughly describe an object-oriented environment capable 
of supporting a decent language.  Now the details of interpretation I 
am not solid on right now, but there are a few ways of doing it:

- Find the target object by name - search proceeds as in 6) above.
- Execute its code, returing the target reference.  
- Find the 'message' withing the dynamic scope of the target object.  
If present, evaluate it with whatever parameters.

Sending a 'no message' message returns the value (equivalent to the 
execution of a method, sending 'value' to a block or fetching a data 
slot).  Note that an object can be referred to by more than one name 
if it's bound to more than one slot.

For example, let's say we have an object foo with slots named A B and 
C.  We can assign an integer 4 to A; a method [A * 2] to B; and a 
closure myClosure to C.  Now, there is no difference between blocks 
and method, eh?  The code is completely decoupled from any bindings 
until runtime.

This arrangement has several benefits over the smalltalk/self model: 
you can totally redirect objects to proxies, or do anything at all at 
the point of lookup and closures are in fact real objects.

	bar.  (returns the result of evaluating an object at a slot 
name bar in self or above).
	bar increment. (returns the result of evaluation of an object 
at the slot named 'increment' found at or above an object at the slot 
named 'bar' in self or above).
	bar := 4 (send := 4 to the object at a slot named 'bar' in 
self or above)...

Sorry about the rambling, but I've been thinking about this for too 
long the wrong way, and the recent brush with self is beginning to 
clear my head (but it's not quite clear yet...)

More information about the Self-interest mailing list