multi sub *infix:<-> (MyInt $left, int $right) {mysub($left, $right)}
multi sub *infix:<-> (int $left, MyInt $right) {myrsub($right, $left)}
The first one would create a MMD function variant of
sub_p_p_i or Pleft."sub"(Iright, Pdest)
or Pdest = Pleft."sub"(Iright)
ok so far. The "PMC type" for the natural int is currently just zero.
But it could be less hackish, if we just reserve three distinct type
numbers for the namespace of these natural types.
The second one is harder. We don't have an opcode
sub_p_i_p
directly. But with the method call syntax the assembler could generate,
it would boild down to:
P_int_namespace."sub"(Pright, Pdest)
where the P_int_namespace is the placeholder class for the MMD lookup of
the natural int. Sounds doable too.
But what about an arbitrary user multi sub, e.g.:
multi sub *foo (MyInt $a, MyInt $b, int $c)
multi sub *foo (MyInt $a, int $b, MyInt $c)
The assembler can create a prototyped call to a MMD "foo" function:
set I0, 1 # prototyped
set I1, 1 # 1 I arg
set I2, 0 # 0 S
set I3, 2 # 2 P args
set I4, 0 # 0 N
call_MMD_3 "foo" # ???
or a method call on the first arg. But whatever we do, the function
signature at the PASM level is the same for the first "foo" and the
second one. We have lost the order of arguments, which is essential to
find the appropriate MMD function or method.
Comments?
leo
1) Anything that is unary (i.e., contains exactly or one argument) is
not affected by MMD. There is no need to replace any such methods.
2) While I don't see Python translators using a "sin" opcode, I can see
the implementation of Math.sin doing a VTABLE_sin(INTERP,value).
3) My biggest problem with the runtime introducing methods is that
language semantics vary. Here's a concrete example: both Ruby and
Python have methods named "index" on string. Ruby returns C<nil> if not
found. Python throws C<value_error> if not found.
String."replace" may be an even better example. Ruby and Python's
methods by this name don't mean the same thing or even have the same
signature.
- - -
Overall, for any non-trivial method, I think we are looking at a double
dispatch: first to the language specific "wrapper", and then to the
common code which backs it. There are advantages and disadvantages to
making the dispatch methods the same. Ultimately, if they are the same,
the names should be picked in a way that minimizes the possibility of
collisions. If they differ, no such possibility exists.
- Sam Ruby
> 1) Anything that is unary (i.e., contains exactly or one argument) is
> not affected by MMD.
That's not quite true. We currently have just infix MMD dispatching on
left and right. That's just a specialized version. S13 has e.g.
multi method prefix:<+> ...
multi method prefix:<~> ...
when I translate that it boils down to:
obj."__get_number"()
obj."__get_string"()
(But there isn't much "multi" on such dispatch, that's right ;)
Anyway the current (2-dim) MMD system is really static. Overriding one
operator doesn't effect any class that inherits from it.
> ... There is no need to replace any such methods.
I haven't stated to get rid of these vtables. I've said that for
function dispatch these should be equivalent for plain PMCs and objects.
While we support above methods aready, we have an extra meta-class
(delegate) to dispatch correctly to the overloaded operator.
> 2) While I don't see Python translators using a "sin" opcode, I can see
> the implementation of Math.sin doing a VTABLE_sin(INTERP,value).
Well, a vtable is a static construct. Having VTABLE_sin (and others)
forces all 100 (or whatever) PMCs and objects to have a vtable slot for
it.
> 3) My biggest problem with the runtime introducing methods is that
> language semantics vary. Here's a concrete example: both Ruby and
> Python have methods named "index" on string. Ruby returns C<nil> if not
> found. Python throws C<value_error> if not found.
Fine. We have e.g. PyString isa String and RbString isa String.
METHOD index() { METHOD index() {
res = SUPER() res = SUPER()
if (res < 0) if (res < 0)
raise ... return RbNil
This is exactly what methods are for.
> String."replace" may be an even better example. Ruby and Python's
> methods by this name don't mean the same thing or even have the same
> signature.
Doesn't really matter.
> Overall, for any non-trivial method, I think we are looking at a double
> dispatch: first to the language specific "wrapper"
Mehods can call each other and parent methods.
> ... There are advantages and disadvantages to
> making the dispatch methods the same.
Why?
> ... Ultimately, if they are the same,
> the names should be picked in a way that minimizes the possibility of
> collisions. If they differ, no such possibility exists.
Why? Px."foo"() and Py."foo"() can be totally different things, if the
classes of Px and Py differ.
> - Sam Ruby
leo