Comportement des opérateurs

Cette section définit le comportement des différents opérateurs M.

Précédence des opérateurs

Quand une expression contient plusieurs opérateurs, la priorité des opérateurs contrôle l’ordre dans lequel ils sont évalués. Par exemple, l’expression x + y * z est évaluée en tant que x + (y * z), car l’opérateur * a une priorité plus élevée que l’opérateur + binaire. La priorité d’un opérateur est établie par la définition de sa production grammaticale associée. Par exemple, une additive-expression se compose d’une séquence de multiplicative-expressions séparées par des opérateurs + ou -, donnant ainsi aux opérateurs + et - une priorité moins élevée que les opérateurs * et /.

La production d’une parenthesized-expression peut être utilisée pour changer l’ordre de priorité par défaut.

parenthesized-expression :
      (expression)

Par exemple :

1 + 2 * 3       // 7 
(1 + 2) * 3     // 9

Le tableau suivant récapitule les opérateurs M, en listant les catégories d’opérateurs par ordre de priorité, de la plus élevée à la plus faible. Les opérateurs d’une même catégorie ont une priorité identique.

Catégorie Expression Description
Principal i
@i
Expression d’identificateur
(x) Expression entre parenthèses
x[i] Lookup
x{y} Accès aux éléments
x(...) Appel des fonctions
{x, y, ...} Initialisation de liste
[ i = x, ... ] Initialisation d’enregistrement
... Non implémenté
Unaire +x Identity
-x Négation
notx Négation logique
Métadonnées xmetay Associer des métadonnées
Multiplicatif x * y Multiplication
x / y Division
Additive x + y Addition
x - y Soustraction
Relationnel x< y Inférieur à
x > y Supérieur à
x<= y Inférieur ou égal à
x >= y Supérieur ou égal à
Égalité x = y Égal à
x<> y Différent de
Assertion de type xasy Est une erreur ou un type primitif nullable compatible
Conformité de type xisy Tester si le type primitif nullable est compatible
ET logique xandy Conjonction de court-circuit
OU logique xory Disjonction de court-circuit
Coalesce x??y Opérateur de coalescence nulle

Opérateurs et métadonnées

Chaque valeur a une valeur d’enregistrement associée qui peut contenir des informations supplémentaires la concernant. Cet enregistrement est l’enregistrement de métadonnées pour une valeur. Un enregistrement de métadonnées peut être associé à n’importe quel genre de valeur, même null. Le résultat d’une telle association est une nouvelle valeur avec les métadonnées correspondantes.

Un enregistrement de métadonnées est simplement un enregistrement standard et peut contenir tous les champs et valeurs qu’un enregistrement standard peut comporter et lui-même a un enregistrement de métadonnées. L’association d’un enregistrement de métadonnées à une valeur est « non intrusive ». Elle ne change pas le comportement de la valeur dans les évaluations, sauf si celles-ci inspectent explicitement les enregistrements de métadonnées.

Chaque valeur a un enregistrement de métadonnées par défaut, même si aucun n’a été spécifié. L’enregistrement de métadonnées par défaut est vide. Les exemples suivants montrent comment accéder à l’enregistrement de métadonnées d’une valeur de texte à l’aide de la fonction de bibliothèque standard Value.Metadata :

Value.Metadata( "Mozart" )   // []

En règle générale, les enregistrements de métadonnées ne sont pas conservés quand une valeur est utilisée avec un opérateur ou une fonction qui construit une nouvelle valeur. Par exemple, si deux valeurs de texte sont concaténées à l’aide de l’opérateur &, les métadonnées de la valeur de texte résultante sont l’enregistrement vide []. Les expressions suivantes sont équivalentes :

"Amadeus " & ("Mozart" meta [ Rating = 5 ])  
"Amadeus " & "Mozart"

Vous pouvez utiliser les fonctions de bibliothèque standard Value.RemoveMetadata et Value.ReplaceMetadata pour supprimer toutes les métadonnées d’une valeur et remplacer les métadonnées d’une valeur (plutôt que fusionner les métadonnées en métadonnées éventuellement existantes).

Le seul opérateur qui retourne des résultats contenant des métadonnées est l’opérateur meta.

Opérateurs récursifs structurellement

Les valeurs peuvent être cycliques. Par exemple :

let l = {0, @l} in l
// {0, {0, {0, ... }}}
[A={B}, B={A}]
// [A = {{ ... }}, B = {{ ... }}]

M gère les valeurs cycliques en gardant une construction différée des enregistrements, des listes et des tables. Toute tentative de construire une valeur cyclique qui ne tire pas parti de valeurs structurées différées intercalées engendre une erreur :

[A=B, B=A] 
// [A = Error.Record("Expression.Error", 
//         "A cyclic reference was encountered during evaluation"), 
//  B = Error.Record("Expression.Error", 
//         "A cyclic reference was encountered during evaluation"), 
// ]

Certains opérateurs dans M sont définis par la récursivité structurelle. Par exemple, l’égalité des enregistrements et des listes est définie par l’égalité conjointe des champs d’enregistrement et des listes d’éléments correspondants, respectivement.

Pour les valeurs non cycliques, l’application de la récursivité structurelle génère une expansion finie de la valeur : les valeurs imbriquées partagées sont parcourues à plusieurs reprises, mais le processus de récursivité se termine toujours.

Une valeur cyclique a une expansion infinie lors de l’application de la récursivité structurelle. La sémantique de M n’offre pas de prise en charge particulière pour les expansions infinies. En règle générale, toute tentative de comparaison de valeurs cycliques en termes d’égalité, par exemple, fait face à un manque de ressources et se termine de manière inattendue.

Opérateurs de sélection et de projection

Les opérateurs de sélection et de projection permettent d’extraire les données des valeurs de liste et d’enregistrement.

Accès aux éléments

Une valeur peut être sélectionnée dans une liste ou une table en fonction de sa position de base zéro dans cette liste ou table à l’aide d’une item-access-expression.

item-access-expression :
      item-selection
      optional-item-selection
item-selection :
      primary-expression
{item-selector}
optional-item-selection :
      primary-expression
{item-selector} ?
item-selector :
      expression

L’item-access-expressionx{y} retourne :

  • Pour une liste x et un nombre y, l’élément de la liste x à la position y. Le premier élément d’une liste est considéré comme ayant un index ordinal égal à zéro. Si la position demandée n’existe pas dans la liste, une erreur est générée.

  • Pour une table x et un nombre y, la ligne de la table x à la position y. La première ligne d’une table est considérée comme ayant un index ordinal égal à zéro. Si la position demandée n’existe pas dans la table, une erreur est générée.

  • Pour une table x et un enregistrement y, la ligne de la table x qui correspond aux valeurs de champ de l’enregistrement y pour les champs dont les noms ccorrespondent à l’un des noms des colonnes de la table. S’il n’existe pas de ligne correspondante unique dans la table, une erreur est générée.

