Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 259754 - Implement ListLiteralExp
Summary: Implement ListLiteralExp
Status: RESOLVED FIXED
Alias: None
Product: QVTo
Classification: Modeling
Component: Engine (show other bugs)
Version: unspecified   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: 2.0 M6   Edit
Assignee: Alexander Igdalov CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-12-29 11:20 EST by Alexander Igdalov CLA
Modified: 2009-02-16 07:45 EST (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alexander Igdalov CLA 2008-12-29 11:20:53 EST
This bug is a compilation of my discussion with Adolfo Sanchez-Barbudo Herrera.
Currently, the QVT specification doesn't describe an AST element for list literals. However, there is an approved OMG issue by Adolfo for this case:
http://www.omg.org/issues/issue12375.txt
This issue suggests adding the ListLiteralExp into the QVTO grammar and says that it "should extend CollectionLiteralExp (From EssentialOCL)".
There will be a certain difficulty to inherit it from CollectionLiteralExp in Java. The problem is that CollectionLiteralExp has a 'kind' attribute of type CollectionKind which is an enumeration (this attribute describes the collection kind - Collection, Sequence, Set, Bag or OrderedSet and must be somehow extended for the List type). Since Java enumerations implicitly extend java.lang.Enum and hence cannot extend anything extending the CollectionKind type is impossible.
So what can be done about it? We can choose one of the following ideas:
1. QVTO side: ListLiteralExp can be made an immediate hier of LiteralExp.
2. EMF side - tempting but hardly possible: Ask EMF to support enumeration extension (via Java interfaces, for instance)
3. MDT OCL side: change CollectionKind type from enumeration to something extensible
4. OCL side (from Adolfo's letter): 
> "Without thinking too deeply (Maybe that CollectionKind enum have
> another role which I'm missing) the following could be possible solution:
> - removing CollectionKind enum.
> - removing the kind property from CollectionType (if we have specific
> meta types what's the reason of this ? a big inconvenience for QVT). The 
> ocl M1 types (generic and specific one) would have sufficient mechanism to
> know which kind of CollectionType is. For example using the new oclType()
>  method.
> - changing the kind property's type to Classifier (Type in EMOF) from
> CollectionLiteralExps and adding a restriction so that 
> Collection *Meta*Types (and sub*Meta*types) can only be used. 
> The problem here is that we are mixing Metamodeling levels (M1 model 
> with references to M2 OCL metamodel instead of using an enumerator value).
> However theses references to M2 are common in OCL models.....mmmm......
> thinking better..... what about doing - kind : CollectionType, so that every
> CollectionLiteralExp instance would exactly refer to a instance of
> CollectionType, so that it knows which kind of collection is (including the 
> element type).
5. OCL side: Remove CollectionKind and make specific literals for each collection type (SetLiteralExp, SequenceLiteralExp, ListLiteralExp, etc.) inherited from a common root - CollectionLiteralExp.
Ideas?
Comment 1 Christian Damus CLA 2008-12-29 11:55:52 EST
Yes, this is something that UML got wrong:  generalization of enumerations just doesn't make sense, because you can't have a fixed set of instances of a type that can be specialized by unknown models.

What does QVTo currently do in the definition of its ListType metaclass?  Is it a subclass of OCL's CollectionType?  Note that the CollectionType::kind attribute in the MDT OCL metamodel is not specified by OMG.  It's a convenience that goes back to the pre-Eclipse history of the OCL component and should be removed in the MDT OCL version 2.0.  Happily, it is at least transient and read-only.

Is it possible simply to ignore the CollectionLiteralExp::kind attribute?  Just set it to CollectionKind::sequence (which maps to java.util.List in Java) and see what happens.  Even nicer, I suppose, would be to leave it at the default if that works, so that it isn't serialized.

This will be a problem for any QVT implementation, because of the problem of enumeration specialization.  It would be good to see this resolved at OMG.  I would only hope that they don't rely on package merge to do it (defining a CollectionType in QVT that adds the new literals) because that would be a disaster for an EMF-based implementation.

You can guess that MDT OCL can't implement any of the suggestions 3/4/5 because they all break API compatibility.  For 2.0, we should adopt an OMG-adopted solution.  I would definitely support removal of the CollectionLiteralExp::kind attribute and the CollectionKindEnum because it is redundant with the expression's static type, with concomitant changes to constraint [2] for CollectionLiteralExp in section 8.3.7.
Comment 2 Radomil Dvorak CLA 2008-12-29 18:29:01 EST
(In reply to comment #1)
> What does QVTo currently do in the definition of its ListType metaclass?  Is 
> it a subclass of OCL's CollectionType?  Note that the CollectionType::kind
> attribute in the MDT OCL metamodel is not specified by OMG.

Our ListType has the CollectionType superclass and does nothing about
the 'kind' feature. It inherits its value from the CollectionType, which is 'CollectionKind.COLLECTION_LITERAL'. MDT OCL then sees our List as a generic collection and I have tested that Collection operations work fine on QVT Lists. Would be great if there could be a contract like this established until it gets removed.
I have checked the CollectionType::kind with the OCL spec recently, so I assumed
it is likely to disappear. Actually, I wanted to raise a bugzilla about this to MDT OCL the nearest days.

> Is it possible simply to ignore the CollectionLiteralExp::kind attribute? >Just set it to CollectionKind::sequence (which maps to java.util.List in Java) 
> and see what happens.  Even nicer, I suppose, would be to leave it at the 
> default if that works, so that it isn't serialized.

I think, no problem to ignore it as long as MDT OCL agrees on doing the same for literals of unknown collection sub-types and makes that as a contract. Good, keeping the default would make eventual 'kind' feature removal easier. In fact, we map QVT List to a special list interface which extends java.util.List.

> It would be good to see this resolved at OMG.  I would only hope that they >don't rely on package merge to do it.

The recent resolution of the issue 12375 in the QVT spec actually introduced this problem, so I find it errorenous. We should have a chance to propose a correction in the 2nd ballot to come, so the list literal can extend LiteralExp. Actually, the same is done in case of DictLiteralExp, which is used to define a Dictionary and the DictionaryType extends CollectionType as well.
However, removal of collection kinds in OCL seems to be the best solution.
Comment 3 Christian Damus CLA 2008-12-30 08:21:48 EST
(In reply to comment #2)
> > Is it possible simply to ignore the CollectionLiteralExp::kind attribute? >Just set it to CollectionKind::sequence (which maps to java.util.List in Java) 
> > and see what happens.  Even nicer, I suppose, would be to leave it at the 
> > default if that works, so that it isn't serialized.
> 
> I think, no problem to ignore it as long as MDT OCL agrees on doing the same
> for literals of unknown collection sub-types and makes that as a contract.

Yes, MDT OCL can guarantee this.  It will be important for us if we are to prepare for removal of the kind concept.


> Good, keeping the default would make eventual 'kind' feature removal easier. In
> fact, we map QVT List to a special list interface which extends java.util.List.
> 
> > It would be good to see this resolved at OMG.  I would only hope that they >don't rely on package merge to do it.
> 
> The recent resolution of the issue 12375 in the QVT spec actually introduced
> this problem, so I find it errorenous. We should have a chance to propose a
> correction in the 2nd ballot to come, so the list literal can extend
> LiteralExp. Actually, the same is done in case of DictLiteralExp, which is used
> to define a Dictionary and the DictionaryType extends CollectionType as well.

IMO, a dictionary shouldn't be a collection unless it is modeled explicitly as a collection of pairs.  Is that how QVT models it?


> However, removal of collection kinds in OCL seems to be the best solution.

Could I ask you to raise an Issue for the OCL RTF?

Comment 4 Radomil Dvorak CLA 2009-01-05 19:44:33 EST
> > I think, no problem to ignore it as long as MDT OCL agrees on doing the same
> > for literals of unknown collection sub-types and makes that as a contract.
> Yes, MDT OCL can guarantee this.  It will be important for us if we are to
> prepare for removal of the kind concept.

Great! Should I raise a bugzilla on this to MDT OCL?

> IMO, a dictionary shouldn't be a collection unless it is modeled explicitly as
> a collection of pairs.  Is that how QVT models it?

QVT models this differently, I'm not sure why. The DictionaryType extends
CollectionType, inherits its 'elementType' and only adds the 'keyType'.
This way a dictionary can be seen as a collection of values each having a key assigned. I agree, it may look odd in contrast with java.util.Dictionary as it defines quite similar operation set.

> Could I ask you to raise an Issue for the OCL RTF?
Sure, I can do that.
Comment 5 Christian Damus CLA 2009-01-06 08:40:32 EST
(In reply to comment #4)
> > > I think, no problem to ignore it as long as MDT OCL agrees on doing the same
> > > for literals of unknown collection sub-types and makes that as a contract.
> > Yes, MDT OCL can guarantee this.  It will be important for us if we are to
> > prepare for removal of the kind concept.
> 
> Great! Should I raise a bugzilla on this to MDT OCL?

Only if there is something that MDT OCL needs to change.  Is there?  We can't really track, in Bugzilla, intention *not* to do stuff.  :-)
Comment 6 Adolfo Sanchez-Barbudo Herrera CLA 2009-01-07 09:06:06 EST
Hi All,

I would have liked to join the bugzilla's discussion before but I have been in holidays. 

Firstly, I'm so glad to see this OMG/Eclipse discussions about OCL/QVT in such an open way. This was specially remarked (as a TODO) in both Eclipse/OMG symposiums in which I took part the last year, and, I haven't certainly seen any kind of work or movement in this way.

About this topic, I don't want to make a big post remarking every point of the discussion. So I'm just going to say some general considerations and few specific remarks.

It seems that every problem should be considered from differents points of view:
- Problems related to OCL/QVT specification, which must be firstly issued to OMG web page.
- Problems related to OCL/QVT implementation to comply the specification, which could be considered as a implementation failure, or they might derive into a new specification problem.
- Another detail to take into account are MDT_OCL/M2M_OML versions. A change in specification may not be included in current projects due to API breakage. MDT OCL will have to release a new 2.x version to be able to comply the resolved deficiences of the current specification, so that some features will not be supported in 1.x versions. I guess that M2M_OML project will have to adopt the same philosophy, launching a new version of the project after MDT_OCL does, and accepting that some OMG specification features would rather wait until then.


>> It would be good to see this resolved at OMG.  I would only hope that they >>don't rely on package merge to do it.

>The recent resolution of the issue 12375 in the QVT spec actually introduced
>this problem, so I find it errorenous. We should have a chance to propose a
>correction in the 2nd ballot to come, so the list literal can extend
>LiteralExp. Actually, the same is done in case of DictLiteralExp, which is used
>to define a Dictionary and the DictionaryType extends CollectionType as well.
>However, removal of collection kinds in OCL seems to be the best solution.

I haven't worked in the area as long as you all have been, but I'm not sure which problem introduces extending CollectionType and CollectionLiteralExp. QVT doesn't create a new CollectionType or CollectionLiteralExp concepts to merge with. It only creates a new subtype which extends the OCL one. Obviously, QVTo collection subtypes have different semantics of the OCL one, but I don't have a clear idea why ListLiteralExp can't extend CollectionLiteralExp. Lists are conceptually collections, therefore, ListLiteralExps should intuitively be CollectionLiteralExps as well.

Anyway if I'm missing something, I'would be pleased to be pointed out.

>You can guess that MDT OCL can't implement any of the suggestions 3/4/5 because
>they all break API compatibility.  For 2.0, we should adopt an OMG-adopted
>solution.  I would definitely support removal of the CollectionLiteralExp::kind
>attribute and the CollectionKindEnum because it is redundant with the
>expression's static type, with concomitant changes to constraint [2] for
>CollectionLiteralExp in section 8.3.7.

I agree that the main problem for such concepts (CollectionType and CollectionTypeExps) is the enumerator CollectionKind. Maybe this enumerator would be interesting for a "finite" and closed type system. However, since OCL types system may be extensible (i.e by QVT), OCL must be refactored (I'm also inclined to remove that enumerator). Besides, as Christian mentioned the CollectionLiteralExp::kind attribute is not necessary.

Unfortunately, I guess that this must be deferred until the MDT-OCL 2.0, and therefore, the formal support of these features in M2M-OML must be also deferred. Meanwhile, we should focus on detecting these kind of incompatibilities, and try to issue them on time, so that they can be resolved all toguether by the RTF.

Finally, I want to point borland's team out to the following bugzilla, in which this kind of considerations could be added in a common place, so that nothing is forbidden when MDT OCL 2.0 were designed and developed. I will also try to use it more frequently.
 
https://bugs.eclipse.org/bugs/show_bug.cgi?id=237438

Cheers,
Adolfo.
Comment 7 Radomil Dvorak CLA 2009-01-07 12:11:52 EST
> >The recent resolution of the issue 12375 in the QVT spec actually introduced
> >this problem, so I find it errorenous.

> I haven't worked in the area as long as you all have been, but I'm not sure
> which problem introduces extending CollectionType and CollectionLiteralExp. QVT
> doesn't create a new CollectionType or CollectionLiteralExp concepts to merge
> with. It only creates a new subtype which extends the OCL one. Obviously, QVTo
> collection subtypes have different semantics of the OCL one, but I don't have 
> a clear idea why ListLiteralExp can't extend CollectionLiteralExp. Lists are > conceptually collections, therefore, ListLiteralExps should intuitively be 
> CollectionLiteralExps as well.

No doubt about extending existing, but only if you can. As for CollectionType, no problems in the OMG spec, but there is also an issue in MDT OCL with the special CollectionType::kind, to be obsoleted in the future. 
Just trying to negotiate a contract with MDT OCL on the steps in this direction ;), as we need to solve this case for the Galileo release.

The actual problem is extending the CollectionLiteralExp, as a new collection literal subtype can't follow the contract of its super-class and can't provide a proper kind enum value. Therefore it should not have been resolved this way in QVT, with respect to the current OCL spec state.
As for reusing collection concepts, I have pointed out the DictionaryLiteral as an example, being a CollectionType too, but does not extend the collection literal concept, no harm. 
Besides, I rather see a concept in the CollectionLiteralPart then in the collection literal itself and this can be freely reused.

As I have mentioned, if the ListLiteralExp extends LiteralExp and follows the concept of collection literal, it is not a horrible change to make it a CollectionLiteralExp sub-type, once the OCL spec kills the collection kind.
Mainly, it would be consistent and implementable for us, which I guess should also be an important aspect of a spec ;).
Comment 8 Radomil Dvorak CLA 2009-01-07 12:29:37 EST
> > Great! Should I raise a bugzilla on this to MDT OCL?
> 
> Only if there is something that MDT OCL needs to change.  Is there?  We can't
> really track, in Bugzilla, intention *not* to do stuff.  :-)

Sure, I had no intent of tracking NOT todos ;). 
I had in mind there could be at least some java comments to mention this and 
referring to the problem in bugzilla, as a not tracked guarantee may be forgotten.
I'm just verifying if all this is OK and will for sure raise a "concrete" bugzilla if needed.


Comment 9 Christian Damus CLA 2009-01-07 12:32:56 EST
(In reply to comment #8)
> 
> Sure, I had no intent of tracking NOT todos ;). 

heh heh

> I had in mind there could be at least some java comments to mention this and 
> referring to the problem in bugzilla, as a not tracked guarantee may be
> forgotten.

That sounds like a good idea.  If you could provide a patch to enhance the relevant doc comments, that would be much appreciated!
Comment 10 Adolfo Sanchez-Barbudo Herrera CLA 2009-01-07 13:07:21 EST
(In reply to comment #7)
> > >The recent resolution of the issue 12375 in the QVT spec actually introduced
> > >this problem, so I find it errorenous.
> 
> > I haven't worked in the area as long as you all have been, but I'm not sure
> > which problem introduces extending CollectionType and CollectionLiteralExp. QVT
> > doesn't create a new CollectionType or CollectionLiteralExp concepts to merge
> > with. It only creates a new subtype which extends the OCL one. Obviously, QVTo
> > collection subtypes have different semantics of the OCL one, but I don't have 
> > a clear idea why ListLiteralExp can't extend CollectionLiteralExp. Lists are > conceptually collections, therefore, ListLiteralExps should intuitively be 
> > CollectionLiteralExps as well.
> 
> No doubt about extending existing, but only if you can. As for CollectionType,
> no problems in the OMG spec, but there is also an issue in MDT OCL with the
> special CollectionType::kind, to be obsoleted in the future. 
> Just trying to negotiate a contract with MDT OCL on the steps in this direction
> ;), as we need to solve this case for the Galileo release.
> The actual problem is extending the CollectionLiteralExp, as a new collection
> literal subtype can't follow the contract of its super-class and can't provide
> a proper kind enum value. Therefore it should not have been resolved this way
> in QVT, with respect to the current OCL spec state.

I agree, but I don't believe proposing a non-natural change to the QVT spec is the good solution, when the problem comes from the OCL spec itself. Taken from the email discussion with alex:

"1. We shouldn't break (with a workaround or whatever) a good design if, in this case, OCL specification is not well-designed for extension. We should change OCL specification.
2. We shouldn't try to change the MDT OCL implementation to solve our implementations when the problem is the specification. If we directly attack and solve the specification problem, the implementation will have to naturally change by itself."

So, instead of making ListLiteralExp inherit from LiteralExp, I would wait until that CollectionLiteralExp::kind were removed from the OCL spec ;).

> As for reusing collection concepts, I have pointed out the DictionaryLiteral as
> an example, being a CollectionType too, but does not extend the collection
> literal concept, no harm. 
> Besides, I rather see a concept in the CollectionLiteralPart then in the
> collection literal itself and this can be freely reused.

I think I don't follow... ¿DictionaryLiteral? ¿as a CollectionType?, You are mixing things here. I'm not sure if you are refering to types or literal expressions. Please take a look this paragraph because I'm not sure what you are refering to.

> 
> As I have mentioned, if the ListLiteralExp extends LiteralExp and follows the
> concept of collection literal, it is not a horrible change to make it a
> CollectionLiteralExp sub-type, once the OCL spec kills the collection kind.
> Mainly, it would be consistent and implementable for us, which I guess should
> also be an important aspect of a spec ;).
> 

You can certainly make your workarounds to make list literal expressions to work for QVT_OML galileo release, but as I have mentioned, I wouldn't definetely propose such a change to the OMG QVT specification.

Cheers,
Adolfo.
Comment 11 Radomil Dvorak CLA 2009-01-07 15:25:38 EST
(In reply to comment #10)
> So, instead of making ListLiteralExp inherit from LiteralExp, I would wait
> until that CollectionLiteralExp::kind were removed from the OCL spec ;).

Well, I'm not pushing this idea, however I'm not sure, who can judge what is a 
better design from those two bellow ;)
1) ListLiteralExp extending CollectionLiteralExp and having let's say CollectionLiteralExp::kind = CollectionKind::Sequence
2) ListLiteralExp extending LiteralExp and just having 'part' reference to 
CollectionLiteralExp

