Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [qvto-dev] Oustanding discussion for QVT 1.3 Ballot 3

Hi

Thanks for the review. Comments inline.

    Regards

        Ed Willink

On 14/10/2015 14:30, Adolfo Sanchez-Barbudo Herrera wrote:
On 14/10/2015 12:40, Ed Willink wrote:

http://solitaire.omg.org/browse/QVT13#selectedTab=org.omg.jira.task-forces%3Ataskforce-issues-panel&view=HAS_PROPOSAL

is the 'active' work in progress/pending.
Hi Ed

After reading the "final" issue resolution, I add the following comments here:

QVTo-dev is a more open/accessible list. So I'll add my comments here about "http://solitaire.omg.org/browse/QVT13-102" and add a link back in JIRA.

Since we don't have lines, I'll refer to "text" which you should be able to identify with a Ctrl+F facility in the issue resolution.

Here we go:

--------------------
 Firstly you mention

"... In the case of a standard mode execution for which no candidate mapping is selected, the trace record contains null entries for executed-mapping, out-parameters and result-parameters fields."

Later one:

"...If no mapping is executed, the executed-mapping, out-parameters and result-parameters are null."

It sounded kinda redundant to me. Feel free to decide if you keep both or not.
Yes. The lines migrated rather close together.
-------------------

An equivalent OCL-like query for SOURCE.resolve(T : TYPE | CONDITION) is


I'm unsure (apologies for vagueness) if for inout parameters you are allowed to return a different object/value, but I'm concerned about what happens if the inout-parameter is the same object at the end of the mapping execution as the object which came in (regardless it is modified by the mapping or not), that might provoke that calls to source.resolve might return the same source object, which at least sounds awkward. I'm not sure what should be done, but I throw the discussion about if:

selectedRecords->collect(out-parameters->union(result-parameters))...

Should be

selectedRecords->collect(out-parameters)->union(selectedRecords->collect(result-parameters))->excludingAll(selectedRecords->collect(in-parameters))...

or at least

selectedRecords->collect(out-parameters)->union(selectedRecords->collect(result-parameters))->excluding(SOURCE)...

Probably the former, in a short form:

selectedRecords.out-parameters->union(selectedRecords.result-parameters)->excludingAll(selectedRecords.in-parameters)...


[NB Is there no excludingAll (i.e. subtract or set complements operation) in OCL library?. excludingAll works in Pivot- Eclipse OCL]
I don't see a problem here. inout-parameters are traced twice.

Class instances are traced by reference and so are blind to mutation. Specification-wise a pair of references is not a problem. If Eclipse QVTo copies instance content, then that is an issue for Eclipse QVTo. To fully support incremental execution traced Class Instances would need to be treated as DataType values so that everything is deepcloned, but of course taking care to share referenced objects in their correct states.

Since the Class instance reference is a reference, it cannot be chnaged to another object so the double trace is redundant.

DataType values (including Dict) are traced by value, so the entire inout Dict is deepcloned twice. Not a problem specification-wise. An implementation might save memory on one of the deepclones. My original QVT Traceability paper thoughts dismissed inout Dict tracing as too expensive in parctice and suggested that inout parameters be excluded from tracing. However redundant execution/re-use requires them to be in the trace. Eclipse Qvto appears to deepclone. I have twice asked Christopher if he is happy with this clear specification and he has not objected. Sergey seems to be busy/elsewhere.

DataType values are passed by reference-to-variable so the entire value may be changed, and so a double trace is necessary.

In the same OCL _expression_. ->collect flattens the result, so ->flatten() seems unnecessary ]
Yes.

-----------------------

invresolve at 8.1.x.4

Whereas from one source object we might produce different output objects through different mappings, from one target there should be just one source object. In any case, filtering types/conditions should apply to source domain. Suggestion

replace

   target.invresolve(t : Table | t.name.startsWith('_'))
   target.invresolveIn(Class2Table, t : Table | t.name.startsWith('_'))

