brackets [,;] Concaténation. Récipients d'une affectation. Résultats d'une function

## Syntaxe

                Mh = [m11 m12 m13.. m1N] or [m11, m12, m13,.., m1N]
                Mv = [m11 ; m21 ; m31..; mN1]
                M  = [m11, m12,...; m21, m22,...;...]
                [r1, r2,...] = func(...)
                [r1, r2,.., rN] = (e1, e2, .., eN)
                [r1, r2,.., rk] = (e1, e2, .., ek,.., eN)
                [r1, r2,.., rN] = mylist(:)
                [r1, r2,.., rN] = S.field([i1 i2.. iN])

## Arguments

m11, m12,...

  Ensemble d'objets à concaténer (rassembler) et à fusionner : les conteneurs individuels initiaux des objets sont supprimés. Les types d'objets des familles suivantes peuvent être mélangés entre eux dans une même famille, mais pas entre familles :

  - Matrices de booléens, nombres décimaux, nombres complexes, polynômes, fractions rationnelles : le type de l'objet résultant est le type de l'élément le plus complexe, des booléens (le moins complexe) aux fractions rationelles à coefficients complexes (voir les règles de transtypages).
  - Matrices d'entiers encodés de type entier inttype quelconque.
    Des entiers de types différents ne peuvent pas être concaténés entre eux.
  - Tableaux de cellules.
  - Tableaux de structures ayant les mêmes champs. Les champs peuvent être dans des ordres différents d'un tableau à l'autre.
  - Listes de type syslin