AFAIK, the ListLiteralExp class is not in the spec yet and to be honest, I'm not sure it is needed at all. Staying without it and using just CollectionLiteralExp to define the contents of all collection types seems to be equally bad for now as a special sub-class of CollectionLiteralExp with invalid collection kind in any case. 
Moreover, once CollectionLiteralExp::kind is gone it is absolutely correct and things even get simpler.
As it was already said, the 'kind' is redundant and the exact collection type is available.
I would not fight for a good design example exactly in case of ListLiteralExp.

> I think I don't follow... ¿DictionaryLiteral? ¿as a CollectionType?, You are
> mixing things here.

Sorry, my apologies. I should have pasted what I have already said in this discussion.
"Actually, the same is done in case of DictLiteralExp, which is used
to define a Dictionary and the DictionaryType extends CollectionType as well."
Comment 12 Adolfo Sanchez-Barbudo Herrera CLA 2009-01-08 04:28:14 EST
(In reply to comment #11)
> (In reply to comment #10)
> > So, instead of making ListLiteralExp inherit from LiteralExp, I would wait
> > until that CollectionLiteralExp::kind were removed from the OCL spec ;).
> 
> Well, I'm not pushing this idea, however I'm not sure, who can judge what is a 
> better design from those two bellow ;)
> 1) ListLiteralExp extending CollectionLiteralExp and having let's say
> CollectionLiteralExp::kind = CollectionKind::Sequence
> 2) ListLiteralExp extending LiteralExp and just having 'part' reference to 
> CollectionLiteralExp

