Provided by: manpages-pl_20060617-3_all bug

NAZWA

       lisp-tut - Wskazowki dla Common LISP

OPIS

       Uwaga:  to  wprowadzenie  do Common Lisp zostalo napisane dla rodowiska
       CMU, wic niektore fragmenty pracy z lispem mog si troch roni  w  ronych
       miejscach.

Inne r'od/la informacji

       Najlepsza ksika o LISP, ktor znam, to

       Guy L. Steele Jr. _Common LISP: the Language_. Digital Press. 1984.

       Pierwsza edycja jest latwiejsza do czytania; druga opisuje troch nowszy
       standard. (Ronice midzy standardami nie powinny sprawia  ronic  zwyklym
       programistom).

       Polecano  mi  rownie  ksik Dave'a Touretsky'ego, cho nie czytalem jej i
       nie mog o niej nic powiedzie.

Symbole

       Symbol to lacuch znakow. Istniej  ograniczenia  co  do  tego,  co  mona
       wstawi  do  symbolu  i  co moe by pierwszym znakiem, lecz tak dlugo jak
       uywasz prostych liter, cyfr i mylnikow, nic si nie stanie.  (Poza  tym,
       e  jeli uywasz tylko cyfr i prawdopodobnie pocztkowego mylnika, to LISP
       moe pomyle, e to liczba calkowita, a nie symbol.)  Przyklady symboli:

               a
               b
               c1
               foo
               bar
               baaz-quux-garply

       Dalej przedstawiamy kilka rzeczy, ktore mona zrobi z symbolami. (Rzeczy
       po  znaku  zachty  ">"  s  tym,  co  naley wstuka do interpretera LISP,
       podczas gdy inne rzeczy s odpowiedziami, drukowanymi przez  LISP.  Znak
       ";"  jest  LISP-owym  znakiem komentarza: wszystko od ";" do koca linii
       jest ignorowane.

       > (setq a 5)         ;zachowaj liczb jako warto symbolu
       5
       > a                  ;pobierz warto symbolu
       5
       > (let ((a 6)) a)    ;przywi tymczasowo warto symbolu do 6
       6
       > a                  ;po zakoczeniu let, warto wraca do 5
       5
       > (+ a 6)            ;uyj wartoci symbolu jako argumentu funkcji
       11
       > b                  ;sprobuj pobra warto symbolu, ktory nie ma wartoci
       Error: Attempt to take the value of the unbound symbol B

       Istniej dwa symbole specjalne, `t' i `nil'. Warto `t' jest zdefiniowana
       zawsze  jako  `t',  a  warto `nil' jest zdefiniowana zawsze jako `nil'.
       LISP uywa `t' i `nil' do reprezentowania prawdy i  falszu.  Przykladowe
       uycie, opisane dokladniej dalej:

       > (if t 5 6)
       5
       > (if nil 5 6)
       6
       > (if 4 5 6)
       5

       Ostatni przyklad jest cudaczny, lecz prawidlowy: `nil' oznacza falsz, a
       wszystko inne oznacza prawd. (O ile nie  mamy  potrzeby  robi  inaczej,
       uywamy t do oznaczania prawdy, tak dla czystej prostoty.)

       Symbole  takie  jak  `t'  i  `nil' s nazywane samorozwijajcymi, poniewa
       rozwijaj si same na siebie. Istnieje  cala  klasa  samorozwijajcych  si
       symboli,  zwanych  slowami  kluczowymi;  dowolny  symbol, ktorego nazwa
       rozpoczyna  si  od  dwukropka  jest  slowem  kluczowym.  (Zobacz   niej
       przyklady zastosowa slow kluczowych.) Przyklady:

       > :this-is-a-keyword
       :THIS-IS-A-KEYWORD
       > :so-is-this
       :SO-IS-THIS
       > :me-too
       :ME-TOO

Liczby

       Liczba ca/lkowita jest lacuchem cyfr, opcjonalnie poprzedzonych + lub -.
       Liczba rzeczywista wyglda jak liczba calkowita, lecz ma kropk  dziesitn
       i  moe by zapisana w notacji naukowej.  Liczba wymierna wyglda jak dwie
       liczby calkowite z kresk  ulamkow  /  midzy  nimi.  LISP  obsluguje  te
       liczbyzespolone,  ktore  s  zapisywane  jako #c(r i) (gdzie r jest czci
       rzeczywist,  a  i  jest  czci  urojon).  Liczb  jest  dowolny  zapis  z
       powyszych. Przyklady:

               5
               17
               -34
               +6
               3.1415
               1.722e-15
               #c(1.722e-15 0.75)

       Standardowe  funkcje  arytmetyczne  s  wci  dostpne: +, -, *, /, floor,
       ceiling, mod, sin, cos, tan,  sqrt,  exp,  expt,  itd.   Wszystkie  one
       przyjmuj  dowolny rodzaj argumentu. +, -, * i / zwracaj liczb zgodnie z
       nastpujcymi zasadami: liczba  calkowita  plus  wymierna  daje  wymiern,
       wymierna  plus rzeczywist daje rzeczywist, a rzeczywista plus zespolona
       daje zespolon. Oto przyklady:

       > (+ 3 3/4)             ;determinacja typu wynikowego
       15/4
       > (exp 1)               ;e
       2.7182817
       > (exp 3)               ;e*e*e
       20.085537
       > (expt 3 4.2)          ;potga o podstawie innej ni e
       100.90418
       > (+ 5 6 7 (* 8 9 10))  ;funkcje +-*/ przyjmuj argumenty wielokrotne

       Nie ma ogranicze w absolutnej wartoci liczby calkowitej, poza rozmiarem
       pamici  komputera. Ostrzegam jednak, e obliczenia na duych liczbach mog
       by wolne. (Podobnie jak obliczenia na liczbach wymiernych,  szczegolnie
       w   porownaniu   do   oblicze   na   malych  liczbach  calkowitych  lub
       rzeczywistych.)

