Κυριακή, 18 Μαρτίου 2018

Έκδοση 9.2 (Αναθεώρηση 1)

Ολοκληρώθηκε η έκδοση 9.2. Πιθανές αναθεωρήσεις θα γίνουν σε περίπτωση που βρεθούν λάθη. Έχει γίνει αρκετός έλεγχος, και διορθώσεις, ώστε να υπάρχει συμβατότητα με τις παλαιότερες εκδόσεις.

Αν και η έκδοση 9.1 μπήκε με την υποστήριξη διάφορων τύπων μεταβλητών, όπως Decimal, Currency, Double, Single, Long, Boolean, ως προς τις σταθερές τιμές πχ το 10000@ είναι Decimal (ή όπως τον λέμε στα ελληνικά στη Μ2000, Αριθμός), για τις μεταβλητές δεν είχε ξεκαθαριστεί ως προς το πότε θα γίνονται μετατροπές τύπων. Γίνονται μετατροπές αυτόματα όταν πχ πολλαπλασιάσουμε έναν Currency (Λογιστικό το λέμε στη Μ2000) με έναν Double θα πάρουμε Double. Το ζήτημα είναι τι γίνεται κατά το πέρασμα με τιμή (by value), και τι γίνεται στο πέρασμα με αναφορά (by reference) που υποστηρίζει η γλώσσα. Αν μια εκχώρηση τιμής αλλάξει το τύπο στην μεταβλητή που προκύπτει από αναφορά τότε αυτό θα είναι άμεσο και στην αναφερόμενη. Αυτό δεν το θέλουμε! Επιπλέον όταν περνάμε με τιμή ενδέχεται να περάσουμε απλά μια έκφραση αντί για μια μεταβλητή (που και αυτή σαν έκφραση θα την δει ο διερμηνευτής) και αυτή να βγάλει έναν τύπο πχ Μακρύς (Long). Αυτό που θέλουμε είναι να μπορούμε να πάρουμε στην παράμετρο την τιμή με το τύπο που θέλουμε, δηλαδή να γίνει μετατροπή κατά τη κλήση.

Στην πρότερη κατάσταση η γλώσσα είχε στο βασικό της σύστημα επεξεργασίας αριθμητικών και λογικών εκφράσεων σαν βάση τον διπλό ή Double (ή πραγματικός σε άλλες γλώσσες, όπως η ΓΛΩΣΣΑ του σχολείου). Μπορούσε να αποθηκεύσει σε Μακρύ ή Long, αλλά οι όποιες πράξεις γίνονταν με Διπλούς. Αυτός ο τύπος (32bit ακέραιος με πρόσημο) είναι χρήσιμος κατά τις κλήσεις εξωτερικών συναρτήσεων σε βιβλιοθήκες "dll". Επίσης για τους λογικούς ή Boolean, απλά χρησιμοποιούσε το 0 και -1, δηλαδή αρθμούς, και έτσι οποιαδήποτε μεταβλητή μπορούσε να παίξει τον ρόλο του Λογικού. Επιγραμματικά δυο ακόμα παρατηρήσεις ως προς το πως ήταν η γλώσσα πριν την 9.2 (1) έκδοση. Οι μεταβλητές (και οι πίνακες) με το % έπαιρναν διπλό εσωτερικά αλλά στις εκχωρήσεις έκαναν αυτόματη αποκοπή δεκαδικών με στρογγυλοποίηση στο μισό. Τα αλφαριθμητικά πάντα ξεχωρίζουν στην γλώσσα γιατί έχουν το $ στο τέλος του ονόματος. Έγινε αναφορά εδώ για τις απλές μεταβλητές (αριθμοί και γράμματα). Περί αντικειμένων θα τα δούμε σε άλλη ανάρτηση, γιατί έχουμε προσθήκες, προχωρημένες, όπως στις ομάδες τελεστής μοναδιαίος, και εκτέλεση εκφράσεων με ομάδες που δεν επιστρέφουν τιμή αλλά κάνουν πράξεις μεταξύ τους και επιστρέφουν αποτέλεσμα ομάδα. Οι ομάδες που επιστρέφουν ιιμή, απλή, λειτουργούν σαν μεταβλητές, με την διαφορά ότι μπορούν να έχουν τμήματα, συναρτήσεις, ιδιότητες.