Par exemple :

{"a","b","c"}{0}                        // "a" 
{1, [A=2], 3}{1}                        // [A=2] 
{true, false}{2}                        // error 
#table({"A","B"},{{0,1},{2,1}}){0}      // [A=0,B=1] 
#table({"A","B"},{{0,1},{2,1}}){[A=2]}  // [A=2,B=1]  
#table({"A","B"},{{0,1},{2,1}}){[B=3]}  // error 
#table({"A","B"},{{0,1},{2,1}}){[B=1]}  // error

item-access-expression prend également en charge la forme x{y}?, qui retourne null quand la position (ou la correspondance) y n’existe pas dans la liste ou la table x. S’il existe plusieurs correspondances pour y, une erreur est toujours générée.

Par exemple :

{"a","b","c"}{0}?                       // "a" 
{1, [A=2], 3}{1}?                       // [A=2] 
{true, false}{2}?                       // null 
#table({"A","B"},{{0,1},{2,1}}){0}?     // [A=0,B=1] 
#table({"A","B"},{{0,1},{2,1}}){[A=2]}? // [A=2,B=1]  
#table({"A","B"},{{0,1},{2,1}}){[B=3]}? // null 
#table({"A","B"},{{0,1},{2,1}}){[B=1]}? // error

L’accès aux éléments n’impose pas l’évaluation des éléments de liste ou de table autres que ceux qui font l’objet d’un accès. Par exemple :

{ error "a", 1, error "c"}{1}  // 1 
{ error "a", error "b"}{1}     // error "b"

Les points suivants s’appliquent lors de l’évaluation de l’opérateur d’accès aux éléments x{y} :

  • Les erreurs générées lors de l’évaluation des expressions x ou y sont propagées.

  • L’expression x produit une liste ou une valeur de table.

  • L’expression y produit une valeur numérique ou, si x produit une valeur de table, une valeur d’enregistrement.

  • Si y produit une valeur numérique et que la valeur de y est négative, une erreur avec le code de raison "Expression.Error" est générée.

  • Si y produit une valeur numérique et que la valeur de y est supérieure ou égale au nombre de x, une erreur avec le code de raison "Expression.Error" est générée sauf si la forme d’opérateur facultative x{y}? est utilisée (dans ce cas, la valeur null est retournée).

  • Si x produit une valeur de table, que y produit une valeur d’enregistrement et qu’il n’existe aucune correspondance pour y dans x, une erreur avec le code de raison "Expression.Error" est générée sauf si la forme d’opérateur facultative x{y}? est utilisée (dans ce cas, la valeur null est retournée).

  • Si x produit une valeur de table, que y produit une valeur d’enregistrement et qu’il y a plusieurs correspondances pour y dans x, une erreur avec le code de raison "Expression.Error" est générée.

Aucun élément de x autre que celui à la position y n’est évalué pendant le processus de sélection d’un élément. (Pour les listes ou les tables de streaming, les éléments ou les lignes avant celui ou celle à la position y sont ignorés, ce qui peut entraîner leur évaluation, en fonction de la source de la liste ou de la table.)

Accès aux champs

field-access-expression est utilisée pour sélectionner une valeur dans un enregistrement ou pour projeter un enregistrement ou une table sur un enregistrement ou une table comportant moins de champs ou de colonnes, respectivement.

field-access-expression :
      field-selection
      implicit-target-field-selection
      projection
      implicit-target-projection
field-selection :
      primary-expression field-selector
field-selector :
      required-field-selector
      optional-field-selector
required-field-selector :

      [field-name]
optional-field-selector:
      [field-name] ?
field-name :
      generalized-identifier
      quoted-identifier
implicit-target-field-selection :
      field-selector
projection :
      primary-expression required-projection
      primary-expression optional-projection
required-projection :

      [required-selector-list]
optional-projection:
      [required-selector-list] ?
required-selector-list :
      required-field-selector
      required-selector-list
,required-field-selector
implicit-target-projection :
      required-projection
      optional-projection

La forme la plus simple d’accès aux champs est la sélection de champ obligatoire. Elle utilise l’opérateur x[y] pour rechercher un champ dans un enregistrement par nom de champ. Si le champ y n’existe pas dans x, une erreur est générée. La forme x[y]? est utilisée pour effectuer une sélection de champ facultative, et retourne null si le champ demandé n’existe pas dans l’enregistrement.

Par exemple :

[A=1,B=2][B]       // 2 
[A=1,B=2][C]       // error 
[A=1,B=2][C]?      // null

L’accès collectif à plusieurs champs est pris en charge par les opérateurs pour la projection d’enregistrement obligatoire et la projection d’enregistrement facultative. L’opérateur x[[y1],[y2],...] projette l’enregistrement sur un nouvel enregistrement contenant moins de champs (sélectionnés par y1, y2, ...). Si un champ sélectionné n’existe pas, une erreur est générée. L’opérateur x[[y1],[y2],...] projette l’enregistrement sur un nouvel enregistrement avec les champs sélectionnés par y1, y2, ... ; si un champ est manquant, null est utilisé à la place. Par exemple :

[A=1,B=2][[B]]           // [B=2] 
[A=1,B=2][[C]]           // error 
[A=1,B=2][[B],[C]]?      // [B=2,C=null]

Les formes [y] et [y]? sont prises en charge en tant que référence abrégée à l’identificateur _ (trait de soulignement). Les deux expressions suivantes sont équivalentes :

[A]                 
_[A]

L’exemple suivant illustre la forme abrégée de l’accès aux champs :

let _ = [A=1,B=2] in [A] //1

Les formes [[y1],[y2],...] et [[y1],[y2],...]? sont également prises en charge en tant que raccourci et les deux expressions suivantes sont équivalentes :

[[A],[B]]                 
_[[A],[B]]

La forme abrégée est particulièrement utile en association avec le raccourci each, qui permet d’introduire une fonction d’un paramètre unique nommé _ (pour plus d’informations, consultez Déclarations simplifiées). Ensemble, les deux raccourcis simplifient les expressions fonctionnelles courantes d’ordre supérieur :

List.Select( {[a=1, b=1], [a=2, b=4]}, each [a] = [b]) 
// {[a=1, b=1]}

L’expression ci-dessus équivaut à la forme suivante plus énigmatique :

List.Select( {[a=1, b=1], [a=2, b=4]}, (_) => _[a] = _[b]) 
// {[a=1, b=1]}

L’accès aux champs n’impose pas l’évaluation des champs autres que ceux qui font l’objet d’un accès. Par exemple :

[A=error "a", B=1, C=error "c"][B]  // 1 
[A=error "a", B=error "b"][B]       // error "b"