M, Mh, Mv

  Matrices ayant le type des éléments `m##` (s'ils ont tous le même type). Tableaux de cellules (si les `mi` en sont). Tableaux de structures (si les `mi` en sont).

e1, e2,..

  Objets d'entrée (litéraux tels que `-1.23` ou `"abcd"`, variables, ou expressions telles que `a+%pi`)

mylist

  Liste simple du type list(..)

S.field

  Tableau de structures ayant un champ nommé `field`.

i1, i2, ..

  Indices des éléments de `S` sélectionnés.

r1, r2,...

  Récipients = variables de sortie

## Description

[] (figurant à droite) : crochets concaténateurs

  [..] assemble les objets de types simples et compatibles pour former un vecteur, une matrice ou une hypermatrice homogène.

  La concaténation horizontale ou verticale de N éléments est un opérateur binaire itératif : la concaténation est réalisée de proche en proche entre 2 élements consécutifs, de la gauche vers la droite, et de haut en bas. Ainsi, `[1 3 5 7]` est effectuée par `[[[1 3] 5] 7]`.

  Dans les crochets,

  - les espaces (blancs ou tabulations) ou les virgules servent de séparateurs.
    Il est préférable d'utiliser des virgules, en particulier lorsque des nombres complexes ou des polynômes sont fournis en expressions litérales. Par exemple, `[2 1 +%i]` sera interprété comme `[2, 1, %i]`, alors que `[2 1 + %i]` sera compris comme `[2, 1+%i]`.
  - les points-virgules ou les changements de lignes sont utilisés comme séparateurs de lignes. Pour peu que la ligne courante soit complète, le passage à la ligne ne pré-requiert pas les points de poursuite-à-la-ligne `..`.

  ### Transtypages

  Avec quelques restrictions, les crochets peuvent être utilisés sur une série de valeurs ayant des types distincts mais compatibles. Des valeurs sont alors converties de proche en proche dans le type de données dominant. Les principales règles de conversion implicite sont les suivantes :

  1. booléen < entier encodé < nombre décimal < nombre complexe
  2. décimal < polynôme < fraction rationelle
     Les booléens et les polynômes ne sont pas compatibles entre eux :
     - `[%t 2. %z]` est accepté, car : `[%t 2.]` est d'abord converti en `[1. 2.]`, puis `[[1. 2.] %z]` est accepté.
     - `[%z %t 2.]` est refusé et produit une erreur. En effet, `[%z %t]` n'est pas permis et bloque la suite.
  3. Tout entier encodé peut être concaténé uniquement avec des booléens, des nombres réels ou complexes, ou d'autres entiers du même type entier (inttype). Ainsi, les expressions `[int8(2) uint8(7)]`, `[int8(2) int16(7)]`, `[int8(2), 7+0*%z]`, `[int8(2), sparse(7)]`, ou `[int8(2), sparse(%t)]` produiront toutes une erreur.
  4. Le résultat est encodé en valeurs complexes (avec parties imaginaires éventuellement nulles) dés qu'un élément -- valeur, polynôme, ou fraction rationnelle -- à valeur complexe est rencontré.

     De même, le résultat est encodé sous forme creuse dés qu'un élément encodé creux est rencontré.

  5. Des polynômes et/ou des fractions rationnelles à concaténer doivent avoir la même variable symbolique.
  6. Les éléments de texte (type "string") peuvent être concaténés (au sens ensembliste, avec les crochets) uniquement entre eux ou avec la matrice vide `[]`.

  ### Surcharge

  - [,]: concaténation horizontale : cet opérateur n-aire (pouvant être appliqué à un nombre arbitraire n de données) est en fait un opérateur binaire automatiquement itéré de la gauche vers la droite. Son code de surcharge est `"c"`.
  - [;]: la concaténation verticale est également un opérateur binaire, itéré du haut vers le bas. Son code de surcharge est `"f"`.

  ### Extensions

  - Pour concaténer des listes simples, utiliser lstcat.
  - Pour assembler des vecteurs ou matrices ou hypermatrices ou autres tableaux selon une dimension > 2 et construire un hypertableau à N dimensions, utiliser cat.
[] figurant à gauche d'une affectation `"="`

  Dans ce cas, les crochets ne désignent en rien une concaténation. Ils délimitent une série de variables servant de récipients.

  - Les termes entre crochets doivent alors impérativement être des variables. Les expressions litérales ou symboliques sont rejetées.
  - Les variables sont séparées par des virgules ou des espaces. Lorsqu'il s'agit de la liste des arguments de sortie d'une function, les virgules sont obligatoires.
  - Dans une affectation distributive, il doit y avoir au plus autant de récipients que de sources de données provenant du terme de droite, pas plus. S'il y moins de récipients à gauche que de sources à droite, les sources non collectées sont ignorées. Exemples :
    - `[a,b] = (%pi,"Hi", %z)` est correct, mais `%z` sera ignoré.
    - `[a,b,c] = (%pi,"Hi")` produit une erreur, car `c` attend du contenu.
  - `[a,b,a] = (%pi, %z, "Allo")` réalise les affectations de la gauche vers la droite, de sorte que finalement `a = "Allo"`.

## Exemples

    // Concaténation horizontale
    a = [ %pi 4 -1 ]
    b1 = grand(3,4,"uin",0,10)
    b2 = grand(3,2,"uin",0,10)
    b = [b1 b2]  // b1, b2.. doivent avoir le même nombre de lignes

    // Concaténation verticale
    a = [-2 ; 10 ; 7]

    b1 = grand(2,4,"uin",0,10)
    b2 = grand(3,4,"uin",0,10)
    b = [b1 ; b2] // // b1, b2.. doivent avoir le même nombre de colonnes

    // Double concaténation horizontale et verticale
    a = [ 3 7 ; 6, 5 ]
    b = [ 1:3 ; 7:3:13]
    c = [ a b ; a b]

    d = [ 3 5
          1 4
        ]
    e = [ d d d
          d d d
        ]
    // Concaténation de types d'objets variés :
    ['this is' ; 'a column' ; 'of texts']

    s = poly(0,'s');[1/s,2/s]
    [tf2ss(1/s),tf2ss(2/s)]

    [%t %f %f %T %F]

Concaténation d'objets de types distincts compatibles, avec transtypages automatiques

    [%T int8(-5)]
    [%T %pi %f 2]
    [%pi, 2+%i, %F]
    [%pi int16(-1000.84) 1.23]
    v = [%pi+0*%i, %F, %z, (1-%z)^2 ]; typeof(v), isreal(v)
    v = [10 1/%z], typeof(v)

    // Cas particulier : int16 et uint8 ensemble, finalement concaténés
    //   par conversion décimale se propageant de gauche à droite :
    [%pi int16(-1000.84) uint8(87)]

Concaténations hétérogènes d'objets de types incompatibles => ERREURS

    [%F %z]
    [%s %z]
    [int8(-70), sparse(18)]
    [int8(-70), sparse([%T %F])]

Concaténation de tableaux de cellules :

    c1 = {%pi %t};
    c2 = {%z "abc"};
    c = [[{%i} c1] ; [c2, {1/%z^2}]]  // virgule obligatoire sinon c2{1/%z^2} => erreur

Affectations distributives :

    // Variables des réponses d'une function.
    // Elles sont le plus souvent optionnelles, l'une après l'autre
    M = rand(3,3);
    [u, s] = schur(M) // Nous attendons et utilisons à la fois u et s
    u = schur(M)      // Nous attendons et stockons uniquement u

    // Liste directe (implicite) d'objets à affecter
    [a, b, c] = (%pi, %t, "test")
    [a, b] = (%e, %f, "Hello")
    [a, b, a] = (%pi, %t, "test"); a

    // Liste explicite d'objets à affecter
    L = list(%z, %i, %t, %pi, "Text");
    [a, b, c] = L(:)

    // Tableau de structures :
    // Sélection de certaines cellules et affectation de leurs contenus
    s(2,3).r = %pi; s(2,1).r = %i; s(2,2) = %e;
    s(2,:).r
    s.r([2 4 6])
    [a, b, c] = s.r([2 4 6])

    // Expressions gauches interdites et rejetées (=> erreur)
    [m, n, m+n] = myfun(a,b) // "m+n" est une expression, non un nom de variable.
    [p, 4.5, q] = myfun(a,b) // "4.5 est une valeur littérale, non un nom de variable.
    [r, s+3 ] = myfun(a,b)   // "s+3" est une expression mixte, non un nom de variable

    --> [a, b, c] = (%pi, %t, "test")
     a  =
       3.1415927

     b  =
      T

     c  =
     test

    --> [a, b] = (%e, %f, "Hello")
     a  =
       2.7182818

     b  =
      F

    --> [a, b, a] = (%pi, %t, "test"); a
     a  =
     test

## Voir aussi

- cat
- lstcat
- comma
- semicolon
- parentheses
- empty
- overloading

## Historique

6.0 Crochets `[..]` et accolades `{..}` ont désormais des fonctions distinctes.
6.1.0

- Booléens et entiers encodés peuvent désormais être concaténés ensemble, comme dans [%t, int8(-5)].
- [a, b, ..] = (A, B,..) réalise désormais les affectations de la gauche vers la droite.

6.1.1

- Concaténer des entiers encodés avec des réels ou complexes est désormais possible.
- Des polynômes et/ou fractions rationnelles à concaténer doivent avoir la même variable symbolique.