GEL je jazyk s dynamickým rozsahem platnosti. Co to znamená hned vysvětlíme. Je to to, že normální proměnné a funkce mají dynamicky vymezenou platnost. Výjimkou jsou proměnné parametrů, kterou jsou vždy globální.
Podobně jako většina programovacích jazyků, i GEL má různé typy proměnných. Když je proměnná normálně definována ve funkci, je viditelná z této funkce a ze všech funkcí, které jsou z ní volány (všechny kontexty s vyšším číslem). Například předpokládejme, že funkce f
definuje proměnnou a
a pak volá funkci g
. Potom se funkce g
může odkazovat na proměnnou a
. Ale jakmile dojde k návratu z funkce f
, platnost a
zaniká. Např. následují kód vypíše 5. Funkce g
nemůže být volána z nejvyšší úrovně (mimo funkci f
, protože proměnná a
pak není definována).
function f() = (a:=5; g()); function g() = print(a); f();
Pokud definujete proměnnou uvnitř funkce, přepíše jinou proměnnou definovanou ve volající funkci. Například upravíme předchozí kód a napíšeme:
function f() = (a:=5; g()); function g() = print(a); a:=10; f();
Tento kód bude stále vypisovat 5. Ale když zavoláte g
mimo funkci f
, dostanete ve výpise 10. Všimněte si, že nastavení a
na 5 uvnitř funkce f
nemění hodnotu a
ve nejvyšší (globální) úrovni, takže když si nyní ověříte hodnotu a
, bude stále 10.
Argumenty funkce jsou úplně stejné jako proměnné definované uvnitř funkce vyjma toho, že jsou inicializovány na hodnotu, která je funkci předána. Kromě této jediné věci se s nimi zachází úplně stejně, jako se všemi ostatními proměnnými definovanými uvnitř funkce.
S funkcemi je zacházeno stejně jako s proměnnými. Proto také můžete lokálně předefinovávat funkce. Normálně (v nejvyšší úrovni) nemůžete předefinovávat chráněné proměnné a funkce. Ale lokálně to udělat můžete. Uvažujme následující situaci:
genius>
function f(x) = sin(x)^2
= (`(x)=(sin(x)^2))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
Funkce a proměnné definované v nejvyšší úrovni jsou považovány za globální. Jsou viditelné odkudkoliv. Jak již bylo řečeno, následující funkce f
nezmění hodnotu a
na 5.
a=6; function f() = (a:=5); f();
Občas je ale nutné nastavit globální proměnnou uvnitř funkce. Když je takové chování zapotřebí, použijte funkci set
. Předáním řetězce nebo identifikátoru s uvozovkou do této funkce se nastaví globální proměnná (v nejvyšší úrovni). Například pro nastavení a
na hodnotu 3 byste mohli zavolat:
set(`a,3)
nebo:
set("a",3)
Funkce set
nastavuje vždy globální proměnné v nejvyšší úrovni. Neexistuje žádný způsob, jak nastavit lokální proměnnou v nějaké funkce z podřízené funkce. Pokud něco takového potřebujete, musíte jedině použít předání reference (odkazu).
Viz také funkce SetElement
a SetVElement
.
Takže sesumírováno do technického jazyka: Genius pracuje s různými očíslovanými kontexty. Nejvyšší úroveň je kontext 0 (nula). Kdykoliv se vstoupí do funkce, je kontext zvýšen a když se funkce opouští, je kontext snížen. Funkce nebo proměnná je vždy viditelná ze všech kontextů, které mají vyšší číslo. Když byla proměnná definována v kontextu s nižším číslem, má nastavení této proměnné vliv na vytváření nové lokální proměnné v aktuálním čísle kontextu a tato proměnná bude nyní viditelná ze všech kontextů s vyšším číslem.
Existují i skutečně lokální proměnné, které nejsou vidět nikde jinde, než v aktuálním kontextu. Rovněž při vracení funkcí hodnotou je možné odkazovat na proměnnou, která není viditelná z vyššího kontextu a to může být problém. Viz oddíl Skutečně lokální proměnné a Vracení funkcí.