Použití LISPu v praxi – AutoCAD a AutoLISP

Pavel Tišnovský 8. 4. 2010

V dnešní části našeho seriálu o historii výpočetní techniky si ukážeme jednu poměrně důležitou oblast informatiky, ve které byl s velkým úspěchem použit dialekt programovacího jazyka LISP. Jedná se o známou aplikaci AutoCAD s AutoLISPem později přejmenovaným na Visual LISP.

Obsah

1. Programování v LISPu prakticky – AutoCAD a AutoLISP

2. Úspěch „skriptovatelného“ CADu

3. Rozšiřování repertoáru příkazů AutoCADu

4. Volání funkcí AutoLISPu jako běžných AutoCADových příkazů

5. Opačný problém – volání AutoCADových výrazů z AutoLISPu

6. Grafická databáze AutoCADu

7. Složitější AutoLISPovské programy

8. Literatura

9. Odkazy na Internetu

1. Programování v LISPu prakticky – AutoCAD a AutoLISP

V předchozích částech tohoto seriálu jsme si popsali základní vlastnosti programovacího jazyka LISP a také jsme se zmínili o některých vlastnostech (především makrech) zavedených v jednom z nejrozšířenějších dialektů tohoto jazyka – Common Lispu. Zpočátku, zejména na přelomu šedesátých a sedmdesátých let minulého století, se programovací jazyk LISP a jeho dialekty (především Scheme) šířil a používal především mezi komunitou vědců zabývajících se výzkumem umělé inteligence a expertních systémů, ovšem posléze se některé jeho vlastnosti ukázaly být výhodné i pro značně odlišné typy aplikací. Příkladem může být známý skriptovatelný textový editor Emacs, jehož první verze byla vyvinuta Richardem Stallmanem spolu s  Guyem L. Steelem, o němž se ještě v tomto seriálu několikrát zmíníme, protože se mj. jedná i o spolutvůrce programovacího jazyka Scheme. Vraťme se však k použití programovacího jazyka LISP ve významných „velkých“ aplikacích.

Mezi uživateli osobních počítačů (PC) se již po velmi dlouhou dobu těší značné popularitě CAD systém AutoCAD, jehož první verze vznikla v počítačovém dávnověku, konkrétně v roce 1982. Jednou z příčin oblíbenosti AutoCADu byl i fakt, že tento nástroj obsahoval i interpret programovacího jazyka LISP odvozený od DOSové verze XLispu. Tento interpret byl zpočátku pojmenován AutoLISP, jeho pozdější verze se přejmenovaly na Visual LISP. Skripty psané v AutoLISPu mohly být použity pro velmi mnoho účelů, například mohly rozšiřovat repertoár příkazů dostupných uživateli (tyto příkazy bylo možné přidat do roletových menu, výběrových formulářů i takzvaného obrazovkového menu zobrazeného většinou na pravém okraji obrazovky – toto menu je vlastně předchůdcem dnešních toolbarů), provádět někdy i velmi komplikované operace s nakreslenými grafickými entitami či se dokonce jednalo o mnohdy velmi rozsáhlé nadstavby nad celým AudoCADem – existovaly například nadstavby určené pro tvorbu stavebních výkresů, elektrických schémat, architektonických výkresů či map (automatická tvorba vrstevnic, speciálních typů čar se symboly – elektrická či plynová vedení) atd.

2. Úspěch „skriptovatelného“ CADu

V současnosti není podpora skriptování ve větších aplikacích ničím zvláštní či dokonce revoluční, viz například různé balíčky „office“ vybavené interpretrem jazyka (Visual) Basic, Python atd., či plně skriptovatelné webové prohlížeče (Firefox), ovšem v dobách DOSu a (většinou) uzavřených CAD systémů umožnil AutoCAD, aby se na rozšiřování jeho funkcionality podíleli i zručnější uživatelé či další firmy, které tak vlastně firmě AutoDesk (výrobci AutoCADu) zvyšovaly obrat, protože se AutoCAD mohl používat i v těch oblastech, pro které původně nebyl určený (na druhou stranu je dnes kromě „plného“ AutoCADu nabízena i značně levnější varianta AutoCAD LT, která je v oblasti skriptování omezena). Pro ukázku možností skriptování AutoCADu se podívejte, jakým způsobem bylo možné modifikovat menu nabízené tabletem (na tablet se přikládala fólie nebo speciální šablona, na níž byly předtištěny ikony jednotlivých příkazů). Podobné LISPovské funkce bylo možné načítat přímo při startu AutoCADu, resp. při otevírání jednotlivých výkresů (vlastnost autoload):

