Closed eclipse-ocl-bot closed 1 month ago
By Ed Willink on Nov 08, 2018 10:10
The initial Map implementation, Bug 462721, omitted iterators and so avoided clarifying the relationship of MapType and CollectionType; both are DataType. Syntactically "->" is rather tied to CollectionType causing failures when maps are sources.
While CollectionType and MapType are essentially independe the code has to do regular ugly CollectionType or MapType tests.
If MapType is changed to be another CollectionType derivation with key renamed as element, since nearly always we want to iterate over the keys, we risk getting some dubious method overrides. Should asBag return keys or values?
If a new IterableType is introduced between MapType/CollectionType and DataType, IterableType can capture the semantic polymorphism without imposing total compatibility.
MapType has no null-free support for keys or values; inconsistent with CollectionType. Surely needed?
MapType has no lower/upper bounds; inconsistent with CollectionType. Could be provided but surely it would be useless bloat?
Seems difficult to elaborate MapType in a maintenance release. Maybe we need a minor version increment for 2018-12.
By Ed Willink on Nov 14, 2018 04:28
(In reply to Ed Willink from comment #0)
Optionally the at(key) can be optimized to avoid a lookup cost.
Not so easy.
'aMap'->select(key | at(key) = ...)
won't work because aMap is not one of the implicit sources.
Workaround:
let aMap = 'aMap' in aMap->select(key | aMap->at(key) = ...)
Semantic solution:
Add the source collection as an implicit source. There are already too many implicit sources, so risking breakages by adding more is not an option.
Expression keyword solution:
Add a new keyword such as 'selves' for the source collection allowing 'selves->at(key)' - ugly, minor compatibility hazard.
Expression operator solution:
Add a magic spelling such as [...] from QVTo or @... for indexing, but this doesn't really solve the problem of the source naming let alone nested iterations.
Iterator declaration solution:
'aMap'->select(key %magic% value | value = ...)
provides a second iterator and avoids the need to 'recognize' the ->at(key).
If %magic% is just ',' we hit an ambiguity with double iterators for for/exists.
If %magic% is just ';' we hit a confusion with iterator accumulators.
If %magic% is an operator such as '+' or 'and' there could be difficulties if iterations are elaboratied to allow sources to be specified as initializer syntax. e.g. forAll(c in sources | ...)
If %magic% is a Tuple constructor to bind two names as one, the names should be types causing clumsiness.
%magic% probably needs to be a new keyword, or a new punctuation sequence.
We already have '<-' for MapLiteral construction, so
'aMap'->forAll(key1 <- value1, key2 <- value2\
| key1=key2 implies value1=value2)
could be the way to go.
In the OCL metamodel elaborating LoopExp.ownedIterators to accommodate a second iterator may be easiest by adding LoopExp.ownedCoIterators rather than some new type of dual name, dual value Variable that requires just ownedIterators.
By Ed Willink on Nov 21, 2018 05:51
map iterators and co-iterators pushed to master for M3.
| --- | --- | | Bugzilla Link | 540884 | | Status | RESOLVED FIXED | | Importance | P3 normal | | Reported | Nov 07, 2018 08:03 EDT | | Modified | Nov 21, 2018 05:51 EDT | | See also | 540353, 462721, 443003 | | Reporter | Ed Willink |
Description
Private communication from Kevin Lano asks about a standard Map and makes some suggestions.
In particular the current Map has no iterators.
Most iterators can trivially be implemented as a standard Set iterator over the key.
Optionally the at(key) can be optimized to avoid a lookup cost.
Possibly a double iterator argument could be key+value, but this would be ambiguous with a double argument dorAll. Perhaps an iterator culd be declared with Tuple(K, V) type to get access to both key and value.
The standard collect would lose keys.
The collectBy constructor suggested in Bug 540353 could support Map to Map computation.