I wouldn't surely be the judge :P, I'm usually changing my ideas about which is the best one. With the past of the years, I will probably be suffiently good judging every kind of scenarios, but until then..... I just have to learn working on them.

In this case, I'm just thinking about what OMG specifications must state, in both OCL and QVT specs.

I think we were agree about the removal of CollectionKind enumerator and the CollectionLiteralExp::kind attribute, so I would try to avoid proposing the first solution as the proposed solution.

About the second, I woud try to avoid composition of expressions when it is not really needed. IMO, inheritance is a better option.  As you say, a ListLiteralExp mightn't be really necessary if CollectionLiteralExp were better designed.

> AFAIK, the ListLiteralExp class is not in the spec yet and to be honest, I'm
> not sure it is needed at all. Staying without it and using just
> CollectionLiteralExp to define the contents of all collection types seems to be
> equally bad for now as a special sub-class of CollectionLiteralExp with invalid
> collection kind in any case. 
> Moreover, once CollectionLiteralExp::kind is gone it is absolutely correct and
> things even get simpler.
> As it was already said, the 'kind' is redundant and the exact collection type
> is available.
> I would not fight for a good design example exactly in case of ListLiteralExp.

Extactly, I completely agree with you. So, if you raised the issue to OMG about the removal of the CollectionKind enumerator and CollectionLiteralExp::kind attribute, we could discuss this topic in the QVT rtf mail list, so that in the second ballot that issue about ListLiteralExp could be reconsidered.

