- How to model the parameters of a ParameterizableClass as a Type that
can be used as declaredType. We should add some sort of a local scope to a type. See: http://code.google.com/p/moose-technology/issues/detail?id=495
I would say that ParameterizedClass has a list of parameter types (here:
This is the ParameterizableClass not the ParameterizedClass.
class Mymap<K,T>
and each type (ex: K or T) could be defined more or less as we define inner classes: a class within the scope of another class (MyMap here).
Right. So, I introduced ParameterType subclassing Type that has as container the ParameterizableClass. The ParameterizableClass computes the parameters as follows:
parameters <MSEProperty: #parameters type: #FAMIXParameterType> <multivalued>
<derived> <MSEComment: 'Parameter types of this class.'>
^self types select: [:each | each isParameterType]
The nice thing about having the ParameterType as contained in the ParameterizableClass is that we have scoping. The not so nice thing is that we have to traverse the inner types to get to the parameters, and now we will also have to take care of distinguishing innerClasses from the parameterType.
Traversing the inner types should not be too much work. This is a feature does is not very much used. Same thing for ParameterTypes.
It does seem a pain to have to test all the time to distinguish innerClasses from ParameterTypes. May be we can just make "parameters" an independent list to contain the parameterTypes?
Another option would be to override the meaning of container in ParameterType and have its opposite the parameters, rather than the types property of ParameterizableClass.
Any opinions?
My general opinion is that overriding implementation is fine, overriding intent is a bad idea. Once one understood what a method is supposed to do or what an attribute means, one should not have to care what class one is looking at to know if this knowledge is still valid or not.
So I would consider changing the meaning of "container" with a lot of care and currently I think it is probably a not-so-good idea.
On the other way, the question is: what would be the meaning of "container" for ParameterType if we wanted to stick to the "normal" definition of container?
And may be the answer is the ParameterizableClass? I am not too sure.
Let's see it from another angle: Currently, the opposite of "container" is "types" defined as "Types contained (declared) in this entity" so can we say that a ParameterType is _declared_ in the ParameterizableClass?
Maybe we should reconsider altogether the idea of defining ParameterType as a subclass of Type? Maybe we should set it apart just as AnnotationType?
[ Actually, this raises another unrelated question: Why is AnnotationType not a subclass of Type? (I am looking at an image from 21/01/2011) ]
Parameters may have a super class (not sure of the exact Java syntax here), but this would be handled normally:
class MyMap<K implements Integer,T>
The problem is in the use of the ParameterizedClass, when we specify (possibly partially) what are the parameters to use.
MyMap<Integer,Object> aMap;
This is now achieved via a ParameterizedType. This in turn has arguments as a collection of Types.
Not sure how this work? You mean for the use of a ParameterizableType, you define a new ParameterizedType that links back to its ParameterizableType and defines the ParameterType-s it uses? And what is the container of ParameterizedType? And its superclass? This is an idea I had too, but somehow I found that _declaring_ a new type when you want only to _use_ an existing type (and give it some parameters) was a bit outstretched, so I rather came with the new associations. I was not sure which solution is the less worse (less worst?!? less bad?!?). I am still not sure.
This would suggest a new association (Reference, Inheritance) where one would specify the parameters of the ParameterizedClass. Not very satisfying but I couldn't think of any better solution. The association would have a list of parameters where order is significant (the same as in the ParameterizedClass). The actual parameters in the Reference could be "real" ("concrete") types or new parameter types if we specify only partially the parameters:
class MyStringMap<T> implements MyMap<String,T> ...
Since Interfaces may also be parameterized, we may want to raise all this at the level of Types (ParameterizedType) instead of classes. Or may be we can use Traits?
Well, the current solution is that interfaces are modeled as FAMIXClass with an isInterface flag. FAMIXParameterizableClass being a subclass of FAMIXClass will be able to model an interface in the same way.
However, I still think it would be nice to have FAMIXInterface explicitly. It would make it easier to clarify the meaning of MooseModel>>allClasses which right now is a bit confusing. So, yes, I think that traits would be an interesting choice.
Any comments?
Again, we can go back to the bases: I teach to my student that when they implement a "type" attribute to avoid defining sub-classes they should think really hard and twice to make sure they have a very good reason to do it that way. So is there a very good reason to keep the attribute isInterface? -> Avoid using traits. Is is a sufficiently good reason? (I don't know because I did not use traits yet)
nicolas