Les instructions copy et =< dans un programme

### 9.4.15 Les instructions `copy` et `=<` dans un programme

`=<` est surtout utile quand on fait beaucoup de modifications dans une liste ou matrice de grande taille, par exemple dans un programme. Mais attention, il faudra utiliser `copy` lors de l’initialisation des variables listes ou matrices qui seront modifiées avec `=<` pour que les modifications se fassent sur la copie.
Voir aussi 2.5.3 et 9.4.14.
Attention
Dans un programme si on met :

    local a;
    a:=[0,1,2,3,4];
    ...
    a[3] =< 33;

Cela modifie le programme lui-même et la ligne `a:=[0,1,2,3,4];` est remplacée par `a:=[0,1,2,33,4];` dans le programme compilé.
Donc dans un programme il faut écrire :

    local a;
    a:=copy([0,1,2,3,4]);
    ...
    a[3] =< 33;

ou

    local a,c;
    c:=[0,1,2,3,4];
    a:=copy(c);
    ...
    a[3] =< 33;

pour que ce soit la copie de `[0,1,2,3,4]` qui soit modifiée et non la liste `[0,1,2,3,4]` elle-même.

Remarque
On peut aussi utiliser les commandes `makelist`, `seq` ou `$`, par exemple :
`a:=makelist(n,n,0,4);` ou
`a:=[n$(n=0..4)]`; puis
`a[3] =< 33;` car `makelist(n,n,0,4)` ou `[n$(n=0..4)]` est une liste qui va se créer à chaque exécution du programme.

Exemple
On veut écrire un programme qui renvoie les nombres entiers inférieurs ou égaux à n et dont la somme des chiffres (en base 10) vaut 5. On tape :

    somme5(n):={
    local L,j,k;
    L:=seq(0,0);
    k:=0;
    for(j:=0;j<=n;j++){
    if (sum(convert(j,base,10))==5){
    L[k]=<j;
    k:=k+1;
    }
    }
    return L;
    }:;

On tape :

`somme5(50)`

On obtient :

`5,14,23,32,41,50`

Dans cet exemple, il faut bien comprendre et faire l’initialisation de `L` correctement.
Dans ce programme, on a choisit d’avoir le résultat sous la forme d’une séquence, et on a initialisé `L` avec `L:=seq(0,0)`. Si on avait mis `L:=NULL`, le programme n’aurait pas fonctionné correctement ! En effet, si on tape :

    fauxsom5(n):={
    local L,j,k;
    L:=NULL;
    k:=0;
    for(j:=0;j<=n;j++){
    if (sum(convert(j,base,10))==5){
    L[k]=<j;
    k:=k+1;
    }
    }
    return L;
    }:;

puis :

`fauxsom5(30)`

on obtient :

`5,14,23,32,41,50`

Cela semble juste..... Mais, lors de l’exécution de `fauxsom5(50)`, au départ `L` pointe sur la séquence `NULL`, puis cette séquence `NULL` est modifiée et devient à la fin du programme `5,14,23,32,41,50` et le programme, si on ne le recompile pas, a lui aussi été modifié est est devenu

    fauxsom5(n):={
    local L,j,k;
    L:=5,14,23,32,41,50;
    k:=0;
    for(j:=0;j<=n;j++){
    if (sum(convert(j,base,10))==5){
    L[k]=<j;
    k:=k+1;
    }
    }
    return L;
    }:;

Si on tape maintenant :

`fauxsom5(30)`

On obtient une séquence trop longue :

`5,14,23,32,41,50`

alors que si on tape :

`somme5(30)`

On obtient :

`5,14,23`

Régle
Dans un programme, si on veut utiliser `=<` pour modifier une liste `L` ou une séquence `LL`, il faut faire attention à l’initialisation.
Par exemple, pour initialiser

- `L` à la liste vide, on tape :
  `L:=[seq(0,0)]` ou `L:=[0$0]` ou `L:=copy([])` car `[seq(0,0)]` ou `[0$0]` désigne une liste qui va se créer à chaque exécution du programme.
- `LL` à la séquence `NULL`, on tape :
  `LL:=seq(0,0)]` ou `LL:=0$0` ou `LL:=copy(NULL)` car `seq(0,0)` ou `0$0` désigne une séquence qui va se créer à chaque exécution du programme.

Il faut donc utiliser `=<` avec précautions car tous les objets pointant sur cette matrice seront modifiés.