v0.2.17
This commit is contained in:
@@ -20,7 +20,7 @@ Il n'existe aucune promotion numérique implicite générale entre deux valeurs
|
||||
|
||||
```text
|
||||
int8 small = ...;
|
||||
int32 large = small; // ERROR
|
||||
int32 large = small; // ERROR
|
||||
int32 explicitLarge = small::toInt32(); // OK
|
||||
```
|
||||
|
||||
@@ -48,63 +48,140 @@ if (animal is Dog) {
|
||||
}
|
||||
```
|
||||
|
||||
Lorsqu'un test du type runtime **exact** est nécessaire, `instanceof` est utilisé.
|
||||
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
|
||||
## 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.
|
||||
|
||||
Principe de nommage :
|
||||
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 et totale
|
||||
|
||||
tryToTarget()
|
||||
conversion exacte pour la valeur courante, récupérable si impossible
|
||||
conversion exacte
|
||||
totale si tout le domaine source est représentable
|
||||
sinon valeur directe + faults NumericConversionFault
|
||||
|
||||
roundToTarget()
|
||||
perte de précision explicitement acceptée, conversion totale
|
||||
|
||||
tryRoundToTarget()
|
||||
perte de précision explicitement acceptée, mais conversion pouvant échouer
|
||||
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 lorsqu'aucun arrondi supplémentaire n'est nécessaire
|
||||
saturation explicite lorsque la politique de plage est le seul ajustement demandé
|
||||
|
||||
saturatingRoundToTarget()
|
||||
arrondi + saturation explicitement annoncés
|
||||
arrondi + saturation explicitement annoncés lorsque les deux sont nécessaires
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
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 `float -> integer` — V1 REQUIS — DIRECTION FIGÉE
|
||||
## 24.6 Entier -> entier — V1 REQUIS — FIGÉ EN PRINCIPE
|
||||
|
||||
Un flottant ne possède jamais un simple `toIntXX()` ou `toUintXX()`.
|
||||
|
||||
La conversion exacte stricte utilise :
|
||||
Si toutes les valeurs source sont représentables exactement dans la destination :
|
||||
|
||||
```text
|
||||
tryToIntXX()
|
||||
tryToUintXX()
|
||||
toTarget() -> Target
|
||||
```
|
||||
|
||||
Elle réussit uniquement si la valeur source est finie, mathématiquement entière et représentable exactement dans le type destination. Sinon elle retourne `Result::Err(NumericConversionError(...))`.
|
||||
est total et ne déclare aucun `NumericConversionFault` lié à la plage.
|
||||
|
||||
Les politiques mathématiques de traitement de la partie fractionnaire restent des opérations Core séparées :
|
||||
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()
|
||||
@@ -116,30 +193,38 @@ truncate()
|
||||
Elles se composent avec la conversion :
|
||||
|
||||
```text
|
||||
value::floor()::tryToInt32()
|
||||
value::ceil()::tryToInt32()
|
||||
value::round()::tryToInt32()
|
||||
value::truncate()::tryToInt32()
|
||||
value::floor()::toInt32()
|
||||
value::ceil()::toInt32()
|
||||
value::round()::toInt32()
|
||||
value::truncate()::toInt32()
|
||||
```
|
||||
|
||||
Saselang n'introduit donc pas les alias redondants `tryFloorToInt32()`, `tryCeilToInt32()`, `tryRoundToInt32()` ou `tryTruncateToInt32()` lorsque ces compositions possèdent exactement la même sémantique.
|
||||
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 suivent la même règle :
|
||||
Les politiques de dépassement de domaine se composent de la même façon :
|
||||
|
||||
```text
|
||||
value::floor()::trySaturateToInt32()
|
||||
value::round()::tryWrapToInt32()
|
||||
value::floor()::saturateToInt32()
|
||||
value::round()::wrapToInt32()
|
||||
```
|
||||
|
||||
`trySaturateToIntXX()` exige une valeur finie et mathématiquement entière, puis sature aux bornes du type destination. Les échecs qui ne relèvent pas de la plage, par exemple `NaN`, une infinité ou une valeur fractionnaire, restent des `NumericConversionError`.
|
||||
Pour `float -> integer` :
|
||||
|
||||
`tryWrapToIntXX()` exige également une valeur finie et mathématiquement entière, puis applique le wrapping entier modulo `2^N` défini par Saselang.
|
||||
```text
|
||||
saturateToTarget()
|
||||
exige encore une valeur finie et mathématiquement entière
|
||||
faults NotFinite / NotIntegral si nécessaire
|
||||
sature uniquement la plage
|
||||
|
||||
Une méthode combinée reste admise lorsqu'une décomposition changerait le contrat ou perdrait l'information nécessaire. C'est notamment le cas de `saturatingRoundToFloat32()` pour certains narrowings flottants : un `roundToFloat32()` séparé pourrait échouer avant que la saturation ne puisse être appliquée.
|
||||
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
|
||||
```
|
||||
|
||||
Aucun comportement de conversion ne dépend d'un profil, d'un linter ou d'un backend.
|
||||
Une méthode combinée reste admise uniquement lorsqu'une décomposition changerait le contrat ou perdrait l'information nécessaire.
|
||||
|
||||
## 24.7 `float -> float`, valeurs IEEE spéciales — V1 REQUIS — FIGÉ
|
||||
## 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 :
|
||||
|
||||
@@ -162,30 +247,33 @@ signe du NaN
|
||||
représentation binaire exacte
|
||||
```
|
||||
|
||||
Ces propriétés relèvent d'un éventuel contrat binaire distinct ; `bitcast<T>` ne peut les préserver que lorsque ses propres contraintes, notamment de taille, sont satisfaites.
|
||||
Ces propriétés relèvent d'un contrat binaire distinct.
|
||||
|
||||
`tryToFloatXX()` traite `NaN` et les infinités comme des valeurs sémantiques représentables du type flottant destination. Le mot « exact » désigne ici l'exactitude de la valeur sémantique Saselang, pas l'identité bit-à-bit d'un payload NaN.
|
||||
|
||||
Pour une valeur finie :
|
||||
Pour une réduction de format :
|
||||
|
||||
```text
|
||||
tryToFloatXX()
|
||||
exige une représentation exacte
|
||||
toFloatXX()
|
||||
exige l'exactitude de la valeur sémantique
|
||||
faults Inexact ou OutOfRange pour une valeur finie si nécessaire
|
||||
|
||||
tryRoundToFloatXX()
|
||||
roundToFloatXX()
|
||||
accepte l'arrondi canonique
|
||||
refuse une valeur finie hors domaine fini destination
|
||||
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
|
||||
```
|
||||
|
||||
Les infinités ne sont pas saturées puisqu'elles sont déjà des valeurs représentables du format flottant destination.
|
||||
`NaN` et les infinities sont déjà représentables dans les formats flottants Saselang et ne sont donc pas saturés.
|
||||
|
||||
## 24.8 `NumericConversionError` — V1 REQUIS — NOM DE TRAVAIL / CODES FIGÉS
|
||||
## 24.10 `NumericConversionFault` — V1 REQUIS — NOM DE TRAVAIL / CODES FIGÉS
|
||||
|
||||
`NumericConversionError` est retenu comme nom de travail du `ResultError` Core utilisé par les conversions numériques récupérables.
|
||||
`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 :
|
||||
|
||||
@@ -213,7 +301,7 @@ Inexact
|
||||
alors que l'opération exige l'exactitude
|
||||
```
|
||||
|
||||
`NumericConversionError` reste volontairement généraliste et minimal. Il n'ajoute pas automatiquement :
|
||||
`NumericConversionFault` reste volontairement minimal. Il n'ajoute pas automatiquement :
|
||||
|
||||
```text
|
||||
sourceType
|
||||
@@ -224,21 +312,19 @@ backend
|
||||
roundingMode
|
||||
```
|
||||
|
||||
au-delà de l'état commun fourni par `ResultError`.
|
||||
au-delà de l'état commun fourni par `Error`/`Fault`.
|
||||
|
||||
Le nom concret et la représentation numérique interne des codes pourront encore être ajustés avant stabilisation publique, mais les catégories sémantiques ci-dessus font partie du contrat V1.
|
||||
|
||||
## 24.9 Réduction anti-doublon par paire — V1 REQUIS — FIGÉ
|
||||
## 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.
|
||||
|
||||
Ainsi, pour une paire `float -> integer` dont toutes les valeurs finies mathématiquement entières sont déjà dans le domaine signé destination, `trySaturateToTarget()` et `tryWrapToTarget()` seraient des doublons de `tryToTarget()` et n'existent pas.
|
||||
Lorsqu'une opération directe est totale pour toute la paire, elle ne déclare aucun fault inutile.
|
||||
|
||||
Pour une destination non signée, les valeurs négatives suffisent généralement à rendre les politiques checked, saturating et wrapping distinctes.
|
||||
Lorsqu'une politique `saturate` ou `wrap` ne peut jamais différer de la conversion exacte sur cette paire, elle est absente.
|
||||
|
||||
La matrice exhaustive en annexe est normative sur ce point.
|
||||
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.10 Disponibilité Core et target — V1 REQUIS — FIGÉ EN PRINCIPE
|
||||
## 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.
|
||||
|
||||
@@ -248,9 +334,9 @@ Un target réduit peut ne pas supporter un type fondamental donné. Dans ce cas
|
||||
|
||||
Voir également le chapitre 40.
|
||||
|
||||
## 24.11 Matrice exhaustive — ANNEXE NORMATIVE EN COURS DE GEL
|
||||
## 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.
|
||||
L'inventaire source -> destination des opérations de conversion est maintenu séparément afin d'éviter les oublis, doublons et incohérences.
|
||||
|
||||
Voir :
|
||||
|
||||
@@ -258,6 +344,6 @@ 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.
|
||||
L'annexe liste les possibilités sémantiquement distinctes après suppression des variantes `try...` purement liées à l'ancien canal `ResultError`.
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user