v0.2.17
This commit is contained in:
@@ -121,3 +121,8 @@ text::append("def"); // OK si append est une méthode mutante de String
|
||||
## DO / DON'T / WHY / compiler error / edge cases
|
||||
|
||||
À consolider progressivement avant la baseline publique V3 et à transformer, lorsque pertinent, en tests de conformité de la toolchain.
|
||||
|
||||
|
||||
## Explicite plutôt qu'ambigu
|
||||
|
||||
Lorsqu'une forme légèrement plus longue supprime un implicite ou une ambiguïté réelle, Saselang la préfère à une syntaxe plus courte.
|
||||
|
||||
@@ -19,7 +19,7 @@ unions
|
||||
tuples
|
||||
generics
|
||||
contrôle de flux
|
||||
erreurs/exceptions
|
||||
erreurs/exceptions/faults
|
||||
opérateurs
|
||||
unsafe
|
||||
scope
|
||||
@@ -38,6 +38,7 @@ Result<T,E>
|
||||
Error
|
||||
ResultError
|
||||
Exception
|
||||
Fault
|
||||
Option<T>
|
||||
Nullable<T>
|
||||
Range<T>
|
||||
@@ -46,10 +47,18 @@ RangeStep<T,Step>
|
||||
RangeReverse<T>
|
||||
RangeReverseStep<T,Step>
|
||||
RangeProgression<T,Step>
|
||||
PartialOrdering
|
||||
Ordering
|
||||
Comparable<T>
|
||||
Comparator<T>
|
||||
Op...
|
||||
Iterable<T>
|
||||
Iterator<T>
|
||||
View<T>
|
||||
Collection<T>
|
||||
List<T>
|
||||
Set<T>
|
||||
Map<K,V>
|
||||
Array<T>
|
||||
StaticArray<T,N>
|
||||
TypeInfo
|
||||
@@ -59,7 +68,7 @@ ExitCode
|
||||
### Exemple 3
|
||||
|
||||
```text
|
||||
collections
|
||||
collections concrètes/spécialisées au-delà des contrats fondamentaux Core
|
||||
encodages explicites
|
||||
regex
|
||||
filesystem
|
||||
|
||||
@@ -19,7 +19,10 @@ type de retour
|
||||
visibilité
|
||||
fallibilité / Result
|
||||
throws
|
||||
contraintes génériques pertinentes
|
||||
qualification const et contraintes génériques pertinentes
|
||||
|
||||
faults
|
||||
visible mais non checked / non exhaustif
|
||||
modificateurs contractuels pertinents
|
||||
```
|
||||
|
||||
|
||||
@@ -16,30 +16,35 @@ operator implémentation d'un contrat opérateur
|
||||
### Exemple 2
|
||||
|
||||
```text
|
||||
opération infaillible
|
||||
-> retourne directement T
|
||||
|
||||
opération pouvant produire une erreur récupérable
|
||||
-> retourne Result<T>
|
||||
ou Result<T,E>
|
||||
T
|
||||
T throws SomeException
|
||||
T faults SomeFault
|
||||
T throws SomeException faults SomeFault
|
||||
Result<T,E>
|
||||
Result<T,E> throws SomeException
|
||||
Result<T,E> faults SomeFault
|
||||
```
|
||||
|
||||
Le type de retour et le mécanisme d'échec sont indépendants.
|
||||
|
||||
### Exemple 3
|
||||
|
||||
```text
|
||||
method length() -> uint64
|
||||
method containsKey(K key) -> bool
|
||||
Object::sameInstance(Object other) -> bool
|
||||
func min(int32 a, int32 b) -> int32
|
||||
func readConfig(String path) -> Config
|
||||
throws IOException
|
||||
|
||||
method elementAt(uint64 index) -> T
|
||||
faults IndexOutOfBoundsFault
|
||||
```
|
||||
|
||||
### Exemple 4
|
||||
|
||||
```text
|
||||
func readFile(String path) -> Result<String, IoError>
|
||||
method parse(String input) -> Result<Value, ParseError>
|
||||
func parseExternalInput(String input) -> Result<Value, ParseError>
|
||||
```
|
||||
|
||||
`Result` reste utilisé lorsque l'échec doit être transporté comme une valeur.
|
||||
|
||||
### Exemple 5
|
||||
|
||||
```text
|
||||
|
||||
@@ -1,259 +1,159 @@
|
||||
# Exemples / DO-DON'T — Chapitre 18 — `Result`, erreurs et exceptions
|
||||
# Exemples / DO-DON'T — Chapitre 18 — `Result`, erreurs, exceptions et faults
|
||||
|
||||
> Document compagnon non normatif tant qu'une règle n'est pas explicitement référencée comme normative par le chapitre.
|
||||
> Document compagnon. Les exemples illustrent les règles du chapitre ; la formulation normative reste dans le chapitre lui-même.
|
||||
|
||||
## Exemples actuellement présents dans le chapitre
|
||||
|
||||
### Exemple 1
|
||||
## Hiérarchie
|
||||
|
||||
```text
|
||||
Object
|
||||
└── Error
|
||||
├── ResultError
|
||||
└── Exception
|
||||
├── Exception
|
||||
└── Fault
|
||||
```
|
||||
|
||||
### Exemple 2
|
||||
|
||||
```text
|
||||
public final class ParseError extends ResultError {
|
||||
}
|
||||
|
||||
public final class FileNotFoundException extends Exception {
|
||||
}
|
||||
```
|
||||
|
||||
### Exemple 3
|
||||
|
||||
```text
|
||||
message: String
|
||||
cause: Option<Error>
|
||||
i18nMessage: Option<I18nMessage>
|
||||
```
|
||||
|
||||
### Exemple 4
|
||||
|
||||
```text
|
||||
message
|
||||
message humain canonique / fallback
|
||||
|
||||
cause
|
||||
erreur causale purement informative
|
||||
peut contenir un ResultError ou une Exception
|
||||
n'est pas automatiquement propagée
|
||||
|
||||
i18nMessage
|
||||
clé et paramètres de localisation
|
||||
ne contient pas un tableau de traductions
|
||||
```
|
||||
|
||||
### Exemple 5
|
||||
|
||||
```text
|
||||
code: ResultErrorCode
|
||||
```
|
||||
|
||||
### Exemple 6
|
||||
|
||||
```text
|
||||
code -> stable, machine-readable, non localisé
|
||||
message -> humain, canonique / fallback
|
||||
i18nMessage -> localisation externe
|
||||
```
|
||||
|
||||
### Exemple 7
|
||||
|
||||
```text
|
||||
throw exception;
|
||||
```
|
||||
|
||||
### Exemple 8
|
||||
|
||||
```text
|
||||
Result::Ok(T)
|
||||
Result::Err(E)
|
||||
```
|
||||
|
||||
### Exemple 9
|
||||
|
||||
```text
|
||||
E doit être ResultError ou un descendant de ResultError
|
||||
```
|
||||
|
||||
### Exemple 10
|
||||
|
||||
```text
|
||||
Result<Data,ResultError>
|
||||
Result<Data,ParseError>
|
||||
Result<Void,ResultError>
|
||||
```
|
||||
|
||||
### Exemple 11
|
||||
|
||||
```text
|
||||
Result<Data,Error>
|
||||
Result<Data,Exception>
|
||||
Result<Data,FileNotFoundException>
|
||||
```
|
||||
|
||||
### Exemple 12
|
||||
|
||||
```text
|
||||
Result<T>
|
||||
```
|
||||
|
||||
### Exemple 13
|
||||
|
||||
```text
|
||||
Result<T,ResultError>
|
||||
```
|
||||
|
||||
### Exemple 14
|
||||
|
||||
```text
|
||||
return Result::Ok(value);
|
||||
return Result::Err(error);
|
||||
```
|
||||
|
||||
### Exemple 15
|
||||
|
||||
```text
|
||||
result::expectOk(...)
|
||||
result::expectErr(...)
|
||||
```
|
||||
|
||||
### Exemple 16
|
||||
|
||||
```text
|
||||
ResultError -> Exception
|
||||
Exception -> ResultError
|
||||
```
|
||||
|
||||
### Exemple 17
|
||||
|
||||
```text
|
||||
throw ParseException(..., Option::Some(parseError));
|
||||
```
|
||||
|
||||
### Exemple 18
|
||||
|
||||
```text
|
||||
catch (FileNotFoundException error) {
|
||||
return Result::Err(FileResultError(..., Option::Some(error)));
|
||||
public final class IndexOutOfBoundsFault extends Fault {
|
||||
}
|
||||
```
|
||||
|
||||
### Exemple 19
|
||||
## `ResultError`
|
||||
|
||||
DO : utiliser `Result` lorsque l'échec est une valeur normale à inspecter explicitement.
|
||||
|
||||
```text
|
||||
T + throws -> interdit
|
||||
Result<T,E> -> valide sans throws
|
||||
Result<T,E> + throws -> valide
|
||||
```
|
||||
|
||||
### Exemple 20
|
||||
|
||||
```text
|
||||
throws IOException
|
||||
```
|
||||
|
||||
### Exemple 21
|
||||
|
||||
```text
|
||||
supprimer entièrement des exceptions déclarées
|
||||
restreindre une famille à une ou plusieurs sous-familles compatibles
|
||||
gérer localement tout ou partie des exceptions du contrat parent
|
||||
```
|
||||
|
||||
### Exemple 22
|
||||
|
||||
```text
|
||||
throw FileNotFoundException(...); // valide
|
||||
throw ParseError(...); // erreur
|
||||
throw Error(...); // erreur
|
||||
```
|
||||
|
||||
### Exemple 23
|
||||
|
||||
```text
|
||||
catch (IOException error) {
|
||||
throw error;
|
||||
func parseExternalInput(String input) -> Result<Value, ParseError> {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### Exemple 24
|
||||
DON'T : placer une `Exception` ou un `Fault` dans le paramètre erreur de `Result`.
|
||||
|
||||
```text
|
||||
try { ... }
|
||||
try { ... } finally { ... }
|
||||
finally { ... }
|
||||
Result<Value,FileNotFoundException> // ERROR
|
||||
Result<Value,IndexOutOfBoundsFault> // ERROR
|
||||
```
|
||||
|
||||
### Exemple 25
|
||||
## `Exception`, `throw` et `throws`
|
||||
|
||||
```text
|
||||
func readConfig(String path) -> Config
|
||||
throws IOException
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Un retour direct est compatible avec `throws`.
|
||||
|
||||
```text
|
||||
throw FileNotFoundException(...); // OK
|
||||
throw IndexOutOfBoundsFault(...); // ERROR
|
||||
throw ParseError(...); // ERROR
|
||||
```
|
||||
|
||||
## `Fault`, `fault` et `faults`
|
||||
|
||||
```text
|
||||
method elementAt(uint64 index) -> T
|
||||
faults IndexOutOfBoundsFault
|
||||
{
|
||||
if (index >= this::length()) {
|
||||
fault IndexOutOfBoundsFault(index, this::length());
|
||||
}
|
||||
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
La clause `faults` est optionnelle et non exhaustive.
|
||||
|
||||
DO : appeler sans cérémonie lorsque le fault n'est pas un chemin normal à traiter.
|
||||
|
||||
```text
|
||||
T value = list::elementAt(index);
|
||||
```
|
||||
|
||||
DO : capturer explicitement lorsque le programme veut réellement récupérer ce cas.
|
||||
|
||||
```text
|
||||
try {
|
||||
...
|
||||
} catch (SpecificException error) {
|
||||
...
|
||||
} catch (ParentException error) {
|
||||
...
|
||||
} finally {
|
||||
T value = list::elementAt(index);
|
||||
} catch (IndexOutOfBoundsFault faultValue) {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### Exemple 26
|
||||
Aucune propagation de `faults` n'est obligatoire :
|
||||
|
||||
```text
|
||||
catch (FileNotFoundException error) {
|
||||
...
|
||||
} catch (IOException error) {
|
||||
...
|
||||
func outer() -> Void {
|
||||
inner(); // inner peut déclarer faults SomeFault
|
||||
return Void;
|
||||
}
|
||||
```
|
||||
|
||||
### Exemple 27
|
||||
## `catch`
|
||||
|
||||
Valide :
|
||||
|
||||
```text
|
||||
catch (IOException error) {
|
||||
...
|
||||
} catch (FileNotFoundException error) {
|
||||
}
|
||||
|
||||
catch (IteratorInvalidatedFault faultValue) {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### Exemple 28
|
||||
Invalide :
|
||||
|
||||
```text
|
||||
fin normale du try
|
||||
fin normale d'un catch
|
||||
return traversant la construction
|
||||
throw propagé
|
||||
break / continue traversant la construction
|
||||
Exception non capturée par les catch
|
||||
catch (Error error) // ERROR
|
||||
catch (ResultError error) // ERROR
|
||||
```
|
||||
|
||||
### Exemple 29
|
||||
`catch` ne peut cibler que `Exception`, `Fault` ou leurs descendants.
|
||||
|
||||
## Direct versus valeur conditionnelle
|
||||
|
||||
Accès affirmatif :
|
||||
|
||||
```text
|
||||
return
|
||||
throw
|
||||
break
|
||||
continue
|
||||
emit
|
||||
User user = users[id]; // absence -> KeyNotFoundFault
|
||||
```
|
||||
|
||||
### Exemple 30
|
||||
Absence normale :
|
||||
|
||||
```text
|
||||
index hors limites
|
||||
division entière par zéro
|
||||
overflow checked
|
||||
représentation mémoire invalide
|
||||
borne dynamique invalide lors d'une construction directe lorsque la règle du type le définit
|
||||
Option<User> user = users::get(id);
|
||||
```
|
||||
|
||||
## DO / DON'T / WHY / compiler error / edge cases
|
||||
Le Core ne doit pas créer automatiquement une variante `tryOp()` uniquement pour transporter le même échec dans `Result`.
|
||||
|
||||
La couverture structurée de cette section sera enrichie au fur et à mesure de la fermeture des règles du chapitre. La migration `0.2.12` conserve volontairement les exemples historiques dans le chapitre afin de ne perdre aucun contexte normatif.
|
||||
## Erreur statique versus fault runtime
|
||||
|
||||
```text
|
||||
StaticArray<int32,3> values = [1, 2, 3];
|
||||
int32 a = values[5]; // ERROR compilation
|
||||
```
|
||||
|
||||
```text
|
||||
uint64 index = readIndex();
|
||||
int32 b = values[index]; // peut produire IndexOutOfBoundsFault au runtime
|
||||
```
|
||||
|
||||
Un statement `fault` explicite reste évidemment valide :
|
||||
|
||||
```text
|
||||
if (!state::isValid()) {
|
||||
fault InvalidStateFault(...);
|
||||
}
|
||||
```
|
||||
|
||||
@@ -91,12 +91,18 @@ transitive
|
||||
### Exemple 11
|
||||
|
||||
```text
|
||||
public enum Ordering {
|
||||
public enum PartialOrdering {
|
||||
Less,
|
||||
Equal,
|
||||
Greater,
|
||||
Unordered
|
||||
}
|
||||
|
||||
public enum Ordering {
|
||||
Less,
|
||||
Equal,
|
||||
Greater
|
||||
}
|
||||
```
|
||||
|
||||
### Exemple 12
|
||||
@@ -124,8 +130,11 @@ container[index] = value
|
||||
|
||||
```text
|
||||
Map<K,V>
|
||||
OpIndex<K,Option<V>>
|
||||
OpIndex<K,V>
|
||||
OpIndexMut<K,V>
|
||||
|
||||
map[key] // strict, absent -> KeyNotFoundFault
|
||||
map::get(key) // Option<V>
|
||||
```
|
||||
|
||||
### Exemple 16
|
||||
|
||||
@@ -78,12 +78,12 @@ char::toUtf8Char()
|
||||
Utf8Char::toChar()
|
||||
Utf8Char::toUtf16Char()
|
||||
|
||||
Utf8Char::tryFrom(uint8)
|
||||
Utf16Char::tryFrom(uint16)
|
||||
Utf32Char::tryFrom(uint32)
|
||||
Utf8Char::from(uint8) faults UnicodeEncodingFault
|
||||
Utf16Char::from(uint16) faults UnicodeEncodingFault
|
||||
Utf32Char::from(uint32) faults UnicodeEncodingFault
|
||||
|
||||
Utf8Char::tryToUint8()
|
||||
Utf16Char::tryToUint16()
|
||||
Utf8Char::toUint8() faults UnicodeEncodingFault
|
||||
Utf16Char::toUint16() faults UnicodeEncodingFault
|
||||
Utf32Char::toUint32()
|
||||
```
|
||||
|
||||
|
||||
@@ -158,7 +158,82 @@ Vector<T>
|
||||
ResizableList<T>
|
||||
```
|
||||
|
||||
### Exemple 18
|
||||
### Exemple 18 — `Iterator<T>`
|
||||
|
||||
```text
|
||||
interface Iterable<T> {
|
||||
const method iterator() -> Iterator<T>;
|
||||
}
|
||||
|
||||
interface Iterator<T> {
|
||||
method next() -> Option<T>;
|
||||
}
|
||||
```
|
||||
|
||||
### Exemple 19 — `View<T>`
|
||||
|
||||
```text
|
||||
interface View<T> extends Iterable<T> {
|
||||
const method count() -> uint64;
|
||||
const method isEmpty() -> bool;
|
||||
}
|
||||
```
|
||||
|
||||
`View<T>` n'impose pas `contains()`.
|
||||
|
||||
### Exemple 20 — Set
|
||||
|
||||
```text
|
||||
ResizableSet<T>::add(T value) -> bool
|
||||
ResizableSet<T>::remove(const T value) -> bool
|
||||
ResizableSet<T>::clear() -> uint64
|
||||
```
|
||||
|
||||
### Exemple 21 — Map
|
||||
|
||||
```text
|
||||
map[key] -> V // strict
|
||||
map::get(key) -> Option<V> // conditionnel
|
||||
map[key] = value // remplacement seulement
|
||||
map::insert(key, value) // clé nouvelle, DuplicateKeyFault sinon
|
||||
map::remove(key) // clé existante, KeyNotFoundFault sinon
|
||||
map::clear() -> uint64
|
||||
```
|
||||
|
||||
### Exemple 22 — Vues de Map
|
||||
|
||||
```text
|
||||
map::keys() -> View<K>
|
||||
map::values() -> View<V>
|
||||
map::entries() -> View<MapEntry<K,V>>
|
||||
```
|
||||
|
||||
### Exemple 23 — Ordre
|
||||
|
||||
```text
|
||||
enum Ordering {
|
||||
Less,
|
||||
Equal,
|
||||
Greater
|
||||
}
|
||||
|
||||
Comparable<T>
|
||||
Comparator<T>
|
||||
SortedSet<T>
|
||||
SortedMap<K,V>
|
||||
```
|
||||
|
||||
### Exemple 24 — Factories ordonnées
|
||||
|
||||
```text
|
||||
TreeSet<T>::natural()
|
||||
TreeSet<T>::withComparator(comparator)
|
||||
|
||||
TreeMap<K,V>::natural()
|
||||
TreeMap<K,V>::withComparator(comparator)
|
||||
```
|
||||
|
||||
## Exemples Range
|
||||
|
||||
```text
|
||||
a..b [a, b] bornes basse et haute incluses
|
||||
@@ -167,13 +242,13 @@ a..<b [a, b) borne basse incluse, borne haute exclue
|
||||
a>..<b (a, b) bornes basse et haute exclues
|
||||
```
|
||||
|
||||
### Exemple 19
|
||||
### Range 1
|
||||
|
||||
```text
|
||||
Range<uint64> ids = 1..100;
|
||||
```
|
||||
|
||||
### Exemple 20
|
||||
### Range 2
|
||||
|
||||
```text
|
||||
NaN interdit comme borne
|
||||
@@ -182,7 +257,7 @@ NaN interdit comme borne
|
||||
valeur finie autorisée
|
||||
```
|
||||
|
||||
### Exemple 21
|
||||
### Range 3
|
||||
|
||||
```text
|
||||
a..a contient exactement a
|
||||
@@ -191,7 +266,7 @@ a..<a vide
|
||||
a>..<a vide
|
||||
```
|
||||
|
||||
### Exemple 22
|
||||
### Range 4
|
||||
|
||||
```text
|
||||
range::lower()
|
||||
@@ -202,7 +277,7 @@ range::isEmpty()
|
||||
range::contains(value)
|
||||
```
|
||||
|
||||
### Exemple 23
|
||||
### Range 5
|
||||
|
||||
```text
|
||||
Range<T> intervalle ordonné
|
||||
@@ -213,13 +288,13 @@ RangeReverseStep<T,Step> parcours arrière avec pas explicite
|
||||
RangeProgression<T,Step> valeur de progression produite
|
||||
```
|
||||
|
||||
### Exemple 24
|
||||
### Range 6
|
||||
|
||||
```text
|
||||
(range)::step(step)
|
||||
```
|
||||
|
||||
### Exemple 25
|
||||
### Range 7
|
||||
|
||||
```text
|
||||
RangeStep<int32,int32>
|
||||
@@ -228,14 +303,14 @@ RangeStep<char,uint32>
|
||||
RangeStep<Date,Duration>
|
||||
```
|
||||
|
||||
### Exemple 26
|
||||
### Range 8
|
||||
|
||||
```text
|
||||
(range)::reverse()
|
||||
(range)::reverse()::step(step)
|
||||
```
|
||||
|
||||
### Exemple 27
|
||||
### Range 9
|
||||
|
||||
```text
|
||||
range
|
||||
@@ -243,25 +318,25 @@ range
|
||||
[::step(step)]
|
||||
```
|
||||
|
||||
### Exemple 28
|
||||
### Range 10
|
||||
|
||||
```text
|
||||
(250u8..255u8)::step(2u8)
|
||||
```
|
||||
|
||||
### Exemple 29
|
||||
### Range 11
|
||||
|
||||
```text
|
||||
250 252 254
|
||||
```
|
||||
|
||||
### Exemple 30
|
||||
### Range 12
|
||||
|
||||
```text
|
||||
(1..10)::step(4)
|
||||
```
|
||||
|
||||
### Exemple 31
|
||||
### Range 13
|
||||
|
||||
```text
|
||||
1 5 9
|
||||
@@ -269,4 +344,4 @@ range
|
||||
|
||||
## DO / DON'T / WHY / compiler error / edge cases
|
||||
|
||||
À consolider progressivement avant la baseline publique V3 et à transformer, lorsque pertinent, en tests de conformité de la toolchain.
|
||||
À consolider progressivement avant la baseline publique V3 et à transformer, lorsque pertinent, en tests de conformité de la toolchain.
|
||||
@@ -2,100 +2,102 @@
|
||||
|
||||
> Document compagnon. Les exemples illustrent les règles du chapitre ; la formulation normative reste dans le chapitre lui-même.
|
||||
|
||||
## Exemples extraits du chapitre
|
||||
|
||||
### Exemple 1
|
||||
|
||||
```text
|
||||
conversion de valeur
|
||||
cast de hiérarchie nominale
|
||||
bitcast de représentation binaire
|
||||
```
|
||||
|
||||
### Exemple 2
|
||||
## Conversion explicite
|
||||
|
||||
```text
|
||||
int8 small = ...;
|
||||
int32 large = small; // ERROR
|
||||
int32 large = small; // ERROR
|
||||
int32 explicitLarge = small::toInt32(); // OK
|
||||
```
|
||||
|
||||
### Exemple 3
|
||||
## Widening total
|
||||
|
||||
```text
|
||||
Dog dog = ...;
|
||||
Animal animal = dog;
|
||||
Serializable serializable = dog;
|
||||
int8 value = ...;
|
||||
int32 larger = value::toInt32();
|
||||
```
|
||||
|
||||
### Exemple 4
|
||||
Aucun `tryToInt32()` parallèle n'est nécessaire si toutes les valeurs source sont exactement représentables.
|
||||
|
||||
## Narrowing exact avec `Fault`
|
||||
|
||||
```text
|
||||
Animal animal = ...;
|
||||
|
||||
if (animal is Dog) {
|
||||
// animal est raffiné en Dog ici.
|
||||
}
|
||||
int32 value = ...;
|
||||
int8 smaller = value::toInt8();
|
||||
```
|
||||
|
||||
### Exemple 5
|
||||
La signature Core peut déclarer :
|
||||
|
||||
```text
|
||||
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
|
||||
toInt8() -> int8
|
||||
faults NumericConversionFault
|
||||
```
|
||||
|
||||
### Exemple 6
|
||||
`OutOfRange` est produit lorsque la valeur ne tient pas dans `int8`.
|
||||
|
||||
## Politiques distinctes
|
||||
|
||||
```text
|
||||
tryToIntXX()
|
||||
tryToUintXX()
|
||||
value::toInt8() // exact, peut fault
|
||||
value::saturateToInt8()
|
||||
value::wrapToInt8()
|
||||
```
|
||||
|
||||
### Exemple 7
|
||||
Ces opérations coexistent seulement lorsque leur résultat peut réellement différer.
|
||||
|
||||
## Flottant vers entier
|
||||
|
||||
```text
|
||||
floor()
|
||||
ceil()
|
||||
round()
|
||||
truncate()
|
||||
float64 value = ...;
|
||||
|
||||
int32 exact = value::toInt32();
|
||||
```
|
||||
|
||||
### Exemple 8
|
||||
La conversion exige une valeur finie, intégrale et dans la plage.
|
||||
|
||||
Pour choisir explicitement une politique mathématique :
|
||||
|
||||
```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()
|
||||
```
|
||||
|
||||
### Exemple 9
|
||||
Pour choisir la politique de plage :
|
||||
|
||||
```text
|
||||
value::floor()::trySaturateToInt32()
|
||||
value::round()::tryWrapToInt32()
|
||||
value::floor()::saturateToInt32()
|
||||
value::round()::wrapToInt32()
|
||||
```
|
||||
|
||||
### Exemple 10
|
||||
## Entier vers flottant
|
||||
|
||||
```text
|
||||
int64 value = ...;
|
||||
|
||||
float64 exact = value::toFloat64();
|
||||
float64 approximated = value::roundToFloat64();
|
||||
```
|
||||
|
||||
`toFloat64()` exige l'exactitude ; `roundToFloat64()` accepte explicitement la perte de précision.
|
||||
|
||||
## Flottant vers flottant
|
||||
|
||||
```text
|
||||
toFloatXX()
|
||||
exige l'exactitude
|
||||
|
||||
roundToFloatXX()
|
||||
accepte l'arrondi canonique
|
||||
peut fault OutOfRange sur une valeur finie
|
||||
|
||||
saturatingRoundToFloatXX()
|
||||
accepte l'arrondi canonique
|
||||
sature une valeur finie hors domaine
|
||||
```
|
||||
|
||||
Les catégories suivantes sont préservées :
|
||||
|
||||
```text
|
||||
NaN -> NaN
|
||||
@@ -105,31 +107,13 @@ NaN -> NaN
|
||||
-0 -> -0
|
||||
```
|
||||
|
||||
### Exemple 11
|
||||
## `NumericConversionFault`
|
||||
|
||||
```text
|
||||
payload NaN
|
||||
quiet/signaling bit
|
||||
signe du NaN
|
||||
représentation binaire exacte
|
||||
NumericConversionFault extends Fault
|
||||
```
|
||||
|
||||
### Exemple 12
|
||||
|
||||
```text
|
||||
tryToFloatXX()
|
||||
exige une représentation exacte
|
||||
|
||||
tryRoundToFloatXX()
|
||||
accepte l'arrondi canonique
|
||||
refuse une valeur finie hors domaine fini destination
|
||||
|
||||
saturatingRoundToFloatXX()
|
||||
accepte l'arrondi canonique
|
||||
sature une valeur finie hors domaine vers +/-Target::Max
|
||||
```
|
||||
|
||||
### Exemple 13
|
||||
Codes :
|
||||
|
||||
```text
|
||||
NotFinite
|
||||
@@ -138,40 +122,10 @@ OutOfRange
|
||||
Inexact
|
||||
```
|
||||
|
||||
### Exemple 14
|
||||
DON'T : introduire mécaniquement :
|
||||
|
||||
```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
|
||||
tryToTarget() -> Result<Target,NumericConversionError>
|
||||
```
|
||||
|
||||
### Exemple 15
|
||||
|
||||
```text
|
||||
sourceType
|
||||
targetType
|
||||
sourceValue
|
||||
timestamp
|
||||
backend
|
||||
roundingMode
|
||||
```
|
||||
|
||||
### Exemple 16
|
||||
|
||||
```text
|
||||
annexes/A-numeric-conversions.md
|
||||
```
|
||||
|
||||
## DO / DON'T / WHY / compiler error / edge cases
|
||||
|
||||
À consolider progressivement avant la baseline publique V3 et à transformer, lorsque pertinent, en tests de conformité de la toolchain.
|
||||
si cette méthode ne ferait que dupliquer `toTarget() faults NumericConversionFault`.
|
||||
|
||||
@@ -13,7 +13,7 @@ threads natifs
|
||||
structured concurrency éventuelle
|
||||
cancellation
|
||||
synchronisation
|
||||
interaction avec Result/throws
|
||||
interaction avec Result/throws/faults
|
||||
interaction avec destruction déterministe
|
||||
runtime minimal
|
||||
```
|
||||
|
||||
@@ -51,3 +51,16 @@ ownership annotations pour les usages ordinaires
|
||||
## DO / DON'T / WHY / compiler error / edge cases
|
||||
|
||||
À consolider progressivement avant la baseline publique V3 et à transformer, lorsque pertinent, en tests de conformité de la toolchain.
|
||||
|
||||
|
||||
## Pointeurs — distinctions à préserver
|
||||
|
||||
```text
|
||||
référence de classe
|
||||
Slice<T>
|
||||
pointeur Saselang
|
||||
pointeur brut / FFI
|
||||
function pointer
|
||||
```
|
||||
|
||||
Les pointeurs explicites restent un sous-modèle mémoire dédié et ne remplacent pas les références/slices sûres dans le code ordinaire.
|
||||
|
||||
@@ -65,3 +65,14 @@ emit
|
||||
## DO / DON'T / WHY / compiler error / edge cases
|
||||
|
||||
La couverture structurée de cette section sera enrichie au fur et à mesure de la fermeture des règles du chapitre. La migration `0.2.12` conserve volontairement les exemples historiques dans le chapitre afin de ne perdre aucun contexte normatif.
|
||||
|
||||
|
||||
## Fault et cleanup
|
||||
|
||||
```text
|
||||
defer {
|
||||
fault CleanupFault(...); // ERROR : fault explicite escaping
|
||||
}
|
||||
```
|
||||
|
||||
Un `Fault` dynamique produit indirectement reste possible car il est unchecked ; l'ordre exact d'unwind/destruction est encore à fermer.
|
||||
|
||||
@@ -162,7 +162,7 @@ désactiver les contrôles d'overflow définis par Saselang
|
||||
modifier la sémantique d'un index hors limites
|
||||
modifier l'ordre d'évaluation
|
||||
modifier la représentation sémantique des types
|
||||
changer les règles Result/throws
|
||||
changer les règles Result/throws/faults
|
||||
désactiver les vérifications de sûreté du langage
|
||||
faire varier la validité d'un programme Saselang autrement que par une limite propre au backend/target
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user