[IronPython] CLS compliance

Peter Mechlenborg metch at daimi.au.dk
Tue Feb 28 22:00:28 CET 2006


Dino Viehland wrote:
 > IronPython can consume CLS types and extend them, but cannot produce
 > new CLS types.  Unfortunately that last part is extremely tricky
 > because CLR types are not dynamic, but Python types are.  It is
 > something that's on our radar but we don't yet have a solution for it.

Thanks for the quick answer.

Up front I must say that my knowledge about Python and CLR is limited,
so I hope that the following is not completely wrong.

My understanding is that the general way of targeting a dynamic
language towards a static VM/language is to escape through the common
root type, i.e., Object, and then use runtime casts to perform runtime
type checks.  The following code fragment should illustrate this
through the use of a Point class, using Java-like syntax:

   class Point {
     Object x,y;
     void move(Object xx, Object yy) {
       x = (int)x + (int)xx;
       y = (int)y + (int)yy;
     }
   }

The fields and arguments are qualified by Object, but cast to integer
before the addition in the move method.  I'm assuming that integers
are objects and not primitive types, I'm not sure how it would look if
integers were primitive.

If the above code was generated from a untyped language, and we wanted
to expose the move method and the Point class through the CLS, we need
some extra type information.  I'm not sure how to do this, but ideas
could be optional type declarations, some kind of IDL, or type
inference, and in my eyes this is the biggest problem when trying to
produce CLS compliant code from a dynamic language.  If we have the
extra type information we can create wrapper methods with more
specific type declarations:

   class Point {
     Object x,y;
     void cls_move(int xx, int yy) {
       this.move((Object) xx, (Object) yy);
     }
     void move (Object xx, Object yy) {
       ...
     }
   }

Here cls_move should be used by foreign languages, while move should
be use natively; in general giving objects two separate interfaces,
one for foreign code, and one for native code (I'm regarding the
fields as private).

What I sketched above is properly too simplistic, but would the
general idea work of wrapper methods work for code produced by
IronPython?  (Maybe the hardest problem is all the little details).


I'm quite interested in how you have implemented consumption of CLS
types, because I don't see an obvious way of doing this.

If we reverse the Point example:

   class Point {
     int x,y;
     void move(int xx, int yy) {
       x = x + xx;
       y = y + yy;
     }
   }

Point is now written in a static language, and we would like to use it
from IronPython.  In this case all arguments passed from the callee to
the move method must be qualified as int, but in IronPython the type
of the arguments are not known.

One solution is to create wrapper objects around all foreign objects,
and that way provide a single location that can translate dynamic
calls into static calls.  This however adds extra overhead, and also
complicates inheritance because the wrapper would have to use
delegation, which does not preserve the self/this reference, which
again conflicts with overriding of methods.  I think delegation would
be needed because CLS only supports single inheritance for classes.
It might also be possible to use reflection, and make all calls to
foreign objects in a reflective way.  Am I missing something obvious?
What is your general strategy for consumption of CLS types in
IronPython?

 >
 > Do you want to help develop Dynamic languages on CLR?
 > (http://members.microsoft.com/careers/search/details.aspx?JobID=6D4754DE-11F0-45DF-8B78-DC1B43134038)

It does seem like a very interesting job.  Its nice to see some focus
on dynamic languages.


Have fun,

   --  Peter



More information about the Ironpython-users mailing list