ALGOL

Σημαντικές υλοποιήσεις

Η International Algorithmic Language (IAL ή ALGOL 58) υπήρξε επιδραστική και γενικά θεωρείται ο πρόγονος πολλών σύγχρονων γλωσσών προγραμματισμού. Επιπλέον, στην επιστήμη υπολογιστών, ο αντικειμενικός κώδικας της ALGOL (ALGOL object code) ήταν ένας απλός και περιεκτικός τρόπος να περιγραφεί σε αρχιτεκτονική με στοίβες, που χρησιμοποιούνταν στη διδασκαλία κατασκευής μεταγλωττιστών και άλλων γλωσσών υψηλού επιπέδου (με την Algol να θεωρείται γενικά η πρώτη από αυτές).

Η Algol και η έρευνα στις γλώσσες προγραμματισμού

Όπως παρατήρησε και ο Peter Landin, η Algol ήταν η πρώτη γλώσσα που συνδύασε επιτυχημένα τα προστακτικά εφέ (imperative effects) με το λ-λογισμό με κλήση κατ' όνομα (call-by-name). Ο John C. Reynolds ίσως έδωσε τον πιο κομψό τυπικό ορισμό της γλώσσας, με τρόπο που επιδεικνύει τη συντακτική και σημασιολογική της καθαρότητα. Η "ιδανική" Algol του Reynolds υπήρξε επίσης επιχείρημα υπέρ της σύγκρισης των τοπικών εφφέ ("local" effects) των γλωσσών με κλήση κατ' όνομα σε σχέση με τα καθολικά εφφέ ("global" effects) που χρησιμοποιούνται από τις γλώσσες με κλήση κατά τιμή (call-by-value), όπως η ML. Η θεωρητική ακεραιότητα της γλώσσας υπήρξε σημαντική για τη χρήση της στην έρευνα της σημασιολογίας, μαζί με την PCF και την ML.

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

Όπως ορίστηκε επίσημα, η ALGOL 60 δεν είχε δυνατότητες εισόδου/εξόδου - κάθε υλοποίηση όριζε το δικό της τρόπο με αποτέλεσμα συνήθως να υπάρχει θέμα συμβατότητας μεταξύ διαφορετικών υλοποιήσεων. Αντίθετα, η ALGOL 68 προσέφερε μια εκτενή βιβλιοθήκη από δυνατότητες transput (όρος της ALGOL 68 για την είσοδο και την έξοδο).
Η ALGOL 60 επέτρεπε δύο ειδών στρατηγικές αποτίμησης για το πέρασμα παραμέτρων: τη συνηθισμένη κλήση κατά τιμή (call-by-value), και την κλήση κατ' όνομα (call-by-name). Η κλήση κατ' όνομα είχε κάποιους περιορισμούς σε σχέση με την κλήση κατ' αναφορά (call-by-reference), με αποτέλεσμα να έχει κάποιες ανεπιθύμητες ιδιότητες όσον αφορά τη σχεδίαση προστακτικών γλωσσών. Για παράδειγμα, είναι αδύνατο στην ALGOL 60 να γραφεί μια διαδικασία που να ανταλλάσσει τις τιμές δύο παραμέτρων, αν αυτές είναι μια παράμετρος τύπου ακεραίου και ένας πίνακας που δεικτοδοτείται από την ίδια μεταβλητή ακεραίου. Έστω ότι περνιέται ένας δείκτης στη swap(i, A[i]) σε μια συνάρτηση. Τότε, κάθε φορά που γίνεται αναφορά στη swap(), αυτή αποτιμάται πάλι. Έστω ότι i := 1 και A[i] := 2, ώστε κάθε φορά που γίνεται αναφορά στη swap(), αυτή θα επιστρέψει τον άλλο συνδυασμό των τιμών ([1,2], [2,1], [1,2], και ομοίως). Άλλη προβληματική περίπτωση είναι το πέρασμα μιας συνάρτησης random() που να επιστρέφει τυχαίες τιμές.
Όμως, η κλήση κατ' όνομα εξακολουθούσε να αποτελεί αγαπημένο θέμα όσων υλοποιούσαν την ALGOL λόγω του ενδιαφέροντος που είχε ο μηχανισμός των "thunks" που χρησιμοποιήθηκε για να την υλοποιήσει. Ο Ντόναλντ Κνουθ εφηύρε το τεστ "άντρας ή αγόρι" ("man or boy test"), για να ξεχωρίσει μεταξύ των μεταγλωττιστών που υλοποιούσαν σωστά την αναδρομή και τις μη-τοπικές αναφορές. Το τεστ αυτό περιλαμβάνει ένα παράδειγμα της κλήσης κατ' όνομα.
Η ALGOL 68 ορίστηκε χρησιμοποιώντας ένα φορμαλισμό γραμματικής δύο επιπέδων που εφευρέθηκε από τον Adriaan van Wijngaarden και από τότε έχει το όνομά του. Οι γραμματικές van Wijngaarden χρησιμοποιούν μια γραμματική χωρίς συμφραζόμενα (context-free grammar) για να παράγουν ένα άπειρο σύνολο από παραγωγές που αναγνωρίζουν ένα συγκεκριμένο πρόγραμμα ALGOL 68 - ειδικότερα, μπορούν να εκφράσουν τις απαιτήσεις αυτές που σε άλλα πρότυπα γλωσσών προγραμματισμού αποκαλούνται "σημασιολογία" και πρέπει να εκφραστούν σε (μη ακριβή) φυσική γλώσσα, σαν κείμενο, και στη συνέχεια να υλοποιηθούν στο μεταγλωττιστή σαν ad hoc κώδικας που συνδέεται με το συντακτικό αναλυτή της γλώσσας.

