Lua

Η Lua είναι ελαφριά προστακτική γλώσσα προγραμματισμού, που σχεδιάστηκε ως γλώσσα σεναρίων με κύριο σκοπό τη δυνατότητα επέκτασης της σημασιολογίας της. Το όνομα προέρχεται από την πορτογαλική λέξη lua που σημαίνει "φεγγάρι". Η Lua έχει ένα σχετικά απλό C API σε σχέση με άλλες γλώσσες σεναρίων.
Επειδή και η Lua και η JavaScript χρησιμοποιούν αντικείμενα βασισμένα στα πρωτότυπα, και επηρεάστηκαν από τη Scheme, έχουν αρκετά κοινή σημασιολογία, παρά τις σημαντικές διαφορές στη σύνταξη. Στη σχεδίασή της, η Lua μοιάζει επίσης με την Icon, ίσως επειδή και οι δύο επηρεάστηκαν από τη SNOBOL.
Η Lua έχει χρησιμοποιηθεί σε πολλές εφαρμογές, εμπορικές και μη-εμπορικές, και ιδιαίτερα στη βιομηχανία βιντεοπαιχνιδιών.

Χαρακτηριστικά

Η Lua συνήθως περιγράφεται σαν μια γλώσσα πολλαπλών παραδειγμάτων (multi-paradigm programming language) και παρέχει ένα μικρό σύνολο από γενικά χαρακτηριστικά που μπορούν να επεκταθούν για να ταιριάζουν σε διαφορετικούς τύπους προβλημάτων, αντί να βασίζεται σε έναν πολύπλοκο και δύσκαμπτο ορισμό που να ταιριάζει μόνο σε ένα παράδειγμα. Για παράδειγμα, δεν παρέχει ρητή υποστήριξη για κληρονομικότητα, αλλά επιτρέπει σχετικά εύκολα να υλοποιηθεί αυτό το χαρακτηριστικό με τη χρήση μετα-πινάκων (metatables). Επίσης η Lua επιτρέπει στον προγραμματιστή να υλοποιεί χώρους ονομάτων (namespaces), κλάσεις, και άλλα σχετικά χαρακτηριστικά με βάση την υλοποίηση των πινάκων της, ενώ οι συναρτήσεις πρώτης τάξης επιτρέπουν τη χρήση πολλών ισχυρών τεχνικών του συναρτησιακού προγραμματισμού, και οι πλήρεις λεκτικές δεσμέυσεις επιτρέπουν τη λεπτομερή απόκρυψη πληροφορίας, με βάση την αρχή του ελάχιστου προνόμιου (principle of least privilege).
Γενικά η Lua προσπαθεί να έχει ευέλικτα μετα-χαρακτηριστικά που να μπορούν να επεκταθούν όταν χρειάζεται, και όχι ένα εξειδικευμένο σύνολο χαρακτηριστικών για κάποιο συγκεκριμένο σκοπό. Αυτό έχει σαν αποτέλεσμα η βασική γλώσσα να είναι ελαφρή - στην πραγματικότητα, ο πλήρης πρότυπος διερμηνέας μεταγλωττισμένος είναι περίπου 150 KB — και προσαρμόζεται εύκολα σε ένα μεγάλο εύρος εφαρμογών.
Η Lua είναι γλώσσα με δυναμικούς τύπους που προορίζεται για επέκταση ή για γλώσσα σεναρίων, και είναι τόσο μικρή που μπορεί να ενσωματωθεί σε πολλές πλατφόρμες. Υποστηρίζει μόνο ένα μικρό αριθμό ατομικών δομών δεδομένων όπως οι τιμές αλήθειας, οι αριθμοί (κινητής υποδιαστολής με διπλή ακρίβεια), και οι συμβολοειρές. Τυπικές δομές δεδομένων όπως οι πίνακες, τα σύνολα, οι λίστες και οι εγγραφές μπορούν να αναπαρασταθούν με τη χρήση της μοναδικής ενσωματωμένης δομης δεδομένων στη Lua, που πρακτικά είναι ένας ετερογενής πίνακας αντιστοίχισης (associative array).
Η Lua υλοποιεί ορισμένα προχωρημένα χαρακτηριστικά όπως οι συναρτήσεις πρώτης τάξης, η συλλογή απορριμμάτων, τα κλεισίματα, η σωστή αναδρομή ουράς, ο εξαναγκασμός τύπων (coercion) (αυτόματη μετατροπή μεταξύ συμβολοσειρών και αριθμών στο χρόνο εκτέλεσης), οι συρρουτίνες (συνεργατική πολυδιεργασία) και η δυναμική φόρτωση μονάδων κώδικα (modules).
Με τη χρήση μόνο αυτού του ελάχιστου συνόλου τύπων δεδομένων η Lua επιτυγχάνει μια ισορροπία μεταξύ ισχύος και μεγέθους.

Παραδείγματα κώδικα

Το κλασικό πρόγραμμα "hello world" γράφεται ως εξής:
print("Hello World!")
Σχόλια:
-- Τα σχόλια στη Lua αρχίζουν με διπλή παύλα και συνεχίζονται ως το τέλος της γραμμής.-- [[Οι συμβολοσειρές και τα σχόλια που καταλαμβάνουν πολλές γραμμές
     "διακοσμούνται" με διπλές αγκύλες.]]
