Εγγραφές ραστηριοποίησης

Σχετικά έγγραφα
Εγγραφές Δραστηριοποίησης

Εγγραφές Δραστηριοποίησης

Εγγραφές Δραστηριοποίησης. Jackson Pollock, The Key, 1946 (action painting)

Πανεπιστήμιο Θεσσαλίας Τμήμα Ηλεκτρολόγων Μηχανικών και Μηχανικών Υπολογιστών Τμήμα Πληροφορικής

Σχεδίαση Γλωσσών Προγραμματισμού. Εαρινό Εξάμηνο Lec03 18/02/2019

Λογισµικό (Software SW) Γλώσσες

Ανάπτυξη και Σχεδίαση Λογισμικού

Αναδρομή. ΗΥ 232 Οργάνωση και Σχεδίαση Υπολογιστών. Διάλεξη 6. Νίκος Μπέλλας Τμήμα Μηχανικών Η/Υ, Τηλεπικοινωνιών και Δικτύων

Εμβέλεια. Παραδείγματα. Παραδείγματα. Μπλοκ (blocks)

Ονόματα και Εμβέλεια. Wassily Kandinsky, Black lines, 1913

Εισαγωγή στη Γλώσσα ML. Juan Miró

Εισαγωγή στη Γλώσσα ML

Δομημένος Προγραμματισμός

Προγραμματισμός Ι (ΗΥ120)

procedure P ( < pars > ) < type> f( < pars > ) begin { < local vars > < local vars > < procedure body> < procedure body> end; }

Ονόµατα και Εµβέλεια 4

Chapter 2. Εντολές : Η γλώσσα του υπολογιστή. (συνέχεια) Η διασύνδεση Υλικού και λογισμικού David A. Patterson και John L.

Αντικειμενοστρέφεια. Henri Matisse, Harmony in Red, Κωστής Σαγώνας Νίκος Παπασπύρου

Ονόματα και Εμβέλεια 6

Η Γλώσσα Προγραµµατισµού C++ (The C++ Programming Language)

Εισαγωγή στους Η/Υ. Γιώργος Δημητρίου. Μάθημα 3-4: Προγραμματισμός MIPS. Πανεπιστήμιο Θεσσαλίας - Τμήμα Πληροφορικής

Προγραμματισμός Υπολογιστών & Υπολογιστική Φυσική

Ευφυής Προγραμματισμός

Εισαγωγή στον Προγραμματισμό

Κεφάλαιο 10 ο Υποπρογράµµατα

Εισαγωγή στη Γλώσσα ML

Chapter 2. Εντολές : Η γλώσσα του υπολογιστή. (συνέχεια) Η διασύνδεση Υλικού και λογισμικού David A. Patterson και John L.

Κεφάλαιο 6 Υλοποίηση Γλωσσών Προγραμματισμού

Ονόματα και Εμβέλεια 4

Εισαγωγή στον Προγραμματισμό

- Το πρόγραµµα σας δίνει τα αναµενόµενα αποτελέσµατα.

Κεφάλαιο 7 : Είδη, Τεχνικές, και Περιβάλλοντα Προγραµµατισµού

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Κλάσεις και Αντικείμενα Αναφορές

Δομημένος Προγραμματισμός (ΤΛ1006)

ΥΠΟΠΡΟΓΡΑΜΜΑΤΑ. Κάθε υποπρόγραμμα έχει μόνο μία είσοδο και μία έξοδο. Κάθε υποπρόγραμμα πρέπει να είναι ανεξάρτητο από τα άλλα.

ΜΥΥ105: Εισαγωγή στον Προγραµµατισµό. Αναδροµικές Συναρτήσεις Χειµερινό Εξάµηνο 2014

Ανάπτυξη Μεγάλων Εφαρµογών στη Γλώσσα C (Programming in the large)

Διάλεξη 13η: Δυναμική Διαχείρηση Μνήμης, μέρος 1

Κεφάλαιο 12 : ΥΠΟΠΡΟΓΡΑΜΜΑΤΑ

