Obsah
1. Interlisp aneb oživujeme dinosaura
3. Interlisp neboli „interactive Lisp“
4. Radikální odklon od předchozích implementací Lispu
5. Ve „stupidních závorkách“ se již neztratíme
6. p-code ve skutečnosti nevznikl pro Pascal
7. Důležitá postava v historii IT: Warren Teitelman
8. Interlisp dostupný pro starší počítačové platformy
9. Pojďme tedy oživit dinosaura
10. Stažení a překlad Interlispu
11. První seznámení s Interlispem
14. Podmínky realizované formami and, or a cond
16. Rekurzivní funkce zkonstruované jak pomocí defineq+lambda, tak i pomocí de
17. Repositář s demonstračními příklady
1. Interlisp aneb oživujeme dinosaura
V poněkud nepravidelně vycházejícím seriálu o rozsáhlém světě Lispovských programovacích jazyků (mezi něž je zařazeno i Scheme a Clojure, i když mezi různými dialekty Lispu existuje mnoho rozdílů shrnutých například zde pro dnes nejpopulárnější varianty) jsme se již seznámili s celou řadou implementací Lispu i Scheme. Kromě úvodního článku se stručnou historií Lispu jsme se zabývali především relativně moderními implementacemi tohoto programovacího jazyka, tj. implementacemi, jejichž interpretry, překladače a popř. v některých implementacích i just-in-time překladače je možné používat i v moderních operačních systémech. Zabývali jsme se i jazyky, které jsou součástí některých používaných a populárních aplikací (typickým příkladem je pochopitelně textový editor Emacs se svým Emacs Lispem neboli Elispem).
Obrázek 1: O dnes popisovaném Interlispu v minulosti vyšlo několik knih. Po MacLispu se totiž jednalo o další široce akceptovaný de facto standard, který byl nahrazen až Common Lispem o desetiletí později.
Jen pro připomenutí si uveďme, s jakými variantami programovacího jazyka Lisp nebo Scheme jsme se již setkali: především se jednalo o projekt nazvaný GNU Guile a taktéž o nástroj TinyScheme. Oba zmíněné projekty nabízí programátorům jak klasickou interaktivní smyčku REPL, tak i možnost vložit (embed) interpret či překladač programovacího jazyka Scheme do dalších nativních aplikací a tím do značné míry rozšířit jejich možnosti (skriptovatelné aplikace, aplikace s podporou pluginů získaných od třetích stran atd.). Zatímco projekt GNU Guile obsahuje jak interpret, tak i překladač (a to relativně dobrý), je TinyScheme v tomto ohledu mnohem jednodušší, protože se jedná o „pouhý“ interpret, ovšem pochopitelně doplněný o automatickou správu paměti a další pro Scheme naprosto nezbytné vlastnosti (podpora uzávěrů, optimalizace tail rekurze atd.).
Obrázek 2: Logo projektu GNU Guile, který se po letech stagnace opět začíná rozvíjet.
Z rozsáhlejších projektů jsme se zmínili o programovacím jazyku nazvaném Kawa, který je zajímavý a potenciálně užitečný hned z několika důvodů. Jedná se totiž o implementaci jazyka Scheme naprogramovanou v Javě a tedy běžící nad virtuálním strojem Javy (JVM). Ovšem současně se v žádném případě nejedná o pouhý primitivní interpret, ale o plnohodnotný překladač jazyka Scheme do bajtkódu JVM. Z benchmarků je patrné, že výsledný kód vůbec není pomalý ale naopak dokáže více než zdárně konkurovat dalším programovacím jazykům, které v současnosti nad JVM existují.
Obrázek 3: Logo projektu Kawa. Kawa je jednou z nejlepších variant lispovského/schemovského jazyka určeného pro běh nad JVM. Pokud z nějakého důvodu vyžadujete rychlejší start aplikací oproti Clojure, může se jednat o velmi užitečný projekt.
A konečně jsme se ve třech článcích zabývali projektem nazvaným Racket, jehož původní jméno bylo PLT Scheme. Samotný programovací jazyk Racketu sice vychází z klasického Scheme, ale je poměrně snadno rozšiřitelný a modifikovatelný, takže vzniklo hned několik jeho variant. Kromě klasického dynamicky typovaného jazyka Scheme je tak možné použít jazyk s možností přesné deklarace datových typů, jazyk s infixovu notací zápisu aritmetických výrazů, dokonce i implementaci Algolu 60 atd. Mezi další zdařilé implementace Scheme patří i Gambit a Chicken Scheme.
Obrázek 4: Logo projektu Racket.
2. Cesta k Interlispu
Vývoj Interlispu začal již v roce 1966, ovšem zdaleka se nejednalo o první široce používanou implementaci Lispu. První práce na programovacím jazyku, který byl později pojmenován Lisp, totiž začaly už v roce 1956, tedy v době, v níž se John McCarthy účastnil dnes již legendárního projektu (a částečně i konference) s předlouhým jménem Dartmouth Summer Research Project on Articial Intelligence. První skutečně použitelná implementace Lispu byla dokončena v roce 1958, což je rok, který je dnes oficiálně považován za rok vzniku Lispu (nebo v té době spíše LISPu; až později se totiž začalo jméno tohoto jazyka psát minuskami). Po roce 1958 začalo období expanze – Lisp se v různých variantách rozšířil na mnoho různých v té době existujících či vznikajících platforem. Buď se využíval takzvaný bootstraping, tedy postupný převod plnohodnotného Lispu v menších krocích (v jednodušších jazycích a nástrojích), nebo alternativně vznikaly zcela nové implementace, což bylo zrovna v případě Lispu relativně jednoduché a přímočaré řešení. Tyto varianty byly zpočátku do značné míry kompatibilní s Lispem 1.5.
Obrázek 5: Postupný vývoj LISPovských jazyků.
Zdroj: Wikipedia
Velmi dobrými příklady implementací Lispu 1.5 je Lisp pro mainframe IBM 7090, Lisp pro Univac M 460, resp. pro Univac 490 (460 byla armádní verze Univacu 490) atd.. Zajímavá cesta vedla z IBM 7090 na slavné PDP-1. Zde se použil již zmíněný bootstraping, kdy se začalo velmi jednoduchým zaváděcím programem (měl několik stovek slov) a přes stále složitější a zejména mocnější jazyky se dospělo do stadia, kdy již bylo možné přenést samotný Lisp 1.5. Mimochodem – oficiálními autory Lispu pro PDP-1 není nikdo jiný než John McCarthy a Steve Russell, kteří stáli za původní ideou a implementací Lispu. Další varianta Lispu pro PDP-1 byla vytvořena ve firmě BBN (Bolt Beranek and Newman). Tato varianta byla nazvána Basic PDP-1 Lisp (ovšem s programovacím jazykem BASIC neměla prakticky vůbec nic společného). Z těchto variant Lispu postupně vznikla varianta určená pro PDP-6 (DEC) a právě z této varianty vznikl rozšířený MacLisp (opět: ten ovšem nemá nic společného s Macintoshem, „mac“ zde znamená „macro“).
… in contrast to most languages, in which the language is first designed and then implemented … it was facetiously said of LISP 2 that is was an implementation in search of a language…
Vraťme se však k již výše zmíněnému MacLispu, který se taktéž zapisoval jako Maclisp, MACLISP nebo dokonce MacLISP. Tento dialekt programovacího jazyka Lisp, který byl používán ve slavných AI Lab na MITu od konce šedesátých let minulého století až do začátku osmdesátých let, byl po dlouhou dobu považován za neoficiální standard Lispu, tedy za jakousi „referenční implementaci“ (což je dnes zcela běžné – ostatně mnoho moderních programovacích jazyků staví právě na referenční implementaci a nikoli na rigidní specifikaci). MacLisp byl rozšířen na poměrně mnoho platforem, například na PDP-6 a PDP-10, Honeywell 6180, běžel na Multicsu (ten ukázal slepou uličku, kterou se NEvydal pozdější UNIX) atd. Samotný MacLisp se pochopitelně postupně vyvíjel a zajímavé je, že byl použit pro vývoj a implementaci dalších variant programovacích jazyků, mezi jinými i jazyka Scheme. Dále není bez zajímavosti, že první varianta Emacsu založená na Lispu, používala právě MacLisp pro systém Multics (v IT je prostě vše propojeno).
Obrázek 6: Část zdrojového kódu systému SHRDLU tak, jak ji tvůrci tohoto systému nikdy neviděli – se zvýrazněnou syntaxí.
Slavný příklad dialogu s SHRDLU:
Person: Pick up a big red block. Computer: OK. Person: Grasp the pyramid. Computer: I DON'T UNDERSTAND WHICH PYRAMID YOU MEAN. Person (changing their mind): Find a block which is taller than the one you are holding and put it into the box. Computer: BY "IT", I ASSUME YOU MEAN THE BLOCK WHICH IS TALLER THAN THE ONE I AM HOLDING. Computer: OK. Person: What does the box contain? Computer: THE BLUE PYRAMID AND THE BLUE BLOCK. Person: What is the pyramid supported by? Computer: THE BOX. Person: How many blocks are not in the box? Computer: FOUR OF THEM. Person: Is at least one of them narrower than the one which i told you to pick up? Computer: YES, THE RED CUBE. Person: Is it supported? Computer: YES, BY THE TABLE. ... ... ... Person: Does the shortest thing the tallest pyramid's support supports support anything green? Computer: YES, THE GREEN PYRAMID. Person: What color is it? Computer: BY "IT", I ASSUME YOU MEAN THE SHORTEST THING THE TALLEST PYRAMID'S SUPPORT SUPPORTS. Computer: RED Person: How many things are on top of green cubes? Computer: I'M NOT SURE WHAT YOU MEAN BY "ON TOP OF "IN THE PHRASE "ON TOP OF GREEN CUBES " . DO YOU MEAN: 1 - DIRECTLY ON THE SURFACE 2 - ANWHERE ON TOP OF ? Person: 2 Computer: THREE OF THEM.
3. Interlisp neboli „interactive Lisp“
Interlisp, jakožto ideový pokračovatel MacLispu, znamenal v době svého vzniku poměrně zásadní změnu v tom, jak byl jazyk a celé jeho interaktivní prostředí navržen. Původní Lispy totiž do značné míry vypadaly tak, jako například dnešní GNU Guile – všechny formy musely být zapsány jako s-výrazy, přičemž se netolerovaly žádné chyby, závorky musely být balancovány atd. Interlisp byl dosti odlišný. Zejména byly rozšířeny možnosti nástrojů dodávaných společně s tímto jazykem – přidán byl například v té době přelomový korektor překlepů, přidány byly balíčky pro práci se soubory, balíček CLISP umožňující zápis algebraických výrazů, programátorský editor pro strukturovaný kód atd. Za většinou nových myšlenek implementovaných v Interlispu stál Warren Teitelman, který napsal svoji disertaci na téma symbiózy mezi člověkem a počítačem. A povšimněte si, že všechny novinky implementované v Interlispu a zmíněné výše se soustředí právě na rozhraní mezi počítačem a uživatelem (resp. programátorem) a nikoli například na nové jazykové konstrukce.
Příkladem může být korektor překlepů realizovaný balíčkem pojmenovaným DWIM neboli „Do What I Mean“. Pokud se ve formě zapsané uživatelem nacházel neznámý symbol, mohl být balíček DWIM automaticky vyvolán, aby našel správný symbol ze seznamu již definovaných symbolů a nabídl uživateli opravu, korigoval chybu automaticky nebo vypsal chybové hlášení, jak je to dodnes běžné.
4. Radikální odklon od předchozích implementací Lispu
Možná ještě důležitější změnou či novinkou zavedenou v Interlispu je programátorský editor. Ten totiž operoval nikoli nad běžným plain textem (jak je tomu většinou dodnes), ale přímo nad lispovskými datovými strukturami, protože díky homoikonicitě je každý lispovský program reprezentován stromovou strukturou (tedy zjednodušeně řečeno seznamem seznamů). Jakákoli změna provedená v programovém kódu se ihned projevila v modifikaci této datové struktury, která mohla být kdykoli uložena do souboru. Tento soubor byl tedy použit jako perzistentní úložiště celého programu a současně i jeho prostředí. To šlo kdykoli později vyvolat.
Interlisp vznikl později než výše zmíněný MacLisp a hned několik vlastností Interlispu bylo odvozeno od zkušeností programátorů s MacLispem. Příkladem může být volitelné použití formy nazvané EVALQUOTE namísto standardní a „čisté“ formy EVAL využívané MacLispem a později například i jazykem Scheme při zpracování jednotlivých forem zapisovaných uživatelem nebo ve skriptech. Podívejme se na jednoduchý příklad, jímž může být výraz pro spojení dvou seznamů. V MacLispu, Scheme atd. by se zapsal následujícím způsobem:
(APPEND (QUOTE (FIRST SECOND THIRD)) (QUOTE (CAR CDR)))
popř. s využitím zkrácení QUOTE za ':
(APPEND '(FIRST SECOND THIRD) '(CAR CDR))
Naproti tomu Intelisp volitelně umožňuje použít EVALQUOTE zajišťující implicitní uvození parametrů:
APPEND((FIRST SECOND THIRD) (CAR CDR))
Zajímavou novinkou byl taktéž balíček nazvaný CLISP, který dovoloval zápis funkcí ve formě, v níž se používala jak Lispovská, tak i Algolská či Fortranovská notace:
DEFINEQ((FACTORIAL (LAMBDA (N) (IF N=0 THEN 1 ELSE N*(FACTORIAL N-1)))))
Díky kombinaci možností balíčků DWIM a CLISP byla dokonce vyhodnotitelná i následující forma s mnoha překlepy:
DEFINEQ((FACTORIAL (LAMBDA (N) (IFFN=0 THENN 1 ESLE N*9FACTORIALNN-1)))))
DEFINEQ((FACTORIAL (LAMBDA (N) (IFFN=0 THENN 1 ESLE N*8FACTORIALNN-1)))))
5. Ve „stupidních závorkách“ se již neztratíme
A konečně poslední zásadní změna zavedená v Intelispu souvisí s uzavíráním forem. V Lispu se totiž většinou na konci formy „nahromadí“ mnoho pravých závorek, které uzavírají jednotlivé subformy. Ovšem Intelisp umožňuje tyto závorky nahradit jedinou pravou hranatou závorkou. Ostatně podívejme se na praktický příklad, který lze spustit v dále popsaném interpretru. Jedná se o definici dvou funkcí, přičemž první definice je psána ve standardním Lispu a druhá využívá automatické uzavření všech závorek ve formě:
(DEFINEQ (ADD (LAMBDA (X Y) (+ X Y)))) NIL (ADD 1 2) 3 (DEFINEQ (SUB (LAMBDA (X Y) (- X Y] NIL (SUB 1 2) -1
6. p-code ve skutečnosti nevznikl pro Pascal
Již několikrát jsme se na stránkách Roota setkali s programovacím jazykem Pascal. Za velmi důležitou implementaci Pascalu je (pochopitelně kromě Turbo Pascalu) považován i UCSD Pascal vyvinutý v roce 1977 a portovaný na mnoho existujících platforem, včetně domácích mikropočítačů (Apple II), TI 99/4A, počítačů s čipy Z80, MOS 6502, Motorola 68000 i Intel 8086). Velká portabilita UCSD Pascalu byla zajištěna díky tomu, že se překlad prováděl do takzvaného p-code, což není nic jiného, než obdoba moderních bajtkódů (například bajtkód JVM atd.). Ostatně právě bajtkód JVM má s p-code mnoho společného: oba jsou založeny na zásobníku operandů. p-code byl sice používán právě UCSD Pascalem, ovšem jeho zcela první varianta vznikla právě pro potřeby Interlispu – uvádí se, že p-code pro Interlisp byl vytvořen přibližně dva roky před p-code pro UCSD Pascal (existuje totiž několik verzí p-code.).
7. Důležitá postava v historii IT: Warren Teitelman
S vývojem Interlispu je neodmyslitelně spojeno jméno Warrena Teitelmana, o němž jsme se již zmínili v předchozích kapitolách. Warren stál za vývojem BBN LISPu a později, když společně s několika kolegy odešel z firmy BBN do slavného Xerox Palo Alto Research Center (PARC), byla jejich implementace LISPu přejmenována na Interlisp. Warren se zabývat především způsobem komunikace mezi člověkem a počítačem, takže se soustředil na techniky, které by pomohly buď zabránit chybám při komunikaci, automaticky je odstraňovat, popř. alespoň odvolat. Warren stojí za vývojem takových dnes již poměrně běžných technologií, jako jsou operace Undo a Redo (podle mého názoru mnohem důležitější věc, než „vymazlené“ UI – možnost odvolat operaci je to, co lidem zpřístupňuje dialog s počítačem a odstraňuje hlavní bariéry), vyvíjel i první automatické korektory textu, spoluvynalezl online nápovědu a v neposlední řadě i systém pro poloautomatickou opravu chyb, s nímž jsme se setkali výše pod zkratkou DWIM neboli Do What I Mean.
Warren se taktéž zabýval rozpoznáváním znaků, což byla v šedesátých letech minulého století ještě zcela neprobádaná technologie. Tato jeho magisterská (ne disertační!) práce byla často citována, a to i poměrně nedávno. Později získal cenu ACM, a to právě za Interlisp a taktéž za jeho přínos v oblasti vývojových prostředí.
8. Interlisp dostupný pro starší počítačové platformy
Většinu původních platforem, na nichž byl Interlisp provozován, dnes nalezneme pouze v muzeích, i když se někdy jedná o funkční počítače. Interlisp však byl později portován i na některé domácí osmibitové mikropočítače, což by nemělo být příliš překvapivé, protože jejich možnosti dosahovaly možností prvních minipočítačů. Příkladem až překvapivě dobré portace je Interlisp/65 určený pro osmibitové domácí mikropočítače Atari. Zajímavé je, že distribuci (ne ovšem samotnou portaci) zajišťovala společnost Datasoft, s níž jsme se seznámili ve zcela jiném kontextu – tato firma totiž vytvářela i počítačové hry; viz například Hry vytvořené firmou Datasoft pro osmibitové domácí mikropočítače (už jsem psal, že v IT vše souvisí se vším, že?).
Ve zkratce se podívejme na to, jak tato stále dostupná varianta Interlispu vypadá:
Obrázek 7: Úvodní obrazovka Interlispu/65.
Obrázek 8: Volání existující funkce *, definice nové funkce a její zavolání.
Obrázek 9: Specifikem Interlispu/65 je existence funkcí POKE, PEEK, STICK atd., tedy funkcí známých z Atari BASICu a důležitých pro vývoj reálných aplikací. Zde se s využitím funkce POKE změnil obsah barvového registru s barvou pozadí obrazovky v textovém režimu.
9. Pojďme tedy oživit dinosaura
Z předchozího textu je pravděpodobně zřejmé, že Interlisp byl jazyk (resp. přesněji řečeno jedna z implementací Lispu), jenž má velký historický význam, který v některých ohledech přesahuje význam MacLispu a možná i pozdějšího Common Lispu. Tohoto faktu jsou si vědomi i autoři projektu nazvaného Medley Interlisp Project, v jehož rámci je udržován projekt Medley. Nás však bude dnes zajímat jiný projekt nazvaný přímočaře LISPF4 – InterLisp Interpreter, který je možné nalézt na GitHubu, konkrétně na adrese https://github.com/blakemcbride/LISPF4. V rámci tohoto projektu došlo k přepsání těch částí Interlispu, které byly původně vytvořeny v assembleru (a to v assembleru pro dobové mainframy a minipočítače). Přepisem těchto obecně velmi těžko přenositelných částí do programovacího jazyka C se zajistila mnohem snadnější přenositelnost, takže dnes pro překlad stačí Linux se základními nástroji GNU toolchainu (překladač jazyka C, linker). Podrobnosti si popíšeme níže.
Obrázek 10: Přebal knihy o Intelispu pro IBM/360 a IBM/370.
10. Stažení a překlad Interlispu
V této kapitole si ukážeme, jak lze stáhnout, přeložit a spustit interpret Interlispu. Budeme přitom potřebovat pouze základní GNU Toolchain (ve skutečnosti lze však překlad provést i s LLVM toolchainem).
Nejprve provedeme naklonování repositáře s upravenými zdrojovými kódy Interlispu:
$ git clone https://github.com/blakemcbride/LISPF4.git Cloning into 'LISPF4'... remote: Enumerating objects: 47, done. remote: Counting objects: 100% (47/47), done. remote: Compressing objects: 100% (36/36), done. remote: Total 293 (delta 15), reused 34 (delta 10), pack-reused 246 Receiving objects: 100% (293/293), 75.29 MiB | 2.30 MiB/s, done. Resolving deltas: 100% (154/154), done.
Přejdeme do adresáře s naklonovaným projektem:
$ cd LISPF4/
Překlad provedeme s využitím souboru Makefile určeného pro Unixy. Jméno Makefile souboru je nestandardní, takže je ho nutné specifikovat explicitně:
$ make -f Makefile.unx
Samotný překlad je prakticky okamžitý, protože je nutné přeložit a slinkovat pouhé tři soubory:
cc -Dstricmp=strcasecmp -O3 -DCELLS=100000 -DATOMS=3000 -DSTACK=1500 -DARRAY=5000 -DYEAR=2021 -DMONTH=1 -DDAY=1 -c -o lispf41.o lispf41.c cc -Dstricmp=strcasecmp -O3 -DCELLS=100000 -DATOMS=3000 -DSTACK=1500 -DARRAY=5000 -DYEAR=2021 -DMONTH=1 -DDAY=1 -c -o lispf42.o lispf42.c cc -Dstricmp=strcasecmp -O3 -DCELLS=100000 -DATOMS=3000 -DSTACK=1500 -DARRAY=5000 -DYEAR=2021 -DMONTH=1 -DDAY=1 -c -o auxillary.o auxillary.c gcc -o lispf4 -O lispf41.o lispf42.o auxillary.o -lm
Dále se automaticky spustí testy a kód pro vytvoření základního obrazu systému:
./lispf4 -x <script.1 Lisp F4 , latest update = (2021 1 1) Space (cells smallnum bignums atoms) = (96865 1073690323 2999 2853) --- Reset _10 _10 _10 _ Exit from Lisp F4 GBC:s (cell compacting num num/atom) = (0 1 0 0) Bye ./lispf4 bare.img <script.2 Lisp F4 , latest update = (2021 1 1) Space (cells smallnum bignums atoms) = (96993 1073690323 2999 2850) --- Reset _10 _5 BASIC1-PACKAGE NIL 80 80 (LAMBDA (FN DEF) (PUTPROP FN 'FNCELL DEF)) [NLAMBDA L (MAPC L '(LAMBDA (X) (PUTD (CAR X) (CADR X] (NLAMBDA (A) (PRINT (LIST 'FILEHEADER A))) (LAMBDA (FILE) (PROG (&&X LFN TEMP) (OR (SETQ LFN (XCALL 1 (LIST 15 FILE 'OLD 'FORMATTED))) (RETURN)) (SETQ TEMP (IOTAB 1 LFN)) LOOP (SELECTQ (SETQ &&X (READ)) (STOP (XCALL 2 LFN) (RETURN (IOTAB 1 TEMP))) (EVAL &&X)) (GO LOOP))) (LAMBDA (A) (PRIN0 A T) (TERPRI) A) _10 __(FILEHEADER BASIC2) BASIC2-PACKAGE (VERSION 11) BASIC2FNS 15 _(FILEHEADER IO1) IO1-PACKAGE (VERSION 2) IO1FNS 15 _(FILEHEADER FUNC1) FUNC1-PACKAGE (VERSION 4) FUNC1FNS FUNC1VARS 15 _(FILEHEADER DEBUG1) DEBUG1-PACKAGE (VERSION 6) SYSERROR REDEFINED DEBUG1FNS DEBUG1VARS 15 _(FILEHEADER DEBUG2) (DEBUG PACKAGE 2) (VERSION 0) PUTD REDEFINED DEBUG2FNS DEBUG2VARS 15 _(FILEHEADER EDIT) EDIT-PACKAGE (VERSION 4) EDITFNS 15 _(FILEHEADER MAKEF) (MAKE FILE PACKAGE MODIFIED BY BLAKE MCBRIDE) (VERSION 8) FILEHEADER REDEFINED MAKEFFNS MAKEFVARS 15 _(FILEHEADER HISTORY) (HISTORY FUNCTIONS) (VERSION 2) LISPX REDEFINED READ REDEFINED HISTORYFNS HISTORYVARS history.lisp - LOADED "history.lisp" _CUR _ --- Compacting GBC. Free cells = 87119 basic.img SAVED "basic.img" _ Exit from Lisp F4 GBC:s (cell compacting num num/atom) = (0 1 0 0) Bye
Nyní by měl být Interlisp připraven k použití. Můžeme se pokusit spustit jeho přeloženou verzi uloženou v podadresáři Linux:
$ ./lispf4 -h Usage: ./lispf4 [-h] [-ZN]... [-x] [FILE.IMG] Where Z is one of: c = car/cdr cells (default 100000) a = atoms (default 3000) s = stack space (default 1500) p = print names / strings / reals / arrays (default 5000) N = a number (no space between the option and N) -x = do not load an image, however, require SYSATOMS file -h = display this help message FILE.IMG = an image file name You'll typically want to start the system with at least the BASIC.IMG image. Without that, the system is quite bare.
Při spuštění se specifikuje jméno souboru se základním obrazem systému (funkce standardní knihovny atd.):
$ ./lispf4 basic.img Lisp F4 , latest update = (2021 1 1) Space (cells smallnum bignums atoms) = (87115 1073690323 2998 2221) --- Reset
Interpret ukončíme funkcí exit:
_(exit) Exit from Lisp F4 GBC:s (cell compacting num num/atom) = (0 0 0 0) Bye
Obrázek 11: Přebal knihy o Intelispu pro IBM/360 a IBM/370.
11. První seznámení s Interlispem
Interpret Interlipsu budeme spouštět následujícím způsobem, který nám zajistí načtení základních funkcí, speciálních forem a maker uložených v souboru basic.img:
$ ./lispf4 basic.img
Podobně jako další varianty LISPu jsou jednou z nejdůležitějších datových struktur seznamy neboli list (samotný název LISP znamená LISt Processing. Podívejme se na úplné základy práce se seznamy.
Prázdný seznam je ekvivalentní symbolu NIL (což ovšem neplatí například pro Scheme):
(print "Empty list") (print '()) "Empty list" NIL
Konstrukce seznamu se čtyřmi prvky (nesmíme zapomenout na formu quote nebo na apostrof):
(print "A list") (print '(1 2 3 4)) "A list" (1 2 3 4)
Seznam lze vytvořit i konstruktorem list:
(print "Another list") (print (list 1 2 3 4)) "Another list" (1 2 3 4)
Seznam lze přiřadit proměnné, podobně jako jinou hodnotu:
(setq a '(1 2 3 4)) (1 2 3 4)
Funkce car vrací první prvek seznamu (neboli hlavu seznamu):
(print "car") (print (car a)) "car" 1
Funkce cdr vrací seznam bez prvního prvku (neboli ocas seznamu):
(print "cdr") (print (cdr a)) "cdr" (2 3 4)
Interlisp, podobně jako další LISPy, obsahuje i funkce kombinující různé kombinace car a cdr:
(print "cadr") (print (cadr a)) "cadr" 2
Další podporovaná kombinace:
(print "cddr") (print (cddr a)) "cddr" (3 4)
Obrázek 12: Referenční manuál k Intelispu. Za jeho vznikem stojí opět Warren Teitelman.
12. Tečka-dvojice a seznamy
V předchozí kapitole jsme si řekli, že programovací jazyk LISP je založen na zpracování seznamů. Jak jsou však seznamy uloženy v operační paměti počítače a jak s nimi interpretry tohoto jazyka pracují? Základní interní strukturou, která je však přímo dostupná i programátorům aplikací v jazyce LISP, je takzvaná tečka-dvojice (dotted-pair). Tuto strukturu si můžeme představit jako dvojici ukazatelů, přičemž každý z těchto ukazatelů může obsahovat adresu atomu, adresu další tečka-dvojice nebo speciální hodnotu nil odpovídající v céčku hodnotě NULL či v Javě hodnotě null, tj. jedná se o speciální hodnotu, která interpretru říká, že daný ukazatel neobsahuje žádný odkaz.
Tečka-dvojici lze v LISPovských programech zapisovat formou dvojice výrazů (takzvaných S-výrazů) oddělených tečkou, které jsou uzavřeny do kulatých závorek (i když je pravda, že se s tečka-dvojicemi v reálných programech příliš často nesetkáme, především z důvodu nepřehledného zápisu s velkým množstvím závorek):
Konstrukce datové struktury z tečka-dvojic:
(print '(1 . ((2 . 3) . 4))) (1 (2 . 3) . 4) (print '((1 . 2) . (3 . 4))) ((1 . 2) 3 . 4)
Konstrukce seznamu z tečka-dvojic je taktéž možná:
(print '(1 . (2 . (3 . nil)))) (1 2 3) (print '(1 . (2 . (3 . ())))) (1 2 3)
Toto ovšem není skutečný seznam:
(print '(1 . (2 . (3 . (4 ()))))) (1 2 3 4 NIL)
Ten totiž vypadá takto:
(print '(1 . (2 . (3 . (4 . ()))))) (1 2 3 4)
Z toho taktéž vyplývá, jak seznamy vypadají interně:
; interní struktura seznamu v paměti ; . ; / \ ; 1 . ; / \ ; 2 . ; / \ ; 3 . ; / \ ; 4 nil
Konstrukce tečka dvojic funkcí cons:
(print (cons 1 2)) (1 . 2) (print (cons 1 (cons 2 3))) (1 2 . 3) (print '((1 . 2) . (3 . 4))) ((1 . 2) 3 . 4)
Konstrukce seznamu funkcí cons:
(print (cons 1 (cons 2 (cons 3 '())))) (1 2 3) (print (cons 1 (cons 2 (cons 3 nil)))) (1 2 3)
Další varianty použití funkce cons:
(print (cons 1 '(2 3 4))) (1 2 3 4) (print (cons 1 (cons 2 (cons 3 (cons 4 nil))))) (1 2 3 4) (print (cons 1 (cons 2 (cons 3 4)))) (1 2 3 . 4)
13. Predikáty
Naprostá většina variant programovacího jazyka LISP obsahuje predikáty, tedy funkce testující nějakou podmínku a vracející hodnoty T a nil na základě vyhodnocení této podmínky. Bývá zvykem, že predikáty končí otazníkem nebo písmenem p, ovšem v Interlispu je tomu odlišně, minimálně u základních predikátů ukázaných v dalších příkladech.
Test, zda hodnotou je atom (což v jiných jazycích zhruba odpovídá skalární hodnotě):
(print (atom nil)) T (print (atom T)) T (print (atom 42)) T (print (atom "string")) NIL (print (atom '(1 2 3))) NIL
Test, zda hodnotou je seznam (zde se používá „p“ na konci jména predikátu):
(print (listp nil)) NIL (print (listp T)) NIL (print (listp 42)) NIL (print (listp "string")) NIL (print (listp '(1 2 3))) (1 2 3)
Predikát, zda hodnota je nulová:
(print (zerop 0)) T (print (zerop 42)) NIL (print (zerop nil)) NIL (print (zerop T)) NIL
Ovšem neplést s predikátem na hodnotu nil neboli na prázdný seznam (opět se jedná o predikát bez „p“ na konci jména):
(print (null 0)) NIL (print (null nil)) T (print (null '())) T (print (null "foobar")) NIL
14. Podmínky realizované formami and, or a cond
V klasických LISPech, mezi něž Interlisp ještě patří, jsou podmínky (rozhodovací konstrukce) v kódu realizovány trojicí speciálních forem nazvaných and, or a cond. Méně „mocná“ forma if není považována za standardní.
Forma and vyhodnocuje podvýrazy zleva doprava a skončí ve chvíli, kdy je již jasné, že výsledek bude nil, tj. po prvním nepravdivém výsledku:
(print (and T T)) T (print (and T nil)) NIL
Naproti tomu forma or sice taktéž vyhodnocuje podvýrazy zleva doprava, ale skončí ve chvíli, kdy je již jasné, že výsledek bude T (tj. po prvním pravdivém výsledku):
(print (or T T)) T (print (or T nil)) T
Počet vyhodnocovaných podvýrazů není nijak omezen:
(print (or nil nil T nil)) T (print (or nil nil nil nil)) NIL
Ukázka, kdy se vyhodnocování zastaví a proč mohou formy and a or nahradit if (v prvním případě se print nezavolá, ve druhém ano):
(or T (print "foo")) T (or nil (print "foo")) "foo"
V praxi se velmi často setkáme s nutností rozhodovat se na základě většího množství podmínek, popř. na základě většího množství hodnot (a obecně pak na základě pattern matchingu, což ovšem v Interlispu není ve standardní knihovně implementováno). Pokud je nutné provést rozhodnutí na základě více podmínek, nabízí se využití makra nazvaného cond, které se mj. objevilo už v prvních verzích LISPu.
Vytvoříme pomocnou proměnnou:
(setq n 10) 10
Test, zda je hodnota kladná, záporná nebo nulová:
(cond ((< n 0) 'negative) ((> n 0) 'positive) ((zerop n) 'zero)) ___POSITIVE
Dtto, ovšem pro jinou hodnotu:
(setq n -10) -10 (cond ((< n 0) 'negative) ((> n 0) 'positive) ((zerop n) 'zero)) ___NEGATIVE
A konečně pro hodnotu nulovou:
(setq n 0) 0 (cond ((< n 0) 'negative) ((> n 0) 'positive) ((zerop n) 'zero)) ___ZERO
15. Definice nových funkcí
V Interlispu je pochopitelně možné vytvářet nové anonymní funkce (a taktéž uzávěry) s využitím standardní speciální formy pojmenované lambda, která se objevuje už v původním návrhu Lispu:
((lambda (x y) (+ x y)) 1 2) 3
Aplikace parametrů do anonymní funkce:
(print ((lambda (x y) (+ x y)) 1 2)) 3
Pro konstrukci pojmenovaných funkcí slouží forma defineq, ovšem její zápis je poněkud komplikovaný:
(defineq (add (lambda (x y ) (+ x y)))) NIL (add 10 20) 30
Počet předávaných parametrů může převyšovat počet parametrů očekávaných:
(add 1 2 3) 3
Ovšem nikoli naopak:
(add 1) --- Illegal argument (subrn) PLUS - (1 NIL) (PLUS BROKEN)
Další pojmenovaná funkce, tentokrát definovaná na více řádcích:
(defineq (mul (lambda (x y) (* x y)))) (mul 6 7) 42
Nevýhodou defineq je dlouhý zápis s množstvím nadbytečných závorek a explicitním použitím lambda. Výhodnější je využití makra de umožňujícího kratší zápis definice funkce:
(de add (x y) (+ x y)) (de mul (x y) (* x y)) (print (add 1 2)) 3 (print (mul 6 7)) 42
16. Rekurzivní funkce zkonstruované jak pomocí defineq+lambda, tak i pomocí de
Klasický rekurzivní „školní“ výpočet faktoriálu lze v Interlispu zapsat takto:
(defineq (factorial (lambda (n) (cond ((zerop n) 1) (T (* n (factorial (- n 1)))))))) (print (factorial 10)) 3628800
Podobný zápis, ovšem bez nutnosti zápisu osmice uzavíracích kulatých závorek:
(defineq (factorial2 (lambda (n) (cond ((zerop n) 1) (T (* n (factorial2 (- n 1] (print (factorial2 20)) 7.5485486E17
Definice faktoriálu založená na de je ještě kratší:
(de factorial3 (n) (cond ((zerop n) 1) (T (* n (factorial3 (- n 1)))))) (print (factorial3 20))
Kombinace obou zkrácení, tedy použití de i pravé hranaté závorky:
(de factorial4 (n) (cond ((zerop n) 1) (T (* n (factorial4 (- n 1] (print (factorial4 30))
17. Repositář s demonstračními příklady
Zdrojové kódy všech dnes použitých demonstračních příkladů byly uloženy do Git repositáře, který je dostupný na adrese https://github.com/tisnik/lisp-families.git (stále na GitHubu :-). V případě, že nebudete chtít klonovat celý repositář (ten je ovšem – alespoň prozatím – velmi malý, můžete namísto toho použít odkazy na jednotlivé příklady, které naleznete v následující tabulce:
18. Literatura
- Alan Bundy, Lincoln Wallen
„Catalogue of Artificial Intelligence Tools“
Department of Artificial Intelligence, Edinburgh University, Scotland - Brian Harvey
„Simply Scheme: Introducing Computer Science“
1999 MIT
Dostupné online na adrese https://people.eecs.berkeley.edu/~bh/ss-toc2.html - Paul R. Wilson
„An Introduction to Scheme and its Implementation“
1997
Dostupné online na adrese https://www.cs.utexas.edu/ftp/garbage/cs345/schintro-v14/schintro_toc.html - Steele, Gabriel
„The Evolution of Lisp“
Association for Computing Machinery, 1993 - Daniel G. Bobrow a Daniel L. Murphy
„Structure of a LISP system using two-level storage“
Scientific Report No. 6, Bolt Beranek and Newman Inc., 4 November 1966 - Daniel G. Bobrow a Daniel L. Murphy
„A note on the efficiency of a LISP computation in a paged machine“
Communications of the ACM, Volume 11, Issue 8, August 1968 - L. Peter Deutsch
„An Interactive Program Verifier“
Xerox Palo Alto Research Center CSL-73–1, May 1973 - J. Strother Moore II
„The INTERLISP Virtual Machine Specification“
Technical Report CSL 76–5, Xerox Palo Alto Research Center. - Robert F. Sproull
„InterLisp Display Primitives“
Palo Alto Research Center, Xerox Corporation, July 1977 - Dorai Sitaram
„Teach Yourself Scheme in Fixnum Days“
1998–2015
Dostupné online na adrese https://ds26gte.github.io/tyscheme/ - Warren Teitelman
„Interlisp Reference Manual“
Xerox Palo Alto Research Center, 1974 - Venue (firma)
„An Introduction to Medley“
Venue, 1982 - Warren Teitelman
„History of Interlisp“
Association for Computing Machinery, 2008 - Warren Teitelman
„PILOT: A Step Toward Man-Computer Symbiosis“
1966 - Peter Seibel
„Practical Common Lisp“
2009 - Paul Graham
„ANSI Common Lisp“
1995 - Gerald Gazdar
„Natural Language Processing in Lisp: An Introduction to Computational Linguistics“
1989 - Peter Norvig
„Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp“
1991 - Alex Mileler et.al.
„Clojure Applied: From Practice to Practitioner“
2015 - „Living Clojure: An Introduction and Training Plan for Developers“
2015 - Dmitri Sotnikov
„Web Development with Clojure: Build Bulletproof Web Apps with Less Code“
2016 - McCarthy
„Recursive functions of symbolic expressions and their computation by machine, part I“
1960 - R. Kent Dybvig
„The Scheme Programming Language“
2009 - Max Hailperin, Barbara Kaiser, Karl Knight
„Concrete Abstractions“
1998 - Guy L. Steele
„History of Scheme“
2006, Sun Microsystems Laboratories - Kolář J., Muller K.:
„Speciální programovací jazyky“
Praha 1981 - „AutoLISP Release 9, Programmer's reference“
Autodesk Ltd., October 1987 - „AutoLISP Release 10, Programmer's reference“
Autodesk Ltd., September 1988 - McCarthy, John; Abrahams, Paul W.; Edwards, Daniel J.; Hart, Timothy P.; Levin, Michael I.
„LISP 1.5 Programmer's Manual“
MIT Press. ISBN 0 262 130 1 1 4 - Carl Hewitt; Peter Bishop and Richard Steiger
„A Universal Modular Actor Formalism for Artificial Intelligence“
1973 - Feiman, J.
„The Gartner Programming Language Survey (October 2001)“
Gartner Advisory - Harold Abelson, Gerald Jay Sussman, Julie Sussman:
Structure and Interpretation of Computer Programs
MIT Press. 1985, 1996 (a možná vyšel i další přetisk) - Paul Graham
On Lisp
Prentice Hall, 1993
Dostupné online na adrese http://www.paulgraham.com/onlisptext.html - David S. Touretzky
Common LISP: A Gentle Introduction to Symbolic Computation (Dover Books on Engineering)
- Peter Norvig
Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp - Patrick Winston, Berthold Horn
Lisp (3rd Edition)
ISBN-13: 978–0201083194, ISBN-10: 0201083191 - Matthias Felleisen, David Van Horn, Dr. Conrad Barski
Realm of Racket: Learn to Program, One Game at a Time!
ISBN-13: 978–1593274917, ISBN-10: 1593274912
19. Předchozí části seriálu
V této kapitole jsou uvedeny odkazy na všechny předchozí části seriálu o světě programovacích jazyků LISP a Scheme (kromě samostatného seriálu, který se věnoval programovacímu jazyku Clojure):
- Jemný úvod do rozsáhlého světa jazyků LISP a Scheme
https://www.root.cz/clanky/jemny-uvod-do-rozsahleho-sveta-jazyku-lisp-a-scheme/ - PicoLisp: minimalistický a přitom překvapivě výkonný interpret Lispu
https://www.root.cz/clanky/picolisp-minimalisticky-a-pritom-prekvapive-vykonny-interpret-lispu/ - PicoLisp: užitečné funkce a speciální formy používané při tvorbě aplikací
https://www.root.cz/clanky/picolisp-uzitecne-funkce-a-specialni-formy-pouzivane-pri-tvorbe-aplikaci/ - PicoLisp: dokončení popisu a několik praktických rad na závěr
https://www.root.cz/clanky/picolisp-dokonceni-popisu-a-nekolik-praktickych-rad-na-zaver/ - GNU Guile – interpret Scheme vestavitelný do nativních aplikací
https://www.root.cz/clanky/gnu-guile-interpret-scheme-vestavitelny-do-nativnich-aplikaci/ - TinyScheme aneb další interpret jazyka Scheme vestavitelný do dalších aplikací
https://www.root.cz/clanky/tinyscheme-aneb-dalsi-interpret-jazyka-scheme-vestavitelny-do-dalsich-aplikaci/ - Kawa: překvapivě silný a výkonný dialekt Scheme pro JVM
https://www.root.cz/clanky/kawa-prekvapive-silny-a-vykonny-dialekt-scheme-pro-jvm/ - Jazyk Kawa v ekosystému virtuálního stroje Javy
https://www.root.cz/clanky/jazyk-kawa-v-ekosystemu-virtualniho-stroje-javy/ - Zpracování vektorů, matic a N-rozměrných polí v programovacím jazyku Kawa
https://www.root.cz/clanky/zpracovani-vektoru-matic-a-n-rozmernych-poli-v-programovacim-jazyku-kawa/ - Racket: programovací jazyk a současně i platforma pro vývoj nových jazyků
https://www.root.cz/clanky/racket-programovaci-jazyk-a-soucasne-i-platforma-pro-vyvoj-novych-jazyku/ - Makra v Racketu i v dalších lispovských jazycích
https://www.root.cz/clanky/makra-v-racketu-i-v-dalsich-lispovskych-jazycich/ - Základní knihovna jazyka Racket
https://www.root.cz/clanky/zakladni-knihovna-jazyka-racket/ - Jazyk Joker: dialekt Clojure naprogramovaný v Go
https://www.root.cz/clanky/jazyk-joker-dialekt-clojure-naprogramovany-v-go/ - Chicken Scheme – další interpret a především překladač programovacího jazyka Scheme
https://www.root.cz/clanky/chicken-scheme-dalsi-interpret-a-predevsim-prekladac-programovaciho-jazyka-scheme/ - Projekt Gambit – další kvalitní interpret i překladač programovacího jazyka Scheme
https://www.root.cz/clanky/projekt-gambit-dalsi-kvalitni-interpret-i-prekladac-programovaciho-jazyka-scheme/
20. Odkazy na Internetu
- The Evolution of Lisp
https://www.csee.umbc.edu/courses/331/resources/papers/Evolution-of-Lisp.pdf - Interlisp.org: Dedicated to Restoring and Preserving the Interlisp experience
https://github.com/Interlisp - Warren Teitelman
https://en.wikipedia.org/wiki/Warren_Teitelman - InterLISP/65
http://www.atarimania.com/utility-atari-400–800-xl-xe-interlisp-65_12477.html - Lisp Editing in the 80s – Interlisp SEdit (Video)
https://www.youtube.com/watch?v=2qsmF8HHskg - Inter-LISP
http://www.atarimania.com/utility-atari-400–800-xl-xe-inter-lisp_29354.html - InterLISP 65 Editing (video)
https://www.youtube.com/watch?v=nY_hcazo86A - Datasoft INTER-LISP/65 (Atari Age, chat)
https://atariage.com/forums/topic/116093-datasoft-inter-lisp65/ - Marvin Minsky – The beauty of the Lisp language (44/151)
https://www.youtube.com/watch?v=YaWVHyIBVeI - History of LISP (Interlisp)
http://www.softwarepreservation.org/projects/LISP/index.html#INTERLISP_ - Computer-Assisted Instruction (Bits and Bytes, Episode 7)
https://www.youtube.com/watch?v=eURtTV_qKw8 - Můžeme věřit překladačům? Projekty řešící schéma „důvěřivé důvěry“
https://www.root.cz/clanky/muzeme-verit-prekladacum-projekty-resici-schema-duverive-duvery/ - Gambit in the browser
https://feeley.github.io/gambit-in-the-browser/ - A Tour of Scheme in Gambit
http://dynamo.iro.umontreal.ca/wiki/images/a/a7/A_Tour_of_Scheme_in_Gambit.pdf - Gambit Scheme: Inside Out
http://www.iro.umontreal.ca/~gambit/Gambit-inside-out.pdf - Gambit Internal Documentation
http://dynamo.iro.umontreal.ca/wiki/index.php/Internal_Documentation - clojure-scheme: Compiling to Native Code via Scheme
http://www.iro.umontreal.ca/~gambit/Sorenson-Clojure-to-Native-via-Scheme.pdf - Gauche – a Scheme implementation
http://practical-scheme.net/gauche/ - Scheme48
https://s48.org/ - SISC (Second Interpreter of Scheme)
http://sisc-scheme.org/ - The SCM Implementation of Scheme
https://people.csail.mit.edu/jaffer/SCM.html - Ypsilon – The ultimate script language system for the video pinball fourth generation
http://www.littlewingpinball.com/doc/en/ypsilon/index.html - Chicken Scheme
https://call-cc.org/ - Eggs Unlimited
http://wiki.call-cc.org/chicken-projects/egg-index-5.html - Chicken Scheme Wiki
https://wiki.call-cc.org/ - CHICKEN for Python programmers
https://wiki.call-cc.org/chicken-for-python-programmers - Programming for Performance
http://wiki.call-cc.org/programming-for-performance - Using the compiler
https://wiki.call-cc.org/man/4/Using%20the%20compiler - CHICKEN Scheme tutorials
https://wiki.call-cc.org/tutorials - Racket: programovací jazyk a současně i platforma pro vývoj nových jazyků
https://www.root.cz/clanky/racket-programovaci-jazyk-a-soucasne-i-platforma-pro-vyvoj-novych-jazyku/ - Makra v Racketu i v dalších lispovských jazycích
https://www.root.cz/clanky/makra-v-racketu-i-v-dalsich-lispovskych-jazycich/ - Základní knihovna jazyka Racket
https://www.root.cz/clanky/zakladni-knihovna-jazyka-racket/ - Grafický metaformát PostScript
https://www.root.cz/clanky/graficky-metaformat-postscript/ - Vektorový grafický formát SVG
https://www.root.cz/clanky/vektorovy-graficky-format-svg/ - The Racket Drawing Toolkit
https://docs.racket-lang.org/draw/index.html - Traditional Turtles
https://docs.racket-lang.org/turtles/Traditional_Turtles.html - [racket] How best to repeat a function call n times?
https://lists.racket-lang.org/users/archive/2014-September/064203.html - Racket: Macros
https://www.it.uu.se/edu/course/homepage/avfunpro/ht13/lectures/Racket-3-Macros.pdf - Beautiful Racket / explainers: Macros
https://beautifulracket.com/explainer/macros.html - Macros (dokumentace k Racketu)
https://docs.racket-lang.org/guide/macros.html - Model syntaxe jazyka Racket
https://docs.racket-lang.org/reference/syntax-model.html - Syntax Objects
https://docs.racket-lang.org/guide/stx-obj.html - Tech behind Tech: Clojure Macros Simplified
http://techbehindtech.com/2010/09/28/clojure-macros-simplified/ - Fatvat – Exploring functional programming: Clojure Macros
http://www.fatvat.co.uk/2009/02/clojure-macros.html - Beautiful Racket: an introduction to language-oriented programming using Racket
https://beautifulracket.com/ - Stránky projektu Racket
https://racket-lang.org/ - Dokumentace k projektu Racket
https://docs.racket-lang.org/index.html - Seznam dostupných balíčků pro Racket
https://pkgs.racket-lang.org/ - Racket na Wikipedii
https://en.wikipedia.org/wiki/Racket_(programming_language) - Vector Library (R7RS-compatible)
https://srfi.schemers.org/srfi-133/srfi-133.html - Blogy o Racketu a navazujících technologiích
https://blog.racket-lang.org/ - Prográmky psané v Racketu na RosettaCode
http://rosettacode.org/wiki/Category:Racket - Fear of Macros
https://www.greghendershott.com/fear-of-macros/ - Rackjure
https://github.com/greghendershott/rackjure - Matthew Flatt’s proposal to change Racket’s s-expressions based syntax to infix representation creates a stir in the community
https://hub.packtpub.com/matthew-flatts-proposal-to-change-rackets-s-expressions-based-syntax-to-infix-representation-creates-a-stir-in-the-community/ - Racket News
https://racket-news.com/ - Racket: Lisp for learning
https://lwn.net/Articles/795385/ - Future of Racket
https://www.greghendershott.com/2019/07/future-of-racket.html - Vectors (pro Gauche)
https://practical-scheme.net/gauche/man/gauche-refe/Vectors.html - Kawa: Compiling Scheme to Java
https://www.mit.edu/afs.new/sipb/project/kawa/doc/kawa-tour.html - Kawa in Languages shootout
http://per.bothner.com/blog/2010/Kawa-in-shootout/ - Kawa 2.0 Supports Scheme R7RS
https://developers.slashdot.org/story/14/12/13/2259225/kawa-20-supports-scheme-r7rs/ - Kawa — fast scripting on the Java platform
https://lwn.net/Articles/623349/ - Tail call (a její optimalizace)
https://en.wikipedia.org/wiki/Tail_call - SLIME (Wikipedia)
http://en.wikipedia.org/wiki/SLIME - slime.vim
http://s3.amazonaws.com/mps/slime.vim - What are the best scheme implementations?
https://www.slant.co/topics/5282/~scheme-implementations - Bigloo homepage
http://www-sop.inria.fr/mimosa/fp/Bigloo/ - FTP s tarbally Bigloo
ftp://ftp-sop.inria.fr/indes/fp/Bigloo - GOTO 2018 • Functional Programming in 40 Minutes • Russ Olsen
https://www.youtube.com/watch?v=0if71HOyVjY - TinyScheme (stránka na Sourceforge)
http://tinyscheme.sourceforge.net/home.html - Embedding Tiny Scheme in a Game
http://www.silicondelight.com/embedding-tiny-scheme-in-a-game/ - Embedding Scheme for a game mission scripting DSL
http://carloscarrasco.com/embedding-scheme-for-a-game-mission-scripting-dsl.html - Všechny verze TinyScheme na SourceForge
https://sourceforge.net/projects/tinyscheme/files/tinyscheme/ - Fork TinyScheme na GitHubu
https://github.com/yawnt/tinyscheme - Ackermannova funkce
https://cs.wikipedia.org/wiki/Ackermannova_funkce - Ackermann function na Rosetta Code
https://rosettacode.org/wiki/Ackermann_function#Scheme - Success Stories (lisp.org)
https://lisp-lang.org/success/ - Allegro Common Lisp Success Stories
https://franz.com/success/ - Clojure Success Stories
https://clojure.org/community/success_stories - Scheme Quick Reference
https://www.st.cs.uni-saarland.de/edu/config-ss04/scheme-quickref.pdf - Slajdy o Scheme (od slajdu číslo 15)
https://docs.google.com/presentation/d/1abmDnKjrq1tcjGvvRNAKhOiSTSE2lyagtcEPal07Gbo/edit - Scheme Cheat Sheet
https://github.com/smythp/scheme-cheat-sheet - Embedding Lua, embedding Guile
http://puntoblogspot.blogspot.com/2013/04/embedding-lua-embedding-guile.html - Lambda Papers
https://en.wikisource.org/wiki/Lambda_Papers - Revised7Report on the Algorithmic Language Scheme
https://small.r7rs.org/attachment/r7rs.pdf - Video Lectures (MIT, SICP 2005)
https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6–001-structure-and-interpretation-of-computer-programs-spring-2005/video-lectures/ - Why is Scheme my first language in university?
https://softwareengineering.stackexchange.com/questions/115252/why-is-scheme-my-first-language-in-university - The Perils of JavaSchools
https://www.joelonsoftware.com/2005/12/29/the-perils-of-javaschools-2/ - How to Design Programs, Second Edition
https://htdp.org/2019–02–24/index.html - LilyPond
http://lilypond.org/ - LilyPond — Extending (přes Scheme)
http://lilypond.org/doc/v2.18/Documentation/extending/scheme-tutorial - Scheme in LilyPond
http://lilypond.org/doc/v2.18/Documentation/extending/scheme-in-lilypond - GnuCash
http://www.gnucash.org/ - Custom Reports (in GNU Cash)
https://wiki.gnucash.org/wiki/Custom_Reports - Program by Design
https://programbydesign.org/ - SchemePy
https://pypi.org/project/SchemePy/ - LISP FQA: Section – [1–5] What is the „minimal“ set of primitives needed for a Lisp interpreter?
http://www.faqs.org/faqs/lisp-faq/part1/section-6.html - femtolisp
https://github.com/JeffBezanson/femtolisp - (How to Write a (Lisp) Interpreter (in Python))
http://norvig.com/lispy.html - Repositář s Guile Emacsem
http://git.hcoop.net/?p=bpt/guile.git - Interacting with Guile Compound Data Types in C
http://www.lonelycactus.com/guilebook/x1555.html - Calling Guile functions from C
http://www.lonelycactus.com/guilebook/c1204.html#SECCALLGUILEFUNC - Arrays, and other compound data types
http://www.lonelycactus.com/guilebook/charrays.html - Interacting with Guile Compound Data Types in C
http://www.lonelycactus.com/guilebook/x1555.html - Guile Reference Manual
https://www.gnu.org/software/guile/manual/html_node/index.html - Scheme: Summary of Common Syntax
https://www.gnu.org/software/guile/manual/html_node/Syntax-Summary.html#Syntax-Summary - Scripting with Guile: Extension language enhances C and Scheme
https://www.ibm.com/developerworks/library/l-guile/index.html - Having fun with Guile: a tutorial
http://dustycloud.org/misc/guile-tutorial.html - Guile: Loading Readline Support
https://www.gnu.org/software/guile/manual/html_node/Loading-Readline-Support.html#Loading-Readline-Support - lispy
https://pypi.org/project/lispy/ - Lython
https://pypi.org/project/Lython/ - Lizpop
https://pypi.org/project/lizpop/ - Budoucnost programovacích jazyků
http://www.knesl.com/budoucnost-programovacich-jazyku - LISP Prolog and Evolution
http://blog.samibadawi.com/2013/05/lisp-prolog-and-evolution.html - List of Lisp-family programming languages
https://en.wikipedia.org/wiki/List_of_Lisp-family_programming_languages - clojure_py na indexu PyPi
https://pypi.python.org/pypi/clojure_py - PyClojure
https://github.com/eigenhombre/PyClojure - Hy na GitHubu
https://github.com/hylang/hy - Hy: The survival guide
https://notes.pault.ag/hy-survival-guide/ - Hy běžící na monitoru terminálu společnosti Symbolics
http://try-hy.appspot.com/ - Welcome to Hy’s documentation!
http://docs.hylang.org/en/stable/ - Hy na PyPi
https://pypi.org/project/hy/#description - Getting Hy on Python
https://lwn.net/Articles/596626/ - Programming Can Be Fun with Hy
https://opensourceforu.com/2014/02/programming-can-fun-hy/ - Přednáška o projektu Hy (pětiminutový lighttalk)
http://blog.pault.ag/day/2013/04/02 - Hy (Wikipedia)
https://en.wikipedia.org/wiki/Hy - GNU Emacs Lisp Reference Manual: Point
https://www.gnu.org/software/emacs/manual/html_node/elisp/Point.html - GNU Emacs Lisp Reference Manual: Narrowing
https://www.gnu.org/software/emacs/manual/html_node/elisp/Narrowing.html - GNU Emacs Lisp Reference Manual: Functions that Create Markers
https://www.gnu.org/software/emacs/manual/html_node/elisp/Creating-Markers.html - GNU Emacs Lisp Reference Manual: Motion
https://www.gnu.org/software/emacs/manual/html_node/elisp/Motion.html#Motion - GNU Emacs Lisp Reference Manual: Basic Char Syntax
https://www.gnu.org/software/emacs/manual/html_node/elisp/Basic-Char-Syntax.html - Elisp: Sequence: List, Array
http://ergoemacs.org/emacs/elisp_list_vs_vector.html - Elisp: Property List
http://ergoemacs.org/emacs/elisp_property_list.html - Elisp: Hash Table
http://ergoemacs.org/emacs/elisp_hash_table.html - Elisp: Association List
http://ergoemacs.org/emacs/elisp_association_list.html - The mapcar Function (An Introduction to Programming in Emacs Lisp)
https://www.gnu.org/software/emacs/manual/html_node/eintr/mapcar.html - Anaphoric macro
https://en.wikipedia.org/wiki/Anaphoric_macro - Some Common Lisp Loop Macro Examples
https://www.youtube.com/watch?v=3yl8o6r_omw - A Guided Tour of Emacs
https://www.gnu.org/software/emacs/tour/ - The Roots of Lisp
http://www.paulgraham.com/rootsoflisp.html - Evil (Emacs Wiki)
https://www.emacswiki.org/emacs/Evil - Evil (na GitHubu)
https://github.com/emacs-evil/evil - Evil (na stránkách repositáře MELPA)
https://melpa.org/#/evil - Evil Mode: How I Switched From VIM to Emacs
https://blog.jakuba.net/2014/06/23/evil-mode-how-to-switch-from-vim-to-emacs.html - GNU Emacs (home page)
https://www.gnu.org/software/emacs/ - GNU Emacs (texteditors.org)
http://texteditors.org/cgi-bin/wiki.pl?GnuEmacs - An Introduction To Using GDB Under Emacs
http://tedlab.mit.edu/~dr/gdbintro.html - An Introduction to Programming in Emacs Lisp
https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html - 27.6 Running Debuggers Under Emacs
https://www.gnu.org/software/emacs/manual/html_node/emacs/Debuggers.html - GdbMode
http://www.emacswiki.org/emacs/GdbMode - Emacs (Wikipedia)
https://en.wikipedia.org/wiki/Emacs - Emacs timeline
http://www.jwz.org/doc/emacs-timeline.html - Emacs Text Editors Family
http://texteditors.org/cgi-bin/wiki.pl?EmacsFamily - Vrapper aneb spojení možností Vimu a Eclipse
https://mojefedora.cz/vrapper-aneb-spojeni-moznosti-vimu-a-eclipse/ - Vrapper aneb spojení možností Vimu a Eclipse (část 2: vyhledávání a nahrazování textu)
https://mojefedora.cz/vrapper-aneb-spojeni-moznosti-vimu-a-eclipse-cast-2-vyhledavani-a-nahrazovani-textu/ - Emacs/Evil-mode – A basic reference to using evil mode in Emacs
http://www.aakarshnair.com/posts/emacs-evil-mode-cheatsheet - From Vim to Emacs+Evil chaotic migration guide
https://juanjoalvarez.net/es/detail/2014/sep/19/vim-emacsevil-chaotic-migration-guide/ - Introduction to evil-mode {video)
https://www.youtube.com/watch?v=PeVQwYUxYEg - EINE (Emacs Wiki)
http://www.emacswiki.org/emacs/EINE - EINE (Texteditors.org)
http://texteditors.org/cgi-bin/wiki.pl?EINE - ZWEI (Emacs Wiki)
http://www.emacswiki.org/emacs/ZWEI - ZWEI (Texteditors.org)
http://texteditors.org/cgi-bin/wiki.pl?ZWEI - Zmacs (Wikipedia)
https://en.wikipedia.org/wiki/Zmacs - Zmacs (Texteditors.org)
http://texteditors.org/cgi-bin/wiki.pl?Zmacs - TecoEmacs (Emacs Wiki)
http://www.emacswiki.org/emacs/TecoEmacs - Micro Emacs
http://www.emacswiki.org/emacs/MicroEmacs - Micro Emacs (Wikipedia)
https://en.wikipedia.org/wiki/MicroEMACS - EmacsHistory
http://www.emacswiki.org/emacs/EmacsHistory - Seznam editorů s ovládáním podobným Emacsu či kompatibilních s příkazy Emacsu
http://www.finseth.com/emacs.html - evil-numbers
https://github.com/cofi/evil-numbers - Debuggery a jejich nadstavby v Linuxu (1.část)
http://fedora.cz/debuggery-a-jejich-nadstavby-v-linuxu/ - Debuggery a jejich nadstavby v Linuxu (2.část)
http://fedora.cz/debuggery-a-jejich-nadstavby-v-linuxu-2-cast/ - Debuggery a jejich nadstavby v Linuxu (3): Nemiver
http://fedora.cz/debuggery-a-jejich-nadstavby-v-linuxu-3-nemiver/ - Debuggery a jejich nadstavby v Linuxu (4): KDbg
http://fedora.cz/debuggery-a-jejich-nadstavby-v-linuxu-4-kdbg/ - Debuggery a jejich nadstavby v Linuxu (5): ladění aplikací v editorech Emacs a Vim
https://mojefedora.cz/debuggery-a-jejich-nadstavby-v-linuxu-5-ladeni-aplikaci-v-editorech-emacs-a-vim/ - Org mode
https://orgmode.org/ - The Org Manual
https://orgmode.org/manual/index.html - Kakoune (modální textový editor)
http://kakoune.org/ - Vim-style keybinding in Emacs/Evil-mode
https://gist.github.com/troyp/6b4c9e1c8670200c04c16036805773d8 - Emacs – jak začít
http://www.abclinuxu.cz/clanky/navody/emacs-jak-zacit - Programovací jazyk LISP a LISP machines
https://www.root.cz/clanky/programovaci-jazyk-lisp-a-lisp-machines/ - Evil-surround
https://github.com/emacs-evil/evil-surround - Spacemacs
http://spacemacs.org/ - Lisp: Common Lisp, Racket, Clojure, Emacs Lisp
http://hyperpolyglot.org/lisp - Common Lisp, Scheme, Clojure, And Elisp Compared
http://irreal.org/blog/?p=725 - Does Elisp Suck?
http://irreal.org/blog/?p=675 - Emacs pro mírně pokročilé (9): Elisp
https://www.root.cz/clanky/emacs-elisp/ - If I want to learn lisp, are emacs and elisp a good choice?
https://www.reddit.com/r/emacs/comments/2m141y/if_i_want_to_learn_lisp_are_emacs_and_elisp_a/ - Clojure(Script) Interactive Development Environment that Rocks!
https://github.com/clojure-emacs/cider - An Introduction to Emacs Lisp
https://harryrschwartz.com/2014/04/08/an-introduction-to-emacs-lisp.html - Emergency Elisp
http://steve-yegge.blogspot.com/2008/01/emergency-elisp.html - Lambda calculus
https://en.wikipedia.org/wiki/Lambda_calculus - John McCarthy's original LISP paper from 1959
https://www.reddit.com/r/programming/comments/17lpz4/john_mccarthys_original_lisp_paper_from_1959/ - Micro Manual LISP
https://www.scribd.com/document/54050141/Micro-Manual-LISP - How Lisp Became God's Own Programming Language
https://twobithistory.org/2018/10/14/lisp.html - History of Lisp
http://jmc.stanford.edu/articles/lisp/lisp.pdf - The Roots of Lisp
http://languagelog.ldc.upenn.edu/myl/llog/jmc.pdf - Racket
https://racket-lang.org/ - The Racket Manifesto
http://felleisen.org/matthias/manifesto/ - MIT replaces Scheme with Python
https://www.johndcook.com/blog/2009/03/26/mit-replaces-scheme-with-python/ - Adventures in Advanced Symbolic Programming
http://groups.csail.mit.edu/mac/users/gjs/6.945/ - Why MIT Switched from Scheme to Python (2009)
https://news.ycombinator.com/item?id=14167453 - Starodávná stránka XLispu
http://www.xlisp.org/ - AutoLISP
https://en.wikipedia.org/wiki/AutoLISP - Seriál PicoLisp: minimalistický a výkonný interpret Lispu
https://www.root.cz/serialy/picolisp-minimalisticky-a-vykonny-interpret-lispu/ - Common Lisp
https://common-lisp.net/ - Getting Going with Common Lisp
https://cliki.net/Getting%20Started - Online Tutorial (Common Lisp)
https://cliki.net/online%20tutorial - Guile Emacs
https://www.emacswiki.org/emacs/GuileEmacs - Guile Emacs History
https://www.emacswiki.org/emacs/GuileEmacsHistory - Guile is a programming language
https://www.gnu.org/software/guile/ - MIT Scheme
http://groups.csail.mit.edu/mac/projects/scheme/ - SIOD: Scheme in One Defun
http://people.delphiforums.com/gjc//siod.html - CommonLispForEmacs
https://www.emacswiki.org/emacs/CommonLispForEmacs - Elisp: print, princ, prin1, format, message
http://ergoemacs.org/emacs/elisp_printing.html - Special Forms in Lisp
http://www.nhplace.com/kent/Papers/Special-Forms.html - Basic Building Blocks in LISP
https://www.tutorialspoint.com/lisp/lisp_basic_syntax.htm - Introduction to LISP – University of Pittsburgh
https://people.cs.pitt.edu/~milos/courses/cs2740/Lectures/LispTutorial.pdf - Why don't people use LISP
https://forums.freebsd.org/threads/why-dont-people-use-lisp.24572/ - Structured program theorem
https://en.wikipedia.org/wiki/Structured_program_theorem - Clojure: API Documentation
https://clojure.org/api/api - Tutorial for the Common Lisp Loop Macro
http://www.ai.sri.com/pkarp/loop.html - Common Lisp's Loop Macro Examples for Beginners
http://www.unixuser.org/~euske/doc/cl/loop.html - A modern list api for Emacs. No 'cl required.
https://github.com/magnars/dash.el - The LOOP Facility
http://www.lispworks.com/documentation/HyperSpec/Body/06_a.htm - Clojure.org: Vars and the Global Environment
http://clojure.org/Vars - Clojure.org: Refs and Transactions
http://clojure.org/Refs - Clojure.org: Atoms
http://clojure.org/Atoms - Clojure.org: Agents as Asynchronous Actions
http://clojure.org/agents - Transient Data Structureshttp://clojure.org/transients
- Dynamic Languages Strike Back
http://steve-yegge.blogspot.cz/2008/05/dynamic-languages-strike-back.html - Scripting: Higher Level Programming for the 21st Century
http://www.tcl.tk/doc/scripting.html - Clojure (na Wikipedia EN)
http://en.wikipedia.org/wiki/Clojure - Clojure (na Wikipedia CS)
http://cs.wikipedia.org/wiki/Clojure - SICP (The Structure and Interpretation of Computer Programs)
http://mitpress.mit.edu/sicp/ - Pure function
http://en.wikipedia.org/wiki/Pure_function - Funkcionální programování
http://cs.wikipedia.org/wiki/Funkcionální_programování - Jazyky Hy a Clojure-py: moderní dialekty LISPu určené pro Python VM
https://www.root.cz/clanky/jazyky-hy-a-clojure-py-moderni-dialekty-lispu-urcene-pro-python-vm/ - Pixie: lehký skriptovací jazyk s „kouzelnými“ schopnostmi
https://www.root.cz/clanky/pixie-lehky-skriptovaci-jazyk-s-kouzelnymi-schopnostmi/ - Programovací jazyk Pixie: funkce ze základní knihovny a použití FFI
https://www.root.cz/clanky/programovaci-jazyk-pixie-funkce-ze-zakladni-knihovny-a-pouziti-ffi/ - Stránka projektu Jython
http://www.jython.org/ - Jython (Wikipedia)
https://en.wikipedia.org/wiki/Jython - Scripting for the Java Platform (Wikipedia)
https://en.wikipedia.org/wiki/Scripting_for_the_Java_Platform - JSR 223: Scripting for the JavaTM Platform
https://jcp.org/en/jsr/detail?id=223 - List of JVM languages
https://en.wikipedia.org/wiki/List_of_JVM_languages - The JavaTM Virtual Machine Specification, Second Edition
http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html - The class File Format
http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html - javap – The Java Class File Disassembler
http://docs.oracle.com/javase/1.4.2/docs/tooldocs/windows/javap.html - javap-java-1.6.0-openjdk(1) – Linux man page
http://linux.die.net/man/1/javap-java-1.6.0-openjdk - Using javap
http://www.idevelopment.info/data/Programming/java/miscellaneous_java/Using_javap.html - Examine class files with the javap command
http://www.techrepublic.com/article/examine-class-files-with-the-javap-command/5815354 - Economy Size Geek – Interview with Rich Hickey, Creator of Clojure
https://www.linuxjournal.com/article/10708