Για να δούμε τις προσθήκες θα ξεκινήσουμε από το πώς ορίζουμε μια συνάρτηση (οι συναρτήσεις ορίζονται μέσα σε τμήματα, σε συναρτήσεις, σε ομάδες με τον ίδιο τρόπο)

 Στο ξεκίνημα της συγγραφής της γλώσσας οι συναρτήσεις γραφόντουσαν έτσι απλά. Η λέξη Συνάρτηση (Function), μετά ένα όνομα που μπορούσε να είχε τόνους και μπορούσε να κληθεί και χωρίς τόνους, ή και με λάθος τόνους, με μικρά ή μεγάλα, όπως θέλουμε, δεν έχει διαφορά. Και μετά το μπλόκ εντολών, ή σώμα της συνάρτησης. Κάπου μέσα στην συνάρτηση η επιστροφή τιμή γίνεται με ένα = χωρίς κάτι αριστερά, δηλαδή αναφέρεται στη συνάρτηση. Παρατηρήστε ότι έξω από το σώμα δεν φαίνονται οι τυχόν παράμετροι. Οποιαδήποτε συνάρτηση μπορούσε (και μπορεί) να πάρει οπιοδήποτε αριθμό παραμέτρων, και τύπων. Κάθε συνάρτηση έχει έναν σωρό τιμών, και αυτός "γενννιέται" κατά την κλήση. Εκεί μπαίνουν όλες οι τιμές που θέλουμε να δώσουμε. Για να τις διαβάσουμε αρκή η χρήση της Διάβασε.


Συνάρτηση Ένα {
      =100
}

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

Συνάρτηση ΚυβικήΡίζα {
      =Αριθμός^(1/3)
}
Τύπωσε ΚυβικήΡίζα(8)

 ή καλύτερα, όπου διπλασιάζουμε τη κορυφή του σωρού, και τραβάμε δυο φορές τον αριθμό, μια για την Σημ() ή Sgn() που γυρίζει -1 για αρνητικό πρόσημο, 0 για μηδέν, και 1 για θετικό πρόσημο, και η άλλη, η Απολ() ή Abs() είναι η απόλυτη τιμή δηλαδή αφαιρεί το πρόσημο, γυρνάει τον αριθμό σε θετικό. Δεν χρησιμοποιήσαμε καμία μεταβλητή, και περιμένει η συνάρτηση έναν οποιοδήποτε αριθμό. Αν δώσουμε παραπάνω ορίσματα θα γραφτούν αρχικά στο σωρό της συνάρτησης αλλά στην επιστροφή από τη συνάρτηση θα διαγραφούν μαζί με το σωρό τιμών. Η επιστροφή εδώ ΔΕΝ γίνεται με την απόδοση τιμής αλλά στο τέλος του μπλοκ εντολών. Αυτό σημαίνει ότι μπορούμε να δώσουμε τιμή επιστροφής πάνω από μια φορά αλλά η τελευταία θα μείνει για επιστροφή. Σε κάποιες περιπτώσεις όπως στις λάμδα συναρτήσεις μας βολεύει να γυρνάμε την τιμή μιας μεταβλητής και μετά να την αυξάνουμε (η μεταβλητή αυτή ανήκει στο κλείσιμο, ή λέγεται και κλείσιμο, τέτοιες προχωρημένες συναρτήσεις έχει η Μ2000)

Συνάρτηση ΚυβικήΡίζα {
      Πάνω  ' διπλασιάζει την κορυφή του σωρού
      =Σημ(Αριθμός)*Απολ(Αριθμός)^(1/3)
}
Ν=ΚυβικήΡίζα(-8)
Τύπωσε Ν**3 ' και το ** σημαίνει δύναμη, όπως το ^

Δείτε ότι μια συνάρτηση μπορεί να έχει όρισμα πάλι μια κλήση στην ίδια συνάρτηση, Θα λέμε κλήση σε συνάρτηση όταν αυτή βρίσκεται σε έκφραση, η και εκτός όπως θα δούμε. Με μπλε γράμματα είναι τα γνωστά ονόματα (έχουν αντιγραφεί από τον ενσωματωμένο διορθωτή, και αυτός στην αντιγραφή δίνει και τα χρώματα, οπότε εδώ στο Blog αντιγράφονται άμεσα με χρώμα). Δείτε ότι απαιτήθηκε η στρογγυλοποίηση!