Les points suivants s’appliquent lors de l’évaluation d’un opérateur d’accès aux champs x[y], x[y]?, x[[y]] ou x[[y]]? :

  • Les erreurs générées lors de l’évaluation de l’expression x sont propagées.

  • Les erreurs générées lors de l’évaluation du champ y sont définitivement associées au champ y, puis propagées. Tout accès futur au champ y génère la même erreur.

  • L’expression x produit une valeur d’enregistrement ou de table, ou une erreur est générée.

  • Si l’identificateur y nomme un champ qui n’existe pas dans x, une erreur avec le code de raison "Expression.Error" est générée sauf si la forme d’opérateur facultative ...? est utilisée (dans ce cas, la valeur null est retournée).

Aucun champ de x autre que celui nommé par y n’est évalué au cours du processus d’accès au champ.

Opérateur de métadonnées

L’enregistrement des métadonnées d’une valeur est modifié à l’aide de l’opérateur meta (x meta y).

metadata-expression :
      unary-expression
      unary-expression
metaunary-expression

L’exemple suivant construit une valeur de texte avec un enregistrement de métadonnées à l’aide de l’opérateur meta, puis accède à l’enregistrement des métadonnées de la valeur résultante à l’aide de Value.Metadata :

Value.Metadata( "Mozart" meta [ Rating = 5 ] ) 
// [Rating = 5 ]
Value.Metadata( "Mozart" meta [ Rating = 5 ] )[Rating] 
// 5

Les points suivants s’appliquent lors de l’utilisation de l’opérateur de combinaison de métadonnées x meta y :

  • Les erreurs générées lors de l’évaluation des expressions x ou y sont propagées.

  • L’expression y doit être un enregistrement, sinon une erreur avec le code de raison "Expression.Error" est générée.

  • L’enregistrement des métadonnées résultant est l’enregistrement des métadonnées de x fusionné avec y. (Pour connaître la sémantique de la fusion d’enregistrements, consultez Fusion d’enregistrements.)

  • La valeur résultante est la valeur de l’expression x, sans ses métadonnées, avec l’enregistrement de métadonnées nouvellement calculé attaché.

Vous pouvez utiliser les fonctions de bibliothèque standard Value.RemoveMetadata et Value.ReplaceMetadata pour supprimer toutes les métadonnées d’une valeur et remplacer les métadonnées d’une valeur (plutôt que fusionner les métadonnées en métadonnées éventuellement existantes). Les expressions suivantes sont équivalentes :

x meta y  
Value.ReplaceMetadata(x, Value.Metadata(x) & y) 
Value.RemoveMetadata(x) meta (Value.Metadata(x) & y)

Opérateurs d’égalité

L’opérateur d’égalité= est utilisé pour déterminer si deux valeurs sont égales. L’opérateur d’inégalité<> est utilisé pour déterminer si deux valeurs ne sont pas égales.

equality-expression :
      relational-expression
      relational-expression
=equality-expression
      relational-expression
<>equality-expression

Par exemple :

1 = 1            // true 
1 = 2            // false 
1 <> 1           // false 
1 <> 2           // true 
null = true      // false 
null = null      // true

Les métadonnées ne font pas partie de la comparaison d’égalité ou d’inégalité. Par exemple :

(1 meta [ a = 1 ]) = (1 meta [ a = 2 ]) // true 
(1 meta [ a = 1 ]) = 1                  // true

Les points suivants s’appliquent lors de l’utilisation des opérateurs d’égalité x = y et x <> y :

  • Les erreurs générées lors de l’évaluation des expressions x ou y sont propagées.

  • L’opérateur = a pour résultat true si les valeurs sont égales et false dans le cas contraire.

  • L’opérateur <> a pour résultat false si les valeurs sont égales et true dans le cas contraire.

  • Les enregistrements de métadonnées ne sont pas inclus dans la comparaison.

  • Si les valeurs produites par l’évaluation des expressions x et y ne sont pas du même genre, elles ne sont pas égales.

  • Si les valeurs produites par l’évaluation des expressions x et y sont du même genre, il existe des règles spécifiques pour déterminer si elles sont égales, comme indiqué ci-dessous.

  • Ce qui suit est toujours vrai :

    (x = y) = not (x <> y)

Les opérateurs d’égalité sont définis pour les types suivants :

  • La valeur null est uniquement égale à elle-même.
    null = null    // true 
    null = true    // false 
    null = false   // false
  • Les valeurs logiques true et false sont uniquement égales à elles-mêmes. Par exemple :
    true = true      // true 
    false = false    // true 
    true = false     // false 
    true = 1         // false
  • Les nombres sont comparés à l’aide de la précision spécifiée :

    • Si l’un des nombres est #nan, les nombres ne sont pas identiques.

    • Quand aucun nombre n’est #nan, les nombres sont comparés à l’aide d’une comparaison de bits de la valeur numérique.

    • #nan est la seule valeur qui n’est pas égale à elle-même.

      Par exemple :

        1 = 1,              // true 
        1.0 = 1             // true 
        2 = 1               // false 
        #nan = #nan         // false 
        #nan <> #nan        // true
  • Deux durées sont égales si elles représentent le même nombre de cycles de 100 nanosecondes.

  • Deux heures sont égales si les grandeurs de leurs parties (heure, minute, seconde) sont égales.

  • Deux dates sont égales si les grandeurs de leurs parties (année, mois, jour) sont égales.

  • Deux datetimes sont égaux si les grandeurs de leurs parties (année, mois, jour, heure, minute, seconde) sont égales.

  • Deux datetimezones sont identiques si les datetimes UTC correspondantes sont égaux. Pour arriver au datetime UTC correspondant, le décalage en heures/minutes est soustrait du composant datetime du datetimezone.

  • Deux valeurs de texte sont égales si, en utilisant une comparaison ordinale, respectant la casse et indépendante de la culture, elles ont la même longueur et les mêmes caractères aux positions correspondantes.

  • Deux valeurs de liste sont égales si toutes les conditions suivantes sont vraies :

    • Les deux listes contiennent le même nombre d’éléments.

    • Les valeurs de chaque élément aux positions correspondantes dans les listes sont égales. Cela signifie non seulement que les listes doivent contenir des éléments égaux, mais que les éléments doivent être dans le même ordre.

      Par exemple :

        {1, 2} = {1, 2}     // true 
        {2, 1} = {1, 2}     // false 
        {1, 2, 3} = {1, 2}  // false
      
  • Deux enregistrements sont égaux si toutes les conditions suivantes sont vraies :

    • Le nombre de champs est le même.

    • Chaque nom de champ d’un enregistrement est également présent dans l’autre enregistrement.

    • La valeur de chaque champ d’un enregistrement est égale au champ de nom similaire dans l’autre enregistrement.

      Par exemple :

        [ A = 1, B = 2 ] = [ A = 1, B = 2 ]        // true 
        [ B = 2, A = 1 ] = [ A = 1, B = 2 ]        // true 
        [ A = 1, B = 2, C = 3 ] = [ A = 1, B = 2 ] // false 
        [ A = 1 ] = [ A = 1, B = 2 ]               // false
      
  • Deux tables sont égales si toutes les conditions suivantes sont vraies :

    • Le nombre de colonnes est le même.

    • Chaque nom de colonne dans une table est également présent dans l’autre table.

    • Le nombre de lignes est le même.

    • Chaque ligne a des valeurs égales dans les cellules correspondantes.

      Par exemple :

        #table({"A","B"},{{1,2}}) = #table({"A","B"},{{1,2}}) // true 
        #table({"A","B"},{{1,2}}) = #table({"X","Y"},{{1,2}}) // false 
        #table({"A","B"},{{1,2}}) = #table({"B","A"},{{2,1}}) // true
      
  • Une valeur de fonction est égale à elle-même, mais peut éventuellement être égale à une autre valeur de fonction. Si deux valeurs de fonction sont considérées comme égales, elles se comportent de la même façon quand elles sont appelées.

    Deux valeurs de fonction données ont toujours la même relation d’égalité.

  • Une valeur de type est égale à elle-même, mais peut éventuellement être égale à une autre valeur de type. Si deux valeurs de type sont considérées comme égales, elles se comportent de la même façon quand elles sont interrogées à des fins de vérification de conformité.

    Deux valeurs de type données ont toujours la même relation d’égalité.

