eclipse-ocl / org.eclipse.ocl

Eclipse Public License 2.0
0 stars 0 forks source link

[language] Refine OMG Issue 14197: OCL 2.0, 2.1 inconsistent definition of null and invalid #453

Closed eclipse-ocl-bot closed 2 hours ago

eclipse-ocl-bot commented 2 hours ago

| --- | --- | | Bugzilla Link | 291721 | | Status | CLOSED FIXED | | Importance | P3 normal | | Reported | Oct 08, 2009 06:25 EDT | | Modified | May 27, 2011 06:40 EDT | | Version | 1.3.0 | | Blocks | 318248 | | Reporter | Ed Willink |

Description

Bug 282882 identified the inadequacies of OclVoid and OclInvalid definitions and provided a significant renaming patch.

Bug 281849 was pretty much a duplicate.

These provoked the raising of OMG Issue 14197 with substantial revised text.

Bug 291623 got sidetracked by detailed null handling, which provoked me to suggest refining that resolution. Achim endorses the suggestion.

This thread is initially for discussion of Issue 14197 and then for implementing it.

Repeating Alex's comments that seem unarguable

  1. oclAsType(), oclIsKindOf(), oclIsTypeOf() invoked on invalid must return\ invalid regardless of the operation argument (even if it is invalid). This\ is done in accordance with the spec.

def OclInvalid::oclAsType(type : Classifier) : T = invalid\ def OclInvalid::oclIsKindOf(type : Classifier) : Boolean = invalid\ def OclInvalid::oclIsTypeOf(type : Classifier) : Boolean = invalid

3.\ null.oclAsType(OclInvalid) -- returns invalid\ null.oclAsType(SomeTypeNotOclInvalid) -- returns null // the only deviation

def OclVoid::oclAsType(type : Classifier) : T =\ if type = OclInvalid then invalid else null endif

But Alex wrote

  1. oclIsKindOf(), oclIsTypeOf() invoked on null must return invalid\ regardless of the operation argument (even if it is OclVoid or OclInvalid).\ This is done in accordance with the spec.

I think

def OclVoid::oclIsKindOf(type : Classifier) : Boolean =\ if type = OclInvalid then invalid else true endif\ def OclVoid::oclIsTypeOf(type : Classifier) : Boolean =\ type = OclVoid

both of which are the inherited OclAny behaviour (well it would be if OclAny defined false as the return when the preducate for a true return is not satisfied.)

Also

null.oclIsInState(...) => false

def OclVoid::oclIsInState(statespec : OclState) : Boolean = false

Philosophically; null is an object that exists, has a type (conformant to all types except OclInvalid) but does not have a value. Therefore any type-based operation behaves like OclAny, any value-based operation needs consideration.

This suggests that

def OclVoid::toString() : String = ???

not sure how to spell null; perhaps $null$

and then does

def OclInvalid::toString() : String = $invalid$

eclipse-ocl-bot commented 2 hours ago

By Laurent Goubet on Oct 08, 2009 08:10

I fully agree with all suggestions made here in comment #1, except for the two "toString". I'd rather remove the '$' here :

def OclVoid::toString() : String = null\ def OclInvalid::toString() : String = invalid

There cannot be any confusion with Java's null : OCL cannot return it (well ... it does in the current implementation, that's another issue), so let's just use the common names. If I type "null" in the OCL console, and it returns me "$null$", I'll just get confused :).

eclipse-ocl-bot commented 2 hours ago

By Alexander Igdalov on Oct 08, 2009 14:56

(In reply to comment #0)

But Alex wrote

  1. oclIsKindOf(), oclIsTypeOf() invoked on null must return invalid regardless of the operation argument (even if it is OclVoid or OclInvalid). This is done in accordance with the spec.

I think

def OclVoid::oclIsKindOf(type : Classifier) : Boolean = if type = OclInvalid then invalid else true endif def OclVoid::oclIsTypeOf(type : Classifier) : Boolean = type = OclVoid

both of which are the inherited OclAny behaviour (well it would be if OclAny defined false as the return when the preducate for a true return is not satisfied.)

Ed, at first I wanted to define oclIsKindOf() and oclIsTypeOf() on null just the way you did above. As you have mentioned, this behaviour is inherited from OclAny. But then I recalled that in Java null instanceof SomeType returns false. This behaviour is very sensible - it lets users avoid checks when type-checking is accompanied with subsequent type-casting. This can be illustrated by the example at http://hanuska.blogspot.com/2006/08/tricky-instanceof-operator.html

To get aligned with Java (oclIsKindOf() is a synonym of 'instanceof' in OCL), we could redefine null.oclIsKindOf(SomeType) so that it would return false regardless of SomeType argument (well, if SomeType is OclVoid it is arguable). It contradicts the OclAny::oclIsKindOf() behaviour but is sensible and is aligned with Java. If we follow this approach we should redefine OclVoid::oclIsTypeOf() in the same manner. IOW, we would do something like:

def OclVoid::oclIsTypeOf(type : Classifier) : Boolean = false.

Very confusing, isn't it?

The considerations above made me feel that following the spec for OclVoid::oclIsKindOf() and OclVoid::oclIsTypeOf() (i.e. return invalid) is the least bad option.

(In reply to comment #1)

I fully agree with all suggestions made here in comment #1, except for the two "toString". I'd rather remove the '$' here :

def OclVoid::toString() : String = null

Did actually you mean

def OclVoid::toString() : String = 'null' ?

def OclInvalid::toString() : String = invalid

+1

eclipse-ocl-bot commented 2 hours ago

By Alexander Igdalov on Oct 08, 2009 15:02

(In reply to comment #2)

To make myself clear:

def OclInvalid::toString() : String = invalid

+1

I mean that invalid.toString() should return invalid (an instance of OclInvalid) not a string literal which value is 'invalid'.

eclipse-ocl-bot commented 2 hours ago

By Ed Willink on Jan 18, 2010 11:49

I have just submitted an OMG resolution suggesting that all oclXXX have explicit and useful reflective semantics. This was motivated by observing that a variety of well-formedness rules currently use oclIsTypeOf(OclVoid) and oclIsTypeOf(OclInvalid) in ways that only make sense if there are explicit overloads such as:

def OclVoid::oclIsTypeOf(Classifier c) : Boolean = c = null

def OclInvalid::oclIsTypeOf(Classifier c) : Boolean = c = invalid

In the new model-driven evaluation these behaviours can be configured arbitrarily by the presence of a definition of an e.g. OclVoid::oclIsTypeOf(Classifier c) associated with an OclVoidOclIsTypeOfOperatuion class that provides the reqiusite evaluate overloads. So we can offer a suite of OCL.oclstdlib models, selectable via an Environment.setLibrary() method, corresponding to each different OCL 2.1, 2.3, 2.5, 2.0A, 2.0B etc that we feel included to support.

eclipse-ocl-bot commented 2 hours ago

By Ed Willink on Feb 01, 2011 02:25

Evaluator follows OMG resolution.

eclipse-ocl-bot commented 2 hours ago

By Ed Willink on May 27, 2011 02:25

Closing since fixed in mature code too.

eclipse-ocl-bot commented 2 hours ago

By Ed Willink on May 27, 2011 06:40

Resolved for Indigo is 3.1.0 not 3.2.0.