Σελίδα 1 από 1

Common Lisp

ΔημοσίευσηΔημοσιεύτηκε: 08 Σεπ 2014, 12:15
από Dimitris
Καλημέρα σας! (ύστερα από πολύ καιρό)

Ο παρακάτω οδηγός έχει ως στόχο να (ξανά) εισάγει ένα παλιό τρόπο σκέψης στον προγραμματισμό. Πρόκειται για τη γλώσσα προγραμματισμού common lisp. Η common lisp ήταν ιστορικά η δεύτερη high-level γλώσσα μετά τη fortran. Σχεδιάστηκε από ένα μαθηματικό ο οποίος ήθελε να κάνει συμβολικά μαθηματικά στον υπολογιστή. Έπειτα έγινε πολύ αγαπητή στον κόσμο της τεχνητής νοημοσύνης και μετά έπεσε στη λήθη γιατί ήταν "δύσκολη". (Εγώ να σας πω την αλήθεια ποτέ δεν κατάλαβα τις λίστες στη C, αλλά με τη lisp ήταν λες και τις ήξερα από γεννησιμιού μου.) Πρόσφατα η google αγοράσε την ITA, εταιρία που φτιάχνει τον αλγόριθμο αναζήτησης ελάχιστου κόστους αεροπορικών συνδέσεων. Η ITA προγραμμάτιζε σε common lisp, και ενώ η google παραδοσιάκα φοβάται τις διαφορετικές γλώσσες, παρόλ'αυτά την εξαγόρασε γιατί ήταν πολύ καλή σ'αυτό που έκανε. Ένα ακόμη παράδειγμα ήταν το yahoo store. Το διαδίκτυο είναι γεμάτο με αναφορές και άρθρα για τις ιστορίες αυτές. Θα αφήσω την εξιχνίασή τους στον αναγνώστη.

Ας προχωρήσουμε με την εγκατάστασή της. Ένας από τους πολλούς interpreter της common lisp είναι ο GNU clisp. Σε debian/ubuntu εγκαθίσταται πολύ απλά:
Κώδικας: Επιλογή όλων
sudo apt-get install clisp


Η σύνταξη στη common lisp ακολουθεί τη prefix notation, δηλαδή ο τελεστής μπαίνει πρώτος και έπειτα τα ορίσματα. Αυτή η πιο γενική σημειολογία που μπορεί να υπάρξει και δε χρειάζεται να θυμάται κανείς προσεταιριστικές και αντιμεταθετικές ιδιότητες.
Αν πληκτρολογήσουμε clisp θα μας περιμένει ο interpreter της lisp:
Κώδικας: Επιλογή όλων
[1]>

Ας προσπαθήσουμε να προσθέσουμε δυο αριθμούς:
Κώδικας: Επιλογή όλων
[1]>(+ 1 2)
3
[2]>

Όπως στην python, θα δούμε το αποτέλεσμα και μια νέα γραμμή να μας περιμένει. Στο προηγούμενο παράδειγμα το + είναι ο τελεστής και οι αριθμοί 1 και 2, είναι τα ορίσματα. Η διαφορά της common lisp με όλες τις άλλες γλώσσες (πλην εκείνων που ανήκουν στην ίδια κατηγορία) είναι ότι κώδικας και δεδομένα είνα το ίδιο και το αυτό: λίστες. Σημειώστε ότι LISP αρχικά σημαίνει LISt Processing. Τώρα θέλουμε να πολλαπλασιάσουμε τους αριθμούς 2 και 3 και έπειτα να προσθέσουμε 1:
Κώδικας: Επιλογή όλων
[2]>(+ 1 (* 2 3))
7

Τι συμβαίνει εδώ; Ξεκινάει να προσθέσει το 1 στην εσωτερική παρένθεση, δε βρίσκει αριθμό οπότε προσπαθεί πρώτα να υπολογίσει την παρένθεση και μετά να συνεχίσει με την πρόσθεση. Ούτε να θυμάσε ποια πράξη έχει προτεραιότητα ούτε τίποτε, απλά παρενθέσεις.

Ας δούμε τώρα το απλό παράδειγμα hello world.
Κώδικας: Επιλογή όλων
[3]>"hello world"
"hello world"

