Files
saselang-bible/chapters/024-casts-et-conversions.md
2026-09-13 10:20:16 +02:00

350 lines
11 KiB
Markdown

# 24. Casts et conversions
## 24.1 Principe général — V1 REQUIS — FIGÉ EN PRINCIPE
Saselang distingue explicitement :
```text
conversion de valeur
cast de hiérarchie nominale
bitcast de représentation binaire
```
Ces mécanismes ne sont pas des alias.
`bitcast<T>(value)` est défini au chapitre 20 et ne constitue jamais une conversion numérique.
## 24.2 Conversions implicites numériques — V1 REQUIS — FIGÉ
Il n'existe aucune promotion numérique implicite générale entre deux valeurs déjà typées de types primitifs différents.
```text
int8 small = ...;
int32 large = small; // ERROR
int32 explicitLarge = small::toInt32(); // OK
```
Le typage contextuel d'un littéral non encore typé reste une règle distincte.
## 24.3 Upcast — V1 REQUIS — FIGÉ
Un upcast compatible dans une hiérarchie de classes ou vers une interface satisfaite est une assignation de sous-typage normale et ne nécessite pas une syntaxe de cast dédiée.
```text
Dog dog = ...;
Animal animal = dog;
Serializable serializable = dog;
```
## 24.4 Downcast et raffinement — V1 REQUIS — FIGÉ EN PRINCIPE
Le mécanisme canonique de downcast V1 est le test `is` suivi du raffinement de type dans le scope positif.
```text
Animal animal = ...;
if (animal is Dog) {
// animal est raffiné en Dog ici.
}
```
Lorsqu'un test du type runtime exact est nécessaire, `instanceof` est utilisé.
Saselang n'introduit pas pour le moment de syntaxe générale concurrente telle que `(Dog)value`, `value as Dog` ou `cast<Dog>(value)`. Une telle opération ne pourra être ajoutée que si un besoin distinct de `is`/`instanceof` + refinement est démontré et si son contrat d'échec est explicite.
## 24.5 API numérique du Core — V1 REQUIS — FIGÉ EN PRINCIPE
Les conversions numériques sont exposées comme membres standard des primitives définis par le Core. Les noms de méthodes ne sont pas des mots-clés du langage.
Le compilateur connaît les règles nécessaires pour typer, vérifier, constant-fold et abaisser ces opérations vers Sase IR, mais l'inventaire exhaustif de la surface API appartient au Core.
L'introduction de `Fault` supprime l'obligation historique de créer une variante `try... -> Result<T,NumericConversionError>` uniquement parce qu'une conversion directe peut échouer.
Principe de nommage V1 :
```text
toTarget()
conversion exacte
totale si tout le domaine source est représentable
sinon valeur directe + faults NumericConversionFault
roundToTarget()
perte de précision / arrondi explicitement accepté
peut fault si une autre précondition reste violée, par exemple le domaine fini destination
saturateToTarget()
saturation explicite lorsque la politique de plage est le seul ajustement demandé
saturatingRoundToTarget()
arrondi + saturation explicitement annoncés lorsque les deux sont nécessaires
wrapToTarget()
wrapping entier explicite
```
Une opération n'existe que si elle apporte une sémantique observable différente d'une autre forme disponible pour la paire source/destination.
Le Core ne duplique pas mécaniquement :
```text
toTarget()
tryToTarget()
```
lorsque la seule différence serait que la seconde transporte le même échec dans `Result`.
Une API spécialisée peut toujours choisir volontairement `Result` si l'échec doit devenir une donnée normale du domaine, mais cela ne fait pas partie de la matrice canonique des conversions primitives.
Règle de composition : deux opérations Core ne sont fusionnées dans un même nom que si leur séparation en opérations successives modifierait la sémantique, perdrait de l'information ou empêcherait d'exprimer le même contrat.
Lorsqu'une composition existante est strictement équivalente, aucun alias combiné n'est ajouté au Core.
## 24.6 Entier -> entier — V1 REQUIS — FIGÉ EN PRINCIPE
Si toutes les valeurs source sont représentables exactement dans la destination :
```text
toTarget() -> Target
```
est total et ne déclare aucun `NumericConversionFault` lié à la plage.
Lorsque certaines valeurs source ne sont pas représentables :
```text
toTarget() -> Target
faults NumericConversionFault
```
avec `OutOfRange` lorsque la valeur courante n'entre pas dans le domaine destination.
Les politiques alternatives restent explicites :
```text
saturateToTarget()
wrapToTarget()
```
Elles ne sont présentes que lorsqu'elles peuvent produire un résultat différent de `toTarget()` pour cette paire.
Aucun wrapping ni saturation n'est implicite.
## 24.7 Entier -> flottant — V1 REQUIS — FIGÉ EN PRINCIPE
`toFloatXX()` exige une représentation exacte de la valeur entière.
```text
toFloatXX() -> floatXX
faults NumericConversionFault
```
n'a une clause `faults` que lorsque certaines valeurs source peuvent être inexactes ou hors du domaine fini destination.
`roundToFloatXX()` accepte explicitement l'arrondi canonique `nearest, ties to even` :
```text
roundToFloatXX() -> floatXX
```
Il peut encore produire `OutOfRange` si une valeur entière finie dépasse le domaine fini de la destination.
Lorsque l'arrondi et la saturation doivent être annoncés ensemble :
```text
saturatingRoundToFloatXX()
```
borne une magnitude finie trop grande au plus grand fini de même signe puis applique la précision destination.
Il n'existe pas de `wrapToFloatXX()`.
## 24.8 `float -> integer` — V1 REQUIS — FIGÉ EN PRINCIPE
La conversion stricte utilise désormais directement :
```text
toIntXX() -> intXX
faults NumericConversionFault
toUintXX() -> uintXX
faults NumericConversionFault
```
Elle réussit uniquement si la valeur source est :
```text
finie
mathématiquement entière
dans le domaine de la destination
exactement représentable comme entier destination
```
Sinon le fault porte la catégorie appropriée.
Les politiques mathématiques de traitement de la partie fractionnaire restent des opérations séparées :
```text
floor()
ceil()
round()
truncate()
```
Elles se composent avec la conversion :
```text
value::floor()::toInt32()
value::ceil()::toInt32()
value::round()::toInt32()
value::truncate()::toInt32()
```
Saselang n'introduit pas les alias redondants `floorToInt32()`, `ceilToInt32()`, `roundToInt32()` ou `truncateToInt32()` lorsque ces compositions possèdent exactement la même sémantique.
Les politiques de dépassement de domaine se composent de la même façon :
```text
value::floor()::saturateToInt32()
value::round()::wrapToInt32()
```
Pour `float -> integer` :
```text
saturateToTarget()
exige encore une valeur finie et mathématiquement entière
faults NotFinite / NotIntegral si nécessaire
sature uniquement la plage
wrapToTarget()
exige encore une valeur finie et mathématiquement entière
faults NotFinite / NotIntegral si nécessaire
applique le wrapping modulo 2^N à l'entier mathématique fini
```
Une méthode combinée reste admise uniquement lorsqu'une décomposition changerait le contrat ou perdrait l'information nécessaire.
## 24.9 `float -> float`, valeurs IEEE spéciales — V1 REQUIS — FIGÉ
Toute conversion de valeur flottante préserve les catégories sémantiques suivantes lorsque la destination est un type flottant Saselang :
```text
NaN -> NaN
+Infinity -> +Infinity
-Infinity -> -Infinity
+0 -> +0
-0 -> -0
```
Pour `NaN`, la conversion garantit uniquement que la destination reste `NaN`.
Elle ne garantit pas lors d'une conversion de valeur :
```text
payload NaN
quiet/signaling bit
signe du NaN
représentation binaire exacte
```
Ces propriétés relèvent d'un contrat binaire distinct.
Pour une réduction de format :
```text
toFloatXX()
exige l'exactitude de la valeur sémantique
faults Inexact ou OutOfRange pour une valeur finie si nécessaire
roundToFloatXX()
accepte l'arrondi canonique
faults OutOfRange si une valeur finie dépasse le domaine fini destination
saturatingRoundToFloatXX()
accepte l'arrondi canonique
sature une valeur finie hors domaine vers +/-Target::Max
```
`NaN` et les infinities sont déjà représentables dans les formats flottants Saselang et ne sont donc pas saturés.
## 24.10 `NumericConversionFault` — V1 REQUIS — NOM DE TRAVAIL / CODES FIGÉS
`NumericConversionFault` est retenu comme nom de travail du `Fault` Core utilisé par les conversions numériques directes dont les préconditions runtime peuvent échouer.
```text
NumericConversionFault extends Fault
```
Les catégories sémantiques V1 sont :
```text
NotFinite
NotIntegral
OutOfRange
Inexact
```
Sens :
```text
NotFinite
NaN ou +/-Infinity lorsqu'une valeur finie est requise
NotIntegral
float -> integer alors que la valeur n'est pas mathématiquement entière
OutOfRange
valeur mathématique hors du domaine de la destination
Inexact
valeur dans le domaine destination mais non représentable exactement
alors que l'opération exige l'exactitude
```
`NumericConversionFault` reste volontairement minimal. Il n'ajoute pas automatiquement :
```text
sourceType
targetType
sourceValue
timestamp
backend
roundingMode
```
au-delà de l'état commun fourni par `Error`/`Fault`.
## 24.11 Réduction anti-doublon par paire — V1 REQUIS — FIGÉ
La matrice examine chaque paire `Source -> Target` et n'expose que les opérations dont le comportement peut réellement être distingué sur le domaine source.
Lorsqu'une opération directe est totale pour toute la paire, elle ne déclare aucun fault inutile.
Lorsqu'une politique `saturate` ou `wrap` ne peut jamais différer de la conversion exacte sur cette paire, elle est absente.
La disparition des variantes `try...` ne modifie pas cette règle de non-redondance ; elle supprime seulement les duplications qui ne différaient que par le canal d'échec `ResultError` versus valeur directe.
## 24.12 Disponibilité Core et target — V1 REQUIS — FIGÉ EN PRINCIPE
Les conversions fondamentales de la matrice sont des capacités Core obligatoires dès lors que les types source et destination sont supportés par le target.
L'absence d'une instruction matérielle native ne justifie pas l'absence d'une conversion si une émulation logicielle conforme est raisonnablement possible.
Un target réduit peut ne pas supporter un type fondamental donné. Dans ce cas l'indisponibilité porte sur le type/capacité fondamentale, pas sur une sélection arbitraire de ses méthodes de conversion.
Voir également le chapitre 40.
## 24.13 Matrice exhaustive — ANNEXE NORMATIVE EN COURS DE GEL
L'inventaire source -> destination des opérations de conversion est maintenu séparément afin d'éviter les oublis, doublons et incohérences.
Voir :
```text
annexes/A-numeric-conversions.md
```
L'annexe liste les possibilités sémantiquement distinctes après suppression des variantes `try...` purement liées à l'ancien canal `ResultError`.
---