> 
> > I think I don't follow... ¿DictionaryLiteral? ¿as a CollectionType?, You are
> > mixing things here.
> 
> Sorry, my apologies. I should have pasted what I have already said in this
> discussion.
> "Actually, the same is done in case of DictLiteralExp, which is used
> to define a Dictionary and the DictionaryType extends CollectionType as well."
> 

hehehehe. You don't have to apologise, I usually have a lot of things in my mind which I don't express as they are in it, even in spanish!!. So you can guess the time I invest trying to write a post in a proper english. I have to read it several times >.<.

I hope we take a good proposal for OCL/QVT specs from this. Cool !!!!

Cheers,
Adolfo.
Comment 13 Christian Damus CLA 2009-01-10 18:06:36 EST
Another point strikes me that suggests the problem of the CollectionKind enumeration could be moot.

I see that the QVT ListType and DictionaryType metaclasses define *mutable* collections.  As such, I think it is inappropriate that they specialize the OCL CollectionType metaclass.  Their semantics are completely incompatible:  OCL collections are immutable.  A mutable collection like a QVT List cannot substitute for an OCL collection in an invocation of an operation that OCL expects to respect its guarantee of being side-effect-free.

If the ListType and DictionaryType are updated to have no relation to OCL's CollectionType metaclass, and the ListExp and DictExp are updated to specialize LiteralExp, then the CollectionKind problem would vanish.

