Bug 419958 - Rationalize DataType construction
Summary: Rationalize DataType construction
Status: NEW
Alias: None
Product: QVTo
Classification: Modeling
Component: Engine (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows Vista
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-10-21 06:05 EDT by Ed Willink CLA
Modified: 2013-10-23 10:20 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ed Willink CLA 2013-10-21 06:05:41 EDT
The QVTo specification does not make it clear how to construct a DataType instance: e.g. an ecore::EDate.

The OCL specification provides no mechanism for DataType construction.

Discussion on Bug 419339 highlighted that an ObjectExp was inappropriate:

object ecore::EDate { "1-jan-2000" }

since DataTypes are not classes, the body has no assignment and objects should not be "=".

The same principle could apply to 

new ecore::EDate("1-jan-2000")

since new should lead to distinct composeable instances.

The problem goes away if OCL introduces a DataType construction capability

ecore::EDate { '1-jan-2000' }

(this is already available in the pivot-based Eclipse OCL variant).

Suggest that QVTo endeavours to migrate to keywordless DataType construction.
Comment 1 Adolfo Sanchez-Barbudo Herrera CLA 2013-10-21 06:26:17 EDT
(In reply to Bug 419840 comment 1)
> (In reply to Adolfo Sanchez-Barbudo Herrera from Bug 419339 comment #33)
> > Trying to look for an alternative to the problem you pointed out for custom
> > datatypes, I guess that what we could relax the instantiation expression to
> > Classifier as you suggest, so that, at least we can do the following:
> >
> > var var1 := new MyDatatype("abc");
> 
> The side-effect OCL type constructor proposal gives an interesting contrast. All
> possible instantiations/values notionally pre-exist; the OCL accesses just
> provide access to that 'pre-existing' value; just the same as all Integers
> notionally exist even though there is insufficient memory to represent them all.
> 
> (GIT\org.eclipse.ocl\tests\org.eclipse.ocl.examples.xtext.tests\src\org\eclipse\ocl\examples\pivot\tests\EvaluateOclAnyOperationsTest4.java)
> 
> assertQueryTrue(null, "ecore::EDate{'2000-01-24'} =
> ecore::EDate{'2000-01-24'}");
> 
> ecore::EDate{'2000-01-24'}
> 
> accesses the notional pool of all values; no side-effect.
> 

This makes sense in OCL and QVTo. Note that EDate is a data type, which represent simply values which, as you have been discussing, should return true under the equality operator.

> Similarly
> 
> (GIT\org.eclipse.ocl\tests\org.eclipse.ocl.examples.xtext.tests\src\org\eclipse\ocl\examples\pivot\tests\EvaluateNameVisibilityTest4.java)
> 
> assertQueryEquals(context, "RedApple",
> "Apple{name='RedApple',color=Color::red}.name");
> 
> does not create a side-effect, since the object is owned by the OCL framework.
> 

The same applies here, your are comparing data types (Strings).

The interesting test would be comparing for instance:

assertQueryEquals(context, "Apple{name='RedApple',color=Color::red}", "Apple{name='RedApple',color=Color::red}")

to verify your prior assertion:

"All possible instantiations/values notionally pre-exist; the OCL accesses just provide access to that 'pre-existing' value"

Which I quite doubt it will return return true, since Apple in this case is a class rather than a data type.

I don't know how it's internally working, but in any case I think that the assertions above must be working due to the equality operator characteristics on data types, rather than having the same 'pre-existing' value.

> In contrast QVTo is operational so
> 
> new Apple(name:='RedApple';color:=Color::red)
> 
> creates a new object with a side effect. The object is available to be composed
> somewhere.
> 
> So new MyDatatype("abc") would be consistent with the operational distinction
> with a side effect.
> 

Well, I think that the premises are not accurate... and, a priori, I don't see too much conceptual differences between the OCL Type Constructor you mention, and the QVTo instantiation expression, excepting:
- InstantiationExpression can only refer Classes. Probably erroneous, otherwise we can't create instances/values for custom datatypes in QVTo.
- They can also specify the extent on which the object is created (the 'somewhere' you mentioned before).

In any case, I find this discussion quite interesting, and it looks like we need to do some alignment between OCL and QVTo in this respect. Do we have a side-effect definition in OCL? Is there any plan for the OCL Type Constructor ?

> > Anyway, this looks like to be an obscure specification area (new and object
> > constructs?, where is object exp body defined in the AS) ... which should
> > probably require some more study to properly revise. I'll wait for your
> > comments, and I'll do some more study on this the next week.
> 
> There is no need for the expression body to be specofoed gain. It just contains
> statements whose side effects populate the object (intermixed with all sorets of
> other operational complexity). NB QVTo is not declarative.

The AS should have some reference to contain those statements... On the other hand,  Why do we have two expression to create objects (new and object)? Any difference about using them when creating class instances ?, what is the role of the Constructor operation ?. I'll be reading a little bit around to clarify something about this, to try to come up with something useful.

Regards,
Adolfo.
Comment 2 Adolfo Sanchez-Barbudo Herrera CLA 2013-10-21 06:34:54 EDT
(In reply to comment #0)
> 
> The problem goes away if OCL introduces a DataType construction capability
> 
> ecore::EDate { '1-jan-2000' }

Ok. This sounds nice. We need some reasoning about why we need it in OCL for data types, and why we don't need it in OCL for classes.

However...

> The same principle could apply to
> 
> new ecore::EDate("1-jan-2000")
> 
> since new should lead to distinct composeable instances.
> 

I have got some doubts here, which could lead to some misleadings comments in comment 1:

"123" = "123" in OCL is true because:
a) We are comparing the same instance/value
b) The equality operator characteristics on data types.

If the latter, the following should also be true

new ecore::EDate("1-jan-2000") = new ecore::EDate("1-jan-2000")

Regards,
Adolfo.
Comment 3 Adolfo Sanchez-Barbudo Herrera CLA 2013-10-21 06:41:27 EDT
> 
> "123" = "123" in OCL is true because:
> a) We are comparing the same instance/value
> b) The equality operator characteristics on data types.
> 

The latter. UML 2.5 spec:

10.2.3 Semantics
DataTypes
A DataType is a kind of Classifier. DataType differs from Class in that instances of a DataType are identified only by their value. All instances of a DataType with the same value are considered to be equal instances.

Therefore, the alternative of using an instantiation expression for QVTo is still there (providing the spec changed to accept data types in instantiation exceptions).
Comment 4 Ed Willink CLA 2013-10-21 06:55:24 EDT
(In reply to Adolfo Sanchez-Barbudo Herrera from comment #2)
> > The same principle could apply to
> > 
> > new ecore::EDate("1-jan-2000")
> > 
> > since new should lead to distinct composeable instances.
> > 
> 
> I have got some doubts here, which could lead to some misleadings comments
> in comment 1:
> 
> "123" = "123" in OCL is true because:
> a) We are comparing the same instance/value
> b) The equality operator characteristics on data types.
> 
> If the latter, the following should also be true
> 
> new ecore::EDate("1-jan-2000") = new ecore::EDate("1-jan-2000")