ALGOL 60

(Ο τρόπος που γράφεται το κείμενο με έντονα γράμματα, εξαρτάται από την υλοποίηση, για παράδειγμα μπορεί να είναι 'INTEGER' (μαζί με τα εισαγωγικά) ή integer (αυτό ονομάζεται stropping).
procedure Absmax(a) Size:(n, m) Result:(y) Subscripts:(i, k);
    value n, m; array a; integer n, m, i, k; real y;
comment Το απόλυτα μεγαλύτερο στοιχείο του πίνακα a, μεγέθους n επί m,
μεταφέρεται στην y και οι δείκτες αυτού του στοιχείου είναι i και k;
begin integer p, q;
    y := 0; i := k := 1;
    for p:=1 step 1 until n do
    for q:=1 step 1 until m do
        if abs(a[p, q]) > y then
            begin y := abs(a[p, q]);
            i := p; k := q
            endend Absmax
Ακολουθεί ένα παράδειγμα παραγωγής ενός πίνακα στην Elliott 803 ALGOL.
 FLOATING POINT ALGOL TEST'
 BEGIN REAL A,B,C,D'
 READ D'
 FOR A:= 0.0 STEP D UNTIL 6.3 DO
 BEGIN
   PRINT PUNCH(3),££L??'
   B := SIN(A)'
   C := COS(A)'
   PRINT PUNCH(3),SAMELINE,ALIGNED(1,6),A,B,C'
 END'
 END'
η PUNCH(3) στέλνει την έξοδο στον εκτυπωτή (teleprinter) αντί για το διατρητή ταινίας (tape punch).

η SAMELINE αποκρύπτει την αλλαγή γραμμής που τυπώνεται κανονικά ανάμεσα σε δύο παραμέτρους.

η ALIGNED(1,6) θέτει τη μορφή της εξόδου σαν 1 ψηφίο πριν και 6 ψηφία μετά από την υποδιαστολή.

ALGOL 68

Ο ακόλουθος κώδικας είναι ο αντίστοιχος σε ALGOL 68 του πρηγούμενου κώδικα σε ALGOL 60.
Η ALGOL 68 κάνει χρήση του stropping της ALGOL 60. Στην ALGOL 68, οι λέξεις με έντονα γράμματα είναι δεσμευμένες λέξεις, τύποι (modes) ή τελεστές.
proc abs max = ([,]real a, ref real y, ref int i, k)real:
comment Το απόλυτα μεγαλύτερο στοιχείο του πίνακα a, μεγέθους ⌈a επί 2⌈a
μεταφέρεται στην y και οι δείκτες του στοιχείου είναι i και k; commentbegin
   real y := 0; i := ⌊a; k := 2⌊a;
   for p from ⌊a to ⌈a do
     for q from 2⌊a to 2⌈a do
       if abs a[p, q] > y then
           y := abs a[p, q];
           i := p; k := q
       fi
     od
   od;
   y
end # abs max #
Σημείωση: τα κατώτερα (⌊) και ανώτερα (⌈) όρια ενός πίνακα, και οι "φέτες" πίνακα (array slicing), είναι διαθέσιμα στον προγραμματιστή.
δοκιμή με αριθμούς κινητής υποδιαστολής (floating point) σε algol68:
(
  real a,b,c,d;
  printf(($pg$,"Εισάγετε d:"));
  read(d);
  for step from 0 while a:=step*d; a <= 2*pi do
    printf($l$);
    b := sin(a);
    c := cos(a);
    printf(($z-d.6d$,a,b,c))
  od
)
printf - στέλνει την έξοδο στο αρχείο πρότυπη έξοδος (stand out).
printf($p$); - επιλέγει μια νέα σελίδα (new page).
printf($l$); - επιλέγει μια νέα γραμμή (new line).
printf(($z-d.6d$,a,b,c)) - μορφοποιεί την έξοδο με 1 ψηφίο πριν και 6 ψηφία μετά την υποδιαστολή.

Χρονοδιάγραμμα: Hello world

Οι διαφορές και η έλλειψη φορητότητας των προγραμμάτων μεταξύ των υλοποιήσεων φαίνεται από το κλασικό πρόγραμμα που εκτυπώνει τη φράση "hello world".

ALGOL 58 (IAL)

Η ALGOL 58 δεν είχε δυνατότητες εισόδου/εξόδου.

Οικογένεια της ALGOL 60

Η ALGOL 60 δεν είχε δυνατότητες εισόδου/εξόδου, επομένως δεν υπάρχει μεταφέρσιμη έκδοση του προγράμματος στην ALGOL. Το πρόγραμμα που ακολουθεί θα μπορούσε να μεταγλωττιστεί και να εκτελεστεί σε μια υλοποίηση της ALGOL για έναν υπολογιστή Unisys A-Series mainframe, και αποτελεί μια απευθείας απλοποιημένη έκδοση του κώδικα από το The Language Guide του Dearborn Computer and Information Science Department του Πανεπιστημίου του Μίσιγκαν.
BEGIN
  FILE F(KIND=REMOTE);
  EBCDIC ARRAY E[0:11];
  REPLACE E BY "HELLO WORLD!";
  WRITE(F, *, E);
END.
Ένα απλό πρόγραμμα που χρησιμοποιεί απευθείας μορφή:
BEGIN
  FILE F(KIND=REMOTE);
  WRITE(F, <"HELLO WORLD!">);
END.
Ένα ακόμα πιο απλό πρόγραμμα που χρησιμοποιεί την εντολή Display:
BEGIN DISPLAY("HELLO WORLD!") END.
Ακολουθεί ένα εναλλακτικό παράδειγμα, που χρησιμοποιεί την είσοδο/έξοδο της Elliott Algol. Η Elliott Algol χρησιμοποιούσε διαφορετικούς χαρακτήρες για τα δεξιά εισαγωγικά και τα αριστερά εισαγωγικά, τους ‘ και ’.
 program HiFolks;
 begin
    print ‘Hello world’;
 end;
Ακολουθεί μια έκδοση για την Elliott 803 Algol (A104). Το Elliott 803 κλασικά χρησιμοποιούσε χαρτοταινία με 5 τρύπες και είχε μόνο κεφαλαία γράμματα. Ο κώδικας δεν είχε χαρακτήρες εισαγωγικών και χρησιμοποιούνταν το £ (σύμβολο της λίρας του Ηνωμένου Βασιλείου) για το αριστερό εισαγωγικό και το ? (αγγλικό ερωτηματικό) για το δεξιό εισαγωγικό. Οι ειδικές ακολουθίες τοποθετούνταν σε διπλά εισαγωγικά (π.χ. η ££L?? παρήγαγε μια νέα γραμμή στον εκτυπωτή).
  HIFOLKS'
  BEGIN
     PRINT £HELLO WORLD£L??'
  END'
Η ICT 1900 Algol επέτρεπε είσοδο από χαρτοταινία ή διάτρητη κάρτα. Σε κατάσταση χαρτοταινίας, επέτρεπε πεζά γράμματα. Η έξοδος εμφανιζόταν σε έναν εκτυπωτή γραμμής (line printer).
  'BEGIN'
     'WRITE TEXT'("HELLO WORLD");
  'END'

ALGOL 68

Ο κώδικας σε ALGOL 68 εμφανιζόταν με τις δεσμευμένες λέξεις σε πεζά γράμματα αλλά με έντονη γραφή ή υπογράμμιση.
begin
  printf(($gl$,"Hello, world!"))
end
Οι δυνατότητες εισόδου/εξόδου στην αναφορά της γλώσσας ("Algol 68 Report") αποκαλούνταν "Transput".