Ν=Στρογγ(ΚυβικήΡίζα(ΚυβικήΡίζα(512))^3^3)
Τύπωσε Ν, Τύπος$(Ν) ' δίνει 512 και Double

 Με χρήση μεταβλητής, δηλαδή θα πάρουμε την τιμή του σωρού σε μια μεταβλητή και θα την δώσουμε δυο φορές στην έκφραση στην εντολή επιστροφής τιμής:
Συνάρτηση ΚυβικήΡίζα {
       Διάβασε χ
      =Σημ(χ)*Απολ(χ)^(1/3)
}

Στις παλιές εκδόσεις το χ ξέραμε ότι είναι Διπλός και ότι επιστρέφεται θα είναι διπλός. Μετατροπές γίνονταν μόνο για τους Ακέραιους (που εσωτερικά ήταν διπλοί, άρα μόνο στρογγυλοποίηση με μηδέν δεκαδικά), και για τους τύπου Μακρύ, αλλά πάντα κατά την εκχώρηση σε αυτού του τύπου μεταβλητές. Η μόνη τότε αλλαγή ήταν στο όνομα της συνάρτησης να φαίνονται οι παράμετροι, αλλά πάλι θα μπορούσαμε να διαβάσουμε επιπλέον τιμές.

Συνάρτηση ΚυβικήΡίζα (χ) {
      =Σημ(χ)*Απολ(χ)^(1/3)
}
ή πιο πρόσφατο (ισχύουν δε όλα τα προηγούμενα)
Συνάρτηση ΚυβικήΡίζα(χ) {
      =Σημ(χ)*Απολ(χ)^(1/3)
}

και επειδή αυτή είναι συνάρτηση μιας γραμμής μπορεί να δημιουργηθεί με την εντολή Κάνε (Def) :

Κάνε ΚυβικήΡίζα(χ)=Σημ(χ)*Απολ(χ)^(1/3)

Στην νέα έκδοση λοιπόν μπήκε ο προσδιορισμός τύπου.Η εντολή Κάνε εκτός από συναρτήσεις κάνει και μεταβλητές (παίρνει και λίστα μεταβλητών και με αρχικές τιμές με το =και έναν αριθμό και όχι αριθμητική παράσταση). Η διαφορά της Κάνε με τις μεταβλητές σε σχέση με άλλες παρόμοιες εντολές είναι ότι επιστρέφει λάθος αν οι μεταβλητές ήδη υπάρχουν. Μια παραλλαγή της, η Κάνε Τοπικά και μετά η λίστα με τις μεταβλητές δημιουργεί νέες ακόμα και αν υπάρχουν (το οποίο θέλουμε σε μια ρουτίνα, επειδή μέσα στη ρουτίνα βλέπουμε οτιδήποτε υπάρχει εντός τμήματος, αλλά όχι εκτός). Εδώ λοιπόν καθορίζουμε και το είδος του ορίσματος. Στην νέα έκδοση, η χ αν δεν καθορίζεται παίρνει τον τύπο από το τύπο της τιμής που διαβάζει ο διερμηνευτής, από το σωρό τιμών. Σε κάθε περίπτωση όταν μια μεταβλητή πάρει τύπο, δεν αλλάζει (τουλάχιστον εύκολα). Μεταβλητές που φτιάχνουμε και χειριζόμαστε με τον διερμηνευτής εντολών γραμμής μπορούν να αλλάξουν (εκεί που δίνουμε εντολές πριν ξεκινήσουμε ένα τμήμα, πάντα μέσα στο περιβάλλον της γλώσσας, δηλαδή εκτός προγραμμάτων, και οι οποίες φαίνονται ως γενικές για τα προγράμματα).

