4.3 KiB
24. Casts et conversions
24.1 Principe général — V1 REQUIS — FIGÉ EN PRINCIPE
Saselang distingue explicitement :
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.
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.
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.
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 — DIRECTION FIGÉE
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.
Principe de nommage :
toTarget()
conversion exacte et totale
tryToTarget()
conversion exacte pour la valeur courante, récupérable si impossible
roundToTarget()
perte de précision explicitement acceptée, conversion totale
tryRoundToTarget()
perte de précision explicitement acceptée, mais conversion pouvant échouer
saturateToTarget()
saturation explicite lorsqu'aucun arrondi supplémentaire n'est nécessaire
saturatingRoundToTarget()
arrondi + saturation explicitement annoncés
wrapToTarget()
wrapping entier explicite
Une forme n'existe que si elle apporte une sémantique observable différente d'une autre forme déjà disponible pour la paire source/destination.
Ainsi, lorsqu'un toTarget() exact et total existe, les variantes tryToTarget(), saturateToTarget() ou wrapToTarget() qui produiraient exactement le même résultat pour tout le domaine source sont absentes.
24.6 float -> integer — V1 REQUIS — DIRECTION FIGÉE
Un flottant ne possède jamais un simple toIntXX() ou toUintXX().
La politique de passage du réel à l'entier doit être explicite, par exemple :
tryExactToInt32()
tryFloorToInt32()
tryCeilToInt32()
tryRoundToInt32()
tryTruncateToInt32()
Les variantes saturantes ou wrapping, lorsqu'elles sont retenues, doivent également annoncer explicitement la politique mathématique appliquée.
Aucun comportement de conversion ne dépend d'un profil, d'un linter ou d'un backend.
24.7 NumericConversionError — V1 REQUIS — NOM DE TRAVAIL
NumericConversionError est retenu comme nom de travail du ResultError Core utilisé par les conversions numériques récupérables.
Son nom définitif, ses codes et son état minimal pourront encore être ajustés lors de la finalisation du Core sans modifier les principes de conversion de ce chapitre.
24.8 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 :
annexes/A-numeric-conversions.md
L'annexe doit lister le maximum de possibilités sémantiquement distinctes avant réduction finale de l'API Core.