This commit is contained in:
2026-09-12 08:56:27 +02:00
parent 426aa92d0d
commit 18306bdc8c
116 changed files with 11080 additions and 0 deletions

365
chapters/020-operateurs.md Normal file
View File

@@ -0,0 +1,365 @@
# 20. Opérateurs
## 20.1 Principe — V1 REQUIS — FIGÉ
Les opérateurs utilisateur ne peuvent être fournis que via un ensemble fermé d'interfaces Core compiler-known préfixées `Op`.
L'utilisateur ne peut pas inventer de nouveaux symboles opérateurs.
Les `operator` contracts :
- retournent directement leur valeur ;
- ne retournent jamais `Result` ;
- ne déclarent jamais `throws`.
Une faute de contrat du langage peut néanmoins déclencher une faute runtime déterministe.
## 20.2 Interfaces arithmétiques — V1 REQUIS — FIGÉ
```text
OpPositive<T>
OpNegate<T>
OpAdd<Lhs,Rhs,Out>
OpSubtract<Lhs,Rhs,Out>
OpMultiply<Lhs,Rhs,Out>
OpDivide<Lhs,Rhs,Out>
OpRemainder<Lhs,Rhs,Out>
```
Les opérations binaires peuvent être hétérogènes.
Exemples légitimes :
```text
Vector3 * float64 -> Vector3
Matrix * Vector3 -> Vector3
Timestamp + Duration -> Timestamp
Timestamp - Timestamp -> Duration
```
L'ordre compte : `A op B` est distinct de `B op A`.
## 20.3 Interfaces bitwise — V1 REQUIS — FIGÉ
```text
OpBitNot<T>
OpBitAnd<Lhs,Rhs,Out>
OpBitOr<Lhs,Rhs,Out>
OpBitXor<Lhs,Rhs,Out>
OpShiftLeft<T,Out>
OpShiftRight<T,Out>
```
Pour les primitives numériques, `& | ^` exigent les mêmes types primitifs exacts, sans promotion implicite.
Les shifts primitifs utilisent initialement `uint32` comme type de count.
Count hors largeur :
```text
statique -> erreur compilation
dynamique -> faute runtime
```
`>>` :
```text
unsigned -> logical zero-fill
signed -> arithmetic sign extension
```
Pas de `>>>`.
## 20.4 Logique booléenne — V1 REQUIS — FIGÉ
Short-circuit :
```text
!a
a && b
a || b
```
Eager :
```text
a & b
a | b
a ^ b
```
`&&`, `||` et `!` ne sont pas surchargeables.
`&`, `|`, `^` ont une sémantique intrinsèque eager pour `bool`, bitwise pour les primitives entières et peuvent utiliser les contrats `OpBit...` sur types utilisateur.
Pas de NAND/NOR natifs.
## 20.5 Égalité — V1 REQUIS — FIGÉ EN PRINCIPE
```text
OpPartialEqual<Lhs,Rhs>
OpEqual<T>
```
`OpEqual<T>` renforce :
```text
OpPartialEqual<T,T>
```
et garantit contractuellement une relation d'équivalence :
```text
réflexive
symétrique
transitive
```
`float*` n'est pas `OpEqual` au sens strict si NaN brise la réflexivité ; il relève de l'égalité partielle.
`!=` est toujours dérivé de `==`, jamais implémenté indépendamment.
Les classes ne reçoivent aucune comparaison champ-à-champ automatique : elles doivent choisir explicitement leur sémantique d'égalité si elles veulent supporter `==`.
## 20.6 Comparaison — V1 REQUIS — FIGÉ EN PRINCIPE
Core :
```text
public enum Ordering {
Less,
Equal,
Greater,
Unordered
}
```
Interfaces :
```text
OpPartialCompare<Lhs,Rhs>
OpCompare<T>
```
`OpCompare<T>` renforce `OpPartialCompare<T,T>` et garantit un ordre total, donc pas de `Ordering::Unordered`.
Les floats utilisent l'ordre partiel ; les entiers peuvent utiliser l'ordre total.
Le lien exact entre égalité et comparaison pour éviter deux contrats contradictoires sur une même paire doit être verrouillé dans la spécification finale des interfaces `Op`.
## 20.7 Comparaisons hétérogènes — V1 REQUIS — FIGÉ EN PRINCIPE
Saselang doit conserver la possibilité d'égalité/comparaison hétérogène.
La forme exacte des paramètres génériques et les règles de symétrie automatique doivent encore être formalisées pour éviter les implémentations concurrentes incohérentes.
## 20.8 Ownership des implémentations opérateur — V1 REQUIS — FIGÉ EN PRINCIPE
Direction :
- normalement l'implémentation appartient au type nominal de gauche ;
- si le LHS est une primitive/Core sealed non extensible, le type nominal de droite peut fournir une forme inverse explicitement permise ;
- un troisième package ne peut pas définir arbitrairement un opérateur entre deux types externes ;
- une seule implémentation canonique par `(operator,Lhs,Rhs)`.
Les détails doivent être alignés sur le resolver des packages.
## 20.9 Indexation — V1 REQUIS — FIGÉ
```text
OpIndex<Index,Read>
OpIndexMut<Index,Write>
```
Les deux contrats sont indépendants.
Syntaxe :
```text
container[index]
container[index] = value
```
Les séquences standard utilisent initialement `uint64` comme index.
D'autres index numériques pourront être supportés ultérieurement sans modifier la largeur de `uint64`.
Un type utilisateur peut utiliser n'importe quel type d'index pertinent.
## 20.10 Map — V1 REQUIS — DIRECTION FIGÉE
Direction recommandée :
```text
Map<K,V>
OpIndex<K,Option<V>>
OpIndexMut<K,V>
```
Lecture : absent -> `None` ; présent -> `Some(value)`.
Écriture : insertion si absent, remplacement si présent.
Une méthode `containsKey` peut compléter l'API sans être obligatoire avant toute lecture.
## 20.11 Affectation — V1 REQUIS — FIGÉ
`=` n'est pas une expression.
Interdits :
```text
if (a = b) { ... }
x = (a = b);
a = b = c;
```
## 20.12 Affectations composées — V1 REQUIS — FIGÉ
```text
+= -= *= /= %=
&= |= ^=
<<= >>=
```
Elles n'ont aucun `Op...` propre et ne sont donc pas surchargeables directement.
Elles sont composées de :
```text
lecture
+ opérateur fondamental surchargeable
+ réaffectation
```
Le résultat de l'opération doit être assignable exactement à la destination.
Aucune conversion implicite ne doit être inventée pour rendre l'affectation composée valide.
## 20.13 `is` — V1 REQUIS — FIGÉ
`is` teste l'appartenance d'une valeur à un type polymorphe ou à l'un de ses sous-types runtime.
```text
value is Type
```
Pour une instance runtime de `Labrador` avec `Labrador extends Dog` et `Dog extends Animal` :
```text
value is Animal // true
value is Dog // true
value is Labrador // true
```
`is` est utilisable sur les classes et les interfaces lorsqu'un polymorphisme runtime existe. Il est interdit sur les types sans polymorphisme runtime tels que les primitives numériques, `char`, les structs, les enums, les tuples ou les unions.
`is` n'est pas surchargeable.
Dans une branche dont la condition positive prouve `value is Type`, le compilateur raffine `value` vers `Type` dans le scope correspondant. Le raffinement cesse avec ce scope.
Saselang n'introduit pas `is not` : la négation générale s'écrit explicitement :
```text
!(value is Type)
```
## 20.14 `instanceof` — V1 REQUIS — FIGÉ
`instanceof` teste le **type de classe runtime exact**.
```text
value instanceof ConcreteClass
```
Pour une instance runtime exacte de `Labrador` :
```text
value instanceof Animal // false
value instanceof Dog // false
value instanceof Labrador // true
```
`instanceof` est utilisable uniquement avec une classe concrète non abstraite. Il est interdit avec une interface, une classe abstraite et tout type sans identité de classe runtime.
`instanceof` n'est pas surchargeable.
Une branche positive raffine la valeur vers la classe concrète testée et établit en plus que son type runtime est exactement cette classe.
Saselang n'introduit pas `not instanceof` :
```text
!(value instanceof ConcreteClass)
```
`is` et `instanceof` coexistent parce qu'ils ont deux sémantiques différentes : appartenance à une hiérarchie pour `is`, identité exacte de classe runtime pour `instanceof`.
## 20.15 `bitcast<T>` — V1 REQUIS — FIGÉ EN PRINCIPE
```text
bitcast<T>(value)
```
est un intrinsic compiler-known, pas un opérateur.
Il préserve exactement les bits et exige des tailles compatibles.
Il ne réalise aucune conversion numérique.
Certains bitcasts sont sûrs lorsque tout motif de bits destination est valide ; d'autres nécessiteront `unsafe`.
Le tableau exact doit être lié au modèle mémoire.
## 20.16 Appel `()` — V1 REQUIS — FIGÉ EN PRINCIPE
`()` est une construction d'appel du langage, pas un opérateur utilisateur.
Il n'est pas prévu de fournir un `OpCall` général.
Les fonctions, closures/lambdas futures seront appelables par définition de leur type, pas en surchargeant arbitrairement `()` sur n'importe quel objet.
## 20.17 Précédence — V1 REQUIS — FIGÉ
Du plus fort au plus faible :
```text
1. qualification / membre . ::
2. appel / indexation () []
3. préfixes +x -x !x ~x
4. multiplicatifs * / %
5. additifs + -
6. shifts << >>
7. relation / type < <= > >= is instanceof
8. égalité == !=
9. bitwise AND &
10. bitwise XOR ^
11. bitwise OR |
12. logique short-circuit AND &&
13. logique short-circuit OR ||
```
`bitcast<T>(...)` suit la syntaxe d'appel et n'a pas sa propre précédence.
`=` et les affectations composées ne figurent pas dans cette hiérarchie puisqu'elles ne produisent pas de valeur.
## 20.18 Associativité — V1 REQUIS — FIGÉ
Les opérateurs binaires arithmétiques/bitwise/logiques sont associatifs syntaxiquement à gauche.
Les préfixes s'imbriquent depuis la droite.
Les comparaisons sont non associatives :
```text
a < b < c -> interdit
a == b == c -> interdit
```
Écrire explicitement :
```text
a < b && b < c
```
---