Παρασκευή 29 Ιουνίου 2018

Revision 17 (Version 9.3) - Visitor Patern

Σε αυτή την αναθεώρηση έκανα μια προσθήκη στους δείκτες για ομάδες ώστε να μπορεί να λειτουργήσει και το παράδειγμα Visitor Pattern.
Το Visitor Pattern, εδώ κάνει την όλη δουλειά στο who.a.accept &this. Αυτό που αλλάζει είναι το a, που μπορεί να είναι literal ή Add, όπου και τα δύο έχουν την accept. Η accept προκαλεί την κλήση πάλι της visitor, στο αρχικό Parser, αλλά γίνεται έλεγχος του τύπου του αντικειμένου. Η Μ2000 δεν έχει τύπους στις ομάδες (όλα είναι ένας τύπος), αλλά μπορούμε να βάλουμε μια μεταβλητή και αυτή να δηλώνει τον τύπο, με έλεγχο που κάνουμε με την Valid() ή Έγκυρο().

Κάθε φορά λοιπόν που θέλει να "προβληθεί" (εδώ να γραφτεί στο  sb$  αλφαριθμητικό) ένα από τις δυο κλάσεις μας, θα καλέσει την visit και θα δώσει μια αναφορά σε αυτό, ώστε να υπάρχει τρόπος να πάρουμε περισσότερα στοιχεία. Έτσι η parser θα πάρει την τιμή του n και θα την γράψει στο sb$, αν η visit κλήθηκε από το accept της literal.

Πριν την προσθήκη λειτουργούσε μόνο με αναφορές:

Πρόγραμμα με χρήση αναφορών



Class literal {
      Iamliteral
      n
      module literal (.n) {}
      module accept(&visitor) {
            visitor.visit &this
      }
}
Class Add {
      Group a
      Group b
      module Add (.a, .b) {}
      module accept( &visitor) {
      visitor.visit &this
      }
}
M=Add(Add(literal(100), literal(200)), Add(Add(literal(100), literal(200)), Literal(50)))
Group Parser {
      sb$
      module visit (&who) {
            If valid(who.Iamliteral) then {
                 .sb$<=.sb$+Str$(who.n,"")
            } else {
                  .sb$<=.sb$+"("
                  who.a.accept &this
                  .sb$<=.sb$+"+"
                  who.b.accept &this
                  .sb$<=.sb$+")"
            }
      }
}
Parser.Visit &M
Print Parser.sb$


Δίνει αυτό:
((100+200)+((100+200)+50))

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

Στο who=>a=>accept m έχουμε δυο δείκτες, το whο και το a, οπότε για να βρούμε το a δίνουμε το who=>a, και μετά επειδή ζητάμε το visit του a δίνουμε ξανά το =>visit m,  ή όλο μαζί who=>a=>visit m


Class literal1 {
      Iamliteral
      n
      module literal1 (.n) {}
      module accept(visitor) {
            m->this
            visitor=>visit m
      }
}
Class Add1 {
      Group a
      Group b
      module Add1 (.a, .b) {}
      module accept( visitor) {
      m->this
      visitor=>visit m
      }
}
Function Literal(a) {->literal1(a)}
Function Add(a, b) {->Add1(a, b)}
M=Add(Add(literal(100), literal(200)), Add(Add(literal(100), literal(200)), Literal(50)))
Group Parser {
      sb$
      module visit (who) {
            If valid(who=>Iamliteral) then {
                 .sb$<=.sb$+Str$(who=>n,"")
            } else {
                  m->This
                  .sb$<=.sb$+"("
                  who=>a=>accept m
                  .sb$<=.sb$+"+"
                  who=>b=>accept m
                  .sb$<=.sb$+")"
            }
      }
}
Parser.Visit M
Print Parser.sb$


From version 10 we can use: If who is type literal1 then ....
We use operator:  is type  with the name of class. 

Τετάρτη 27 Ιουνίου 2018

Αναθεώρηση 16 (Έκδοση 9.3)

Διορθώθηκε η ανάγνωση αριθμού από Κατάσταση (Inventory) ώστε να γυρνάει ο τύπος αριθμού όπως καταχωρήθηκε.

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

