LISPouczek



STRONA SAMOUCZKA JĘZYKA LISP  



powered by FreeFind
główna

lekcje

odnośniki

pliki
<< lekcja 10 | lekcja 12 >>

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



<< lekcja 10 | lekcja 12 >>