Παρασκευή 16 Μαΐου 2014

Ημερολόγιο Προγραμματισμού

Έφτασα στην έκδοση 6.4 της Μ2000. Ουσιαστικά στοχεύω στην 7η έκδοση με την ενσωμάτωση κλάσεων και αντικειμένων.
Εκτός από την προεργασία που έχω κάνει για την τελική έκδοση έκανα μερικές προσθήκες:

Περιβάλλον Μ2000

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

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

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

Επίσης μπορεί κανείς να κάνει ελαχιστοποίηση (ενώ παλιά δεν γίνονταν) και μπορεί αυτή να γίνεται και με επιλογή από το πρόγραμμα. Για το σκοπό αυτό η εντολή ΤΙΤΛΟΣ αλφαριθμητικό μπορεί να πάρει και άλλη μια παράμετρο, όπου με 0 γίνεται ελαχιστοποίηση και με 1 γίνεται επαναφορά. Μπορούν να γίνουν και από τη γραμμή έναρξης όπου εμφανίζεται ο τίτλος. Αν δεν δώσουμε αλφαριθμητικό τότε φεύγει ο τίτλος από την γραμμή έναρξης και δεν μπορούμε να κάνουμε ελαχιστοποίηση (και κλείσιμο γίνεται από εκεί ή προγραμματιστικά από τη γλώσσα).

Επίσης μπορεί κανείς να μειώσει την ένταση των χρωμάτων με μια άμεση εντολή ΕΠΙΦΑΝΕΙΑ 100, όπου η ΕΠΙΦΑΝΕΙΑ είναι ένα νέο επίπεδο πίσω από το  ΠΕΡΙΘΩΡΙΟ και έχει πάντα το μέγεθος της οθόνης. Στην ΕΠΙΦΑΝΕΙΑ μπορούμε να αντιγράψουμε μια εικόνα, ή ακόμα μπορούμε να την κρύψουμε ενώ έχουμε δώσει αδιαφάνεια στο ΠΕΡΙΘΩΡΙΟ...(και όλα πάνω σε αυτό ΟΘΟΝΗ και κάθε ΕΠΙΠΕΔΟ). Η επιφάνεια ξαναέρχεται με την εντολή ΕΠΙΦΑΝΕΙΑ και με ένα ή δυο αριθμούς, ο πρώτος αν είναι 255 σημαίνει 100% αδιάφανα όλα τα χρώματα, ενώ με 0 σημαίνει 100% διάφανα όλα τα χρώματα, και το δεύτερο νούμερο λέει ποιο χρώμα θα είναι πραγματικά 100% διάφανο, χωρίς να το αλλάζει το πρώτο νούμερο! Η παλιά εντολή ΕΠΙΦΑΝΕΙΑ χωρίς όρισμα, κάνει ότι έκανε και στις άλλες εκδόσεις, γεμίζει το περιθώριο με την εικόνα της επιφάνειας εργασίας.

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

Έγινε επέκταση της εντολής ΑΝΑΝΕΩΣΗ με ένα όρισμα ώστε αν θέλουμε να αλλάζουμε τον ρυθμό ανανέωσης της οθόνης. Μια ολίσθηση προκαλεί ανανέωση όπως και να έχει το πράγμα.

Πίνακες
Πρόσθεσα πίνακες που μπορούν να οριστούν ξανά, και χωρίς να χάσουν τα δεδομένα τους. Πχ. DIM A$(10,4) και έστω ότι η πρώτη διάσταση λέμε να είναι γραμμές, με DIM A$(20,4) βάζουμε άλλες δέκα γραμμές χωρίς να σβήσουμε ότι είχε πριν ο πίνακας! Μπορούμε να αλλάζουμε ένα πίνακα ακόμα και όταν τον περνάμε με αναφορά σε τμήμα ή συνάρτηση (Στη Μ2000 προς το παρόν δεν περνάει με αντιγραφή ένας πίνακας, αλλά μεμονωμένα στοιχεία του). Οπότε έφτιαξα και μια συνάρτηση για να βρίσκουμε πόσες διαστάσεις έχει ένας πίνακας και το εύρος της κάθε διάστασης (το πρώτο στοιχείο είναι στο 0, άρα με εύρος 10 θα έχουμε από 0 έως 9 οι σωστοί δείκτες).

ΠΙΝΑΚΑΣ Α(10,3)
ΤΥΠΩΣΕ ΔΙΑΣΤΑΣΗ(Α())  ' ΤΥΠΩΝΕΙ 2
ΤΥΠΩΣΕ ΔΙΑΣΤΑΣΗ(Α(),1) ' ΤΥΠΩΝΕΙ 10
ΤΥΠΩΣΕ ΔΙΑΣΤΑΣΗ(Α(),2) ' ΤΥΠΩΝΕΙ 3

Μπορούμε να αλλάζουμε όχι μόνο τον αριθμό του εύρους των διαστάσεων αλλά και τον αριθμό των διαστάσεων. Δηλαδή μπορούμε ένα μονοδιάστατο πίνακα να τον κάνουμε δυο διαστάσεων και το ανάποδο!
Παραμένει το "κόλπο" που έπαιζε και στο ξεκίνημα της  6ης έκδοση, να μπορούμε να περάσουμε με αναφορά σε άλλο τύπο, δηλαδή ενώ έχουμε ορίσει αριθμητικό πίνακα να φτιάξουμε μια αναφορά στον πίνακα και να την μεταφέρουμε σε αλφαριθμητικό ώστε τελικά να μπορούμε ταυτόχρονα σε άλλα στοιχεία να βάζουμε αριθμό και σε άλλα αλφαριθμητικό!  Μάλιστα αν το αλφαριθμητικό είναι χαρακτήρες που δηλώνουν αριθμό, τότε αν το ζητήσουμε ως αριθμό θα το μετατρέψει ο μεταφραστής αυτόματα σε αριθμό! Παραμένει εσωτερικά ο πίνακας που αντιστοιχεί στον πίνακα της Μ2000 να έχει στοιχεία τύπου Variant (δες Visual Basic 6)

Προς το παρόν δεν μπορούμε να σβήσουμε ένα πίνακα (θα σβήσει με το πέρας του τμήματος ή της συνάρτησης που το δημιούργησε), μπορούμε όμως να τον ορίσουμε με ένα μόνο στοιχείο ΠΙΝΑΚΑΣ Α(1)



Δομές
Εμπλουτίστηκε η ΑΝ  συνθήκη ΤΟΤΕ { εντολές } ΑΛΛΙΩΣ {εντολές} με την προσθήκη του ΑΛΛΙΩΣ.ΑΝ συνθήκη {εντολές}, όπου { εντολές } μπορεί να είναι ένα μπλοκ πολλαπλών εντολών - σε πολλές γραμμές. Μπορούν να μπουν πολλά ΑΛΛΙΩΣ.ΑΝ αλλά μόλις βρεθεί συνθήκη που ικανοποιείται τα υπόλοιπα και το ΑΛΛΙΩΣ θα αγνοηθούν.

Σε μπλοκ εντολών η ΔΙΕΚΟΨΕ τερματίζει ένα τμήμα άμεσα, χωρίς να σταματήσει το τμήμα που κάλεσε το τρέχον τμήμα, εκτός από την περίπτωση να βρίσκεται σε ένα μπλοκ μέσα στην ΕΠΙΛΕΞΕ ΜΕ. Στην ΕΠΙΛΕΞΕ ΜΕ η ΔΙΕΚΟΨΕ έχει το νόημα, διέκοψε την λειτουργία σου, και εκτέλεσε κάθε περίπτωση μέχρι τέλους ή να βρεθεί μια ΣΥΝΕΧΙΣΕ (τις συνθήκες δεν τις εκτελεί σε κάθε ΜΕ)
Οι εντολές ΚΥΚΛΙΚΑ, ΕΞΟΔΟΣ, ΞΕΚΙΝΑ, ΔΙΕΚΟΨΕ, ΣΥΝΕΧΙΣΕ, ΛΑΘΟΣκατευθύνουν την ροή εντολών σε ένα μπλοκ εντολών που προσδιορίζεται με αγκύλες. Και ένα τμήμα είναι ένα μεγάλο μπλοκ, οπότε μια ΚΥΚΛΙΚΑ οπουδήποτε στο σώμα των εντολών θα κάνει το τμήμα να ξανατρέξει στο πέρας των εντολών. Μια ΞΕΚΙΝΑ ξανατρέχει άμεσα το τμήμα (είναι σαν μια ΚΥΚΛΙΚΑ και μια ΣΥΝΕΧΙΣΕ μαζϊ). Μια ΔΙΕΚΟΨΕ όπως και η ΕΞΟΔΟΣ  διακόπτει τη ροή, αλλά η ΕΞΟΔΟΣ έχει βάθος που ενεργεί σε ένα μπλοκ ενώ η ΔΙΕΚΟΨΕ αρκετά..αλλά σταματάει μέχρι το Τμήμα στο Τμήμα που θα τρέξει. Τώρα πια η ΕΞΟΔΟΣ σταματάει και την ΓΙΑ όπως και έκανε για τις  ΕΝΩ και ΕΠΑΝΑΛΑΒΕ - οι δομές αυτές είναι ΕΝΩ συνθήκη { εντολές } και ΕΠΑΝΑΛΑΒΕ { εντολές} ΜΕΧΡΙ συνθήκη ή ΠΑΝΤΑ χωρίς συνθήκη.  (υπάρχει και το ΕΠΑΝΕΛΑΒΕ  )
Η εντολή ΣΥΝΕΧΙΣΕ κάνει το εξής...αδειάζει ότι έχει άλλο το μπλοκ να εκτελέσει και αν ετρεξε μια ΚΥΚΛΙΚΑ στο ίδιο μπλοκ τότε ενεργεί σαν την ΞΕΚΙΝΑ διαφορετικά τερματίζει το μπλοκ και συνεχίζει μετά από αυτό.  Η ΛΑΘΟΣ τερματίζει όλα τα τμήματα (σε οποιοδήποτε βάθος και αν έχουν φτάσει) εκτός από την περίπτωση της δομής ΔΕΣ μεταβλητήΕλέγχου {μπλοκ εντολών} όπου αυτή πιάνει τα λάθη και σε περίπτωση λάθους συνεχίζει άμεσα και το αναφέρει (κάνει ψευδες την μεταβλητή ελέγχου, δηλαδή την κάνει 0).
Τέλος η ΑΠΟ παράστασηΑριθμητική ΠΡΟΣ ετικέτα1, ετικέτα2.... τώρα λειτουργεί και με νούμερα (από 1 ως 99999) τα οποία μπορούμε να βάζουμε σε οποιαδήποτε γραμμή. Όμως τα άλματα και σε αυτή την δομή ή με το απλό ΠΡΟΣ πρέπει να είναι εντός μπλοκ εντολών. Μάλιστα δεν υπάρχει διάκριση ως προς το τι είναι η γραμμή που θα βρεθεί η ετικέτα, ή αν υπάρχουν δέκα ίδιες, πάντα θα βρίσκει την πρώτη. Είναι στην ευχέρεια του προγραμματιστή...να κάνει λάθος. Δεν μπήκε έλεγχος για να μην καθυστερεί το άλμα, αφού η γλώσσα κάθε φορά το ψάχνει!

