v0.2.16
This commit is contained in:
@@ -1,26 +1,159 @@
|
||||
# 22. Collections et itération
|
||||
|
||||
## 22.1 `Array<T>` — V1 REQUIS — DIRECTION FIGÉE
|
||||
## 22.1 `Array<T>` — V1 REQUIS — FIGÉ EN PRINCIPE
|
||||
|
||||
`Array<T>` est une séquence contiguë dont la taille est fixée lors de la création et n'est pas redimensionnable.
|
||||
`Array<T>` est une séquence contiguë dont la longueur est déterminée au runtime lors de la construction et reste fixe ensuite.
|
||||
|
||||
## 22.2 `StaticArray<T,N>` — V1 REQUIS — DIRECTION FIGÉE
|
||||
Il n'expose pas d'opération structurelle de redimensionnement.
|
||||
|
||||
`StaticArray<T,N>` est un tableau à taille connue à la compilation.
|
||||
|
||||
Le mécanisme exact de const generics nécessaire à `N` doit être défini avec les generics.
|
||||
|
||||
## 22.3 Collection redimensionnable — V1 REQUIS — À FINALISER
|
||||
|
||||
Un type du type :
|
||||
Les éléments suivent exactement la sémantique normale de `T` :
|
||||
|
||||
```text
|
||||
Vector<T>
|
||||
T primitif -> valeur by-value
|
||||
T struct -> valeur by-value
|
||||
T class -> référence de classe
|
||||
```
|
||||
|
||||
est envisagé pour les séquences redimensionnables, mais l'API et le nom final doivent être figés dans le SDK V1.
|
||||
Copier un `Array<T>` crée une collection indépendante. Les éléments eux-mêmes sont copiés selon la sémantique normale de `T`.
|
||||
|
||||
## 22.4 `Iterable<T>` / `Iterator<T>` — V1 REQUIS — FIGÉ
|
||||
Pour `Array<User>`, deux arrays copiés peuvent donc contenir des références vers les mêmes objets `User`, tout en restant indépendants quant au remplacement de leurs cases.
|
||||
|
||||
### 22.1.1 Initialisation complète
|
||||
|
||||
Un `Array<T>` safe doit être entièrement initialisé avant de devenir observable.
|
||||
|
||||
Il n'existe aucune initialisation implicite en zéro, `null`, `None` ou valeur indéfinie.
|
||||
|
||||
```text
|
||||
Array<int32> values = [1, 2, 3];
|
||||
Array<int32> empty = [];
|
||||
```
|
||||
|
||||
Le littéral `[...]` est contextualisé par le type attendu ; il ne reçoit pas automatiquement un type autonome hors contexte suffisant.
|
||||
|
||||
Les expressions d'un littéral d'array sont évaluées exactement une fois, de gauche à droite. En cas d'échec pendant la construction, aucun array partiellement initialisé ne devient observable.
|
||||
|
||||
### 22.1.2 `filled`
|
||||
|
||||
```text
|
||||
Array<T>::filled(uint64 length, T value)
|
||||
```
|
||||
|
||||
`value` est évaluée une seule fois, puis répétée selon la sémantique normale de copie de `T`.
|
||||
|
||||
```text
|
||||
User firstUser = ...;
|
||||
User otherUser = ...;
|
||||
|
||||
Array<User> users = Array<User>::filled(3, firstUser);
|
||||
users[1] = otherUser; // OK si l'accès n'est pas const
|
||||
```
|
||||
|
||||
Initialement, les trois cases contiennent la même référence `firstUser`. Chaque case reste cependant un emplacement indépendant et peut recevoir ultérieurement une autre référence.
|
||||
|
||||
`filled()` ne clone jamais implicitement un objet référencé.
|
||||
|
||||
### 22.1.3 `empty` et `generate`
|
||||
|
||||
```text
|
||||
Array<T>::empty()
|
||||
```
|
||||
|
||||
construit un array de longueur zéro.
|
||||
|
||||
Une opération `generate` est retenue conceptuellement pour construire une valeur distincte par index. Sa syntaxe exacte sera figée avec les callables/lambdas.
|
||||
|
||||
La factory devra être appelée exactement une fois par index, dans l'ordre croissant, sans parallélisation implicite.
|
||||
|
||||
Le safe code ne peut pas obtenir un `Array<T>` observable partiellement/non initialisé. Le compilateur/runtime reste libre d'utiliser de la mémoire non initialisée en interne tant qu'elle n'est jamais observable.
|
||||
|
||||
## 22.2 `StaticArray<T,N>` — V1 REQUIS — FIGÉ
|
||||
|
||||
`StaticArray<T,N>` est une séquence contiguë dont la longueur `N` est connue à la compilation et reste fixe.
|
||||
|
||||
```text
|
||||
StaticArray<int32, 3> values = [10, 20, 30];
|
||||
StaticArray<int32, 0> empty = [];
|
||||
```
|
||||
|
||||
Le nombre d'éléments du littéral doit correspondre exactement à `N`.
|
||||
|
||||
Une initialisation répétée utilise :
|
||||
|
||||
```text
|
||||
StaticArray<T,N>::filled(T value)
|
||||
```
|
||||
|
||||
avec la même sémantique de copie que `Array<T>::filled`.
|
||||
|
||||
`StaticArray<T,N>` n'autorise pas davantage qu'`Array<T>` l'observation d'éléments non initialisés.
|
||||
|
||||
## 22.3 `Slice<T>` — V1 REQUIS — FIGÉ EN PRINCIPE
|
||||
|
||||
`Slice<T>` est une vue contiguë, de longueur fixe, sur une portion d'un stockage existant.
|
||||
|
||||
Une slice ne réalise aucune copie sémantique des éléments.
|
||||
|
||||
```text
|
||||
Array<int32> values = ...;
|
||||
Slice<int32> part = values::slice(10..<20);
|
||||
|
||||
part[0] = 42; // modifie values[10]
|
||||
```
|
||||
|
||||
Une slice :
|
||||
|
||||
```text
|
||||
reste attachée à la portion qu'elle désigne
|
||||
conserve une longueur fixe
|
||||
n'est pas redimensionnable
|
||||
n'est pas déplaçable vers une autre portion
|
||||
peut modifier les éléments uniquement si l'accès source l'autorise
|
||||
ne peut jamais augmenter les droits de mutabilité de la source
|
||||
```
|
||||
|
||||
La constness se propage :
|
||||
|
||||
```text
|
||||
const Array<User> users = ...;
|
||||
const Slice<User> part = users::slice(0..<4);
|
||||
|
||||
part[0] = otherUser; // ERROR
|
||||
part[0]::setName("Alice"); // ERROR
|
||||
part[0]::getName(); // OK
|
||||
```
|
||||
|
||||
Le backing storage nécessaire à une slice reste vivant aussi longtemps que nécessaire. Cette garantie ne requiert aucune syntaxe de lifetime utilisateur.
|
||||
|
||||
Une slice vide est une valeur valide.
|
||||
|
||||
Les indices d'une sous-slice sont relatifs à la slice source.
|
||||
|
||||
`Slice<T>` garantit la contiguïté. Une éventuelle vue non contiguë constituerait un autre concept et n'est pas réservée sans besoin réel.
|
||||
|
||||
## 22.4 Interfaces de collections — V1 REQUIS — FIGÉ EN PRINCIPE
|
||||
|
||||
Les interfaces décrivent des capacités réellement garanties. Les classes/structs génériques fournissent le stockage et l'implémentation.
|
||||
|
||||
Saselang ne retient pas le modèle d'opérations optionnelles qui existent dans une interface mais échouent ensuite au runtime comme « unsupported ».
|
||||
|
||||
Hiérarchie principale retenue :
|
||||
|
||||
```text
|
||||
Iterable<T>
|
||||
↓
|
||||
Collection<T>
|
||||
↓
|
||||
List<T>
|
||||
↓
|
||||
SettableList<T>
|
||||
↓
|
||||
ResizableList<T>
|
||||
```
|
||||
|
||||
`Set<T>` et `Map<K,V>` sont des branches distinctes à préciser.
|
||||
|
||||
### 22.4.1 `Iterable<T>` / `Iterator<T>`
|
||||
|
||||
Interfaces Core reconnues par `foreach`.
|
||||
|
||||
@@ -28,6 +161,107 @@ Elles ne portent pas le préfixe `Op`, car `foreach` est une construction du lan
|
||||
|
||||
Indexabilité et itérabilité sont indépendantes.
|
||||
|
||||
### 22.4.2 `Collection<T>`
|
||||
|
||||
`Collection<T>` étend `Iterable<T>` et représente une collection finie d'éléments.
|
||||
|
||||
Contrat minimal retenu :
|
||||
|
||||
```text
|
||||
count() -> uint64
|
||||
isEmpty() -> bool
|
||||
contains(const T value) -> bool
|
||||
```
|
||||
|
||||
`count()` exprime le nombre d'éléments au sens général de collection.
|
||||
|
||||
### 22.4.3 `List<T>`
|
||||
|
||||
`List<T>` étend `Collection<T>` et `OpIndex<uint64,T>`.
|
||||
|
||||
Elle garantit :
|
||||
|
||||
```text
|
||||
ordre stable
|
||||
indexation positionnelle en lecture
|
||||
length() -> uint64
|
||||
```
|
||||
|
||||
Pour une `List<T>` :
|
||||
|
||||
```text
|
||||
count() == length()
|
||||
```
|
||||
|
||||
Les deux noms sont néanmoins conservés parce qu'ils expriment des concepts différents : cardinalité générale de collection et longueur d'une séquence indexable.
|
||||
|
||||
`List<T>` ne garantit ni remplacement d'un élément, ni redimensionnement, ni complexité algorithmique particulière de l'accès indexé.
|
||||
|
||||
### 22.4.4 `SettableList<T>`
|
||||
|
||||
`SettableList<T>` étend `List<T>` et `OpIndexMut<uint64,T>`.
|
||||
|
||||
Elle garantit le remplacement d'un élément existant sans modification de la longueur.
|
||||
|
||||
```text
|
||||
list[index] = value;
|
||||
```
|
||||
|
||||
ne signifie jamais `append` lorsque `index == length()`.
|
||||
|
||||
### 22.4.5 `ResizableList<T>`
|
||||
|
||||
`ResizableList<T>` étend `SettableList<T>`.
|
||||
|
||||
Elle garantit des opérations structurelles capables de modifier la longueur, par exemple ajout, insertion et suppression.
|
||||
|
||||
Les signatures exactes seront figées lors de la définition du type concret redimensionnable.
|
||||
|
||||
Un `resize(newLength)` sans information d'initialisation n'est pas retenu implicitement : agrandir une collection doit toujours définir comment les nouveaux éléments sont construits.
|
||||
|
||||
### 22.4.6 Capacité du type et permission `const`
|
||||
|
||||
La capacité intrinsèque du type et la permission d'un accès sont deux dimensions distinctes.
|
||||
|
||||
```text
|
||||
SettableList<User> users = ...;
|
||||
const SettableList<User> readonly = users;
|
||||
```
|
||||
|
||||
Le type sait remplacer des éléments, mais l'accès `readonly` ne peut pas utiliser cette capacité.
|
||||
|
||||
La propagation générale de `const` reste applicable aux éléments obtenus via cet accès.
|
||||
|
||||
### 22.4.7 Classification initiale
|
||||
|
||||
```text
|
||||
StaticArray<T,N>
|
||||
List<T>
|
||||
SettableList<T>
|
||||
pas ResizableList<T>
|
||||
|
||||
Array<T>
|
||||
List<T>
|
||||
SettableList<T>
|
||||
pas ResizableList<T>
|
||||
|
||||
Slice<T>
|
||||
List<T>
|
||||
SettableList<T>
|
||||
pas ResizableList<T>
|
||||
|
||||
Vector<T>
|
||||
List<T>
|
||||
SettableList<T>
|
||||
ResizableList<T>
|
||||
```
|
||||
|
||||
`Vector<T>` reste à définir précisément.
|
||||
|
||||
Un type persistant/immutable par nature n'a aucune obligation d'implémenter `List<T>`. Par exemple, un futur `PersistentList<T>` peut implémenter uniquement `Collection<T>` et fournir ses propres opérations si cela correspond mieux à sa sémantique.
|
||||
|
||||
Une interface Saselang n'est jamais implémentée uniquement parce qu'un type ressemble conceptuellement à une autre famille de types.
|
||||
|
||||
## 22.5 `Range<T>` — V1 REQUIS — FIGÉ EN PRINCIPE
|
||||
|
||||
`Range<T>` est une vraie valeur Saselang immuable représentant un intervalle ordonné. Il ne représente ni un pas ni une progression d'itération.
|
||||
|
||||
Reference in New Issue
Block a user