Clojure

Η Clojure (προφέρεται όπως ο αγγλικός όρος "closure") είναι μια σύγχρονη διάλεκτος της γλώσσας προγραμματισμού Lisp. Είναι γλώσσα γενικού σκοπού, υποστηρίζει τη διαδραστική ανάπτυξη, ενθαρρύνει το στυλ συναρτησιακού προγραμματισμού και απλοποιεί τον πολυνηματικό προγραμματισμό. Η Clojure τρέχει στην Εικονική μηχανή της Java (JVM) και στην Common Language Runtime (CLR). Η Clojure τηρεί τη φιλοσοφία "κώδικας-σαν-δεδομένα (code-as-data)" και έχει ένα εκτεταμένο σύστημα μακροεντολών.

 Ο Rich Hickey ανέπτυξε την Clojure γιατί ήθελε μια σύγχρονη διάλεκτο της Lisp για συναρτησιακό προγραμματισμό, που να συνεργάζεται με την καθιερωμένη πλατφόρμα της Java και να είναι σχεδιασμένη για ταυτοχρονισμό.Η προσέγγιση της Clojure στον ταυτοχρονισμό χαρακτηρίζεται από την έννοια των identities, τα οποία αναπαριστούν αμετάβλητες καταστάσεις στο χρόνο. Επειδή η κατάσταση αποτελείται από αμετάβλητες τιμές, οποιοσδήποτε αριθμός υποπρογραμμάτων-"εργατών" ("workers") μπορεί να τις χρησιμοποιεί παράλληλα, και ο ταυτοχρονισμός εξαρτάται από το πώς ελέγχονται οι αλλαγές από τη μια κατάσταση στην άλλη. Για αυτόν το λόγο, η Clojure παρέχει αρκετούς τύπους μεταβλητής αναφοράς (mutable reference types), ο καθένας από τους οποίους έχει ξεκάθαρη σημασιολογία όσον αφορά τη μετάβαση μεταξύ των καταστάσεων. Όπως και όλες οι άλλες Lisp, η σύνταξη της Clojure βασίζεται σε συμβολικές εκφράσεις (S-expressions) που αρχικά διαβάζονται σε ειδικές δομές δεδομένων από έναν αναγνώστη (reader) πριν τη μεταγλώττιση. Εκτός από λίστες, ο αναγνώστης της Clojure υποστηρίζει ρητή σύνταξη για αντιστοιχίσεις, σύνολα και διανύσματα (vectors), και αυτά δίνονται στο μεταγλωττιστή όπως είναι. Με άλλα λόγια, ο μεταγλωττιστής της Clojure δε μεταγλωττίζει μόνο λίστες αλλά υποστηρίζει άμεσα όλους τους προαναφερθέντες τύπους. Η Clojure είναι μια Lisp-1, και δεν προορίζεται να είναι συμβατή σε επίπεδο κώδικα με άλλες διαλέκτους της Lisp. Το σύστημα μακροεντολών της Clojure μοιάζει με αυτό της Common Lisp με την εξαίρεση ότι η έκδοση της Clojure για τον τελεστή backquote (που καλείται "syntax quote") δίνει στα σύμβολα και το χώρο ονομάτων τους (namespace). Επειδή απαγορεύεται η δέσμευση ονομάτων που περιέχουν χώρο ονομάτων, αποφεύγονται καταστάσεις ακούσιας δέσμευσης ονομάτων. Μια επέκταση μακροεντολής μπορεί να δεσμεύει ονόματα, αλλά αυτό πρέπει να γίνει ρητά από τον προγραμματιστή. Η Clojure επίσης απαγορεύει την επαναδέσμευση καθολικών ονομάτων σε άλλους χώρους ονομάτων που έχουν εισαχθεί (import) στον τρέχοντα χώρο ονομάτων. Δυναμική ανάπτυξη με βρόχο read-eval-print Οι συναρτήσεις είναι αντικείμενα πρώτης τάξης με έμφαση στην αναδρομή αντί για την επανάληψη με παρενέργειες Οκνηρές ακολουθίες (lazy sequences) Πλούσιο σύνολο από αμετάβλητες διαρκείς δομές δεδομένων (immutable persistent data structures) Ταυτοχρονισμός μέσω μνήμης συναλλαγών σε λογισμικό (software transactional memory), συστήματος με agents, και συστήματος δυναμικών μεταβλητών Οι πολυμέθοδοι (multimethods) επιτρέπουν δυναμική αποστολή (dynamic dispatch) στους τύπους και τις τιμές οποιουδήποτε συνόλου από ορίσματα (πρβ. ο κλασικός αντικειμενοστρεφής πολυμορφισμός χρησιμοποιεί τον τύπο αυτού που είναι πρακτικά το πρώτο όρισμα μιας μεθόδου) Η Clojure είναι μεταγλωττιζόμενη γλώσσα που παράγει κώδικα byte για την JVM Πλήρης ενσωμάτωση με τη Java: Μεταγλωττιζόμενες σε κώδικα για την JVM, οι εφαρμογές σε Clojure μπορούν εύκολα να πακεταριστούν, να εγκατασταθούν και να εκτελεστούν σε υλοποιήσεις JVM και σε εξυπηρετητές εφαρμογών χωρίς πολυπλοκότητα. Η γλώσσα παρέχει επίσης μακροεντολές που απλοποιούν τη χρήση των υπαρχόντων Java API. Όλες οι δομές δεδομένων της Clojure υλοποιούν βασικα interfaces της Java, διευκολύνοντας την εκτέλεση κώδικα της Clojure από τη Java. "Γεια σου, κόσμε!": "Γεια σου, κόσμε!" (GUI): Μια γεννήτρια μοναδικών σειριακών αριθμών ασφαλής για πολυνηματική εκτέλεση (thread-safe): Μια ανώνυμη υποκλάση της java.io.Writer που δεν γράφει πουθενά, και μια μακροεντολή που τη χρησιμοποιεί για να κρύψει όλες τις εντολές εξόδου (print) σε αυτή: 10 νήματα που χειρίζονται μια κοινή δομή δεδομένων, η οποία αποτελείται από 100 διανύσματα, το καθένα από τα οποία περιέχει 10 (αρχικά διαδοχικούς) αριθμούς. Κάθε νήμα τότε επαναλαμβανόμενα επιλέγει δύο τυχαίες θέσεις σε δύο τυχαία διανύσματα και τα αντιμεταθέτει: Όλες οι αλλαγές στα διανύσματα συμβαίνουν μέσα σε συναλλαγές χρησιμοποιώντας το σύστημα μνήμης συναλλαγών σε λογισμικό της Clojure. Με αυτόν τον τρόπο, ακόμα και μετά από 100.000 επαναλήψεις κάθε νήματος δε χάνεται κανένας αριθμός. Έξοδος του προηγούμενου παραδείγματος: Lisp Halloway, Stuart (28 Μαΐου 2009), Programming Clojure (1st έκδοση), Pragmatic Bookshelf, σελ. 304, ISBN 1934356336, https://archive.org/details/programmingcloju00hall/page/304 VanderHart, Luke (31 Δεκεμβρίου 2009), Practical Clojure (1st έκδοση), Apress, σελ. 350, ISBN 1430272317, http://www.apress.com/book/view/9781430272311, ανακτήθηκε στις 2010-07-26 Rathore, Amit (Δεκέμβριος 2009), Clojure in Action (1st έκδοση), Manning, σελ. 475, ISBN 9781935182597, http://www.manning.com/rathore/ Fogus, Michael; Houser, Chris (Ιανουάριος 2010), The Joy of Clojure (1st έκδοση), Manning, σελ. 300, ISBN 9781935182641, http://www.manning.com/fogus/ Η σελίδα της Clojure (Αγγλικά) Σύντομη περίληψη των βασικών χαρακτηριστικών της Clojure Αρχειοθετήθηκε 2011-06-28 στο Wayback Machine. (Αγγλικά)