by
   invresolve(Class)
   invresolveIn(Class2Table, c : Class | c.name.startsWith('_'))
   target.invresolve() // No filtering conditions: just one object can be the source of a created object

No. This is an ambiguity that my words and pseudo-code clear up. Given:

Tuple{gOut, hOut} t := aIn.map m(bIn, cIn, dInout, eOut, fOut)

{aIn,bIn,cIn,dInOut} are traced to {dInout,eOut,fOut,gOut,hOut}

so all sources for the dInout target/ m mapping are {aIn,bIn,cIn,dInOut}.

[NB 8.1.x.5 has similar issues with the same invresolveone expressions]
-----------------------------

"deep value equality". Is this a standarized/well-known concept ?. I think I know that you refer, but... others might not.
Dotting every I and crossing every T formally is beyond my current ambition. Once QVT 2.0 provides a solid CS2AS and perhaps AS evaluation semantics, we can try to do better. Otherwise I'll wait for the 'what does deep equality mean' issue.

-----------------

In 8.1.x.7. Redundant execution

In second paragraph, you comment what happens when input objects are modified, with respect to decide if a mapping is not re-executed (and returns previous outputs)

In last paragraph, perhaps evident, but I think a sentence might be similarly added with respect to the out-put objects which also might be modified between redundant mapping calls.
Yes.

"...matching name and argument count." => "...matching name and arguments."

No. If you mean in the 8.2.1.15 Replace.

This is not OO. arguments may be covariant or contravariant.

m(Real) is a candidate implicit disjunct of m(String). However when the candidate list of an invocation of m(Real) is built giving the choices {m(Real), m(String)} static analysis can reveal that String is neither a supertype nor subtype of Real. Its implicit argument type predicate can never match and so there is no point seeing if it does.

In practice this is very important.

OO does not allow f(A) to be overloaded by f(BextendsA). A mapping call does so we achieve the utopia of a layer of derived types that work together unlike OO where we need to keep downcasting.
-----------------

Removal of Mapping disjuncts as a reuse facility.

To me disjunct is arguably a reuse facility, but I like the direction you want to give to that part. Perhaps using "mapping extension" rather than "re-use facility" is more appropriate.
It's hardly that either. It is really just a mapping selection/switch.

Another issue I find in that part is that you:

1. firstly mention mapping inheritance/merge as the only two reuse facility,
2. then clarify a disjuncting mapping.
3. then you mention: The execution semantics subsection below provides the details of these reuse facilities.
Probably just being lazy and trying to rewrite not enough.

Therefore I'd rework that part as follows:

In section 8.2.15 Replace

There are three reuse and composition facilities associated to mapping operations:
1. A mapping operation may inherit from another mapping operation. This means invoking the initialization section of
the inherited operation after executing its own initialization section.
2. A mapping operation may also merge other mapping operations. This means invoking the merged operations after the
termination section.
3. A mapping operation may be defined as a disjunction of other mapping operations. This means selecting, among the
set of disjuncted mappings, the first that satisfies the when clause and then invoking it. The execution semantics subsection
below provides the details of these reuse facilities

By

A mapping operation may be defined as an explicit disjunction of candidate mapping operations. This means selecting and executing the first candidate mapping whose when clause and other predicates are satisfied. The empty body of the disjuncting mapping is not executed. An implicit disjunction of candidate mappings is formed by overloaded mappings with matching name and argument count.

Additionally, there are two extension mechanisms associated to mapping operations:
1. A mapping operation may inherit from another mapping operation. This means invoking the initialization section of the inherited operation after executing its own initialization section.
2. A mapping operation may also merge other mapping operations. This means invoking the merged operations after the termination section.

The execution semantics subsection below provides the details of these mapping extension mechanisms.


Probably. More important to get the more interesting replies out sooner.
----------------

Final corrections:

"In strict mode failure to evaluate..." => "In strict mode, failure to evaluate..."
Yes.

"This is shorthand for invoking it in the body of a ForExp _expression_" => "This is shorthand for invoking it in the body of a xcollect ImperativeIterateExp _expression_."
Yes.


Back to the top