Χρησιμοποιώ Decimal (Αριθμός) τύπο για να κρατήσω τα στοιχεία στη Κατάσταση.
  659034621587630041982498215

 
Inventory K=0:=0,1:=1
fib=Lambda K (x as decimal)-> {
      If Exist(K, x) Then =Eval(K) :Exit
      Def Ret as Decimal
      Ret=If(x>1->Lambda(x-1)+Lambda(x-2), x)
      Append K, x:=Ret
      =Ret
}
For i=1 to 139 {
      Print Fib(i)
}
\\ Write number to clipboard
clipboard str$(fib(139))


Και στα ελληνικά με παραλλαγή για να φτιάξουμε την εξαγωγή. Αλλάζουμε τα διαστήματα με το 160 που είναι το non brake space (και έτσι δεν εξαφανίζονται από το html)


Κατάσταση Κ=0:=0,1:=1
Φιμπ=Λάμδα Κ (χ ως Αριθμός)-> {
      Αν Υπάρχει(Κ, χ) Τότε =Εκφρ(Κ) :Έξοδος
      Κάνε Απάντηση ως Αριθμός
      Απάντηση=Αν(χ>1->Λάμδα(χ-1)+Λάμδα(χ-2), χ)
      Προσθήκη Κ, χ:=Απάντηση
      =Απάντηση
}
Έγγραφο Ε$
Για ι=0 έως 139 {
      Ε$=Αλλαγή$(" ", ΧαρΚωδ$(160),Μορφή$("{0:-10} {1::-40}",Μορφή$("Φιμπ({0}}",ι), Φιμπ(ι)))+{
      }
}

