Les structures de données
Maple est un langage qui est typé au niveau des objets, mais non typé au niveau des variables, c'est à dire que toute variable peut contenir un objet de n'importe quel type (contrairement à Pascal ou C). Dans ce chapitre nous allons nous intéresser aux types des objets (et non des variables), puis au contrôle des types et enfin aux mécanismes de l'évaluation des objets.
I. Types simples
Nous avons déjà rencontré précédemment la plupart des types simples.
1. Types numériques
?integer
SYNOPSIS:   
- An expression is of type integer if it is an (optionally signed) sequence of one or more digits of arbitrary length.  The length limit of an integer is system dependent but generally much larger than users will encounter -- typically greater than 500,000 decimal digits.
- In addition to arithmetic operators, other basic functions of integers are
               abs           sign   min      max        factorial
               irem          iquo   modp     mods       mod
               isqrt         iroot  isprime  ifactor    ifactors
               igcd          ilcm   igcdex   iratrecon  rand
- There are also many special functions for integers in the numtheory and combinat packages including the binomial coefficients, Fibonacci numbers, Stirling numbers, Jacobi symbol, Eulers totient function etc.
?fraction
SYNOPSIS:   
- <signed integer> / <natural integer>
- An expression of type fraction is represented by a pair of integers (numerator and denominator) with all common factors removed and with a positive denominator.
- Like integers, fractions can be of arbitrary length.
- The op function considers the fraction data type to have two operands, where  the first operand is the numerator and the second operand is the denominator.
- A rational is defined to be either an integer or a fraction.
?float
CALLING SEQUENCE:
   <integer>.<integer>
   <integer>.
   .<integer>
   Float(mantissa, exponent)
PARAMETERS:
   mantissa, exponent - integers
SYNOPSIS:   
- A floating-point number (called type float) is shown as a sequence of digits  with a decimal point.
- Floating-point numbers are represented internally by a pair of integers (the  mantissa and the exponent), which represent the number  mantissa * 10^(exponent).  The exponent is ``word-size'' but the mantissa can  be of any length.
- An alternative way to input floating-point numbers is  Float(mantissa, exponent) which corresponds to the internal representation.  The latter notation is used to output numbers with very small or very large  magnitudes.
- The op function considers this data type to have two operands: the mantissa  and the exponent.  For example, op(150.1) yields 1501, -1.
- Arithmetic with floating-point numbers is performed by the evalf function,  although floating-point evaluation takes place automatically for arithmetic  operations whenever one of the operands is a float.
- The number of digits carried in the mantissa for floating-point arithmetic is  determined by the global variable Digits (default 10).
Remarquons que Maple (contrairement à d'autres langages de calcul formel) ne connait pas de type complexe. Pour lui un complexe est une expression algébrique de la forme a+b*sqrt(-1) qui s'écrit sous la forme a+b*I par l'intermédiaire d'un alias.
2. Les chaines de caractères et le type "name"
Les chaînes de caractère ont dans Maple un double rôle. D'une part elles servent (comme en Pascal ou en C)  à stocker des expressions alphanumériques, mais elles servent également comme variables. C'est là un premier aspect déroutant de la plupart des langages de calcul formel. Alors qu'en Pascal ou en C il n'y a aucun risque de confusion entre la variable monTableau   et la chaîne de caractères "monTableau"  (en C, 'monTableau' ), dans Maple il n'y a aucune différence. Une chaîne de caractères devient automatiquement une variable par le seul fait qu'on l'utilise en tant que telle (et en particulier si on l' affecte). En fait, le vocabulaire des concepteurs de Maple établit une dsitinction artificielle mais utile entre les chaînes de caractère utilisées en tant que telles (string) et les chaînes de caractères utilisées comme variables (name), mais il faut savoir que rien dans le langage ne distingue les deux et que l'on peut au cours d'une même seance ou procédure utiliser le même objet alternativement dans un sens ou dans l'autre.
	Une chaîne de caractères est délimitée par des accents graves (en anglais backquotes) que l'on prendra garde à ne pas confondre avec les accents aigus ou apostrophes qui servent à empêcher une évaluation. Ces accents graves sont facultatifs si la chaîne de caractères satisfait aux règles habituelles de formation des noms de varaibles dans les langages de haut niveau (commencer par une lettre ou un _ et ne comporter que des caractères alphanumériques).
	Ceci a pour conséquence que rien ne vous interdit de nommer une variable comme `n-1` ou `Monsieur le Président Directeur Général` avec tous les risques de confusion que cela comporte au niveau de l'affichage (imaginez l'affectation `n-1`:=n-1).