Opérateurs relationnels

Les opérateurs <, >, <= et >= sont appelés opérateurs relationnels.

relational-expression :
      expression-additive
      additive-expression
<relational-expression
      additive-expression
>relational-expression
      additive-expression
<= _relational-expression
      additive-expression >=relational-expression

Ces opérateurs sont utilisés pour déterminer la relation de classement relatif entre deux valeurs, comme indiqué dans le tableau suivant :

Opération Résultat
x < y true si x est inférieur à y, false sinon
x > y true si x est supérieur à y, false sinon
x <= y true si x est inférieur ou égal à y, false sinon
x >= y true si x est supérieur ou égal à y, false sinon

Par exemple :

0 <= 1            // true 
null < 1          // null 
null <= null      // null 
"ab" < "abc"      // true 
#nan >= #nan      // false  
#nan <= #nan      // false

Les points suivants s’appliquent lors de l’évaluation d’une expression contenant les opérateurs relationnels :

  • Les erreurs générées lors de l’évaluation des expressions d’opérande x ou y sont propagées.

  • Les valeurs produites par l’évaluation des expressions x et y doit être de type binaire, date, DateHeure, datetimezone, durée, logique, nombre, nul, texte ou heure. Sinon, une erreur avec le code de raison "Expression.Error" est générée.

  • Les deux opérandes doivent avoir le même type de valeur ou null. Sinon, une erreur avec le code de raison "Expression.Error" est générée.

  • Si un ou les deux opérandes sont null, le résultat est la valeur null.

  • Deux binaires sont comparés octet par octet.

  • Deux dates sont comparées en fonction de leurs parties « année » et, en cas d’égalité, de leurs parties « mois » et, en cas d’égalité, de leurs parties « jour ».

  • Deux datetimes sont comparés en fonction de leurs parties « année » et, en cas d’égalité, de leurs parties « mois » et, en cas d’égalité, de leurs parties « jour » et, en cas d’égalité, de leurs parties « heure » et, en cas d’égalité, de leurs parties « minutes » et, en cas d’égalité, de leurs parties « secondes ».

  • La comparaison de deux datetimezones consiste à les normaliser en temps UTC en soustrayant leur décalage en heures/minutes, puis à comparer leurs composants datetime.

  • Deux durées sont comparées en fonction du nombre total de cycles de 100 nanosecondes qu’elles représentent.

  • Deux logiques sont comparées de telle sorte que true est considéré comme supérieur à false.

  • Deux nombres x et y sont comparés en fonction des règles de la norme IEEE 754 :

    • Si l’un des opérandes est #nan, le résultat est false pour tous les opérateurs relationnels.

    • Quand aucun opérande n’est #nan, les opérateurs comparent les valeurs des deux opérandes floatingpoint au niveau du classement -∞ < -max < ... < -min < -0.0 = +0.0 < +min < ... < +max < +∞, où min et max sont les valeurs finies positives les plus petites et les plus grandes pouvant être représentées. Les noms M pour -∞ et +∞ sont -#infinity et #infinity.

      Les effets notables de ce classement sont les suivants :

      • Les zéros positifs et négatifs sont considérés égaux.

      • Une valeur -#infinity est considérée inférieure à toutes les autres valeurs numériques, mais égale à une autre valeur -#infinity.

      • Une valeur #infinity est considérée supérieure à toutes les autres valeurs numériques, mais égale à une autre valeur #infinity.

  • Deux textes sont comparés à l’aide d’une comparaison ordinale caractère par caractère, respectant la casse et indépendante de la culture.

  • Deux heures sont comparées en fonction de leurs parties « heure » et, en cas d’égalité, de leurs parties « minutes » et, en cas d’égalité, de leurs parties « secondes ».

Opérateurs logiques conditionnels

Les opérateurs and et or sont appelés opérateurs logiques conditionnels.

logical-or-expression :
      logical-and-expression
logical-and-expression
orlogical-or-expression
logical-and-expression :
      is-expression
      is-expression
andlogical-and-expression

L’opérateur or retourne true quand au moins l’un de ses opérandes est true. L’opérande de droite est évalué si et seulement si l’opérande de gauche n’est pas true.

L’opérateur and retourne false quand au moins l’un de ses opérandes est false. L’opérande de droite est évalué si et seulement si l’opérande de gauche n’est pas false.

Les tables de vérité pour les opérateurs or et and sont indiquées ci-dessous, avec le résultat de l’évaluation de l’expression de l’opérande de gauche sur l’axe vertical et le résultat de l’évaluation de l’expression de l’opérande de droite sur l’axe horizontal.

and true false null error
true true false null error
false false false false false
null null false null error
error error error error error
or true false null error
or true false null error
true true true true true
false true false null error
null true null null error
error error error error error

Les points suivants s’appliquent lors de l’évaluation d’une expression contenant des opérateurs logiques relationnels :

  • Les erreurs générées lors de l’évaluation des expressions x ou y sont propagées.

  • Les opérateurs logiques conditionnels sont définis sur les types logical et null. Si les valeurs d’opérande ne sont pas de ces types, une erreur avec le code de raison "Expression.Error" est générée.

  • Le résultat est une valeur logique.

  • Dans l’expression x ou y, l’expression y est évaluée si et seulement si x n’a pas la valeur true.

  • Dans l’expression x et y, l’expression y est évaluée si et seulement si x n’a pas la valeur false.

