Δεδομένου ότι το όνομα της γλώσσας που χρησιμοποιούμε, Lisp, σημαίνει LIST Processing, θα περίμενες ότι η γλώσσα θα έχει δυνατότητες για τον χειρισμό λιστών από στοιχεία, και θα είχες δίκιο!
Αν και η Common Lisp έχει δομές δεδομένων πέρα από τις λίστες, οι λίστες χρησιμοποιούνται ακόμα πολύ.
Μια λίστα στην Common Lisp είναι μια ακολουθία στοιχείων. Ονομάζεται επίσης cons (κυρίως για ιστορικούς λόγους).
Τα ίδια τα στοιχεία δεν χρειάζεται να είναι του ίδιου τύπου.
Για παράδειγμα, μπορείς να έχεις μια λίστα με 1, two, "III".
Μπορείς απλώς να πληκτρολογήσεις μια λίστα με παράθεση, όπως αυτή: '(1 two "III"), και αυτό θα έχει ως αποτέλεσμα να δημιουργηθεί και να αξιολογηθεί μια λίστα (αξιολογείται σε (1 two "III")).
Υπάρχουν επίσης δύο βασικές συναρτήσεις που χρησιμοποιούνται για τη δημιουργία λιστών: οι list και cons.
Η list δέχεται μηδέν ή περισσότερα ορίσματα και αξιολογείται σε μια λίστα που έχει δημιουργηθεί με αυτές τις τιμές:
(list 1 'two "III") ; => (1 two "III")
Η cons δέχεται δύο στοιχεία και δημιουργεί μια λίστα που έχει το πρώτο στοιχείο ως car (την κεφαλή της λίστας) και το δεύτερο στοιχείο ως cdr (το υπόλοιπο της λίστας):
(cons 1 2) ; => (1 . 2) ;; (a list without `nil` as its `cdr` is printed in this way)
(cons 1 nil) ; => (1)
(cons 1 (cons 2 nil)) ; => (1 2)
Οι συναρτήσεις car και cdr μπορούν να χρησιμοποιηθούν για την πρόσβαση στο car και στο cdr μιας λίστας.
(Οι first και rest είναι συνώνυμες των car και cdr και λειτουργούν ακριβώς το ίδιο.)
Το μήκος μιας λίστας μπορεί να προσδιοριστεί με τη χρήση της length.
Μια κενή λίστα έχει μήκος μηδέν.
Ένα οποιοδήποτε στοιχείο μπορεί να προσπελαστεί με τη nth (πρόσεξε ότι η αρίθμηση των θέσεων στις λίστες ξεκινά από το μηδέν).
Δεν είναι σφάλμα να ζητήσεις μια θέση μεγαλύτερη από το μήκος της λίστας.
Αντ' αυτού, αξιολογείται σε nil:
(nth 23 '(short list)) ; => nil
Υπάρχουν επίσης αρκετές βοηθητικές μέθοδοι για την πρόσβαση στα πρώτα στοιχεία μιας λίστας: first, second, third, μέχρι και τη tenth. Έξυπνο, ε;
Δύο ή περισσότερες λίστες μπορούν να συνδυαστούν με τη append:
(append '(a b c) '(1 2 3)) ; => (A B C 1 2 3)
(append '(a b c) '()) ; => (A B C)
Κάθε όρισμα που δίνεται στη append πρέπει να είναι λίστα.
Ο Leslie, ο εξωγήινος της Lisp, πρέπει να κάνει κάποια ψώνια. Είναι πολύ σημαντικό να έχει μια λίστα αγορών. Πρέπει να μπορεί κανείς να προσθέτει πράγματα σε αυτήν και να αφαιρεί πράγματα από αυτήν.
Φυσικά, ένα απλό στυλό και χαρτί δεν αρκούν για έναν εξωγήινο της Lisp. Άλλωστε, το "List" είναι το μεγαλύτερο μέρος της λέξης "Lisp"! Πρέπει να υπάρχουν κάποιες συναρτήσεις γραμμένες που να βοηθούν στην παρακολούθηση των ψωνιών.
Μπορείς να βοηθήσεις τον Leslie να κρατάει τη λίστα αγορών;
Καταρχάς, ο Leslie πρέπει να δημιουργήσει μια κενή λίστα. Μια συνάρτηση με το όνομα new-list θα ήταν ιδανική γι' αυτό.
(new-list) ; => ()
Ωχ όχι... Ο Leslie έχει ήδη στο μυαλό του μερικά πράγματα, οπότε χρειάζεται μια συνάρτηση που παίρνει τρία στοιχεία (ευτυχώς ο Leslie φτιάχνει λίστες με τρία μόνο στοιχεία. Ούτε περισσότερα, ούτε λιγότερα!) και δημιουργεί μια νέα λίστα αγορών με αυτά τα πράγματα. Γράψε μια συνάρτηση, τη list-of-things, η οποία παίρνει τρία στοιχεία και επιστρέφει μια λίστα με αυτά.
(list-of-things 'bread 'milk 'butter) ; => '(bread milk butter)
Πριν πάει στο κατάστημα, ο Leslie κοιτάζει στο ντουλάπι για να δει τι χρειάζεται. Βοήθησέ τον γράφοντας τη συνάρτηση add-to-list, η οποία προσθέτει ένα στοιχείο στην αρχή μιας λίστας.
(add-to-list 'butter '(bread)) ; => '(butter bread)
Όταν κάνει ψώνια, ο Leslie θέλει να ξέρει τι να ψάξει μετά. Του αρέσει επίσης να ρίχνει μια ματιά πιο μπροστά στη λίστα για να δει το δεύτερο, το τρίτο ή ακόμα και το 23ο στοιχείο (τον τυχερό του αριθμό).
first-thing θα αξιολογείται στο πρώτο πράγμα της λίσταςsecond-thing θα αξιολογείται στο δεύτερο πράγμαthird-thing θα αξιολογείται στο τρίτο πράγμαtwenty-third-thing θα αξιολογείται στο εικοστό τρίτο πράγμα(first-thing '(bread butter milk)) ; => 'bread
(second-thing '(bread butter milk)) ; => 'butter
(third-thing '(bread butter milk)) ; => 'milk
Ο Leslie θέλει να βρει το πρώτο στοιχείο της λίστας και να το αφαιρέσει από το ράφι. Βοήθησέ τον γράφοντας μια συνάρτηση remove-first-item, η οποία δίνει μια λίστα με όλα τα στοιχεία της λίστας εισόδου εκτός από το πρώτο.
(remove-first-item '(bread butter milk)) ; => '(butter milk)
Ο Leslie συνειδητοποίησε ότι κατά λάθος έφτιαξε δύο λίστες αγορών, όχι μία! Γράψε μια συνάρτηση, τη list-append, η οποία επιστρέφει μια λίστα με τα στοιχεία της πρώτης λίστας ακολουθούμενα από αυτά της δεύτερης λίστας.
(list-append '(bread salt) '(butter milk)) ; => '(bread salt butter milk)
Ο Leslie αρχίζει να ανησυχεί ότι αυτή η εξόρμηση για ψώνια θα πάρει πολύ ώρα. Πόσα πράγματα έχει τελικά αυτή η λίστα; Γράψε μια συνάρτηση just-how-long που θα του πει πόσο μεγάλη είναι η λίστα του.
(just-how-long '(bread milk butter salt)) ; => 4
Γράψου στο Exercism για να μάθεις και να κατακτήσεις Common Lisp με 27 έννοιες92 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.