Jeff Clites wrote:
On Nov 3, 2004, at 8:09 AM, Dan Sugalski wrote:

At 11:04 AM -0500 11/3/04, Sam Ruby wrote:

A single pow_p_p_p op backed by a (non-MMD) vtable entry would make it easier to support code like the following:

  def f(x): return x**3
  print f(3), f(2.5)


Yeah, it would. I know I'm going to regret asking, but... any reason *not* to make it MMD? (Though I have no idea what happens if you square a matrix)

I feel like we have op-itis and vtable-itis. I would think that rather than a pow_p_p_p, you'd compile "x**y" as something like:


set N0, P0
set N1, P1
pow N2, N0, N1
new P2, .PythonNumber
assign P2, N2

I.e., PMCs don't inherently exponentiate--numbers do, and you can exponentiate PMCs by numberizing them, exponentiating, and creating a PMC with the result.

Or, if we must have an op, implement it something like this (without needing a new vtable entry, or MMD):

inline op pow(out PMC, in PMC, in PMC) :base_core {
  $1 = pmc_new(interpreter, $2->vtable->type(interpreter, $2));

  $1->vtable->set_number_native(interpreter, $1,
             pow( $2->vtable->get_number(interpreter, $2),
                 $3->vtable->get_number(interpreter, $3)))

  goto NEXT();
}

Those would probably JIT to about the same thing, given register mapping.

This is the viewpoint that pow() isn't a fundamental operation that makes sense for all types; it's a numeric operation, which can be extended in a straighforward manner to types which know how to represent themselves as numbers. (e.g., it's gibberish to raise a ManagedStruct to a ParrotIO power, except that you can stretch and interpret such a thing as just implicit num-ification of the arguments.)

From a Python or Ruby language perspective, infix operators are not fundamental operations associated with specific types, they are syntactic sugar for method calls.


A the moment, I'm compiling x=y**z into:

    x = y.__pow__(z)

There is nothing "reserved" about the name "__pow__". Any class can define a method by this name, and such methods can accept arguments of any type, and return objects of any type. They can be called explicitly, or via the infix syntax.

What's the downside of compiling this code in this way? If you are a Python programmer and all the objects that you are dealing with were created by Python code, then not much. However, if somebody wanted to create a language independent complex number implementation, then it wouldn't exactly be obvious to a Python programmer how one would raise such a complex number to a given power. Either the authors of the complex PMC would have to research and mimic the signatures of all the popular languages, or they would have to provide a fallback method that is accessible to all and educate people to use it.

Ultimately, Parrot will need something akin to .Net's concept of a "Common Language Specification" which defines a set of rules for designing code to interoperate. A description of .Net's CLS rules can be found in sections 7 and 11 (a total of six pages) in the CLI Partition I - Architecture document[1].

- Sam Ruby

[1] http://msdn.microsoft.com/net/ecma/

Reply via email to