apohllo.pl
więcej niż strona domowa...
 

Lekcja 11

Spis treści | Lekcja 10 | Lekcja 12

2. 11. Instrukcje warunkowe – IF, WHEN, UNLESS, CASE, COND

IF

LISP wyposażony jest również w specjalne formy dla wyrażeń warunkowych. IF jest najprostszą z nich. Specjalna funkcja IF bierze trzy argumenty: próba, prawdziwa część i fałszywa część. Jeśli próba jest prawdziwa, IF zwraca wartość prawdziwej części. Jeśli próba jest fałszywa, to opuszcza prawdziwą część i zamiast zwraca wartość fałszywej części.

11.1.

(if t 2 8)                        =>  2
(if nil 2 8)                      =>  8
(if 9 2 8)                        =>  2
(if (oddp 7) 'odd 'even)          =>  odd
(if (oddp 6) 'odd 'even)          =>  even
(if t 'tekst-jest-prawdziwy 'tekst-jest-falszywy) 
                                  =>  tekst-jest-prawdziwy 
(if nil 'tekst-jest-prawdziwy 'tekst-jest-falszywy) 
                                  =>  tekst-jest-falszywy 
(if (symbolp 'slowo) (* 3 4) (+ 3 4))  
                                  =>  12
(if (symbolp 6) (* 3 4) (+ 3 4))  =>  7

W przypadku gdy potrzeba wykonać więcej niż jedną instrukcję w klauzuli then lub else IF’a, to można użyć specjalenej formy PROGN. PROGN wykonuje każdą instrukcję swojego ciała i zwraca ostatnią wartość.

WHEN i UNLESS

WHEN i UNLESS w przeciwieństwie do IF, zezwalają na dowolną liczbę instrukcji w swoich ciałach. (Np. (when x a b c) jest równoważne (if x (progn a b c)).

Instrukcja IF, której brak klauzuli then lub else, może być zapisana przy użyciu specjalnej formy UNLESS.

11.2.

(when t 5)                        =>  5
(when nil 5)                      =>  NIL
(unless t 5)                      =>  NIL
(unless nil 5)                    =>  5

CASE

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

11.3.

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

Klauzula otherwise oznacza, że jeśli x nie jest a, b, d, e lub f, instrukcja CASE ma zwrócić 9.

Bardziej złożone warunki można definiując przy użyciu formy specjalnej COND która jest równoważna konstrukcji: if … else if …

COND

COND składa się z symbolu ‘COND’, za którym następują klauzule COND, z których każda jest listą. Pierwszy element klauzuli cond jest warunkiem; pozostałe elementy (jeśli istnieją) są akcją. Forma COND szuka pierwszej klauzuli, której warunek jest spełniony; potem wykonuje odpowiednią akcję i zwraca wartość wynikową. Żaden pozostały warunek nie jest już analizowany; nie są też wykonywane inne akcje niż ta, odpowiadająca warunkowi.

Ogólna forma wyrażenia COND wygląda tak:

(cond (test-1 consequent-1)
 (test-2 consequent-2)
 (test-3 consequent-3)
 ....
 (test-n consequent-n))

11.4.

(setq a 3)                        =>  3
(cond
  ((evenp a) a)     ;jeśli a jest parzyste, zwróć a
  ((> a 7) (/ a 2)) ;inaczej, jeśli a jest > niż 7, zwróć a/2
  ((< a 5) (- a 1)) ;inaczej, jeśli a jest < niż 5, zwróć a-1
  (t 17)            ;inaczej zwróć 17
)                                 =>  2

Jeśli w danej klauzuli COND brakuje akcji, COND zwraca wartość, do której został zredukowany warunek:

11.5.

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

Instrukcje warunkowe to specjalne funkcje decydowania, które wybierają rezultat spośród zbioru wartości bazujących na wyniku jednego lub kilku predykatów. Tryby warunkowe pozwalają funkcji na zmianę zachowania w zależności od rodzaju wejścia. Odkąd możemy pisać funkcje, które robią dowolnie złożone decyzje.

Użyjmy COND do napisania funkcji COMPARE porównującej dwie liczby. Jeśli liczby są równe, COMPARE „powie” ‘liczby-sa-rowne’; jeśli pierwsza liczba będzie mniejsza niż druga, to „powie” ‘pierwsza-liczba-jest-mniejsza’; jeśli pierwszy numer będzie większe niż drugi, to „powie” ‘pierwsza-liczba-jest-wieksza’. Każdy przypadek jest obsłużony przez oddzielną klauzulę COND.

11.6.

(defun compare (x y)
  (cond ((equal x y) 'liczby-sa-rowne)
    ((< x y) 'pierwsza-liczba-jest-mniejsza)
    ((> x y) 'pierwsza-liczba-jest-wieksza)
  )
)

Jedna ze standardowych sztuczek używania COND to umieszczenie na końcu COND klauzuli

(T consequent)

Ponieważ T jest zawsze prawdziwe, więc jeśli COND kiedykolwiek dotrze do tej klauzuli, to wykona consequent. Z drugiej strony klauzula ta zostanie osięgnięta tylko wtedy, jeśli zawiodą wszystkie poprzedzające ją klauzule.

11.7.

(defun gdzie-jest (x)
  (cond ((equal x 'paryz) 'francja)
    ((equal x 'londyn) 'anglia)
    ((equal x 'pekin) 'chiny)
    (t 'nieznane)
  )
)

Warto zauważyć, że ostatnia klauzula COND zaczyna się z T. Oznacza to, że jeśli żadna z poprzedzających klauzuli nie zostanie wykonana, wykona się ostatnia klauzula i funkcja zwróci NIEZNANE.

11.8.

(gdzie-jest 'londyn )             =>  anglia
(gdzie-jest 'pekin  )             =>  chiny
(gdzie-jest 'parasol)             =>  nieznane

Spis treści | Lekcja 10 | Lekcja 12

lisp | Opublikowano 12:29 29-11-2010. Ostatnia modyfikacja 12:29 29-11-2010 |
comments powered by Disqus