Σύντομο tutorial (common) LISP

2010 Jul 01

functions

Ορισμός:

(defun average (nums)
 (/ (reduce #'+ nums)
   (length nums)))

κλήση:

(function-name arg1 arg2 ...)

loop

(loop repeat 10 ...)

Επανάληψη 10 φορές…

(loop for i below 100 ...)

Το i παίρνει τιμές από 0 μέχρι 99

(loop for i below 100 summing i)

Αθροίσμα των i που διατρέχονται

(loop for i below 100 count (> i 10))

Πόσες φορές το i ήταν μεγαλύτερο από 10

(loop for i below 100 maximize i)

Επιστρέφει το μέγιστο i που είδε

(loop for i to 100 ...)

το i παίρνει τιμές από 0 μέχρι 100

(loop for i from 10 below 20 ...)

Το i παίρνει τιμές από 10 μέχρι 19

(loop for i below 100 by 0.1 ...)

Το i παίρνει τιμές από 0 μέχρι 99 με βήμα 0.1

(loop for i in '(a b c d) ...)

Το i παίρνει διαδοχικά τις τιμές ‘a, ‘b, ‘c και ’d

(loop for i on '(a b c d) ...)

Το i παίρνει διαδοχικά τις τιμές ‘(a b c d), ‘(b c d), ‘(c d) και ‘(d)

(loop while (kati) ...)

Μένει στο loop όσο το “kati” είναι true

(loop ... finally (...))

Το finally θα εκτελεστεί αφού τελειώσει το loop

Όλα τα παραπάνω συνδιάζονται. Πχ:

(loop for i below 100
       for j below 50
            when (evenp i) sum (+ i j))

Έχει το ίδιο αποτέλεσμα με τον C-κώδικα:

     sum = 0;
     for (i=0;i<100;i++)
            for (j=0;j<50;j++)
                    if (i%2 == 0)
                            sum += (i+j)

format

Το format είναι το αντίστοιχο printf της C. То ~ αντιστοιχεί στο % της printf.

> (format t "~r" 1202)
one thousand, two hundred and two
> (format t "~:r" 4)
fourth
> (format t "~o" 800) ; Octal
1440
> (format t "~b" 800) ; Binary
1100100000
> (format t "~5R" 800) ; 5-αδικό
11200

Conditional format

> (setf *format*  "Buy ~r book~:*~[s~;~:;s~].")
> (format t *format* 0)
Buy zero books.
> (format t *format* 1)
Buy one book.
> (format t *format* 2)
Buy two books.
> (format t *format* 3)
Buy three books.

Iteration in format

(setf *format*  "~@{~a~^, ~}")
> (format t *format* 1)
1
> (format t *format* 1 2)
1, 2
> (format t *format* 1 2 3 4)
1, 2, 3, 4
> (setf *format2* "~#[NONE~;~a~;~a and ~a~:;~a, ~a~] ~#[~; and ~a~:;, ~a, etc~].")
> (format t *format2*)
"NONE."
> (format t *format2* 'a)
"A."
> (format t *format2* 'a 'b)
"A and B."
> (format t *format2* 'a 'b 'c)
"A, B and C."
> (format t *format2* 'a 'b 'c 'd)
"A, B, C, etc."
> (format t *format2* 'a 'b 'c 'd 'e)
"A, B, C, etc."

(Από παράδειγμα του Practical common Lisp)

macros

Δημιουργούμε το “join” που λειτουργεί σαν το “join” της Python:

> (join '(1 2 3) ", ")
1, 2, 3
> (join '(1 2 3) "--")
1--2--3
> (join '("one" (a "bee" c) "three") "--")
one--(A bee C)--three

ορίζοντας το macro join:

(defmacro join (l k)
`(let ((fmt (concatenate 'string "~{~a~^" ,k "~}")))
   (format t fmt ,l)))