From: [EMAIL PROTECTED]
   Date: Thu, 28 Aug 2008 12:43:20 -0700 (PDT)

   Author: allison
   Date: Thu Aug 28 12:43:19 2008
   New Revision: 30622

I've not responded to all your comments, just some of the key ones that
I hope will promote understanding.  I won't commit any changes until
after I hear what you have to say.  (Some of the hunks have been
reformatted for readability.)

   @@ -41,6 +41,13 @@
    case, some translation may be required by both the calling language and the
    called language:

   +{{ There seems to be an implied basic assumption here that language
   +interoperability is the responsibility of the language
   +implementor. It is not.  We cannot require that language
   +implementors design and implement their languages according to some
   +global specification.

If you are not happy with that assumption, then I'm surprised you
bothered to commit this draft at all, even as a starting point.  Even
then, surely, it must *still* be the responsibility of the language
implementor not to introduce gratuitous barriers to interoperability?

   As a case in point, consider keyword (named) parameters in Lisp.
Kea-CL does not use Parrot named parameters to implement "&key", partly
for ANSI compliance and partly for efficiency.  This currently makes it
problematic (though not impossible) for other languages to call Lisp
functions that accept keywords.  You can either say I'm a bad boy for
not fully using Parrot features and "require" me to "design and
implement ... according to some global specification," forcing me to
solve the performance vs. compliance vs. interoperability tradeoff in
each sub, or allow me to do my own thing internally and accept the need
for glue around the edges (which in turn requires compliance with
another specification).

   Another example is object system metamodel compatibility.  I am not
an expert on metamodels, but all the ones I *think* I know make it very
hard for me to imagine inheritance across language boundaries without
some very careful design and coding on the part of language implementors
on both sides of the boundary.  (Who will no doubt be grateful for "some
global specification" to help them in that work.  ;-)

   +Any interoperability
   +infrastructure must be provide by Parrot, and must work for all languages.
   +--allison }}

Do you really think that Parrot can subsume all object system metamodels
well enough to provide all the infrastructure?  Just the CLOS and Perl 6
MOPs are each complicated enough on their own; I'm tempted to advocate
$n^2$ metamodel interfaces in order to break the problem down into
manageable chunks.  (And, not incidentally, push the problems onto the
people who understand them.)

   @@ -117,6 +132,8 @@
    call intra-language subs, they should be very sure they understand that
    language's calling conventions.

   +{{ It's not possible to define a sub that can't be called externally 
--allison }}

Not now, true.  Except that we currently support ".sub foo :anon ..."
for compilation-unit scoping.  Are you saying you object to language
scoping of subs?

   @@ -139,13 +156,22 @@
    access the module API (though it may need additional hints).  Of course, 
that
    also requires a PIR API for accessing this metainformation . . .

   +{{ Exporting is very much a Perl idea, not much applicability for exporting
   +outside of Perl. --allison}}

Eh?  I think we are having another terminology issue.  By "export" I
meant "make public."  Perl is not the only language to use this term;
just off the top of my head I can think of CL and Erlang.

   @@ -175,6 +201,10 @@
    functions, i.e. a method defined for C<VECTOR> must be considered when 
passed
    a string as a parameter.

   +{{ Common Lisp (for example) will have its own set of type relationships,
   +because it will have its own set of types . . .

I *could* represent CL strings explicitly as vectors of characters
instead of using the String type.  But that would mean that I couldn't
use the wealth of Parrot string ops, and would be inviting more
interoperability problems to boot.  Ditto for Integer and Float, which
are exactly what I need in terms of representation.  CL does not need
new types for these.  And that is a good thing.

   @@ -235,6 +275,12 @@
    floating-point result from Common Lisp code that happens to get two integers
    from Perl or Lua (or both!).

   +{{ Not a bug, it's the expected result. Divide operations are 
multi-dispatched.
   +If you pass two Common Lisp integers into a divide operation in Perl 5, 
it'll
   +search for the best matching multi, and if it finds one for Common Lisp
   +integers (an exact match), it'll run that and return a Common Lisp ratio.
   +--allison }}

We are at an impasse, then.

   But I suppose it doesn't matter.  If language implementers believe
that is OK, then they can accept whatever the builtin returns.  If not,
they can use MMD to define any exceptions they require.

   @@ -242,6 +288,10 @@
    inputs to these operations differently; they can all be represented by the
    same C<Integer> PMC class.

   +{{ The whole point of having sets of PMCs in different languages is to 
handle
   +the case where "it's an integer, but has a different division operation than
   +other languages" --allison}}

You are not persuaded by my argument that PMC classes are about
representation, and "multi variants" are about operation semantics?

   In any case, language-specific PMC classes are not needed for this
purpose, only language-specific operations.

   @@ -278,6 +331,10 @@
    specialize the other operands, in the hope that other exotics are subclasses
    of these.

   +{{ It is perfectly fine for a Lisp arithmetic operator to return a RATIONAL
   +subtype. Please don't define methods for a pile of operations that already 
have
   +vtable functions --allison }}

When I said "methods" here, I was actually speaking of defining "multi
variants" for that Lisp arithmetic operator.  Does that help?

   @@ -287,10 +344,18 @@
    responsibility of the language that defines the exotic class, since it is in
    charge of its internal representation.

   +{{ The default multi for a common operation like division will call the 
PMC's
   +C<get_number> vtable function, perform a standard division operation, and
   +return a standard Integer/Number/BigNum. --allison }}

???  C<get_number> always returns a float, which would force the answer
to be a float (in all languages I can think of).  But, yes, this is a
reasonable default.

    {{ We can define multimethods on another language without loading it, can't
    we?  If not, then making this work may require negotiation between language
    implementors, if it is feasible at all.  -- rgr, 31-Jul-08. }}

   +{{ I'm not sure what you mean by defining multimethods on another language.
   +Perhaps you're asking if it's possible to declare a multisub for a type that
   +doesn't exist yet?  --allison }}

I would like to be able to define a "multi variant" on another language
that handles my language's types, without loading the other language, so
that *if* the other language is ever loaded, it handles the new types
gracefully.

   @@ -301,20 +366,31 @@
    Define language-specific operations using multimethods (to avoid conflict 
with
    other languages).

   +{{ Clarify? How would non-multi's conflict?  --allison }}

Method dispatch is done by string lookup on the operation name; there
are no package names to bind the operation to a language implementation.

    =item 2.

    Define them on the highest (most general) possible PMC classes (in order 
that
    they continue to work if passed a subclass by a call from a different
    language).

   +{{ Define them on the class that makes sense. There's no point in targeting 
any
   +particular level of the inheritance hierarchy. --allison }}

Yes, but I'm trying to explain what makes sense.  But I'll add "... the
highest ... PMC classes that make sense" if you like.

   @@ -328,6 +404,12 @@
    {{ This section is meant to answer Geoffrey's "What does Lisp do with a 
Perl 5
    Scalar?" question.  I gotta think about this more.  -- rgr, 29-Jul-08.  }}

   +{{ The scalar decides when to morph, not the language. All the languages 
that
   +have morphing scalars implement them in such a way that they know how to
   +handle, for example, morphing when a string value is assigned to an integer
   +scalar, and what to do if that value is later used as an integer again.
   +--allison }}

This is not about assignment, but about use:  If you pass a "5" from
Perl to a Lisp function that tries to use it as a number, Lisp would
normally barf.  Arguably, it should just coerce it to a number (not
least because it may be hard to control the representation from the Perl
side), but that still leaves the question:  How does Lisp recognize that
it's OK in this case?

   @@ -372,10 +467,14 @@
   . . .

    Several questions arise for languages with multiple representations for
    aggregate types.  Typically, this is because these types are more restricted
    in some fashion.  [finish.  -- rgr, 29-Jul-08.]

   +{{ Not clear where you're going with this --allison }}

Neither was I.  ;-}  In one of the inter-HLL thread in late July,
somebody mentioned Tcl aggregates as being problematic:  Sometimes they
act as arrays, and sometimes as hashes (IIRC).  This is where I wanted
to address such things, but didn't have enough of a clue.

   @@ -383,6 +482,9 @@
    hand, if a language doesn't support functional arguments, then there is no
    hope of using an API written in another language that requires them.

   +{{ Hmmm? They're just subs, how would they not be callable from another
   +language? --allison }}

If the *calling* language doesn't have a syntax for "pass this function
to this other function," then there's no hope of using a foreign API
that requires that.  (Not that there are many such languages targeted by
Parrot.)

   @@ -397,6 +499,10 @@
    could Ruby do with a Scheme list when it can't even get to the Scheme C<car>
    function?

   +{{ Except that Ruby would never even get a Scheme list in the first
   +place if it hadn't loaded a Scheme library of some sort. And, being
   +a list, the Scheme list would still support the standard vtable
   +functions for lists. --allison }}

???  What "standard vtable functions for lists"?  What's a "standard
list" in this context?

   @@ -408,9 +514,14 @@
    not need anything out of the ordinary, from either language or the called
    module author.  -- rgr, 29-Jul-08. }}

   +{{ There is a common introspection API, the 'inspect' vtable
   +function. But what you're describing here isn't introspection, it's
   +actually the standard vtable functions.  --allison }}

If we're lucky, yes.  If not, we'll have to define more.  But I'm still
fuzzy on what's needed here, so I'm afraid I can't be more concrete.

   @@ -430,10 +545,20 @@
    necessary) around it.  It is therefore not expected that all compilers will
    provide a way to define methods on all foreign classes for all language 
pairs.

   +{{ These should generally be handled by subclassing the parent
   +language class, and adding your method to the subclass.

Possibly.  But you may have trouble getting the called module to create
instances of your new class.

   +Monkeypatching is certainly possible, but not encouraged.

Cool; a new term in Allison-speak!  ;-}  But it need not apply.  If your
application defines a new "multi variant" that dispatches on a class you
define, then it cannot conflict with other uses of the multisub.  And
even for methods (as you define them), I understand this is acceptable
Ruby, for example, where it is also called "duck punching."

   +And, there really isn't any distinction between "treating the new
   +method as part of the calling language" and "treat[ing] the new
   +method as part of the foreign language". It's a method, you call it
   +on an object, the class of the object determines how it's found and
   +invoked. --allison }}

If that's true, then great.  It may be that I'm being too pessimistic,
worrying about how to achieve CL AMOP compliance *and* be
Parrot-friendly at the same time.  (But that only affects multis, since
Lisp doesn't do single-dispatch per se.)

   @@ -441,10 +566,16 @@
    specialized only on Parrot or called-language classes, then the compiler
    should take care to make it generally usable.

   +{{ Not sure what you mean here. --allison }}

Again, by "method" I meant "multi variant."  If the new variant defined
in the called-language multisub is specialized on at least one
calling-language class, then it can only be invoked by code that is
already aware of both languages, and less care is required.  (I think.)

    =head3 Subclassing across language boundaries

    {{ This is an important feature, but requires compatible metamodels.  -- 
rgr,
   -29-Jul-08. }}
   +29-Jul-08.
   +
   +Or Proxy PMCs, which is how we're currently handling inheritance across
   +metamodel boundaries. --allison
   +}}

Which means we probably need a section describing how those proxy PMCs
get created.

   @@ -458,6 +589,11 @@
    hack for obligate OO languages like Ruby.)  Defining methods across the
    boundary is harder, and may not be worth the trouble.  -- rgr, 29-Jul-08. }}

   +{{ That's "multiple dispatch" and "single dispatch". In general,
   +defining code in one language and injecting it into the namespace of
   +another language isn't the primary focus of language
   +interoperability. Using libraries from other languages is.
   +--allison }}

I don't see a sharp boundary between "using libraries" and "injecting
[code] into the namespace" myself.

                                        -- Bob

Reply via email to