Στο παράδειγμα, η ύψωση σε δύναμη ενώς Decimal (Αρθμός, έχει 29 ψηφία) δίνει πάντα διπλό. Η συνάρτηση αν και χρησιμοποίησε τον Decimal, γύρισε διπλό. Όμως η συνάρτηση έχει καλύτερη ακρίβεια υπολογισμού, και δεν χρειάζεται η στρογγυλοποίηση. Η Ν παραμένει ως Decimal, παρά την εκχώρηση Double από την ΚυβικήΡίζα(). Η Μ δείνχει ότι η ύψωση Decimal σε δύναμη δίνει Διπλό, ή Double.  Το ^3^3 είναι ισοδύναμο με αυτό ^9. Πράγματι 2^9 δίνει 512.

Κάνε Ν ως Αριθμός
Κάνε ΚυβικήΡίζα(χ ως αριθμός)=Σημ(χ)*Απολ(χ)^(1/3)
Ν=ΚυβικήΡίζα(8)
Τύπωσε Ν**3, Τύπος$(Ν) ' και το ** σημαίνει δύναμη, όπως το ^
Ν=ΚυβικήΡίζα(ΚυβικήΡίζα(512))^3^3
Τύπωσε Ν, Τύπος$(Ν) ' δίνει 512 και Decimal (Αριθμός)
Μ=Ν**3
Τύπωσε Τύπος$(Μ) ' Double

Όπως και αυτό (προσθήκη στο προηγούμενο), δείχνει ότι αν φτιάχναμε νέα μεταβλητή με το αποτέλεσμα της συνάρτησης θα γίνονταν Διπλός ή Double.
Ζ=ΚυβικήΡίζα(27)
Τύπωσε Τύπος$(Ζ)

Το κύριο λοιπόν νέο στην 9.2 είναι ότι πήρε τους πολλούς τύπους που μπήκαν στην 9.1 και τώρα κάθε μεταβλητή εντός τμήματος κατά την διάρκεια εκτέλεσης θα έχει τον ίδιο τύπο, ενώ μπορεί να έχει καθοριστεί εντός του τμήματος (ή συνάρτησης), ή να καθοριστεί απ΄έξω (αν δεν ορίσουμε), αλλά και πάλι η μεταβλητή που θα διαβάσει τον τύπο θα παραμείνει σε αυτόν μέχρι να διαγραφεί με το πέρας εκτέλεσης του τμήματος αυτού.

Επιπλέον ενώ υπήρχε η Διάβασε ? η οποία δέχονταν τιμές προεραιτικά δηλαδή, κάποιες μεταβλητές να κρατούσαν την τιμή τους αν δεν δίναμε τιμή (πχ δίναμε συνεχόμενα κόμμα  κατά τη κλήση ή δίναμε το ? που σημαίνει αδιάφορο, πάντα κατά την κλήση), τώρα μια οποιαδήποτε Διάβασε αν έχει το = και έναν αριθμό ή σε αλφαριθμητικά ένα αλφαριθμητικό ως εναλλακτική τιμή τότε, αν οι μεταβλητές δεν υπάρχουν και βρεθεί στο σωρό τιμών αντί για μια τιμή ένας δείκτης που λέει "προαιρετικό" (optional), τότε θα πάρουν αυτές τις αρχικές τιμές.

Ο χαρακτήρας @ όταν ακολουθεί αριθμό σήμαίνει ότι ο αριθμός διαβάζεται ως Decimal (ή Αριθμός). Όταν ακολουθεί # σημαίνει ότι διαβάζεται ως Currency (Λογιστικό το λέμε στη Μ2000), Το σύμβολο ~ είναι  για τους απλούς, και το & για τους τύπου Μακρύς. Οι διπλοί δεν έχουν σύμβολο εδικό. Δείτε ότι ο ψ δεν δηλώθηκε ως τύπος με την Ως <Τύπος>, θα πάρει ότι του δώσουμε, και αν δεν του δώσουμε θα πάρει την δική του "επιλογή", και το τύπο της.


