On Nov 8, 2004, at 12:50 AM, Leopold Toetsch wrote:

Jeff Clites <[EMAIL PROTECTED]> wrote:
On Nov 5, 2004, at 9:40 AM, Leopold Toetsch wrote:

In Python, semantically you know that you'll end up doing a method call
(or, behaving as though you had), so it's very roundabout to do a
method call by using an op which you know will fall back to doing a
method call. Clearer just to do the method call.

No. The binary operations in Python are opcodes, as well as in Parrot. And both provide the snytax to override the opcode doing a method call, that's it.

I guess we'll just have to disagree here. I don't see any evidence of this from an API/behavior perspective in Python. I think the existence of a separate Python opcode is just a holdover from a time when these infix operators only existed for built-in types (just inferring this). I can't find any case where Python would act differently, if these were compiled directly to method calls. And for Ruby, it's *explicit* that these "operators" are just method calls. And languages like Java don't have these operators at all, for objects.


The only thing that's special is that there are certain built-in
classes, and some of them implement __pow__, but that's not really
anything special about __pow__.

Yes. And these certain *builtin* classes have MMD functions for binary opcodes.

Not actually MMD in Python--behavior only depends on the left operand, it seems.


And even the ops we currently have are broken semantically. Consider "a
= b + c" in Python. This can't compile to add_p_p_p, because for that
op to work, you have to already have an existing object in the first P
register specified. But in Python, "a" is going to hold the result of
"b + c", which in general will be a new object and could be of any
type, and has nothing to do with what's already in "a".

That's a totally different thing and we have to address that. I have already proposed that the sequence:

   null dest
   dest = l + r

should produce a *new* dest PMC. That's quite simple. We just have to
pass the address of the dest PMC pointer instead of the PMC to all such
operations. Warnocked.

Yes, it's a separate issue, but it's pointing out a general design problem with these ops--their baseline behavior isn't useful. The result of "l + r" will not depend on what's to the left of the "=" by HLL semantics, for any case I can think of. (Perl cares about context, but that's not really the same thing.)


... I think
we should create PMC-based ops only if one of the following criteria
are met: (a) there's no other reasonable way to provide some needed
functionality,

So, this is already a perfect reason to have these opcodes with PMCs.

  a = b + c

behaves differently, if b and c are plain (small) integers or
overflowing integers or complex numbers and so on. You can't provide
this functionality w/o PMCs.

I don't understand this example. Certainly you need PMCs, but if b and c are I or N types, of course you'd use add_i_i_i or add_n_n_n, but for PMCs this could compile like "a = b.plus(c)". Of course you have to know I v. N v. P at compile-time, and there's no reason that I/N v. P pasm must look identical, for similar-looking HLL code. You need PMCs, but you don't need add_p_p_p, just method invocation.


For complex numbers and such, I'd want to be able to define classes for them in bytecode. For that to work, ops would eventually have to resolve to method calls anyway. (You can't create a new PMC and vtable/MMDs in bytecode.) Why not skip the middle-man?

JEff



Reply via email to