Χειρισμός μεταβλητών
Αντί να δώσουμε α=α+1 μπορούμε να δώσουμε αυτό:
α++
αλλά και τα παρακάτω:
α--
α+=10
α-=3
α*=12
α/=2
χ-! αλλαγή προσήμου.
Τα παραπάνω δεν μπορούν να είναι στην δεξιά πλευρά μιας αντικατάστασης και δεν λειτουργούν για πίνακες (ίσως σε άλλη έκδοση)

Μπορούμε να χειριστούμε αλφαριθμητικά με τις αγκύλες
α$= {"ασαδ"}+{
α}+{σδφσ
σδφσφ
σδφσ  }

Νήματα
Εδώ φτιάχτηκαν μερικά πράγματα: δυο άμεσα νήματα, που φτιάχνονται χωρίς να  πάρουμε αριθμό χειρισμού νήματος.
ΜΕΤΑ αριθμητικήΠαράσταση { εντολές}
Μετά από τον αριθμό των χιλιοστών δευτερολέπτου θα εκτελεστούν οι εντολές μια φορά. Βεβαίως αν το τμήμα που δημιουργήθηκε το νήμα τερματίσει πριν ξεκινήσει το μπλοκ εντολών της ΜΕΤΑ τότε θα χαθεί (επειδή τα τμήματα τερματίζουν όλα τα νήματα πριν κλείσουν).
ΚΥΡΙΟ.ΕΡΓΟ αριθμητικήΠαράσταση {εντολές}
Αυτή η δομή είναι ίδια "εξωτερικά"με την εντολή ΚΑΘΕ, αφού εκτελεί και αυτή τις εντολές σε τακτά χρονικά διαστήματα, αλλά η διαφορά είναι στο ότι το ΚΥΡΙΟ.ΕΡΓΟ είναι νήμα και πως αν κάνουμε ΕΞΟΔΟ τότε θα κλείσει όλα τα νήματα. Η δομή ΚΑΘΕ δεν είναι νήμα. Για να συμπεριφερθεί σαν αυτή τη δομή η ΚΥΡΙΟ.ΕΡΓΟ εκτελεί εκτός νήματος μια εσωτερική επανάληψη να δει πότε θα τερματίσει. Με την ΚΥΡΙΟ.ΕΡΓΟ όλα τα μπλοκ εντολών είναι νήματα και ο χρόνος τους είναι διαχειρίσιμος από το σύστημα!
Αναβάθμισα το σύστημα και μπορούν με το Esc να διακοπούν άμεσα τα νήματα. Τα νήματα καλούνται ξεχωριστά από τα Windows με χρονιστή. Αν ένα νήμα δεν δίνει χρόνο στα άλλα τότε φρακάρει το σύστημα. Για το λόγο αυτό οι εργασίες που καλούνται να κάνουν θα πρέπει να είναι μικρές, να προχωρούν με βήματα. Παρόλα αυτά τα νήματα ενδέχεται να τρέξουν το ένα μέσα στο άλλο. Αυτό που δεν γίνεται είναι να τρέξει ταυτόχρονα ένα νήμα δυο φορές και αυτό γιατί κάθε νήμα βγαίνει από την λίστα προς εκτέλεση και πάει σε μια λίστα των υπό εκτέλεση νημάτων! Τα νήματα ανήκουν στο χώρο του τμήματος που τα δημιούργησε, βλέπουν τις μεταβλητές του τμήματος και τις γενικές. Μπορούν όμως να δημιουργήσουν τμήματα, άρα και άλλα νήματα! Τα οποία όμως για να τρέξουν πρέπει να δώσει το τμήμα χρόνο άρα να καθυστερήσει το  νήμα. Το σύστημα της Μ2000 διαχειρίζεται το πότε μπορεί ένα νήμα να ξεκινήσει και πότε μπορεί να έχει χρόνο το σύστημα να ανανεώνει φόρμες και άλλα "γεγονότα"! Αυτά τα δυο δηλαδή στην έκδοση 6.4 διαχωρίστηκαν, με συνέπεια βέβαια να χαθεί λίγο η ακρίβεια χιλιοστού του χρονιστή εκκίνησης  των νημάτων (τα νήματα καλούνται με μέτρημα χρόνου).


Αυτά τα ολίγα...και συνεχίζω! Θέλω να γράψω την ενσωματωμένη βοήθεια! Ευτυχώς έχω προγράμματα αναφοράς και ελέγχο την συμβατότητα της γλώσσας κάθε φορά που την αλλάζω σε όλα τα επίπεδα!






Παρασκευή 9 Μαΐου 2014

Περί γλωσσών προγραμματισμού τα βασικά!

Σήμερα αποφάσισα να κάνω ένα διάλειμμα από την συγγραφή της 7ης έκδοσης της Μ2000, για να γράψω μερικά πράγματα για τις γλώσσες προγραμματισμού και τις εφαρμογές τους, σε αυτό εδώ το Blog.

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

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

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

Στα πρώτα χρόνια λοιπόν χρήσης υπολογιστών οι προγραμματιστές ασχολήθηκαν με την αναζήτηση του σωστού προγράμματος που θα "εκτιμήσει" σωστά τα δεδομένα. Μπορεί να φαίνεται αυτό αρκετό αλλά δεν είναι! Αν τα δεδομένα ήταν πιάτα και το πρόγραμμα το πλυντήριο τότε θα σκεφτεί κανείς .."αυτό το πράγμα πλένει όλα τα πιάτα;".  Γιατί υπάρχουν πιάτα με διαφορετικές ποιότητες, άρα θα απαιτούν ειδική μεταχείριση. Οι προγραμματιστές πήγαν παραπέρα. Σκέφτηκαν να ονομάσουν το πλύσιμο ως μια μέθοδο για κάθε πράγμα που πλένεται, ανεξάρτητα από τη συσκευή πλύσης. Στην κυριολεξία βγήκαν εφαρμογές που δέχονταν "αρχεία" ανεξάρτητα από τη συσκευή "επίδειξης". Ακόμα και η έννοια "προσωπικός υπολογιστής" εμπεριέχει την έννοια του "χειρισμού" ανεξάρτητων δεδομένων. Εκεί χάθηκε η γνώση ότι τα δεδομένα είναι εντολές και πέρασε το κομμάτι των εντολών στον χειρισμό του χρήστη επί των δεδομένων. Αργότερα επανήλθαν τα πράγματα, με την έννοια των μεταδεδομένων, των δεδομένων που πάνε παρέα με στοιχεία για την επίδειξή τους και χρήση τους, άρα με εντολές! Για παράδειγμα ένα αρχείο φωτογραφικής μηχανής λέει μεν τι χρώματα θέλει να δείξει στην εμφάνισή της αλλά δίνει και πρόσθετες πληροφορίες για το αν θα πρέπει να την βλέπουμε οριζόντια ή κάθετα, δηλαδή μια εντολή του τι θα γίνει πριν δούμε η φωτογραφία αλλά δεν έχει γίνει ήδη στο αρχείο η προεργασία!

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


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

Δεν σταμάτησε όμως η εφευρετικότητα του ανθρώπου σε αυτά! Με το διαδίκτυο αναπτύχθηκαν οι περιφραστικές γλώσσες όπως η Html, όπου δεν περιλαμβάνουν υποχρεωτικά διαδικασίες αλλά αποτελούν τα προγράμματά τους τα δεδομένα με τα καλοπιστικά τους στοιχεία και "ζωντανά" στοιχεία όπως οι υπερσυνδέσεις και τα γεγονότα. Αν δεν υπήρχαν τα ζωντανά στοιχεία στην Html θα μιλάγαμε για μια φόρμα, για μεταδεδομένα. Τα ζωντανά στοιχεία δίνουν λειτουργικότητα και τότε ακριβώς μιλάμε για πρόγραμμα.


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


Το τελικό ερώτημα εδώ είναι: Υπάρχει η γλώσσα προγραμματισμού που τα κάνει όλα; Όχι δεν υπάρχει. Αν υπήρχε θα είχε αντικαταστήσει τις άλλες. Δεν είναι μόνο σκοπός να φέρει αποτέλεσμα ένα πρόγραμμα αλλά και αν ο κόπος και το κόστος που θα κάνει για να το φέρει θα είναι υποφερτός για μας. Οι γλώσσες προγραμματισμού δεν είναι ελεύθερες γλώσσες κατ' ανάγκη. Και αυτό γιατί για να τις χρησιμοποιήσει κανείς πρέπει να αγοράσει το περιβάλλον ανάπτυξης μαζί με τις συνοδευτικές βιβλιοθήκες διαδικασιών ή και αντικειμένων. Μεγάλες εταιρείες σου δίνουν δωρεάν την βασική έκδοση, που αν θες με αυτή μπορείς να ανακαλύψεις πάλι τον τροχό. Για να φτιάξεις  όμως εδώ και τώρα μια "λύση" για το πρόβλημα που θες λύσεις προγραμματιστικά ή θες να προσφέρεις μια Εφαρμογή για όμοια προβλήματα ή ένα γενικευμένο αντικείμενο, τότε θα πρέπει να πληρώσεις για να έχεις πρόσβαση  σε ιδιωτικό λογισμικό.


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


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

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

Γιώργος Καρράς