Πρόχειρο Ε$


  
   Φιμπ(0}                                        0
   Φιμπ(1}                                        1
   Φιμπ(2}                                        1
   Φιμπ(3}                                        2
   Φιμπ(4}                                        3
   Φιμπ(5}                                        5
   Φιμπ(6}                                        8
   Φιμπ(7}                                       13
   Φιμπ(8}                                       21
   Φιμπ(9}                                       34
  Φιμπ(10}                                       55
  Φιμπ(11}                                       89
  Φιμπ(12}                                      144
  Φιμπ(13}                                      233
  Φιμπ(14}                                      377
  Φιμπ(15}                                      610
  Φιμπ(16}                                      987
  Φιμπ(17}                                     1597
  Φιμπ(18}                                     2584
  Φιμπ(19}                                     4181
  Φιμπ(20}                                     6765
  Φιμπ(21}                                    10946
  Φιμπ(22}                                    17711
  Φιμπ(23}                                    28657
  Φιμπ(24}                                    46368
  Φιμπ(25}                                    75025
  Φιμπ(26}                                   121393
  Φιμπ(27}                                   196418
  Φιμπ(28}                                   317811
  Φιμπ(29}                                   514229
  Φιμπ(30}                                   832040
  Φιμπ(31}                                  1346269
  Φιμπ(32}                                  2178309
  Φιμπ(33}                                  3524578
  Φιμπ(34}                                  5702887
  Φιμπ(35}                                  9227465
  Φιμπ(36}                                 14930352
  Φιμπ(37}                                 24157817
  Φιμπ(38}                                 39088169
  Φιμπ(39}                                 63245986
  Φιμπ(40}                                102334155
  Φιμπ(41}                                165580141
  Φιμπ(42}                                267914296
  Φιμπ(43}                                433494437
  Φιμπ(44}                                701408733
  Φιμπ(45}                               1134903170
  Φιμπ(46}                               1836311903
  Φιμπ(47}                               2971215073
  Φιμπ(48}                               4807526976
  Φιμπ(49}                               7778742049
  Φιμπ(50}                              12586269025
  Φιμπ(51}                              20365011074
  Φιμπ(52}                              32951280099
  Φιμπ(53}                              53316291173
  Φιμπ(54}                              86267571272
  Φιμπ(55}                             139583862445
  Φιμπ(56}                             225851433717
  Φιμπ(57}                             365435296162
  Φιμπ(58}                             591286729879
  Φιμπ(59}                             956722026041
  Φιμπ(60}                            1548008755920
  Φιμπ(61}                            2504730781961
  Φιμπ(62}                            4052739537881
  Φιμπ(63}                            6557470319842
  Φιμπ(64}                           10610209857723
  Φιμπ(65}                           17167680177565
  Φιμπ(66}                           27777890035288
  Φιμπ(67}                           44945570212853
  Φιμπ(68}                           72723460248141
  Φιμπ(69}                          117669030460994
  Φιμπ(70}                          190392490709135
  Φιμπ(71}                          308061521170129
  Φιμπ(72}                          498454011879264
  Φιμπ(73}                          806515533049393
  Φιμπ(74}                         1304969544928657
  Φιμπ(75}                         2111485077978050
  Φιμπ(76}                         3416454622906707
  Φιμπ(77}                         5527939700884757
  Φιμπ(78}                         8944394323791464
  Φιμπ(79}                        14472334024676221
  Φιμπ(80}                        23416728348467685
  Φιμπ(81}                        37889062373143906
  Φιμπ(82}                        61305790721611591
  Φιμπ(83}                        99194853094755497
  Φιμπ(84}                       160500643816367088
  Φιμπ(85}                       259695496911122585
  Φιμπ(86}                       420196140727489673
  Φιμπ(87}                       679891637638612258
  Φιμπ(88}                      1100087778366101931
  Φιμπ(89}                      1779979416004714189
  Φιμπ(90}                      2880067194370816120
  Φιμπ(91}                      4660046610375530309
  Φιμπ(92}                      7540113804746346429
  Φιμπ(93}                     12200160415121876738
  Φιμπ(94}                     19740274219868223167
  Φιμπ(95}                     31940434634990099905
  Φιμπ(96}                     51680708854858323072
  Φιμπ(97}                     83621143489848422977
  Φιμπ(98}                    135301852344706746049
  Φιμπ(99}                    218922995834555169026
 Φιμπ(100}                    354224848179261915075
 Φιμπ(101}                    573147844013817084101
 Φιμπ(102}                    927372692193078999176
 Φιμπ(103}                   1500520536206896083277
 Φιμπ(104}                   2427893228399975082453
 Φιμπ(105}                   3928413764606871165730
 Φιμπ(106}                   6356306993006846248183
 Φιμπ(107}                  10284720757613717413913
 Φιμπ(108}                  16641027750620563662096
 Φιμπ(109}                  26925748508234281076009
 Φιμπ(110}                  43566776258854844738105
 Φιμπ(111}                  70492524767089125814114
 Φιμπ(112}                 114059301025943970552219
 Φιμπ(113}                 184551825793033096366333
 Φιμπ(114}                 298611126818977066918552
 Φιμπ(115}                 483162952612010163284885
 Φιμπ(116}                 781774079430987230203437
 Φιμπ(117}                1264937032042997393488322
 Φιμπ(118}                2046711111473984623691759
 Φιμπ(119}                3311648143516982017180081
 Φιμπ(120}                5358359254990966640871840
 Φιμπ(121}                8670007398507948658051921
 Φιμπ(122}               14028366653498915298923761
 Φιμπ(123}               22698374052006863956975682
 Φιμπ(124}               36726740705505779255899443
 Φιμπ(125}               59425114757512643212875125
 Φιμπ(126}               96151855463018422468774568
 Φιμπ(127}              155576970220531065681649693
 Φιμπ(128}              251728825683549488150424261
 Φιμπ(129}              407305795904080553832073954
 Φιμπ(130}              659034621587630041982498215
 Φιμπ(131}             1066340417491710595814572169
 Φιμπ(132}             1725375039079340637797070384
 Φιμπ(133}             2791715456571051233611642553
 Φιμπ(134}             4517090495650391871408712937
 Φιμπ(135}             7308805952221443105020355490
 Φιμπ(136}            11825896447871834976429068427
 Φιμπ(137}            19134702400093278081449423917
 Φιμπ(138}            30960598847965113057878492344
 Φιμπ(139}            50095301248058391139327916261