Les opérateurs logiques conditionnels doivent leur qualification de « conditionnel » aux deux dernières propriétés, également désignées sous le terme de « court-circuit ». Ces propriétés sont utiles pour écrire des prédicats protégés compacts. Par exemple, les expressions suivantes sont équivalentes :

d <> 0 and n/d > 1 if d <> 0 then n/d > 1 else false

Opérateurs arithmétiques

Les opérateurs +, -, * et / sont les opérateurs arithmétiques.

additive-expression :
      multiplicative-expression
      additive-expression
+multiplicative-expression
      additive-expression
-multiplicative-expression
multiplicative-expression :
      metadata- expression
      multiplicative-expression
*metadata-expression
      multiplicative-expression
/metadata-expression

Précision

Les nombres dans M sont stockés sous diverses représentations afin que soient conservées autant d’informations que possible sur les nombres provenant de diverses sources. Les nombres ne sont convertis d’une représentation en une autre qu’en fonction des besoins des opérateurs qui leur sont appliqués. Deux précisions sont prises en charge dans M :

Précision Sémantique
Precision.Decimal Représentation décimale sur 128 bits avec une plage allant de ±1.0 x 10-28 à ±7.9 x 1028 et 28 à 29 chiffres significatifs.
Precision.Double Représentation scientifique utilisant la mantisse et l’exposant, conforme à la norme arithmétique IEEE 754 concernant le format double précision binaire sur 64 bits (IEEE 754-2008).

Les opérations arithmétiques consistent à choisir une précision, à convertir les deux opérandes en cette précision (si nécessaire), à effectuer l’opération proprement dite, puis à retourner un nombre dans la précision choisie.

Les opérateurs arithmétiques intégrés (+, -, *, /) utilisent le format double précision. Vous pouvez utiliser des fonctions de bibliothèque standard (Value.Add, Value.Subtract, Value.Multiply, Value.Divide) pour demander ces opérations à l’aide d’un modèle de précision spécifique.

  • Aucun dépassement numérique n’est possible : #infinity ou -#infinity représentent des valeurs de grandeur trop grande pour être représentées.

  • Aucun soupassement numérique n’est possible : 0 et -0 représentent des valeurs de grandeur trop petite pour être représentées.

  • La valeur spéciale IEEE 754 #nan (NaN-Not a Number, soit « Pas un nombre ») est utilisée pour couvrir les cas arithmétiques non valides, tels qu’une division de zéro par zéro.

  • La conversion du format décimal au format double précision consiste à arrondir les nombres décimaux à la valeur double précision équivalente la plus proche.

  • La conversion du format double précision au format décimal consiste à arrondir les nombres double précision à la valeur décimale équivalente la plus proche et, si nécessaire, à effectuer un dépassement jusqu’aux valeurs #infinity ou -#infinity.

Opérateur d’addition

L’interprétation de l’opérateur d’addition (x + y) dépend du genre de valeur des expressions évaluées x et y, comme suit :

x y Résultat Interprétation
type number type number type number Somme numérique
type number null null
null type number null
type duration type duration type duration Somme numérique de grandeurs
type duration null null
null type duration null
typedatetime type duration typedatetime Datetime décalé d’une durée
type duration typedatetime typedatetime
typedatetime null null
null typedatetime null

Dans le tableau, typedatetime correspond à type date, type datetime, type datetimezone ou type time. Quand vous ajoutez une durée et une valeur d’un type datetime, la valeur résultante est du même type.

Pour les combinaisons de valeurs autres que celles listées dans le tableau, une erreur avec le code de raison "Expression.Error" est générée. Chaque combinaison est couverte dans les sections suivantes.

Les erreurs générées lors de l’évaluation de l’un des opérandes sont propagées.

Somme numérique

La somme de deux nombres est calculée à l’aide de l’opérateur d’addition ; le résultat est un nombre.

Par exemple :

1 + 1             // 2 
#nan + #infinity  // #nan

L’opérateur d’addition + sur des nombres utilise le format double précision ; vous pouvez utiliser la fonction de bibliothèque standard Value.Add pour spécifier le format précision décimale. Les points suivants s’appliquent lors du calcul d’une somme de nombres :

  • La somme au format double précision est calculée en fonction des règles de la norme arithmétique IEEE 754 concernant le format double précision binaire sur 64 bits (IEEE 754-2008). Le tableau suivant liste les résultats de toutes les combinaisons possibles de valeurs finies non nulles, de zéros, de valeurs infinies et de valeurs NaN. Dans le tableau, x et y sont des valeurs finies non nulles, et z est le résultat de x + y. Si x et y ont la même grandeur, mais des signes opposés, z est un zéro positif. Si x + y est trop grand pour être représenté dans le type de destination, z est un infini avec le même signe que x + y.

    + y +0 -0 +∞ -∞ NaN
    x z x x +∞ -∞ NaN
    +0 y +0 +0 +∞ -∞ NaN
    -0 y +0 -0 +∞ -∞ NaN
    +∞ +∞ +∞ +∞ +∞ NaN NaN
    -∞ -∞ -∞ -∞ NaN -∞ NaN
    NaN NaN NaN NaN NaN NaN NaN
  • Le quotient au format précision décimale est calculé sans perte de précision. L’échelle du résultat est la plus grande des échelles des deux opérandes.

Somme de durées

La somme de deux durées correspond à la durée représentant la somme du nombre de cycles de 100 nanosecondes représenté par les durées. Par exemple :

#duration(2,1,0,15.1) + #duration(0,1,30,45.3) 
// #duration(2, 2, 31, 0.4)

Datetime décalé d’une durée

Vous pouvez ajouter un datetimex et une durée y à l’aide de x + y pour calculer un nouveau datetime dont la distance par rapport à x sur une chronologie linéaire correspond exactement à la grandeur de y. Ici, datetime correspond à Date, DateTime, DateTimeZone ou Time, et un résultat non nul est du même type. Le datetime décalé d’une durée peut être calculé comme suit :

  • Si la valeur du nombre de jours depuis l’époque du datetime est spécifiée, construisez un nouveau datetime avec les éléments d’information suivants :

    • Calculez une nouvelle valeur du nombre de jours depuis l’époque en divisant la grandeur de y par le nombre de cycles de 100 nanosecondes sur une période de 24 heures, en tronquant la partie décimale du résultat et en ajoutant cette valeur au nombre de jours depuis l’époque de x.

    • Calculez une nouvelle valeur du nombre de cycles écoulés depuis minuit en ajoutant la grandeur de y aux cycles de x depuis minuit, puis en divisant le résultat par le nombre de cycles de 100 nanosecondes sur une période de 24 heures ; la partie entière du résultat final correspond à la nouvelle valeur. Si x ne spécifie pas de valeur pour les cycles depuis minuit, la valeur 0 est supposée.

    • Copiez la valeur de x pour le décalage en minutes par rapport à l’heure UTC inchangée.

  • Si la valeur du nombre de jours depuis l’époque du datetime n’est pas spécifiée, construisez un nouveau datetime avec les éléments d’information suivants spécifiés :

    • Calculez une nouvelle valeur du nombre de cycles écoulés depuis minuit en ajoutant la grandeur de y aux cycles de x depuis minuit, puis en divisant le résultat par le nombre de cycles de 100 nanosecondes sur une période de 24 heures ; la partie entière du résultat final correspond à la nouvelle valeur. Si x ne spécifie pas de valeur pour les cycles depuis minuit, la valeur 0 est supposée.

    • Copiez les valeurs de x pour les jours depuis l’époque et le décalage en minutes par rapport à l’heure UTC inchangée.

