On 12/28/05, Nicolas Cannasse <[EMAIL PROTECTED]> wrote: > Neko will support continuations, since it makes a lot of sense to have > such feature handled at the VM level. It's just a matter of time. > Great.
> > I guess other alternatives would be to "roll out" the hierarchy by
> > having the "instance prototype" object for each Ruby class having the
> > correct neko function in each slot and instead updating all the
> > affected "instance prototype" objects when there is a method
> > changed/added. However, it is not clear what performance/mem
> > implications that solution will have. Is there any sharing between
> > (similar/copied/cloned) neko objects?
>
> Right now there is no sharing. When you $new(o) you allocate a new
> object with a table which is a copy of the "o" table.
>
I guess this can be discussed in the future since the mem overhead
might become prohibitive but for a long time that should not be a
concern so let's try to avoid premature optimization... ;)
> Here's a proposal similar to yours, but with method-sharing : the object
> store "instance fields" and the prototype store "class fields".
>
> proto = { f => function() { return this.msg; } };
> inst = { msg => "hello", __proto__ => proto };
> // call method
> protocall = function(inst,proto,method,args) {
> var m = $objget(proto,method);
> if( m == null ) {
> if( proto.__super__ == null )
> $throw("no method");
> return protocall(inst,proto.__super__,method,args);
> } else
> return $objcall(inst,m,args);
> }
> if( inst.f != null )
> inst.f() // overriden method
> else
> protocall(inst,inst.__proto__,$hash("f"),$array());
>
> This allow sharing, instance-specific overriding (since instance
> fields have priority on prototype fields) and chaining. However it does
> not allow transparent interoperability.
>
> One possibility I see to achieve transparent interoperability would be
> to be able to specify a "resolve" method when the field is not found :
>
> protoloop = function(proto,field) {
> var f = $objget(proto,field);
> if( f != null )
> return f;
> proto = proto.__super__;
> if( proto == null )
> return null;
> return protoloop(proto,field);
> }
> protoselect = function(field) {
> return protoloop(this.__proto__,field)
> }
> inst = {
> msg => "hello",
> __proto__ => proto,
> __resolve__ => protoselect
> };
>
> You'll notice that __resolve__ returns "null" when the field is not
> found. In next version of Neko, there is more runtime exceptions so for
> example a call on a value which is not a method with the correct number
> of arguments will raise an exception.
>
> __resolve__ looks like a good addition to the language, and it's nice to
> be able to have this supported by the VM. If this solution is satisfying
> for you I'll add it soon on NekoCVS.
>
Yes, this makes sense and makes it almost trivial to map Ruby's object
system. Your __resolve__ would be Ruby's method_missing, basically. In
general, I think it would be a good thing for Neko to support a
rudimentary prototype-based oo system since most OO systems can be
modeled on top of that.
Before seeing your proposal I toyed around with using MethodContext's
(mc in code below) with a rolled out version of the class hierarchy in
each MC. Turns out a core for the Ruby OO system can be done in 50-100
lines of Neko in this way. However, handling Ruby's method_missing
would mean adding a handler for that to each "unused" method field in
each MC which would work but be kind of awkward. Also with this
solution interoperability is hard of course. However, it allows the
following Ruby code:
-------
class Super
def s1
puts "s1a!"
end
end
class C < Super
def m1
puts "m1!"
end
end
c = C.new
c.s1 # Output: s1a!
c.m1 # Output: m1!
class Super
def s1
puts "s1b!"
end
end
c.s1 # Output: s1b!
-------
to be mapped to the neko code:
-------
if (Super == null) {Super = new_class_inheriting_from(Class);}
self = Super;
set_instance_method(self, "s1", function(self, args) {
$print("s1a!\n");
})
if (C == null) {C = new_class_inheriting_from(Super);}
self = C;
set_instance_method(self, "m1", function(self, args) {
$print("m1!\n");
})
c = [EMAIL PROTECTED](C, EA);
[EMAIL PROTECTED](c, EA);
[EMAIL PROTECTED](c, EA);
if Super == null {Super = new_class_inheriting_from(Class);}
self = Super;
set_instance_method(self, "s1", function(self, args) {
$print("s1b!\n");
})
[EMAIL PROTECTED](c, EA);
------
and has sharing of the MC's. However, the indirection in each method
call and having to send self is awkard...
I like your solution with __resolve__ but worry that neko will have to
continue adding things to support other OO systems / languages in
order to support a simple mapping. This might make the core language
harder to understand and the implementation more complex?! Something
to look out for at least...
Thanks,
Robert
ruby_core.neko
Description: Binary data
--- Neko : One VM to run them all