Κάνε ΝιΡίζα(χ ως αριθμός, ψ=2)=Σημ(χ)*Απολ(χ)^(1/ψ)
Ν%=ΝιΡίζα(2) ' χρήση Ν ως ακέραιος
Τύπωσε Ν%**2, Τύπος$(Ν%)
Ν%=ΝιΡίζα(ΝιΡίζα(512, 5), 2)^5^2
Τύπωσε Ν%, Τύπος$(Ν%) ' δίνει 512 και Double
\\ όλες οι μεταβλητές σε % είναι ακέραιες με οποιοδήποτε τύπο:
Μ%=1232133.12312322133321337@*10000000000000000000@
\\ δίνει τεράστιο νούμερο!
Τύπωσε Μ%, Τύπος$(Μ%) 'Decimal
Μ%+=99
Τύπωσε Μ%, Τύπος$(Μ%) 'Decimal


Συναρτήσεις μπορούμε να καλέσουμε και χωρίς να είναι σε έκφραση, και μπορούμε να μην έχουμε επιστροφή τιμής. Εδώ δίνουμε το Άδειασε στην αρχή για να καθαρίσουμε τον τρέχον σωρό τιμών ώστε με σιγουριά νε μην περάσουμε κάποια άλλη τιμή, η δεςμε κατά την κλήση, και να πάρει την προαιρετική (πάντα υπό τον έλεγχό μας, ως προγραμματιστές).

Άδειασε
Συνάρτηση δεςμε (κ ως Λογιστικό=2){
      Τύπωσε τύπος$(κ), κ
}
κάλεσε δεςμε(50&)
κάλεσε δεςμε()


Η διαφορά με την συνάρτηση στην έκφραση είναι ότι εδώ ο σωρός τιμών δίνεται κατά κλήση, και είναι ενιαίος. Δηλαδή αν θέλουμε αφήνουμε τίμες στο σωρό τιμών, θα τις παραλάβει αυτός που κάλεσε! Επιπλέον να σημειωθεί ότι έξω από μια συνάρτηση για την συνάρτηση είναι σαν το μακρινό σύμπαν, υπάρχει αλλά δεν μορούμε να το αγγίξουμε! Έτσι και η συνάρτηση δεν βλέπει έξω από το σώμα της! Τουλάχιστον με κανονικές κλήσεις, και όταν δεν είναι μέλος ομάδας.

Κάνε ΝιΡίζα(χ ως μακρύς, ψ ως μακρύς=2)=Σημ(χ)*Τιμή(Στρογγ(Απολ(χ)^(1/ψ),5)->μακρύς)
Ρ=ΝιΡίζα(2131233,8) ' χρήση της συνάρτησης να επιστρέφει Μακρύ  (LONG)
Τύπωσε Ρ**5, Τύπος$(Ρ)


Δείτε λοιπόν πως χρησιμοποιούμε το πέρασμα με αναφορά, με το χαρακτήρα &. Όλα τα αποτελέσματα είναι Decimal

Συνάρτηση ΑύξησεΜετά(&Ν) {
      =Ν
      Ν++
}
Κάνε Αριθμό Κ=2@, Λ, Μ
Τύπωσε Τύπος$(Κ), Τύπος$(Λ), Τύπος$(Μ)
Μ=ΑύξησεΜετά(&Κ)
Λ=ΑύξησεΜετά(&Κ)
Τύπωσε Τύπος$(Κ), Τύπος$(Λ), Τύπος$(Μ)
Τύπωσε Κ, Λ, Μ ' 4, 3, 2


Και τελευταίο για την ανάρτηση. Αλλάζουμε το τύπο της ΑύξησεΜετά(),  ώστε αν δοθεί αναφορά από αλλο τύπο να βγει λάθος,.

Συνάρτηση ΑύξησεΜετά(&Ν ως Λογιστικό) {
      =Ν
      Ν++
}
Κάνε Λογιστικό Κ=2#, Λ, Μ
Τύπωσε Τύπος$(Κ), Τύπος$(Λ), Τύπος$(Μ)
Μ=ΑύξησεΜετά(&Κ)
Λ=ΑύξησεΜετά(&Κ)
Τύπωσε Τύπος$(Κ), Τύπος$(Λ), Τύπος$(Μ)
Τύπωσε Κ, Λ, Μ ' 4, 3, 2

Ζ=10&
Δες οκ {
     Τύπωσε ΑύξησεΜετά(&Ζ)
}
Αν όχι οκ ή λάθος Τότε Τύπωσε Λάθος$
Τύπωσε Ζ ' δεν άλλαξε, γιατί βγήκε λάθος


ΓΚ