Vnútorná reprezentácia symbolov v lispe

Pre každý symbol v systéme Lispu existuje jednoznačné zobrazenie z jeho označenia (meno) do objektu v pamäti. Dva a viac symbolov s rovnakým menom sa vždy odvolávajú na rovnaký objekt v pamäti. Ale dva rovnako vyzerajúce zložené s-výrazy (s rovnakou štruktúrou), nemusia reprezentovať (a väčšinou ani nereprezentujú) ten istý objekt v pamäti.

Na prednáškach sme spomínali predikát EQ. Má dva argumenty a testuje ich zhodnosť. EQ porovnáva atómy. Stačí testovať zhodnosť smerníkov na ich reprezentáciu v pamäti. V prípade čísel závisí výsledok operácie EQ od konkrétnej implementácie Lispu. Niekedy EQ pre čísla nie je definovaná a treba použiť funkciu =.
Takže

(EQ 'A 'A) --> T,
lebo dva výskyty atómu 'A sa reprezentujú v pamäti rovnako (zhodnými smerníkmi).
Na druhej strane
(EQ (CONS 'A 'A)  (CONS 'A 'A)) --> NIL,
lebo dva výskyty bodka dvojice (A . A) sa reprezentujú dvoma rôznymi pamäťovými miestami. EQ vráti T pre dve bodka dvojice (príp. zoznamy), ak ich reprezentácia v pamäti je rovnaká. Napr. ak atóm X je naviazaný na hodnotu (A . A), potom
(EQ X X) --> T.
Nech hodnoty atómov ZOZ-1, ZOZ-2 a ZOZ-3 sú naviazané takto:
 > (SETQ ZOZ-1 '(A B C))
 (A B C)
 > (SETQ ZOZ-2 '(A B C))
 (A B C)
 > (SETQ ZOZ-3 ZOZ-2)
 (A B C)
 
Zoznamy ZOZ-1 a ZOZ-2 sa reprezentujú v pamäti rôznymi pamäťovými bunkami, na rozdiel od zoznamov ZOZ-2 a ZOZ-3. Teda:
 > (EQ ZOZ-1 ZOZ-2)
 NIL
 > (EQ ZOZ-2 ZOZ-3)
 T
 > (EQUAL ZOZ-1 ZOZ-2)
 T
Symboly sa v Lispe reprezentujú ako zložené objekty (záznamy). V Common Lispe symbol predstavuje záznam s položkami, ktoré predstavujú smerníky na meno symbolu, hodnotu, funkčnú väzbu, zoznam vlastností. Jednotlivé položky sa sprístupňujú jednoargumentovými funkciami SYMBOL-NAME, SYMBOL-VALUE, SYMBOL-FUNCTION a SYMBOL-PLIST.

Každému symbolu možno priradiť iba jednu hodnotu. Vtedy symbol slúži ako globálna premenná. Symbol možno použiť aj na pomenovanie lokálnych premenných, jeho väzba na hodnotu sa však tým nezmení. Hodnota symbolu závisí od kontextu, v ktorom sa požaduje:

 > (SETQ X 57)
 57
 > (DEFUN NOVA-PREM (X)
       (LIST 'HODNOTA 'X 'JE X))
 NOVA-PREM
 > X
 57

 > (NOVA-PREM 'HOCICO)
 (HODNOTA X JE HOCICO)
 > X
 57
Funkčná väzba symbolu predstavuje označenie funkcie daným menom. Môže ísť o vstavané (väčšinou kompilované) funkcie systému Lispu alebo používateľom definované funkcie. V prvom prípade funkčná väzba predstavuje smerník na skompilovaný tvar funkcie v pamäti a v druhom prípade lambda výraz, ktorý sa reprezentuje pomocou cons buniek.
 > (SYMBOL-FUNCTION 'CONS)
 #
 > (DEFUN DRUHA-MOCNINA (N) (* N N))
 DRUHA-MOCNINA
 > (SYMBOL-FUNCTION 'DRUHA-MOCNINA)
 (LAMBDA (N) (* N N))
Zoznam vlasností symbolu je tabuľka, v ktorej sú uložené kľúče (mená vlastností) a im priradené hodnoty. Zoznam vlastností je priradený ku každému symbolu a reprezentuje sa zoznamom:
   (kľúč1 hodnota1 kľúč2 hodnota2 .... kľúčn hodnotan)
Hodnoty možno sprístupniť funkciou GET:
   (GET symbol kľúč)
Hodnota daného kľúča sa mení pomocou makra SETF:
   (SETF (GET symbol kľúč) nová-hodnota)
Rovnako možno vytvoriť novú položku zoznamu vlastností:
   (SETF (GET symbol nový-kľúč) nová-hodnota)
A nakoniec položku (kľúč spolu s hodnotou) sa zruší zo zoznamu vlastností funkciou REMPROP:
   (REMPROP symbol kľúč)
Zoznam vlastností možno použiť na priradenie rôznych typov hodnôt danému symbolu. Napr.
 > (SYMBOL-PLIST 'CISLA)
 NIL
 > (SETF (GET 'CISLA 'PI) 3.14159)
 3.14159
 > (SYMBOL-PLIST 'CISLA)
 (PI 3.14159)
 > (GET 'CISLA 'PI)
 3.14159
 > (REMPROP 'CISLA 'PI)
 T
 > (SYMBOL-PLIST 'CISLA)
 NIL
Zoznam vlastností možno použiť aj na definíciu funkcií vymenovaním hodnôt, ak definičný obor je množina symbolov. Dvojice (symbolj, hodnotaj) funkcie F, t.j. F(symbolj) = hodnotaj, možno uchovať buď ako vlastnosti symbolu F pridaním dvojice symbolj hodnotaj do zoznamu vlastností alebo ako vlastnosti symbolu symbolj pridaním dvojice F hodnotaj. Druhý prístup sa hodí najmä vtedy, ak máme niekoľko funkcií s malým a rovnakým definičným oborom. Vyhodnotenie takto definovanej funkcie zabezpečíme v prvom prípade:
     (LAMBDA (FN X) (GET FN X))
a v druhom prípade
     (LAMBDA (FN X) (GET X FN)
Na záver spomeniem ešte funkciu DESCRIBE. Pomocou tejto funkcie možno v prehľadnej forme získať informácie o symbole.
 > (DESCRIBE 'CAR)
 CAR is a SYMBOL
 NAME          "CAR"
 VALUE         #
 FUNCTION      #
 PLIST         (COMPILER::PC-FNDEFS # SETF::SETF-METHOD SEQ::SET-CAR)
 PACKAGE       #

 > (DEFUN SQUARE (N) (* N N))
 SQUARE
 > (SETQ SQUARE 5)
 5
 > (DESCRIBE 'SQUARE)
 SQUARE is a SYMBOL
 NAME          "SQUARE"
 VALUE         5
 FUNCTION      #'(LAMBDA (N) (DECLARE (LAMBDA-NAME SQUARE)) (BLOCK SQUARE (* N N)))
 PLIST         (PKG::SYMBOL-NAME-STRING "SQUARE")
 PACKAGE       #

to Homepage to Teaching to FLP to the Top

Home
Research
Projects
Publications
Books
SCM
Teaching
Links
Last updated:
Mária Bieliková bielik [zavináč] fiit-dot-stuba-dot-sk
Design © 2oo1 KoXo