Απλό έτσι; Επιστρέφει τη τιμή που της έδωσες. Θα μπορούσαμε να το κάνουμε λίγο πιο δύσκολο:
Κώδικας: Επιλογή όλων
[4]>(print "hello world")
"hello world"
"hello world"

Τι συμβαίνει εδώ; Χμμ, πρώτον τυπώνει το string "hello world", και έπειτα επιστρέφει την τιμή που τελευταία υπολόγισε. Αυτό είναι ένα από τα βασικά χαρακτηριστικά της (το οποίο έχει υιοθετήσει και η ruby). Όλες οι συναρτήσεις επιστρέφουν μια τιμή, πάντα.

Είπε κανείς τη λέξη συνάρτηση; Ένα άλλο χαρακτηριστικό της lisp είναι ότι μπορεί να προγραμματίσει κανείς και συναρτησιακά (functional). Η lisp είναι multi-paradigm, δηλαδή μπορεί κανείς να προγραμματίσει τόσο procedural, object-oriented, όσο και functional. Όπως θα μαντέψατε στο συναρτησιακό κομμάτι είναι πιο γυαλίζει. Ας δούμε πώς μπορούμε να ορίσουμε μια συνάρτηση.
Κώδικας: Επιλογή όλων
[5]>(defun foo (x) (+ 1 x))
FOO

Τι κάνει το παραπάνω παράδειγμα; Όρισε μια συνάρτηση (defun) με όνομα foo, η οποία επιστρέφει την τιμή 1 + x. Ακόμη και η συνάρτηση defun επιστρέφει την τιμή FOO (η lisp δεν είναι case-sensitive), που είναι το όνομα της συνάρτησης που μόλις ορίσαμε. Καλώντας τη συνάρτηση foo, έχουμε:
Κώδικας: Επιλογή όλων
[6]>(foo 3)
4


Προηγουμένως είπαμε ότι όλα είναι λίστες. Ένα παράδειγμα θα σας πείσει:
Κώδικας: Επιλογή όλων
[7]>(list 1 2 "string")
(1 2 "string")

Συγγνώμη, θέλω μόνο το τελευταίο στοιχείο της λίστας. Δώστε απλά:
Κώδικας: Επιλογή όλων
[8]>(last (list 1 2 "string"))
("string")

Εύκολα μπορεί να μαντέψει κανείς ότι το πρώτο στοιχείο υπολογιζεται:
Κώδικας: Επιλογή όλων
[9]>(first (list 1 2 "string"))
1

Να σημειωθεί μια μικρή διαφορά, η συνάρτηση first επιστρέφει το πρώτο στοιχείο, ενώ η last μια λίστα με το τελευταίο στοιχείο. Οι διαφορές είναι λεπτές για να τις εξηγήσω τώρα. Αν θελήσουμε την υπόλοιπη λίστα μετά το πρώτο στοιχείο, τοτε τη ζητάμε με τη συνάρτηση rest:
Κώδικας: Επιλογή όλων
[10]>(rest (list 1 2 "string"))
(2 "string")

Και κάπως έτσι μπορούμε να κάνουμε μια αναζήτηση σε μια λίστα, δενδρική δομή, γράφημα ή ό,τι άλλο μπορεί να φανταστεί ο νούς σας.

Σημείωση του συγγραφέα: θα μπορούσε κανείς να ρωτήσει γιατί δεν είναι και τα strings λίστες; Υπάρχει μια διάλεκτος της lisp, η arc, η οποία έχει ενοποιήσει όλα τα αντικείμενα σε λίστες, αλλά δεν είναι τόσο διαδεδομένη. Υπάρχει επίσης και η scheme, μια πιο καθαρή γλώσσα προγραμματισμού, με την έννοια ότι έχει μόνο εκείνες τις συντακτικές δομές που χρειάζονται για να δημιουργήσει κανείς όλα τα υπόλοιπα, και όλα τα υπόλοιπα είναι βιβλιοθήκες. Εγώ θα συνιστούσα την ANSI Common Lisp.

Για αρχή καλά δεν είναι;

Creative Commons License
Η εργασία υπάγεται στην άδεια Creative Commons Αναφορά-Παρόμοια διανομή 3.0 Ελλάδα

Re: Common Lisp

ΔημοσίευσηΔημοσιεύτηκε: 08 Σεπ 2014, 13:49
από evolgen
:bow: :thumbup: Ευχαριστούμε πολύ!