Closure/method discrepancy...
victor_yurkovsky
7dreamer at usa.net
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
slots.
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