Dan Sugalski wrote:
At 2:03 PM -0400 10/11/04, Sam Ruby wrote:
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. :)
Yes, *but" we have to do that for any string PMC, not only for a Python string. *If* we are executing a Python module, the MMD("add", any_string, any_string) operation is concat.
In Python terms, __add__ is but one of several methods that strings have. Other common ones include index, join, lower, replace, and split.
In Ruby, "+" for String is is also a concatenation, and common methods include each, length, index, join, downcase, replace, and split. Note that the definition of index (search for a given substring) handles the case of "not found" differently than the similarly named Python function.
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)
No. I don't think that the "no matter what language" holds. Just the opposite. In a Perl module MMD("add", string, string) is C<+>, in a Python module its C<concat>. But these different functions occupy the same MMD slot.
z="a".__add__ print z("b")
... 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)
No chance AFAIK to fix that at code generation level:
def f(a,b): return a + b
There is absolutely no indication that, when strings are passed, it should do concatenation.
So again: if the code origin is Python, we have to do concat at runtime, *if* both argments are strings.
Lets make this more interessting:
def f(x): return x("d") def g(x): return f(x.index) print g("abcdefg")
The desired result is "3".
Do we want to go so far as "if the code origin in Python, then MMD("get_attr", string, "index") returns the Python str.index function bound to this instance?
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",;
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.
The question is, if we can afford do have different semantics.
I don't see how these problems can be solved in general at either code generation or runtime.
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.
Again: def f(a,b): return a+b
... 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 :)
It's of course a language issue. *But* if we want to run Python, we have basically two choices:
1) force Python coders to write "a".concat("b") with a language change
2) implement the MMD add function for strings, so that it acts differently depending on the code origin.
The latter minimizes the difference of String/PerlString/PyString to probably nothing.
Or we require a Python programmer to use the "str" function on any potentially foreigh object received as a parameter if they wish to depend on Python string semantics.
- Sam Ruby