Thoughts?
Comment 14 Alexander Igdalov CLA 2009-01-11 09:44:52 EST
(In reply to comment #13)
> I see that the QVT ListType and DictionaryType metaclasses define *mutable*
> collections.  As such, I think it is inappropriate that they specialize the OCL
> CollectionType metaclass.  Their semantics are completely incompatible:  OCL
> collections are immutable.  A mutable collection like a QVT List cannot
> substitute for an OCL collection in an invocation of an operation that OCL
> expects to respect its guarantee of being side-effect-free.
> 

Hi Christian,

This is just what I was going to write about=)) To illustrate the problems caused by mixing mutable and immutable collections, consider the example below:

var a : List(EClass) := List {object EClass {name := 'eClass'}}; -- (1)
var b : List(EClassifier) := a; -- (2)
b.add(object EDataType {name := 'eDataType'}); -- (3)
a.last().eOperations; -- (4) ClassCastException

// Just to mention, the QVT spec says Lists inherit all Collection operations and add some others (add, prepend, etc.), so strictly all Sequence-specific operations including 'last()' become unavailable. However, I suppose the actual intention of the spec was to make List inherit all Sequence operations =)) Thus, I am using 'last()' in line (4).

If the script compiles successfully this may cause runtime-errors like in line (4). So how should we handle the initialization in line (2)?

