At 2:03 PM -0400 10/11/04, Sam Ruby wrote:
Dan Sugalski wrote:

At 4:23 PM -0400 10/9/04, Michal wrote:

On Sat, 9 Oct 2004, Sam Ruby wrote:

 Inheritance can reduce the combinatorial problem, but it can introduce a
 precendence question.  The most interesting case still seems to be:

mmd_lookup(MMD_ADD, PerlString, PyString)

What if, as a fallback mechanism, the foreign object were cast into a simpler type? The PyString could just have a marker on it that says it should be downcast into a native string (or ParrotString) in cross language situations. You could do the same for all the basic types.

That way, if you evaluate $perlString + $pyString
in perl, you get perlish behavior, and if you
evaluate perlString+pyString in python, you get
pythonic behavior.

This, I think, is something I'd prefer to not do. An operation should behave identically regardless of the language that's performing the operation. The alternative, a separate and distinct op, is probably a better option here, though that's got issues as well.

Separate op won't work for Python. Consider:

  def f(x,y): return x+y
  print f(5,6)     # 11
  print f("a","b") # ab

Oh, sure it'd work, if you had an ADD_OR_CONCATENATE op with an appropriate MMD table. :)


Still, the downside is that you'd like:

    a + b

to do the same thing no matter what language emitted the code. (Though arguably perl's + is the same as, say, a lisp +, but different from a VB/Python +, they just happen to have the same sigil)

Also:

  def f(x,y): return x.__add__(y)
  print f(5,6)     # 11
  print f("a","b") # ab

In fact, it gets stranger. Methods can be detached from their classes and accessed as functions:

  print int.__add__(3,4)
  z="a".__add__
  print z("b")

Ah, I get stranger things than that with my breakfast cereal. (Which is one of the reasons I tend to have a bagel for breakfast, but that's neither here nor there) That's not actually a big problem, though it's something we'd *definitely* want to wedge into the code generator. (One of those places where dealing with the AST is a lot nicer than dealing with the bytecode)


With AST access, the z="a".__add__ would end up with code to check for an __add__ method and if found create an anonymous method closure PMC for z. Invoking z invokes the closure, sets up the object slot, and makes the method call as it ought. (Whether it should go search the hierarchy when bound or invoked is a separate thing)

Then there's the question of what things that aren't base types should do. Should PyString+RubyObjectWhichIsAString do concatenation or addition? And how exactly would you tell if the object really is a string or not? (And what about objects that are multiple things simultaneously -- that is, should behave as a string and a number)

We are going to find a lot of surprises. In Perl 5, hashes can only be indexed by strings. In Python, anything that contains a __hash__ method may be used as an index. At the moment Parrot's PerlString doesn't have a hash method.

Yeah. Perl 6 is opening that one up, and it's one of the reasons that each element in a key structure is tagged with both its actual and intended type. (Though that's not as yet exposed)


Here's a script that will run in both Python and Perl. It simply will return different results.

  print "1" + "2"        ,"\n",;
  print "45%s8" % "7"    ,"\n",;
  print 45 / 7           ,"\n",;
  print ['a','b','c']    ,"\n",;
  print ['a'] + ['b']    ,"\n",;
  print 9 + None         ,"\n",;

Yep, though in part because "1" gets turned into a PerlString by the perl compiler and a PythonString by the python compiler, with different semantics.


This is a barrel 'o worms, no doubt. Luckily I don't have to care, as such, since it's a language issue. (Though I do have to care about providing the mechanisms to make it not only possible but actually easy to do, but that's not too tough. The tough part's making it so that language implementers find it easier to do it in the way that makes interop easy than do it the hard way :)

But actually, my recommendation is that we don't go that far yet. Yesterday, I coded up a number of python pmcs:

  pyboolean.pmc  pyfloat.pmc  pylist.pmc  pyobject.pmc  pytuple.pmc
  pydict.pmc     pyint.pmc    pynone.pmc  pystring.pmc

Actually, when I say "coded", all I did was copy some existing pmcs and made minimal changes (global renames, removed the checks for PARROT_PYTHON_MODE by making such paths the defaults, added some get_repr implementations, and some minor tweaks like making integers no longer promote to floats).

While I got a version of Pirate to work with these new classes, the result feels a bit like cheating. What I would like to do is to evolve this into a complete Python object model, focusing first on being a faithful implementation of Python, initially at the expense of interlanguage interop.

Seems like the right thing to do to me. -- Dan

--------------------------------------it's like this-------------------
Dan Sugalski                          even samurai
[EMAIL PROTECTED]                         have teddy bears and even
                                      teddy bears get drunk

Reply via email to