Τετάρτη 7 Μαΐου 2014

Περιορισμός στο Προγραμματισμό!

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

Η γλώσσα έχει εδώ την Α_Τ() συνάρτηση που σημαίνει ακέραια τιμή. Μερικές γλώσσες όταν διαβάζουν ακέραιο λογαριάζουν μόνο την εισαγωγή χαρακτήρων που κάνουν ένα ακέραιο..και έτσι μεταβιβάζουν το πρόβλημα της σωστής εισαγωγής στοιχείων στον χρήστη. Άλλες γλώσσες το πλεόνασμα το πετάνε! Δηλαδή διαβάζουν ό,τι εισαγωγή δώσει ο χρήστης και από αυτήν βγάζουν ένα αποτέλεσμα. Ουσιαστικά ο περιορισμός υφίσταται στη γλώσσα και απλά εδώ συζητάμε για το χειρισμό. Γιατί όμως να έχει η γλώσσα περιορισμούς, και αφού μιλάμε για τον χειρσμό, άρα μιλάμε για τον προγραμματισμό, αυτό δηλαδή που δίνει εκείνο που θα χειριστούμε;

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

ΠΡΟΓΡΑΜΜΑ διαιρεση
ΣΤΑΘΕΡΕΣ
  ΑΡΙΘΜΟΣ_ΔΕΚΑΔΙΚΩΝ=12
ΜΕΤΑΒΛΗΤΕΣ
  ΑΚΕΡΑΙΕΣ: Α,Β, ΘΕΣΗ
  ΑΚΕΡΑΙΕΣ: ΑΡΧΙΚΟ_Α, ΑΡΧΙΚΟ_Β
  ΧΑΡΑΚΤΗΡΕΣ: Π[3], ΑΠ

ΑΡΧΗ
   ! Πινακας Π μετατροπής προσήμου σε χαρακτήρα
  Π[1] <-- '-'
   ! στο μηδέν λέμε πρόσημο (+) στην εμφάνιση
   ! διότι μας ενδιαφέρει τα +/-, το μηδέν θα φανεί!
  Π[2] <-- '+'
  Π[3] <-- '+'
  ΓΡΑΨΕ '---------------ΕΠΙΔΕΙΞΗ ΔΙΑΙΡΕΣΗΣ-----------'
  ΓΡΑΨΕ 'ΔΩΣΕ ΑΚΕΡΑΙΟ ΩΣ ΔΙΑΙΡΕΤΕΟ'
  ΔΙΑΒΑΣΕ Α
  ΑΡΧΙΚΟ_Α <-- Α

  ΓΡΑΨΕ 'ΔΩΣΕ ΑΚΕΡΑΙΟ ΩΣ ΔΙΑΙΡΕΤΗ'
  ΔΙΑΒΑΣΕ Β
  ΑΡΧΙΚΟ_Β <-- Β
  ΓΡΑΨΕ 'ΠΡΟΣΗΜΟ ΑΠΟΤΕΛΕΣΜΑΤΟΣ=', Π[ΠΡΟΣΗΜΟ(Α)*ΠΡΟΣΗΜΟ(Β)+2]
  Α <-- Α_Τ(Α)
  Β <-- Α_Τ(Β)
   ! Η εξαγωγή της ΠΡΟΣΗΜΟ() μας δίνει τρια πιθανά αποτελέσματα
   ! και εδώ χρησιμοποιούμε το ένα, αν και με ένα Β=0 θα είχαμε το ίδιο αποτέλεσμα

  ΑΝ ΠΡΟΣΗΜΟ(Β)=0 ΤΟΤΕ
    ΓΡΑΨΕ 'ΔΙΑΙΡΕΣΗ ΜΕ ΤΟ ΜΗΔΕΝ - ΛΑΘΟΣ'
  ΑΛΛΙΩΣ
    ΓΡΑΨΕ 'ΔΙΑΙΡΕΣΗ=', (Α DIV Β)
    ΓΡΑΨΕ 'ΥΠΟΛΟΙΠΟ=', (Α MOD Β)
    ΓΡΑΨΕ 'ΥΠΟΛΟΓΙΣΜΟΣ ΔΕΚΑΔΙΚΩΝ'
    ΘΕΣΗ <-- 0
    Α <-- (Α MOD Β)
    ΟΣΟ  (ΘΕΣΗ <  ΑΡΙΘΜΟΣ_ΔΕΚΑΔΙΚΩΝ ) ΚΑΙ (Α>0)  ΕΠΑΝΑΛΑΒΕ
      ΘΕΣΗ <-- ΘΕΣΗ+1
      Α <-- Α*10
      ΓΡΑΨΕ (Α DIV Β)
      Α <-- (Α MOD Β)
    ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
    ΓΡΑΨΕ 'ΕΠΑΛΗΘΕΥΣΗ:', ΑΡΧΙΚΟ_Α/ΑΡΧΙΚΟ_Β
  ΤΕΛΟΣ_ΑΝ
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ

   ! Στην BASIC υπάρχει η SGN() που δουλεύει ακριβώς όπως η ΠΡΟΣΗΜΟ()
   ! Η διαφορά είναι ότι σε επιστημονικούς υπολογισμούς μπορεί κανεις
   ! να κάνει έτσι την ΠΡΟΣΗΜΟ ώστε σε ένα μικρό διάστημα γύρω από το μηδέν
   ! να δίνει μηδέν π.χ. ( ΑΝ -.00000000000000005<ΑΛΦΑ<.00000000000000005 ΤΟΤΕ ΑΛΦΑ=0)
   ! Στους αυτοματισμούς το λέμε DEAD ZONE:
   ! όσο αυξάνουμε τη νεκρή περιοχή τόσο αναίσθητο κάνουμε το σύστημα!!!!

ΣΥΝΑΡΤΗΣΗ ΠΡΟΣΗΜΟ(ΑΛΦΑ):ΑΚΕΡΑΙΑ
ΜΕΤΑΒΛΗΤΕΣ
  ΠΡΑΓΜΑΤΙΚΕΣ:  ΑΛΦΑ
ΑΡΧΗ
  ΑΝ ΑΛΦΑ=0 ΤΟΤΕ
    ΠΡΟΣΗΜΟ <-- 0
  ΑΛΛΙΩΣ_ΑΝ ΑΛΦΑ>0 ΤΟΤΕ
    ΠΡΟΣΗΜΟ <-- 1
  ΑΛΛΙΩΣ
    ΠΡΟΣΗΜΟ <-- -1
  ΤΕΛΟΣ_ΑΝ
ΤΕΛΟΣ_ΣΥΝΑΡΤΗΣΗΣ

Περί της Μ2000

Η γλώσσα Μ2000 σχεδιάστηκε το 1999 σε μια προσπάθεια να φτιάξω  μια εφαρμογή ασχολίας με το προγραμματισμό, κύρια για εκπαιδευτικούς λόγους.
Γράφω ασχολίας διότι δεν ήθελα να είναι ένα εργαλείο επαλήθευσης αλγορίθμων.  Τέτοιο εργαλείο χρειάζονται οι καθηγητές πληροφορικής και υπάρχει η απλή ΓΛΩΣΣΑ και εφαρμογές πολύ καλές όπως η ΓΛΩΣΣΟΜΑΘΕΙΑ για παράδειγμα, και ο Διερμηνευτής της Γλώσσας.

Επιπλέον στόχο είχα βάλει να περιλαμβάνει διπλό σύνολο εντολών, Ελληνικών και Αγγλικών. Άλλη "προδιαγραφή" ήταν να χρησιμοποιεί το λειτουργικό σύστημα για τις περισσότερες εργασίες παρά εξειδικευμένες βιβλιοθήκες. Έπρεπε να φτιάξω ένα περιβάλλον που θα θύμιζε υπολογιστή της δεκαετίας του 80. Έτσι το πρώτο πράγμα που έφτιαξα ήταν τον μεταφραστή γραμμής και την εντολή ΤΥΠΩΣΕ.

Ασφαλώς υπάρχουν γλώσσες προγραμματισμού "τεράστιες". Όμως είναι πολύ "Αφηρημένες" δηλαδή αφήνουν πολλά πράγματα στην πρωτοβουλία του προγραμματιστή, πράγμα που δεν μπορεί να έχει ένας νέος στο χώρο! Από την άλλη πλευρά δεν γίνεται να φτιάξει κανείς κάτι καλό αν δεν εξειδικεύσει σε αυτό που απλά λέμε δυνατότητες του συστήματος. Έτσι η Μ2000 είχε σαν στόχο από την αρχή να δίνει δυνατότητες μέσα στην "κονσόλα" της να μπορεί κανείς να χαράζει γραμμές, καμπύλες, πολύγωνα και κύκλους. Επίσης να γεμίζει την οθόνη με σχήματα από αρχεία emf και wmf , να φορτώνει εικόνες jpg σε μεταβλητές αλφαριθμητικών, να μετακινεί την "Οθόνη" πάνω στο "Περιθώριο" και το τελευταίο να μετακινείται στην οθόνη του υπολογιστή. Άλλες "προδιαγραφές" ήταν η χρήση χαρακτήρων ο ένας κάτω από τον άλλο, όπως στις κονσόλες εντολών και επιλογή τύπου γραμματοσειράς (όλες οι γραμματοσειρές ακόμα και οι αναλογικές μπορούν να χρησιμοποιηθούν με μη αναλογική γραφή). Φυσικά μπορούσε κανείς να βάλει και επιγραφές με αναλογική γραφή και μάλιστα και με γωνία σε ακτίνια. Επιπλέον ήθελα και ένα ωραίο χαρακτηριστικό, την χωριστή οθόνη, όπου ένα μέρος της πάνω δεν ολισθαίνει όταν "ζητάμε" γραμμή, καθώς γεμίζει η οθόνη. Δεν έμεινα μόνο σε αυτά για την οθόνη.  Οι εντολές εκτύπωσης οδηγούνται ή στην Οθόνη, ή στο Περιθώριο ή στον Εκτυπωτή.

