Πέμπτη 14 Ιανουαρίου 2016

Αναθεώρηση 137 - Περάσματα Συναρτήσεων

Βελτίωση στη ταχύτητα.
Δείτε το παρακάτω παράδειγμα. Περνάω μια συνάρτηση με τρεις τρόπους σε ένα τμήμα Η συνάρτηση ανήκει σε μια κλάση και από αυτή έχω φτιάξει μια ανώνυμη ομάδα (αντικείμενο). Το For A(0)  { } μπλοκ ανοίγει την  ομάδα.
Καλώ το πρώτο τμήμα, το Check και περνάω την GG() συνάρτηση. Στο Check καλώ τη συνάρτηση με το 100, και τυπώνεται το αποτέλεσμα .Α*100 δηλαδή το 100. Κάνω την Α 20, και αυτή αλλάζει στην ανοικτή ομάδα...έξω από το τμήμα!

Καλώ το δεύτερο τμήμα, το Check1 αλλά εδώ έχω κάνει το εξής. Έχω συνδέσει το This (την ανοικτή ομάδα) σε ένα όνομα...το Β. Τώρα μπορώ να φτιάξω μια οκνηρή αποτίμηση. Δηλαδή το B.GG(BB*100) δεν εκτελείται άμεσα αλλά φτιάχνει μια ανώνυμη συνάρτηση και εκτελείται εκεί που θα παραδοθεί (όσες φορές θέλουμε). Αυτήν περνάω στην Check1 και εκεί εκτελείται και μας δίνει το 20000 και επίσης αυξάνει το Α σε 30. Δείτε όμως ότι η ΒΒ είναι μεταβλητή του τμήματος απ΄όπου καλέσαμε το Check1. Στην ουσία η συνάρτηση που δίνουμε είναι τμήμα του τμήματος που κάλεσε το Check1.

Καλώ το τρίτο τμήμα, το Check2 και εδώ δίνω μια συνάρτηση μόνο την &.GG() χωρίς να δώσω τιμές αλλά με παραγωγή αλφαριθμητικού. To Check2 διαβάζει το αλφαριθμητικό και το χρησιμοποιεί στην Function() με παράμετρο το 50.

Ξανά καλώ το Check με το Lazy$(&.GG()) το οποίο είναι ίδιο με αυτό &.GG() και τα δυο δηλαδή δίνουν το ίδιο πράγμα, ένα αλφαριθμητικό που θα γίνει συνάρτηση.


Αν το δει κανείς το θέμα αυτό...δίνουμε συνάρτηση σε ένα τμήμα και αυτό μπορεί να τη καλέσει όσες φορές θέλει, και να αλλάζει κάτι εκεί από όπου πήραμε τη συνάρτηση.

Ενώ λοιπόν όταν καλούμε ένα τμήμα μπορούμε να περάσουμε τιμές ή αναφορές σε μεταβλητές, ή αναφορές σε συναρτήσεις (οι οποίες όπως φάνηκε και εδώ είναι αντιγραφή του κώδικα της συνάρτησης), λογικά θα έπρεπε να μην γνωρίζαμε πόσες φορές χρησιμοποιήθηκε αυτό που δώσαμε. Όμως δείτε πως κάθε φορά η συνάρτηση αυξάνει κατά 10 την Α στο αντικείμενο, στο a(0). Αυτό σημαίνει ότι δεν περνάμε απλά μια συνάρτηση αλλά και το περιβάλλον μαζί.

Η συνάρτηση ModulePart είναι τμήμα του τμήματος το οποίο το περνάμε στο Check1. Εκεί εκτελείται μεταφέροντας το περιβάλλον του αρχικού τμήματος. Δείτε πως καλούμε την Check1 και πάλι την καλούμε μέσα από την ModulePart.
Αν αφαιρέσουμε το Function ModulePart { } και την εντολή μετά, και αφήσουμε το περιεχόμενο τότε θα έχουμε ακριβώς το ίδιο αποτέλεσμα!



Class AAA {
      A=10
      FUNCTION GG {
            Read num
            Print .A*num
            .A+=10
      }
}
Module Check {
      Read &B()
      Call B(100)
}
Module Check1 {
      Read A$
      AA=Function(A$)
}
Module Check2 {
      Read A$
      AA=Function(A$, 50)
}


dim a(1)
a(0)=AAA()
BB=10


Function ModulePart {
      For a(0) {
            Check &.GG() ' 1000
            Link This to B \\ we give a temporary name to A(0)
            Check1 Lazy$(B.GG(BB*100)) ' 20000
            Check2 Lazy$(&.GG()) ' 1500
            Check Lazy$(&.GG()) ' 4000
      }
}
Check1 Lazy$(&.ModulePart())

Print a(0).A ' 50

Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου

You can feel free to write any suggestion, or idea on the subject.