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
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")
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.
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",;
I think we may want to think about multiple inheritance for PMC classes and add in some basic attribute types to inherit from. (Like Stringish, Intish, FloatIsh, BigNumish, Booleanish, to denote things that should be considered strings or whatever, rather than just having a string representation)
A first approximation might be to define a ParrotString with minimal methods, and allow each language to subclass it and add additional behavior.
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.
Once enough of that is in place, we can start to explore what it would take to make interop more of a reality. And how to structure the code so that things like Python and Perl support could be a shared library that is only loaded when the application requires it.
- Sam Ruby