{ int a = 5; { int b = 7; a = b + 3;

Προγραμματισμός Η/Υ (ΤΛ2007 )

Βασικά Στοιχεία της Java

Προγραµµατισµός. Αναδροµή (1/2)

Pascal. 15 Νοεμβρίου 2011

Ανάπτυξη Μεγάλων Εφαρµογών στη Γλώσσα C (2)

Οι δείκτες στη γλώσσα C

2 Ορισμός Κλάσεων. Παράδειγμα: Μηχανή για Εισιτήρια. Δομή μιας Κλάσης. Ο Σκελετός της Κλάσης για τη Μηχανή. Ορισμός Πεδίων 4/3/2008

Κεφάλαιο 7: Υπορουτίνες

Sheet2. - Άσκηση 1 οκ - Άσκηση 2 οκ. Σκέψου πώς θα µπορούσες να την

for for for for( . */

Ανάπτυξη και Σχεδίαση Λογισμικού

Εισαγωγή στον Προγραμματισμό (με. τη C)

Προγραμματισμός Ι. Συναρτήσεις. Πανεπιστήμιο Πελοποννήσου Τμήμα Πληροφορικής & Τηλεπικοινωνιών

Γλώσσες Προγραμματισμού Μεταγλωττιστές

Συναρτήσεις-Διαδικασίες

Κλάσεις και Αντικείµενα

Σε γενικές γραμμές, είναι καλή πρακτική να γράϕουμε προγράμματα C που αποτελούνται από πολλές και μικρές συναρτήσεις, παρά από λίγες και μεγάλες.

Προηγμένοι Μικροεπεξεργαστές. Έλεγχος Ροής Προγράμματος

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αναφορές Στοίβα και Σωρός Αναφορές-Παράμετροι

FAIL PASS PASS οριακά

Η γλώσσα προγραμματισμού C

Προγραμματισμός ΙI (Θ)

Διαδικασιακός Προγραμματισμός

Προγραμματισμός Η/Υ. Ενότητα 7: Συναρτήσεις

FORTRAN και Αντικειμενοστραφής Προγραμματισμός

Φροντιστήριο. Παραγωγή τελικού κώδικα. Παραγωγή τελικού κώδικα

Εισαγωγή στον δομημένο προγραμματισμό

ΕΙΣΑΓΩΓΗ ΣΤΟN ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ ΠΑΝΕΠΙΣΤΗΜΙΟ ΠΑΤΡΩΝ ΠΟΛΥΤΕΧΝΙΚΗ ΣΧΟΛΗ ΤΜΗΜΑ ΜΗΧΑΝΙΚΩΝ Η/Υ ΚΑΙ ΠΛΗΡΟΦΟΡΙΚΗΣ

Δομές Δεδομένων (Εργ.) Ακ. Έτος Διδάσκων: Ευάγγελος Σπύρου. Εργαστήριο 3 Επανάληψη Γ μέρος

Sheet2. Σωστή, και µπράβο που µεριµνήσατε για λίστες διαφορετικών µεγεθών.

Τεχνολογία Λογισµικού Ι Κεφάλαιο 5

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αναφορές Στοίβα και Σωρός Μνήμης Αντικείμενα ως ορίσματα

Εισαγωγή στον Προγραµµατισµό «C»

Διαδικασιακός Προγραμματισμός

Παράμετροι 19/9/2007. Πέρασμα παραμέτρων. Περιεχόμενα. Θέσεις και ονόματα στο ταίριασμα παραμέτρων. Ταίριασμα παραμέτρων μέσω ονομάτων

Διάλεξη 13: Δομές Δεδομένων ΙΙ (Ταξινομημένες Λίστες)

Δομές Δεδομένων (Data Structures)

Γιάννης Σαμωνάκης. 1 ο ΣΧΟΛΕΙΟ ΚΩΔΙΚΑ «Βασικά Θέματα Προγραμματισμού στην Ανάπτυξη Δυναμικών Διαδικτυακών Εφαρμογών» (Part 4 - PHP)

Chapter 2. Εντολές : Η γλώσσα του υπολογιστή. (συνέχεια) Η διασύνδεση Υλικού και λογισμικού David A. Patterson και John L.

Εργαστήριο 1: Επανάληψη Βασικών Εννοιών στη Γλώσσα C

ΥΠΟΠΡΟΓΡΑΜΜΑΤΑ. Διαδικασίες και συναρτήσεις. 22 Νοε 2008 Ανάπτυξη εφαρμογών/ Υποπρογράμματα 1

είκτες και Πίνακες (2)

lab13grades 449 PASS 451 PASS PASS FAIL 1900 FAIL Page 1

Διδάσκων: Παναγιώτης Ανδρέου

Βασικά Στοιχεία της Java

Αρχές Γλωσσών Προγραμματισμού και Μεταφραστών

Κεφάλαιο 5ο: Εντολές Επανάληψης

Αναδροµή. Σε αυτήν την (βοηθητική) ενότητα θα µελετηθούν τα εξής : Η έννοια της αναδροµής Υλοποίηση και αποδοτικότητα Αφαίρεση της αναδροµής

ΚΥΡΙΑ ΜΟΝΤΕΛΑ ΓΛΩΣΣΩΝ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

Κεφάλαιο , 3.2: Συναρτήσεις II. ( ιάλεξη 12) ιδάσκων: ηµήτρης Ζεϊναλιπούρ

Αρχές Γλωσσών Προγραμματισμου Χρήστος Νομικός Τμήμα Μηχανικών Η/Υ και Πληροφορικής Πανεπιστήμιο Ιωαννίνων 2015 Χρήστος Νομικός ( Τμήμα Μηχανικών Αρχές

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

Διαδικαστικός Προγραμματισμός

Εισαγωγή στον δομημένο προγραμματισμό

υναµικές οµές εδοµένων

ΚΕΦΑΛΑΙΟ 2: Χειρισµός εδοµένων

Κεφάλαιο 7: Υποπρογράμματα. Αρχές Γλωσσών Προγραμματισμού και Μεταφραστών

ΣΧΕΔΙΑΣΗ ΚΑΙ ΥΛΟΠΟΙΗΣΗ ΛΟΓΙΣΜΙΚΟΥ

3ο σετ σημειώσεων - Πίνακες, συμβολοσειρές, συναρτήσεις

Αρχές Γλωσσών Προγραμματισμού και Μεταφραστών

Transcript:

Εγγραφές ραστηριοποίησης Ερώτηση για δέσιµο Κατά την εκτέλεση του προγράµµατος, οι µεταβλητές δένονται (δυναµικά) µε τιµές Οι τιµές αυτές πρέπει να αποθηκευτούν κάπου Κατά συνέπεια, οι µεταβλητές πρέπει κάπως να δεθούν µε θέσεις µνήµης Πώς γίνεται αυτό; Jackson Pollock, The Key, 1946 (action patg) Κωστής Σαγώνας <kostis@cs.ntua.gr> Εγγραφές δραστηριοποίησης 2 Συναρτησιακές γλώσσες συναντούν προστακτικές Οι προστακτικές γλώσσες κάνουν εµφανή την έννοια των θέσεων µνήµης: a := 0 Αποθήκευσε µηδέν στη θέση µνήµης της µεταβλητής a Οι συναρτησιακές γλώσσες τις κρύβουν: val a = 0 έσε το όνοµα a µε την τιµή µηδέν Και τα δύο είδη γλωσσών πρέπει να ενώσουν µεταβλητές µε τιµές που αναπαρίστανται στη µνήµη Άρα και οι δύο πρέπει να αντιµετωπίσουν την ίδια ερώτηση δεσίµατος Περιεχόµενα Εγγραφές δραστηριοποίησης (s) Στατική δέσµευση εγγραφών δραστηριοποίησης Στοίβες από εγγραφές δραστηριοποίησης Χειρισµός φωλιασµένων ορισµών συναρτήσεων Συναρτήσεις ως παράµετροι Μακρόβιες εγγραφές δραστηριοποίησης Εγγραφές δραστηριοποίησης 3 Εγγραφές δραστηριοποίησης 4

ραστηριοποιήσεις συναρτήσεων Ο χρόνος ζωής της εκτέλεσης µιας συνάρτησης, από την κλήση µέχρι την αντίστοιχη επιστροφή, ονοµάζεται δραστηριοποίηση (activation) της συνάρτησης Όταν κάθε δραστηριοποίηση έχει το δικό της δέσιµο µεταβλητών σε θέσεις µνήµης, λέµε ότι έχουµε µεταβλητές ειδικές για κάθε δραστηριοποίηση Οι µεταβλητές αυτές ονοµάζονται επίσης δυναµικές (dynamic dynamic) ή αυτόµατες (automatic) µεταβλητές Μεταβλητές ειδικές για κάθε δραστηριοποίηση Στις περισσότερες µοντέρνες γλώσσες προγραµµατισµού, οι πιο συνήθεις αυτόµατες µεταβλητές είναι αυτές που είναι βοηθητικές για κάθε δραστηριοποίηση συνάρτησης: fun days2ms days = val hours = days * 24.0 val mutes = hours * 60.0 val seconds = mutes * 60.0 seconds * 1000.0 Εγγραφές δραστηριοποίησης 5 Εγγραφές δραστηριοποίησης 6 ραστηριοποίηση των µπλοκ Για µπλοκ που περιέχουν κώδικα, µιλάµε για Τη δραστηριοποίηση του µπλοκ Το χρόνο ζωής µιας εκτέλεσης του µπλοκ Μια µεταβλητή µπορεί να είναι ειδική για κάποια µόνο δραστηριοποίηση ενός συγκεκριµένου µπλοκ µιας συνάρτησης: fun fact n = if n = 0 then 1 else val fac = fact (n-1) n*fac Χρόνοι ζωής για τις µεταβλητές Οι περισσότερες προστακτικές γλώσσες έχουν κάποιο τρόπο να δηλώσουν ότι κάποιες µεταβλητές δένονται µε µια συγκεκριµένη θέση µνήµης για όλη τη διάρκεια εκτέλεσης του προγράµµατος Προφανής λύση δέσµευσης: στατική δέσµευση (ο φορτωτής δεσµεύει χώρο για αυτές τις µεταβλητές) t count = 0; t nextcount() { count = count + 1; return count; Εγγραφές δραστηριοποίησης 7 Εγγραφές δραστηριοποίησης 8

Η εµβέλεια και ο χρόνος ζωής διαφέρουν Στις περισσότερες µοντέρνες γλώσσες, οι µεταβλητές µε τοπική εµβέλεια έχουν χρόνο ζωής που συνήθως ταυτίζεται µε τη δραστηριοποίηση του µπλοκ Όµως, οι δύο έννοιες είναι διαφορετικές µεταξύ τους, όπως π.χ. µπορεί να γίνει στη C µέσω του προσδιοριστή static: t nextcount() { static t count; count = count + 1; return count; Άλλοι χρόνοι ζωής για τις µεταβλητές Οι γλώσσες αντικειµενοστρεφούς προγραµµατισµού χρησιµοποιούν µεταβλητές των οποίων ο χρόνος ζωής είναι συσχετισµένος µε το χρόνο ζωής των αντίστοιχων αντικειµένων Κάποιες γλώσσες έχουν µεταβλητές των οποίων οι τιµές είναι επίµονες (persistent): µε άλλα λόγια διατηρούν την τιµή τους για πολλαπλές εκτελέσεις του ίδιου προγράµµατος Εγγραφές δραστηριοποίησης 9 Εγγραφές δραστηριοποίησης 10 Εγγραφές δραστηριοποίησης Οι υλοποιήσεις των γλωσσών συνήθως συσκευάζουν όλες τις µεταβλητές που αναφέρονται σε µια συγκεκριµένη δραστηριοποίηση της συνάρτησης σε µια εγγραφή δραστηριοποίησης () Οι εγγραφές δραστηριοποίησης περιέχουν επίσης και όλα τα άλλα δεδοµένα που σχετίζονται µε δραστηριοποιήσεις, όπως: Τη διεύθυνση επιστροφής () της δραστηριοποίησης: δείχνει σε ποιο σηµείο του προγράµµατος πρέπει να πάει ο έλεγχος όταν επιστρέψει η συγκεκριµένη δραστηριοποίηση Ένα σύνδεσµο πρόσβασης (access lk) που δείχνει την εγγραφή δραστηριοποίησης της καλούσας συνάρτησης (callg function) Εγγραφές δραστηριοποίησης 11 Εγγραφές δραστηριοποίησης για µπλοκ Όταν εκτελείται ένα µπλοκ κώδικα, χρειαζόµαστε χώρο για τις τοπικές µεταβλητές του συγκεκριµένου µπλοκ Υπάρχουν διάφοροι τρόποι δέσµευσης χώρου: εσµεύουµε από πριν χώρο στην εγγραφή δραστηριοποίησης της περικλείουσας συνάρτησης Επεκτείνουµε την εγγραφή δραστηριοποίησης της συνάρτησης όταν η εκτέλεση εισέλθει στο µπλοκ (και τη µειώνουµε ξανά όταν εξέλθουµε του µπλοκ) εσµεύουµε κάποια ξεχωριστή εγγραφή δραστηριοποίησης για το µπλοκ Θα δούµε τον πρώτο από αυτούς τους τρόπους Εγγραφές δραστηριοποίησης 12

Στατική δέσµευση (static allocation) Η απλούστερη προσέγγιση: δέσµευσε µία εγγραφή δραστηριοποίησης για κάθε µια συνάρτηση, στατικά Οι παλιές διάλεκτοι της Fortran και της Cobol χρησιµοποιούσαν (µόνο) αυτό το σύστηµα δέσµευσης Αποτελεί απλό και πολύ γρήγορο τρόπο υλοποίησης Παράδειγµα FUNCTION AVG (ARR, N) DIMENSION ARR(N) SUM = 0.0 DO 100 I = 1, N SUM = SUM + ARR(I) 100 CONTINUE AVG = SUM / FLOAT(N) RETURN END N address ARR address I SUM AVG Εγγραφές δραστηριοποίησης 13 Εγγραφές δραστηριοποίησης 14 Μειονέκτηµα στατικής δέσµευσης Κάθε συνάρτηση έχει µία εγγραφή δραστηριοποίησης Μπορεί να υπάρξει µία µόνο δραστηριοποίηση συνάρτησης ζωντανή κάθε χρονική στιγµή Οι µοντέρνες γλώσσες (συµπεριλαµβανοµένων των µοντέρνων διαλέκτων της Cobol και της Fortran) δεν υπακούν σε αυτόν τον περιορισµό λόγω: Αναδροµής Πολυνηµατικότητας (multithreadg) Στοίβες από εγγραφές δραστηριοποίησης (1) Για την υποστήριξη της αναδροµής, πρέπει να δεσµεύσουµε µια νέα εγγραφή δραστηριοποίησης για κάθε δραστηριοποίηση της συνάρτησης υναµική δέσµευση: η εγγραφή δραστηριοποίησης δεσµεύεται όταν η συνάρτηση καλείται Σε πολλές γλώσσες, όπως η C, η εγγραφή αυτή αποδεσµεύεται όταν η συνάρτηση επιστρέψει Εγγραφές δραστηριοποίησης 15 Εγγραφές δραστηριοποίησης 16

Στοίβες από εγγραφές δραστηριοποίησης (2) Με άλλα λόγια, η εκτέλεση δηµιουργεί µια στοίβα από εγγραφές δραστηριοποίησης, όπου πλαίσια (frames) σπρώχνονται στη στοίβα κατά την κλήση των συναρτήσεων, και αποµακρύνονται από τη στοίβα κατά την επιστροφή τους Τρέχουσα εγγραφή δραστηριοποίησης Στη στατική δέσµευση η θέση κάθε εγγραφής δραστηριοποίησης καθορίζεται πριν την έναρξη εκτέλεσης του προγράµµατος Στη δυναµική δέσµευση η θέση της τρέχουσας εγγραφής δραστηριοποίησης ( ) δεν είναι γνωστή παρά µόνο κατά το χρόνο εκτέλεσης Κάθε συνάρτηση πρέπει να ξέρει πως θα βρει τη διεύθυνση της τρέχουσας εγγραφής δραστηριοποίησης Συχνά, ένας καταχωρητής της µηχανής δεσµεύεται για να περιέχει/κρατάει τη συγκεκριµένη τιµή Εγγραφές δραστηριοποίησης 17 Εγγραφές δραστηριοποίησης 18 Παράδειγµα σε C Αποτιµούµε την κλήση fact(3). Η εικόνα δείχνει τα περιεχόµενα της στοίβας ακριβώς πριν την αναδροµική κλήση της fact(2) που θα δηµιουργήσει τη δεύτερη εγγραφή δραστηριοποίησης. t fact(t n) { t result; if (n < 2) result = 1; else result = n * fact(n-1); return result; activation record n: 3 Τα περιεχόµενα της µνήµης ακριβώς πριν την τρίτη δραστηριοποίηση. t fact(t n) { t result; if (n < 2) result = 1; else result = n * fact(n-1); return result; n: 2 n: 3 result:? result:? result:? Εγγραφές δραστηριοποίησης 19 Εγγραφές δραστηριοποίησης 20

Τα περιεχόµενα της µνήµης ακριβώς πριν επιστρέψει η τρίτη δραστηριοποίηση. t fact(t n) { t result; if (n < 2) result = 1; else result = n * fact(n-1); return result; Η δεύτερη δραστηριοποίηση ακριβώς πριν επιστρέψει. t fact(t n) { t result; if (n < 2) result = 1; else result = n * fact(n-1); return result; n: 1 n: 2 n: 3 n: 1 n: 2 n: 3 result: 1 result:? result:? result: 1 result: 2 result:? Εγγραφές δραστηριοποίησης 21 Εγγραφές δραστηριοποίησης 22 Η πρώτη δραστηριοποίηση ακριβώς πριν επιστρέψει µε το αποτέλεσµα fact(3) = 6. n: 1 result: 1 t fact(t n) { t result; if (n < 2) result = 1; else result = n * fact(n-1); return result; n: 2 result: 2 n: 3 result: 6 Παράδειγµα σε ML Αποτιµούµε την κλήση halve [1,2,3,4] Η εικόνα δείχνει τα περιεχόµενα της µνήµης ακριβώς πριν την αναδροµική κλήση που δηµιουργεί τη δεύτερη δραστηριοποίηση. fun halve nil = (nil, nil) halve [a] = ([a], nil) halve (a::b::cs) = val (x, y) = halve cs (a::x, b::y) Οι εικόνες περιλαμβάνουν μια μικρή απλοποίηση όσον αφορά στο τι πράγματι αποθηκεύεται στη στοίβα activation record [1,2,3,4] a: 1 b: 2 cs: [3,4] x:? y:? value to return:? Εγγραφές δραστηριοποίησης 23 Εγγραφές δραστηριοποίησης 24

Τα περιεχόµενα της µνήµης ακριβώς πριν την τρίτη δραστηριοποίηση. [3,4] [1,2,3,4] [] Τα περιεχόµενα της µνήµης ακριβώς πριν επιστρέψει η τρίτη δραστηριοποίηση. [3,4] [1,2,3,4] a: 3 a: 1 value to return: ([], []) a: 3 a: 1 fun halve nil = (nil, nil) halve [a] = ([a], nil) halve (a::b::cs) = val (x, y) = halve cs (a::x, b::y) b: 4 cs: [] x:? y:? b: 2 cs: [3,4] x:? y:? value to return:? value to return:? fun halve nil = (nil, nil) halve [a] = ([a], nil) halve (a::b::cs) = val (x, y) = halve cs (a::x, b::y) b: 4 cs: [] x:? y:? b: 2 cs: [3,4] x:? y:? value to return:? value to return:? Εγγραφές δραστηριοποίησης 25 Εγγραφές δραστηριοποίησης 26 Η δεύτερη δραστηριοποίηση ακριβώς πριν επιστρέψει. Η πρώτη δραστηριοποίηση ακριβώς πριν επιστρέψει µε το αποτέλεσµα halve [1,2,3,4] = ([1,3],[2,4]) [] value to return: ([], []) fun halve nil = (nil, nil) halve [a] = ([a], nil) halve (a::b::cs) = val (x, y) = halve cs (a::x, b::y) [3,4] a: 3 b: 4 cs: [] x: [] y: [] value to return: ([3], [4]) [1,2,3,4] a: 1 b: 2 cs: [3,4] x:? y:? value to return:? Εγγραφές δραστηριοποίησης 27 [] value to return: ([], []) fun halve nil = (nil, nil) halve [a] = ([a], nil) halve (a::b::cs) = val (x, y) = halve cs (a::x, b::y) [3,4] a: 3 b: 4 cs: [] x: [] y: [] value to return: ([3], [4]) [1,2,3,4] a: 1 b: 2 cs: [3,4] x: [3] y: [4] value to return: ([1,3],[2,4]) Εγγραφές δραστηριοποίησης 28

Φωλιασµένες συναρτήσεις Χειρισµός φωλιασµένων συναρτήσεων Ότι είδαµε µέχρι στιγµής επαρκεί για πολλές γλώσσες, συµπεριλαµβανοµένης της C Αλλά όχι για γλώσσες που επιτρέπουν το ακόλουθο τρικ: Οι ορισµοί των συναρτήσεων µπορεί να είναι φωλιασµένες µέσα σε άλλους ορισµούς συναρτήσεων Οι εσωτερικές συναρτήσεις µπορεί να αναφέρονται σε τοπικές µεταβλητές των εξωτερικών συναρτήσεων (ακολουθώντας τους συνήθεις κανόνες εµβέλειας όταν υπάρχουν µπλοκ) ηλαδή δεν επαρκεί για γλώσσες όπως η ML, η Ada, η Pascal, κ.α. Εγγραφές δραστηριοποίησης 29 Εγγραφές δραστηριοποίησης 30 Παράδειγµα fun quicksort nil = nil quicksort (pivot::rest) = fun split(nil) = (nil,nil) split(x::xs) = val (below, above) = split(xs) if x < pivot then (x::below, above) else (below, x::above) val (below, above) = split(rest) quicksort below @ [pivot] @ quicksort above Το πρόβληµα Πώς µπορεί η δραστηριοποίηση της εσωτερικής συνάρτησης (split) να βρει την εγγραφή δραστηριοποίησης της εξωτερικής συνάρτησης (quicksort); Παρατηρήστε ότι δεν είναι απαραίτητα η προηγούµενη εγγραφή δραστηριοποίησης, επειδή η συνάρτηση που κάλεσε την εσωτερική συνάρτηση: µπορεί να είναι µια άλλη εσωτερική συνάρτηση, ή µπορεί να είναι µια αναδροµική κλήση συνάρτησης, όπως συµβαίνει µε τη split Εγγραφές δραστηριοποίησης 31 Εγγραφές δραστηριοποίησης 32

Σύνδεσµος φωλιάσµατος (nestg lk) a split activation another split activation... first caller: a quicksort activation Μια εσωτερική συνάρτηση πρέπει να είναι σε θέση να βρει τη διεύθυνση της πιο πρόσφατης δραστηριοποίησης της αµέσως εξωτερικής της συνάρτησης Μπορούµε να κρατήσουµε αυτό το σύνδεσµο στην εγγραφή δραστηριοποίησης split s variables: x, xs, etc. split s variables: x, xs, etc. quicksort s variables: pivot, rest, etc. Εγγραφές δραστηριοποίησης 33 Εγγραφές δραστηριοποίησης 34 a split activation another split activation... first caller: a quicksort activation nestg lk nestg lk nestg lk: null split s variables: x, xs, etc. split s variables: x, xs, etc. quicksort s variables: pivot, rest, etc. Πως παίρνουν τιµές οι σύνδεσµοι φωλιάσµατος; Εύκολα αν υπάρχει µόνο ένα επίπεδο φωλιάσµατος: Όταν καλείται µια εξωτερική συνάρτηση: θέτουµε την τιµή null στο σύνδεσµο Όταν καλείται µια εσωτερική συνάρτηση από µία εξωτερική: ο σύνδεσµος φωλιάσµατος παίρνει ως τιµή την εγγραφή δραστηριοποίησης της καλούσας συνάρτησης Όταν καλείται µια εσωτερική συνάρτηση από µία εσωτερική: ο σύνδεσµος φωλιάσµατος παίρνει ως τιµή το σύνδεσµο φωλιάσµατος της καλούσας συνάρτησης Πιο πολύπλοκα από τον παραπάνω τρόπο εάν υπάρχουν πολλαπλά επίπεδα φωλιάσµατος Εγγραφές δραστηριοποίησης 35 Εγγραφές δραστηριοποίησης 36

Πολλαπλά επίπεδα φωλιάσµατος function f1 variable v1 function f2 variable v2 function f3 variable v3 Οι αναφορές στο ίδιο επίπεδο (π.χ. της f1 στη v1, της f2 στη v2, ) χρησιµοποιούν την τρέχουσα εγγραφή δραστηριοποίησης Οι αναφορές σε ονόµατα που βρίσκονται σε κ επίπεδα φωλιάσµατος διατρέχουν κ συνδέσµους της αλυσίδας Εγγραφές δραστηριοποίησης 37 Άλλες λύσεις Το πρόβληµα είναι οι αναφορές από εσωτερικές συναρτήσεις σε µεταβλητές κάποιας εξωτερικής Λύσεις του προβλήµατος αποτελούν οι: Σύνδεσµοι φωλιάσµατος των εγγραφών δραστηριοποίησης (όπως δείξαµε στις προηγούµενες διαφάνειες) Displays: οι σύνδεσµοι φωλιάσµατος δε βρίσκονται στις εγγραφές δραστηριοποίησης, αλλά συλλέγονται σε ένα στατικό πίνακα Λάµδα άρση (Lambda liftg): οι αναφορές του προγράµµατος αντικαθίστανται από αναφορές σε νέες, κρυφές παραµέτρους Εγγραφές δραστηριοποίησης 38 Συναρτήσεις ως παράµετροι Συναρτήσεις ως παράµετροι Όταν περνάµε µια συνάρτηση ως παράµετρο, τι ακριβώς είναι αυτό που πρέπει να µεταβιβαστεί; Ο κώδικας της συνάρτησης πρέπει να είναι µέρος αυτού που περνιέται: είτε σε µορφή πηγαίου κώδικα, είτε σε µορφή µεταγλωττισµένου κώδικα, δείκτη σε κώδικα, ή µέσω υλοποίησης κάποιας άλλης µορφής Κάποιες γλώσσες, χρειάζονται κάτι περισσότερο Εγγραφές δραστηριοποίησης 39 Εγγραφές δραστηριοποίησης 40

Παράδειγµα fun addxtoall (x,thelist) = fun addx y = y + x; map addx thelist Η παραπάνω συνάρτηση προσθέτει την τιµή του x σε κάθε στοιχείο της λίστας thelist Η addxtoall καλεί τη map, η map καλεί τη addx, και η addx αναφέρεται στη µεταβλητή x στην εγγραφή δραστηριοποίησης της συνάρτησης addxtoall Εγγραφές δραστηριοποίησης 41 Σύνδεσµοι φωλιάσµατος ξανά Όταν η map καλέσει την addx, τι σύνδεσµος φωλιάσµατος θα δοθεί στην addx; Όχι η εγγραφή δραστηριοποίησης της map διότι η addx δεν είναι φωλιασµένη µέσα στη map Όχι ο σύνδεσµος φωλιάσµατος της map διότι η map δεν είναι κάπου φωλιασµένη Για να δουλέψει η συνάρτηση addxtoall, η παράµετρος που περνά η addx στη map πρέπει να περιλαµβάνει το σύνδεσµο φωλιάσµατος που θα χρησιµοποιηθεί όταν κληθεί η addx fun addxtoall (x,thelist) = fun addx y = y + x; map addx thelist Εγγραφές δραστηριοποίησης 42 Όχι µόνο για τις παραµέτρους Πολλές γλώσσες επιτρέπουν σε συναρτήσεις να περαστούν ως παράµετροι Οι συναρτησιακές γλώσσες επιτρέπουν περισσότερα είδη λειτουργιών σε συναρτήσεις-τιµές: Πέρασµα συναρτήσεων ως παραµέτρους Επιστροφή συναρτήσεων από συναρτήσεις Κατασκευή συναρτήσεων από εκφράσεις Οι συναρτήσεις-τιµές περιλαµβάνουν τόσο τον κώδικα που θα εκτελεστεί όσο και το σύνδεσµο φωλιάσµατος που θα χρησιµοποιηθεί όταν κληθεί η συνάρτηση Εγγραφές δραστηριοποίησης 43 Παράδειγµα activation record nestg lk x thelist addx fun addxtoall (x,thelist) = fun addx y = y + x; map addx thelist y => y + x Τα περιεχόµενα της µνήµης ακριβώς πριν την κλήση της map. Η µεταβλητή addx είναι δεµένη µε µια συνάρτηση-τιµή η οποία περιλαµβάνει κώδικα και ένα σύνδεσµο φωλιάσµατος. Εγγραφές δραστηριοποίησης 44

Μια ακόµα περιπλοκή Μακρόβιες εγγραφές δραστηριοποίησης Τι συµβαίνει εάν µια συνάρτηση-τιµή χρησιµοποιείται από τη συνάρτηση που τη δηµιούργησε µετά την επιστροφή της συνάρτησης-δηµιουργού; val test = val f = funtoaddx 3; f 5 fun funtoaddx x = fun addx y = y + x; addx Εγγραφές δραστηριοποίησης 45 Εγγραφές δραστηριοποίησης 46 val test = val f = funtoaddx 3; f 5 fun funtoaddx x = fun addx y = addx y + x; activation record x: 3 nestg lk: null addx nestg lk: null f:? val test = val f = funtoaddx 3; f 5 fun funtoaddx x = fun addx y = addx y + x; x: 3 nestg lk: null addx activation record nestg lk: null f Τα περιεχόµενα της µνήµης ακριβώς πριν η funtoaddx επιστρέψει. y => y + x Μετά την επιστροφή της funtoaddx, η f δεσµεύεται µε τη νέα συνάρτηση-τιµή. y => y + x Εγγραφές δραστηριοποίησης 47 Εγγραφές δραστηριοποίησης 48

Το πρόβληµα Όταν η test καλέσει την f, η συνάρτηση θα χρησιµοποιήσει το σύνδεσµο φωλιάσµατος για να προσπελάσει το x Με άλλα λόγια, θα χρησιµοποιήσει ένα δείκτη σε µια εγγραφή δραστηριοποίησης για µια δραστηριοποίηση που έχει τερµατίσει Αυτό θα αποτύχει εάν η υλοποίηση της γλώσσας αποδεσµεύσει την εγγραφή δραστηριοποίησης τη στιγµή επιστροφής της συνάρτησης Εγγραφές δραστηριοποίησης 49 Η λύση του προβλήµατος Στην ML, και σε άλλες γλώσσες όπου υπάρχει η ίδια περιπλοκή, οι εγγραφές δραστηριοποίησης δε µπορούν πάντα να δεσµευθούν και να αποδεσµευθούν ακολουθώντας δοµή στοίβας Αυτό διότι ακόµα και όταν µια συνάρτηση επιστρέψει, µπορεί να υπάρχουν σύνδεσµοι στην εγγραφή δραστηριοποίησής της Οι εγγραφές δε µπορεί να αποδεσµευθούν παρά µόνο όταν καταστούν απροσπέλαστες Αυτό συνήθως συµβαίνει µε αυτόµατη διαχείριση µνήµης ή αλλιώς µε συλλογή σκουπιδιών (garbage collection) Εγγραφές δραστηριοποίησης 50 Συµπερασµατικά Όσο πιο σοφιστικέ είναι µια γλώσσα, τόσο πιο δύσκολο είναι να δεθούν οι µεταβλητές µε θέσεις µνήµης Στατική δέσµευση: δουλεύει σε γλώσσες που επιτρέπουν το πολύ µια δραστηριοποίηση κάθε συνάρτησης κάθε στιγµή (όπως σε πρώιµες διαλέκτους της Fortran και της Cobol) υναµική δέσµευση σε στοίβα: δουλεύει σε γλώσσες που δεν επιτρέπουν φωλιασµένες συναρτήσεις (όπως η C) Σύνδεσµοι φωλιάσµατος (ή κάτι αντίστοιχο): επιβάλλεται σε γλώσσες που επιτρέπουν φωλιασµένες συναρτήσεις (όπως η ML, η Ada και η Pascal). Οι συναρτήσεις τιµές πρέπει να περιλαµβάνουν τόσο κώδικα όσο και σύνδεσµο φωλιάσµατος Κάποιες γλώσσες (όπως η ML) επιτρέπουν αναφορές σε εγγραφές δραστηριοποιήσεων συναρτήσεων που έχουν περατώσει την εκτέλεσή τους. Κατά συνέπεια, οι εγγραφές δραστηριοποίησης δε µπορούν να αποδεσµευθούν αµέσως µετά την επιστροφή τους και η χρήση στοίβας δεν επαρκεί. Εγγραφές δραστηριοποίησης 51