Επιπλέον στις πρώτες εκδόσεις έβαλα και την διαχείριση βάσεων δεδομένων τύπου MDB. Με απλές εντολές μπορούμε να χτίσουμε μια βάση και με ερωτήματα SQL ή πιο απλά , να πάρουμε στοιχεία. Παρακάτω είναι το σύνολο εντολών για τις βάσεις δεδομένων. Περιλαμβάνει την ΔΟΜΗ για την ανάγνωση της Δομής της, τις ΒΑΣΗ, ΠΙΝΑΚΑΣ και ΤΑΞΗ που δημιουργούμε τα βασικά (μια βάση με πίνακες και σε κάθε πίνακα τον τρόπο  ταξινόμησης)
 Αναζητηση, Search, Ανακτηση, Retrieve, Αρχειο, Table, Αφαιρεση, Delete, Βαση, Base, Δειξε, View, Δομη, Structure, Επιστροφη, Return, Προσθηκη, Append, Συμπιεση, Compress, Ταξη, Order

Ακολουθεί το πρόγραμμα που εμφανίζει η βοήθεια (υπάρχει ενσωματωμένη στη γλώσσα π.χ. γράφουμε βοηθεια δομη χωρίς τόνους και ανοίγει ένα παράθυρο με τα σχετικά). Παρακάτω αναφέρεται μια λίστα επιλογών. Αυτή είναι ένα κοινό Listbox το οποίο εμφανίζεται στην θέση των χαρακτήρων της οθόνης. Π.χ. Επιλογη "Ναι","Όχι" θα δώσει μια λίστα με δυο στοιχεία, δυο επιλογές. Την λίστα την χρησιμοποιούν η εντολή Αρχεια και η Δειξε για να επιλέξουμε στοιχεία από πίνακα της Βάσης (ή από SQL ερώτημα)

\\ Διορθώθηκε στις τάξεις. Δεν γίνεται επιστροφή μήκους, μόνο όνομα πεδίου και αν είναι Αύξουσα ή Φθίνουσα Τάξη. Επίσης με την ΒΑΣΗ.ΠΑΡΟΧΟΣ "" κάθε φορά επαναφέρουμε στον βασικό πάροχο σε περίπτωση που αυτόματα η Μ2000 άλλαξε πάροχο για να ανοίξει μια παλιά βάση mdb.


ΦΟΡΜΑ 80,50
ΒΑΣΗ.ΠΑΡΟΧΟΣ ""   ' ρυθμίζει τον πάροχο στον βασικό (ενδέχεται να αλλαχθεί αυτόματα αν δεν μπορεί να ανοίξει μια βάση η Μ2000)
α=ΣΤΗΛΗ ' κρατάμε στο α το πλάτος νοητής στήλης στην οθόνη
ΤΥΠΩΣΕ $(0,8) ' ορίζουμε πλάτος 8
ΕΠΙΛΟΓΗ ' σβήνουμε την λίστα επιλογών
ΑΡΧΕΙΑ + "mdb"  ' βάζουμε στην λίστα επιλογών όλα τα αρχεία τύπου "mdb"
                          ' από τον τρέχον κατάλογο
ΑΝ ΕΠΙΛΟΓΕΣ>0 ΤΟΤΕ {  ' αν υπάρχουν επιλογές στην λίστα
      ΤΥΠΩΣΕ "Επέλεξε ένα αρχείο:";
      ΕΠΙΛΟΓΗ ! ' εμφάνιση της λίστας για να επιλέξουμε
      ΑΝ ΕΠΙΛΟΓΗ>0 ΤΟΤΕ {
            ΒΑΣΗ$=ΕΠΙΛΟΓΗ$( ΕΠΙΛΟΓΗ )
            ΤΥΠΩΣΕ ΠΕΖ$(ΒΑΣΗ$)+".mdb"
            ΤΥΠΩΣΕ "Δομή"
            ΤΥΠΩΣΕ "Αρχεία:";
            ΔΟΜΗ ΒΑΣΗ$
            ΔΙΑΒΑΣΕ ΑΡΧΕΙΑ ' εδώ δεν έχουμε την εντολή ΑΡΧΕΙΑ
                     'αλλά φτιάχνουμε μια μεταβλητή με το ίδιο όνομα και δίνουμε τιμή
                     ' από τον σωρό
            ΤΥΠΩΣΕ ΓΡΑΦΗ$(ΑΡΧΕΙΑ)
            ΑΝ ΑΡΧΕΙΑ>0 ΤΟΤΕ {
                  ΓΙΑ Ι=1 ΕΩΣ ΑΡΧΕΙΑ {
                        ΔΙΑΒΑΣΕ ΟΝΟΜΑΤΑ$, ΤΑΞΕΙΣ
                        ΤΥΠΩΣΕ Ι,") "+ΟΝΟΜΑΤΑ$
                        ΔΟΜΗ ΒΑΣΗ$, ΟΝΟΜΑΤΑ$
                        ΔΙΑΒΑΣΕ ΠΕΔΙΑ, ΤΑΞΕΙΣ
                                    ' αν υπάρχει αριθμός στο σωρό και όχι λέξη τότε...
                        ΑΝ ΠΕΔΙΑ>0 ΤΟΤΕ {
                              ΓΙΑ Π=1 ΕΩΣ ΠΕΔΙΑ {
                                    ΔΙΑΒΑΣΕ ΠΕΡΙΓΡΑΦΗ$, ΤΥΠΟΣ$, ΜΗΚΟΣ
                                    ΤΥΠΩΣΕ "",Π,") "+ΠΕΔΙΟ$(ΠΕΡΙΓΡΑΦΗ$,17),"",ΤΥΠΟΣ$, ΜΗΚΟΣ
                              }
                        }
                        ΑΝ ΤΑΞΕΙΣ>0 ΤΟΤΕ {
                              ΤΥΠΩΣΕ "","ΤΑΞΗ:"
                              ΔΙΑΒΑΣΕ ΠΕΔΙΑ
                              ΑΝ ΠΕΔΙΑ>0 ΤΟΤΕ {
                                    ΓΙΑ Π=1 ΕΩΣ ΠΕΔΙΑ {
                                          ΔΙΑΒΑΣΕ ΠΕΡΙΓΡΑΦΗ$, ΤΥΠΟΣ$
                                          ΤΥΠΩΣΕ "",Π,") "+ΠΕΔΙΟ$(ΠΕΡΙΓΡΑΦΗ$,17),"",ΤΥΠΟΣ$
                                    }
                              }
                        }
                  }
            }
      }
}
ΤΥΠΩΣΕ $(0,α)


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

Τα σημεία που άλλαζαν την έκδοση ήταν: Η δεύτερη έκδοση απέκτησε την SELECT CASE (ΕΠΙΛΕΞΕ ΜΕ) και άλλες βελτιώσεις. Η τρίτη βελτίωσε τα γραφικά με πρόσθετες εντολές όπως γέμισμα χρώματος. Η τέταρτη έφερε την ενσωματωμένη βοήθεια. Η πέμτη έφερε τις συναρτήσεις χρήστη με δυνατότητα αναδρομής (κλήση του εαυτού της), τους πολυδιάστατους πίνακες. Σε αυτήν την έκδοση χώρισε ο σωρός, έτσι ώστε οι συναρτήσεις να μπορούν να έχουν τμήματα στο δικό της σωρό. Ο σωρός είναι το μέρος που από την πρώτη έκδοση πέρναγαν από και προς τα τμήματα τιμές, αριθμοί και αλφαριθμητικά (by value, με τιμή όπως λέμε). Μέχρι εδώ δεν υπήρχε μεταφορά τιμών με αναφορά. Πέρασαν αρκετά χρόνια (πάνω από δέκα) όπου ξεκίνησα να φτιάχνω την έκτη έκδοση. Από θέμα εντολών "κόρμού" μπήκε το πέρασμα με αναφορά. Με κλήση π.χ. ΟνομαΤμηματος &Α() αφήνει στον σωρό ένα αλφαριθμητικό που δηλώνει τον δείκτη που δείχνει τη θέση της "γνήσιας" μεταβλητής ή πίνακα. Έτσι με μια Διαβασε &Β() κάνουμε την Β() να δείχνει ότι και η Α(). Από την 6.2 μπορούμε να αλλάζουμε μέγεθος στον πίνακα Β() και θα αλλάξει (αφού είναι ο ίδιος) και στην Α(), και έτσι φτιάχτηκε και εντολή που "ρωτάει" για το πόσες διαστάσεις έχει ένας πίνακας και τι μέγεθος έχει σε κάθε μία!
Μια ιδιότητα που βρήκα. χωρίς να την είχα υπολογίσει είναι ότι επειδή οι πίνακες και οι μεταβλητές τουλάχιστον μέχρι την 6η έκδοση είχαν τιμές σε έναν δυναμικά αναπτυσσόμενο πίνακα τύπου variant, ώστε όπου ήθελα έβαζα αλφαριθμητικά και όπου ήθελα αριθμούς, μέσα από τον μηχανισμό αναφορών το εξέθεσα καλώς!
Να ένα παράδειγμα. Ένας μόνο πίνακας υπάρχει ο a(), ενώ ο b$() είναι η αναφορά στον α() αλλά επειδή είναι αλφαριθμητικός περνάει τιμές αλφαριθμητικών! Αυτόματα έχουμε μετατροπή από αριθμό σε αλφαριθμητικό όταν ζητάει ο b$() και το ανάποδο, μετατροπή του  aaaa σε αριθμό (0). Αν αντί του "aaaa" είχα δώσει ας πούμε το 123 θα έδινε αριθμό 123 η a(3)

          Dim a( 10 )
          a( 2 ) = 1000
          Push "aaaa"
          Push &a( )
          Read &b$( )
          Read b$( 3 )
          ? b$( 2 ), b$( 3 )
          ' τυπώνει 1000 και aaaa ως αλφαριθμητικά
          ? a( 2 ), a( 3 )
          ' τυπώνει 1000 και 0 (επειδή τα βλέπει ως τιμές).
 