Les exemples suivants illustrent le calcul de la somme temporelle absolue quand le datetime spécifie le nombre de jours depuis l’époque :

#date(2010,05,20) + #duration(0,8,0,0) 
    //#datetime( 2010, 5, 20, 8, 0, 0 ) 
    //2010-05-20T08:00:00 
 
#date(2010,01,31) + #duration(30,08,0,0) 
    //#datetime(2010, 3, 2, 8, 0, 0) 
    //2010-03-02T08:00:00 
 
#datetime(2010,05,20,12,00,00,-08) + #duration(0,04,30,00) 
    //#datetime(2010, 5, 20, 16, 30, 0, -8, 0) 
    //2010-05-20T16:30:00-08:00 
 
#datetime(2010,10,10,0,0,0,0) + #duration(1,0,0,0) 
   //#datetime(2010, 10, 11, 0, 0, 0, 0, 0) 
   //2010-10-11T00:00:00+00:00

L’exemple suivant montre le calcul du datetime décalé d’une durée pour une heure donnée :

#time(8,0,0) + #duration(30,5,0,0) 
   //#time(13, 0, 0) 
   //13:00:00

Opérateur de soustraction

L’interprétation de l’opérateur de soustraction (x - y) dépend du genre de la valeur des expressions évaluées x et y, comme suit :

x Y Résultat Interprétation
type number type number type number Différence numérique
type number null null
null type number null
type duration type duration type duration Différence numérique des grandeurs
type duration null null
null type duration null
typedatetime typedatetime type duration Durée entre datetimes
typedatetime type duration typedatetime Datetime décalé d’une durée négative
typedatetime null null
null typedatetime null

Dans le tableau, typedatetime correspond à type date, type datetime, type datetimezone ou type time. Quand vous soustrayez une durée d’une valeur d’un type datetime, la valeur résultante est du même type.

Pour les combinaisons de valeurs autres que celles listées dans le tableau, une erreur avec le code de raison "Expression.Error" est générée. Chaque combinaison est couverte dans les sections suivantes.

Les erreurs générées lors de l’évaluation de l’un des opérandes sont propagées.

Différence numérique

La différence entre deux nombres est calculée à l’aide de l’opérateur de soustraction ; le résultat est un nombre. Par exemple :

1 - 1                // 0 
#nan - #infinity     // #nan

L’opérateur de soustraction - sur des nombres utilise le format double précision ; vous pouvez utiliser la fonction de bibliothèque standard Value.Subtract pour spécifier le format précision décimale. Les points suivants s’appliquent lors du calcul d’une différence de nombres :

  • La différence au format double précision est calculée en fonction des règles de la norme arithmétique IEEE 754 concernant le format double précision binaire sur 64 bits (IEEE 754-2008). Le tableau suivant liste les résultats de toutes les combinaisons possibles de valeurs finies non nulles, de zéros, de valeurs infinies et de valeurs NaN. Dans le tableau, x et y sont des valeurs finies non nulles, et z est le résultat de x - y. Si x et y sont égaux, z est un zéro positif. Si x - y est trop grand pour être représenté dans le type de destination, z est un infini avec le même signe que x - y.

    - y +0 -0 +∞ -∞ NaN
    x z x x -∞ +∞ NaN
    +0 -y +0 +0 -∞ +∞ NaN
    -0 -y -0 +0 -∞ +∞ NaN
    +∞ +∞ +∞ +∞ NaN +∞ NaN
    -∞ -∞ -∞ -∞ -∞ NaN NaN
    NaN NaN NaN NaN NaN NaN NaN
  • La différence au format précision décimale est calculée sans perte de précision. L’échelle du résultat est la plus grande des échelles des deux opérandes.

Différence de durées

La différence de deux durées correspond à la durée représentant la différence entre le nombre de cycles de 100 nanosecondes représenté par chaque durée. Par exemple :

#duration(1,2,30,0) - #duration(0,0,0,30.45) 
// #duration(1, 2, 29, 29.55)

Datetime décalé d’une durée négative

Vous pouvez soustraire un datetimex et une durée y à l’aide de x - y pour calculer un nouveau datetime. Ici, datetime correspond à date, datetime, datetimezone ou time. Le datetime résultant a une distance par rapport à x sur une chronologie linéaire qui correspond exactement à la grandeur de y, dans la direction opposée au signe de y. La soustraction de durées positives donne des résultats qui sont antérieurs dans le temps à x, tandis que la soustraction de valeurs négatives génère des résultats qui sont postérieurs dans le temps.

#date(2010,05,20) - #duration(00,08,00,00) 
   //#datetime(2010, 5, 19, 16, 0, 0) 
   //2010-05-19T16:00:00 
#date(2010,01,31) - #duration( 30,08,00,00) 
   //#datetime(2009, 12, 31, 16, 0, 0) 
   //2009-12-31T16:00:00

Durée entre deux datetimes

Vous pouvez soustraire deux datetimest et u à l’aide de t - u pour calculer la durée qui les sépare. Ici, datetime correspond à date, datetime, datetimezone ou time. Si vous ajoutez à u la durée produite par la soustraction de u de t, vous devez obtenir t.

#date(2010,01,31) - #date(2010,01,15) 
// #duration(16,00,00,00) 
// 16.00:00:00 
 
#date(2010,01,15)- #date(2010,01,31) 
// #duration(-16,00,00,00) 
// -16.00:00:00 
 
#datetime(2010,05,20,16,06,00,-08,00) - 
#datetime(2008,12,15,04,19,19,03,00) 
// #duration(521,22,46,41)
// 521.22:46:41

La soustraction t - u quand u > t aboutit à une durée négative :

#time(01,30,00) - #time(08,00,00) 
// #duration(0, -6, -30, 0)

Le point suivant s’applique lors de la soustraction de deux datetimes à l’aide de t - u :

  • u + (t - u) = t

Opérateur de multiplication

L’interprétation de l’opérateur de multiplication (x * y) dépend du genre de valeur des expressions évaluées x et y, comme suit :