There can be three possible solutions. The first one (Java-style) is to prohibit type conformance in cases where mutable collection template aren't equal, i.e. to say that 'List(EClass)' is not a 'List(EClassifier)'. The second one (proposed by Sergey Boyko) is to allow casting 'List(EClass)' to 'List(EClassifier)' in any cases except initializations, assignments, passing  non-final parameters to operations (for QVT mappings - inout and out parameters and inout context), returning values from operations. Perhaps, there are some other cases to be considered. The third solution - which I do not appreciate, is to forget about it at all and to let users overcome their own troubles ;))

This is, of course, subject to another bug which I will raise soon. In any case (except the 3rd solution), for mutable collections we should handle type conformance issues in an other way than described in the OCL spec (7.4.5) which leads me to the conclusion than mutable collections and immutable collections type hierarchy is to be made different.

> If the ListType and DictionaryType are updated to have no relation to OCL's
> CollectionType metaclass, and the ListExp and DictExp are updated to specialize
> LiteralExp, then the CollectionKind problem would vanish.
> 
> Thoughts?
> 

This would be a more significant patch to the whole OCL/QVT collection type subsystem but for me the ideal solution would be making a common root - e.g. AbstractCollectionType with two subtypes ImmutableCollectionType and MutableCollectionType. OCL collections such as Set, Sequence, etc. would inherit from ImmutableCollectionType while Lists (and maybe Dict?) would inherit from MutableCollectionType. This would help us avoid multiple instanceof-checks in cases where the behaviour differs. The standard predefined operations for these types should be revised as well.
Comment 15 Christian Damus CLA 2009-01-11 14:13:30 EST
(In reply to comment #14)

> var b : List(EClassifier) := a; -- (2)

Please tell me that QVT does not permit this.  This assumes that List(EClass) conforms to List(EClassifier), but this only works for OCL's collections precisely because they are immutable.  Given that Lists are mutable, this conformance does not make sense because, as you indicate in (4), it permits attempts to introduce objects that don't conform to the collection type.

This is exactly why Java has bounded unknown types, that actually prevent the add(...) operation from parsing (it's one aspect of generic typing that Java did better than any language before it, IMO).


> b.add(object EDataType {name := 'eDataType'}); -- (3)
> a.last().eOperations; -- (4) ClassCastException
> 
> // Just to mention, the QVT spec says Lists inherit all Collection operations
> and add some others (add, prepend, etc.), so strictly all Sequence-specific
> operations including 'last()' become unavailable. However, I suppose the actual
> intention of the spec was to make List inherit all Sequence operations =))