It is the same contradiction:
Multiple DataTypes should be equal
Multiple new things should be different

And: new things should be containable/composeable; DataTypes aren't.
Comment 5 Adolfo Sanchez-Barbudo Herrera CLA 2013-10-21 07:09:08 EDT
(In reply to comment #4)
> Multiple new things should be different
> 
> And: new things should be containable/composeable

because.... ????

values ("12", 4, ecore::EDate { '1-jan-2000' }) are instances of DataType, can't figure out why an (obviously reworked and probably promoted to OCL) instantiation expression doesn't fit here ... More seriously, if we really need to distinguish in QVTo between Type Constructor Expressions, Instantiation Expressions and Object Expressions we have to find more strong arguments to justify the need.... I hope to come up with something useful, but if you have any direction/clue about this, don't hesitate to drop it here.
Comment 6 Ed Willink CLA 2013-10-21 07:15:05 EDT
(In reply to Adolfo Sanchez-Barbudo Herrera from comment #2)
> (In reply to comment #0)
> > 
> > The problem goes away if OCL introduces a DataType construction capability
> > 
> > ecore::EDate { '1-jan-2000' }
> 
> Ok. This sounds nice. We need some reasoning about why we need it in OCL for
> data types, and why we don't need it in OCL for classes.

We do need it for OCL classes too. See Bug 293622, which is all about Classes; DataTypes just piggy-backed on the implementation.

It was only while implementing Type Constructors for the code generator that I finally understood how we can avoid the side effect in the memory system. All possible primitive types, data types, type type, class instantiations notionally exist before OCL starts evaluating. At run-time the 'already existing' instance is made available for use whenever required.

In practice, pre-creating everything is clearly impossible, so instances are created lazily and maintained in a suitable cache for re-use.

The pivot-based implementation does not yet have an InstanceManager similar to its TupleTypeManager so a couple of tests such as

assertQueryFalse(context, "let thisApple = Apple{name='AnApple',color=Color::red}, thatApple = Apple{name='AnApple',color=Color::red} in thisApple = thatApple");

are wrong. For the compiled OCL the result is true since Common SubExpression Elimination statically detects the comparison of identical terms to yield true.

NB. Apple{name='AnApple',color=Color::red} provides access to the shared instance maintained (and composed) by the OCL environment.

object Apple(name:='AnApple';color:=Color::red) creates a new instance that may be composed as required.

The following are all true

Apple{} = Apple{}                 // same shared instance
Apple{} <> object Apple()         // different instances
object Apple() <> object Apple()  // different instances
Comment 7 Ed Willink CLA 2013-10-21 07:20:03 EDT
(In reply to Adolfo Sanchez-Barbudo Herrera from comment #5)
> (In reply to comment #4)
> > Multiple new things should be different
> > 
> > And: new things should be containable/composeable
> 
> because.... ????

Simplistically, every object (except the root) in a model has exactly one container using a composition relationship.

DataTypes are shared and so a "name : String" relationship does not compose.

> values ("12", 4, ecore::EDate { '1-jan-2000' }) are instances of DataType,
> can't figure out why an (obviously reworked and probably promoted to OCL)
> instantiation expression doesn't fit here ... More seriously, if we really
> need to distinguish in QVTo between Type Constructor Expressions,
> Instantiation Expressions and Object Expressions we have to find more strong
> arguments to justify the need.... I hope to come up with something useful,
> but if you have any direction/clue about this, don't hesitate to drop it
> here.

Not sure what you're saying other than perhaps pivot::ConstructorExp may be the promotion of qvto::InstantiationExp.
Comment 8 Adolfo Sanchez-Barbudo Herrera CLA 2013-10-21 07:36:43 EDT
(In reply to comment #7)
> (In reply to Adolfo Sanchez-Barbudo Herrera from comment #5)
> > (In reply to comment #4)
> > > Multiple new things should be different
> > >
> > > And: new things should be containable/composeable
> >
> > because.... ????
> 
> Simplistically, every object (except the root) in a model has exactly one
> container using a composition relationship.
> 
> DataTypes are shared and so a "name : String" relationship does not compose.
> 

I obviously meant why "new things should be composeable" as you have nicely described.

From this point of view, new Class instances should be composeable, new DataTypes instances shouldn't. 

Therefore by doing:

new MyDatatype("asdas") = new MyDatatype("adsds") 

- I'm creating two 'different' new things (values)
- which are equals
- and are not composeable (as you have defined it).

> > values ("12", 4, ecore::EDate { '1-jan-2000' }) are instances of DataType,
> > can't figure out why an (obviously reworked and probably promoted to OCL)
> > instantiation expression doesn't fit here ... More seriously, if we really
> > need to distinguish in QVTo between Type Constructor Expressions,
> > Instantiation Expressions and Object Expressions we have to find more strong
> > arguments to justify the need.... I hope to come up with something useful,
> > but if you have any direction/clue about this, don't hesitate to drop it
> > here.
> 
> Not sure what you're saying other than perhaps pivot::ConstructorExp may be the
> promotion of qvto::InstantiationExp.

Yes. Need to study. However your reasoning about that "access to the share instance expression" (Type Constructor Expression) vs "create a new instance expression" (InstantiationExp ) doesn't seem to fit with it .... Anyway, much to study, discuss and argument... I'll create an open goolge docs to document my study.

Regards,
Adolfo.
Comment 9 Ed Willink CLA 2013-10-21 07:51:50 EDT
(In reply to Adolfo Sanchez-Barbudo Herrera from comment #8)
> Therefore by doing:
> 
> new MyDatatype("asdas") = new MyDatatype("adsds") 
> 
> - I'm creating two 'different' new things (values)
> - which are equals
> - and are not composeable (as you have defined it).

Which once again is the contradiction. I'm not clear what you're still puzzled about.
Comment 10 Adolfo Sanchez-Barbudo Herrera CLA 2013-10-21 08:27:36 EDT
(In reply to Ed Willink from comment #9)
> (In reply to Adolfo Sanchez-Barbudo Herrera from comment #8)
> > Therefore by doing:
> > 
> > new MyDatatype("asdas") = new MyDatatype("adsds") 
> > 
> > - I'm creating two 'different' new things (values)
> > - which are equals
> > - and are not composeable (as you have defined it).
> 
> Which once again is the contradiction. I'm not clear what you're still
> puzzled about.

Sorry Ed, but you will have re-ellaborate your "contradiction" hyphotesis. For better or worse now we are talking about instances of (data) types.

I'm not saying a contradcition when in this expression

"abc" = "abc" 

We have two different values/instances which when compared they are equal. UML, indeed says, that:
1. we may have different values/instances for the same data type
2. in this case, they are considered to be same instance.

The same reasoning applies to your Constructor types (in spite of the fact that you want to show us, that the same value/instance is returned when using the String constructor expression, which curiously recieves two differente "abc" values/instances in both sides of the '=' expression):

String("abc") = String ("abc")

The same reasoning applies to an hypothethical instantiation expression (which differes to yours, that two different values/instances are returned, but they are equals):

xxx String("abc") = xxx String ("abc")

[Being xxx any keyword you want to come up with, in order to represent that you want to create an instance of the String data type.]

Please, could you point me out somewhere in any UML/MOF/OCL specification which clarifies where the contradiction is ?

Regards,
Adolfo.
Comment 11 Ed Willink CLA 2013-10-21 08:50:28 EDT
(In reply to Adolfo Sanchez-Barbudo Herrera from comment #10)
> The same reasoning applies to an hypothethical instantiation expression
> (which differes to yours, that two different values/instances are returned,
> but they are equals):
> 
> xxx String("abc") = xxx String ("abc")

No "new" implies new and so distinct, so I expect that

new String("abc") = new String ("abc")

whaich contradicts DataType equality.

It seems to me to be a bad idea to extend the functionality of "new"/InstamtiationExp to allow some new things to be "<>" and others to be "=".
Comment 12 Adolfo Sanchez-Barbudo Herrera CLA 2013-10-21 10:07:17 EDT
Hi Ed,

I'm afraid that you fail to supply arguments to demonstrate the contradiction. OCL/QVT is not Java.

In Java I expect, like you:

"abc" != "abc"

and

new String("abc") != new String("abc")

In QVTo, I'd expect, not like you:

"abc" = "abc"

and

new String("abc") = new String("abc").

Argument for my expectations. UML 2.5, Section 10.2.3:

"All instances of a DataType with the same value are considered to be equal instances".

Regards,
Adolfo.
Comment 13 Adolfo Sanchez-Barbudo Herrera CLA 2013-10-21 11:02:20 EDT
More separate argumentation. In this case, from MOF specification, and the Object concept. Section 9.3.1 (Object operations):

"equals(object: Object): Boolean

Determines if the object equals this Object instance. For instances of Class, returns true if the object and this Object
instance are references to the same Object. For instances of DataType, returns true if the object has the same value as this
Object instance. Returns false for all other cases."

No doubt, that QVT needs a lot to rework with the more changing UML/MOF/OCL specifications,  but from the point of view of this discussion ... I see no point about the aforementioned contradiction. Basically, two different instances of a DataType, yielding the same value, have to be considered as the same instance.

N.B: I'll provide a link with some other conclusions about this topic, when I finish the document.

Regards,
Adolfo.
Comment 14 Ed Willink CLA 2013-10-21 11:25:28 EDT
(In reply to Adolfo Sanchez-Barbudo Herrera from comment #13)
> More separate argumentation. In this case, from MOF specification, and the
> Object concept. Section 9.3.1 (Object operations):
> 
> "equals(object: Object): Boolean

I have already pointed out that MOF::Reflection::equals is specifically excluded from OCL and that anyway "equals" is not necessarily the same concept as "=" which is defined by OCL without any requirement to be related to MOF::Reflection::equals.

(In reply to Adolfo Sanchez-Barbudo Herrera from comment #12)
> new String("abc") = new String("abc").
> 
> Argument for my expectations. UML 2.5, Section 10.2.3:
> 
> "All instances of a DataType with the same value are considered to be equal
> instances".

"equal" again without any specification as to what equal might mean and no relationship to OCL "=".

"new" is a purely QVTo concept defined in conjunction with an InstantiationExp that is clearly only specified for Classes.

Any extension of "new" to DataTypes is a specification extension and therefore may define whatever we like, subject only to common sense.

So I expect: new MyString("abc") <> new MyString("abc")
and          MyString{'abc'} = MyString{'abc'}

If you expect: new MyString("abc") = new MyString("abc")
and            MyString{'abc'} = MyString{'abc'}

then perhaps the extension is too confusing and should not be made.

Thinking a bit harder, I don't like new MyString("abc") at all, since it implies creation of an instance that could be the target of a composition relationship; it can't.

So I oppose extension of new/InstantiationExp to DataType.
Comment 15 Adolfo Sanchez-Barbudo Herrera CLA 2013-10-21 12:39:44 EDT
(In reply to comment #14)
> (In reply to Adolfo Sanchez-Barbudo Herrera from comment #13)
> > More separate argumentation. In this case, from MOF specification, and the
> > Object concept. Section 9.3.1 (Object operations):
> >
> > "equals(object: Object): Boolean
> 
> I have already pointed out that MOF::Reflection::equals is specifically excluded
> from OCL and that anyway "equals" is not necessarily the same concept as "="
> which is defined by OCL without any requirement to be related to
> MOF::Reflection::equals.
> 

Yes. You are right... Although comprising the same idea than UML, it doesn't nothing to do with OCL. For the track, adding argumentation reference (OCL Section 13.2, point 7) 

> (In reply to Adolfo Sanchez-Barbudo Herrera from comment #12)
> > new String("abc") = new String("abc").
> >
> > Argument for my expectations. UML 2.5, Section 10.2.3:
> >
> > "All instances of a DataType with the same value are considered to be equal
> > instances".
> 
> "equal" again without any specification as to what equal might mean and no
> relationship to OCL "=".
> 

So because, "we" don't like the what UML says to this respects, We need to
1) Stupidly say that for every OCL built-in data type how the = equals behaves for them (comparing by value )
2) not to implicitly support data type comparisons (by equality) or to make up some rationale about those Type Constructor which map to the same data type instance...

And just because we don't want to assume that the well known "equals" concept can't mean the obvious OCL operator of '='... common sense everywhere...

Ok, I'll stop it here... Of course I'm not in favour of not accepting the sensible idea that all Datatype instances are equals (and '=') when they comprise the same value.... I'll see how to better deal with this.

Regards,
Adolfo.
Comment 16 Ed Willink CLA 2013-10-21 13:59:26 EDT
(In reply to Adolfo Sanchez-Barbudo Herrera from comment #15)
> Ok, I'll stop it here... Of course I'm not in favour of not accepting the
> sensible idea that all Datatype instances are equals (and '=') when they
> comprise the same value.... I'll see how to better deal with this.

You seem to keep missing my point.

There is no mandatory correctaion bnetween "equials" in UML/MOF and "=" in OCL.

In OCL 2.4 we clarified OclAny::"=" for DataType so that DataType are indeed "=" by value.

This is why we have a contradiction when anything suggests that DataType should not be equal. The obvious behaviour of "new" gives this contradiction.

"new" gives a new chunk of memory that is different to an old chunk.
if the chunk is a DataType the two chunks are equal (contradiction).

"new" creates a chunk of memory that needs to be owned/composed.
A DataType chunk cannot be owned/composed (contradiction)
Comment 17 Sergey Boyko CLA 2013-10-21 16:06:46 EDT
(In reply to Adolfo Sanchez-Barbudo Herrera from comment #12)
> Hi Ed,
> 
> I'm afraid that you fail to supply arguments to demonstrate the
> contradiction. OCL/QVT is not Java.
> 
> In Java I expect, like you:
> 
> "abc" != "abc"
> 
> and
> 
> new String("abc") != new String("abc")
> 
> In QVTo, I'd expect, not like you:
> 
> "abc" = "abc"
> 
> and
> 
> new String("abc") = new String("abc").
> 
> Argument for my expectations. UML 2.5, Section 10.2.3:
> 
> "All instances of a DataType with the same value are considered to be equal
> instances".
> 
> Regards,
> Adolfo.

I'll add one more argument to the explanation above (which I fully share and aree with) - Ed always considers immutable DataType. This allows him to state that "All possible instantiations/values notionally pre-exist". 
This is not true for mutable DataTypes (like List) - their instances are necessarily distinct while they are the same in terms of equality relation.
Comment 18 Ed Willink CLA 2013-10-21 16:29:09 EDT
(In reply to Sergey Boyko from comment #17)
> I'll add one more argument to the explanation above (which I fully share and
> aree with) - Ed always considers immutable DataType. This allows him to
> state that "All possible instantiations/values notionally pre-exist". 
> This is not true for mutable DataTypes (like List) - their instances are
> necessarily distinct while they are the same in terms of equality relation.

Interesting. Is the conformance of List and Dict to Collection and so to DataType sound?
Comment 19 Adolfo Sanchez-Barbudo Herrera CLA 2013-10-22 05:55:51 EDT
Hi Ed, Sergey,

Thanks Sergey for joining the discussion

The point is not related to mutability or composeability. In my opinion is a matter of quantity.

I think that Ed's argument about "prexistence" (Ed, correct me if I'm wrong) is trying to sell us that:
1. There is only one instance underlying the same value for a given data type
2. You can't create new instances for a data type.

So basically, the fact that for UML we may have "many instances of a data type underlying the same value which can be considered equals", in OCL turns into "we only have one instance of a data type underlying the same value"

So for instance when have have:

a) 'abc' = 'abc'

EDs: there is just one instance of the String data type whose value is "abc" and owned by the OCL Environment.

Me: here we are creating two different String data type instances and comparing them by value.

More examples, as I see how the values (instances of data types) are created in OCL:

b) 'abc' = 'abc'.concat('')

Here we would have 4 different instances of the the String data type:
1 Comprising the empty string value
3 Comprising the "abc" value (the two String literal expressions and the result of the concat operation)

Using a prototypical data type constructor:

c) new String('abc') = new String('abc')

We would have 4 different instances of the String data type, which would be equal among them (two comprised by the string literal expressions used as arguments of a data type constructor, two as the result of the data type constructor)

d) new MyDataType('abc') = new MyDataType('abc')

We would have 4 different data type instances:
2 of them instance of the String data type (which should be equal between them)
2 of them instance of the MyDataType data type (which should be equal between them).

More thoughts:
- Nobody would use a data type constructor to create String values (example c)), since there is an specific language construct, String literal expression, (example a) ) to do so.
- However we need (also in OCL) a data type constructor to create instances of other user data types (example d) ).

In the end,  "new MyDataType('abc')" is not more than a different syntax of "MyDataType{'abc'}". 

As I understand Ed's point of view, the semantics are obviously different:

1. MyDataType{"abc"} implies no data type instance creation (Their values "pre-exist" in a unique way in the OCL framework}

2. new MyDataType("abc") implies data type instance creation and it's not allowed in OCL becase... they can't be composeable ?... wherever you compose "abc" you can compose the created "new String("abc")". 

From my point of view, it's not more than a new data type instance creation, and therefore:

MyDataType{"abc"} = new MyDataType("abc")

More formally, the constraint which would produce a contradiction (and needs more convincing argumentation, in my opinion) is the following:

let s : String = "abc" in new MyDataType(s) <> new MyDataType(s)

Instead, in my opinion:

let s : String = "abc" in new MyDataType(s) = new MyDataType(s)

Recalling my reasoning: Indeed, they are new and different data type instances, but given the semantic of a data type, they are equals (comparing one to the other is true).

Regarding the argument of as OCL side-effect free language, as long as we don't allow OCL assign those created data types instances, the system would not really be modified. As you defended in Bug 293622 comment 5:

"I think this is no more of a side effect than an individual object construction, which from the perspective of the memory system is clearly side-effecting, but from the perspective of OCL evaluations is side-effect-free."

So, basically, it's not the InstantiationExp which makes QVTo a side-effect language, but the AssignExp.

Regards,
Adolfo.
Comment 20 Adolfo Sanchez-Barbudo Herrera CLA 2013-10-22 06:14:56 EDT
To move forward, I think what we need more arguments about why we need to make a difference between the InstantiationExp (for QVTo) and ConstructorExp (for OCL).

Perhaps, focusing on the differences, we may accurately envision how to rework both specification to have more sensible specifications

I rather see the prototypical ConstructorExp, as explained by Ed, as an ObjectExp for OCL which:
1. Can be applied to any Type (not only Classes)
2. Always returns the same created instance.

Regarding 1. In my opinion I think, that at least, QVTo also needs to have the ability to construct new data types (relax the InstantiationExp) to assign them to properties of the classes involved in the transformation.

Regarding 2. I think that a key point is, which is the requirement to justify a ConstructorExp always return the same instance, rather than always returning a new one (which is a clear QVT requirement). Given the OCL side-free nature and with the goal of reducing memory footprint, this could could be a justification.

P.S: I'll go on with the document where I'm exposing more problems and thoughts about it.
Comment 21 Adolfo Sanchez-Barbudo Herrera CLA 2013-10-22 06:22:44 EDT
(In reply to comment #19)
> Hi Ed, Sergey,
> 
> Thanks Sergey for joining the discussion
> 
> The point is not related to mutability
Note that I also agree that if we consider that every data type is immutable, having a unique pre-existing data type instance can help in decreasing memory footprint. However, I don't think that this fact justifies:
- Prohibition in creation of new data type instances (as UML allows)
- MyDataType("abc") <> MyDataType("abc")
- Mandate that every user data types (or those defined by QVTo) need to be immutable.

Regards,
Adolfo.
Comment 22 Adolfo Sanchez-Barbudo Herrera CLA 2013-10-22 09:16:04 EDT
I think that current Ed's ConstructorExp design seems beneficial, specially in terms of performance, optimizations for code generator, etc.

It's also clear that we need the QVTo InstantiationExp (new XXX() ), which in short, of replace the former in order to always create new/different instances.

You may find more comments and rationale in the following link, which I've finally and publicly shared (Comments are welcome):
https://docs.google.com/a/york.ac.uk/document/d/1KaqpzOrI67EZfevVqGo2x70pmWF2g9LNbAos0PLJ5u0

That said, I still believe that 

"abc" = new String ("abc") = String {"abc"} (note that there is a pending concern about how to use the ConstructorExp for simple data types (see the document for more information))

whereas

Apple {color = "red"} = Apple {color = "red" } <> new Apple("red") <> object Apple { color := "red" }
Comment 23 Ed Willink CLA 2013-10-22 10:11:55 EDT
 (In reply to Ed Willink from comment #18)
> Interesting. Is the conformance of List and Dict to Collection and so to
> DataType sound?

In UML terms a List/Dict is a Structured DataType whereas Boolean is Unstructured. Structured DataTypes can certainly mutate.

The earlier discission has been confused by which of two out of three are bl;urred together:
- Immutable DataTypes { e.g. Boolean, String, Collection, Tuple, user-Datatype }
- Mutable DataTypes { Dict, List, Tuple }
- Classes { user-classes }

The existence of Tuple as Immutable in OCL and Mutable in QVTo makes for significant implementation and user hazards.
- the QVTo implementation must clone an OCL immutable Tuple before treating it as Mutable - not obvious
- the user may be surprised when Tuples are cloned and consequently mutations may be ineffective

For Immutable DataTypes construction as T{...} seems fine, and augmenting this with new T(...) or object T{...} seems gratuitous.
- T{...} is the proposed new OCL type constructor for a user-Datatype

For Classes QVTo construction as new T(...) or object {...} seems fine; both suggest creation of a new entity
- additionally if OCL introduces the T{...} type constructor, this seems consistent with a shared entity

Mutable DataTypes is where QVTo has created a mess.

Using T{} rather than new T() for Dict and List is unfortunate because it hides the important mutable/immutable distinction from users. However new would also be misleading because the created entity cannot be owned/composed; List/Dict are subject to shared ownership in a similar fashion to Java objects. "new T(...)"would also be confusing since two distinct List creations may be "=". Adding support for "object List{...}" seems to only add to the confusion,. So on balance, I advocate no change for Dict/List since the alternatives seem to have at least as many problems.

Tuples seem to be badly broken.

What is the meaning of
    var t = Tuple{s : String = 'x'};
    var n = (t.s += 'y').s;

If we introduce .clone() to clarify the implementation alternatives
    var t = Tuple{s : String = 'x'}.clone();
    var n = (t.s += 'y').s;
or
    var t = Tuple{s : String = 'x'};
    var n = (t.clone().s += 'y').s;
we have uncertainty as to whether "t" mutates.

It seems to me that OCL defined Tuples as Immutable and QVTo cannot change this. QVTo must introduce a MutableTuple with appropriate conversion operations to make the semantics clear. In the absence of a better construction operator for List/Dict I would advocate MutableTuple{...} for symmetry.

Further symmetry is possible if List is MutableSequence, and Dict is MutableMap, with Map added to OCL. May be this is the way forward. The preferred construction could be in full

var l : MutableSequence(String) := mutable Sequence{....};

or in short just

var l  := mutable Sequence{....};

The "mutable" keyword could be used for  any Collection type, Map, Tuple and may be even classes, consistently converting an immutable OCL argument to something more interesting for QVTo.

------
Summary for QVT 1.1

No extension of new/object to data types.

Maintain the distinction between Tuple and MutableTuple as an analysis artifact, requiring the user to explicitly .clone() in order to convert an immutable OCL Tuple into a mutable QVTo Tuple before any mutable operations are permitted.

-----
Summary for QVT 1.x

Consider introducing "mutable" and Mutable-types for consistency.
Comment 24 Adolfo Sanchez-Barbudo Herrera CLA 2013-10-22 12:09:45 EDT
(In reply to comment #23)
> (In reply to Ed Willink from comment #18)
> > Interesting. Is the conformance of List and Dict to Collection and so to
> > DataType sound?
> 
> In UML terms a List/Dict is a Structured DataType whereas Boolean is
> Unstructured. Structured DataTypes can certainly mutate.
> 
> The earlier discission has been confused by which of two out of three are
> bl;urred together:
> - Immutable DataTypes { e.g. Boolean, String, Collection, Tuple, user-Datatype }
> - Mutable DataTypes { Dict, List, Tuple }
> - Classes { user-classes }
> 

Prior note: no data types mutability mentions along OMG UML/OCL specification.

Just one disagreement. Datatypes may have operations (as UML states), which may potentially change the value of the data type instance. I can understand imposing immutability on OCL types, I don't see why creating such imposition in user data types.

Imposing simple (unstructured) data types to be immutable seems gratuitious limitation.

> The existence of Tuple as Immutable in OCL and Mutable in QVTo makes for

QVTo only declares as mutable List and Dictionary. The introduction of OrderedTupleType has order purposes (having unnamed tuples) rather having mutable tuples, actually, it explicitly says that they are not mutable (Sect. 8.2.2.27).

> significant implementation and user hazards.
> - the QVTo implementation must clone an OCL immutable Tuple before treating it
> as Mutable - not obvious
> - the user may be surprised when Tuples are cloned and consequently mutations
> may be ineffective
> 

Red herring...

> For Immutable DataTypes construction as T{...} seems fine, and augmenting this
> with new T(...) or object T{...} seems gratuitous.

The mutability should not be implicit to the (meta) type. It depends on how the datatype is modelled: does it accessible (changeable) properties or operations to mutate the instance ?

In any case, I agree that having  T{...} to create/provide a type instance seems fine/enough in the OCL context (In my document I provide a name change: InstanceLiteralExp rather than ConstructorExp) .

In a QVTo context, I think that we still need some construct to create different data type instances (which may underly the same value) since nobody can assure that the data types are mutable. If my data types are immutable, I'd definitely use an InstanceLiteralExp rather than a InstantiationExp since they should perform better.

> - T{...} is the proposed new OCL type constructor for a user-Datatype
> 

Ok. but I can't still come up with a coherent syntax to cover simple (unstructured) data types... providing that we are also interested on it for structured data types, classes, etc. One idea I proposed to discuss:

ecore::EDate {self = "01-Ja-2013"}

which aligns with the declarative fashion of OCL.

> For Classes QVTo construction as new T(...) or object {...} seems fine; both
> suggest creation of a new entity
> - additionally if OCL introduces the T{...} type constructor, this seems
> consistent with a shared entity

Agree. But I remark again, the need to use "new T(...)/ object T {...} " for user data types, when we are interested in having different instances rather than the same shared instance.

> 
> Mutable DataTypes is where QVTo has created a mess.
> 
> Using T{} rather than new T() for Dict and List is unfortunate because it hides
> the important mutable/immutable distinction from users. However new would also
> be misleading because the created entity cannot be owned/composed; List/Dict are
> subject to shared ownership in a similar fashion to Java objects. "new
> T(...)"would also be confusing since two distinct List creations may be "=".
> Adding support for "object List{...}" seems to only add to the confusion,. So on
> balance, I advocate no change for Dict/List since the alternatives seem to have
> at least as many problems.

Well... let's say that I agree to preserve the current List/Dict literal expressions to create (mutable) instances.

> 
> Tuples seem to be badly broken.
> 
> What is the meaning of
> var t = Tuple{s : String = 'x'};
> var n = (t.s += 'y').s;
> 
> If we introduce .clone() to clarify the implementation alternatives
> var t = Tuple{s : String = 'x'}.clone();
> var n = (t.s += 'y').s;
> or
> var t = Tuple{s : String = 'x'};
> var n = (t.clone().s += 'y').s;
> we have uncertainty as to whether "t" mutates.
> 

Red herring... Tuples and OrderedTuples are not mutable in QVTo. 

> It seems to me that OCL defined Tuples as Immutable and QVTo cannot change this.
> QVTo must introduce a MutableTuple with appropriate conversion operations to
> make the semantics clear. In the absence of a better construction operator for
> List/Dict I would advocate MutableTuple{...} for symmetry.
> 

Maybe I'm missing something, but I ask, just in case... Why do we need to mutate tuples in QVT (in general) ?

> Further symmetry is possible if List is MutableSequence, and Dict is MutableMap,
> with Map added to OCL. May be this is the way forward. The preferred
> construction could be in full
> 
> var l : MutableSequence(String) := mutable Sequence{....};
> 
> or in short just
> 
> var l  := mutable Sequence{....};
> 
> The "mutable" keyword could be used for  any Collection type, Map, Tuple and may
> be even classes, consistently converting an immutable OCL argument to something
> more interesting for QVTo.
> 

All of this looks to be aligned to the idea that the mutability comes implicit with the (meta) type. I think it's an incorrect thinking, mutability comes in the form of having a way, free of exception, to modify an instance of a given type.

We think of Java String, Integer, etc as immutable objects, but this feature is not defined by Java language itself. They are immutable because we don't have a mean via public fields or methods which may allow us mutate its value.

The same occurs with immutable OCL types.

Similarly, Lists and Dicts are not mutable just because the specification says so... they are, because the specification provides some operations (add, put,...) to modify the instance.

> ------
> Summary for QVT 1.1
> 
> No extension of new/object to data types.
> 
> Maintain the distinction between Tuple and MutableTuple as an analysis artifact,
> requiring the user to explicitly .clone() in order to convert an immutable OCL
> Tuple into a mutable QVTo Tuple before any mutable operations are permitted.
> 
> -----
> Summary for QVT 1.x
> 
> Consider introducing "mutable" and Mutable-types for consistency.

Due to several comments above, I can't agree with the summary...

I think that in QVTo we still need a way to create user data-types. ObjectExp (object T {...}) looks like a good candidate since it resembles in notation to ConstructorExp or InstanceLiteralExp (T {...}).

InstantiationExp must be suitable as well: new T(...) but this need more work around the specification/s to be useful for simple (unstructured) data types. A couple of ideas:

a) Specification says at 8.2.1.13 that "To create an object it is not mandatory to define a constructor operation. For each class, if not defined explicitly, there is
an implicit default constructor that has no parameter and that has the name of the class."

We would require a similar sentence what respects unstructured user data types for which we require a default constructor with one argument with the underlying value.

b) It's also interesting to note, the role of a Factory (from MOF) to create instances for user data types from string values (which are the usual serialized representation of data type values). This is implemented in EMF, but Unfortunately, this element also belongs to the MOF::Reflection package. This direction could require more hard work around various specifications and how QVT should really be defined (extending EMOF and EssentialOCL, doing a selective merge of those ?)

If something doesn't make sense, please let know.

Regards,
Adolfo.
Comment 25 Ed Willink CLA 2013-10-22 12:42:36 EDT
(In reply to Adolfo Sanchez-Barbudo Herrera from comment #24)
> > The earlier discission has been confused by which of two out of three are
> > bl;urred together:
> > - Immutable DataTypes { e.g. Boolean, String, Collection, Tuple, user-Datatype }
> > - Mutable DataTypes { Dict, List, Tuple }
> > - Classes { user-classes }
> > 
> 
> Prior note: no data types mutability mentions along OMG UML/OCL
> specification.

I don't understand what you're trying to say.
> 
> Just one disagreement. Datatypes may have operations (as UML states), which
> may potentially change the value of the data type instance. I can understand
> imposing immutability on OCL types, I don't see why creating such imposition
> in user data types.

Yes/No.I  just added the missing name as an afterthought thinking too much from an OCL perspective.

Unstructured DataTypes are immutable.

Structured DataTypes are mutable by changing their properties.

Neither may have operations in UML.

Both may acquire operations through Complete OCL, but these can only be queries.
> 
> Imposing simple (unstructured) data types to be immutable seems gratuitious
> limitation.

No see above.

> 
> The introduction of
> OrderedTupleType has order purposes (having unnamed tuples) rather having
> mutable tuples, actually, it explicitly says that they are not mutable
> (Sect. 8.2.2.27).

Excellent; that eliminates all the really bad problems.

> Ok. but I can't still come up with a coherent syntax to cover simple
> (unstructured) data types... providing that we are also interested on it for
> structured data types, classes, etc. One idea I proposed to discuss:
> 
> ecore::EDate {self = "01-Ja-2013"}
> 
> which aligns with the declarative fashion of OCL.

The OCL type constructor syntax for classes is the same as the Tuple syntax; just replace "Tuple" by the class path name.

The OCL type constructor syntax for data types is PathName { string-expr }. This exploits the ECore practicve of requiring a user-defined String-to-internal conversion function.

If you want to implement ecore::EDate in OCL, you either define it as a black box datatype with a String argument, or you reify it as a Class with hour/minute/second/... properties and all the corresponding parsing code; why bother?


> All of this looks to be aligned to the idea that the mutability comes
> implicit with the (meta) type. I think it's an incorrect thinking,
> mutability comes in the form of having a way, free of exception, to modify
> an instance of a given type.

Mutability is one of the primary considerations when designing a Class. It either does or does not have public/protected setMethods. 

> We think of Java String, Integer, etc as immutable objects, but this feature
> is not defined by Java language itself. They are immutable because we don't
> have a mean via public fields or methods which may allow us mutate its value.

Exactly; the library designer decided to make them immutable.

> The same occurs with immutable OCL types.
> 
> Similarly, Lists and Dicts are not mutable just because the specification
> says so... they are, because the specification provides some operations
> (add, put,...) to modify the instance.

Exactly. They are designed to be mutable.

When I thought that Tuples could be mutable, a generic immutable/mutable seemed to be a way of simplifying things. It still is but it may not now be worth the disruption and the hassle of supporting MutableSet, MutableBag etc except that they're all potentially useful and a generic solution may actually be easier.

Implementation-wise an optimised executor may actually want to use a MutableBagImpl so that the final operation on e.g. a Bag can be optimised into a mutable change rather than a copy and create with minor change.
Comment 26 Adolfo Sanchez-Barbudo Herrera CLA 2013-10-22 14:40:06 EDT
Hi Ed,

Some other comments.

> 
> I don't understand what you're trying to say.

I mean that there is not discussion in UML nor OCL about mutability associated to user data types.

> > 
> > Just one disagreement. Datatypes may have operations (as UML states), which
> > may potentially change the value of the data type instance. I can understand
> > imposing immutability on OCL types, I don't see why creating such imposition
> > in user data types.
> 
> Yes/No.I  just added the missing name as an afterthought thinking too much
> from an OCL perspective.

which reinforces that it´s your point of view, not an specification one.

> 
> Unstructured DataTypes are immutable.
> 
> Structured DataTypes are mutable by changing their properties.
> 
> Neither may have operations in UML.
> 

UML 2.5 (Section 10.2.2 and  10.5)

DataType::ownedOperation : Operation [0..*]

As expected, if you check Pivot::DataType you may find that ownedOperation containment references.

> Both may acquire operations through Complete OCL, but these can only be
> queries.

Agree.

> 
> The OCL type constructor syntax for classes is the same as the Tuple syntax;
> just replace "Tuple" by the class path name.
> 
> The OCL type constructor syntax for data types is PathName { string-expr }.
> This exploits the ECore practicve of requiring a user-defined
> String-to-internal conversion function.
> 

This doesn´t fit in current ConstructorExp, giving current ConstructorPart AS:
- "abc"  doesnt fit as a ConstructorPart
- Actually, self = "abc" doesn´t fit neither...

... I guess we need to rework this (not today)


> If you want to implement ecore::EDate in OCL, you either define it as a
> black box datatype with a String argument, or you reify it as a Class with
> hour/minute/second/... properties and all the corresponding parsing code;
> why bother?
> 

I think that your are missing the semantics/purpose of Datatypes in UML (maybe biased by EMF ones). They mainly differ from classes that they are identified by value rather than reference, therefore, different instances of the same data type underlying the same value, are equal. 

You could have a UML Date (structured) datatype with a hour/minute/seconds properties if you want. No need to reify as a Class. See for example UML 10.2.5 section (Figure 10.3) where you have a FullName data type comprising a "firstName", a "secondName" and "initial".

> 
> > All of this looks to be aligned to the idea that the mutability comes
> > implicit with the (meta) type. I think it's an incorrect thinking,
> > mutability comes in the form of having a way, free of exception, to modify
> > an instance of a given type.
> 
> Mutability is one of the primary considerations when designing a Class. It
> either does or does not have public/protected setMethods. 

That´s my point, which also applies to DataTypes. UML/OCL can define their own built-in data types (Intenger, String, Sequence,...) as immutable if they want, but they shouldn´t impose user data types to be immutable if the user don´t want to be so. It´s a user decision, not an UML/OCL decision.

Regards,
Adolfo.
Comment 27 Ed Willink CLA 2013-10-23 03:59:28 EDT
DataType::ownedOperation. Yes. I was getting confused with Classifier that has attributes but not operations.

So Structured DataTypes are 'mutable'... But what are DataTypes?

UML 2.5 10.2.3 "A DataType is a kind of Classifier. DataType differs from Class in that instances of a DataType are identified only by their value. All instances of a DataType with the same value are considered to be equal instances."

i.e. A DataType is data or more simply just information. You cannot tell how or where this information is maintained. You cannot tell whether it is shared or not, consequently any part that changes cannot be shared while changing. If part of it changes you cannot tell whether the change occurs in part, or through a redirection to a completely different location that has the changed value.

So given a Time DataType with h,m,s integer properties.

var t1 := Time{h=10,m=10,s=10};            // The proposed OCL type constructor
var t2 := t1;
t1.s += 1;

t2.s is unchanged, since t1 and t2 were initially assigned the same information not the same object.

In contrast given a TimePiece Class with h,m,s integer properties, and an (h,m,s) initialization function.

var t1 := object TimePiece{h:=10; m:=10;s:=10;};    // The QVTo type constructor
var t2 := t1;
t1.s += 1;

t2.s is changed since t1 and t2 were initially assigned the same object.

If we now use the OCL type constructor for a Class in QVTo

var t1 := TimePiece{h=10,m=10,s=10};
t1.s += 1;

we must detect the assignment to t1 as an error; use of a ClassInstance-valued Declarative Expression in an Imperative Expression/Statement.

NB.

var t1 := TimePiece{h=10,m=10,s=10} = TimePiece{h=10,m=10,s=10};

is not an error since "TimePiece{h=10,m=10,s=10} = TimePiece{h=10,m=10,s=10}" is a Boolean-valued Declarative Expression which may be safely used in an Imperative Expression/Statement.

So as before, "new", "object" imply allocation of an observable/shareable chunk of memory. They should therefore not be used for DataTypes.
Comment 28 Ed Willink CLA 2013-10-23 05:47:06 EDT
(In reply to Ed Willink from comment #27)
> So as before, "new", "object" imply allocation of an observable/shareable
> chunk of memory. They should therefore not be used for DataTypes.

Trying to bring this thread to a conclusion.

DataTypes can be constructed in QVTo using the proposed OCL type constructor.

For structured types (very analoguous to TupleLiteralExp):

type-name '{' (part-decl ';')* '}'

For unstructured types:

type-name '{' string-expr '}'

---

No extension of ObjectExp or InstantiationExp is needed.

Use of a Declarative Class Instance in an Imperative Expression/Statement must be diagnosed.

---

Bug 420150 starts a new thread to investigate inconsistencies in the behaviour of List and Dict.
Comment 29 Adolfo Sanchez-Barbudo Herrera CLA 2013-10-23 06:33:29 EDT
(In reply to comment #27)
> DataType::ownedOperation. Yes. I was getting confused with Classifier that has
> attributes but not operations.
> 
> So Structured DataTypes are 'mutable'... But what are DataTypes?
> 

Important hint: "might" be 'mutable'. As occur with classes, the data type designer may decide if the structured data type properties are unchangeable after construction or not.

> UML 2.5 10.2.3 "A DataType is a kind of Classifier. DataType differs from Class
> in that instances of a DataType are identified only by their value. All
> instances of a DataType with the same value are considered to be equal
> instances."
> 
> i.e. A DataType is data or more simply just information. You cannot tell how or
> where this information is maintained. You cannot tell whether it is shared or
> not, consequently any part that changes cannot be shared while changing. If part
> of it changes you cannot tell whether the change occurs in part, or through a
> redirection to a completely different location that has the changed value.
> 
> So given a Time DataType with h,m,s integer properties.
> 
> var t1 := Time{h=10,m=10,s=10};            // The proposed OCL type constructor
> var t2 := t1;
> t1.s += 1;
> 
> t2.s is unchanged, since t1 and t2 were initially assigned the same information
> not the same object.
> 
Might be an option, but I think it's presuming too much (there should be an implicit clone of the 'information'). If I maintain my point that DataTypes are like Classes with additional semantic on comparing their instances, I can only say that:

- I only see one Time instance, and two variables referring the same instance.

Java String, perfectly fits on the definition of a UML datatype (to be more precise, PrimitiveType), since we can have many instances of them, while they are all equals among them when underlying the same value. If Java String were mutable, what you described above would not happen (in Java). 

This doesn't justify that what you described is not correct, but I would like find more arguments to support that rationale.

> In contrast given a TimePiece Class with h,m,s integer properties, and an
> (h,m,s) initialization function.
> 
> var t1 := object TimePiece{h:=10; m:=10;s:=10;};    // The QVTo type constructor
> var t2 := t1;
> t1.s += 1;
> 
> t2.s is changed since t1 and t2 were initially assigned the same object.
> 

Agree. But again, I have the feeling that a data type should not be different.

> If we now use the OCL type constructor for a Class in QVTo
> 
> var t1 := TimePiece{h=10,m=10,s=10};
> t1.s += 1;
> 
> we must detect the assignment to t1 as an error; use of a ClassInstance-valued
> Declarative Expression in an Imperative Expression/Statement.
> 

Might be:
- On one hand, it could be useful having access to the same shared instance of class.
- On the other hand, if the shared instance is modified could be dangerous (even to retrieve it via 

I guess that prohibiting should be more beneficial than prejudicial, since the transformation could keep the same shared object via other mechanisms.

> NB.
> 
> var t1 := TimePiece{h=10,m=10,s=10} = TimePiece{h=10,m=10,s=10};
> 
> is not an error since "TimePiece{h=10,m=10,s=10} = TimePiece{h=10,m=10,s=10}" is
> a Boolean-valued Declarative Expression which may be safely used in an
> Imperative Expression/Statement.
> 

Agree.

> So as before, "new", "object" imply allocation of an observable/shareable chunk
> of memory. They should therefore not be used for DataTypes.

As commented, not sure about this, yet. I'd like more argumentation about why, in QVTo, when doing the following:

Time{h=10,m=10,s=10} = Time{h=10,m=10,s=10}

We are comparing the same information (the shared Time instance), whereas when doing the following:

var t1 := Time{h=10,m=10,s=10} 
var t2 := Time{h=10,m=10,s=10}

We have two variables "containing" two different "information" (two different Time instances)

Regards,
Adolfo.
Comment 30 Ed Willink CLA 2013-10-23 07:49:02 EDT
(In reply to Adolfo Sanchez-Barbudo Herrera from comment #29)
> > So given a Time DataType with h,m,s integer properties.
> > 
> > var t1 := Time{h=10,m=10,s=10};            // The proposed OCL type constructor
> > var t2 := t1;
> > t1.s += 1;
> > 
> > t2.s is unchanged, since t1 and t2 were initially assigned the same information
> > not the same object.
> > 
> Might be an option, but I think it's presuming too much (there should be an
> implicit clone of the 'information'). If I maintain my point that DataTypes
> are like Classes with additional semantic on comparing their instances, I
> can only say that:
> 
> - I only see one Time instance, and two variables referring the same
> instance.

You are not being consistent. The term 'instance' is unhelpful and confusing for DataTypes hence my movement to the clearly distinct concept of information.

In the example:

> > var t1 := Time{h=10,m=10,s=10};            // The proposed OCL type constructor

t1 is assigned the information: 10:10:10.

> > var t2 := t1;

t2 is assigned the same information: how it maintains it is not specified, but certainly the most obvious way would be a property by property copy to establish a clone.

I think we agree that at this point t1 and t2 'contain' the same information: 10:10:10

> > t1.s += 1;

This clearly modifies the information held by t1 to be perhaps 10:10:11.

If Time is a DataType, I am arguing that t2 is unaffected and reamins at 10:10:10; its information 'content' is unaffected.

In the converse example using a TimePiece rather than a Time, an object exists and so it is shared so t2 changes when t1 changes.

> > t1.s += 1;
> > 
> > t2.s is unchanged, since t1 and t2 were initially assigned the same information
> > not the same object.
> > 
> Might be an option, but I think it's presuming too much (there should be an

There is no option. You have to decide for the Time DataType example

Either my interpretation that t1 and t2 contain the same unshared information is right leaving t2 unaffected

Or your DataTypes-are-just-classes-with-"=" is right in which case t1,t2 share an object and t2 changes.

Or ... another interpretation.

It seems to me that to share the information for your DataTypes-are-just-classes-with-"=" view you have to identify the DataType by more than the information. t2 has to retain knowledge that the information is shared with t1 if the value of t2 is to change when t1 changes. This would be contrary to "instances of a DataType are identified only by their value".

If it helps consider Java int/Integer.

int t1 = 10;
int t2 = t1;
t1++;          // Does not change t2 because the information '10' was copied/cloned

Integer t1 = 10;
Integer t2 = t1;
t1++;         // Changes t2 because the object containing the information '10' was shared
Comment 31 Adolfo Sanchez-Barbudo Herrera CLA 2013-10-23 10:20:55 EDT
Hi Ed,

Regarding the Time example, I agree with everything what you have say excepting the "copy" by assignment of data types "instances", which I'm not convinced of, yet.

I understand it's not an straightforward thinking, specially when we try to mix in thediscussion, a modeling language and a programming one. However, for better or worse, the term "instance" is being used by UML, as you have many times pasted from the specification excerpts. In essential,

"1", "1" and "2" are instances of the String primitive type
1, 1, and 2 are instances of the Integer primitive type

in general everything is an instance of a type (regardless it's a datatype or a class).

Things get even worse when, you can check for example (better than instance :P) that in section 6.3.1 it says the following:

"Classifiers. A classifier describes a set of objects. An object is an individual thing with a state and relationships to other objects."

So, in UML, providing "1" could be instance of String ...  is this instance a plain value or an object underlying the "1" value ?. I must confess, that common sense would says the former...

(In reply to comment #30)
> 
> There is no option. You have to decide for the Time DataType example
> 

Apologies for my flaky language usage, I should definitely have mentioned "alternative".

> If it helps consider Java int/Integer.
> 
> int t1 = 10;
> int t2 = t1;
> t1++;          // Does not change t2 because the information '10' was
> copied/cloned
> 
> Integer t1 = 10;
> Integer t2 = t1;
> t1++;         // Changes t2 because the object containing the information '10'
> was shared

Unfortunately, you have not chosen the best example. Java primitive types (are their counterpart classes) doesn't provide means to modify the instance (they are immutable), so 

t1++ really turns into t1 = t1 + 1; // so t2 is not related to t1 in both cases (using primitive type and classes)

However, I've been doing some tests and I've looked for more information. The own wikipedia tells us about assignment semantics [1]. It depends of the language, but in Java the assignment work as you described via a copying values (not only for data types, though), so that when doing an assignment :

int a = 1; // you are assigning(copying) the value 1 to the variable a
int b = a; // you are assigning(copying) the value of a (1) to the variable  b

The same when using classes

Integer a = new Integer(1); // you are creating a new object and assigning(copying) the value (a reference to the created object) to the variable a
Integer b = a; // you are assigning(copying)  the value (a reference to an object) to the variable b
 
So finally we only need to clarify, for UML, what the term "instance" of a data type is:
a) a value ? (which would support you alternative)
b) an object underlying the value ? (which would support mine, DataTypes-are-just-classes-with-"=")

The point you recalled about "instances of a DataType are identified only by their value" sounds to be in the direction of a). UML 21.2 Section also seems revealing (what respects at least to primitive types, but I guess we can do it extensive to any datatype - including collections, I guess - )

Resume:
I think we've got an agreement what respects to this long thread. Therefore comment 28 seems fine to me, although I'd recall that, not only the concrete syntax needs to be reworked, but also the abstract syntax (of InstanceLiteralExp).

Regards,
Adolfo.

[1] http://en.wikipedia.org/wiki/Assignment_(computer_programming)#Semantics