Η έκτη έκδοση έγινε λοιπόν 10 χρόνια μετά και προστέθηκαν εκτός από αυτό τον μηχανισμό, τα νήματα δηλαδή πολυεπεξεργασία, αυλοί επικοινωνίας, 32 επίπεδα (σαν hardware sprites), μουσική με νότες και επιλογή οργάνων, καθώς και η Repeat Until που δεν την έβαλα από την αρχή αφού υπήρχε τρόπος να στηθεί "περιφραστικά". ειδικά τα νήματα άλλαξαν τα πάντα. Στην έκδοση που φτιάχνω το σύστημα αντέχει να τρέχει "πολυεπίπεδα" νήματα, δηλαδή νήματα σε διαφορετικά τμήματα (αν το κάνει κανείς στην έκδοση έξι, ρισκάρει να δημιουργήσει μεταβλητές με ένα νήμα , και ενώ το τμήμα που το δημιούργησε έχε καλέσει ήδη ένα άλλο τμήμα). Ο κανόνας μέχρι την έκδοση έξι έλεγε ότι όταν ένα τμήμα τερματίζει ότι έχει φτιαχτεί από τον χρόνο που ξεκίνησε...θα σβήσει. Αν όλα τα νήματα τρέχουν στο ίδιο τμήμα δεν φοβάται κανείς το σβήσιμο, αφού αυτό θα γίνει όταν τερματίοει το τμήμα! Ο άλλος τρόπος είναι όπως αυτός που σχεδιάζω τώρα..όπου  τα τμήματα δημιουργούν μεταβλητές στο δικό τους χώρο Έτσι φαίνονταν και παλιά αλλά η διαφορά είναι ότι παλιά ο τρόπος που έβρισκε κανείς τις μεταβλητές τις έκανε να ξεχωρίζουν και όχι ο τρόπος αποθήκευσης και αυτό γιατί δεν είχα την ιδέα πώς να πετύχω την πολυεπεξεργασία. Την οποία κάπου τη βρήκα βέβαια αλλά αυτός που την έφτιαξε δεν είχε καν κάνει το κόπο να κάνει κάτι με αυτή, ήταν ένα απλό ομιχλώδες σχέδιο! Εγώ ξεκίνησα να την χρησιμοποιώ με τη μουσική και μετά σκέφθηκα τα νήματα επεξεργασίας.

Αυτό είναι από την βοήθεια των εντολών Φωνη και Παιξε

          Score 3, 1000, "C5F#@2B@2C5F#@2B"
               Score 1, 1000, "D@2E@2C#3 @2D5@2V90 @3F#4V127"
                              '/ C C# D D# E F F# G G# A# B
                              '/
               Play 1, 19, 3, 22 ' VOICE, INSTRUMENT
     
          'Υπάρχουν 16 φωνές Φωνη 12, 1000,"C5"
          'βάζουμε στη φωνή 12 να παίξει μια νότα Από την 5η οκτάβα για 1000 χιλιοστά
          'Αν βάλουμε @2 θα παίξει σε χρόνο 1000/2, μέχρι @6 δηλαδή 1000/32
          'Αν βάλουμε V και έναν αριθμό Από 1 μέχρι 127 αλλάζουμε την Ενταση
          'Αν δεν βάλουμε γράμμα νότας και βάλουμε διάστημα Τότε παίζει παύση Με το διαιρέτη @ Αν υπάρχει
          'Για να παίξουμε τη κάθε φωνή αρκεί να δώσουμε μια εντολή Παιξε Η Play
          'όπου συνδιάζουμε φωνή και όργανο
          'Η Παιξε 0 κλείνει την μουσική.
          'Η Ενταση αλλάζει την Ενταση του ήχου συνολικά.
          'Η Επιλεξε.Οργανο δίνει το νούμερο στο όργανο που θα επιλέξουμε από μια λίστα οργάνων
          'Για να το χρησιμοποιήσουμε στην Παιξε (το διαβάζουμε με την Επιλογη)
         
Προσθήκη 13-4-2019
Η τρέχουσα έκδοση είναι η 9.8 (αναθεώρηση 17)
Από την αρχική Μ2000 έχει αφαιρεθεί ο προεπεξεργαστής με εντολές που ξεκίναγαν στην γραμμή με το σύμβολο #. Όλες οι άλλες εντολές εκτελούνται όπως είχαν σχεδιαστεί, και εμπλουτίστικαν στην πορεία.

Η γλώσσα είναι σε μια όριμη φάση, και το μόνο που σκέφτομαι να κάνω μέσα στο υπόλοιπο 2019, αν τα καταφέρω, είναι να φτιάξω έναν AST interpreter, που σημαίνει ότι θα σκανάρεται το κείμενο και θα δημιουργείται ένα δένδρο το οποίο αυτό θα εκτελείται. Υποτίθεται ότι θα κερδίσω σε ταχύτητα, αφού δεν θα χρειάζεται σε μια επανάληψη να διαβάζονται σταθερές αριθμητικές, και επίσης όλες οι δομές ροής θα είναι ενσωματομένες στο δέντρο (ως επιλογές κατά δεξιό ή αριστερό κλάδο). Προς το παρόν η γλώσσα είναι γραμμένη με συναρτήσεις, που δέχονται ένα αντικείμενο εκτέλεσης (ένας δείκτης σε αυτό), και ένας δείκτης σε ένα αλφαριθμητικό, το οποίο συνέχεια καταναλώνεται, δηλαδή κώδικας που διαβάζεται αφαιρείται. Ορισμένες φορές κοιτάει μπροστά ο διερμηνευτής και παίρνει αντίγραφο και το εκτελεί. Πχ σε μια Για Επόμενο, παίρνει αντίγραφο των εντολών ανάμεσα και στέλνει από αυτά ένα αντίγραφο για εκτέλεση για κάθε βήμα της επανάληψης. Η εκτέλεση είναι γρήγορη, γιατί αφενός ο εκτελεστής έχει μεταφραστεί από την Visual Basic 6 σε γρήγορη γλώσσα μηχανής και αφετέρου, ο κώδικας βρίσκεται σε μικρότερο αλφαριθμητικό και μπορεί να δουλευτεί γρήγορα στην γρήγορη μνήμη του επεξεργαστή.

Σκοπός της γλώσσας δεν είναι ο παραγωγικός κώδικας, δηλαδή να φτιάξουμε επαγγελματικές εφαρμογές. Για το σκοπό αυτό η ταχύτητα δεν είναι προτεραιότητα για τη Μ2000. Πολλές φορές δεν χρειαζόμαστε τον γρήγορο κώδικα, αλλά γρήγορες εντολές που έχει η γλώσσα, όπως για παράδειγμα την περιστροφή εικόνων, ή τη χρήση λιστών με συνάρτηση κατακερματισμού (Hash). Επειδή η εφαρμογή του διερμηνευτή τρέχει σε παραθυρικό περιβάλλον, δηλαδή όπως και να έχει τρέχει το σύστημα παραθύρων (άρα και το message loop), γίνεται πάντα διαχείριση μηνυμάτων. Αυτό από μόνο του είναι μια καθυστέρηση για το σύστημα. Όμως έχει και τα καλά του, επειδή μπορούμε να φτιάχνουμε δικά μας παράθυρα χρήση (φόρμες χρήστη) και να χρησιμοποιούμε στοιχεία ελέγχου.

Οι φόρμες χρήστη χρησιμοποιούν ένα συγκεκριμένο (φτιαγμένο από μένα) στοιχείο ελέγχου, το οποίο παίρνει διάφορες διαμορφώσεις. Η βασική του λειτουργία είναι του listbox, αλλά μέσω άλλων κλάσεων που το έχουν ως βάση, και διαβάζουν τα γεγονότα του, το διαμορφώνουν διαφορετικά.
Για παράδειγμα υπάρχει το στοιχείο Κείμενο ή Editbox το οποίο εμφανίζει ένα στοιχείο για να γράφουμε κείμενο σε πολλές γραμμές, έχει πολλές ιδιότητες, μια εκ των οποίων είναι ο χρωματισμός κειμένου. Όλα τα στοιχεία ελέγχου προγραμματίζονται με εντολές της Μ2000, τόσο για την σχεδίαση, όσο και για την λειτουργία.

Αν και η γλώσσα χρησιμοποιεί το μπλοκ κώδικα με αγκύλες, στην έκδοση 9 έχουν μπει οι δομές επανάληψης χωρίς τις αγκύλες.καθώς και η δομή Αν.
Έχει αναφερθεί παραπάνω η χρήση του & για πέρασμα με αναφορά. Αυτό που πρέπει να γίνει κατανοητό είναι ότι αν κάτι χρειάζεται να περαστεί με αναφορά πρέπει να περαστεί με αναφορά, σε αντίθεση με μερικές γλώσσες που ακόμα και το πέρασμα με τιμή δύναται να περαστεί εκεί που ζητάμε με αναφορά (πχ γίνεται στην Visual Basic, να ορίσουμε ByValue πριν την μεταβλητή, ή να δώσουμε έκφραση, άρα να μπει ByValue αυτόματα). Στη Μ2000 αν ζητάμε κάτι με αναφορά θα πρέπει να το περάσουμε με αναφορά.

Υπάρχει παράδειγμα όπου φτιάχνουμε ένα dll σε c, καλώντας τον gcc compiler, και στο ίδιο πρόγραμμα φορτώνουμε το dll και το συνδέουμε σε συνάρτηση χρήση (user function) η οποία παίρνει παραμέτρους και καλεί τη συνάρτηση στο dll όπως ορίσαμε, και μας γυρνάει το αποτέλεσμα.

Επίσης μπορούμε να δημιουργούμε αντικείμενα τύπου COM αν είναι καταχωρημένα στο registry των Windows, και είναι για δημόσια χρήση. Υπάρχει πρόγραμμα που στέλνει κείμενο στο αντικείμενο SAPI (speech API) και αυτό όχι μόνο διαβάζει το κείμενο, αλλά μας ενημερώνει με γεγονότα που έχουμε ορίσει ότι θα παίρνουμε, για κάθε λέξη που λέει, και έτσι το πρόγραμμα εμφανίζει ότι "μιλάει" το πρόγραμμα στο ρυθμό που μιλάει!

Στα αντικείμενα COM ανοίκει και το Office, και μπορούμε όχι μόνο να ανοίξουμε το Word αλλά και να δημιουργήσουμε κείμενο και να γράφει η Μ2000 σε αυτό. Μπορούμε να χειριστούμε και γεγονότα από το Word.