Wagoniki (ang. conses)

       Wagonik jest zwyklym dwuelementowym rekordem. Z przyczyn  historycznych
       jego  pola  s nazywane "car" i "cdr". (Na pierwszej maszynie, na ktorej
       zaimplementowano LISP  istnialy  dwie  instrukcje,  CAR  i  CDR,  ktore
       oznaczaly  "contents  of  address  register"  i  "contents of decrement
       register".  Wagoniki byly zaimplementowane przy uyciu tych rejestrow.)

       Wagoniki s latwe w uyciu:

       > (cons 4 5)            ;Zaalokuj wagonik. Ustaw car na 4 a cdr na 5.
       (4 . 5)
       > (cons (cons 4 5) 6)
       ((4 . 5) . 6)
       > (car (cons 4 5))
       4
       > (cdr (cons 4 5))
       5

Listy

       Z wagonikow mona budowa wiele struktur. Pewnie  najprostsz  jest  lista
       powizana:  car  kadego  wagonika wskazuje na jeden z elementow listy, a
       cdr albo na nastpny element, albo na nil.  Moesz  stworzy  tak  powizan
       list przy uyciu funkcji list:

       > (list 4 5 6)
       (4 5 6)

       Zauwa,  e  LISP  drukuje  powizane  listy  w  szczegolny sposob: pomija
       niektore kropki i nawiasy. Zasada jest taka: jeli cdr wagonika to  nil,
       LISP  nie drukuje kropki, ani nil; jeli cdr wagonika A to wagonik B, to
       nie drukuje kropki dla wagonika A, ani nawiasow dla wagonika B. Wic:

       > (cons 4 nil)
       (4)
       > (cons 4 (cons 5 6))
       (4 5 . 6)
       > (cons 4 (cons 5 (cons 6 nil)))
       (4 5 6)

       Ostatni przyklad jest rownowany  dokladnie  wywolaniu  (list  4  5  6).
       Zauwa,  e nil oznacza teraz list bez elementow: cdr listy 2 elementowej
       (a b) to (b), lista o jednym elemencie; cdr 1 elementowego (b) to  nil,
       ktory jest list bez elementow.

       Pusty (nil) car i cdr jest definiowany jako `nil'.

       Jeli  zapisujesz  swoj list w zmiennej, moesz spowodowa, e bdzie dziala
       jak stos:

       > (setq a nil)
       NIL
       > (push 4 a)
       (4)
       > (push 5 a)
       (5 4)
       > (pop a)
       5
       > a
       (4)
       > (pop a)
       4
       > (pop a)
       NIL
       > a
       NIL

Funkcje

       Powyej byl przyklad funkcji. Oto kilka innych:

       > (+ 3 4 5 6)                  ;ta funkcja pobiera dowoln liczb argumentow
       18
       > (+ (+ 3 4) (+ (+ 4 5) 6))    ;czy notacja przedrostkowa nie jest super?
       22
       > (defun foo (x y) (+ x y 5))  ;definiowanie funkcji
       FOO
       > (foo 5 0)                    ;wolanie funkcji
       10
       > (defun fact (x)              ;funkcja rekursywna
           (if (> x 0)
             (* x (fact (- x 1)))
             1
         ) )
       FACT
       > (fact 5)
       120
       > (defun a (x) (if (= x 0) t (b (- x))))    ;funkcje wzajemnie rekurencyjne
       A
       > (defun b (x) (if (> x 0) (a (- x 1)) (a (+ x 1))))
       B
       > (a 5)
       T
       > (defun bar (x)                ;funkcja o wielu instrukcjach w swoim
           (setq x (* x 3))            ;ciele -- zwroci warto, zwracan przez
           (setq x (/ x 2))            ;jej ostatni instrukcj
           (+ x 4)
         )
       BAR
       > (bar 6)
       13

       Gdy zdefiniowalimy `foo', nadalimy mu dwa argumenty, `x' i `y'.  Teraz,
       gdy  wolamy `foo', musimy poda dokladnie dwa argumenty: pierwszy stanie
       si na czas wywolania wartoci `x', a drugi stanie  si  wartoci  `y'.   W
       lispie  wikszo  zmiennych jest zawona leksykalnie; to znaczy jeli `foo'
       wola `bar', a `bar' probuje odnie si do `x', to nie jest to moliwe.

       Proces przyznawania symbolowi wartoci na czas  zawe  leksykalnych  jest
       nazywany wizaniem (binding).

       Dla  swoich  funkcji moesz podawa argumenty dodatkowe. Kady argument po
       symbolu &optional jest opcjonalny:

       > (defun bar (x &optional y) (if y x 0))
       BAR
       > (defun baaz (&optional (x 3) (z 10)) (+ x z))
       BAAZ
       > (bar 5)
       0
       > (bar 5 t)
       5
       > (baaz 5)
       15
       > (baaz 5 6)
       11
       > (baaz)
       13

       Funkcj `bar' mona wywola z jednym lub dwoma argumentami. Po wywolaniu z
       jednym  argumentem,  warto  `x' jest ustawiana normalnie, natomiast `y'
       jest ustawiane na `nil'. Po wywolaniu z dwoma argumentami, warto `x'  i
       `y' zostanie odpowiednio nimi zainicjalizowana.

       Funkcja  `baaz'  ma  dwa  argumenty  opcjonalne. Dla kadego z nich daje
       warto domyln: jeli wolajcy poda  tylko  jeden  argument,  `z'  zostanie
       zwizane  nie  z  `nil',  lecz  z  10,  a  gdy  wolajcy w ogole nie poda
       argumentow, `x' zostanie powizany z 3, a `z' z 10.

       Moesz spowodowa, e funkcja przyjmuje dowoln liczb argumentow, koczc jej
       argument  parametrem  &rest.  LISP wtedy zbierze wszystkie argumenty do
       listy i przywie j do parametru &rest.

       > (defun foo (x &rest y) y)
       FOO
       > (foo 3)
       NIL
       > (foo 4 5 6)
       (5 6)

       W  kocu,  moesz  poda   swojej   funkcji   dowolny   rodzaj   argumentu
       opcjonalnego,  zwanego argumentem s/lowa kluczowego.  Wolajcy moe podawa
       takie  argumenty  w  dowolnej  kolejnoci--s  one  etykietowane  slowami
       kluczowymi.

       > (defun foo (&key x y) (cons x y))
       FOO
       > (foo :x 5 :y 3)
       (5 . 3)
       > (foo :y 3 :x 5)
       (5 . 3)
       > (foo :y 3)
       (NIL . 3)
       > (foo)
       (NIL)

       Parametr &key moe mie rownie warto domyln:

       > (defun foo (&key (x 5)) x)
       FOO
       > (foo :x 7)
       7
       > (foo)
       5

Drukowanie

       Niektore  funkcje  mog  przesyla dane na wyjcie. Najprostsz jest print,
       ktora drukuje swoj argument i zwraca go.

       > (print 3)
       3
       3

       Pierwsze 3 zostalo wydrukowane, drugie zwrocone.

       Jeli oczekujesz  bardziej  zloonego  wyjcia,  musisz  uy  formatu.  Oto
       przyklad:

       > (format t "An atom: ~S~%and a list: ~S~%and an integer: ~D~%"
                 nil (list 5) 6)
       An atom: NIL
       and a list: (5)
       and an integer: 6

       Pierwszy  argument  instrukcji  format  to  `t', `nil' lub strumie. `T'
       wskazuje na wyjcie na terminal.  `Nil'  oznacza,  e  niczego  nie  mona
       drukowa,  a  naley zamiast tego powroci do lacucha zawierajcego wyjcie.
       Strumienie s ogolnymi miejscami przeplywu  wyjcia:  wskazuj  na  pliki,
       terminale  lub  inne  programy.  Ten  podrcznik nie bdzie si dokladniej
       zajmowal strumieniami.

       Kolejnym  argumentem  jest  matryca  formatujca,  ktora  jest  lacuchem
       opcjonalnie zawierajcym dyrektywy formatujce.

       Wszystkie pozostale argumenty mog by uywane przez dyrektywy formatujce.
       LISP zamieni dyrektywy na odpowiednie znaki, w  oparciu  argumenty,  do
       ktorych   (dyrektywy)   si   one   odnosz.   Nastpnie  lacuch  zostanie
       wydrukowany.

       Format zawsze zwraca `nil', chyba  e  jego  pierwszym  argumentem  jest
       `nil'--wtedy nic nie drukuje i zwraca lacuch.

       W  powyszym  przykladzie  istniej  trzy  rone  dyrektywy:  ~S, ~D i ~%.
       Pierwsza przyjmuje dowolny obiekt  LISP  i  jest  zamieniana  drukowaln
       reprezentacj  tego  obiektu  (tak  sam,  jak  produkowana przez print).
       Druga przyjmuje tylko liczby  calkowite.  Ostatnia  nie  odnosi  si  do
       argumentu.  Jest zawsze zamieniana na powrot karetki.

       Inn przydatn dyrektyw jest ~~, ktora jest zamieniana na pojedyncz `~'.

       Zajrzyj do podrcznika LISP, s tam rone inne dyrektywy formatujce.

Formy i ptla g/l'owna

       Wszystko,  co wpisujesz do interpretera LISP okrelane jest mianem form;
       interpreter odczytuje tak form, analizuje j i drukuje wynik.  Procedura
       ta jest nazywana ptl odczytu-analizy-drukowania.

       Niektore  formy  mog  dawa  bldy.  Po  bldzie,  LISP  przerzuci  ci  do
       debuggera, aby mogl znale bld. Kady debugger  LISP  jest  inny;  jednak
       wikszo z nich odpowiada na komend "help" lub ":help".

       Ogolnie,  form jest zarowno atom (np. symbol, liczba calkowita, lacuch)
       jak lista. Jeli forma jest atomem, LISP analizuje j  natychmiast.  Jeli
       jest  list,  to jej pierwszy element jest traktowany jak nazwa funkcji;
       pozostale elementy analizowane s rekurencyjnie i wywoluje si t funkcj z
       wartociami pozostalych elementow jako argumentami.

       Na  przyklad,  jeli  LISP  widzi  form  (+ 3 4), traktuje `+' jako nazw
       funkcji. Potem analizuje 3 aby pobra 3 i 4 aby pobra 4; w kocu wola `+'
       z  argumentami  3  i  4.  Funkcja  `+' zwraca 7, co jest drukowane jako
       wynik.

       Ptla glowna daje  inne  udogodnienia;  szczegolnie  wygodn  rzecz  jest
       moliwo  mowienia  o  wynikach  poprzednio  wpisanych  form. LISP zawsze
       udostpnia swoje trzy najwiesze wyniki; kryj si one pod symbolami *,  **
       i ***. Na przyklad:

       > 3
       3
       > 4
       4
       > 5
       5
       > ***
       3
       > ***
       4
       > ***
       5
       > **
       4
       > *
       4

Formy specjalne

       Istnieje  pewna  liczba  form  specjalnych, ktore wygldaj jak wywolania
       funkcji, lecz nimi nie s. Zaliczaj si  do  nich  konstrukcje  sterujce,
       takie  jak  instrukcje  if i ptle do; przypisania takie jak setq, setf,
       push i pop; definicje takie, jak defunidefstruct;  a  take  konstrukcje
       wice,  takie  jak  let.  (Nie wszystkie te formy zostaly ju wymienione.
       Patrz niej.)

       Jedn przydatn form specjaln jest forma cytowania  (quote):  chroni  ona
       argument przed zanalizowaniem. Na przyklad:

       > (setq a 3)
       3
       > a
       3
       > (quote a)
       A
       > 'a                    ;'a jest skrotem dla (quote a)
       A

       Inn  prost form specjaln jest forma funkcji (function): powoduje, e jej
       argument jest interpretowany jako funkcja:

       > (setq + 3)
       3
       > +
       3
       > '+
       +
       > (function +)
       #<Function + @ #x-fbef9de>
       > #'+                   ;#'+ jest skrotem dla (function +)
       #<Function + @ #x-fbef9de>

       Ta forma specjalna jest  przydatna  gdy  chcesz  przekaza  funkcj  jako
       argument do innej funkcji. Niej s przyklady funkcji, biorcych argumenty
       funkcyjne.

Wizanie

       Wizanie to zawone leksykalnie  przypisanie.  Zachodzi  na  zmiennych  w
       licie   parametrow   funkcji  za  kadym  wywolaniem  funkcji:  formalne
       parametry s  wizane  do  rzeczywistych  parametrow  na  czas  wywolania
       funkcji.   Zmienne  mona  wiza  w  dowolnym  miejscu  programu,  uywajc
       specjalnej formy let, ktora wyglda tak:

               (let ((var1 val1)
                     (var2 val2)
                     ...
                    )
                 body
               )

       `Let' wie `var1' do `val1' i `var2' do  `val2'  (i  tak  dalej);  potem
       wykonuje instrukcje swojego ciala. Cialo `let' podpada pod dokladnie te
       same reguly, co cialo funkcji. Przyklady:

       > (let ((a 3)) (+ a 1))
       4
       > (let ((a 2)
               (b 3)
               (c 0))
           (setq c (+ a b))
           c
         )
       5
       > (setq c 4)
       4
       > (let ((c 5)) c)
       5
       > c
       4

       Zamiast (let ((a nil) (b nil)) ...), moesz napisa (let (a b) ...).

       `Val1', `val2', itd. wewntrz `let'  nie  mog  odnosi  si  do  zmiennych
       `var1', `var2', itd., ktore s wizane. Na przyklad

       > (let ((x 1)
               (y (+ x 1)))
           y
         )
       Error: Attempt to take the value of the unbound symbol X

       Jeli symbol `x' ju ma warto globaln, wynikiem bd dziwne zdarzenia:

       > (setq x 7)
       7
       > (let ((x 1)
               (y (+ x 1)))
           y
         )
       8

       Forma  specjalna  let* jest podobna do `let', lecz zezwala wartociom na
       wskazywanie na zmienne, zdefiniowane w `let' wczeniej. Na przyklad:

       > (setq x 7)
       7
       > (let* ((x 1)
                (y (+ x 1)))
           y
         )
       2

       Forma

               (let* ((x a)
                      (y b))
                 ...
               )

       jest rownowana

               (let ((x a))
                 (let ((y b))
                   ...
               ) )

Zakresy dynamiczne

       Formy `let' i `let*' daj  zawanie  leksykalne,  ktore  jest  rzecz,  do
       ktorej  mogle  si  przyzwyczai  w  C  lub  Pascalu.  Zakresy  (zawanie)
       dynamiczne s popularne  w  BASIC-u:  jeli  przypiszesz  warto  zmiennej
       dynamicznej,  kade  wspomnienie  tej zmiennej zwraca nadan warto, a nie
       przyznasz nowej.

       W  LISP-ie,  zmienne  dynamicznego   zakresu   s   nazywane   zmiennymi
       specjalnymi.   Moesz  je  deklarowa  w  formie  defvar.  Oto  przyklady
       zmiennych dynamicznie i leksykalnie zawanych.

       W tym  przykladzie,  funkcja  `check-regular'  odnosi  si  do  zmiennej
       `regular'  (np.  leksykalnej). Poniewa `check-regular' jest leksykalnie
       poza `let', ktory wie `regular', `check-regular' zwraca  globaln  warto
       zmiennej.

       > (setq regular 5)
       5
       > (defun check-regular () regular)
       CHECK-REGULAR
       > (check-regular)
       5
       > (let ((regular 6)) (check-regular))
       5

       W  tym  przykladzie,  funkcja  `check-special'  odnosi  si  do zmiennej
       `special' (np.  dynamicznie zawonej). Poniewa wywolanie `check-special'
       jest  tymczasowo  wewntrz  `let',  ktory wie `special', `check-special'
       zwraca lokaln warto zmiennej.

       > (defvar *special* 5)
       *SPECIAL*
       > (defun check-special () *special*)
       CHECK-SPECIAL
       > (check-special)
       5
       > (let ((*special* 6)) (check-special))
       6

       Tradycyjnie, nazwa zmiennej specjalnej rozpoczyna si  od  `*'.  Zmienne
       specjalne  s  uywane  glownie  jako  zmienne  globalne,  gdy programici
       zazwyczaj oczekuj dla zmiennych lokalnych zawania leksykalnego,  a  dla
       globalnych dynamicznego.

       Dla  dalszych  informacji  o  ronicach  midzy  zaweniami leksykalnymi i
       dynamicznymi, zobacz Common LISP: the Language.

Tablice

       Funkcja make-array tworzy  tablic.  Funkcja  aref  daje  dostp  do  jej
       elementow.  Wszystkie  elementy tablicy s pocztkowo ustawione na `nil'.
       Na przyklad:

       > (make-array '(3 3))
       #2a((NIL NIL NIL) (NIL NIL NIL) (NIL NIL NIL))
       > (aref * 1 1)
       NIL
       > (make-array 4)        ;tablice 1D nie wymagaj dodatkowych nawiasow
       #(NIL NIL NIL NIL)

       Indeksy tablic zawsze rozpoczynaj si od 0.

       Jak ustawia elementy tablicy, opisano niej.

Napisy

       Napis jest sekwencj znakow w podwojnych cudzyslowach. W LISP napis jest
       reprezentowany jako tablica znakow o zmiennej dlugoci. Napis zawierajcy
       podwojne cudzyslowy mona zapisa, poprzedzajc cudzyslow  znakiem  lewego
       ukonika;  podwojny  lewy  ukonik  oznacza  pojedynczy  lewy  ukonik. Na
       przyklad:

               "abcd" ma 4 znaki
               "\"" ma 1 znak
               "\\" ma 1 znak

       Oto kilka funkcji zajmujcych si napisami:

       > (concatenate 'string "abcd" "efg")
       "abcdefg"
       > (char "abc" 1)
       #\b                     ;LISP zapisuje znaki poprzedzone #\
       > (aref "abc" 1)
       #\b                     ;pamitaj, napisy w rzeczywistoci s tablicami

       Funkcja concatenate moe w  rzeczywistoci  dziala  z  dowolnym  rodzajem
       sekwencji:

       > (concatenate 'string '(#\a #\b) '(#\c))
       "abc"
       > (concatenate 'list "abc" "de")
       (#\a #\b #\c #\d #\e)
       > (concatenate 'vector '#(3 3 3) '#(3 3 3))
       #(3 3 3 3 3 3)

Struktury

       Struktury  LISP  s  analogiczne do struktur C lub rekordow Pascala. Oto
       przyklad:

       > (defstruct foo
           bar
           baaz
           quux
         )
       FOO

       Przyklad ten definiuje typ danych o nazwie `foo', ktory jest  struktur,
       zawierajc  3  pola.  Definiuje  te 4 funkcje, ktore operuj na tym typie
       danych: make-foo, foo-bar, foo-baaz i foo-quux.  Pierwsza  tworzy  nowy
       obiekt  typu  `foo'; pozostale daj dostp do poszczegolnych pol obiektu.
       Oto jak uywa tych funkcji:

       > (make-foo)
       #s(FOO :BAR NIL :BAAZ NIL :QUUX NIL)
       > (make-foo :baaz 3)
       #s(FOO :BAR NIL :BAAZ 3 :QUUX NIL)
       > (foo-bar *)
       NIL
       > (foo-baaz **)
       3

       Funkcja `make-foo' moe pobiera argument  slowa  kluczowego  dla  kadego
       pola  struktury  `foo'.  Funkcje dostpu do pol pobieraj jeden argument,
       struktur typu `foo' i zwracaj odpowiedni warto.

       Zobacz niej jak ustawi pola struktury.

Setf

       Pewne formy w LISP-ie naturalnie definiuj pozycj w pamici. Na przyklad,
       jeli  warto `x' jest struktur typu `foo', to (foo-bar x) definiuje pole
       `bar' o wartoci `x'. Lub jeli  warto  `y'  jest  jednowymiarow  tablic,
       (aref y 2) definiuje trzeci element `y'.

       Specjalna forma setf uywa swojego pierwszego argumentu do zdefiniowania
       miejsca w pamici, analizuje drugi argument i zapisuje wynik w wynikowej
       pozycji pamici. Na przyklad,

       > (setq a (make-array 3))
       #(NIL NIL NIL)
       > (aref a 1)
       NIL
       > (setf (aref a 1) 3)
       3
       > a
       #(NIL 3 NIL)
       > (aref a 1)
       3
       > (defstruct foo bar)
       FOO
       > (setq a (make-foo))
       #s(FOO :BAR NIL)
       > (foo-bar a)
       NIL
       > (setf (foo-bar a) 3)
       3
       > a
       #s(FOO :BAR 3)
       > (foo-bar a)
       3

       Setf jest jedynym sposobem na ustawianie pol struktury lub tablicy.

       Oto kilka innych przykladow setf i zwizanych z nim funkcji.

       > (setf a (make-array 1))       ;setf na zmiennej jest rownowane setq
       #(NIL)
       > (push 5 (aref a 1))           ;push moe dziala jak setf
       (5)
       > (pop (aref a 1))              ;podobnie pop
       5
       > (setf (aref a 1) 5)
       5
       > (incf (aref a 1))             ;incf odczytuje z danego miejsca,
       6                               ;inkrementuje i zapisuje z powrotem.
       > (aref a 1)
       6

Zmienne logiczne i warunki

       LISP  do  oznaczania  falszu uywa symbolu `nil'. Wszystko inne ni `nil'
       oznacza prawd. O ile nie mamy specjalnych powodow, dla prawdy  uywa  si
       symbolu `t'.

       LISP  daje  standardowy  zestaw funkcji logicznych, np.  and, or i not.
       And i or s blisko-zwierajce: and nie zanalizuje  adnych  argumentow  na
       prawo  od  pierwszego zrozumianego jako nil, a or nie zanalizuje adnych
       argumentow na prawo od pierwszego, zrozumianego jako t.

       LISP daje te specjalne formy dla wyrae warunkowych. Najprostsz jest if.
       Pierwszy  argument  tej  formy  okrela  czy  wywola argument drugi, czy
       trzeci.

       > (if t 5 6)
       5
       > (if nil 5 6)
       6
       > (if 4 5 6)
       5

       Jeli potrzebujesz wicej ni jednej instrukcji w klauzuli then  lub  else
       if'a, to moesz uy specjalnej formy progn.  Progn wykonuje kad instrukcj
       swojego ciala i zwraca ostatni warto.

       > (setq a 7)
       7
       > (setq b 0)
       0
       > (setq c 5)
       5
       > (if (> a 5)
           (progn
             (setq a (+ b 7))
             (setq b (+ c 8)))
           (setq b 4)
         )
       13

       Instrukcja if, ktorej brak klauzuli then lub else, moe by zapisana przy
       uyciu specjalnej formy unless:

       > (when t 3)
       3
       > (when nil 3)
       NIL
       > (unless t 3)
       NIL
       > (unless nil 3)
       3

       When  i  unless  w  przeciwiestwie  do  if,  zezwalaj  na  dowoln liczb
       instrukcji w swoich cialach. (Np. (when x a b c) jest rownowane  (if  x
       (progn a b c)).

       > (when t
           (setq a 5)
           (+ a 6)
         )
       11

       Bardziej zloone warunki mona definiujc przy uyciu formy specjalnej cond
       ktora jest rownowana konstrukcji if ... else if .. fi.

       Cond sklada si z symbolu `cond', za ktorym nastpuj   klauzule  cond,  z
       ktorych  kada jest list. Pierwszy element klauzuli cond jest warunkiem;
       pozostale elementy (jeli istniej) s akcj. Forma  cond  szuka  pierwszej
       klauzuli, ktorej warunek jest spelniony; potem wykonuje odpowiedni akcj
       i zwraca warto wynikow. aden pozostaly warunek nie jest ju analizowany;
       nie  s  te  wykonywane  inne  akcje  ni  ta, odpowiadajca warunkowi. Na
       przyklad:

       > (setq a 3)
       3
       > (cond
          ((evenp a) a)        ;jeli a jest parzyste, zwro a
          ((> a 7) (/ a 2))    ;inaczej, jeli a jest > ni 7, zwro a/2
          ((< a 5) (- a 1))    ;inaczej, jeli a jest < ni 5, zwro a-1
          (t 17)               ;inaczej zwro 17
         )
       2

       Jeli w danej klauzuli cond brakuje akcji, cond zwraca warto, do  ktorej
       zostal zredukowany warunek:

       > (cond ((+ 3 4)))
       7

       Oto  mala  sprytna  rekurencyjna  funkcja, uywajca cond. Moesz sprobowa
       udowodni, e koczy  si  dla  wszystkich  liczb  calkowitych  x  wielkoci
       przynajmniej 1. (Jeli ci si uda, opublikuj rezultat.)

       > (defun hotpo (x steps)        ;hotpo oznacza Half Or Triple Plus One
           (cond
            ((= x 1) steps)
            ((oddp x) (hotpo (+ 1 (* x 3)) (+ 1 steps)))
            (t (hotpo (/ x 2) (+ 1 steps)))
         ) )
       A
       > (hotpo 7 0)
       16

       Instrukcja case w LISP jest podobna do instrukcji switch w C:

       > (setq x 'b)
       B
       > (case x
          (a 5)
          ((d e) 7)
          ((b f) 3)
          (otherwise 9)
         )
       3

       Klauzula  otherwise  oznacza,  e  jeli  x  nie  jest  a, b, d, e lub f,
       instrukcja case ma zwroci 9.

Iteracja

       Najprostsz konstrukcj iteracyjn w LISP jest ptla (loop): konstrukcja ta
       kolejno wykonuje swoje ciala, a nie natrafi na specjaln form return. Na
       przyklad

       > (setq a 4)
       4
       > (loop
          (setq a (+ a 1))
          (when (> a 7) (return a))
         )
       8
       > (loop
          (setq a (- a 1))
          (when (< a 3) (return))
         )
       NIL

       Kolejn najprostsz jest dolist: wie ona  zmienn  do  elementow  listy  w
       kolejnoci i koczy gdy trafi na koniec listy.

       > (dolist (x '(a b c)) (print x))
       A
       B
       C
       NIL

       Dolist  zawsze  zwraca `nil'. Zauwa, e warto `x' w powyszym przykladzie
       nigdy nie byla `nil': NIL znajdujcy si po C byl wartoci  zwracan  przez
       dolist, drukowan przez ptl odczytu-analizy-drukowania.

       Najbardziej  skomplikowanym  rodzajem  iteracji  jest do. Instrukcja do
       wyglda nastpujco:

       > (do ((x 1 (+ x 1))
              (y 1 (* y 2)))
             ((> x 5) y)
           (print y)
           (print 'working)
         )
       1
       WORKING
       2
       WORKING
       4
       WORKING
       8
       WORKING
       16
       WORKING
       32

       Pierwsza cz `do' okrela, ktore zmienne naley zwiza, jakie s ich wartoci
       pocztkowe i jak je odwiea. Nastpna cz okrela warunek zakoczenia i warto
       zwracan. Ostatni czci jest cialo. Forma do wie jak `let' swoje  zmienne
       do  wartoci  pocztkowych,  a  potem  sprawdza warunek zakocznia. Dopoki
       warunek jest falszywy, wykonuje cialo; gdy warunek staje si  prawdziwy,
       zwraca warto formy return-value.

       Forma do* jest analogiczna do `let*' w `let'.

Nielokalne wyjcia

       Forma specjalna return, wspomniana w poprzedniej sekcji o iteracji jest
       przykladem nielokalnego wyjcia. Innym  przykladem  jest  forma  return-
       form, ktora zwraca warto z otaczajcej funkcji:

       > (defun foo (x)
           (return-from foo 3)
           x
         )
       FOO
       > (foo 17)
       3

       Wlaciwie,  forma  return-form  moe  zwroci  warto z dowolnego nazwanego
       bloku--po prostu funkcje s jedynymi blokami, ktore s domylnie  nazwane.
       Blok nazwany moesz tworzy specjaln form block:

       > (block foo
           (return-from foo 7)
           3
         )
       7
       Forma  specjalna  return  moe  zwroci  warto z dowolnego bloku o nazwie
       `nil'.  Domylnie przez nil oznaczane  s  ptle,  lecz  moesz  te  tworzy
       wlasne bloki oznaczone `nil':

       > (block nil
           (return 7)
           3
         )
       7

       Inn form, ktora powoduje nielokalne wyjcie jest forma error:

       > (error "This is an error")
       Error: This is an error

       Forma  error zalcza format do swoich argumentow, a potem umieszcza ci w
       debuggerze.

Funcall, Apply, i Mapcar

       Wczeniej obiecalem, e dam troch funkcji, ktore jako argumenty  pobieraj
       funkcje. Oto one:

       > (funcall #'+ 3 4)
       7
       > (apply #'+ 3 4 '(3 4))
       14
       > (mapcar #'not '(t nil t nil t nil))
       (NIL T NIL T NIL T)

       Funcall wola swoj pierwszy argument z pozostalymi argumentami.

       Apply dziala podobnie do funcall, lecz jej ostatni argument powinien by
       list; elementy tej listy  s  traktowane  tak,  jakby  byly  dodatkowymi
       argumentami funcall.

       Pierwszy argument mapcar musi by funkcj jednoargumentow; mapcar stosuje
       t funkcj do kadego elementu listy i zbiera wyniki w innej licie.

       Funcall i apply s  uywane  czsto  gdy  ich  pierwszym  argumentem  jest
       zmienna.   Na  przyklad  mechanizm przeszukiwania moe bra jako parametr
       funkcj heurystyczn i uywa funcall lub apply do wolania  jej  dla  opisu
       stanu.   Funkcje  sortowania,  opisane  dalej  uywaj funcall do wolania
       funkcji porownawczych.

       Mapcar wraz funkcjami bez nazwy (patrz niej) moe zastpi wiele ptli.

Lambda

       Jeli chcesz utworzy funkcj tymczasow i nie chcesz nadawa jej nazwy,  to
       moesz uy lambda.

       > #'(lambda (x) (+ x 3))
       (LAMBDA (X) (+ X 3))
       > (funcall * 5)
       8
       Polczenie lambda i mapcar moe zastpi wiele ptli. Na przyklad, nastpujce
       postacie s rownowane:

       > (do ((x '(1 2 3 4 5) (cdr x))
              (y nil))
             ((null x) (reverse y))
           (push (+ (car x) 2) y)
         )
       (3 4 5 6 7)
       > (mapcar #'(lambda (x) (+ x 2)) '(1 2 3 4 5))
       (3 4 5 6 7)

Sortowanie

       LISP daje do sortowania dwa prymitywy: sort i stable-sort.

       > (sort '(2 1 5 4 6) #'<)
       (1 2 4 5 6)
       > (sort '(2 1 5 4 6) #'>)
       (6 5 4 2 1)

       Pierwszym argumentem  sort  jest  lista;  drugim  funkcja  porownawcza.
       Funkcja  sortujca nie gwarantuje stabilnoci: jeli s dwa elementy takie,
       e (and (not (< a b)) (not (< b a)))  ,  to  sort  moe  zaaranowa  je  w
       dowolnym  porzdku.  Funkcja  stable-sort  jest taka sama jak sort, lecz
       gwarantuje, e dwa rownowane elementy pojawi si w licie  posortowanej  w
       tej samej kolejnoci co na licie wejciowej.

       Uwaga: sort moe niszczy swoj argument, wic jeli sekwencja wejciowa jest
       dla ciebie wana, utworz jej kopi  poleceniem  copy  lub  copy-list  czy
       copy-seq.

R'owno

       LISP  ma  wiele  ronych  wizji rownoci. Rowno numeryczna jest oznaczana
       przez =. Dwa symbole s eq tylko gdy s identyczne. Dwie kopie tej  samej
       listy nie s eq, cho s rowne.

       > (eq 'a 'a)
       T
       > (eq 'a 'b)
       NIL
       > (= 3 4)
       T
       > (eq '(a b c) '(a b c))
       NIL
       > (equal '(a b c) '(a b c))
       T
       > (eql 'a 'a)
       T
       > (eql 3 3)
       T

       Eql jest rownowany eq dla symboli i = dla liczb.

       Equal  jest r'ownowany eql dla symboli i liczb. Jest prawdziwy dla dwoch
       wagonikow tylko gdy ich car-y i cdr-y s sobie rowne. Jest prawdziwy dla
       dwoch struktur tylko gdy wszystkie ich pola s sobie rowne.

Przydatne funkcje listowe

       Oto funkcje, dzialajce na listach.

       > (append '(1 2 3) '(4 5 6))    ;lcz (konkatenuj) listy
       (1 2 3 4 5 6)
       > (reverse '(1 2 3))            ;odwro elementy listy
       (3 2 1)
       > (member 'a '(b d a c))        ;ustaw czlonkowstwo--zwraca pierwszy ogon
       (A C)                           ;w ktorym car jest danym elemetem.
       > (find 'a '(b d a c))          ;inny sposob ustawiania czlonkowstwa
       A
       > (find '(a b) '((a d) (a d e) (a b d e) ()) :test #'subsetp)
       (A B D E)                       ;find jest jednak bardziej elastyczny
       > (subsetp '(a b) '(a d e))     ;zawieranie si zbiorow
       NIL
       > (intersection '(a b c) '(b))  ;przekroj zbiorow
       (B)
       > (union '(a) '(b))             ;suma zbiorow
       (A B)
       > (set-difference '(a b) '(a))  ;ronica zbiorow
       (B)

       Subsetp,  intersection,  union  i  set-difference  zakladaj,  e  aden z
       argumentow nie posiada zduplikowanych elementow. Np.  (subsetp  '(a  a)
       '(a b b)) moe si nie powie.

       Find,  subsetp, intersection, union i set-difference mog bra argument o
       slowie kluczowym :test; domylnie wszystkie uywaj eql.

Pocztki z Emacsem

       Do  edycji  kodu  LISP  moesz  uywa   Emacsa:   wikszo   Emacsow   jest
       skonfigurowania  na  wchodzenie  w  tryb  LISP za kadym razem gdy znajd
       plik, koczcy si na .lisp. Jeli u ciebie tak si nie  dzieje,  wpisz  M-x
       lisp-mode.

       Pod  Emacsem moesz te uruchamia LISP: upewnij si, e masz w ciece komend
       o nazwie lisp, ktora uruchamia twojego ulubionego LISP-a.  Na  przyklad
       moesz wpisa

               ln -s /usr/local/bin/clisp ~/bin/lisp

       Potem,  w  Emacsie  wpisz  M-x  run-lisp. Moesz wtedy wysla kod LISP do
       interpretera  i  zrobi  wiele  innych  fajnych  rzeczy;  dla   dalszych
       informacji wpisz C-h m z dowolnego bufora w trybie LISP.

       W  rzeczywistoci  nawet  nie musisz tworzy dowizania. Emacs ma zmienn o
       nazwie inferior-lisp-program; wic jeli dodasz lini

               (setq inferior-lisp-program "/usr/local/bin/clisp")

       do swojego pliku .emacs, to Emacs bdzie wiedzial  gdzie  szuka  CLISP-a
       dla komendy M-x run-lisp.

AUTORZY

       Geoffrey   J.  Gordon  <ggordon@cs.cmu.edu>  (pitek,  5  lutego  1993).
       Poprawione   przez   Brunona   Haible'a   <haible@ma2s2.mathematik.uni-
       karlsruhe.de>.   Przetlumaczone  na  jzyk  polski i przekonwertowane do
       postaci man przez Przemka Borysa <pborys@dione.ids.pl>

INFORMACJE O T/LUMACZENIU

       Powysze tlumaczenie pochodzi z nieistniejcego ju  Projektu  Tlumaczenia
       Manuali  i  moe nie by aktualne. W razie zauwaenia ronic midzy powyszym
       opisem a rzeczywistym zachowaniem  opisywanego  programu  lub  funkcji,
       prosimy o zapoznanie si z oryginaln (angielsk) wersj strony podrcznika.

                                 wrzesie 1999                      LISP-TUT(5)