Heh heh ... a leap of faith!  It would, of course, make sense.


> Thus, I am using 'last()' in line (4).
> 
> If the script compiles successfully this may cause runtime-errors like in line
> (4). So how should we handle the initialization in line (2)?
> There can be three possible solutions. The first one (Java-style) is to
> prohibit type conformance in cases where mutable collection template aren't
> equal, i.e. to say that 'List(EClass)' is not a 'List(EClassifier)'. The second

Yep.


> one (proposed by Sergey Boyko) is to allow casting 'List(EClass)' to
> 'List(EClassifier)' in any cases except initializations, assignments, passing 
> non-final parameters to operations (for QVT mappings - inout and out parameters
> and inout context), returning values from operations. Perhaps, there are some

But, these are precisely the constructs that have assignment semantics and, therefore, type conformance concerns.  AFAICS, there is no difference between this option and the first.


> other cases to be considered. The third solution - which I do not appreciate,
> is to forget about it at all and to let users overcome their own troubles ;))

Hah!  An anti-Eclipsian option, indeed.


> This is, of course, subject to another bug which I will raise soon. In any case
> (except the 3rd solution), for mutable collections we should handle type
> conformance issues in an other way than described in the OCL spec (7.4.5) which
> leads me to the conclusion than mutable collections and immutable collections
> type hierarchy is to be made different.

I agree.  But, clearly you would be deviating from the QVT spec (which I think we agree is deficient in this regard).  Do you foresee compliance/portability issues for your users?


> > If the ListType and DictionaryType are updated to have no relation to OCL's
> > CollectionType metaclass, and the ListExp and DictExp are updated to specialize
> > LiteralExp, then the CollectionKind problem would vanish.
> > 
> > Thoughts?
> > 
> 
> This would be a more significant patch to the whole OCL/QVT collection type
> subsystem but for me the ideal solution would be making a common root - e.g.
> AbstractCollectionType with two subtypes ImmutableCollectionType and
> MutableCollectionType. OCL collections such as Set, Sequence, etc. would
> inherit from ImmutableCollectionType while Lists (and maybe Dict?) would
> inherit from MutableCollectionType. This would help us avoid multiple
> instanceof-checks in cases where the behaviour differs. The standard predefined
> operations for these types should be revised as well.

(just to be clear, I was speaking of revisions to the QVT spec, not your implementation)

This makes sense for a Java API, in particular one that encompasses both OCL ad QVT in a single component.  However, from the perspective of OCL as a self-contained specification and implementation, it is perhaps difficult to introduce classes whose sole purpose is to support extensibility.  Especially when the semantics of those classes are fundamentally contrary to the language.  In OCL, the MutableCollectionType metaclass would have to be abstract, otherwise we would be able to define mutable collection types and, hence, mutable collections that would break the language.  But then, obviously OCL would not, itself, define any concrete subclasses of MutableCollectionType, so OCL would be left with a metaclass that it does not use.  This is not good (we already have ElementType and OclElement, which are chaff from 1.x; happily, OCL 2.1 eliminates TypeType and OclType).

I am a firm believer in the Open-Closed principle, but I think this goes beyond open.  :-)
Comment 16 Alexander Igdalov CLA 2009-01-12 06:37:41 EST
(In reply to comment #15)
> (In reply to comment #14)
> 
> > var b : List(EClassifier) := a; -- (2)
> 
> Please tell me that QVT does not permit this. 

=)) The QVT spec drops no hint about it so we are to decide how to handle the case.

> > The second
> > one (proposed by Sergey Boyko) is to allow casting 'List(EClass)' to
> > 'List(EClassifier)' in any cases except initializations, assignments, passing 
> > non-final parameters to operations (for QVT mappings - inout and out parameters
> > and inout context), returning values from operations. Perhaps, there are some
> 
> But, these are precisely the constructs that have assignment semantics and,
> therefore, type conformance concerns.  AFAICS, there is no difference between
> this option and the first.
> 
> 

Well, the second option allows to pass read-only parameters to operations. In QVTO there is an 'in' qualifier for mapping parameters that ensures that the corresponding parameters are read-only. IOW, 'List(EClass)' would be a valid parameter for a method accepting 'List(EClassifier)' provided that the parameter is not changed.