Η factorial (παραγοντικό) είναι ένα παράδειγμα αναδρομικής συνάρτησης:
function factorial(n)
  if n == 1 or n == 0 then
    return 1
  else
    return n * factorial(n - 1)
  endend
Μια δεύτερη μορφή της συνάρτησης "παραγοντικό" προέρχεται από τη βραχυκυκλωμένη αποτίμηση των τελεστών αλήθειας στη Lua, με βάση την οποία η Lua επιστρέφει την τιμή του τελευταίου τελεστή που αποτιμήθηκε σε μια έκφραση:
function factorial2(n) 
  return n == 0 and 1 or n * factorial2(n - 1)end
 
Ο χειρισμός των συναρτήσεων από τη Lua σαν τιμές πρώτης τάξης φαίνεται στο επόμενο παράδειγμα, που τροποποιεί τη συμπεριφορά της συνάρτησης print:
do
  local oldprint = print           -- Αποθήκευσε την τρέχουσα συνάρτηση print σαν oldprint
  function print(s)                -- Όρισε πάλι τη συνάρτηση print
    if s == "foo" then
      oldprint("bar")
    else 
      oldprint(s) 
    end
  endend
Οι επόμενες κλήσεις στην ‘print’ θα οδηγηθούν τώρα στη νέα συνάρτηση και, χάρη στην εμβέλεια της Lua, η παλιά συνάρτηση είναι προσβάσιμη μόνο μέσα από τη νέα, τροποποιημένη συνάρτηση.
Η Lua επίσης υποστηρίζει κλεισίματα, όπως φαίνεται παρακάτω:
function makeaddfunc(x)
  -- Επιστρέφει μια νέα συνάρτηση που προσθέτει x στο όρισμά της
  return function(y)
    -- Όταν αναφερόμαστε στη μεταβλητή x, που είναι εκτός της τρέχουσας
    -- εμβέλειας και η διάρκεια ζωής της είναι μεγαλύτερη από αυτή της ανώνυμης
    -- συνάρτησης, η Lua δημιουργεί ένα κλείσιμο.
    return x + y
  endendplustwo = makeaddfunc(2)print(plustwo(5)) -- Εκτυπώνει 7
Ένα νέο κλείσιμο για τη μεταβλητή x δημιουργείται κάθε φορά που καλείται η makeaddfunc, ώστε η ανώνυμη συνάρτηση που επιστρέφεται να έχει πάντα πρόσβαση στη δική της παράμετρο x. Η διαχείριση του κλείσιμου γίνεται από τη συλλογή απορριμμάτων της Lua, όπως κάθε άλλο αντικείμενο.
Η επεκτάσιμη σημασιολογία είναι βασικό χαρακτηριστικό της Lua, και η ιδέα του “μεταπίνακα” (“metatable”) επιστρέφει στους πίνακες της Lua να διαμορφώνονται με ισχυρούς και μοναδικούς τρόπους. Το επόμενο παράδειγμα δείχνει έναν “άπειρο” πίνακα. Για κάθε , η fibs[n] επιστρέφει τον -οστό αριθμό Fibonacci χρησιμοποιώντας δυναμικό προγραμματισμό και memoization.
fibs = { 1, 1 } -- Αρχικές τιμές για τις fibs[1] και fibs[2].setmetatable(fibs, { -- Δίνει στη fibs κάποια "μαγική" συμπεριφορά.
  __index = function(name, n)                  -- Καλεί αυτήν τη συνάρτηση αν η fibs[n] δεν υπάρχει.
    name[n] = name[n - 1] + name[n - 2]        -- Υπολογίζει και απομνημονεύει την fibs[n].
    return name[n]
  end})

Επέκταση και αντιστοίχιση

Είναι δυνατό να γραφτούν επεκτάσεις χρησιμοποιώντας το API της Lua. Οι επεκτάσεις αυτές είναι δυναμικά συνδεδεμένα αντικείμενα που μπορούν να χρησιμοποιηθούν για να επεκτείνουν τη λειτουργικότητα του διερμηνέα παρέχοντας δυνατότητες χαμηλού επιπέδου της πλατφόρμας στα σενάρια σε Lua. Από την πλευρά της Lua, μια τέτοια επέκταση εμφανίζεται σαν ένας πίνακας-χώρος ονομάτων (namespace) που κρατά τις συναρτήσεις και τις μεταβλητές. Τα σενάρια Lua μπορούν να φορτώνουν επεκτάσεις χρησιμοποιώντας την εντολή require.
Μια ολοένα και αυξανόμενη συλλογή από επεκτάσεις (rocks) είναι διαθέσιμη μέσα από το σύστημα διαχείρισης πακέτων LuaRocks,, σε αντίστοιχία με το RubyGems. Άλλες πηγές είναι το LuaForge και ο κατάλογος Lua Addons του wiki στη σελίδα lua-users.org.
Έτοιμα πακέτα αντιστοίχισης με τη Lua υπάρχουν για τις πιο πολλές γνωστές γλώσσες προγραμματισμού, περιλαμβάνοντας άλλες γλώσσες σεναρίων.
Για τις C/C++, υπάρχουν κάποιες προσεγγίσεις βασισμένες σε πρότυπα και κάποια αυτόματα εργαλεία παραγωγής όπως το tolua, το tolua++, το SWIG, το Luabind, το LuaPlus και το Luna.