Archiv pro štítek: dynamický rozsah platnosti

Lexikální a dynamický rozsah platnosti proměnné

Až budete příště pracovat ve svém oblíbeném programovacím jazyku, pozastavte se na chvíli nad tím, že principy, které tak již bezpečně dobře znáte, nemusí platit všude. Řeč bude na následujících řádcích o rozsahu platnosti proměnné. Uvažovat lze přitom dva modely — lexikální a dynamický rozsah.

Lexikální rozsah platnosti proměnné

Následujcí chování vám bude dobře známé. Používá jej totiž většina soudobých programovacích jazyků. Pokud se v nich rozhodnete aplikovat libovolnou proceduru obsahující ve svém těle proměnou neinicializovanou v lokálním prostředí této procedury, hledá se hodnota (vazba) proměnné v prostředí vzniku procedury. A co si představit pod pojmem prostředí vzniku procedury? Jde o prostředí nadřazené tomu lokálnímu. Důsledkem toho pokud v proceduře použijeme proměnnou, jejíž hodnota není v těle inicializována, je nutno vazbu hledat výše, kde s největší pravděpodobností narazíme na příslušnou globální proměnnou a z ní hodnotu vyčteme. Pokud by zde náhodou taková proměnná nebyla, nezbude než nahlásit chybu — proměnná totiž neexistuje.

Abychom to lépe pochopili, podívejme se nyní společně na komentovaný příklad:

(define test
  (lambda (y)
    (lambda (x)
      (+ y x))))

(define y 100);v globálním prostředí máme y = 100

(define f (test 20));vzniká procedura, nyní máme y = 20
(f 10);aplikace procedury, za x dosadíme 10 a spočítáme 20 + 10 = 30

;procedura ví, že má sečíst y a x
;hodnotu pro x zná (je to 10), tato hodnota byla předána v argumentu
;nyní je třeba zjistit hodnotu pro y, ta se totiž v lokálním prostředí nevyskytuje
;procedura tedy začíná hledat v "prostředí vzniku procedury", to je to prostředí, které je nadřazené tomu aktuálnímu
;v tomto nadřazeném prostředí je nalezeno kýžené y (s hodnotou 20)
;procedura sečte 20 + 10 a vrátí 30
;hodnota y = 100 v globálním prostředí je v tomto případě směle ignorována

Dynamický rozsah platnosti

A teď si představme, že by se hodnoty proměnných hledaly úplně jinak, konkrétně v prostředí aplikace procedury. Nutno podotknout, že tuto metodu téměř nikdo nepoužívá, ale existují výjimky. Než se podíváme na příklad, řekněme si, jaká je hlavní potíž tohoto přístupu — hodnoty proměnných zjistíme až za běhu programu, čímž stoupá časová náročnost ladění a hledání chyb.

(define test
  (lambda (y)
    (lambda (x)
      (+ y x))))

(define y 100);v globálním prostředí máme y = 100

(define f (test 20));vzniká procedura, nyní máme y = 20
(f 10);aplikace procedury, za x dosadíme 10 a spočítáme 100 + 10 = 110

;procedura ví, že má sečíst y a x
;hodnotu pro x zná (je to 10), tato hodnota byla předána v argumentu
;nyní je třeba zjistit hodnotu pro y, ta se totiž v lokálním prostředí nevyskytuje
;procedura tedy začíná hledat v "prostředí aplikace procedury"
;v tomto aktuálním prostředí se y = 100
;procedura sečte 100 + 10 a vrátí 110