Příklad -=-=-=-=- Real computer scientists only write specs for languages that might run on future hardware. Nobody trusts them to write specs for anything homo sapiens will ever be able to fit on a single planet. Lisp je velmi výkoný a úsporný programovací jazyk. Jako příklad jsem si vybral quick sort. Každý asi znáte tento algoritmus. Implementovat ho v C není tak velká legrace. V Lispu to je snadné. Protože Lisp má mnohem mocnější pojetí funkcí a maker, můžete velmi elegantně využívat knihovních funkcí, které toho umí opravdu hodně. (define (partition compare l1) (cond ((null? l1) '()) ((compare (car l1)) (cons (car l1) (partition compare (cdr l1)))) (else (partition compare (cdr l1))))) (define (quicksort l1) (cond ((null? l1) '()) (else (let ((pivot (car l1))) (append (append (quicksort (partition (lambda (x) (< x pivot)) l1)) (partition (lambda (x) (= x pivot)) l1)) (quicksort (partition (lambda (x) (> x pivot)) l1))))))) Jak to funguje? Začneme od funkce partition. Ta rozdějule seznam l1 podle funkce compare na dvě části. Napřed otestuje jestni už není nahodou hotový. K tomu slouží makro cond. Jedná se o chytřejší if. Bere své parametry jeden po druhém. Každý parametr je list. Jako první v listu očekává podmínku. Pokud se podmínka vyhodnotí do #t, provede tělo za podmínkou a zkončí. Jinak pokračuje na další podmínku. Na konci můře být volitebně else větev. Jedná se tedy o něco mezi switch a case. První podmínka je (null? l1). Funkce null? vrací #t pokud jeho parametr je prázdný seznam. Takže pokud je parametr prázdný seznam, funkce zkončí. Jinak porovná první prvek seznamu l1, pokud je menší, rekurzivně se zavolá na zbytek seznamu a prvek přihodí na začátek (pomocí funkce cons, která ze svých parametrů vytvoří cons). Pokud je ale prvek větší, zahodí ho a rekruzivne se zavolá na zbytek. Funkce quicksort potom používá této funkce. Na začátku opět ošetří, jestli není seznam nulový. Pokud není, vybere pivota ze začátku seznamu a provede rozdělení. Partitiion potom volá z nově vytvořenou funkcí, která vybere ty prvky, které potřebuje. Quicksort se zavolá rekurzivně na obě větve a vše je hotovo. Kód není zrovna optimální. Chtěl jsem na něm ukázat co nejvíc konstrukcí, ale když ho srovnáte se srovnatelně funkčním quicksortem v C, Lisp na délku kódu rozhodně vede. I použítí je jednodušší: (quicksort '(1 3 2 6 5 4 0)) => (0 1 2 3 4 5 6) ekvivalent v C: #include <stdio.h> #include <stdlib.h> int nums[] = {1, 3, 2, 6, 5, 4, 0}; int compar (const void *a, const void *b) { return (*(int *) a - *(int *) b); } void main (void) { int i; qsort (nums, sizeof (nums) / sizeof (int), sizeof (int), compar); for (i = 0; i < sizeof (nums) / sizeof (int); i++) printf ("%i ", nums[i]); printf ("\n"); } výheň