X Y Résultat Interprétation
type number type number type number Produit numérique
type number null null
null type number null
type duration type number type duration Multiple de durée
type number type duration type duration Multiple de durée
type duration null null
null type duration null

Pour les combinaisons de valeurs autres que celles listées dans le tableau, une erreur avec le code de raison "Expression.Error" est générée. Chaque combinaison est couverte dans les sections suivantes.

Les erreurs générées lors de l’évaluation de l’un des opérandes sont propagées.

Produit numérique

Le produit de deux nombres est calculé à l’aide de l’opérateur de multiplication ; le résultat est un nombre. Par exemple :

2 * 4                // 8 
6 * null             // null 
#nan * #infinity     // #nan

L’opérateur de multiplication * sur des nombres utilise le format double précision ; vous pouvez utiliser la fonction de bibliothèque standard Value.Multiply spécifier le format précision décimale. Les points suivants s’appliquent lors du calcul d’un produit de nombres :

  • Le produit au format double précision est calculé en fonction des règles de la norme arithmétique IEEE 754 concernant le format double précision binaire sur 64 bits (IEEE 754-2008). Le tableau suivant liste les résultats de toutes les combinaisons possibles de valeurs finies non nulles, de zéros, de valeurs infinies et de valeurs NaN. Dans le tableau, x et y sont des valeurs finies positives. z est le résultat de x * y. Si le résultat est trop grand pour le type de destination, z est une valeur infinie. Si le résultat est trop petit pour le type de destination, z est égal à zéro.

    * +y -y +0 -0 +∞ -∞ NaN
    +x +z -Z +0 -0 +∞ -∞ NaN
    -x -Z +z -0 +0 -∞ +∞ NaN
    +0 +0 -0 +0 -0 NaN NaN NaN
    -0 -0 +0 -0 +0 NaN NaN NaN
    +∞ +∞ -∞ NaN NaN +∞ -∞ NaN
    -∞ -∞ +∞ NaN NaN -∞ +∞ NaN
    NaN NaN NaN NaN NaN NaN NaN NaN
  • Le produit au format précision décimale est calculé sans perte de précision. L’échelle du résultat est la plus grande des échelles des deux opérandes.

Multiples de durées

Le produit d’une durée et d’un nombre est la durée représentant le nombre de cycles de 100 nanosecondes représenté par l’opérande de la durée multiplié par l’opérande du nombre. Par exemple :

#duration(2,1,0,15.1) * 2 
// #duration(4, 2, 0, 30.2)

Opérateur de division

L’interprétation de l’opérateur de division (x / y) dépend du genre de valeur des expressions évaluées x et y, comme suit :

X Y Résultat Interprétation
type number type number type number Quotient numérique
type number null null
null type number null
type duration type number type duration Fraction de durée
type duration type duration type duration Quotient numérique des durées
type duration null null
null type duration null

Pour les combinaisons de valeurs autres que celles listées dans le tableau, une erreur avec le code de raison "Expression.Error" est générée. Chaque combinaison est couverte dans les sections suivantes.

Les erreurs générées lors de l’évaluation de l’un des opérandes sont propagées.

Quotient numérique

Le quotient de deux nombres est calculé à l’aide de l’opérateur de division ; le résultat est un nombre. Par exemple :

8 / 2               // 4 
8 / 0               // #infinity 
0 / 0               // #nan 
0 / null            // null 
#nan / #infinity    // #nan

L’opérateur de division / sur des nombres utilise le format double précision ; vous pouvez utiliser la fonction de bibliothèque standard Value.Divide pour spécifier le format précision décimale. Les points suivants s’appliquent lors du calcul d’un quotient de nombres :

  • Le quotient au format double précision est calculé en fonction des règles de la norme arithmétique IEEE 754 concernant le format double précision binaire sur 64 bits (IEEE 754-2008). Le tableau suivant liste les résultats de toutes les combinaisons possibles de valeurs finies non nulles, de zéros, de valeurs infinies et de valeurs NaN. Dans le tableau, x et y sont des valeurs finies positives. z est le résultat de x / y. Si le résultat est trop grand pour le type de destination, z est une valeur infinie. Si le résultat est trop petit pour le type de destination, z est égal à zéro.

    / +y -y +0 -0 +∞ -∞ NaN
    +x +z -Z +∞ -∞ +0 -0 NaN
    -x -Z +z -∞ +∞ -0 +0 NaN
    +0 +0 -0 NaN NaN +0 -0 NaN
    -0 -0 +0 NaN NaN -0 +0 NaN
    +∞ +∞ -∞ +∞ -∞ NaN NaN NaN
    -∞ -∞ +∞ -∞ +∞ NaN NaN NaN
    NaN NaN NaN NaN NaN NaN NaN NaN
  • Le quotient au format précision décimale est calculé sans perte de précision. L’échelle du résultat est la plus grande des échelles des deux opérandes.

Quotient des durées

Le quotient de deux durées correspond au nombre représentant le quotient du nombre de cycles de 100 nanosecondes représenté par les durées. Par exemple :

#duration(2,0,0,0) / #duration(0,1,30,0) 
// 32

Durées mises à l’échelle

Le quotient d’une durée x et d’un nombre y est la durée représentant le quotient du nombre de cycles de 100 nanosecondes représenté par la durée x et le nombre y. Par exemple :

#duration(2,0,0,0) / 32 
// #duration(0,1,30,0)

Combinaison de structures

L’opérateur de combinaison (x & y) est défini sur les genres de valeurs suivants :

X Y Résultat Interprétation
type text type text type text Concaténation
type text null null
null type text null
type date type time type datetime Fusionner
type date null null
null type time null
type list type list type list Concaténation
type record type record type record Fusionner
type table type table type table Concaténation

Concaténation

Deux valeurs de texte, de liste ou de table peuvent être concaténées à l’aide de x & y.

L’exemple suivant illustre la concaténation de valeurs de texte :

"AB" & "CDE"     // "ABCDE"

L’exemple suivant illustre la concaténation de listes :

{1, 2} & {3}     // {1, 2, 3}

Les points suivants s’appliquent lors de la concaténation de deux valeurs à l’aide de x & y :

  • Les erreurs générées lors de l’évaluation des expressions x ou y sont propagées.

  • Aucune erreur n’est propagée si un élément de x ou y contient une erreur.

  • Le résultat de la concaténation de deux valeurs de texte est une valeur de texte qui contient la valeur de x immédiatement suivie de y. Si l’un des opérandes a pour valeur Null et que l’autre est une valeur de texte, le résultat est Null.

  • Le résultat de la concaténation de deux listes est une liste qui contient tous les éléments de x suivis de tous les éléments de y.

  • Le résultat de la concaténation de deux tables est une table qui contient l’union des colonnes de table des deux opérandes. L’ordre des colonnes de x est conservé, suivi des colonnes qui apparaissent uniquement dans y, avec conservation de leur classement relatif. Pour les colonnes qui apparaissent uniquement dans l’un des opérandes, null est utilisé pour remplir les valeurs de cellule pour l’autre opérande.