;;; Set alternate tablet menus based on cfg settings
(defun set_alt_tabs ()

    ;; check for active tablet areas
    (setq T_Menu (read (ai_popmenucfg "T_Menu")))
    (mapcar
        '(lambda (x y z)
            (if (= (logand x T_Menu) x)
                (progn
                    (menucmd (strcat "T" y "=TABLET" y "ALT"))
                    (if (/= "" (getcfg "CfgData/Editor/TabletMenusActive"))
                        (eval z)
                    )
                )
            )
        )
        '(1 2 4 8)
        '("1" "2" "3" "4")
        '(
            (princ ;|ACAD_MNL_6|;"\nAlternativní oblast tabletu 1 načtena.  ")
            (princ ;|ACAD_MNL_10|;"\nAlternativní oblast tabletu 2 načtena.  ")
            (princ ;|ACAD_MNL_14|;"\nAlternativní oblast tabletu 3 načtena.  ")
            (princ ;|ACAD_MNL_18|;"\nAlternativní oblast tabletu 41 načtena.  ")
        )
    )
    (if (and (/= "" (getcfg "CfgData/Editor/TabletMenusActive"))
            (/= 0 T_Menu)
        )
        (terpri)
    )
    (setq set_alt_tabs nil)
)

3. Rozšiřování repertoáru příkazů AutoCADu

Nejčastějším použitím programovacího jazyka AutoLISP v AutoCADu byla tvorba poměrně jednoduchých funkcí, které rozšiřovaly repertoár příkazů nabízených samotným AutoCADem. Při tvorbě funkcí v AutoLISPu bylo samozřejmě možné používat prakticky všechny možnosti nabízené grafickým uživatelským rozhraním AutoCADu. Například zavolání funkce (getpoint „libovolná textová zpráva“) z LISPovského programu vedlo k tomu, že se uživateli zobrazilo zvolené textové hlášení na textové konzoli (nebo na posledních řádcích grafické obrazovky) s tím, že uživatel mohl myší, tabletem či s pomocí klávesnice provést výběr bodu ve výkresu, samozřejmě s využitím všech dostupných uchopovacích režimů (osnap modes), které AutoCAD nabízel – získání koncového bodu úsečky či jiné entity, prostředního bodu úsečky, středu kružnice či oblouku, průsečíku dvou entit atd. Bod vrácený funkcí (getpoint) obsahoval tři souřadnice [x,y,z] (jednalo se o běžný LISPovský seznam), nezávisle na tom, jakým způsobem byly tyto souřadnice získány. Pokud například uživatel potřeboval používat funkci pro výpočet vzdálenosti dvou bodů (ve skutečnosti by to nepotřeboval, protože taková funkce již existuje :-), mohl si ji jednoduše vytvořit:

(defun vzdalenost ()
    (setq bod1 (getpoint "\nZadej počáteční bod: ") )
    (setq bod2 (getpoint "\nZadej koncový bod: ") )
    (distance bod1 bod2)
)

Zavolání této funkce mohlo být provedeno buď z menu (to bylo plně konfigurovatelné) nebo přímo z příkazové řádky AutoCADu. Povšimněte si použití závorek při volání funkce z příkazového řádku i toho, že poslední výraz ve funkci vzdalenost je současně i její návratovou hodnotou, která je vypsána na textovou konzoli při návratu z funkce (pokud by poslední příkaz nevracel žádnou hodnotu, vypíše se nil, což se dá potlačit například zavoláním funkce (princ)):

(vzdalenost)

4. Volání funkcí AutoLISPu jako běžných AutoCADových příkazů

Ovšem nutnost psaní závorek při volání funkce (vzdalenost) ukázané v předchozí kapitole by běžné uživatele zbytečně mátla a zdržovala. Z tohoto důvodu bylo možné, aby se před jméno libovolné LISPovské funkce přidala dvojice znaků C:. Takto pojmenovaná funkce se pak mohla volat (spouštět) stejně jako jiný AutoCADovský příkaz, například line, insert či chprop:

(defun C:vzdalenost ()
    (setq bod1 (getpoint "\nZadej počáteční bod: ") )
    (setq bod2 (getpoint "\nZadej koncový bod: ") )
    (distance bod1 bod2)
)

