A big topic with Lists and Maps is how to handle covariance. But actually this is a more general problem, consider a common pattern like:
class Obj { Obj clone() }
class Foo { Foo clone() }
By the nature of the problem, return type covariance is safe (since it meets parent method contract) and method parameter covariance is unsafe (it narrows parent method contract). I'm still not sure if we should support parameter covariance since it means you are narrowing a virtual method to be potentially incompatible with your base class. However if you are just going to fail with a class cast exception, then it probably makes sense to save the developer from inserting the casts, and letting the compiler warn the user if using the method non-polymorphically (it's a bit different for Fan from Java/C# since we don't overload by parameters).
Java 1.5 supports return type covariance now, so I could potentially just change the method signature of what I emit and it would work. However I'm not sure what the CLR does. Furthermore we don't really want to generate new classes for List and Map with new signatures which then have an extra method call to super. So basically what I am thinking is that a method ref in fcode should contain both a return type (for the method being called), and an optional narrow type which if specified would insert a checkcast operation into the emit code. Then for Lists and Maps I can just call the standard method and specify that a narrowing cast should be inserted for the generic methods like get() or remove(). Nothing would be done for parameters - they wouldn't have any runtime type checking.
How I actually implement the List and Map types is a whole other topic. They really are generics, but I'm not sure how to tackle this, especially in the reflection APIs. For example at the simplest level, I wouldn't even allow something like "x is Str[]" because it would be totally erased at runtime (only the compiler would know about the generic types). But that seems just wrong, so we must preserve some identity of the types at runtime. So what would something like this return: "Str[].type.method("get").returns"? Does it return Obj or Str? Or does it return something messed up like Java's new 1.5 reflect API (which I can't even begin to decipher). Note that methods like "add(Obj)" are actually parameter covariant which means that technically Str[] isn't a Obj[].
Anyways, just a couple of thoughts - tackling covariance and Lists is my next big task since requires so many major design decisions.
brian Sun 1 Jan 2006
A big topic with Lists and Maps is how to handle covariance. But actually this is a more general problem, consider a common pattern like:
By the nature of the problem, return type covariance is safe (since it meets parent method contract) and method parameter covariance is unsafe (it narrows parent method contract). I'm still not sure if we should support parameter covariance since it means you are narrowing a virtual method to be potentially incompatible with your base class. However if you are just going to fail with a class cast exception, then it probably makes sense to save the developer from inserting the casts, and letting the compiler warn the user if using the method non-polymorphically (it's a bit different for Fan from Java/C# since we don't overload by parameters).
Java 1.5 supports return type covariance now, so I could potentially just change the method signature of what I emit and it would work. However I'm not sure what the CLR does. Furthermore we don't really want to generate new classes for List and Map with new signatures which then have an extra method call to super. So basically what I am thinking is that a method ref in fcode should contain both a return type (for the method being called), and an optional narrow type which if specified would insert a checkcast operation into the emit code. Then for Lists and Maps I can just call the standard method and specify that a narrowing cast should be inserted for the generic methods like get() or remove(). Nothing would be done for parameters - they wouldn't have any runtime type checking.
How I actually implement the List and Map types is a whole other topic. They really are generics, but I'm not sure how to tackle this, especially in the reflection APIs. For example at the simplest level, I wouldn't even allow something like "x is Str[]" because it would be totally erased at runtime (only the compiler would know about the generic types). But that seems just wrong, so we must preserve some identity of the types at runtime. So what would something like this return: "Str[].type.method("get").returns"? Does it return Obj or Str? Or does it return something messed up like Java's new 1.5 reflect API (which I can't even begin to decipher). Note that methods like "add(Obj)" are actually parameter covariant which means that technically Str[] isn't a Obj[].
Anyways, just a couple of thoughts - tackling covariance and Lists is my next big task since requires so many major design decisions.