Skip to content

Commit 113fc8a

Browse files
Add Parametrics Next Generation as draft.
1 parent 2340d54 commit 113fc8a

File tree

8 files changed

+151
-1
lines changed

8 files changed

+151
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ Gemfile.lock
77
.bundle
88
vendor/
99
.DS_Store
10+
.vscode/ltex.dictionary.en-US.txt

_data/authors.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
},
5252
"Clotilde Toullec": {
5353
"name": "Clotilde Toullec",
54-
"role": "Moose developer",
54+
"role": "Research engineer",
5555
"bio": "Software engineer, maintains and develops Moose",
5656
"github": "https://github.com/ClotildeToullec",
5757
"linkedin": "https://www.linkedin.com/in/clotilde-toullec-3aa685105/",
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
---
2+
layout: post
3+
title: "Parametrics next generation"
4+
subtitle: The Famix metamodel evolves
5+
date: 2025-05-07 15:02:34
6+
background: '/img/posts/bg-posts.jpg'
7+
author: Clotilde Toullec
8+
comments: true
9+
tags: meta-model
10+
---
11+
12+
How do we represent the relation between a generic entity, its type parameters and the entities that concretize it? The Famix metamodel has evolved over the years to improve the way we represent these relations. The last increment is described in a previous [blogpost]({% link _posts/2023-07-13-parametric.md %}).
13+
We present here a new implementation that eases the management of parametric entities in Moose.
14+
15+
The major change between this previous version and the new implementation presented in this post is this:
16+
**We do not represent the parameterized entities anymore**.
17+
18+
> #### :paperclip: Generic? Parametric? Parameterized? Know the difference.
19+
> - A **parametric entity** is an entity that declares type parameters or arguments. It can be generic or parameterized, according to the following definitions.
20+
> - A **generic entity** is an entity that defines 1 or several type parameters. To be instantiated, inherited, implemented or invoked, their type parameters must be replaced by existing types (type arguments). `ArrayList<E>` is a generic class. In Famix Java, we represent generic classes, interfaces and methods.
21+
> - A **type parameter** is a parameter that must be replaced by an existing type in order to use the generic entity that defines it. In `ArrayList<E>`, `E` is a type parameter.
22+
> - A **parameterized entity** is a parametric entity for which the type parameters have been replaced by existing types. `ArrayList<String>` is a parameterized class. Parameterized entities are not represented as entities in the new Famix implementation.
23+
> - A **type argument** is the type used to replace a type parameter. It can be any type, except primitive types. `String` is a type argument of `ArrayList<String>`.
24+
> - A **concretization** is a Famix association that represents the fact that a type parameter has been replaced by a type argument.
25+
>
26+
>> :information_source: In Famix, because parameterized entities are not represented anymore, "parametric" and "generic" can be used interchangeably to refer to generic entities.
27+
28+
## What's wrong with the previous parametrics implementation?
29+
30+
### Difference between parametric and non-parametric entities
31+
32+
The major issue with the previous implementation was the difference between parametric and non-parametric entities in practice, particularly when trying to trace the inheritance tree.
33+
Here is a concrete example: getting the superclass of the superclass of a class.
34+
- For a non-parametric class, the sequence is straightforward: ask the inheritance for the superclass, repeat.
35+
36+
![Getting super inheritances - Non-parametric entities.](/img/posts/2025-05-07-Parametrics-Next-Generation/sequence-inheritance-non-parametric.png)
37+
- For a parametric class (see the little code snippet below), there was an additional step, navigating through the concretization:
38+
39+
{% highlight java %}
40+
import java.util.ArrayList; "public class ArrayList<E> { /* ... */ }"
41+
42+
public MySpecializedList extends ArrayList<String> {}
43+
{% endhighlight %}
44+
45+
![Getting super inheritances - Parametric entities.](/img/posts/2025-05-07-Parametrics-Next-Generation/sequence-inheritance-parametric.png)
46+
47+
This has caused many headaches to developers who wanted to browse a hierarchy: how do we keep track of the full hierarchy when it includes parametric classes? How to manage both situations without knowing if the classes will be parametric or not?
48+
The same problem occurred to browse the implementations of parametric interfaces and the invocations of generic methods.
49+
### Naming
50+
The previous implementation naming choices were a little complex to grasp and did not match the standard vocabulary, especially in Java:
51+
- A type parameter was named a `ParameterType`
52+
- A type argument was named a `ConcreteParameterType`
53+
54+
### Entities duplication
55+
56+
Each time there was a concretization, a parametric entity was created. This created duplicates of virtually the same entity: one for the generic entity and **one for each parameterized entity**.
57+
Let's see an example:
58+
{% highlight java %}
59+
public MyClass implements List<Float> {
60+
61+
public List<Integer> getANumber() {
62+
List<Number> listA;
63+
List<Integer> listB;
64+
}
65+
}
66+
{% endhighlight %}
67+
68+
For the interface `List<E>`, we had 6 parametric interfaces:
69+
- One was the generic one: `#isGeneric >>> true`
70+
- 3 were the parameterized interfaces implemented by `ArrayList<E>`, its superclass `AbstractList<E>` and `MyClass`. They were different because the *concrete types* were different: `E` from `ArrayList<E>`, `E` from `AbstractList<E>`and `Float`.
71+
- 2 were declared types: `List<Number>` and `List<Integer>`.
72+
73+
## The new implementation
74+
75+
### Parametric associations
76+
77+
When deciding of a new implementation, our main goal was to create a situation in which the dependencies would work in the same way for all entities, parametric or not.
78+
That's where we introduce parametric associations. These associations only differ from standard associations by one property: they trigger a concretization.
79+
80+
Here is the new Famix metamodel traits that represent concretizations:
81+
82+
![Class diagram for Parametric Associations](/img/posts/2025-05-07-Parametrics-Next-Generation/uml-parametric-association.png)
83+
84+
There is a direct relation between a parametric entity and its type parameters.
85+
A concretization is the association between a type parameter and the type argument that replaces it.
86+
A parametric association triggers one or several concretizations, according to the number of type parameters the parametric entity has. Example: a parametric association that targets `Map<K,V>` will trigger 2 concretizations.
87+
88+
The parametric entity is the target of the parametric association. It is always generic. As announced, we do not represent parameterized entities anymore.
89+
Coming back to the entities' duplication example above, we now represent only 1 parametric interface for `List<E>`and it is the target of the 5 parametric associations.
90+
91+
### Entity typing
92+
93+
This metamodel evolution is the occasion of another major change: the replacement of the direct relation between a typed entity and its type. This new association is called Entity typing.
94+
95+
![Class diagram for Entity Typing](/img/posts/2025-05-07-Parametrics-Next-Generation/uml-entity-typing.png)
96+
97+
The choice to replace the existing relation by a reified association is made to represent the dependency in coherence with the rest of the metamodel.
98+
99+
With this new association, we can now add parametric entity typings.
100+
101+
In a case like this:
102+
{% highlight java %}
103+
public ArrayList<String> myAttribute;
104+
{% endhighlight %}
105+
we have an "entity typing" association between `myAttribute` and `ArrayList`. This association is parametric: it triggers the concretization of `E` in `ArrayList<E>` by `String`.
106+
107+
> ##### :recycle: Deprecation
108+
> The method `#declaredType` is still part of the API of `TTypedEntity`. However, it's not a getter for the `#declaredType` attribute anymore. It now returns the type that is target of the association.
109+
>
110+
> The setter `#declaredType:` is deprecated and cannot be automatically transformed. If you need to replace it, you should create an instance of the EntityTyping class in your metamodel and set the declared type as its target. You will have something like:
111+
{% highlight smalltalk %}
112+
myVariable := myModel newLocalVariableNamed: #myVar.
113+
myType := myModel newTypeNamed: #MyType.
114+
myVariable typing: (myModel newEntityTyping
115+
declaredType: myType;
116+
yourself).
117+
{% endhighlight %}
118+
119+
### Type parameters bounds
120+
121+
Type parameters can be bounded:
122+
{% highlight java %}
123+
public class MyParametricClass<T extends Number> {}
124+
{% endhighlight %}
125+
In the previous implementation, the bounds of type parameters were implemented as inheritances: in the example above, `Number` would be the superclass of `T`.
126+
Since this change, bounds were introduced for wildcards.
127+
We have now the occasion to also apply them to type parameters.
128+
In the new implementation, `Number` is the upper bound of `T`.
129+
130+
## Summary
131+
132+
This diagram sums up the new parametrics implementation in Famix traits and Java metamodel.
133+
134+
![Class diagram for all changes](/img/posts/2025-05-07-Parametrics-Next-Generation/uml-new-parametrics-mm.png)
135+
136+
## What's next?
137+
138+
### Should Concretization really be an association?
139+
140+
The representation of parametric entities is a challenge that will most likely continue as Famix evolves. The next question will probably be this one: should `Concretization` really be an association?
141+
An association is the reification of a dependency. Yet, there is no dependency between a type argument and the type parameter it replaces. Each can exist without the other. The dependency is in fact between the source of the parametric association and the type parameter.
142+
143+
With one of our previous examples:
144+
{% highlight java %}
145+
public MySpecializedList extends ArrayList<String> {}
146+
{% endhighlight %}
147+
`MySpecializedList` has a superclass (`ArrayList<E>`) and also depends on `String`, as a type argument. However, `String` does not depend on `E` neither `E`on `String`.
148+
149+
The next iteration of the representation of parametric entities will probably cover this issue. Stay tuned!
10.8 KB
Loading
24.9 KB
Loading
7.94 KB
Loading
114 KB
Loading
25.5 KB
Loading

0 commit comments

Comments
 (0)