Volání z příkazové řádky již nemůže být jednodušší:

vzdalenost

5. Opačný problém – volání AutoCADových výrazů z AutoLISPu

V mnoha případech však programátoři stáli před opačným problémem – potřebovali z AutoLISPovského programu zavolat nějaký uživatelský příkaz AutoCADu, například ve chvíli, kdy potřebovali nakreslit nějakou grafickou entitu, změnit její atributy (barvu, hladinu, typ čáry, text) atd. Tvůrci AutoCADu sice mohli zpřístupnit „pouze“ aplikační programové rozhraní (API) celého systému, ovšem to by znamenalo, že by se programátoři museli učit stejné funkce dvakrát – jednou by se jednalo o uživatelské příkazy (line – nakreslení čáry, copy – kopie objektu či objektů, zoom – změna pohledu), podruhé o funkci API. Namísto toho dali tvůrci AutoCADu všem programátorům kromě vlastního API k dispozici jedinou funkci nazvanou jednoduše (command), které bylo možné předat jak téměř libovolný AutoCADovský uživatelský příkaz, tak i parametry tohoto příkazu (a to stejným způsobem, jakým se zadávají při interaktivním zavolání tohoto příkazu z AutoCADu).

Například výše zmíněné programové vykreslení úsečky by se mohlo zajistit jedním z následujících volání funkce (command). Jednotlivá volání se liší pouze tím, že v prvním případě jsou všechny parametry předány formou řetězců (podobně, jako by je zapisoval uživatel na klávesnici) a ve druhém případě jako číselné hodnoty umístěné v seznamech, tj. tak, jak je může sestavit jakýkoli program. Posledním parametrem je prázdný řetězec, kterým je příkaz line ukončený, stejně jako v samotném AutoCADu, kde se používá buď mezerník nebo klávesa Enter:

(command "line" "0,0" "100,100", "" )

; apostrof před oběma seznamy je nutný, aby se
; LISP nepokoušel seznamy vyhodnotit
(command "line" '(0 0) '(100 100) "" )

Ve starších verzích AutoCADu neexistoval příkaz pro vykreslení osově orientovaného obdélníka, ovšem není žádný problém si ho dopsat. Na následujícím příkladu je asi nejzajímavější způsob vytvoření druhého a čtvrtého bodu, protože je nutné použít funkci (list) pro tvorbu seznamu. Posledním parametrem příkazu pline (polyčára) je řetězec „close“, kterým je polyčára uzavřena, takže vytvoří polygon:

(defun C:obdelnik()
    (setq bod1 (getpoint "\nZadej počáteční bod obdélníka: ") )
    (setq bod3 (getpoint "\nZadej protilehlý bod obdélníka: ") )
    (setq bod2 (list (car bod3) (cadr bod1) ) )
    (setq bod4 (list (car bod1) (cadr bod3) ) )
    (command "PLINE" bod1 bod2 bod3 bod4 "CLOSE")
)

6. Grafická databáze AutoCADu

Všechny výše ukázané demonstrační příklady byly poměrně jednoduché – v podstatě se jednalo o obdoby maker, jak je známe například z balíku aplikací OpenOffice.org. Ovšem programátoři v AutoLISPu mohli přímo přistupovat ke grafické databázi samotného AutoCADu, tj. k interním datovým strukturám, ze kterých je vytvořen celý výkres, což se ukázalo být velmi silným prostředkem, zejména při tvorbě složitějších nadstaveb. Výkres lze považovat za množinu grafických entit a každá entita má na sobě navázáno množství atributů – kromě geometrických informací (pozice koncových bodů úsečky, střed kružnice a její poloměr atd.) se jedná například o hladinu, ve které se entita nachází, barvu entity, typ čáry a mnohé další. Přístup k této databázi umožňuje provádět různé výběry entit či modifikaci jejich atributů. Následující příklad spočítá všechny úsečky, které se výkrese nachází:

; **********************************************************
; tato funkce vrátí počet všech úseček ve výkrese
; **********************************************************
(defun lines_count ()
    ; počitadlo entit
    (setq count 0)
    ; první entita v grafické databázi
    (setq entity (entnext))

    ; iterování seznamem všech entit
    (while entity
        ; získat seznam základních dat entity
        (setq entity_data (entget entity))

        ; pokud se jedná o úsečku
        (if (= "LINE" (cdr (assoc 0 entity_data)))
            ; zvýší se počitadlo úseček
            (setq count (1+ count))
        )
        ; přechod na další entitu ve výkresu
        (setq entity (entnext entity))
    )   ;konec while

    ; hodnota posledního výrazu ve funkci je i její návratovou hodnotou
    count
)