Δευτέρα 25 Ιουνίου 2018

Abstract Type Emulation in M2000

M2000 has no interfaces, but we can change definitions in groups for functions and modules, and we can declare them as final, so no more change allowed. So to implement an interface as an abstract type, we have to implement functions and modules with an Error statement (we can use a private module to return that error, and we can change the name of module, to return more info.

One type of inheritance comes from combining groups. Here class BaseState is a function which return a group with private members only, without special constructor. We call function AbstractOne which can take a group, or not (we check input with Match() function). First in AbstractOne a group created and then module with same name called, with one feature that other modules don't have, after return of the call nothing erased. But because this call happen inside function AbstractOne() we get a copy of group, and everything erased. So in first call, a group with a combination of two groups feed k, or to speak the truth, k created as the type of function commands, as a group.
If we call k.GetStrings$(), then This.Err called inside k.GetStrings$(). So we have to implement it, and we can do that using a Group command. As we see each member as module and function, get a Final clause to inform interpreter that these members can't changed anymore.
We have a read only property, Z, made it as a Group in a Group, and when we use K.Z in an expression then Value function called. Because an inner group has no direct view of parent's group members, we have to explicitly link parent member (value type, not module) with an new name (maybe the same name). In fact, Interpreter make a new identifier as a reference. We can do that for private variables too. So K.Z return value of K.Z1 which is private and we can't see from outside. Because we didn't make Set { } function for K.Z, and K.Z has Value {}, we can't change K.Z by assign a value. So K.Z is read only property.




Class BaseState {
Private:
      x as double=1212, z1 as currency=1000, k$="ok"
      Module Err {
                  Module "Class.BaseState"
                  Error "not implement yet"
      }      
}
Class AbstractOne {
Public:
      Group z {
            Value {
                  Link parent z1 to z1
                  =z1
            }
      }
      Function M(k as double) {
            .Err
      }
      Module AddCurrency (k as currency) {
            .Err
      }
      Function GetString$ {
            .Err
      }
Class:
      Module AbstractOne {
                  If Not Match("G") Then Exit
                  Read x
                  \\ combine x with This
                  This=x
      }
}
\\ create new group as K
K=AbstractOne(BaseState())
Try  ok {
      Print K.GetString$()
}
If Not ok Then Print Error$
\\ Now Add final functions/modules
Group k {
      Function Final M(k as double) {
            =.x*k
      }
      Module Final AddCurrency (k as currency) {
            .z1+=k
      }
      Function Final GetString$ {
            =.K$
      }       
}
Print k.M(100), k.GetString$()
K.AddCurrency 50.12
Def ExpType$(x)=Type$(x)
Print k.z=1050.12, ExpType$(k.z), Type$(k.z) ' true, Currency, Group
\\ Now combine AbstractOne without new BaseState
\\ but because all functions are final in k, nothing combined
k=AbstractOne()
Print k.M(100), k.GetString$()
For k {
      \\ we can use For Object {} and a dot before members to get access
      Print .z=1050.12, ExpType$(.z), Type$(.z) ' true, Currency, Group
}

Accumulator Factory Solution in M2000

From http://www.rosettacode.org/wiki/Accumulator_factory
This a a solution for Accumulator Factory.
From a Foo() we make a x() function, who holds an accumulator.
If we feed integer value we get as return value integer value. Because M2000 can use Double, Single (~ at the end, eg 12.23~), Decimal (12.12@), Currency (12.12#), Long (12&) and Integer (12%),  we can use any of it, and we take return value same as the input value (Functions in M2000 have master types, eg Numbers or Strings depends from $ in names to distinguish for string type, here in this example we have a string function as ExpType$()).





\\ M2000 Interpreter
\\ accumulator factory
foo=lambda (n as double) -> {
      =lambda n (x) -> {
            \\ x has no type here, can be any numeric type (also can be an object too)       
            \\ accumulator is double, and is a closure (a copy of n in foo)
            n+=x
            \\ any variable in M2000 hold  first type
            \\ if x is an object then we get error, except if object use this operator
            x=n
            \\ so we return x type
            =x
      }
}
x=foo(1)
call void x(5)
call void foo(3)
print x(2.3) \ 8.3

\\ We can add this code to check x() function for result type.

\\ Check Types of return value
\\ ExpType$() return string - is not a lambda function
x1=-x
Def ExpType$(x)=Type$(x)
\\ We can write this as lambda function: ExpType$=Lambda$ (x) -> Type$(x)
Print ExpType$(x(5&))="Long"
Print x(1)=14.3 ' True
Print ExpType$(x(2@))="Decimal"
Print x(1)=17.3 ' True
Print x1(0)=8.3 ' true
Print x1(0&)=8 ' true  ' because we set x as Long

\\ Second part. We make a Class function which is a function (a global one) which return a group (this group is not a pointer to group, is a group).
\\ x() and x1() return numeric value. Class Beta return what Value function define, and we want at x() the n+=x to add a numeric value to n.
\\ A class: label in group/class definition make any member to exist in first "named" group, and not in any copy of it. So module Beta, the constructor, exist only in Beta() class function, and not in Z group.


Class Beta {
private:
      m
public:
      Operator "+=" {
            .m+=number
      }
      Set (z) {
            .m<=z
      }
      Value {
            =.m
      }
Class:
      Module Beta (x) {
      \\ swapping variables we swap types too.
      swap x, .m
      }
}
z=Beta(5.2)
\\ so now z is an object, and we place an object instead of a numeric value
\\ group() return a copy of z. Normal a group return a copy, but we define a value function, so return a number
\\ but group() first check if z is a group, if not an error occur else return a nameless group with a copy of z
Print x(group(z))
z1=Beta(2.23#) ' so now z1 has a Currency type
x2=x ' we get a copy of lambda x, with a copy of n closure.
m=x(group(z1)) ' so x return a Currency too
Print Type$(m)="Currency", m =24.73# ' True
m1=x1(group(z))
Print Type$(m1)="Double", m1=13.5



Change lines with these lines to use event "Display", so each copy call the event from original named group, if exist.

Class Beta {
Event "display"
private:
      m
public:
      Operator "+=" {
            .m+=number
      }
      Set (z) {
             call event "display", .m, z
            .m<=z
      }
      Value {
            =.m
      }
Class:
      Module Beta (x) {
      \\ swapping variables we swap types too.
      swap x, .m
      }
}
Group WithEvents z=Beta(5.2)
Function z_display (new m, z) {
      Print format$("old value={0}, new value={1}", m, z)
}

Until here all groups are used as "values". We can define a pointer to z too, as pZ,
\\ check pointers too
pZ->Z
Z=500
Print x1(Group(pZ)) ' Also event fired here
Print EVal(pz)=Z
For pZ {This=1000} ' Also event fired here
Print Z=1000 ' true



Παρασκευή 22 Ιουνίου 2018

Module decoration and passing variables by name

In M2000 we can call modules (procedures with inner modules/functions/subs) using name only, or using Call and name. Using Call we can call itself. Using name only, we can't call itself but we can use decoration. A decoration is a mechanism to place modules inside a module before the calling. Each time we call a module, interpreter just get the code from a list and execute it. If a module placed as decoration in a module say Kappa then at execution of Kappa a module definition for this decoration skipped. 

In the example bellow we see that we can pass values using names, in any order. So in module Alfa we can use 1 and 2 to feed by value x and z, or we can use %z=1, %x=2 to feed z and x before calling Alfa, but these are local to Alfa.


Module Alfa (x, z) {
      Print "x=";x
      Print "z=";z
}

Alfa 1, 2
\\ By Name pass
Alfa %z=1, %x=2

Module Alfa (x as Integer, z as Double) {
      Print "x=";x,"  "+ Type$(x)
      Print "z=";z, "  "+Type$(z)
}

Alfa 1, 2
\\ By Name pass
Alfa %x=2, %z=1

Module Kappa {
      Module Beta {
            Print Stack.Size ' 2
            Drop 2
      }
      Beta 1, 2
      Beta %z=1, %x=2
}
Kappa
\\ Passing temporary module in place of other module
Print "Decorate Kappa using Beta as Alfa"
Kappa ; Beta as Alfa
Module Zeta (x , z) {
      Print "x=";x,"  "+ Type$(x)
      Print "z=";z, "  "+Type$(z)
}
Kappa ; Beta as Zeta
Kappa

Αναθεώρηση 14 (Έκδοση 9.3)

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

Στο παράδειγμα (έστω το έχουμε γράψει στο τμήμα Α, με την Σ Α ανοίγουμε το διορθωτή και αντιγράφουμε το παρακάτω και πατάμε Esc):

Ομάδα Α {
      Χ=10
      Πίνακας Μ(10)=4
}
Α=Α
Λίστα

Τρέχουμε το τμήμα με το Α και enter από τη γραμμή εντολών της Μ2000.
Η εντολή Λίστα πρέπει να εμφανίσει τρεις μεταβλητές, την Ομάδα Α.Α, το μέλος Α.Α.Χ = 10 και το Α.Α.Μ(10)
Η εντολή Λίστα δεν εμφανίζει ιδιωτικές μεταβλητές/πεδία των ομάδων. Εξ ορισμού τα μέλη μιας ομάδας είναι δημόσια.
Η εντολή Α=Α λέει να γίνει συγχώνευση του Α στο Α, και στην ουσία δίνει τις ίδιες τιμές στο Α. Με τις προηγούμενες αναθεωρήσεις, εμφανίζονταν δυο φορές τα Α.Α.Χ και τα Α.Α.Μ(), αν και ο διερμηνευτής χρησιμοποιούσε τις τελευταίες και για το λόγο αυτό δεν είχε πρόβλημα στην εκτέλεση. Το λάθος το βρήκα όταν έβαλα σε ένα παράδειγμα την εντολή Λίστα και είδα τα διπλά μέλη!

Το δεύτερο λάθος ήταν πιο δύσκολο: Έπρεπε να επαναφέρω μια λειτουργία που εμφανίστηκε στις αρχικές αναθεωρήσεις της έκδοσης 9.3 (Δείτε εδώ) και εδικότερα στο παρακάτω:
Group alfa {
      x=10
}
inventory beta="10":=alfa
Group n=beta("10")
Print n.x=10
Print beta("10").x=10
a->Beta("10")
for Beta("10") {
      Print .x=10
       a=>x++
      Print a=>x=11
}
a=>x+=100
Print a=>x=beta("10").x ' true
a=>x++
Print beta("10").x=112
beta("10").x++
Print beta("10").x=113
Print a=>x=113

Δεν είναι εύκολα κατανοητό το τι θέλει να δείξει το πρόγραμμα:
Ανοίγουμε το Beta("10") το οποίο είναι η ομάδα στη Κατάσταση Beta(), στο κλειδί "10". Η ομάδα είναι "κλειστή" και με την For (ή Για στα ελληνικά), έχουμε μια ανοιχτή ομάδα, με κρυφό όνομα, όπου το .x αναφέτεται στο μέλος x. Έχουμε ήδη φτιάξει το a ως δείκτης σε αυτή την κλειστή ομάδα. Όταν δίνουμε το a=>x++ ο διερμηνευτής πάει να ανοίξει το κλειστό αντικείμενο αλλά βλέπει ότι είναι ήδη ανοικτό, και αλλάζει την τιμή του x, και το αποθηκεύει κιόλας. Όταν τελειώνει το For {} θα αποθηκευτεί πάλι αλλά δεν μας πειράζει. Στην ουσία εμείς βλέπουμε ότι ο δείκτης a λειτούργησε. Στην πράξη υπήρχαν δυο αντικείμενα, το κλειστό και το ανοιχτό, αλλά στο κλειστό είχε γραφτεί το κρυφό όνομα του ανοιχτού και από εκεί το βρήκε το α=>χ++, όπως και το α=>x=11

Δουλεύει και έτσι:
 
Group alfa {
      x=10
}
inventory beta="10":=alfa
Group n=beta("10")
Print n.x=10
Print beta("10").x=10
a->Beta("10")
For Beta("10"), a {
      Print .x=10
      ..x++
      Print ..x=11
}
a=>x+=100
Print a=>x=beta("10").x ' true
a=>x++
Print beta("10").x=112
beta("10").x++
Print beta("10").x=113
Print a=>x=113


Δουλεύει και με υπορουτίνα:

Group alfa {
      x=10
}
inventory beta="10":=alfa
Group n=beta("10")
Print n.x=10
Print beta("10").x=10
a->Beta("10")
For Beta("10") {
      Print .x=10
      IncX(a)
}
a=>x+=100
Print a=>x=beta("10").x ' true
a=>x++
Print beta("10").x=112
beta("10").x++
Print beta("10").x=113
Print a=>x=113

Sub IncX(a)
      a=>x++
End Sub

Θα μπορούσαμε να γράψουμε τη ρουτίνα έτσι:

Sub IncX(a as pointer)
      a=>x++
End Sub

Στο παράδειγμα που ακολουθεί κάνουμε την IncX να πάρει λάθος αντικείμενο, να πάρει δείκτη έμμεσο, και δείκτη άμεσο. Ο έμμεσος δείκτης είναι στην ουσία ισχνή αναφορά. Όταν χρειάζεται να επιλύσει την ισχνή αναφορά ο διερμηνευτής θα δει αν υπάρχει τo k, και αν όχι θα βγάλει λάθος. Ο άμεσος δείκτης δείχνει πάντα κλειστό αντικείμενο (δεν έχει δηλαδή όνομα). Να θυμήσω εδώ ότι μπορεί να έχει τελικά όνομα το κλειστό αντικείμενο γιατί μπορεί ένας άλλος δείκτης σε αυτό να το έχει "ανοίξει" με κρυφό όνομα. Παρόλα αυτά και εδώ είναι που λύθηκε το λάθος, θα το "καταλάβει" ο διερμηνευτής και θα το χειριστεί κατάλληλα.
Για να δώσουμε από δείκτη αντίγραφο για συγχώνευση πρέπει να χρησιμοποιήσουμε τη συνάρτηση Ομάδα() ή Group()


Group k {
      x=10
}
Try ok {
      IncX(k)
}
If not ok then print Error$ ' Wrong object type
Z->k ' έμμεσος δείκτης επειδή το k είναι στατικό αντικείμενο
incX(Z)
Print Z=>x
Z->(k) ' κανονικός δείκτης επειδή το (k) είναι νέο αντικείμενο (Αντίγραφο του k)
incX(Z)
Print Z=>x
Print k.x = Z=>x-1 'Αληθές
k=Group(Z)
Print k.x = Z=>x ' Αληθές
\\ η Sub δουλεύει και ως Exit αν τη συναντήσει η ροή εκτέλεσης
Sub IncX(a as pointer)
      a=>x++
End Sub

Και με ελληνικές εντολές:

Ομάδα Κ {
      χ=10
}
Δες οκ {
      ΑύξησεΧ(Κ)
}
Αν όχι οκ Τότε Τύπωσε Λαθος$ 'Λάθος τύπος αντικειμένου
Ζ->Κ ' έμμεσος δείκτης επειδή το Κ είναι στατικό αντικείμενο
ΑύξησεΧ(Ζ)
Τύπωσε Ζ=>χ
Ζ->(Κ) ' κανονικός δείκτης επειδή το (Κ) είναι νέο αντικείμενο (Αντίγραφο του Κ)
ΑύξησεΧ(Ζ)
Τύπωσε Ζ=>χ
Τύπωσε Κ.χ = Ζ=>χ-1 'Αληθές
Κ=Ομάδα(Ζ)
Τύπωσε Κ.χ = Ζ=>χ ' Αληθές
\\ η Ρουτίνα δουλεύει και ως Έξοδος αν τη συναντήσει η ροή εκτέλεσης
Ρουτίνα ΑύξησεΧ(α ως δείκτης)
      α=>χ++
Τέλος Ρουτίνας