Closed eclipse-ocl-bot closed 1 month ago
By Alexander Igdalov on Sep 28, 2009 06:53
First, I would note that I am treating the term "property" according to 7.5: "For the purpose of this document, we will refer to attributes, association-ends, and side-effect-free methods and operations as being properties."
My solution to the problem is based on section 7.5.3: "A property of the collection itself is accessed by using an arrow ‘->’ followed by the name\ of the property." I would like this statement to be refined so that the arrow-accessor is the only way to refer to a property of a collection. IOW:
1) A property of any object except collections is accessed using '.' navigation 2) A property of a collection is accessed using '->' navigation
The decision whether srcExp.foo()
is an implicit collect shorthand or an operation call must be made statically, i.e. at compilation stage. This decision must be based on the declared type of srcExp.
To my mind, this approach is consistent - it eliminates the ambiguities between implicit collect shorthand and collection property calls. It doesn't require significant changes to the OCL 2.1 specification (just one refinement). It is also 100% backwards compatible with OCL 2.0.
By Alexander Igdalov on Sep 28, 2009 07:16
In our private discussion Ed has composed a good example that checks whether the solution described above preserves the polymorphic behaviour of Object-Oriented languages. It is listed below:
context OclAny def: isCollection() : Boolean = false
context Collection def: isCollection() : Boolean = true
....
let anObject : OclAny = ... in anObject.isCollection()
should work polymorphically.
Although at first it may seem that the accessor-based solution breaks the polymorphic behaviour, a deeper look at the example proves that this approach respects the principles of object-oriented language design.
Regardless of the actual (runtime) type of anObject (which can be a collection or a non-collection) the mentioned above statement is true:
The decision whether
srcExp.foo()
is an implicit collect shorthand or an operation call must be made statically, i.e. at compilation stage. This decision must be based on the declared type of srcExp.
Thus,
let anObject : OclAny = 100 in anObject.isCollection() // evaluated to false\ let anObject : OclAny = Bag{10, 20, 30} in anObject.isCollection() // evaluated to true
This is actually what we expect from this example.
Note that if we somehow managed to find out the actual type at compile stage and produce an implicit collect in the expression below:\ \ let anObject : OclAny = Bag{10, 20, 30} in anObject.isCollection() // evaluated to Collection{false, false, false}\ \ then this would truly break the object-oriented concepts and make the language object-based.
By Ed Willink on Sep 28, 2009 15:40
I am not clear why this Bugzilla has been raised as more than a title at this point.
Alex and myself have significant disagreement as to how the ambiguities from Issue 12948 should be resolved. Since a long thread initially on mdt-ocl-dev that continued off-list was making limited progress, I have undertaken to write up a paper this week endeavouring to present a balanced summary of the alternatives.
Once these alternatives are available for balanced consideration we can decide how to tackle a variety of related TypeType, Element, OclAny, Classifier, Collection issues.
These should not be tackled or discussed piecemeal. The OCL 2.0 and 2.1 specifications are seriously flawed, we cannot cherry-pick convenient sub-justifications, we must identify a coherent solution, prototype it and submit it to the RTF for consideration as an implementable OCL. Obviously we would like to achieve as much compatibility with the OMG spec as possible, but one of many difficult decisions may be whether we consider OCL 2.0 or OCL 2.1 compatibility to be paramount. I think we are aiming to achieve the language advances of OCL 2.1 while minimising OCL 2.0 incompatibilities.
The first three comments demonstrate the severe problems of interleaved email threads. It is difficult to establish a coherent meaning. I do not know what comment #2 advocates beyond being fairly sure that I don't agree with it.
We need to work with a base document, discuss contentious points, revise the document, discuss/vote etc. Discussion alone does not work. Once we have some kind of plan, we probably want to publish the document to the newsgroup for comments.
By Adolfo Sanchez-Barbudo Herrera on Sep 28, 2009 18:25
Hi all,
I hope to read all emails soon, so that there is another point of view on this.
Another consideration which could be taken is that solving or deferring the issue could imply an innecesary MDT-OCL major release increment in the future (not acceptable for a bug only). I think that we must adopt a solution as closer as the specification states, but if we foresee that it's a horrible change which will be rolled back in an early OCL 2.3, I would inclined on not adopting the change.
I agree that a more concise info about the best solution would help, so I guess we could wait until your paper.... I had some ideas about all this OCL 2.0 to 2.1/2.2 changes, but sinceresly no time for it ;P
We have a lot of work in hands, and I suppose that we can wait some milestones before tackling this.
I think that the bugzilla is helpful. We could focus the discussion on this concrete issue rather than dev list or emails.
Cheers,\ Adolfo.
By Ed Willink on Sep 29, 2009 04:16
Created attachment 148303 (attachment deleted)\
OclAny options paper
Attached reviews the options for OclAny.
Do we have anywhere in CVS to put sources for the above and the plugins/features drawing?
By Alexander Igdalov on Sep 29, 2009 08:34
(In reply to comment #3)
I am not clear why this Bugzilla has been raised as more than a title at this point.
During QVTO development I realized that bugzilla is the best place to hold discussions on how to understand and implement OMG specifications. It is clear, trackable and public. To me, it is much better than a bundle of branching e-mail messages on the dev list. Moreover, the discussion in this bug would be a good start for the final document sent to OMG and published on the wiki and in the newsgroup.
(In reply to comment #5)\ I have several comments on the attached paper. They fall into 3 sets.
Comments on Liskov Substitution Principle
Example error in your paper
Analysis of your approach (COH')
First of all, the Principle itself:
"Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T."
The original paper (http://reports-archive.adm.cs.cmu.edu/anon/1999/CMU-CS-99-156.ps) explains the term "property" used in the statement above. The Principle is not about any kind of properties provable about objects, but about behavioural properties only. It is rather about the runtime execution, not about syntactic notation. I would like to recapitalize that accessor-based solution (or DON' as you call it) solves the ambiguity before the AST is created and thus, doesn't influence the runtime behaviour. Therefore, the Liskov Principle is not applicable here.
Secondly, though it is wise to follow the principle, its violations do not always lead to practical problems. See http://en.wikipedia.org/wiki/Liskov_substitution_principle
def: OclAny::isCollection() : Boolean = false\ def: Collection::isCollection() : Boolean = true
let aCollection1 : Collection = Set{}\ in aCollection1.isCollection() -- error, value is invalid
As I see it, the last expression is an attempt to use the implicit collect shorthand which is successful because isCollection() is defined on OclAny. The result will be another collection equivalent to aCollection1->collect(i|i.isCollection()). See comment #2.
def: OclAny::foo() : Boolean = false
What is then aCollection.foo()
? An operation call on the collection or an implicit collect shorthand? It seems that this solution doesn't actually solve the problem but just introduces weird supplementary syntax.
By Ed Willink on Sep 30, 2009 03:04
Created attachment 148390 Revised analysis
Great; we have progress. Your point 3 is crucial although the same as point 2. We do not need to waste time discussing the applicability of LSP to static behaviour.
My analysis of the Implicit Collect Ambiguity is ok, but the identification of the causes of the ambiguous RHS is not. The ambiguous RHS may arise from either ICAco (E->F equivalence to E.F) or ICAof (simple inheritance as in your point 3); see revised analysis.
All discussion of CHO' is therefore irrelevant, since the associated ICA' analysis ignores ICAof.
In the absence of a credible DON'' or CCO' or DIC' proposal, my analysis seems to prove an incompatibility between CCO + DON and DIC, which DON' fully resolves at the expense of static LSP violation.
Since DON' differs from DON through a statically determined property, we can at least offer a warning message when DON' rather than DON compiles a DIC syntax, and a better error message when DON' rather than DON gives a syntax error.
To re-instate LSP requires abandoning implicit collect and migrating collection operations from arrow to dot. Such a big compatibility issue that it's hardly worth raising an OMG Issue for.
Specifying DON' rather DON is potentially just a matter of tightening up some loose and inconsistent statements. Mariano might manage to do this as an editorial clean-up without a further RTF vote. Is the attached ready for submission to OMG? Any suggestions on where to put it in CVS?
We probably agree that DON' is what we now implement. Once stdlib represents the correct type conformance, OCLAbstractAnalyzer can exploit it. I'm happy to do the analyzer but don't have time for more than 'supervision' of the library.
I suspect that the current type conformance code is distributed and inconsistent, and so may need careful analysis and revision rather than just a couple of tweaks.
By Alexander Igdalov on Sep 30, 2009 08:39
(In reply to comment #7)
Created an attachment (id=148390) [details] Revised analysis
Great; we have progress.
It's good that we are agreed to implement the accessor-based approach. I would still like Adolfo and Laurent to +1 this solution or say whether they have objections/supplements/other ideas.
We do not need to waste time discussing the applicability of LSP to static behaviour.
It seems we have different vision of LSP. I agree not to proceed discussing this principle in case we eliminate all references to it from the description of the accessor-based solution. Violation of LSP though softened with the words "static behaviour" still sounds threatening. IMO we have a different case.
Since DON' differs from DON through a statically determined property, we can at least offer a warning message when DON' rather than DON compiles a DIC syntax, and a better error message when DON' rather than DON gives a syntax error.
Not sure I understand you. Could you give some examples?
Is the attached ready for submission to OMG?
I would like to make some improvements before the paper is sent to OMG. As I have mentioned, I object to references to LSP because I consider it to be improperly used.\ The attached document also criticises the wrong usage of the word "property" in the specification. As mentioned in comment #1, section 7.5 gives a definition of this term. In particular, according to 7.5, operations are properties.\ The last remark is about the overall style of the paper. I agree that clever guys might use the TLA style to express their thoughts, but apparently I am not in that number;) I'd rather use plain English to describe the problem and its solution. Why don't we just rewrite that sentence in 7.5.3 stating that "A property of the collection itself is accessed by using an arrow ‘->’ followed by the name of the property. This is the only way to refer to a property of a collection."? If a more detailed description is needed I would refer to comment #0 (the problem) and comment #1 (the solution).
Any suggestions on where to put it in CVS?
o.e.mdt/o.e.ocl/doc ?
We probably agree that DON' is what we now implement. Once stdlib represents the correct type conformance, OCLAbstractAnalyzer can exploit it. I'm happy to do the analyzer but don't have time for more than 'supervision' of the library.
In case we all agree on the solution I would be glad to make a patch to the bug (both the analyzer and stdlib) by myself.
By Laurent Goubet on Sep 30, 2009 09:11
(In reply to comment #8)
(In reply to comment #7)
Created an attachment (id=148390) [details] [details] Revised analysis
Great; we have progress.
It's good that we are agreed to implement the accessor-based approach. I would still like Adolfo and Laurent to +1 this solution or say whether they have objections/supplements/other ideas.
To be honest, I couldn't make any sense out of comment #7. I might be the only one, but 31 acronyms in 28 lines of text is enough for me to stop even trying to understand, and simply reject the thing. Based on this, I am in favour of your solution that 'any property call on Collection is made using ->' so anything with a '.' would be an implicit collect. If that's indeed what we need to +1, you have mine :).
By Adolfo Sanchez-Barbudo Herrera on Sep 30, 2009 09:48
Hi All,
I'm glad that both have aligned ideas and you have got a same approach to solve this. Fortunately, I'm not going to put a rock in the way which may avoid making this progres ;).
About the paper, congratulations Ed. Very instructive, a little bit hard to follow when having a lot acronyms, but this is only another point which demonstrates the complexisty of the situation. Anyway, I could finally got it ;).
My opinion:\ I think that I could sumarize the problem with these simple statements, assupmting that we want to adopt making Collections conform to OclAny (CCO):
If we don't want make an OCL user dramatically change the way he uses OCL, we should keep the current language usage so that aCollection->size(), is the call to an operation and aCollection.size() is the implicit collect. So OCL 2.1 + DON' should be choosen.
On the other hand, we would like to matain the LSP so that aCollection.size() is the call to the operation. The problem is obviously that in order to resolve ambiguities we would have to change mind of the current OCL user, so that he has to use . (or the unnecesary -> ) to call a collection operation, and learn that the implicit collect which uses the . accessor, doesn't exist anymore. So OCL 2.1 should be chosen to avoid that LSP issue.
In principle I would be inclined on 1. Furthermore, I think that it's not a problem of LSP violation, but it's problem of notation. Any (Object Oriented) Collection is able to expose an operation of its supertype (like any other object), but there is a subtle difference in the notation. So you are allowed to invoke any operation of a object/expression, regarddles it is a Collection or any other type.
The OCL user only has to know that in order to invoke an operation of a collection (regardless the operation is defined on Collection or OclAny) he has to write '->', otherwise he would be invoking an implicit collect or receiving an error (depending on the type of its elements).
Fortunately, the OCL user already knows that, and this subtle difference in the notation just comes from the sensible need of "Not having to change the OCL users mind".
From my point of view, what OCL 2.1 needs to clarify and not beeing contradictory about how properties are accessed: '->' for sources whose type (computed at compile-time) are Collections and '.' for sources whose type is distinct to Collections.
Cheers,\ Adolfo.
By Ed Willink on Sep 30, 2009 15:48
In Reply to #8
I thought I had demoted LSP significantly by moving it from an implicit specification to just a localised footnote, with the 'static' qualification.
With no other contenders an LSP surprise (rather than violation) DON' is easily the least bad option. Sadly we cannot find a solution that is surprise-free.
Feature is the correct UML term, which OCL is catching up with much too slowly.
One day some enthusiast may submit a resolution with revised text for all occurences.
Go for it on stdlib, but please consider the variety of other stdlib issues that may need addressing by a refactoring too. I think the analyzer might just work. It's probably on warning messages that extra code is needed.
I was not quite right in referring to a 3-way amibiguity. From a user perspective only two ever exist, since the Collection::size() and OclAny::size() ambiguity will be dynamically resolved to Collection::size(). The three way ambiguity exists solely in whether the AST references the base or the derived operation.
We should have some JUnit tests verifying that def OclAny::size() is correctly resolvced dynamically to Collection::size().
Example better error and warning:
aCollection.size()\ -- Error: Collection::size() could be accessed using ->size().
def OclAny::size() : Integer\ aCollection.size()\ -- Warning: This is an implicit collect of OclAny::size();\ Collection::size() could be accessed using ->size()\ or OclAny::size() could be accessed using .oclAsType(OclAny).size()
The warning should be suppressable as a ParsingOption.
By Alexander Igdalov on Oct 01, 2009 07:26
It's great that we have agreed. I am starting to work on the bug.
(In reply to comment #11)
In Reply to #8
I thought I had demoted LSP significantly by moving it from an implicit specification to just a localised footnote, with the 'static' qualification.
With no other contenders an LSP surprise (rather than violation) DON' is easily the least bad option. Sadly we cannot find a solution that is surprise-free.
Let's call it an exception from the general property call notation. I just don't like LSP used here. It sounds too impressive.\ For example, RuntimeException is not declared to be thrown in method signatures in Java. However, Exception which is the base type of RuntimeException must be declared. But no one calls it a violation from LSP because it is related to notation only.
Feature is the correct UML term, which OCL is catching up with much too slowly.
One day some enthusiast may submit a resolution with revised text for all occurences.
Agreed.
Go for it on stdlib, but please consider the variety of other stdlib issues that may need addressing by a refactoring too. I think the analyzer might just work. It's probably on warning messages that extra code is needed.
I was not quite right in referring to a 3-way amibiguity. From a user perspective only two ever exist, since the Collection::size() and OclAny::size() ambiguity will be dynamically resolved to Collection::size(). The three way ambiguity exists solely in whether the AST references the base or the derived operation.
We should have some JUnit tests verifying that def OclAny::size() is correctly resolvced dynamically to Collection::size().
Example better error and warning:
aCollection.size() -- Error: Collection::size() could be accessed using ->size().
Yes, this error message is very helpful. +1.
def OclAny::size() : Integer aCollection.size() -- Warning: This is an implicit collect of OclAny::size(); Collection::size() could be accessed using ->size() or OclAny::size() could be accessed using .oclAsType(OclAny).size()
The warning should be suppressable as a ParsingOption.
I am inclined to consider it the least bad option. I have always thought of warnings as signals for the user that something bad/obsolete/weird is done that will work though. IOW, something that is better to rewrite. This case is different. Here the user calls a shorthand (possibly what is actually intended). But we must somehow inform him to be especially attentive there. I would set the severity level of this warning message as INFO so that it can be suppressed as a ParsingOption. IOW, +1.\ There is a small typo in the message text though. Should be "...\ or OclAny::size() could be accessed using ->oclAsType(OclAny).size()". Or maybe part of the message could even be omitted?
Your comment reminded me that there is no dynamic binding in OCL. IOW,
context OclAny\ def: isInteger() : Boolean = false
context Integer\ def: isInteger() : Boolean = true
let anObject : OclAny = 1 in anObject.isInteger()
is evaluated to false because OclAny::isInteger() is called (not Integer::isInteger()). Please, correct me if I am wrong here.
By Alexander Igdalov on Jan 18, 2010 11:43
Created attachment 156407 Initial patch for Collections conforming to OclAny
Hi all,
This patch is expected to make Collections conform to OclAny. However, there are still some annoying problems which I will describe in more specific bugs. One of them has been recently caught by Ed in bug 299882. Another one is Laurent's bug 286929.
There is one thing I am not sure about in my patch. I do not know whether my insertion into UMLEvaluationEnvironment.isKindOf() method has been done in the best place. Perhaps, it should be made at the beginning of the method. Since I am not a very big UML2 expert I would be thankful if someone could pay special attention when reviewing that method.
Regards, -Alex.
:notepad_spiral: patch.txt
By Ed Willink on Jan 18, 2010 11:54
This is very awkward. You are trying to make the existing code base work.
In the ReflectiveLibrary branch, I am converting the code to be model-driven and so expect to fix about 20 bugs, some of which explicitly call for a model-driven approach.
We cannot pursue both approaches so I'm afraid that I must "-1" since I do not have time to review it and cannot incorporate it. Unfortunately you didn't provide any clues that you were going to work on this. When I requested assistance in resolving library and evaluatir bugs, there was no response, so I reluctantly undertook to do it myself.
By Alexander Igdalov on Jan 18, 2010 12:03
(In reply to comment #13)
However, there are still some annoying problems which I will describe in more specific bugs. One of them has been recently caught by Ed in bug 299882. Another one is Laurent's bug 286929.
Further on this:
Bug 299957 - Cannot specify CollectionType in type operations on OclAny\ Bug 299959 - [library] OclAny::oclAsType() doesn't check the source type
By Alexander Igdalov on Jan 18, 2010 12:14
(In reply to comment #14)
This is very awkward. You are trying to make the existing code base work.
In the ReflectiveLibrary branch, I am converting the code to be model-driven and so expect to fix about 20 bugs, some of which explicitly call for a model-driven approach.
We cannot pursue both approaches so I'm afraid that I must "-1" since I do not have time to review it and cannot incorporate it. Unfortunately you didn't provide any clues that you were going to work on this. When I requested assistance in resolving library and evaluatir bugs, there was no response, so I reluctantly undertook to do it myself.
Hi Ed,
I think we will eventually merge both patches - or are you fixing this issue as well in the branch? The question is whether you feel the ReflectiveLibrary branch is stable enough to be committed. If yes, we can commit it first and then I will merge this patch with it. If not, I think we could commit the patch to HEAD and commit (possibly modified) patch to the branch.
I will look at the branch tomorrow to see how my changes could be merged with it.
By Ed Willink on Jan 18, 2010 12:25
(In reply to comment #16)
I will look at the branch tomorrow to see how my changes could be merged with it.
Good. There is a lot that is working very nicely with the new approach.
My plans are to try to commit it in two phases.
Phase 1 (hopefully before M5):
The evaluator is converted to resolve all operations via the binding-neutral standard library.
For compatibility, the OclAnalyzer continues to generate Ecore/UML specific binding references, so the evaluator lazily builds a mapping from Ecore/UML operation URIs to generic URIs.
This phase is a lot of work; nearly done. It poses few API compatibility challenges; the functionality is mostly extra.
Currently only Ecore tests run; some trivial bug in the UML resource initialisation I hope.
Phase 2 (before M6):
The analyzer is converted to generate neutral operation URIs, and the evaluator uses them directly.
The compatibility for old-style Ecore/UML URIs is retained.
This involves relatively little code, but my first experiment hit severe API challenges.
Any help progressing/reviewing is very welcome.
By Alexander Igdalov on Jan 19, 2010 13:19
Created attachment 156539 Interim patch for the reflective library branch
This patch contains an interim implementation of the issue targeted for the reflective library branch. After phase 2 the major part of the patch is to be refactored.
I came across two issues when running the tests from this patch.
First, there is numeric type coercion on evaluation entry point which handles numeric types. However, it doesn't handle collections of numeric types so that evaluation of a Sequence of Integers in OCL results in Java's ArrayList
Secondly, let c : OclAny = Bag{1, 2} in c->size()
evaluates to 2 instead of 1 since now c->size()
is implicitly converted to c.oclAsCollection()->size(). On the contrary, the implementation in HEAD would implicitly wrap c
into a Set, i.e. Set{c}->size()
so that let c : OclAny = Bag{1, 2} in c->size()
becomes Set{Bag{1, 2}}->size()
. I don't know yet whether this change is good or bad... But I think it is subject to an OMG issue.
:notepad_spiral: patch.txt
By Ed Willink on Jan 19, 2010 16:35
Alex: If you write tests in the style of o.e.o.tests.GenericXXX they will work on both Ecore and UML and ... bindings. The assertQueryXXX functions make for shorter more readable tests and better per sub-test diagnosis.
You've got some interesting overloading, so maybe this should be the start of a suite of EvaluateOverloadTests. Could you evolve your new tests into a GenericEvaluateOverloadTests.java and I'll make them work?
I'm puzzled by StatesTest on the Ecore bindings. States only exist in UML.
I'm not sure about fixing the code-based Collection conformance in this branch where the goal is model-driven Collection conformance. I'm very reluctant to change the existing code where a function is defined\ a) in Ecore modelled model\ b) in Ecore Java-code model\ c) in UML modelled model\ d) in UML Java-codemodel\ e) in result-type predictor\ f) in evaluation visitor\ The new approach defines it just in the generic modelled model.
I'm hoping that the old code will just go obsolete. The result predictor is all private so that should be able to reference the model easily....
By Ed Willink on Jan 19, 2010 16:49
(In reply to comment #18)
First, there is numeric type coercion on evaluation entry point which handles numeric types. However, it doesn't handle collections of numeric types so that evaluation of a Sequence of Integers in OCL results in Java's ArrayList
.
The API has always been vague; potentially returns could be all over the place. Inputs could mostly be any type, but not for all purposes.
I think evaluate() should do a deep normalisation to BigXXX on input, and a joint ceoercion to a minimum type on output. This gives a high probability of compatibility while supporting extended functionality.
rawEvaluate() gives the predictable BigXXX always behaviour.
By Ed Willink on Jan 19, 2010 16:58
(In reply to comment #18)
Secondly,
let c : OclAny = Bag{1, 2} in c->size()
evaluates to 2 instead of 1 since nowc->size()
is implicitly converted to c.oclAsCollection()->size(). On the contrary, the implementation in HEAD would implicitly wrapc
into a Set, i.e.Set{c}->size()
so thatlet c : OclAny = Bag{1, 2} in c->size()
becomesSet{Bag{1, 2}}->size()
. I don't know yet whether this change is good or bad... But I think it is subject to an OMG issue.
This is the consequence of static determination of c->size() that we agreed was the only not very bad approach. [You may or may not like calling it a Liskov Substitution Principle violation but it demonstrates that the language is surprising (broken).] This isn't a new OMG Issue. It is a resolution explaining quite what the corrolaries of Collection conforms to OclAny is with respect to other language features. I've written most of it by revising from our earlier discussion.
oclAsCollection() is my experimental resolution of the problem that for non-Collection x
x-> means Set{x}->
but
null-> means Bag{}->
and of course x may be null at run-time, so MDT OCL 1.3.0's assumption that x-> can be converted at compile time to Set{x} is not valid.
By Alexander Igdalov on Jan 19, 2010 17:45
(In reply to comment #21)
After further thinking about this problem, I found the current behaviour of oclAsCollection to be not well-formed.
Consider defining a new operation on OclAny:
def OclAny::foo() : Integer = 1;
The code in branch considers the following expressions to be equivalent
let c : OclAny = Bag {1, 2} in c.foo();\ let c : OclAny = Bag {1, 2} in c->foo();
To my mind, these expressions shouldn't be synonyms.
I would propose x->foo()
to be at COMPILE-time resolved to:
a) invocation of foo() on x
if the DECLARED type of x
is a CollectionType\
b) Collection{x}->foo() if the DECLARED type of x
is NOT a CollectionType
-- at evaluation-time b) would turn into:\
b1) Set{x}->foo() if the DECLARED type of x
is NOT a CollectionType AND x is NOT null.\
b2) Bag{}->foo() if the DECLARED type of x
is NOT a CollectionType AND x is null.
I am basing my judgement on 9.6: "As a general guideline nothing will be implicit (for example, implicit collect, implicit use of object as set, etc.) and all iterator variables will be filled in completely. The mapping is not formally defined in this document but should be obvious."
... It seems that this case is obvious for us in a different manner))
Moreover, I agree that sentence is contradicting with null-to-empty-Bag conversion, therefore, it should be changed to "..for example, implicit collect, implicit use of object as Collection...".
By Ed Willink on Jan 21, 2010 15:42
Following the mdt-ocl thread discussion
x->foo()
Compile-time (static type)
a) x is a Collection: x->foo().\ b) x is not a Collection: x.oclAsSet()->foo()
Run-time (dynamic type)
b1) x is not null so x.OclAny::oclAsSet()->foo() => Set{x}->foo()\ b2) x is null so x.OclVoid::oclAsSet()->foo() => Set{}->foo()
By Ed Willink on Jan 30, 2010 02:10
I'm trying to categorise tests that do not pass in the ReflectiveBranch. Laurent's new test:
assertQueryFalse(null, "Sequence{4, 5, 'test'} = OrderedSet{4, 5, 'test', 5}");
currently fails in the analyzer because
I went back to the initial patch hoping to find the fix.
I therefore skimmed the initial patch to see whether we want to commit it anyway now that the ReflectiveLibrary will not be in Helios. The various fixes all look like like plausible progress, but the context of many is difficult to fully understand, so I'm inclined to commit it since tests don't break. But I would like to see the new Ecore/UML test as shared code.
I would also like to see the fix for Sequence=OrderedSet that I think means copying all the OclAny operations into all the Collections in {Ecore,UML} variants of oclstdlib {EMF-'model',Java-code}.
By Ed Willink on Jan 31, 2010 04:09
I've now merged the 'initial' patch into the ReflectiveLibrary branch and fixed many more OclAny conforms issues such as getAllCollectionOperations() now invoking getAnyOperations() and corresponding getCollectionResult...
I'll look at trying to merge the non-Library aspects of the branch back into HEAD so that many of the evaluator and library bugs are fixed for Helios.
By Alexander Igdalov on Jan 31, 2010 14:51
(In reply to comment #25)
I've now merged the 'initial' patch into the ReflectiveLibrary branch and fixed many more OclAny conforms issues such as getAllCollectionOperations() now invoking getAnyOperations() and corresponding getCollectionResult...
I'll look at trying to merge the non-Library aspects of the branch back into HEAD so that many of the evaluator and library bugs are fixed for Helios.
Hi Ed,
I'd like to avoid duplication here. Should I postpone my modifications to this patch while you are merging it with other issues you fixed?
Regards,\ -Alex.
By Ed Willink on Feb 01, 2010 02:40
Alex: Yes, there is no point duplicating.
I'm trying to merge now. It's quite painful. I have the tests merged which reveals 90 failures in the Ecore tests for which corresponding non-test code needs merging to provide fixes.
The merge is hampered by needing to undo bug 290605. Would you care to review it, at least in principle, to see whether we want it in M6 after all.
By Ed Willink on Feb 01, 2010 07:23
Created attachment 157766 Merge of ReflectiveLibrary tests
Sorry. This is not going to be possible. Attached is my work-in-progress merge of the tests from the ReflectiveLibrary branch. There have 119 Ecore failures (compared to 26 in the branch and those highlight suspect functionality that are arguably bugs in HEAD). The extra tests include Laurent's new tests revised to match what I think is right. They therefore all pass in the ReflectiveLibrary branch.
There are perhaps 20 fixes which should be reviewed one at a time, but there is not time to support the typical 2 to 4 week delay, and we have seen that Eclipse tooling causes major trouble when overlapping patches are submitted.
It is clear that merging a significant development branch is going to be very hard. I'm afraid that I don't have time to do this more than once, so I'll try to post a set of orthogonal patches, and a jumbo patch against the final 3.0.0 code, so that reviews can complete for M1.
If you want to try rescuing bits of CollectionUtil and ObjectUtil that await a more comprehensive merge, you are welcome to try.
However my feeling is that 3.0.0 has major behind the scenes improvements in the parser with minor syntax enhancements. There is no way we can claim that we have completed the transition to 'OCL 2.1' rather much old behaviour persists. We should leave it rather than create a half-way house that will be resolved by the merge from the ReflectiveLibrary branch.
We should endeavour to restrict ourselves now to simple local fixes.
:notepad_spiral: Bug290680.patch
By Alexander Igdalov on Feb 01, 2010 08:11
(In reply to comment #28)
Ed, I have read your previous comment but I am not sure I understand your opinion about this bugzilla. Do you think we should have the patch in M6 or proceed with it in our next release only?
By Ed Willink on Feb 01, 2010 12:06
With specific regard to this bug, I give a +0 for incorporation of the patch; not in favour but not violently opposed.
Collection non-conformance with OclAny is hard coded in many places. It is difficult to correct them all; I identified two significant further coded places and two further semi-modelled places that your patch missed. I think we therefore risk introducing a late change that only accomplishes half its goal.
Collection conformance with OclAny is poorly considered in the OCL specification. We have had interesting detailed discussions about trying to resolve the corrolaries. I think we reached agreement, but I'm not sure that the code has caught up. I raised a new issue yesterday, number still pending, whereby the signature of Collection::=(Collection(T)) should be Collection::=(OclAny) in order to override OclAny::=(OclAny). This signature issue requires that OCL specify to what extent overloads are resolved statically and to what extent dynamically. I suggest that a Java-like policy of selecting the most derived conformant signature statically and then doing dynamic dispatch of precisely that signature on the self object at evaluation time. We need to implement this, which means we need to get the signatures right.
With regard to related bugs, I have found too many fixes to easily disentangle and so have abandoned the attempt to merge the non-Library non-BigNumber parts of the ReflectiveLibrary branch into Helios.
I plan to take a quick pass over all the bugs to see if there are any trivial ones. I'll then submit independent patches against HEAD as of M5.
By Ed Willink on Feb 01, 2011 01:59
Collection conformance to OclAny is defined by the stndard library model.
By Ed Willink on May 27, 2011 06:41
Resolved for Indigo is 3.1.0 not 3.2.0.
By Ed Willink on May 29, 2012 13:22
Closing all bugs resolved in Indigo.
By Ed Willink on Feb 16, 2019 14:55
(In reply to Ed Willink from comment #31)
Collection conformance to OclAny is defined by the stndard library model.
The RESOLVED FIXED is confusing. Very little if any Collection-conforms-to-OclAny was merged from the Reflective Library branch. It was abanoned as too hard.
The comment only makes sense wrt to the evolving Pivot OCLstdlib model.
Today's comment on https://issues.omg.org/browse/OCL25-77 suggests that direct Collection-conforms-to-OclAny be abandoned in favour of wrapping ElementalCollection types.
By Ed Willink on Jul 16, 2021 04:29
Bug 574884 follows the OCL 2.5 RFP and a new commont on https://issues.omg.org/browse/OCL25-77 to introduce a C-like Union type so that where Collection/OclAny polymorphism is really needed it can be declared as needed. A Union also supports strong declaration of a Tree.
| --- | --- | | Bugzilla Link | 290680 | | Status | CLOSED FIXED | | Importance | P3 normal | | Reported | Sep 28, 2009 06:03 EDT | | Modified | Jul 16, 2021 04:29 EDT | | Version | 3.0.0 | | Blocks | 156363 | | See also | 574884 | | Reporter | Alexander Igdalov |
Description
The 09-05-02 specification of the OCL languages proclaims OclAny as a supertype of all objects including Collections (8.2):
"Issue 12948: Making OclAny denote any object\ AnyType is the metaclass of the special type OclAny, which is the type to which all other types conform. OclAny is the sole instance of AnyType. This metaclass allows defining the special property of being the generalization of all other\ Classifiers, including Classes, DataTypes and PrimitiveTypes."
However, the specification does not clearly state how to implement this amendment. It is possible to understand the specification like this: "Properties of any object can be accessed using '.' navigation". If it is true then the specification becomes ambiguous. The example below proves this:
Let's define a new operation
foo()
on OclAny. An expressionaCollection.foo()
can be considered either1) an implicit collect shorthand, the same as: aCollection->collect(i|i.foo()) 2) invocation of foo() on aCollection itself, which is the same as: aCollection->foo()
In my next comment I will sum up my solution to the problem. Ed has some alternative ideas. I would ask the team to discuss pros and cons of each approach and decide how we are going to proceed.