# 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(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(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` 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`. ---