> > other cases to be considered. The third solution - which I do not appreciate,
> > is to forget about it at all and to let users overcome their own troubles ;))
> 
> Hah!  An anti-Eclipsian option, indeed.
>

I see you don't like it either =)))
 
> 
> > This is, of course, subject to another bug which I will raise soon. In any case
> > (except the 3rd solution), for mutable collections we should handle type
> > conformance issues in an other way than described in the OCL spec (7.4.5) which
> > leads me to the conclusion than mutable collections and immutable collections
> > type hierarchy is to be made different.
> 
> I agree.  But, clearly you would be deviating from the QVT spec (which I think
> we agree is deficient in this regard).  Do you foresee compliance/portability
> issues for your users?
> 

Well, since mutable collections in QVTO are yet under construction I do not expect any compliance/portability issues.

> > This would be a more significant patch to the whole OCL/QVT collection type
> > subsystem but for me the ideal solution would be making a common root - e.g.
> > AbstractCollectionType with two subtypes ImmutableCollectionType and
> > MutableCollectionType. OCL collections such as Set, Sequence, etc. would
> > inherit from ImmutableCollectionType while Lists (and maybe Dict?) would
> > inherit from MutableCollectionType. This would help us avoid multiple
> > instanceof-checks in cases where the behaviour differs. The standard predefined
> > operations for these types should be revised as well.
> 
> (just to be clear, I was speaking of revisions to the QVT spec, not your
> implementation)
> 
> This makes sense for a Java API, in particular one that encompasses both OCL ad
> QVT in a single component.  However, from the perspective of OCL as a
> self-contained specification and implementation, it is perhaps difficult to
> introduce classes whose sole purpose is to support extensibility.  Especially
> when the semantics of those classes are fundamentally contrary to the language.
>  In OCL, the MutableCollectionType metaclass would have to be abstract,
> otherwise we would be able to define mutable collection types and, hence,
> mutable collections that would break the language.  But then, obviously OCL
> would not, itself, define any concrete subclasses of MutableCollectionType, so
> OCL would be left with a metaclass that it does not use.  This is not good (we
> already have ElementType and OclElement, which are chaff from 1.x; happily, OCL
> 2.1 eliminates TypeType and OclType).
> 
> I am a firm believer in the Open-Closed principle, but I think this goes beyond
> open.  :-)
> 

MutableCollectionType can placed in QVTO so that OCL would have AbstractCollectionType, ImmutableCollectionType and concrete immutable collection types only. Although there would be some overhead for those who would like to extend OCL in a way QVT does, OCL will not have abstract metaclasses without implementation.
Comment 17 Radomil Dvorak CLA 2009-01-12 08:45:33 EST
Initially, I thought we could solve this issue just by restricting the type conformancy rules for mutable collection types to require the same element type.

But there is yet another aspect to take into account.
Imagine, a variable of OCL collection type (which has been assigned a List) 
might appear to change its contents, if some mutator operations are called on the original List.
Additionally, QVT also does not define how to handle modifications that happen during iteration on mutable collections.

It's bad, I found it pretty useful, if a List can also be queried using all the power given to collection types. Otherwise, it does not offer too much.

Also, if List is not a collection type, the definition of Dict looks odd too, as it exposes keys, values via List type (wierd as well, is that to be a write through List?).
A couple of things point out that the way QVT spec tries to extend OCL with its mutable types is at minimum immature and the ListLiteralExp is just one of the many entries into this maze ;).

>> But, clearly you would be deviating from the QVT spec (which I think
>> we agree is deficient in this regard).  Do you foresee compliance/portability
>> issues for your users?

As Alex said, we have newly introduced List and Dict for the Galileo release. Unfortunately, not implementing it is at the cost of deviation from the OMG spec and getting alligned is our main goal for this release.
Actually, this appears to be the hardest job ever ;).

Not sure yet, whether to rollback where we were or let the users share the pain that an OMG specification may cause (which I don't like as well as all of us).
Comment 18 Alexander Igdalov CLA 2009-02-16 07:41:04 EST
Implemented through a CollectionLiteralExp.
The 'kind' attribute is set to CollectionKind.SEQUENCE_LITERAL. It is ignored on evaluation and validation phases, the CollectionLiteralExp.getType() is checked for being ListType instead. In case an empty list literal is used its type is considered to be OclVoid similarly to OCL collections.
There are still some questions left to be resolved:
1. CollectionType.kind and CollectionLiteralExp.kind are still used in some places in the OCL implementation. These must be checked since to eliminate ambiguities between Lists and Sequences.
2. Mutable collections type conformance problem (see comment #14). Empty lists must be checked as a special case.