Υπάρχουν γλώσσες που κάνουν όλα αυτά, όπως η Python. Η διαφορά εδώ είναι ότι έχουμε ένα περιβάλλον που τα έχει όλα μέσα. Κάτι παρόμοιο λέει και η Python, αλλά ουσιαστικά χρειάζεται κάποιος να συμπεριλάβει πακέτα, και εδώ υπάρχουν πακέτα για ίδιες δουλείες με διαφορετικό τρόπο, δηλαδλη υπάρχει μια "πολυγλωσσία" η οποία αυξάνει την απαότηση για γνώση. Η Μ2000 κρατάει μικρότερο ποσό γνώσης που χρειάζεται κανείς για να την μάθει. Είναι προβλέψιμη γλώσσα.

Κύρια χαρακτηριστικά  της Μ2000 που βοηθούν τον εκπαιδευόμενο είναι τα παρακάτω:

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

Στο πρόγραμμα εγκατάστασης υπάρχει το info.gsb, ένα αρχείο με τμήματα (το καθένα είναι και ένα πρόγραμμα) το οποίο αποτελείται από 12310 γραμμές κώδικα. Μέσα σε αυτό υπάρχει το τμήμα meditor ο οποίος είναι ένα παραθυρικός διορθωτής προγράμματος της Μ2000 (γραμμένος στη Μ2000), όπου γράφουμε το πρόγραμμά μας και το εκτελούμε σε έναν νέο διερμηνευτή που φορτώνει αυτόματα το πρόγραμμα δίνοντας το αρχείο με κατάλληξη gsb για εκτέλεση. Ο διερμηνευτής μπορεί να εκτελείται πολλές φορές, δηλαδή να εκτελούμε στον ίδιον υπολογιστή πολλά προγράμματα σε Μ2000 κώδικα.

Για να μεταφέρουμε το πρόγραμμa info.gsb στον φάκελο χρήση υπάρχουν οδηγίες στο readme.txt, το οποίο φαίνεται και κατά την εγκατάσταση, και οι οποίες αντιγράφονται εδώ:
dir appdir$
load info
then press F1 to save info.gsb to M2000 user directory

Αλλάζουμε τον τρέχον φάκελο στο φάκελο της εφαρμογής του διερμηνευτή, φορτώνουμε το info.gsb το οποίο εκτελεί άμεσα ένα τμήμα και ρυθμίζει τα πλήκτρα λειτουργιών ή Function Keys του πληκτρολογίου. Με το F1 (βάσει του προγραμματισμού που κάνει το info) κάνουμε άμεσα αλλαγή καταλόγου στον κατάλογο του χρήστη και σώνει το πρόγραμμα εκ νέου, μαζί με την εντολή εκτέλεσης. Αν ανοίξουμε έναν δεύτερο διερμηνευτή της Μ2000 αρκεί να γράψουμε Φόρτωσε info ή Load info και θα φορτωθούν οι 12k+ γραμμές άμεσα.

Κάτι παρόμοιο θα ήθελα και για την Python, να μπορώ να έχω σε ένα περιβάλλον διαδραστικό, φορτωμένα δυο ή περισσότερα προγράμματα και να μπορώ να αλλάζω το κώδικα και να τα εκτελώ άμεσα. Για να κάνει κανείς κάτι τέτοιο πρέπει να χρησιμοποιήσει κάποιο IDE, πχ το PyCharm, το οποίο όμως κάθε φορά εκτελεί το κώδικα σαν να είναι η πρώτη φορά. Η διαφορά με το περιβάλλον της Μ2000 είναι ότι μπορούμε να έχουμε γενικές μεταβλητές, δηλαδή να έχουμε σώσει κάποια κατάσταση, καθώς επίσης και στατικές μεταβλητές στις οποίες τμήματα και συναρτήσεις μπορούν να έχουν σώσει κάποια κατάσταση και να την χρησιμοποιήσουν στην επόμενη κλήση. Αν και η χρήση των γενικών μεταβλητών είναι "προβληματική" στο προγραμματισμό εντούτοις είναι χρήσιμη κατά την διαδικασία ελέγχου για τους εκπαιδευόμενους. Πχ θέλει κάποιος να μετρήσει πόσες φορές περνάει από ένα σημείο το πρόγραμμα. Αρκεί να φτιάξει πριν την κλήση του προγράμματος (το οποίο έχει φορτωθεί) μια γενική μεταβλητή έστω Κ και να βάλει στο κώδικα εκεί που θέλει το Κ++ το οποίο το αυξάνει κατά ένα. Με την έξοδο από το πρόγραμμα γράφει το Τύπωσε Κ ή ? Κ  (το ? είναι το Τύπωσε)  και εμφανίζει την τιμή άμεσα. Με τη ΓΛΩΣΣΑ της Γ' Λυκείου δεν μπορεί να γίνει η μέτρηση, γιατί δεν υπάρχουν γενικές μεταβλητές που να έχουν πρόσβαση τα υποπρογράμματα, και θα πρέπει να οριστεί στο κύριο σώμα, να υπάρχει η Γράψε (η αντίστοιχη της Τύπωσε) στο ίδιο πρόγραμμα, και όπου καλούμε το υποπρόγραμμα πρέπει να περνάμε την μεταβλητή ως παράμετρο. Δηλαδή πολύ δουλειά για μια απλή εισαγωγή του Κ++.

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

Συνεχίζεται...








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

