Interpretrovane jazyky
Obsah:
Ja vim ze si hodne lidi mysli:ja umim cecko kdo umi vic. Ale to je
chyba! Ja nerikam, ze by se melo prestat psat v cecku. Programy vnem
jsou nejlepsi. Ale interpretrovany jazyky se hodi na moc jinych
zajimavych veci hlavne proto ze se daji specializovat. Je mnohem
jednodussi spoustet programy shelem, nez mit na prikazove radce nejaky
skoro kompiler cecka. Hodne lidi dela ruzne toolkity na psani her,
nejake graficke programky jako generatory fraktalu, nebo cadiky apod.
Takovy programovaci jazyk rozsiri schopnosti takoveho programu 1000
krat! Proste dela z amaterske hracky profesinalni vykony nastroj! Ono
psat ve specializovanem jazyce je vetsinou jedodussi rychlejsi a
odolnejsi proti chybam.(typickym prikladem je emacs,abuse nebo autocad)
Treba nextep ma tak zajimave prostredi protoze se ridi postscriptem.
Tiskarny rizene programovacim jazykem jsou take lepsi nez ty co
chroustaj bitmapy atd. Proste programovaci jazyk obcas vyleze i tam kde
by jste ho necekaly. Obecne veci z programovacim jazykem zastaravaji
pomaleji, protoze se daji rozsirovat bez nejakych drastickych zasahu.
Vetsina lidi se psani interpretru boji. Argumentuji tim ze psat
interpretr je moc prace, ze je to zbytecne apod. Ale ono to je tak
jednoduche! Staci mit jenom dobry navrh!(nebo pouzit nejaky hotovy-treba
tcl)
Proto jsem se rozhodl napsat par skolicek o tom jak to v takovych
dobrych interpretrech chodi. Oni jsou vlastne vsichni stejni. Kdyz
clovek pochopi zaklad nauci se delat skoro ve vsem a tak ty dobre a
vykone toolkity nejen psat ale i pouzivat :) (Ja osobne jsem se naucil
tcl/tk,lisp,cmlisp,clos,STk a prolog za tyden!)
Ja delim jazyky nejen na interpretrovane a kompilovane ale jeste na dve
skupiny. Do prvni skupiny patri treba:
C, C++, Pascal, Assembler, Basic, Shell, CShell, Ada, Perl, Fortran, Awk, postscript,
cobol atd.
A do druhy treba:
TCL/Tk, Scheme, Prolog, common lisp, cmlisp, castecne objective c, elisp, autolisp,
RTL, smalltalk atd.
Tak a ted schvalne jestli uhadnete podle ceho se to deli :) Na prvni
pohled je videt ze vetsina kompilovanych jazyku patri do prvni skupiny.
Jsou tam taky ostatni klasicke jazyky jako basic a fortran. Tedy v prvni
jsou klasicke jazyky. Kdyz vyndame kompilovane
zbude:Basic,Shell,Cshell,Perl, postscript.
Tyto jazyky maji par
spolecnych rysu: Je relativne tezke je interpretrovat (kouknete se na
zdrojaky bashe) Jsou omezene a protoze interpretr je dlouhy a slozity
tak i pomaly. Jsou nerozsiritelne(treba do cecka pridat objekty znamena
predelat cely kompiler, do basicu funkce je stejny problem) Jejich
syntaxe je slozita. Presto, ze na pohled vypadaji jednoduse jsou
vlastne strasne zaludne nebo neelegantni(kdo z vas muze rict ja umim
100% cely bash) Proto je povazuju za spatne jazyky a nebudu je
rozebirat.
Asi jste uhadli ze se vam snazim vysvetlit ze druha skupina
je mnohem lepsi. Budu radsi predpokladat ze neznate ani jeden z
vypsanych jazyku. (ostatne donedavna jsem je taky neznal) Tyto jazyky
maji hodne spolecneho:Pokud to uz jsou intepretrovany jazyky neni mozne
napsat jejich kompiler. Lidi se jich boji. Jenom u nekterejch maji pocit
ze toho umi vic nez by cekali(napriklad simcity napsany v tcl nebo cele
slozite nadstavby pro autocad napsane v autolispu) Jsou to jazyky
strasne jednoduse rozsiritelne-treba Tk-okenkova nadstavba tcl je mnohem
jednodussi nez vpodstate stejny motif pro cecko. Kazdemu doporucuju
downloadnout abusi(ze sunsite/games/video) aby se podival jak na 200KB
radcich lispu a jejich vlastnim interpretru ze specialnim rozsirenim na
herni grafiku dokazali udelat skvele promakanou hru. A to je teprve
zacatek! Z takovym toolkitem udelat novou hru je hracka-sam jsem si to
vyzkousel. Vsechny ty jazyky maji spolecny zaklad a tim je (nelekejte
se) lisp. No proste v ty prvni skupine jsou jazyky jejiz autori neumeli
lisp nebo potrebovali kompilovanej jazyk. V ty druhy jsou lispove
zalozene.
nee!!! nevypinat, neodhlasovat se, nezvracet stoji to za to cist dal
lisp neni stejne historicka nesmyslnoust jako fortran,basic nebo cobol
lisp je skvely jazyk! ma jenom jednu nevyhodu: vypada _ODPORNE_ :)
Jeho vykonost dokazuje treba i to ze v dobe kdy zacinal basic lisp mel
uz funkce V dobe standarizace ansi C lisp byl uz objektovej. Dneska kdyz
objective C ho pomalu dohani v objektech(c++ objekty se nedaji srovnavat
z lispovyma) Lisp uz vese bezi na paraelnich masinach. A to vsechno bez
nejakych zasadnich zasahu do interpretru!(lispovskej interpretr ze v
zasade nezmenil od roku 1955 tedy 40 let!)
Proste ten kdo umi lisp uz nikdy nemuze uvazovat nad tim ze by do svyho
programu udelal interpretr basicu proto je v druhy skupine tolik jazyku.
Vzhledem k tomu ze lisp umi maximalne 10% programatoru. Prumerny
programator co umi lisp udela v prumeru 10 vic docela dobrych
programovacich jazyku nez tech zbylych 90% :)
Kdo umi lisp se uz bez problemu nauci vsechny zbyly jazyky ve skupine 2
proste tim ze zjisti jak se zmenila syntaxe a co tomu jazyku
chybi(jediny jazyky co maj neco navic proti lispu jsou smalltalk a mozna
prolog) ostatni jazyky nesahaji lispu ani pokolena a daj se do neho
prelozit(i cecko se da prelozit do lispu relativne snadno obracene to
dre)
Lisp ma taky tu vyhodu ze jeho interpretrace je tak jednoducha ze se
stavely (a dodneska stavi) stroje co maji nejdulezitejsi cast
interpretru lispu vestavenou v procesoru a pouzivaji predkousany lisp
jako assembler-takove masiny jsou vetsinou salove a vyrabi je
IBM,Xerox,TMC atd.. Pouzivaji se hlavne na vyzkum umele inteligence. Pro
ktery byl lisp na MITu vyvinut. Lisp je mnohem chytrejsi nez cecko!
Proto se pri vetsich projetkech vyplati napred udelat interpretr
specializovaneho lispu a potom zbytek udelat v nem (znova emacs a abuse)
No doufam ze jsem vas dost naladil a ze muzu vysvetlit zakladni navrh
lispu. Lisp interpretr se zklada ze tri casti:
The lisp reader(ctecka),The Lisp evaulator(vyhodnocovac-to maj ty procesory vsobe),
The lisp writer(vypisuje)
Reader funguje tak, ze dostane jako vstup stringovy objekt a na vystupu
je jiny nacteny objekt. Reader musi sam zjistit jakeho typu vstup je a
nejak z nim nalozit. Lispovske objekty nejsou v zadnem pripade normalni
objekty protoze lisp neni objektovy. Objekt jsou nejaka data. Objekt
muze spadat do nekolika typu-takze to neni jako v cecku ze char je char
ale je tu moznost se zeptat objektu jestli se snim da pracovat jako z
charem.
Lisp potrebuje nekolik typu:
atomicke(zakladni typy) Ty muzou byt ruzne podle toho na jakem stroji se
lisp interpretruje. Protoze dnesni pocitace porad nejsou nic jineho nez
drtice cisel uzakladni typ co maji lispy byva number. Typ number vetsinou
jeste muze byt integer,float atd.. Mame tedy cisla. Vysvetlim na
integeru zakladni funkci lispovskeho interpretru: reader dostane
vstup:123 zjisti ze to je cele cislo tedy typ integer a vytvori
integerovy objekt. Dale se na nej vrhne evaluator. Ten se zepta jestly
je objekt typu atomic(to je taky protoze integer je zaroven
number,atomic a kdovi co jeste) a zajasa! Z atomickyma typama se nemusi
nic delat-jsou self evaluating tedy posle objekt dal-writerovi ten
zjisti ze je to integer a vypise ho jako integer tedy 123. Kdyz tedy na
prikazovou radku lispovskyho interpretru date 123 vypise se 123. Kazdy
lispovky objekt ma svoji psanou podobu. Nekteri se daji i cist potom
jejich ctena podoba je stejna jako psana. Ze psane podoby se da urcit
typ tedy float 123 se vzdy vypise 123.0 .No ale z takovym jazykem by nic
neslo delat :)
symbol je libovolna posloupnost znaku co se nepodari urcit jako neco
jinyho. Jednim ze zakladnich symbolu je promena. To je objekt ktery ma
svoje jmeno (treba blb) a pri vyhodnocovani se nahradi jinym objektem co
je jeho hodnota. Promene se nemusi nijak deklarovat. Protoze obsahuji
objekty vi svuj typ,muzou ho za behu menit. Jejich hodnoty jsou ulozene
v enviromentu-enviromenty se muzou za behu menit tedy treba lokalni
promena se ulozi do novyho enviromentu ktery dedi starej enviroment.
Enviroment je dalsi dulezitej lispovskej objekt. Jsou tu jsete dva
specialni symboly a to nil co se pozuiva jako false nul atd a t co se
pouziva jako true. Ty jsou zvlastni tim ze se vyhodnocuji taky samy do
sebe. Kdyz napisete t na vstup interpretru t se taky vypise
Nejdulezitejsi lispovskej objekt je cons. Cons je objekt co se sklada ze
dvou objektu a zapisuje se: (prvni.druhy) tedy (123.444) je objekt co se
sklada z objektu typu integer 123 a 444. Prvnimu se rika car a druhymu
cdr to je proto ze pocitac kte mitaci delali lisp mel takovy registry.
Protoze cons muze obashovat libovolnej objekt cons (nil.t) nebo (nil.2)
a tedy i ((1.2).(3.4)) jsou spravne. Posledni priklad je cons co
obsahuje dve cons.
Protoze se consy takhle daji neomezene vnorovat jde udelat nasledujici
konstrukce:
(1 . (2 . (3 . (4 . (5 . nil))))
to je moc zajimava vec. Car vzdy ukazuje na objekt a Cdr na dalsi cons.
Posledni cdr ukazuje na nil. To je naprosto typicky jednosmerne vazany
seznam tedy list. A to je jedna z nejdulezitejsich lispovskych
konstrukci (lisp se podle toho i jmenuje- znamena list procesing
language) Aby se usetrily zavorky kdyz cdr ukazuje na cons dela se
skraceny zapis: (1.(2.3)) se da napsat taky jako (1 2.3). nil na car se
nepise tedy listy se daji psat taky jako:
(1 2 3 4 5 . nil) a (1 2 3 4 5)
Tenhle zapis se pouziva protoze je nejkratsi. List samozdrejme muze
obsahovat vsechny typy objektu tedy i dalsi listy nebo consy:
(1 nil (1 2 3) (2 . 3))
je taky spravne ale je to trochu divne.
Napisem tedy na vstup (1 2 3 4 5) vytvorime list o 5 objektech ktery se
nam ale nevypise protoze lisp ho nebude schopny vyhodnotit.
Vyhodnocovani listu totiz probiha tak, ze eval zjisti jestli prvni prvek
je funkce a kdyz ano spusti ji a zbyle casti listu ji preda. Jak jste
asi uhadli funkce je dalsi dulezity lispovsky typ. Ta zase muze byt
ruznych typu:nejzakladnejsi jsou subroutine a specialni forma
soubroutine je normalni funkce zabudovana do interpretru(tedy napsana v
cecku) Nez se zavola list se zpracuje tak, ze vsechny jeho clenove se
vyhodnoti a vyhodnocenej list se ji preda. Typicka subr je + coz je fce
pro praci z objekty typu number trdy:
(+ 1 2) zavola subroutinu + a preda ji parametry 1 2 ta je pochopitelne
secte a jako vysledek vati ciselny objekt 3 ktery se vypise-tedy list (+
1 2) po vyhodnoceni je 3 a to se vypise. Protoze se parametry pred
zavolanim fce vyhodnoti muzeme napsat i: (+ 1 (+ 3 4))
a lisp to precte jako list co obsahuje subr + integer 1 a cons ktera je
vlastne list(+ 3 4) eval zjisti ze prvni prvek listu je subr zavola se
tedy rekurzivne na 1-vyhodnoti se do 1(atomic) a na (+ 3 4) kde se
proces bude opakovat-vyhodnoti se do 7 tedy vznikne list (+ 1 7) a
provede se subr + a vypise se vysledek:8
Tady je uz videt moc dulezita vec v lispu a to ze neni rozdil mezi kodem
a datama. Program je nekolik listu(spustitelne listy se jmenujou formy)
za sebou. Tedy se da ulozit do promene a potom na nej zavolat eval (eval
je primitivni funkce co vola the lisp evaulator ) treba takto: (eval a)
a pokud je v a nejaky pekny kod tak se provede
To je sice pekne ale furt tu chybi jakakoliv sance ridit chod programu-
vstup se vyhodnocuje objekt po objektu a posledni vysledek se vypise.
Kdyz se zamyslite kod jsou vlastne data-normalni list a tak ho muze brat
funkce jako parametr. To presne je to co je na lispovi revolucni a
krasne nejsou treba zadne "conditional construct" tedy jazykove
konstrukce typu if,for,while apod jak tomu je v cecku. If se da napsat
jako primitivni funkce co vyhodnoti svuj prvni parametr a pokud je t
vyhodnoti svuj druhy a pokud ne treti. Jediny problem je v tom ze kdyz
volame funkci, parametry se vyhodnoti to znamena ze kdyz by mela jako
parametr list ten by se provedl a funkce by dostala jenom vysledek:
(if (= 1 2) (+ 2 4) (+ 5 6)) by spravne melo vyhodnotit prvni parametr
jako nil a tedy vyhodnotit posledni a vysledek by mel byt 11 k
vyhodnoceni prostredniho parametru by nemelo dojit-tady by to nevadilo
ale kdyby prostredni parametr neco vypisoval-byl treba(print 1) vypsalo
by se to taky. ale funkce dostane jako parametry:
(if nil 6 11) jsou tedy vyhodnocene predem a to necheme. Jak to udelat?
Od toho jsou specialni formy. Ty se lisi od funkci tak, ze jejich
parametry se nevyhodnocuji ale nechaji se tak jak jsou-neco jako
ceckovsky makra Takova specialni forma muze byt treba loop co jako prvni
parametr vyzaduje cislo-tenhle parametr si evalem vyhodnoti a ostatni
parametry jsou formy ktere se provedou tolikrat kolik vyslo z evalu tedy
takova forma by se mohla volat takto:
(loop 2 (+ 1 2)) a uz je tu smycka co dvakrat secte 1 2 a nakonec
celkova hodnota je tri. udelat treba takovou formu na if je hrackou
potom zapis:
(if t (+ 0 1) 2) vrati 1 a (if nil (+0 1) 2) vrati 2.
A to je vse pratele! verte nebo ne vsechno ostatni se v lispovi da
udelat pridavanim novych typu,primitivnich funkci a specialnich forem.
Pridavani novych funkci a forem je jednoduche. Dobry interpretr lispu je
open takze pridat ceckarsky kod neni problem. V cecku vetsinou existuje
typ Object a vsechny ceckarsky funkce dostavaji objekt z listem ktery
obsahuje jejich volani. Takze napsat funkci + je legrace kdyz uz mame
funkce na vycisleni ciselneho objektu a praci z listem-proste vemem
vsechny cleny listu krome prvniho,vycislime je, secteme a vysledek
ulozime zpet do nove vytvoreneho objektu.
Pridavani novych typu je brutalnejsi protoze to vyzaduje jeste napsani
cteci a zapisovaci funkce a pridani novych primitivnich funkci nebo
rozsireni existujicich. To je celkem pracne nastesti nove typy se
pridavaji minimalne. (asi tak stejne casto jako pridavate novy typ do
kompileru cecka-long long int apod. proste je to vec vyvojaru
interpretru ne jeho uzivatelu) Tento problem resi smalltalk tim ze typy
jsou objekty ale ten ma zase jiny problemy a tak lisp povazuju za lepsi
jazyk. Ale i toto jde udelat BEZ zasahu do interpretru. Jak to casem
ukazu.
hlavni volani lispu-tedy eval print a read
zakladni prace z typy:
number: aritmetika,funkce jako sin,cos,vsechny funkce musi podporovat
prevody v pripade ze je vice ciselnych typu-treba (+ float integer)
vyjde float atd..
promeny: nastavovani-nejcasteji setq nastaveni setq na nil vymaze
(setq a 1) nastavi a na 1
vytvareni enviromentu(lokalni promene)-nejcasteji specialni forma let:
(let (a b) (setq a 1)(setq b 1))
vytvori novy enviroment z promenou a-prvni parametr je vetsinou
listing promenych co se maji dat do noveho enviromentu-treba (a b)
vytvori envoroment z promenejma 'a' a 'b' a provede ostatni parametry
a nakonec zrusi enviroment. Samozdrejme ze let vola nejaky podfunkce
ale let je celkem standard. Vysledna hodnota je 1-hodnota posledni
vycislene formy: (setq b 1)
t,nil: zakladni boolienovske operace a taky test schodnosti-funkce eql
ktera urci jestli obaje jeji parametry jsou schodne a equal ktera
oba paremetry porovna-treba kdyz mate dva listy (1 2 3 4) a druhy
(1 2 3 4) ty nejsou eql-jsou jinde v pameti ale jsou equal maji
stejnej obsah.
consy: funkce cons ktera svoje dva parametry da do consy:
(cons 1 2) vypise (1.2)
funkce car ktera vraci car cast consy:
(car `(1 2 3)) vrati 1
funkce cdr ktera vraci cdr cast consy
(cdr `(1 2 3)) vrati (2 3)
subroutiny/specialni formy: V zasade neni nic treba.
Jeste je dulezita sada funkci ktera zjisiti jestli je prametr nejakeho
typu vetsinou se jmenuji nejak jako:
integer? float? variable? atomic? symbol?
tedy
(atomic? 1)
vrati t
Primitivni funkce:
if,smycka z podminkou nakonci a nazacatku a quote
quote je funkce co zajisti ze jeji parametr se nevyhodnoti:
na prikazovou radku lispu nejde napsat:(1 2 3) protoze list nejde
vyhodnotit ale kdyz napisete (quote (1 2 3)) vysledek je (1 2 3)
to je treba kdyz potrebujete do promene ulozit list:
(setq a (quote (+ 1 2)))
vypise (+ 1 2) tedy promena a obsahuje formu
a
vypise (+ 1 2)-obsah promene kdyz chceme formu vyhodnotit dame:
(eval a)
vypise 3
protoze jsou lispari lini (quote 1) se da napsat jako '1
Pokud jste postrehli napsanim funkce eval,read,write a nekolika
primitivnich funkci a nekolika forem jsme ziskali celkem mocny jazyk.
Veskera interpretace je strasne snadna-volani read a eval a nakonec
write. Nic se nemusi ukladat do pameti jako v basicovi-co se jednou
vyhodnoti muze byt zapomenuto. Zadna slozita syntaxe jako v cecku nebo
++ kde jenom lexikalni analyza je 10 tisic radku dlouhy program. Proste
zakladni interpretr lispu se vejde do 40 kilovyho programu.
Ted vam ukazu jeho hlavni silu-rozsiritelnost.
Treba chceme zaridit aby se daly psat nove funkce nejen v cecku ale i v
lispovi. Proste udelat z lispu strukturovanej jazyk. Takhle to vyresili
priblizne v 60 letech:
napsali jednoduchou funkci funcall ktera bere jako prni parametr
lispovskou funkci a jako dalsi parametry jsou parametry pro tu funkci-
lispovska funkce je list z nasledujicim obsahem:
(lambda (list parametru) nejaky formy-telo funkce)
(prvni prvek musi byt symbol lambda-ten urcuje ze list je funkce lambda
se jmenuje podle slavne A. Crunchovy lambda-kalkulu kterou napsal ve
40.letech)
Navratova hodnota funkce je hodnota posledni vyhodnocene formy.
treba funkce inc co vraci hodnotu parametru zvetsenou o 1
(lambda (a) (+ a 1))
(a) znamena ze funkce ma jeden parametr-a
(+ a 1) je forma co se vyhodnoti-pricte jedna k parametru funkce a protoze
je posledni jeji hodnota bude funkci vracena
tedy
(funcall '(lambda (a) (+ a 1)) 1)
vrati 2 (vrati budu dal psat jako -->)
Toto je volani tzv. anonymni funkce tedy funkce beze jmena. Pri beznych
konstrukcich to nema moc uzitku lepsi je funkci priradit nejakymu symbolu:
(setq inc `(lambda (a) (+ a 1)))
--> (lambda (a) (+ a 1))
' tam musi byt aby nedoslo k vyhodnocovani listu tedy k chybe.
No a ted si muzeme pekne funkci zavolat:
(funcall inc 1)
--> 2
No a strukturovanej jazyk je na svete! nebylo to snadny? Samozdrejme ze
to je jen zaklad a z funkci se da vydrit mnohem vic. Protoze za veskery
zpracovani parametru zodpovida funcall je mozny treba rozsirit listing
parametru o specifikovani optionu. bezne se pouzivaji tyto optiony:
- & optional
- volitebny parametr da se nastavit i standartni hodnota promene
- & rest
- kdyz je to nakonaci zbyly parametry se daji do listu-volitebny pocet
parametru
- & key
- specialni format volani:
(setq a (lambda (& key (x t) y) (cons x y)))
(funcall a) vrati (t.nil)
(funcall a :x 1) vrati (1.nil)
(funcall a :x 1 :y 1) vrati (1.1)
- & aux
- zabrani vyhodnoceni vyrazu pred zavolanim funkce-umoznuje psat makra
tady vlastne novy specialni formy-muzete si udelat ceckarsky for
nebo treba i pascalacky kdyz se vam zachce
Vetsina definuje novy typ pro lambda listy(funkce) aby se nemuselo psat:
(funcall a 1) ale stacilo (a 1) takze se schoval rozdil mezi vestavenyma
funkcema a novyma.
Common lisp ma specialni formu defun ktera sama vytvori lambda list.
Volani:
(defun (list parametru) formy)
A rovnou priradi spravnej typ takze potom jde skracene volani(bez funcalu)
takze inc se dela:
(defun inc (x) (+ x 1))
Common lisp nema & aux ale pridava jeste defmacro co udela to same jako
defun ale prvnim clenem listu neni lambda ale macro. Macro se od funkce
lisi v tom ze jeho parametry se nepredspracovavaji (jako u specialnich
forem) a vola se pomoci fce expand
Taky se da pridat funkce return ktera prerusi provadeni apod.
no proste fantazii se meze nekladou
jak asi vidite lisp ma takovy moznosti z funkcema o kterych se cecku ani
nesni- jednoduche predelavani funkce za behu,mnohem lepsi parametry Nove
funkce se muzou vytvaret za behu atd... Kod kterej provedete si muzete
za behu vytvaret Proste kam se hrabe cecko! :)
Taky je dulezity podotknout ze jako ma cecko knihovny vetsina lispovych
interpretru ma taky rozsahly knihovny v lispu co se nahravaji nazacatku.
(do takovych knihovnich funkci patri treba ceckarsky for,ruzna prace z
listy (zjistovani delky,spojovani apod) prace ze strukturovanymy
typy,objektova nadstavba a fura dalsich veci co je nermalne soucast
interpretru v podstate jakakoliv primitivni funkce nebo specialni forma
jde v lispu nejak opsat jinyma funkcema a zalezi jen na autorovy ktery
implementuje v lispovi a ktery v cecku) Bezny interpretry lispu maj asi
300 Kb ceckovskyho kodu a 5MB lispovskych knihoven ktery vetsinou nejak
predkousou pro rychlejsi nahravani. Take v lispu jde napsat konstrukce
autoload ktera dohraje funkci kdyz se pouzije (napisete (autoload ) a fce autoload vytvori funkci se jmenem jmeno
funkce ktera po svem spusteni vincludi (include jde taky napsat v
lispu-pomoci read a eval) prislusnej fajl tim se predeklaruje na
spravnou funkci a rekurzivne se spusti.Samozdrejme ze tech 300Kb cecka
je hodne-je to proto ze autori maji tendenci prepisovat lispovsky funkce
do cecka-kazdej interpretr zacina asi ze 40Kb a cim vic starne tim je
toho vic v cecku nakonec ceckovsky zdrojaky dosahujou 3MB Ale je to
jenom kvuli rychlosti.
Jediny problem na ktery jsem pri psani lisp interpretru narazil bylo
kdy uvolnovat objekty z pameti-musel jsem udelat u kazdeho objektu citac
kolik objektu na nej ukazuje a kdyz je citac na 0 objekt zrusit.
Promene se ve vetsine lispu rusi prirazenim nil Tento problem je v lispu
zname a jmenuje se garbage collection a ma hodne jinych reseni tohle se
mi zda nejrychlejsi a nejjednodusi. Je to sice krize si to v celym
interpretru ohlidat ale jde to.
Tento soubor je soucasti rozsahle sbirky skolicek na
http://www.ucw.cz/~hubicka/skolicky
Take si muzete prohlidnout jeji puvodni textovou podobu
Nebo mi mailnout na
hubicka@ucw.cz
Copyright (C) Jan Hubicka 1995