Γλώσσες και προγραμματιστικά υποδείγματα
Διαδικαστικό, αντικειμενοστραφές, συναρτησιακό — και οι μεταφραστές.
40 λεπτά
Θα μάθεις να
- Να διακρίνεις γλώσσα μηχανής, συμβολική γλώσσα και γλώσσες υψηλού επιπέδου.
- Να συγκρίνεις μεταγλωττιστή και διερμηνέα ως προς τον τρόπο λειτουργίας και τα σφάλματα.
- Να αναγνωρίζεις το διαδικαστικό, το αντικειμενοστραφές, το συναρτησιακό και το λογικό υπόδειγμα.
- Να γράφεις την ίδια λύση σε Python με διαδικαστικό και με συναρτησιακό τρόπο.
Από τα bits στις λέξεις
Ο επεξεργαστής καταλαβαίνει μόνο τη γλώσσα μηχανής: εντολές γραμμένες ως αριθμοί σε δυαδικό. Οι πρώτοι προγραμματιστές έγραφαν ακριβώς αυτό, και ένα λάθος bit σήμαινε ώρες αναζήτησης. Από τότε, κάθε γενιά γλωσσών απομακρύνεται λίγο ακόμα από τη μηχανή και πλησιάζει τον άνθρωπο.
| Επίπεδο | Πώς μοιάζει η πρόσθεση c = a + b | Ποιος τη διαβάζει εύκολα |
|---|---|---|
| Γλώσσα μηχανής | 0001 1010, 0011 1011, 0010 1100 | μόνο η μηχανή |
| Συμβολική γλώσσα (assembly) | LOAD a, ADD b, STORE c | ο άνθρωπος, με κόπο |
| Γλώσσα υψηλού επιπέδου | c = a + b | ο άνθρωπος |
Οι δυαδικοί κωδικοί της πρώτης γραμμής είναι φανταστικοί, όπως ο επεξεργαστής του μαθήματος για την αρχιτεκτονική. Κάθε πραγματικός επεξεργαστής έχει τους δικούς του. Η συμβολική γλώσσα είναι απλώς ονόματα για τους ίδιους κωδικούς, μία προς μία, άρα είναι κι αυτή δεμένη με έναν συγκεκριμένο τύπο επεξεργαστή. Μια γλώσσα υψηλού επιπέδου δεν είναι: το ίδιο πρόγραμμα μπορεί να τρέξει σε υπολογιστή, σε κινητό ή σε εξυπηρετητή.
Οι μεταφραστές
Αφού η μηχανή καταλαβαίνει μόνο γλώσσα μηχανής, κάθε άλλη γλώσσα χρειάζεται μεταφραστή.
- Ο συμβολομεταφραστής (assembler) μετατρέπει συμβολική γλώσσα σε γλώσσα μηχανής.
- Ο μεταγλωττιστής (compiler) μεταφράζει ολόκληρο το πρόγραμμα μία φορά και παράγει ένα εκτελέσιμο αρχείο. Μετά, το πρόγραμμα τρέχει χωρίς τον μεταγλωττιστή.
- Ο διερμηνέας (interpreter) διαβάζει το πρόγραμμα και το εκτελεί απευθείας, εντολή προς εντολή, κάθε φορά που τρέχει.
| Μεταγλωττιστής | Διερμηνέας | |
|---|---|---|
| Πότε μεταφράζει | μία φορά, πριν από την εκτέλεση | κάθε φορά, κατά την εκτέλεση |
| Ταχύτητα εκτέλεσης | συνήθως μεγαλύτερη | συνήθως μικρότερη |
| Τι χρειάζεται ο χρήστης | μόνο το εκτελέσιμο | τον πηγαίο κώδικα και τον διερμηνέα |
| Συντακτικά λάθη | εντοπίζονται όλα πριν τρέξει οτιδήποτε | εμφανίζονται όταν φτάσει η εκτέλεση εκεί |
| Δοκιμή μιας αλλαγής | μεταγλώττιση και μετά εκτέλεση | εκτέλεση αμέσως |
Προγραμματιστικά υποδείγματα
Ένα προγραμματιστικό υπόδειγμα (programming paradigm) είναι ένας τρόπος σκέψης για το πώς περιγράφεται μια λύση. Δεν είναι γλώσσα: πολλές γλώσσες, όπως η Python, υποστηρίζουν περισσότερα από ένα.
| Υπόδειγμα | Το πρόγραμμα είναι… | Τυπικές γλώσσες |
|---|---|---|
| Διαδικαστικό (procedural) | σειρά εντολών που αλλάζουν τις τιμές μεταβλητών, οργανωμένη σε υποπρογράμματα | C, Pascal, η ΓΛΩΣΣΑ του σχολικού βιβλίου |
| Αντικειμενοστραφές (object-oriented) | αντικείμενα που κρατούν δεδομένα και ξέρουν να κάνουν πράγματα με αυτά | Java, C++, C#, Python |
| Συναρτησιακό (functional) | σύνθεση συναρτήσεων, χωρίς αλλαγές σε μεταβλητές | Haskell, Lisp, και εν μέρει η Python |
| Λογικό (logic) | γεγονότα και κανόνες, και ερωτήσεις πάνω σε αυτά | Prolog |
Το ίδιο πρόβλημα, «το άθροισμα των τετραγώνων των άρτιων αριθμών μιας λίστας», σε τρία υποδείγματα, όλα σε Python:
numbers = [3, 8, 5, 2, 10, 7]
# Διαδικαστικό: βήματα που αλλάζουν μια μεταβλητή
total = 0
for x in numbers:
if x % 2 == 0:
total += x * x
print(total)
# Συναρτησιακό: σύνθεση συναρτήσεων, καμία μεταβλητή δεν αλλάζει
print(sum(map(lambda x: x * x, filter(lambda x: x % 2 == 0, numbers))))
# Αντικειμενοστραφές: δεδομένα και λειτουργίες μαζί σε ένα αντικείμενο
class NumberBag:
def __init__(self, items):
self.items = list(items)
def evens(self):
return NumberBag(x for x in self.items if x % 2 == 0)
def sum_of_squares(self):
return sum(x * x for x in self.items)
bag = NumberBag(numbers)
print(bag.evens().sum_of_squares())
Και οι τρεις τυπώνουν 168, γιατί οι άρτιοι είναι , και , και .
- Στο διαδικαστικό, η μεταβλητή
totalαλλάζει τιμή σε κάθε επανάληψη. Για να καταλάβεις το πρόγραμμα, το ακολουθείς βήμα-βήμα. - Στο συναρτησιακό, δεν αλλάζει τίποτα: το
filterκρατά τους άρτιους, τοmapτους υψώνει στο τετράγωνο, τοsumτους προσθέτει. Διαβάζεται από μέσα προς τα έξω, σαν μαθηματική σύνθεση. - Στο αντικειμενοστραφές, τα δεδομένα και οι λειτουργίες τους είναι πακεταρισμένα μαζί στην κλάση
NumberBag. Όποιος τη χρησιμοποιεί ζητά από το αντικείμενο να κάνει κάτι, χωρίς να ξέρει πώς είναι φτιαγμένο μέσα.
Στο λογικό υπόδειγμα δεν γράφεις καν πώς βρίσκεται η απάντηση. Δηλώνεις γεγονότα («η Άννα είναι μητέρα της Ελένης») και κανόνες («Χ είναι γιαγιά του Ζ αν Χ είναι μητέρα του Υ και Υ είναι γονέας του Ζ»), και ρωτάς: «ποιος είναι γιαγιά της Μαρίας;». Το σύστημα βρίσκει μόνο του τη διαδρομή.
Δύο παρατηρήσεις ακόμα. Η SQL, που θα δούμε στις βάσεις δεδομένων, είναι δηλωτική (declarative) γλώσσα: λες τι δεδομένα θέλεις και όχι πώς να βρεθούν. Και η HTML δεν είναι γλώσσα προγραμματισμού αλλά γλώσσα σήμανσης: περιγράφει τη δομή ενός εγγράφου, δεν εκτελεί υπολογισμούς.
Λυμένα παραδείγματα
Παράδειγμα 1
Ένα παιχνίδι διανέμεται ως ένα εκτελέσιμο αρχείο που τρέχει χωρίς να χρειάζεται εγκατεστημένο κανένα άλλο εργαλείο. Τι μεταφραστής χρησιμοποιήθηκε πιθανότατα;
Δοκίμασέ το πρώτα. Μετά δες τη λύση.
Παράδειγμα 2
Ξαναγράψε σε συναρτησιακό ύφος: «total = 0· για κάθε x στη λίστα, αν x > 5, total += x».
Δοκίμασέ το πρώτα. Μετά δες τη λύση.
Παράδειγμα 3
Ένα αρχείο Python έχει γραμμές. Η γραμμή έχει μια παρένθεση που ανοίγει και δεν κλείνει. Τι θα δει ο χρήστης όταν το τρέξει; Και τι αν αντί γι' αυτό η γραμμή τύπωνε μια μεταβλητή που δεν έχει οριστεί;
Δοκίμασέ το πρώτα. Μετά δες τη λύση.
Παράδειγμα 4
Σε ποιο υπόδειγμα ταιριάζει καλύτερα καθένα από τα εξής: (α) ένα παιχνίδι με πολλούς χαρακτήρες, καθένας με δική του ενέργεια και κινήσεις, (β) ένα σύστημα που απαντά σε ερωτήσεις για ένα γενεαλογικό δέντρο, (γ) ένα σενάριο που μετατρέπει μια λίστα τιμών σε νέα λίστα χωρίς να αλλάζει την αρχική;
Δοκίμασέ το πρώτα. Μετά δες τη λύση.
Ασκήσεις
Πρώτα ερωτήσεις με επιλογές: διαλέγεις, πατάς «Έλεγξε» και μαθαίνεις αμέσως αν το βρήκες και γιατί. Στο τέλος, λίγες ασκήσεις χωρίς επιλογές — εκεί κρύβεται μόνο η απάντηση.
Τα κατάφερες;
- Να διακρίνεις γλώσσα μηχανής, συμβολική γλώσσα και γλώσσες υψηλού επιπέδου.
- Να συγκρίνεις μεταγλωττιστή και διερμηνέα ως προς τον τρόπο λειτουργίας και τα σφάλματα.
- Να αναγνωρίζεις το διαδικαστικό, το αντικειμενοστραφές, το συναρτησιακό και το λογικό υπόδειγμα.
- Να γράφεις την ίδια λύση σε Python με διαδικαστικό και με συναρτησιακό τρόπο.
Λύσε τις ασκήσεις πιο πάνω και θα δεις εδώ πού στέκεσαι.