Jak jsme si již řekli, je možné atributy entit ve výkrese taktéž měnit, například přesunout všechny úsečky do zvolené hladiny:

; **********************************************************
; tato funkce přesune všechny úsečky do zvolené hladiny
; **********************************************************
;presun vsech kruznic do jine hladiny
(defun change_lines_layer (new_layer)
    ; počitadlo entit
    (setq count 0)
    ; první entita v grafické databázi
    (setq entity (entnext))

    ; iterování seznamem všech entit
    (while entity
        ; získat seznam základních dat entity
        (setq entity_data (entget entity))

        ; pokud se jedná o úsečku
        (if (= "LINE" (cdr (assoc 0 entity_data)))
            ; programový blok
            (progn
                ; zvýší se počitadlo úseček
                (setq count (1+ count))
                ; změna atributů grafické entity
                ; každý atribut je dvojice kód atributu:hodnota atributu
                (setq entity_data (subst (cons 8 new_layer) (assoc 8 entity_data) entity_data))
                (entmod entity_data)
            )
        )

        ; přechod na další entitu ve výkresu
        (setq entity (entnext entity))
    )   ;konec while
    ; hodnota posledního výrazu ve funkci je i její návratovou hodnotou
    count
)

7. Složitější AutoLISPovské programy

V této kapitole se ukážeme dva poněkud složitější AutoLISPovské programy. První příklad ukazuje použití rekurze při vykreslení takzvané Dračí křivky (Dragon curve), která má fraktální strukturu. Tento příklad se skládá ze dvou funkcí. První funkce je uživatelská (volá ji uživatel z AutoCADu) a slouží k inicializaci všech potřebných parametrů. Druhá funkce provádí vlastní vykreslování s rekurzivním zanořením, při němž se zkracuje délka vykreslovaných segmentů. Pokud je délka menší než zadaná hodnota, je rekurze ukončena:

; **********************************************************
; Inicializační funkce pro vykreslení fraktální Dračí křivky
; **********************************************************
(defun C:drak (/ point1 segment-length min-segment-length)
    (setq point1 (getpoint "\nEnter origin of curve: ")
    (setq segment-length (getdist "\nEnter length of one segment: ")
    (setq min-segment-length (getdist "\nEnter minimal segment length: "))
    ; vypnutí opisu všech příkazů na terminál
    (setvar "cmdecho" 0)
    ; vypnutí vykreslování pomocných bodů
    (setvar "blipmode" 0) ;vypne pomocné body
    ; začátek vykreslování polyčáry
    (command "PLINE" point1)
    (dragon-curve segment-length 0 1 min-segment-length)
    ; konec vykreslování polyčáry
    (command "")
    ; zapnutí opisu všech příkazů na terminál
    (setvar "cmdecho" 1)
)

; **********************************************************
; Tato funkce generuje fraktální (rekurzivní) Dračí křivku
; **********************************************************
(defun dragon-curve (segment-length uhel sign min-segment-length)
    (cond
        ( (< segment-length min-segment-length)
            (command (polar (getvar "LASTPOINT") uhel segment-length))
        )
        ; větev "else"
        ( T
            ; zkrácení délky segmentu o odmocninu ze dvou
            ; a provedení rekurze
            (dragon-curve (/ segment-length (sqrt 2.0))
                (+ uhel (* sign (/ pi 4.0)))
                1.0
                min-segment-length
            )
            ; zkrácení délky segmentu o odmocninu ze dvou
            ; a provedení rekurze
            (dragon-curve (/ segment-length (sqrt 2.0))
                (- uhel (* sign (/ pi 4.0)))
                -1.0
                min-segment-length
            )
        )
    )
)

Druhou AutoLISPovskou aplikaci jsem naprogramoval kdysi dávno pro dávkové převody souborů z formátu DXF (tyto soubory byly generovány mimo AutoCAD) do formátu DWF. Důvod tohoto převodu byl jednoduchý – výkresy ve formátu DWF je možné vystavit na internetu nebo intranetu, protože pro jejich prohlížení existují volně dostupné prohlížeče (buď jde o samostatné aplikace nebo o pluginy do prohlížečů). Na dále vypsané aplikaci je zajímavé především to, že je napsána čistě imperativně, na rozdíl od LISPaři prosazovaného funkcionálního přístupu:

widgety

;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;
;: Jednoducha aplikace pro davkovy prevod vykresove dokumentace
;: z formatu DXF do formatu DWF
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;



;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;
; Tato funkce slouzi k vymazani vsech entit z aktualne editova-
; neho vykresu. Soucasne s entitami dojde k vymazani vsech
; dalsich AutoCADovskych objektu, jako jsou typy car, dostupne
; fonty, hladiny a bloky.
;
; parametry: zadne
; vystupni hodnota: zadna
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;
(defun erase_drawing( / i)
    (command "_erase" "_all" "")
    (command "_purge" "_all" "*" "_n")
)



;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;
; Tato funkce funguje jako filtr, ktery ze jmena vstupniho
; souboru vytvori jmeno souboru vystupniho. Prevod se
; provadi tak, ze se odmaze jmeno koncovky vstupniho souboru
; (koncovka by mela byl .dxf) a pripoji se koncovka nova
; (v nasem konkretnim pripade .dwf).
;
; parametry: jmeno vstupniho souboru s koncovkou DXF
; vystupni hodnota: jmeno vystupniho souboru s koncovkou DWF
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;
(defun create_output_name(input_file_name / output_file_name name_length)
    (setq output_file_name "")
    (setq name_length (- (strlen input_file_name) 4))
    (setq output_file_name (substr input_file_name 1 name_length))
    (setq output_file_name (strcat output_file_name ".dwf"))
)



;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;
; Pomocna funkce provadejici import vykresu z formatu DXF
; a nasledny zoom na celou plochu vykresu
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;
(defun import_and_zoom(input_file_name)
    (command "_dxfin" input_file_name)
    (command "_zoom" "_all")
)



;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;
; Tato funkce prevede jeden vykres ze souboroveho formatu DXF do
; vystupniho souboroveho formatu DWF. Vystupni vykres ma pritom
; rozmery upravene tak, aby ho bylo mozne vytisknout na list
; papiru o normovane velikosti A3.
;
; parametry: jmeno vstupniho souboru s koncovkou DXF a DWF
; vystupni hodnota: zadna
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;
(defun create_dwf_a3(input_file_name output_file_name)
    (import_and_zoom input_file_name)
    (command "_plot" "_y" "" "DWF ePlot.pc3"
             "ISO A3 (420.00 x 297.00 MM)"
             "M" "K" "N" "" "" "" "_n" ""
             "_n" "_n" output_file_name "_y" "_y")
    (princ)
)



;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;
; Tato funkce prevede jeden vykres ze souboroveho formatu DXF do
; vystupniho souboroveho formatu DWF. Vystupni vykres ma pritom
; rozmery upravene tak, aby ho bylo mozne vytisknout na list
; papiru o normovane velikosti A3.
;
; parametry: jmeno vstupniho souboru s koncovkou DXF a DWF
; vystupni hodnota: zadna
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;
(defun create_dwf_a4(input_file_name output_file_name)
    (import_and_zoom input_file_name)
    (command "_plot" "_y" "" "DWF ePlot.pc3"
             "ISO A4 (210.00 x 297.00 MM)"
             "M" "K" "N" "" "" "" "_n" ""
             "_n" "_n" output_file_name "_y" "_y")
    (princ)
)



;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;
; Tato funkce prevede vsechny vykresy v adresari ze souboroveho
; formatu DXF do souboroveho formatu DWF. Pokud se na konci
; jmena souboru vyskytuje znak 'H', provede se prevod na papir
; velikosti A4, v opacnem pripade se prevadi na papir velikosti
; A3.
;
; parametry: zadne
; vystupni hodnota: zadna
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;
(defun C:convert_all( / cmd_echo work_dir dirlist fout)
    (command "_UNDO" "_C" "_O")
    (command "_UNDO" "_C" "_N")
    ; zapamatujeme si stav promenne prostredi CMDECHO
    (setq cmd_echo (getvar "CMDECHO"))
    (setvar "CMDECHO" 0)
    (setvar "SDI" 1)
    ; typ dialogu pro vyber souboru
    (setvar "FILEDIA" 0)
    ; nastavit promennou podle implicitniho ulozeni vykresu
    (setq work_dir "")
    ; uzivatel si vybere jeden vstupni soubor
    (setq work_dir (getfiled "Vyber jeden soubor z pracovniho adresare" work_dir "dxf" 0))
    ; zobrazeni terminalu
    (command "_textscr")
    (if (not (null work_dir))
        (progn
            ; vykousnuti adresare z celeho jmena souboru
            (setq work_dir (vl-filename-directory work_dir))
            (princ (strcat "Vypis vsech souboru v adresari " work_dir))
            ; ziskani vsech souboru se zadanou priponou
            (setq dirlist (vl-directory-files work_dir "*.dxf" 1))
            ; pro jistotu otestujeme spravnost naplneni seznamu,
            ; i kdyz by mel byt vzdy vytvoreny korektne
            (if (null work_dir)
                (progn
                    (princ "zadny soubor nenalezen")
                    (exit)
                )
            )
            ; logovaci soubor
            (setq fout (open "dxf2dwf.log" "w"))
            ; prochazeni celym seznamem s nalezenymi soubory
            (while (not (null dirlist))
                (setq full_name (strcat work_dir "\\" (car dirlist)))
                (print full_name)
                (princ full_name fout)

                ; test, zda konec jmena souboru neobsahuje na konci znak 'H'
                (setq name_length (- (strlen full_name) 4))
                (setq name_res (substr full_name name_length 1))
                (erase_drawing)
                (setq output_file_name (create_output_name full_name))
                ; kontrolni vypis nazvu vstupniho a vystuphiho souboru
                (print input_file_name)
                (print output_file_name)
                (if (= name_res "H")
                    ; obsahuje "H"
                    (create_dwf_a4 full_name output_file_name)
                    ; neobsahuje "H"
                    (create_dwf_a3 full_name output_file_name)
                )
                (princ "\n" fout)
                (setq dirlist (cdr dirlist))
            )
            (close fout)
        )
        (princ "Zadny soubor nebyl vybran")
    )
    (setvar "CMDECHO" cmd_echo)
    (prin1)
)

;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;
;; finito
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;

8. Literatura

  1. Hillis, D.
    „New Computer Architectures and Their Relationship to Physics or Why CS is No Good“
    Int J. Theoretical Physics 21 (3/4) 255–262.
  2. Lewis W. Tucker, George G. Robertson,
    „Architecture and Applications of the Connection Machine“
    Computer, vol. 21, no. 8, pp. 26–38, August, 1988.
  3. Arthur Trew and Greg Wilson (eds.) (1991)
    „Past, Present, Parallel: A Survey of Available Parallel Computing Systems“
    New York: Springer-Verlag. ISBN 0–387–19664–1.
  4. W. Daniel Hillis and Lewis W. Tucker
    „The CM-5 Connection Machine: A Scalable Supercomputer“
    In Communications of the ACM, Vol. 36, No. 11 (November 1993)
  5. Cliff Lasser, Jeff Mincy, J.P. Massar
    „The Essential *LISP Manual“
    Thinking Machines Corporation, 1986.
  6. Anonymous
    „Getting Started in *Lisp, Version 6.1“
    Thinking Machines Corporation, Cambridge, Massachusetts, June 1991.
  7. Anonymous
    „*Lisp Dictionary“
    Thinking Machines Corporation, Cambridge, Massachusetts.
  8. Anonymous
    „*Lisp Timesharing User's Guide“
    Online at CMU AI Repository
  9. Zdzislaw Meglicki
    „The CM5 *Lisp Course“
    Centre for Information Science Research, The Australian National University, 1994
  10. McCarthy
    „Recursive functions of symbolic expressions and their computation by machine, part I“
    1960
  11. Guy L. Steele
    „History of Scheme“
    2006, Sun Microsystems Laboratories
  12. Kolář J., Muller K.:
    „Speciální programovací jazyky“
    Praha 1981
  13. „AutoLISP Release 9, Programmer's re­ference“
    Autodesk Ltd., October 1987
  14. „AutoLISP Release 10, Programmer's re­ference“
    Autodesk Ltd., September 1988
  15. McCarthy, John; Abrahams, Paul W.; Edwards, Daniel J.; Hart, Timothy P.; Levin, Michael I.
    „LISP 1.5 Programmer's Ma­nual“
    MIT Press. ISBN 0 262 130 1 1 4
  16. Carl Hewitt; Peter Bishop and Richard Steiger
    „A Universal Modular Actor Formalism for Artificial Intelligence“
    1973
  17. Feiman, J.
    „The Gartner Programming Language Survey (October 2001)“
    Gartner Advisory

9. Odkazy na Internetu

  1. GNU Emacs
    http://www.gnu­.org/software/e­macs/emacs.html
  2. Emacs
    http://en.wiki­pedia.org/wiki/E­macs
  3. AutoCAD
    http://en.wiki­pedia.org/wiki/Au­tocad
  4. AutoLISP
    http://en.wiki­pedia.org/wiki/Au­toLISP
  5. (welcome '(schemers . org))
    http://www.sche­mers.org/
  6. Revised5 Report on the Algorithmic Language Scheme
    http://www.sche­mers.org/Docu­ments/Standar­ds/R5RS/
  7. The Revised6 Report on the Algorithmic Language Scheme
    http://www.r6rs­.org/
  8. Scheme
    http://groups­.csail.mit.edu/mac/pro­jects/scheme/
  9. The Kawa language framework
    http://www.gnu­.org/software/ka­wa/
  10. Scheme 48
    http://s48.org/
  11. Introductory textbooks for Schemers
    http://www.sche­mers.org/Docu­ments/#intro-texts
  12. Scheme (programming language)
    http://en.wiki­pedia.org/wiki/Sche­me_(programmin­g_language)
  13. Scheme
    http://cs.wiki­pedia.org/wiki/Sche­me
  14. Scheme-faq
    http://communi­ty.schemewiki­.org/?scheme-faq
  15. Scheme implementations
    http://communi­ty.schemewiki­.org/?scheme-faq-standards#imple­mentations
  16. Successful Scheme
    http://www.it­world.com/swol-1013-regex
  17. Why Java (and almost every other programming language) sucks (lisp)
    http://www.per­kiset.org/forum/pyt­honlispscheme­erlangobscuri­ties/why_java_an­d_almost_every_ot­her_programmin­g_language_suc­ks_lisp-t26.0.html;msg57#­msg57
  18. PLT Scheme
    http://www.plt-scheme.org/
  19. Guy L. Steele, Jr.
    http://en.wiki­pedia.org/wiki/Gu­y_L._Steele
  20. Gerald Jay Sussman
    http://en.wiki­pedia.org/wiki/Ge­rald_Jay_Sussman
  21. Lecture Notes: Macros
    http://www.apl­.jhu.edu/~hall/Lisp-Notes/Macros.html 
  22. Common Lisp's Loop Macro Examples for Beginners
    http://www.uni­xuser.org/~eus­ke/doc/cl/loop­.html
  23. Macro LOOP
    http://www.lis­pworks.com/do­cumentation/Hy­perSpec/Body/m_lo­op.htm
  24. Loop
    http://www.cs­.cmu.edu/Grou­ps/AI/html/cltl/­clm/node235.html
  25. Tutorial for the Common Lisp Loop Macro
    http://www.ai­.sri.com/~pkar­p/loop.html
  26. LISPová makra aneb programovatelný programovací jazyk
    http://www.ro­ot.cz/clanky/lis­pova-makra-aneb-programovatelny-programovaci-jazyk/
  27. Jemný úvod do LISPu
    http://www.ro­ot.cz/clanky/jem­ny-uvod-do-lispu/
  28. *Lisp
    http://en.wiki­pedia.org/wiki/*Lisp
  29. Lisp machine
    http://en.wiki­pedia.org/wiki/Lis­p_machine
  30. MIT CADR Lisp Machine FAQ
    http://www.un­lambda.com/ca­dr/cadr_faq.html
  31. Symbolics LISP Machines
    http://www.fro­benius.com/sym­bolics.htm
  32. UNIVAC
    http://en.wiki­pedia.org/wiki/U­nivac
  33. UNIVAC 1100/2200 series
    http://en.wiki­pedia.org/wiki/U­NIVAC_1100/220­0_series#UNIVAC_1100_se­ries
  34. Allegro CL Examples and Utilities
    http://examples­.franz.com/in­dex.html
  35. LISP 1.5 for the Univac 1100 Mainframe
    http://www.fro­benius.com/uni­vac.htm
  36. STARSIM: Thinking Machines' *Lisp Simulator
    http://www-2.cs.cmu.edu/af­s/cs/project/ai-repository/ai/lan­g/lisp/impl/star­lisp/0.html
  37. Connection Machine
    http://en.wiki­pedia.org/wiki/Con­nection_Machi­ne
  38. Connection Machine –1–2–5
    http://ed-thelen.org/comp-hist/vs-cm-1–2–5.html
  39. Richard Feynman and The Connection Machine
    http://www.lon­gnow.org/essa­ys/richard-feynman-connection-machine/
  40. Sheryl Handler
    http://en.wiki­pedia.org/wiki/She­ryl_Handler
  41. W. Daniel Hillis
    http://en.wiki­pedia.org/wiki/Dan­ny_Hillis
  42. The Rise and Fall of Thinking Machines
    http://www.in­c.com/magazine/19950915/­2622.html
  43. Lisp (programming language)
    http://en.wiki­pedia.org/wiki/Lis­p_(programmin­g_language)
  44. On Lisp
    http://paulgra­ham.com/onlis­ptext.html?as­df
  45. Lambda calculus
    http://en.wiki­pedia.org/wiki/Lam­bda_calculus
  46. A Short Introduction to the Lambda Calculus
    http://www.cs­.bham.ac.uk/~ax­j/pub/papers/lam­bda-calculus.pdf
  47. A Tutorial Introduction to the Lambda Calculus
    http://www.inf.fu-berlin.de/leh­re/WS03/alpi/lam­bda.pdf
  48. An Introduction to Scheme and its Implementation
    ftp://ftp.cs.u­texas.edu/pub/gar­bage/cs345/sch­intro-v14/schintro_toc­.html
  49. Humor on Computers, Systems and Programming
    http://www-crypto.htw-saarland.de/we­ber/misc/program­ming.html
  50. Teach Yourself Scheme in Fixnum Days
    http://www.ccs­.neu.edu/home/do­rai/t-y-scheme/t-y-scheme.html
  51. Rosetta Code – Category:Lisp
    http://rosetta­code.org/wiki/Ca­tegory:Lisp
  52. Retrocomputing – MIT CADR Lisp Machines
    http://www.un­lambda.com/ca­dr/index.html
Našli jste v článku chybu?
DigiZone.cz: Ultra HD v praxi a v Portugalsku

Ultra HD v praxi a v Portugalsku

120na80.cz: Co je padesátkrát sladší než cukr?

Co je padesátkrát sladší než cukr?

Vitalia.cz: Test dětských svačinek: Tyhle ne!

Test dětských svačinek: Tyhle ne!

120na80.cz: Galerie: Čínští policisté testují českou minerálku

Galerie: Čínští policisté testují českou minerálku

Vitalia.cz: Voda z Vltavy před a po úpravě na pitnou

Voda z Vltavy před a po úpravě na pitnou

Lupa.cz: Jak levné procesory změnily svět?

Jak levné procesory změnily svět?

Vitalia.cz: Jak Ondra o astma přišel

Jak Ondra o astma přišel

DigiZone.cz: Numan Two: rozhlasový přijímač s CD

Numan Two: rozhlasový přijímač s CD

Vitalia.cz: Tahák, jak vyzrát nad zápachem z úst

Tahák, jak vyzrát nad zápachem z úst

Root.cz: Hořící telefon Samsung Note 7 zapálil auto

Hořící telefon Samsung Note 7 zapálil auto

DigiZone.cz: Wimbledon na Nova Sport až do 2019

Wimbledon na Nova Sport až do 2019

Vitalia.cz: 5 chyb, které děláme při skladování potravin

5 chyb, které děláme při skladování potravin

DigiZone.cz: DVB-T2 ověřeno: seznam TV zveřejněn

DVB-T2 ověřeno: seznam TV zveřejněn

Lupa.cz: Adblock Plus začal prodávat reklamy

Adblock Plus začal prodávat reklamy

Měšec.cz: TEST: Vyzkoušeli jsme pražské taxikáře

TEST: Vyzkoušeli jsme pražské taxikáře

Vitalia.cz: Antibakteriální mýdla nepomáhají, spíš škodí

Antibakteriální mýdla nepomáhají, spíš škodí

Podnikatel.cz: Nemá dluhy? Zjistíte to na poště

Nemá dluhy? Zjistíte to na poště

Vitalia.cz: Tesco nabízí desítky tun jídla zdarma

Tesco nabízí desítky tun jídla zdarma

DigiZone.cz: Nova opět stahuje „milionáře“

Nova opět stahuje „milionáře“

Lupa.cz: Jak se prodává firma za miliardu?

Jak se prodává firma za miliardu?