Συναρτήσεις ανωτέρου βαθμού
- Μπορούμε να ορίσουμε μια
συνάρτηση ανωτέρου βαθμού (higher order function)
ορίζοντας ως ένα όρισμα της συνάρτησης μια άλλη συνάρτηση.
- Τη συνάρτηση-όρισμα μπορούμε να την εφαρμόσουμε πάνω σε κάποιες
τιμές με τη συνάρτηση apply η οποία λαμβάνει ως όρισμα μια συνάρτηση το
πρώτο όρισμα και μια λίστα με τα υπόλοιπα όρισματά της (ή nil) και επιστρέφει το
αποτέλεσμα της συνάρτησης εφαρμοσμένο στο όρισμα.
- Μπορούμε ακόμα να ορίσουμε δυναμικά μια τιμή τύπου συνάρτησης
με τη σύνταξη:
(lambda (όρισμα) τιμή)
Το παρακάτω παράδειγμα συνθέτουμε τις έννοιες αυτές για να ορίσουμε
τις συναρτήσεις map και reduce.
Map
Η συνάρτηση map μετατρέπει μια λίστα σε μια άλλη με βάση μια συνάρτηση που έχει
δοθεί ως όρισμα.
(defun mymap (f lst)
(if (null lst)
nil
(cons (apply f (cons (car lst) nil)) (mymap f (cdr lst)))))
Έτσι μπορούμε π.χ. να διπλασιάσουμε να στοιχεία της λίστας '(1 2 3) με την
κλήση:
(mymap (lambda (x) (* 2 x)) '(1 2 3))
(2 4 6)
Reduce
Η συνάρτηση reduce συμπυκνώνει μια λίστα εφαρμόζοντας αναδρομικά
τη συνάρτηση σε κάθε στοιχείο της λίστας αρχίζοντας από μια αρχική τιμή.
(defun myreduce (f v lst)
(if (null lst)
v
(apply f (cons (car lst) (cons (myreduce f v (cdr lst)) nil)))))
Έτσι μπορούμε να ορίσουμε συναρτήσεις όπως τις:
- sum επιστρέφει το σύνολο των τιμών μιας λίστας
(defun mysum (lst) (myreduce '+ 0 lst))
- product επιστρέφει το γινόμενο των τιμών μιας λίστας
(defun myproduct (lst) (myreduce '* 1 lst))
- alltrue επιστρέφει αληθές αν όλες οι τιμές μιας λίστας είναι αληθείς
(defun alltrue (lst) (myreduce 'and t lst))
- anytrue επιστρέφει αληθές αν τουλάχιστον μια τιμή μιας λίστας είναι αληθής
(defun anytrue (lst) (myreduce 'or nil lst))