Fusionner

Fusion d’enregistrements

Deux enregistrements peuvent être fusionnés à l’aide de x & y ; le résultat est un enregistrement qui comprend les champs de x et de y.

Les exemples suivants illustrent la fusion d’enregistrements :

[ x = 1 ] & [ y = 2 ]                // [ x = 1, y = 2 ] 
[ x = 1, y = 2 ] & [ x = 3, z = 4 ]  // [ x = 3, y = 2, z = 4 ]

Les points suivants s’appliquent lors de la fusion de deux enregistrements à l’aide de x + y :

  • Les erreurs générées lors de l’évaluation des expressions x ou y sont propagées.

  • Si un champ apparaît dans x et y, la valeur de y est utilisée.

  • L’ordre des champs dans l’enregistrement résultant est celui de x, suivi des champs dans y qui ne font pas partie de x, dans l’ordre dans lequel ils apparaissent dans y.

  • La fusion des enregistrements n’entraîne pas l’évaluation des valeurs.

  • Aucune erreur n’est générée parce qu’un champ contient une erreur.

  • Le résultat est un enregistrement.

Fusion d’une date et d’une heure

Une date x peut être fusionnée avec une heure y à l’aide de x & y ; le résultat est un datetime qui combine les parties de x et de y.

L’exemple suivant illustre la fusion d’une date et d’une heure :

#date(2013,02,26) & #time(09,17,00) 
// #datetime(2013,02,26,09,17,00)

Les points suivants s’appliquent lors de la fusion de deux enregistrements à l’aide de x + y :

  • Les erreurs générées lors de l’évaluation des expressions x ou y sont propagées.

  • Le résultat est un datetime.

Opérateurs unaires

Les opérateurs +, - et not sont des opérateurs unaires.

unary-expression :
      type-expression

      +unary-expression
      -unary-expression
      notunary-expression

Opérateur plus unaire

L’opérateur plus unaire (+x) est défini pour les genres de valeurs suivants :

X Résultat Interprétation
type number type number Plus unaire
type duration type duration Plus unaire
null `null

Pour les autres valeurs, une erreur avec le code de raison "Expression.Error" est générée.

L’opérateur plus unaire permet l’application d’un signe + à une valeur numérique, datetime ou Null. Le résultat est cette même valeur. Par exemple :

+ - 1                 // -1 
+ + 1                 // 1 
+ #nan                // #nan 
+ #duration(0,1,30,0) // #duration(0,1,30,0)

Les points suivants s’appliquent lors de l’évaluation de l’opérateur plus unaire +x :

  • Les erreurs générées lors de l’évaluation de x sont propagées.

  • Si le résultat de l’évaluation de x n’est pas une valeur numérique, une erreur avec le code de raison "Expression.Error" est générée.

Opérateur moins unaire

L’opérateur moins unaire (-x) est défini pour les genres de valeurs suivants :

X Résultat Interprétation
type number type number Négation
type duration type duration Négation
null null

Pour les autres valeurs, une erreur avec le code de raison "Expression.Error" est générée.

L’opérateur moins unaire est utilisé pour changer le signe d’un nombre ou d’une durée. Par exemple :

- (1 + 1)       // -2 
- - 1           // 1 
- - - 1         // -1 
- #nan          // #nan 
- #infinity     // -#infinity 
- #duration(1,0,0,0)  // #duration(-1,0,0,0) 
- #duration(0,1,30,0) // #duration(0,-1,-30,0)

Les points suivants s’appliquent lors de l’évaluation de l’opérateur moins unaire -x :

  • Les erreurs générées lors de l’évaluation de x sont propagées.

  • Si l’expression est un nombre, le résultat est la valeur numérique de l’expression x avec son signe changé. Si la valeur est NaN, le résultat est également NaN.

Opérateur de négation logique

L’opérateur de négation logique (not) est défini pour les genres de valeurs suivants :

X Résultat Interprétation
type logical type logical Négation
null null

Cet opérateur calcule l’opération not logique sur une valeur logique donnée. Par exemple :

not true             // false 
not false            // true 
not (true and true)  // false

Les points suivants s’appliquent lors de l’évaluation de l’opérateur de négation logique not x :

  • Les erreurs générées lors de l’évaluation de x sont propagées.

  • La valeur produite par l’évaluation de l’expression x doit être une valeur logique, sinon une erreur avec le code de raison "Expression.Error" doit être déclenchée. Si la valeur est true, le résultat est false. Si l’opérande est false, le résultat est true.

Le résultat est une valeur logique.

Opérateurs de type

Les opérateurs is et as sont appelés opérateurs de type.

Opérateur de compatibilité de type

L’opérateur de compatibilité de type x is y est défini pour les types de valeurs suivants :

X Y Résultat
type any nullable-primitive-type type logical

L’expression x is y retourne true si le type attribué de x est compatible avec y, et retourne false si le type attribué de x est incompatible avec y. y doit être un nullable-primitive-type.

is-expression :
      as-expression
      is-expression
isnullable-primitive-type
nullable-primitive-type :

      nullableopt primitive-type

La compatibilité de type, telle qu’elle est prise en charge par l’opérateur is, est un sous-ensemble de la compatibilité de type générale et est définie à l’aide des règles suivantes :

  • Si x est null, il est compatible si y est le type any, le type null ou un type nullable.

  • Si x est non Null, il est compatible si le type primitif de x est le même que y.

Les points suivants s’appliquent lors de l’évaluation de l’expression x is y :

  • Une erreur générée lors de l’évaluation de l’expression x est propagée.

Opérateur d’assertion de type

L’opérateur d’assertion de type x as y est défini pour les types de valeurs suivants :

X Y Résultat
type any nullable-primitive-type type any

L’expression x as y déclare que la valeur x est compatible avec y conformément à l’opérateur is. Si elle n’est pas compatible, une erreur est générée. y doit être un nullable-primitive-type.

as-expression :
      equality-expression
      as-expression
asnullable-primitive-type

L’expression x as y est évaluée comme suit :

  • Une vérification de la compatibilité de type x is y est effectuée et l’assertion retourne x inchangé si ce test réussit.

  • Si la vérification de la compatibilité échoue, une erreur avec le code de raison "Expression.Error" est générée.

Exemples :

1 as number               // 1 
"A" as number             // error 
null as nullable number   // null

Le point suivant s’applique lors de l’évaluation de l’expression x as y :

  • Une erreur générée lors de l’évaluation de l’expression x est propagée.

Opérateur de coalescence

L’opérateur de coalescence ?? retourne le résultat de son opérande gauche s’il n’est pas null ; sinon, il retourne le résultat de son opérande droit. L’opérande de droite est évalué si et seulement si l’opérande de gauche est null.