Variables globales et portée des variables

GEL is a dynamically scoped language. We will explain what this means below. That is, normal variables and functions are dynamically scoped. The exception are parameter variables, which are always global.

Comme la plupart des langages de programmation, GEL possède différents types de variables. Normalement lorsqu'une variable est définie dans une fonction, elle est visible dans cette fonction et à partir de toutes les fonctions qui sont appelées (tous les contextes supérieurs). Par exemple, supposons qu'une fonction f définit une variable a puis appelle la fonction g. Alors la fonction g peut faire référence à a. Mais dès que la fonction f est quittée, la variable a disparaît de la portée. Par exemple, le code suivant affiche 5. La fonction g ne peut pas être appelée à partir du niveau supérieur (en dehors de f puisque a n'est pas défini).

function f() = (a:=5; g());
function g() = print(a);
f();

Si vous définissez une variable à l'intérieur d'une fonction, elle va supplanter toutes variables définies dans les fonctions appelantes. Par exemple, si nous modifions le code ci-dessus et écrivons :

function f() = (a:=5; g());
function g() = print(a);
a:=10;
f();

Ce code affiche toujours 5. Mais si vous appelez g à l'extérieur de f alors la valeur 10 s'affiche. Remarquez que le fait d'initialiser a à 5 à l'intérieur de f ne modifie pas la valeur de a au niveau (global) supérieur donc si vous contrôlez maintenant la valeur de a, elle sera toujours de 10.

Les arguments de fonction sont exactement comme les variables définies à l'intérieur de la fonction sauf qu'ils sont initialisés à la valeur qui a été transmise à la fonction. En dehors de ce point, ils sont traités exactement comme toutes les autres variables définies dans la fonction.

Les fonctions sont traitées exactement comme les variables. Par conséquent, vous pouvez redéfinir localement les fonctions. Normalement (au niveau supérieur) vous ne pouvez pas redéfinir des variables et fonctions protégées mais, vous pouvez le faire localement. Considérons la session suivante :

genius> function f(x) = sin(x)^2
= (`(x)=(sin(x)^2))
genius> function g(x) = ((function sin(x)=x^10);f(x))
= (`(x)=((sin:=(`(x)=(x^10)));f(x)))
genius> g(10)
= 1e20

Functions and variables defined at the top level are considered global. They are visible from anywhere. As we said the following function f will not change the value of a to 5.

a=6;
function f() = (a:=5);
f();

Sometimes, however, it is necessary to set a global variable from inside a function. When this behavior is needed, use the set function. Passing a string or a quoted identifier to this function sets the variable globally (on the top level). For example, to set a to the value 3 you could call:

set(`a,3)

or:

set("a",3)

La fonction set définit toujours au niveau global supérieur. Il n'est pas possible de définir une variable locale dans des fonctions à partir d'un sous-programme. Si c'est nécessaire, vous devez utiliser la transmission par référence.

See also the SetElement and SetVElement functions.

Donc pour récapituler dans un langage plus technique : genius opère avec différents contextes numérotés. Le niveau supérieur est le contexte 0 (zéro). À chaque fois qu'une fonction est entrée, le contexte est augmenté et lorsqu'une fonction est quittée, le contexte est diminué. Une fonction ou une variable est toujours visible à partir de tous les contextes de numéro plus élevé. Si une variable a été définie dans un contexte de numéro plus bas alors attribuer une valeur à cette variable a pour effet de créer une nouvelle variable locale dans le numéro de contexte actuel et cette variable est maintenant visible de tous les contextes de numéro plus élevé.

There are also true local variables that are not seen from anywhere but the current context. Also when returning functions by value it may reference variables not visible from higher context and this may be a problem. See the sections True Local Variables and Returning Functions.