Στην έκδοση 10 της Μ2000 τα ανιικείμενα τύπου Ομάδα έχουν ολοκληρωθεί και μπορούν να έχουν τύπους, να υπάρχουν ως μεταβλητές (Επώνυμα αντικείμενα) συνδεδεμένες με το τμήμα ή τη συνάρτηση που δημιουργούνται γι όσο το τμήμα ή η συνάρτηση δεν τερματίζει,  να υπάρχουν σε πίνακες και άλλα αντικείμενα καταχώρησης (οπότε και διαγράφονται αν αλλάξουμε τιμή - άλλη ομάδα, ή αν σβήσουμε τον καταχωρητή), να υπάρχουν μέσω δεικτών. Οι δείκτες σε ομάδες μπορούν ή να δείχνουν ένα επωνυμο αντικείμενο (στην ουσία εσωτερικά είναι ισχνή αναφορά στο αντικείμενο) ή να δείχνουν αντικείμενο όπου η ζωή του αντικειμένου χάνεται όταν χαθεί και ο τελευταίος δείκτης. Μπορούμε να έχουμε συνάρτηση Διαγραφή που καλείται όταν το αντικείμενο πρέπει να διαγραφεί. Επίσης μπορούμε να έχουμε ομάδες εντός ομάδων, ιδιότητες, τελεστές, και να ορίσουμε πως μια ομάδα επιστρέφει τιμή (και όχι αντίγραφο του εαυτού της) και πώς δέχεται τιμή (και όχι την διαδικασία συγχώνευσης που εξορισμού έχουν οι ομάδες). Η διαδικασία συγχώνευσης Α+Β δίνει μια νέα ομάδα με αλλαγμένες τιμές στις ιδιότητες που έχει η Α και η Β με τιμές της Β και επιπλέον δίνει ότι δεν είναι κοινό στις Α και Β. Έτσι το Α=Α+Β δίνει ένα Α με ότι έχει το Β και ότι δεν έχει το Β αλλά υπάρχει στο Α. Οι ιδιότητες ορίζονται ως ομάδες που επιστρέφουν ή παίρνουν τιμές ή κάνουν και τα δύο. Μπορούμε να έχουμε πεδία (μεταβλητές, πίνακες, άλλα αντικείμενα) ιδιωτικά ή δημόσια. Μια Κλάση είναι ο ορισμός μιας ομάδας ως μια συνάρτηση που επιστρέφει μια ομάδα. Μπορούμε να ορίσουμε κλάσεις να γίνονται από άλλες κλάσεις. Τα ονόματα των κλάσεων που δημιουργούν μια ομάδα είναι τύποι της ομάδας. Μια Ομάδα μπορεί να περαστεί σε κλήση με τιμή (αντίγραφο) ή με αναφορά ή με δείκτη  σε ομάδα ή με αναφορά ενός δείκτη σε ομάδα. Δημιουργούμε ομάδες από κλάσεις ή από άλλες ομάδες. Αν Α είναι μια επώνυμη ομάδα (δημιουργήθηκε σαν τοπική μεταβλητή σε τμήμα ή συνάρτηση) τότε αν Β είναι ένα νέο όνομα τότε το Β=Α δημιουργεί το Β ως αντίγραφο το Α. Αν δώσουμε αργότερα πάλι το Β=Α τότε το Β θα πάρει τις τιμές του Α. Μπορούμε να αλλάξουμε τον τελεστή "=" ως πως  το λειτουργεί στην εκχώρηση. Αν Α είναι μια ομάδα τότε το Κ->Α δημιουργεί έναν δείκτη στο Α (ισχή αναφορά). Μπορούμε να αλλάξουμε το Κ να δείχνει άλλη ομάδα (ακόμα και άλλο τύπο), είτε είναι επώνυμη είτε πτητική (πτητικό είναι το αντικείμενο που δεν σχετίζεται με κάποιο τμήμα ή κάποια συνάρτηση, αλλά βρίσκεται σε καταχωρητές όπως πίανκες, λίστες, ουρές σωρούς τιμών, ή απλά δημιουργήθηκαν άμεσα εκτός καταχωρητή. Αν το Αλφα() είναι συνάρτηση που επιστρέφει πτητική ομάδα (δηλαδή υπάρχει το Κλάση Αλφα { }) τότε το Μ->Αλφα() φτιάχνει άμεσα ένα αντικείμενο Άλφα και δίνει ένα δείκτη στο Μ. Το M->Τίποτα ελευθερώνει το Μ και αν δεν υπάρχει άλλος δείκτης στο αντικείμενο τότε διαγράφει το αντικείμενο. Αν Χ είναι ιδιότητα του Αλφα τότε το Μ=>Χ είναι η τιμή της ιδιότητας X (αν επιστρέφει τιμή). Αν το Α είναι νέο όνομα τότε το Α=Αλφα() φτιάχνει το επώνυμο αντικείμενο Α και η Α.Χ είναι η ιδιότητα Χ του Α. Έτσι αναγνωρίζουμε στο κώδικα πότε μια μεταβλητή είναι δείκτης σε αντικείμενο (Μ=>Χ)  και πότε είναι το αντικείμενο (Α.Χ).


Το πρόγραμμα παρακάτω ήταν μια αρχική ιδέα για το πώς θα βάλω τα αντικείμενα στη Μ2000.

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

Έγιναν αλλαγές για να τρέχει στην έκδοση 8.6 αναθεώρηση 6 για να γυρίσει η συμβατότητα ως είχε
Το γράφουμε σε ένα τμήμα έστω Α

Τμημα ΕΝΑΕΠΙΠΕΔΟ {
                Τμημα ΕΝΑΕΠΙΠΕΔΟΚΑΤΩ {
                      ' Όταν τρέχει ένα τμήμα το περιβάλλον της Μ2000 αντιγράφει το κείμενό του σε ένα και μόνο αλφαριθμητικό!
                      ' Σε αυτό αφαιρούνται οι εντολές που έτρεξαν. Σε περίπτωση επανάληψης το κομάτι έχει κρατηθεί για το σκοπό αυτό
                      ' Μπορούμε όμως να δώσουμε με την  Ενθεση άμεσα κώδικα για τρέξιμο
                      ' Θα φτιάξω μια κλάση με μια μεταβλητή που θα βλέπουν όλες
                      ' καθώς και ένα πρότυπο με το οποίο θα κατασκευάζω νέες παρουσίες
                      ' Θα χρησιμοποιώ τα @@ εντός του πρότυπου για να περνάω το όνομα
                      ' της νέας παρουσίας
                      ' φτιάχνω μια σφαιρική (τοπικά) μεταβλητή που μπορούν να την διαβάζουν και όλα τα τμήματα που θα τρέξουν εδώ!
                      'Στην 8.1 ήθελε αυτό: Γενική ΔΙΚΟΜΟΥ.ΓΕΝΙΚΟ = 1000
                      ΔΙΚΟΜΟΥ@ΓΕΝΙΚΟ = 1000
                      ΤΕΛΕΥΤΑΙΑ@ΚΛΑΣΗ$ = "" ' θα δημιουργούμε μια συνδεδεμένη λίστα και αυτή η μεταβλητή θα δείχνει τη κορυφή της λίστας
                      ' ακολουθεί μια μεταβλητή που παίρνει κείμενο, το οποίο όμως θα γίνει ο κατασκευαστής της κλάσης μας!
                      ΓΕΝΙΚΟ@ΠΡΩΤΟ$ = {
' το @ στο όνομα της μεταβλητής την κάνει σφαιρική μεταβλητή (κάτι ως FRIEND σε άλλες γλώσσες)
' και θα διαβάζεται όσο υπάρχει το τμήμα που την έφτιαξε
' και δεν θα φτιάξουμε τοπική μεταβλητή με το ίδιο όνομα (αν ξεχάσουμε να βάλουμε το @ στο όνομα όταν είναι αριστερά στο =)
' αλλιώς θα γίνει σκίαση...θα βρίσκει την τοπική και όχι την σφαιρική
ΒΑΛΕ ΤΜΗΜΑ$ ' βάζουμε στο σωρό το όνομα του τμήματος που θα κάτσει η παρουσία, του γονικού τμήματος
ΤΜΗΜΑ @@ ' εδώ έχουμε το όνομα της παρουσίας...θα το κάνουμε όνομα του τμήματος (με αλλαγή του @@ με το όνομα)
ΔΙΑΒΑΣΕ ΓΟΝΙΟΣ$ ' κρατάμε το όνομα του τμήματος στον ΓΟΝΙΟΣ$ η οποία είναι ιδιότητα του @@
ΕΠΟΜΕΝΗΚΛΑΣΗ$=ΤΕΛΕΥΤΑΙΑ.ΚΛΑΣΗ$ ' στην ιδιότητα ΕΠΟΜΕΝΗΚΛΑΣΗ$ βάζουμε την μέχρι τώρα κορυφή
ΤΕΛΕΥΤΑΙΑ@ΚΛΑΣΗ$="@@" 'και εδώ αλλάζουμε κορυφή, έτσι μόλις συνδέσαμε τη παρουσία @@
a=1 ' ακολουθούν τρεις ιδιότητες
b=2
n$="no man"
' ακολουθεί ένας πίνακας (από την έκδοση 6.1 έχουμε και αλλαγή διαστάσεων και μεγέθους με χρήση πάλι της DIM με το ίδιο όνομα
' ή ακόμα καλύτερα με πέρασμα αναφοράς σε συνάρτηση και εκεί αλλαγή μεγέθους ...π.χ. να πάρει ένα ακόμα στοιχείο!
ΠΙΝΑΚΑΣ a(10)
ΣΥΝΑΡΤΗΣΗ personal {
' Αυτή είναι η "προσωπική" συνάρτηση καλούμε συναρτήσεις με personal() χωρίς παράμετρο
' Στην Μ2000 τα ορίσματα των συναρτήσεων δεν είναι προκαθορισμένα! Μπορούμε να καλέσουμε
' τη συνάρτηση με ότι ορίσματα θέλουμε. Αρκεί να έχουμε κανονίσει ένα τρόπο να τα διαβάζουμε.
' και παραπάνω να βάλουμε δεν πειράζει!
' Για κάθε παρουσία θα υπάρξει μια νέα συνάρτηση.
' η c είναι τοπική στη συνάρτηση, ΔΙΚΟΜΟΥ@ΓΕΝΙΚΟ είναι σφαιρική, την βλέπουν όλες οι παρουσίες
' @@.a και @@.bb είναι ιδιότητες της κλάσης και πρέπει να γίνει αναφορά με το όνομα της παρουσίας
' εδώ δεν το γνωρίζουμε επειδή είναι το πρότυπο.
c=12
ΔΙΚΟΜΟΥ.ΓΕΝΙΚΟ++ \\έβγαλα το @ γιατί δίνει λάθος στην 8
\\ ΔΙΚΟΜΟΥ@ΓΕΝΙΚΟ++ ' από την έκδοση 6.3 έχω βάλει τα ++ -- += -= /= και *= για μεταβλητές (όχι για στοιχεία πινάκων)
'ΔΙΚΟΜΟΥ@ΓΕΝΙΚΟ=ΔΙΚΟΜΟΥ@ΓΕΝΙΚΟ+1
' η συνάρτηση δεν έχει "return" για επιστροφή τιμής αλλά = και η επιστροφή γίνεται στην αγκύλη τέλους.
=(@@.a+@@.b)*ΔΙΚΟΜΟΥ.ΓΕΝΙΚΟ+c ' στο δεξί μέρος η σφαιρική μεταβλητή μπορεί να γραφεί και με τελεία στη θέση του @
}
ΤΜΗΜΑ ΓΟΝΙΟΣ$ 'στο τέλος του πρότυπου επαναφέρουμε το όνομα του τμήματος σε αυτό του γονικού.
'πάνω σε αυτήν την δυνατότητα στήριξα όλο αυτό!
}
                      ' τώρα θα δώσουμε συναρτήσεις που θα έχουν να κάνουν με οποιαδήποτε παρουσία της κλάσης. Για να κάνουμε δοκιμές!
                      ' θα πρέπει να δίνουμε το όνομα σε αλφαριθμητικό και είναι λογικό αφού θα θέλουμε να έχουμε μια λίστα με ονόματα παρουσιών
          
                      Τμημα ΕΜΕΝΑ.ΘΕΣΕ {
                            Διαβασε ΟΝΟΜΑΠΑΡΟΥΣΙΑΣ$ : Τμημα ΟΝΟΜΑΠΑΡΟΥΣΙΑΣ$
                                  ' διαβάζουμε το όνομα παρουσίας και το κάνουμε όνομα τμήματος (namespace)
                            Διαβασε a, b, n$ ' διαβάζουμε απ΄ευθείας από το σωρό και τοποθετούμε τιμές στις ιδιότητες a, b, n$
                                                          'υποθέτουμε ότι θα στέλνουμε τιμές για αυτές τις ιδιότητες.
                            Τμημα ΓΟΝΙΟΣ$ ' επαναφέρουμε το όνομα του τμήματος με το όνομα του γονικού (να γιατί το κρατήσαμε)
                      }
                      Τμημα ΕΜΕΝΑ.ΤΥΠΩΣΕ {
                            Διαβασε ΟΝΟΜΑΠΑΡΟΥΣΙΑΣ$ : Τμημα ΟΝΟΜΑΠΑΡΟΥΣΙΑΣ$
                            Print a, b, n$ ' εδώ τυπώνουμε τις ιδιότητες (στις κλάσεις οι μεταβλητές που ανήκουν σε παρουσίες και έχουμε εξωτερική
                                                          ' πρόσβαση λέγονται ιδιότητες
                            Module ΓΟΝΙΟΣ$
                      }
                      ' Άρα μέχρι εδώ έχουμε φτιάξει πρότυπο, σφαιρικές μεταβλητές, μια για παράδειγμα και μια για λειτουργία λίστας
                      ' Και έχουμε φτιάξει μια συνάρτηση (μέθοδο της κλάσης) για την κάθε παρουσία ξεχωριστά και
                      ' δυο τμήματα, το ένα βάζει τιμές, το άλλο τυπώνει, για όλες τις παρουσίες της κλάσης.
          
                      ' Από εδώ ξεκινούν τα μαγικά!
                      ' Φτιάχνουμε ένα αλφαριθμητικό το οποίο θα μπει με μια ΕΝΘΕΣΗ (ένθεση κώδικα) τέσσερις φορές, μία για κάθε παρουσία
                      ' Το αλφαριθμητικό αυτό περιέχει μια εντολή ΕΝΘΕΣΗ που βάζει το αποτέλεσμα μιας Αλλαγη$( η οποία αλλάζει τα @@ με το ΝΑΗΚΛΑΣΗΜΟΥ$
                      ' στο πρότυπο ΓΕΝΙΚΟ@ΠΡΩΤΟ$
                      ' Έτσι μέσα στο Για {} θα έρθει και θα τρέξει τέσσερις φορές το πρότυπο με το σωστό όνομα παρουσίας,
                        ' Και θα αφήσει μεταβλητές Και συναρτήσεις.
                      ' θα μπορούσα να δώσω απευθείας το Ενθεση Αλλαγη$("@@",ΟΝΟΜΑΠΑΡΟΥΣΙΑΣ$,ΓΕΝΙΚΟ@ΠΡΩΤΟ$ ) αλλά ήθελα να φανεί το όνομα της κλάσης!
                      
                      ΝΑΗΚΛΑΣΗΜΟΥ$ = {Ενθεση Αλλαγη$("@@", ΟΝΟΜΑΠΑΡΟΥΣΙΑΣ$, ΓΕΝΙΚΟ@ΠΡΩΤΟ$ )}
                      Βαλε "ena", "allo", "ekeino", "kaiafto"
                      Για i = 1 Εως 4 {
                            Διαβασε ΟΝΟΜΑΠΑΡΟΥΣΙΑΣ$
                            Ενθεση ΝΑΗΚΛΑΣΗΜΟΥ$ 'καλούμε τον κατασκευαστή της κλάσης, βάζοντας κώδικα (στο αλφαριθμητικό που "τρέχει")!
                      }
                      ' τα μαγικά δεν σταματούν εδώ. Καθώς φτιάχνονταν τα παραπάνω...φτιάχνονταν και η συνδεδεμένη λίστα
                      ' Η οποία χρειάζεται για να αλλάξει την σειρά ή να διαγράψει κανείς κάποια παρουσία από τη σειρά!
                      ' Ας γεμίσουμε τις παρουσίες με στοιχεία (φαίνεται πως μπορούν να περάσουν και με Σειρα ή με Εισαγωγη από αρχείο!
                      ' Αυτός είναι ο Serialize τρόπος, ή σειριακός χειρισμός. Ο άλλος είναι να γίνεται ανά ιδιότητα το διάβασμα και το γράψιμο.
                      ΕΜΕΝΑ.ΘΕΣΕ "ena", 1, 2, "aaaaaaaa" 'οι τιμές πάνε στα αντικείμενα τα οποία περνάμε με όνομα
                      ΕΜΕΝΑ.ΘΕΣΕ "allo", 4, 5, "bbbbbbb" ' Η 6η έκδοση δεν γνωρίζει από κλάσεις!
                      ΕΜΕΝΑ.ΘΕΣΕ "ekeino", 7, 8, "ccccccccc"
                      ΕΜΕΝΑ.ΘΕΣΕ "kaiafto", 100, 120, "ok"
                      ' θα τυπώσω μόνο για το "ενα"
                      ΕΜΕΝΑ.ΤΥΠΩΣΕ "ena"
                      Τυπωσε "Τώρα όλα μαζί"
                      ' τώρα θα σβήσω το σωρό γιατί η Σειρα βάζει από το τέλος
                      Αδειασε ' αν και δεν περίμενα τίποτα εκεί, η καλή συνήθεια δεν βλάπτει!
                      Σειρα "ena", "allo", "ekeino", "kaiafto"
                      Για i = 1 Εως 4 {ΕΜΕΝΑ.ΤΥΠΩΣΕ }' δεν δίνω παράμετρο άμεσα στο Τμήμα, έχω δώσει στο σωρό.
                      ' χωρίς ΑΔΕΙΑΣΜΑ με την flush ή Αδειασε
                      Βαλε "kaiafto", "ekeino", "allo", "ena" ' με την ανάποδη σειρά ΤΕΛΕΥΤΑΙΟ ΜΠΑΙΝΕΙ ΠΡΩΤΟ ΒΓΑΙΝΕΙ (LIFO)
                      Για i = 1 Εως 4 {ΕΜΕΝΑ.ΤΥΠΩΣΕ }' πάλι ξανά
          
                      ' Ανά ιδιότητα χειρισμός:
                      ena.a( 4 ) = 1000 ' γράφουμε στον πίνακα του ena
                      Τυπωσε "ena.a(4)=" ; ena.a( 4 ) ' τυπώνουμε από τον πίνακα
                      ' θα καλέσουμε την συνάρτηση της ena τρεις φορές.
                      Για i = 1 Εως 3 {
                            Τυπωσε "ena.ΠΡΟΣΩΠΙΚΗ()=" ; ena.personal( ) ' η οποία χρησιμοποιεί ιδιότητες, σφαιρική μεταβλητή και τοπικές μεταβλητές.
                      }
                      ' Αλλάζω με σειριακό χειρισμό
                      ΕΜΕΝΑ.ΘΕΣΕ "allo", 1000, 2000, "George"
                      Τυπωσε "allo.n$=" ; allo.n$ ' ενώ διαβάζω με χειρισμό ανά ιδιότητα
                      Τυπωσε "allo.ΠΡΟΣΩΠΙΚΗ()=" ; allo.personal( ) ' εδώ καλώ την μέθοδο
                      kaiafto.a( 6 ) = 4
                      ' Πάμε στο τελευταίο μέρος των μαγικών όπου θα δούμε όλες τις παρουσίες
                      ' με γνώση μόνο ενός αντικειμένου, αυτού που είναι στην κορυφή στην ΤΕΛΕΥΤΑΙΑ@ΚΛΑΣΗ$
          
                      ' Θα ξαναφτιάξουμε ένα κώδικα σε αλφαριθμητικό, επειδή θέλουμε να τον καλέσουμε χωρίς να είναι σε τμήμα.
                      ' Γιατί όλες οι παρουσίες μας ανήκουν σε αυτό το τμήμα και κάθε Ενθεση βάζει κώδικα γι΄αυτό το τμήμα!
                      ' Επιπλέον θέλουμε να προσθέσουμε συνάμα και μια νέα ιδιότητα την check
                      ' η οποία θα έχει ρόλο σε αυτό τον κώδικα. θα καλέσουμε τον ίδιο κώδικα δυο φορές.
                      ' Την πρώτη φορά θα φτιάξει την ιδιότητα και θα τυπώσει όλα τις παρουσίες
                      ' Μετά θα αλλάξουμε μόνο την ιδιότητα σε μια συγκεκριμένη παρουσία.
                      ' Θα ξανά τρέξουμε τον ίδιο κώδικα και τώρα η ιδιότητα θα αλλάξει το τρόπο εμφάνισης αποτελεσμάτων!
                      ' Θα εξαιρέσει την παρουσία εκείνη για την οποία αλλάξαμε την ιδιότητα check.
          
                      ΣυνδεδεμενηΛιστα$ = {
' έχουμε βάλει στο σωρό την κορυφή της λίστας
Επαναλαβε {
Τμημα Γραμμα$ 'καθορίζουμε το όνομα του τμήματος (η letter$ ή Γραμμα$ σηκώνει το αλφαριθμητικό από τον σωρό)
' δείτε πως η αλλαγή έγινε μέσα το repeat για να γλιτώσουμε μια εντολή!
' Κοιτάμε με την valid() ή ΕΓΚΥΡΟ() αν υπάρχει η check, αν όχι τότε την φτιάχνουμε και βάζουμε τιμή
' αυτή θα φτιαχτεί για τον χώρο ονόματος module$ (μπορούμε να το διαβάσουμε σε αυτήν την μεταβλητή)
' ο οποίος είναι αυτό που περάσαμε παραπάνω στην module
Αν Οχι Εγκυρο(check) Τοτε check=Αληθης
Αν check Τοτε { ' τώρα θα υπάρχει η check
Τυπωσε "Αντικείμενο:";Τμημα$ ,, ' τυπώνουμε όνομα
Τυπωσε ">>>>>>>>>>>>>>>>";n$,, ' και ένα στοιχείο, για γούστο!
}
Βαλε ΕΠΟΜΕΝΗΚΛΑΣΗ$ ' Είχαμε κρατήσει όμως την επόμενη παρουσία και την βάζουμε στο σωρό (για να διαβαστεί από την Γραμμα$)
} Μεχρι ΕΠΟΜΕΝΗΚΛΑΣΗ$="" ' συνεχίζουμε μέχρι το τέλος όπου δεν υπάρχει επόμενη παρουσία.
Διαβασε ΑΔΕΙΟ$ ' πετάμε το "", ' μπορούμε να αδειάσουμε το σωρό FLUSH ΑΔΕΙΑΣΕ
Τυπωσε "Όνομα Τμήματος:";Τμημα$ ' εδώ έχει γυρίσει το όνομα στο σωστό χωρίς να δώσουμε εντολή!
' αυτό συμβαίνει γιατί με το πέρας της repeat το όνομα επανήλθε

}
                      Βαλε ΤΕΛΕΥΤΑΙΑ.ΚΛΑΣΗ$ ' Αυτό είναι το "ena"
                      Ενθεση ΣυνδεδεμενηΛιστα$ ' μπαίνει ο κώδικας και εκτελείται
                                              'υπενθυμίζω δεν μπαίνει σε αυτό το αρχείο αλλά στη "θέση" όπου έχει αντιγραφεί το αρχείο και μεταφράζεται
                                              ' η ένθεση γίνεται στο χώρο της μετάφρασης όχι σε αυτόν της αποθήκευσης!
                                              ' τώρα αλλάζουμε με ανά ιδιότητα χειρισμό την νέα ιδιότητα check
                      ekeino@check = Ψευδης
                      ' και ξανά τρέχουμε την "ανάγνωση συνδεδεμένης λίστας με περιορισμούς"
                      Βαλε ΤΕΛΕΥΤΑΙΑ.ΚΛΑΣΗ$
                      Ενθεση ΣυνδεδεμενηΛιστα$
                      ' και βλέπουμε πως το ekeino λείπει.
                      ' εδώ μπορούμε να δώσουμε μια Λιστα (list) και να μας δείξει ο μεταφραστής όλες τις μεταβλητές και τις ιδιότητες που έχουν "παρουσία"
                      ' μπορούμε να δώσουμε και την Τμηματα και να δούμε όλες τις μεθόδους που έχουν "παρουσία"
                      \ ΤΜΗΜΑΤΑ
                      ' εδώ η εσωτερική μεταβλητή μας δείχνει σε ποιό όνομα τμήματος βρισκόμαστε!
                      Τυπωσε "Όνομα Τμήματος:" ; Τμημα$
          
                      ' δεν μπορούμε να διαγράψουμε ένα αντικείμενο αλλά όλα θα διαγραφούν με το πέρας της παρουσίας αυτού του τμήματος!
                      ' ακριβώς τώρα
                      }
          ΕΝΑΕΠΙΠΕΔΟΚΑΤΩ ' εδώ καλούμε το τμήμα...(κλήση τμήματος μέσα σε τμήμα)
          }
          ΕΝΑΕΠΙΠΕΔΟ