?string
SYNOPSIS:   
- A name is usually a string, which in its simplest form is a letter followed  by zero or more letters, digits, and underscores with lower and upper case  letters distinct.  The maximum length of a name is 499 characters.
- Any expression may be assigned to a name.  If no value has been assigned to  the name then it stands for itself.
- More generally, names (strings) may be formed with the concatenation operator: . or with the function: cat.
- A string may also be formed by enclosing any sequence of characters in a pair  of backquotes ` `.  Since any string is a valid <name> in Maple, the following is valid: `This is a name!` := 1.
- For any valid Maple name formed without using backquotes, the name formed by  surrounding it with backquotes is precisely the same name.  Thus x and `x`  both refer to the same name x.  However, a keyword may not be used as a name  or string unless it is enclosed in backquotes.
- Strings formed using backquotes are often used in the sense of character  strings rather than names.  A common example is the string used as an error  message, as in: ERROR(`the argument must be an integer`).
- Two successive backquotes appearing after the opening of a string will be  parsed as a single backquote.  Thus, `abc``de` yields abc`de.
- The type function understands the typenames string and indexed, and type name  is defined to be either of: string or indexed.
II. Types composés
1. Sequences
Le type composé le plus simple (et celui qui provoque le plus de surprise) est la séquence. Il s'agit uniquement d'une suite d'objets Maple séparés par une virgule. En particulier les paramètres d'une fonction, les éléments d'une liste ou d'un ensemble forment une séquence. le type des séquences est exprseq.
?sequence
SYNOPSIS:   
- Expression sequences, (or simply sequences), are created using the comma  operator ,.  For example s := 1,2,3 assigns s the sequence 1,2,3.  In Maple,  sequences form the basis of many data types.  In particular, they appear in  function calls, lists, sets and subscripts.  
Example:
- f(s) applies the function f to the sequence 1,2,3,
- [s] creates the list containing the elements 1,2,3,
- {s} creates the set containing the elements 1,2,3, and
- a[s] is the 1,2,3 subscript.
- These are equivalent to f(1,2,3), [1,2,3], {1,2,3}, and a[1,2,3] respectively.   
- When sequences are concatenated with a comma, the result is a single,  unnested sequence.  Thus t := s,s assigns t the sequence 1,2,3,1,2,3.  The  empty sequence is available as the value of the global variable NULL.  It  also appears implicitly in the empty list [], the empty set {}, a function  call f() with no parameters, and an indexed name a[] with no subscripts.
- Two key tools for constructing sequences are the seq function and the repetition operator $.  For example, the call seq(f(i), i=1..3) will generate the  sequence f(1), f(2), f(3).  The call x$3 will generate the sequence x, x, x.
- Sequences can also be constructed using the op function.  The op function  when applied to any Maple expression (except a sequence itself) returns a  sequence of the operands of that expression.  For example, op([x,y,z]) and  op(x+y+z) both return the sequence x, y, z.
- The op and nops functions cannot be applied to a sequence because the elements of the sequence are taken to be individual arguments to the function.  However, the i-th operand of a sequence s may be accessed using the selection  operation s[i].  The length of a sequence may be determined by doing  nops([s]), that is, by determining the length of the list containing the  expression sequence.

 On peut créer une séquence soit en écrivant les objets séparés par une virgule soit en utilisant une fonction de construction de sequence comme seq ou l'opérateur de répétition $.
?seq
FUNCTION: seq - create a sequence
CALLING SEQUENCE:
   seq(y, i = m..n)
   seq(y, i = x)
PARAMETERS:
   y    - any expression
   i    - name
   m, n - numerical values
   x    - an expression
SYNOPSIS:   
- The seq function is related to the for loop construct.  It behaves in a similar manner to for except that seq constructs a sequence of values.
- The most typical call is seq(f(i), i = 1..n) which generates the sequence  f(1), f(2), ..., f(n).  More generally, seq(f(i), i = m..n) generates the  sequence f(m), f(m+1), f(m+2), ..., f(n).  Here m and n do not have to be  integers.
- The call seq(f(i), i = x) generates a sequence by applying f to each operand  of x.  Here, x would most commonly be a set or list, but could be a sum, product, etc.
?$
FUNCTION: $ - operator for forming an expression sequence
CALLING SEQUENCE:
   expr $ i = m..n; expr $ n; $ m..n;
PARAMETERS:
   expr - an expression
   i    - an unevaluated name
   m,n  - expressions
SYNOPSIS:   
- $ returns the expression sequence produced by substituting for i in expr the
  values m,m+1,...,n (or up to the last value not exceeding n).
- If m>n then the NULL expression sequence is returned.
- A call to $ in the form: $ m..n; will have the same effect as the call:
  i $ i = m..n;.
- A call to $ in the form: expr $ n; will have the same effect as the call:
  expr $ i = 1..n ; (assuming that expr does not contain i).
- Note: It is recommended (and often necessary) that both 'expr' and 'i' be
  enclosed in single quotes to prevent premature evaluation.  (E.g., i may have
  had a previous value).  I.e., the common format is 'expr' $ 'i' = m..n;
2. Listes
Une liste dans Maple est une suite d'objets ordonnés, séparés par des virgules et encadrés par des crochets. Une liste est donc de la forme [sequence ].
?list
CALLING SEQUENCE:
   [es]   
PARAMETERS:
   es - an expression sequence
SYNOPSIS:   
- A list is an ordered sequence of expressions enclosed in square brackets. The ordering of the expressions is the ordering of es.
- Note that es may be empty so that the empty list is represented by [].
- The elements of list may be extracted via the selection operation. Thus, if S is a set or list then the i-th element of S can be obtained by: S[i] or equivalently, op(i,S).
Les listes peuvent être construites explicitement, ou alors en utilisant les fonctions de construction de séquences. Un certain nombre d'opérateurs s'appliquent aux listes comme union, intersect, minus, member.
• [x,y,y,z];
                               [x, y, y, z]

• [seq(i^2,i=-2..5)];
                        [4, 1, 0, 1, 4, 9, 16, 25]

• [$1..6];
                            [1, 2, 3, 4, 5, 6]
3. Ensembles
Un ensemble dans Maple est une suite d'objets distincts, non ordonnés, séparés par des virgules et encadrés par des accolades Une liste est donc de la forme {sequence }. Un ensemble est toujours simplifié par Maple pour éviter les répétitions et il est stocké et affiché dans un ordre interne à Maple, sur lequel on n'a aucune prise.

CALLING SEQUENCE:
   {es}   
PARAMETERS:
   es - an expression sequence
SYNOPSIS:   
- A set is an unordered sequence of distinct expressions enclosed in braces,  representing a set in the mathematical sense.  The user should not assume  that the expressions will be maintained in any particular order because Maple  uses an ordering convenient for its implementation.
- Note that es may be empty so that the empty set is represented by {}.
- The elements of a setmay be extracted via the selection operation. Thus, if S is a set or list then the i-th element of S can be obtained by: S[i] or equivalently, op(i,S).
Les ensembles peuvent être construits explicitement, ou alors en utilisant les fonctions de construction de séquences. Un certain nombre d'opérateurs s'appliquent aux ensembles comme union, intersect, minus, member.
• {z,x,y,y};
                                {x, y, z}
• {seq(i^2,i=-2..5)};
                           {0, 1, 4, 9, 16, 25}
• {$1..6};
                            {1, 2, 3, 4, 5, 6}
4. Type indexé
Le type indexé est une facilité de Maple pour créer de nouveaux noms à l'aide d'un symbole indexé. C'est ainsi que, de même qu'en Mathématiques on peut nommer trois points du plan sous la forme A1, A2 et A3, on peut créer en Maple trois noms A[1], A[2] et A[3]. Bien entendu, les indices peuvent être des séquences de n'importe quels objets Maple. On prendra garde à ne pas confondre les objets indexés de Maple avec les tableaux de Pascal ou C.
?indexed
CALLING SEQUENCE:
   <name> [ <expression sequence> ]
SYNOPSIS:   
- <name> [ <expression sequence> ]
- An indexed name may appear anywhere a name may appear.  In particular, since A[1,2,3] is valid so is A[1,2,3][x,y] and A[1,2,3][x,y][2,1].
- The op function applied to an indexed name yields the expression sequence of indices appearing within the rightmost brackets, and the zero'th operand is the corresponding <name>.
- The use of the indexed name b[1] does not imply that b is an array.  For  instance: 
		a := b[1] + b[2] + b[1000]; 
simply forms a sum of three indexed names.
- The assignment of a value to an indexed name will implicitly create a table. Thus the statement:
		b[1] := 10; 
creates a table for b and assigns the value 10 to the component of the table indexed by 1.

On prendra garde également à ne pas confondre les crochets des symboles indexés avec les crochets qui permettent d'accéder (en tant que rvalue  ne pouvant être affectée) aux différents éléments d'une séquence, d'une liste ou d'un ensemble.
5. Tables
La structure de table est tout à fait particulière à Maple. Elle reprend la notion mathématique de famille indexée, avec la seule différence que, alors qu'en matématiques on notre ai, en Maple on note a[i]. Bien entendu, aussi bien en mathématiques qu'en Maple, "i " peut être une séquence, et alors on notera a[i,j,k,…] à la place de ai,j,k,….
?table
FUNCTION: table - create a table
CALLING SEQUENCE:
   table( F, L )
PARAMETERS:
   F - (optional) the indexing function
   L - (optional) list of initial table entries
SYNOPSIS:   
- A table is created either explicitly by a call to the table function or  implicitly by assigning to an indexed name.  Unlike arrays, where indices  must be integers, the indices (or keys) of a table can be any value.
- The table function creates a table with initial values specified by L.  If L  is a list of equations then the left-hand-side is taken to be the table index  (key), and the right-hand-side the entry (value).  Otherwise, L is taken to  be a list of entries with indices 1, 2, ... etc.  If L is not specified, then  an empty table is created.
- New entries can be added to a table using the subscript notation.  Thus  T := table([4]) is equivalent to: T := table() and T[1] := 4 or equivalently:  T[1] := 4 if T was unassigned (implicit creation).  Entries can be removed  from a table by assigning a table entry to its own name.  Thus T[1] := 'T[1]'  removes the entry 4 from T.
- The indexing function F can be a procedure or a name specifying how indexing  is to be performed; if null then ordinary indexing is implied.  The built in  indexing functions are: symmetric, antisymmetric, sparse, diagonal, and identity.   
- Tables have special evaluation rules (like procedures) so that if the name T  has been assigned a table then T evaluates to T.  The call op(T) yields the  actual table structure; and op(op(T)) yields the components of the table,  i.e. the indexing function (if there is one) and a list of equations for the  tables values.
- The indices function can be used to obtain a sequence of a tables indices and  likewise, the entries function returns a sequence of the table's entries.
Il faut donc faire un certain nombre de remarques:
	- les indices d'une table n'ont aucune raison d'être entiers ni même d'être homogènes, rien ne vous interdit de poser a[1]:=1 et  a[sin,alpha,2]:=x
	- si aucune fonction d'indexage n'est fournie, les appels a[sequence d'indices ] non affectés retournent simplement non évalués, il n'y a donc pas de débordement possible (au contraire de Pascal ou C); le rôle des fonctions d'indexage est de donner des valeurs par défaut aux a[sequence d'indices ]
	- les tables peuvent être créées explicitement par la fonction table mais aussi implicitement simplement en assignant une valeur à un a[...].

Exemple:
	- une table créée explicitement sans initialisations
• a:=table():
• a[1]:=1: a[cos,alpha,1]:=x:
• a[2],a[1],a[x],a[toto,truc],a[cos,alpha,1];
                     a[2], 1, a[x], a[toto, truc], x

	- une table créée implicitement avec initialisations
• b[2,{x,y}]:=1: 
• b[1],b[2,x,y],b[2,{x,y}];
                           b[1], b[2, x, y], 1

	- une table créée explicitement avec initialisations; remarquer la syntaxe des initialisations : (séquence d'indices ) = …
• c:=table([(1)=1,(cos,alpha,1)=x]):
• c[cos,alpha,1];
                                    x

Les entrées initialisées d'une table peuvent être récupérées avec les fonctions indices (qui donne les indices affectés sous forme de séquence de listes) et entries (qui donne, dans le même ordre, leurs affectations également sous forme de séquence de listes)
FUNCTION: indices - indices of a table or array , entries - entries of a table or array
CALLING SEQUENCE:
   indices(t); and entries(t);
PARAMETERS:
   t - a table or array
SYNOPSIS:   
- The indices and entries functions return sequences of the indices (or keys)  and the entries respectively of the table or array t corresponding to the entries that are explicitly stored.
- The result returned is a sequence of lists in an apparently arbitrary order which cannot be controlled by the user.  There is though a one to one correspondence between the result of indices and entries.
• t:=table([(1,2)=moi,(3,2)=toi,(1,3)=lui]):
• indices(t);
                          [2, 3], [1, 3], [1, 2]
• entries(t);
                           [toi], [lui], [moi]

Attention: contrairement aux autres objets de Maple, le nom d'une table ne désigne pas la table elle-même mais un pointeur sur la table (autrement dit l'adresse en mémoire de la table). C'est ainsi qu'une affectation entre tables ne réalise par une recopie de la table. Après une affectation du type b:=a, où a est une table, b ne réalise pas une copie de a, mais au contraire a et b désignent la même table (en particulier toute modification de b se répercute sur a  et réciproquement)
• a[1]:=1: b:=a:  b[1]:=x:
• a[1];
                                    x
De même, une variable de type table ne renvoie pas le contenu de la table elle même mais son nom.
• a;
                                    a
Si l'on veut le contenu de a (en fait l'objet pointé par a) il faut demander un niveau d'évaluation supplémentaire.
• eval(a);
                                table([
                                    1 = x
                                ])
Pour plus de détail, voir le paragraphe sur l'évaluation ci-dessous.
5. Array
	Le type array est un type particulier du type table dans lequel l'ensemble d'indices est un intervalle d'entiers ou un produit cartésien de tels intervalles d'entiers. L'accès à un élément se fait donc nécessairement sous la forme a[i,j,k,…] dans lequel i,j,k,… sont des entiers dont le nombre et les bornes sont fixés a priori  . Bien entendu un tel objet doit être créé explicitement pour définir le nombre d'indices et les intervalles dans lesquels ils varient. C'est le rôle de la fonction array.
FUNCTION: array - create an array
CALLING SEQUENCE:
   array( indexfcn, bounds, list)
PARAMETERS:
   indexfcn - (optional) an indexing function
   bounds   - (optional) sequence of ranges
   list     - (optional) list of initial values
SYNOPSIS:   
- An array is a specialization of a table, with zero or more specified dimensions, where each dimension is an integer range.  The result of executing the  array function is to create an array.  For example, V := array(1..10) creates  a one dimensional array (a Maple vector) of length 10 but with no explicit  entries.  The command A := array(1..m,1..n) creates a two dimensional array  (a Maple matrix) with m rows and n columns.
- All parameters to the array function are optional and may appear in any  order.  The bounds parameter is a sequence of integer ranges which must  appear consecutively.  If the bounds are not specified then they are deduced  from the list of initial values.
- The indexfcn can be a procedure or a name specifying how indexing is to be  performed - see indexfnc for more information.  The built-in indexing functions are symmetric, antisymmetric, sparse, diagonal, and identity.  If  indexfnc is not specified, then ``ordinary'' indexing is used.
- The list of initial values may be a list of equations (cf. tables), or a list  of values (one-dimensional), or a nested list of lists (row-by-row).
- The map function can be used to apply a function to each entry of an array.  For example, map (simplify, A) simplifies each entry of the array A.
- Arrays have special evaluation rules (like procedures) so that if the name A  has been assigned an array then A evaluates to the name A and eval(A) yields  the actual array structure.
- The op function can be used to pick apart an array structure.  Specifically  op(eval(A)) yields indexfcn, bounds, and entries where entries is a list of  equations corresponding to the explicit entries in the array (cf. entries).  Hence op(1,eval(A)) returns the array dimensions.
Contrairement à une table générale, dans une array, un contrôle du nombre d'indices et de leurs bornes est effectué, si bien qu'aucun débordement n'est possible.
• m:=array(1..3,0..2,[(1,1)=1,(3,2)=x]):
• m[1,2],m[3,2];
                                m[1, 2], x
• m[1];
Error, index incompatible with bounds
• m[0,10];
Error, index outside of bound
III. Types expressions. Opérandes
1. Arbre d'une expression
Considérons une opération n-aire  que nous noterons &. Si expr1,…,exprn sont n expressions algébriques, nous considérerons comme équivalentes les expressions
(expr1) & … & (exprn)
et
&(expr1,…,exprn).
Dans la première notation, nous nous autoriserons à supprimer les parenthèses autour des expressions algébriques qui sont réduites à des atomes.  La première forme sera appelée la forme parenthésée de l'expression algébrique, la deuxième forme la forme prénexe. Un moyen classique de stocker une expression algébrique sous forme prénexe est de la stocker sous forme de liste "à la LISP"
(& (expr1) … (exprn))
en supprimant encore une fois les parenthèses autour des atomes.
Par exemple l'expression  Sin(2x+y+f(z)) sera stockée sous la forme
(Sin  (Plus  (Mult  2  x)  y  (f  z)))
Un autre moyen classique est de la stocker sous forme d'arbre

La solution retenue par Maple (comme par Mathematica) est une solution intermédiaire.

Bien entendu le passage d'une forme liste à la forme arbre (ou à la forme intermédiaire de maple) et inversement est un exercice de programmation à peu près trivial. Par contre la passage de la forme parenthésée à l'une de ces trois formes est beaucoup plus délicat (surtout si l'expression n'est pas complêtement parenthésée et utilise des priorités entre les opérateurs, comme l'on fait habituellement), mais est fait de façon transparente à l'utilisateur par Maple.
2. Type et opérandes d'une expression
Pour Maple, le type d'une expression algébrique non atomique est son en-tête (ou encore sa racine). C'est ainsi que
- le type de  sin(2x+y+f(z))   est    sin
- le type de    2x+y+f(z)     est    sum  (plus en anglais)
- le type de   2x     est   times   (multiplié en anglais)
- le type de  f(z)    est      f .
Quand aux opérandes ce sont les diverses sous expressions (éventuellement atomiques) auxquelles s'appliquent l'opérateur de l'en tête.
- l'expression sin(2*x+y+f(z))   a un seul opérande    2*x+y+f(z)
- l'expression   2*x+y+f(z)     a trois opérandes     2x,	y, 	f(z)
- l'expression  2*x a deux opérandes     2 , 	x
- l'expression  f(z)    a un seul opérande    z.
Dans la notation en arbre, le type correspond à la racine de l'arbre et les opérandes a chacun des sous arbres partant de la racine. La fonction op retourne les divers opérandes d'une expression algébrique. Quant à la fonction nops elle renvoie le nombre d'opérandes (c'est à dire le nombre de flèches partant de la racine).
?op, nops
FUNCTION: op - extract operands from an expression
FUNCTION: nops - the number of operands of an expression
CALLING SEQUENCE:
   op(i,e) op(i..j,var e); op(e); and nops(e);
PARAMETERS:
   i,j - non-negative integers marking positions of operands
   e   - any expression
SYNOPSIS:   
- The op function extracts the components of an expression.  The nops function  returns the number of components of an expression.
- If the first argument is a nonnegative integer i then the result is the i'th  operand of e.
- If the first argument is a range i..j then the result is an expression  sequence of the i'th to j'th operands of e.  If there is only one argument:  op(e) = op(1..nops(e),e)
- If e is an integer or a string, nops(e) yields 1 and op(1,e) yields e.
- For some data structures, op 0 is defined as a special case.  For subscripts  and functions, op 0 is the name of the subscript or function and for series,  op 0 is the expansion point of the series.

Retenez en particulier que op(i,exp) renvoie le i-ième opérande de exp et que op(exp) renvoie la séquence des opérandes de f.
• expr:=sin(2*x+y+f(z)):
• expr2:=op(1,expr);
                         expr2 := 2 x + y + f(z)

• op(0,expr);
                                   sin

• op(1,expr2);
                                   2 x

• op(expr2);
                               2 x, y, f(z)
IV. Typage
1. Les types prédéfinis
Nous avons rencontré précédemment la plupart des types usuels de Maple. 
* les types simples 
	- boolean
	- integer (lui même subdivisé en odd et even d'une part, en posint et negint d'autre part)
	- fraction
	- rational  (qui englobe à la fois integer et fraction)
	- float
	- numeric (qui englobe à la fois integer, fraction et float)
	- string
* les types composés
	- sequence
	- list
	- set
	- array (qui englobe un type matrix pour les array dont les indices commencent à 1 et un type vector pour les matrices à une dimension)
	- range (pour les intevalles d'entiers, notés  a..b)
* les types d'expressions algébriques
	- polynom (qui englobe un type monomial pour les monômes et un type expanded pour les polynômes développés)
	- ratpoly pour une fraction rationnelle
	- series pour des séries (en fait des développements limités)
En fait, la gamme des types connus est beaucoup plus riche. En voici la liste:
   
       *             **         +         .          ..         <
       <=            <>         =         RootOf     ^          algebraic
       algext        algfun     algnum    algnumext  and        anything
       array         boolean    constant  cubic      equation   even
       expanded      facint     float     fraction   function   indexed
       integer       intersect  laurent   linear     list       listlist
       logical       mathfunc   matrix    minus      monomial   name
       negative      negint     nonneg    nonnegint  not        numeric
       odd           operator   or        plot       plot3d     point
       polynom       posint     positive  primeint   procedure  quadratic
       quartic       radext     radfun    radfunext  radical    radnum
       radnumext     range      rational  ratpoly    realcons   relation
       scalar        series     set       sqrt       square     string
       taylor        trig       type      uneval     union      vector

Les appellations sont la plupart du temps suffisamment parlantes. Vous pouvez demander des explications supplémentaires avec la fonction help(type[nom_du_type ]).
Remarque: à la lumière des types ci dessus, on peut constater qu'il y d'une part une hiérarchie de types de type héritage, que d'autre part le type ne décrit pas seulement un pur stockage informatique de l'objet, mais également un certain nombre de ses propriétés. On est là en plein dans les principaux concepts de la programmation par objet (en anglais Object Oriented Programming, ou OOP).
2. Le contrôle des types
Il se fait à partir d'un petit nombre de fonctions. La fonction type permet de tester si une expression est bien d'un type donné. On en verra la principale utilité en programmation où presque toute fonction commencera par un if type(....) then .
FUNCTION: type - type-checking function
CALLING SEQUENCE:
   type(x, t)
PARAMETERS:
   x - any expression
   t - type name or set of type names
SYNOPSIS:   
- The type function is a boolean function which returns true if x is of type t;
  false otherwise.
- In the case where t is specified as a set of type names, the value returned
  is true if x is any of the types in the set; false otherwise.
- Note: If a type name is an operator, it must be back-quoted to prevent a syn-
  tax error.  See the examples below.
- For further information, see type[<datatype>] where <datatype> is one of the
  names in the above list.
- A user can make a datatype known to the type function in the following way.
  If the user has defined the procedure `type/mytype` then a call to type of
  the form: type(a, mytype(b, c, ...)); will generate the function call
  `type/mytype`(a, b, c, ...).
- See type[definition] and type[structured] for information on defining and
  using type expressions.
- See type[surface] for information on the distinction between a ``surface
  type'' and a ``nested type''.

Le but de la fonction whattype permet au contraire de récupérer directement sous forme de symbole le type d'une expression.
FUNCTION: whattype - query the basic data type of an expression
CALLING SEQUENCE:
   whattype(expr)
PARAMETERS:
   expr - any expression
SYNOPSIS:   
- The function whattype returns the data type name of expr, which may be any of the following basic data types:
   
          `+`           `*`        `^`       `=`       `<>`     `<`
          `<=`          `.`        `..`      `and`     `or`     `not`
          exprseq       float      fraction  function  indexed  integer
          list          procedure  series    set       string   table
          uneval
             
- For a general expression, whattype returns the ``top level'' data type as determined by the order of precedence of the operators.

Quant à la fonction hastype elle permet de tester la présence dans une expression de sous-expressions d'un type donné 
FUNCTION: hastype - test for a specified type
CALLING SEQUENCE:
   hastype( expr, t );
PARAMETERS:
   expr - any expression
   t    - name of a datatype
SYNOPSIS:   
- The boolean function hastype returns true if and only if expr has any subexpressions of the type t.

Exemples:
• type( a + b, polynom );
                                      true
• type( a + b, `+` );
                                      true
• type( a * b, `+` );
                                     false
• type( a and b, `and` );
                                      true
• type(1+2*sqrt(3),numeric);
                                  false
• type(1+2*sqrt(3),algebraic);
                                   true
• type(x,name);
                                   true
• whattype(a+b);
                                    +
• whattype(2*sqrt(3));
                                    *
• whattype(f(x));
                                 function
• hastype(3+sqrt(2*sin(x)),function);
                                   true
• hastype(3+sqrt(2*sin(x)),`*`);
                                   true
3. Les types définis par l'utilisateur
Maple permet comme beaucoup de langages de programmations de définir ses propres types et de les nommer. Pour définir son propre type (par exemple un type truc), il suffit d'assigner la valeur du type à `type/truc` (attention aux accents graves).
• `type/truc`:=integer:
• type(3,truc);
                                   true
Bien entendu cette possibilité trouve tout son intérêt avec la possibilité de définir des types structurés. Un type structuré est toute expression Maple autre qu'une chaîne de caractère qui peut être interprétée comme un type à l'aide de la grammaire suivante les notation habituelles pour une grammaire sont
	::=      signifie  "est défini comme"
	|          signifie  "ou"
	*	signifie "zero, une ou plusieurs occurences de ..."
   
               Syntaxe               Correspond à
    
 type ::=      { type* }             alternation; any of the types
               | [ type* ]           concatenation; a list of the given types
               | numeric             match a numerical constant exactly
               | string              a system, procedural, or assigned type
               | type = type         an equation of the corresponding types
               | type <> type        an inequality of the corresponding types
               | type < type         a relation of the corresponding types
               | type <= type        a relation of the corresponding types
               | type > type         a relation of the corresponding types
               | type >= type        a relation of the corresponding types
               | type .. type        a range of the corresponding types
               | type and type       an and of the corresponding types
               | type or type        an or of the corresponding types
               | not type            a not of the corresponding type
               | type ^ type         a power of the corresponding types
               | type.type           a concatenation of the corresponding types
               | 'type'              an unevaluated expression of the given type
               | fcntype             a function or special type
               | name[type*]         an indexed reference of the given types
    
 fcntype ::=   set(type)             a set of elements of the given type
               | list(type)          a list of elements of the given type
               | `+`(type)           a sum of terms of the given type
               | `*`(type)           a product of factors of the given type
               | identical(expr)     an expression identical to expr
               | specfunc(type,foo)  the function foo with type arguments
               | anyfunc(type*)      any function of the given types
               | foo(type*)          type defined by a procedure `type/foo`
               | foo(type*)          the function foo of the given types    
	Les crochets sont utilisés pour tester une suite fixée d'arguments. Le type [name,set] désigne une liste avec exactement deux arguments, un nom suivi d'un ensemble.
	Par contre les accolades sont utilisées pour une alternative. Le type {set(name),list(integer)} correspond indifféremment à un ensemble de symboles et à une liste d'entiers.
	Le type anything s'adapte à n'importe quoi, sauf une séquence. Le type identical(expr) ne s'adapte qu'à une expression identique à expr. Le type anyfunc(t1,…,tn) s'adapte à toute fonction avec n arguments de types t1,…,tn. Le type specfunc(f,t) s'adapte uniquement à la fonction  f  appelée avec des arguments de type t.
• `type/truc`:={list(name),set(numeric)}:
• type({3,x},truc);
                                  false
• type({x,y},truc);
                                  false
• type([x,y],truc);
                                   true
• type({3,5/3,1.2},truc);
                                   true
• `type/tsin`:=specfunc(anything,sin):
• hastype(3+sqrt(2*sin(x)),tsin);
                                   true
V. L'evaluation
	Nous avons déjà vu que le mode normal de travail de Maple est celui de l'évaluation au niveau le plus profond. Ceci signifie que l'expression est évaluée jusqu'à ce qu'une évaluation supplémentaire n'induise pas de changement dans l'expression. Bien entendu cette expression est en général effectuée à l'aide de l'arbre de l'expression, c'est à dire qu'en premier lieu chacune des sous expressions est évaluée (normalement de la gauche vers la droite) et qu'ensuite l'expression totale est évaluée. Un certain nombre d'exceptions existent à cette évaluation au niveau le plus profond:
- les termes de gauche des affectations ne sont pas évalués (par contre les termes de droite le sont)
- les expressions entre apostrophes ne sont pas évaluées (ou plutôt l'évaluation d'une telle expression consiste à retirer un niveau d'apostrophes); on a vu comment cette possibilité permettait une affectation différée au lieu d'une affectation immédiate (ou encore une affectation par référence au lieu d'une affectation par valeur); elle évite aussi des évaluations intempestives de variables d'indice (empêcher par exemple une évaluation de i dans l'expression  seq(i*i,i=1..10) dans le cas où la variable i aurait été préalablement affectée, on a plutôt intérêt à utiliser seq(i*i,'i'=1..10)); elle peut également empêcher des évaluations intempestives dans la définition de types structurés (le type diff(name,name) étant par exemple évalué par Maple suivant les règles habituelles de dérivation pour donner 1, il faut pour définir un tel type le mettre entre apostrophes pour empêcher son évaluation).
- les tables et les procédures sont évaluées non pas en leur valeur au niveau le plus profond, mais en le dernier nom rencontré dans la chaîne d'évaluation.
	Cette dernière règle a un certain nombre de conséquences, dont la plus importante concerne les affectations. Si A est une table, une affectation du type  B:=A n'affecte pas à la variable B la valeur de A (c'est à dire ne recopie pas dans B la table contenu de A), mais au contraire affecte à B le nom A; ceci signifie qu'après l'affectation, les variables A et B désignent la même table (et non pas des tables égales). En particulier, toute modification de B se répercute automatiquement sur A et inversement. On peut comparer ce phénomène avec le système des tableaux en C où le nom du tableau désigne non pas le tableau lui même, mais un pointeur sur ce tableau. Si l'on veut échapper à ce sytème, il faut affecter à B une copie de A en écrivant  B:=copy(A).
	De même, si l'on veut afficher le contenu d'une table A, il ne suffit pas d'effectuer une évaluation de A de la manière habituelle car cette évalaution donnera simplement le dernier nom recontré au cours de la chaîne d'évaluation (la plupart du temps A lui même, sauf si A provient d'une affectation). Il faut au contraire forcer une évaluation complête à l'aide de la fonction eval. Celle ci a d'autres utilisations (forcer un niveau donné d'évaluation, forcer une évaluation complête après une substitution, forcer une évaluation complête des paramètres ou des variables locales d'une procédure qui ne sont normalement évalués qu'à un seul niveau).
FUNCTION: eval - explicit evaluation
CALLING SEQUENCE:
   eval(x)   
   eval(x, n)
PARAMETERS:
   x - an expression
   n - an integer
SYNOPSIS:   
- The normal evaluation rules in Maple are full evaluation for global variables, and one-level evaluation for local variables and parameters.  Sometimes the user requires full evaluation or one-level evaluation explicitly. The eval function is used for this purpose.
- The call eval(x) means fully evaluate the expression x.
- The call eval(x, 1) means evaluate the expression x one level.  More generally, eval(x, n) yields n-level evaluation.
- If x := y and y := 1 in a Maple session, what does the variable x evaluate to?  In an interactive session where x and y are global variables, x would evaluate to 1.  In this case, we say that x is ``fully evaluated''.  For one-level evaluation, we would use the command eval(x, 1) which would in this case yield y.  
• a:=table([(x)=1,(1,2)=sin,(2,4)=Pi]):
• a;
                                    a
L'évaluation a simplement renvoyé le nom de a qui est le dernier recontré.
• eval(a);
                             table([
                                 (1, 2) = sin
                                 (2, 4) = Pi
                                 x = 1
                             ])
L'évaluation complête a renvoyé le contenu de la table.
• b:=a;
                                  b := a
• b;
                                    a
L'évaluation a renvoyé le dernier nom rencontré, c'est à dire a. On va maintenant modifier b:
• b[1,2]:=3:
• eval(a);
                             table([
                                 (1, 2) = 3
                                 (2, 4) = Pi
                                 x = 1
                             ])
La table pointée par a  a été modifiée par la même occasion. Les noms a et b désignent bien la même table. Par contre, on va créer une nouvelle table c dans laquelle on recopiera la valeur de la table a. Les noms c et a désigneront donc deux tables distinctes (bien qu'initialement égales).
• c:=copy(a);
                           c := table([
                                    (1, 2) = 3
                                    (2, 4) = Pi
                                    x = 1
                                ])

• c[y]:=E:
• eval(a);
                             table([
                                 (1, 2) = 3
                                 (2, 4) = Pi
                                 x = 1
                             ])
La table a n'a pas été modifiée lors de la modification de c.
.