Closed seidewitz closed 5 years ago
When the template activity is represented in Alf, T
is a template parameter, which, in the Alf abstract syntax, is a kind of classifier. However, when the activity is represented in UML, it has a template classifier parameter whose parametered element is the actual classifier T
. The parameters of the activity are typed by the parametered element, not the template parameter.
In the case of Reverse
being a UML activity, the T
in the explicit binding Reverse<T>
gets resolved to an external reference to the template parameter, not the parametered element. However, for the purposes of Alf processing, a classifier template parameter is considered to effectively be a classifier, even though the "real" classifier is the parametered element. The template parameter substitution for Reverse<T>
then results in the return type for the invocation being the template parameter.
Next, the invocation of the (template) collection function including
is implicitly bound to the effective common ancestor of the types of the two arguments to the function. The first argument is the result of the Reverse<T>
invocation, which, as indicated above, has the classifier template parameter as its type. The second argument, seq[1]
, however, has the actual parametered element classifier as its type.
Finally, when the effective common ancestor is computed, the classifier template parameter is not "deferenced" to its parameter element. Therefore, no common ancestor is found between it and the actual classifier that is the type of seq[1]
, resulting in the effective common ancestor any
. And this is not compatible with the return type of the Reverse
activity.
If, on the other hand, an implicit invocation is used for the call to Reverse
, then the implicit binding is the type of seq->excludeAt(1)
, which is the actual paramtered element classifier. This is then the same as the type of seq[1]
, so also becomes the result type for the call to including
, which is compatible with the return type of the activity.
Fixed in v1.1.0h.
Consider the following example activity for reversing a sequence:
This parses and executes successfully with our without the explicit template binding for
Reverse<T>
. However, if the return statement is used as the body of the equivalent template activity in an external UML model, then there is areturnStatementContext
constraint violation because of a type incompatibility between the return statement and the return type, but only when the explicit bindingReverse<T>
is used. If the recursiveReverse
call is implicitly bound, there is no violation.