Community
Participate
Working Groups
Existing behavior in <3.1.0 allowed users to "define" operation bodies which are retrieved by AbstractEvaluationVisitor.getOperationBody, e.g., by AbstractEnvironment.setBodyCondition(...). Along these lines, the caching of compiled ASTs introduced for 3.1.0 has been designed and implemented. On the other hand, we have the OCL invocation delegate which can be invoked using dynamic Java dispatch where the delegate for the specific implementing subclass will be used to determine the corresponding OCL operation body which may be a redefinition of some definition body provided by a superclass implementation. It seems to me like an inconsistency that invocation through Java + OCL delegates can resolve to a different operation body expression as when invoking from within an OCL expression. We should try to make dynamic dispatch consistent across OperationCallExp evaluation and invocation through delegates. As this may be considered an API change because existing getBodyCondition / getDefinition behavior may have to change, this may have to be a post-Indigo change now.
I don't see the problem. Delegates are a new feature that users may choose to use. It may therefore have any semantics we like; OCL doesn't define them. The new pivot model evaluator prototypes a proposal for static analysis and subsequent dynamic dispatch of same signature. To this end all contributions to a type are gathered together for coherent treatment in a complete type. 'additional' operations are not special. They therefore have URIs which are referencable and persistable. ?? WONTFIX ??
(In reply to comment #1) > I don't see the problem. The OCL spec of OperationCallExp semantics is, as usual, a bit imprecise: "The definition of the semantics of the operation call expression depends on the definition of operation call execution in the UML semantics. This is part of the UML infrastructure specification, and will not be defined here." Replace UML by Ecore, and we can at least reasonably assume that the evaluation of an OperationCallExp referring to an EOperation shall happen according to the Ecore rules. This would IMHO imply dynamic dispatch. Therefore, I consider the behavior as introduced by the delegates as closer to the "spirit" of the spec than what was in the MDT/OCL implementation before. Only now we have an additional problem of an inconsistency. We could rename this bugzilla to something like "OperationCallExp evaluation must support dynamic dispatch" if you think that's more appropriate. > ?? WONTFIX ?? I don't think so.
The OCL specification is precisely imprecise. OCL defers to/aligns with UML. UML defines overload semantics as a variation point. The UML guys were a little surprised when I pointed out that their OCL for specifying UML was dependent on this unspecified chasm. They were actually using covariant overloading in a couple of places: e.g X::f(X) can be overloaded by a derived Y::f(Y). It was agreed that this was inappropriate so UML 2.5 only overloads by Y::f(X). The OCL library spec has a Collection::=(Collection) overload for OclAny::=(OclAny)! So OCL has no semantics today so the old code has a free choice, which I feel we can define as what we have done/acquired. The pivot code observes rigorous overloading which everyone I have discussed it with agrees is what the OCL specification should say and will do once I write up some tooled resolutions. I have no intention of fixing this in the old code; it is not yet wrong. You will find that Bug 291220 identifies more problems to be dealt with to handle overloading. Complete OCL allows injection into OclAny!
Ed, (In reply to comment #3) > The OCL specification is precisely imprecise. OCL defers to/aligns with UML. > UML defines overload semantics as a variation point. The UML guys were a little > surprised when I pointed out that their OCL for specifying UML was dependent on > this unspecified chasm. They were actually using covariant overloading in a > couple of places: e.g X::f(X) can be overloaded by a derived Y::f(Y). It was > agreed that this was inappropriate so UML 2.5 only overloads by Y::f(X). The > OCL library spec has a Collection::=(Collection) overload for > OclAny::=(OclAny)! I see little use in OMG bashing here. Ecore has very obvious and clear execution semantics for operation calls. It's just not pragmatic and counter-intuitive to have OCL operations calls on EMF models not use dynamic dispatch. Yes, I see the effort this will cause in the existing implementation, but that's a different story again. Given your reasoning, one may start wondering why dynamic dispatch should be in the Pivot implementation, particularly as it creates an incompatibility between the evaluation semantics of OCL/Ecore expressions and equivalent OCL/Pivot expressions. > So OCL has no semantics today so the old code has a free choice, which I feel > we can define as what we have done/acquired. I find the spec highly suggestive. It leads me to believe that an OperationCallExp should be evaluated with the given environment's semantics, making the existing choice a bad choice that is very likely to give users trouble and not be what they expect. Quality means to meet user expectations. We may therefore be able to significantly improve the OCL/Ecore quality if we took this seriously. > The pivot code observes rigorous overloading which everyone I have discussed it > with agrees is what the OCL specification should say and will do once I write > up some tooled resolutions. Well, good if we can discuss what it *should* say. This, though, partly invalidates your rigorous point of view regarding the lacks in the OCL spec. All users that I've spoken to in this regard deeply regret the lack of polymorphic resolution of OperationCallExp as it leads to massive extensibility problems when you have a growing base of OCL-defined operations in your Ecore models. It leads to nasty and unmaintainable if/oclIsKindOf cascades. > I have no intention of fixing this in the old code; it is not yet wrong. You > will find that Bug 291220 identifies more problems to be dealt with to handle > overloading. Complete OCL allows injection into OclAny! oclIsUndefinded() redefinition as well as the redefinition of other stdlib-imposed operations, particularly on OclAny, may be a different story. I find it very likely that many users could easily accept a few restrictions regarding polymorphic redefinitions (making a few of those operations "final") if in turn they get true redefinition capabilities on regular Ecore classes.
(In reply to comment #4) > Given your reasoning, one may start > wondering why dynamic dispatch should be in the Pivot implementation, > particularly as it creates an incompatibility between the evaluation semantics > of OCL/Ecore expressions and equivalent OCL/Pivot expressions. There are two plausible delivered semantics. a) whatever we happened to deliver in 3.0, debatable bugs and all b) a convergence with an implementable OMG specification perhaps OCL 2.5 The Pivot model is an attempt at b) and given my dual Eclipse and OMG role, there are reasonable prospects that the principles, but not Eclipse-isms may become part of the OCL specification. The Pivot model looks a long way forward, modelled library, modelled iterators, modelled precedence, UML alignment, persistable XMI, reflective oclType(), internal generics ... dynamic dispatch. Semantic changes to a) are very difficult, because perhaps for every 10 people who like the change there will be one who is broken by the change. Every change is a declared or semantic API fight. An incomplete change that does not fully align with OMG lacks the authority to persuade the broken code of the benefit. The purposes of continuing to supply a) for many years is to ensure that code using a) is not broken. The pivot code can never usurp the traditional namespaces. If you have the man-year of effort to really try to advance the old code, then let's consider it. But if you're only going to tackle low hanging fruit ignoring the numerous difficult issues, particularly Complete OCL and UML, then I'm doubtful that a+++ will be worth the effort compared to making b) acceptable to the a) community given that every enhancement to a) is counterbalanced by reduced effort available for b).
> is a declared or semantic API fight. An incomplete change that does not fully > align with OMG lacks the authority to persuade the broken code of the benefit. > The purposes of continuing to supply a) for many years is to ensure that code > using a) is not broken. The pivot code can never usurp the traditional > namespaces. This gets us back to the discussion of standard compliance and adoption. EMF as something resembling an EMOF implementation has not lacked adoption despite its standard compliance issues. While I'm a fan of working standards, there are a few known issues with the OMG ones in particular, caused by things like the missing need for reference implementations and compliance testing processes. This has turned a number of OMG standards into not very useful documents. I would hope that this is different for OCL, but when I consider the additional cost and effort of OMG compliance of an OCL implementation for people who are on Eclipse with EMF/Ecore, I wonder how far their love towards OMG goes. > If you have the man-year of effort to really try to advance the old code, then > let's consider it. But if you're only going to tackle low hanging fruit > ignoring the numerous difficult issues, particularly Complete OCL and UML, then > I'm doubtful that a+++ will be worth the effort compared to making b) > acceptable to the a) community given that every enhancement to a) is > counterbalanced by reduced effort available for b). Getting back to the subject: polymorphic method invocation should be the standard for OperationCallExp evaluation, and I think we can even read this into the OMG's OCL specification without contradiction. I claim it's the behavior expected by users and go as far as calling the current behavior a bug. If people specify OCL bodies for overriding/redefining operations, these will be invoked polymorphically by invocations coming from Java that are statically bound to an overridden method, but not for polymorphic OperationCallExp expressions statically referring to an overridden operation. I have a hard time imagining an OCL user who depends on (and wants to continue to depend on) this type of behavior. I don't expect such a change to require a person-year of effort. The evaluation of OperationCallExp and the process of obtaining the implementing OCL body is fairly centralized in the evaluation visitor implementation. I expect the major ripples in the impact analyzer which, as it turns out, benefits from the status quo because when tracing back through OperationCallExp it currently only has to consider call expressions referring to the operation whose body is analyzed. This will have to change such that OperationCallExp expressions referring to any operation overridden by the one whose body is analyzed are included in the traceback. Again, obtaining this set of OperationCallExp instances happens in a single place which should make this change feasible in what I would "guesstimate" to be a few days of work.
(In reply to comment #6) > I have a hard time imagining an OCL user who depends on (and wants to continue > to depend on) this type of behavior. Users won't want it as such, but corporations have an understandable desire for upgrading and continuing to experience unchanged behaviour. > I don't expect such a change to require a person-year of effort. This particular change might be a day creeping to a week. I expect to see difficulties in establishing what is an overloaded signature: Integer/EInt/EBigInteger etc. The old code has two (Ecore and OCL) type systems. Also difficulties ensuring that analysis identifies a static overload decision in a compatible way with the evaluation dispatch. Also difficulties for overloaded collection operations and Collection conforms to OclAny. The year guesstimate is for making the current code base coherent, maintainable and extensible fixing the many bugs resolved by the pivot model.
Continuing the mdt-ocl.dev "Partial IA code generated evaluation" discussion. Offering dynamic dispatch in Ecore's visitOperationCallExp will make it slower, but could be done, and might be assisted by some lazy dispatch caches. A behaviour option will be needed to preserve the existing behaviour for QVTo, GMF and other legacy users. This could be on the OCL preference page (Bug 360354). As noted above, I see significant difficulties for overload detection for data types and collections. Given the effect on the Impact Analyzer, looking at the problem from IA users perspective may show the way forward. IA users are variously interested in speed/formality. Where speed is concerned, the new dispatch table evaluator is a useful benefit for interpreted execution, and a dramatic benefit once direct OCL 2 Java code generation is exploited. The direct evaluator potentially eliminates the pivot/Ecore meta-model variation; it operates on Values, EObjects and their EClasses and potentially anything else for which a meta-model is constructable by reflection. If the IA is to be promoted for Juno, it would be good if the IA API is able to exploit the new evaluation environment, even if the full support is not introduced till Juno+1. It appears that the threat of QVTo's demise has sparked new interest. I now see reasonable prospects for QVTo evolving and aligning with the new OCL, so I see even less value in struggling to evolve the Ecore binding for OCL.
*** This bug has been marked as a duplicate of bug 367822 ***
See http://wiki.eclipse.org/MDT/OCL_Limitations for detailed comparison of Ecore and Pivot functionality and OCL 2.5 considerations.