Skip to content

Dyalog Next Generation: Un-named Window Refs

Vector 20:4, page 98

user interfaces language design

Transcribed from the printed issue; not yet reviewed. Read it in the PDF of the issue, page 98

With version 9, besides variables, functions and operators, Dyalog had introduced a new data type: the object reference, known as “ref”.

Refs are pointers to namespaces and can be assigned, compared and formatted. So they behave in a very similar way to variables.

The result of formatting a ref is the name of the object, where the ref points to. If the result is identical with the full qualified name of the ref, the ref represents the object itself, a self reference.

Refs need not be references to named objects. Using ⎕NS'' refs to un-named objects can be generated. Un-named objects can never have a self reference. So, the formatted result of such an un-named ref looks like this:

      ⍕oRef←⎕NS''
#.[Namespace]

Instead of the object name, which cannot exist for un-named objects, the formatted result of an un-named ref is the path to its class (here: Namespace), distinguished by being enclosed in square brackets.

The structure type of object refs is native scalar and they may be composed to vectors, matrices, etc., among other structures. In accordance with the rules of array processing in APL, structures of refs are executed in parallel too:

      os←⎕NS¨4⍴⊂''
      os[1].F←+
      os[2].F←-
      os[3].F←×
      os[4].F←÷
      8 os.F ⍳4
9 6 24 2

      os[1 3].(F/⍳10)
55 3628800

Beginning with version 10 of Dyalog APL, now these un-named refs also act on Windows’ GUI classes, by an appended root method, realized as a dynamic function:

#.CreateObject←{⍺←⍎↑⎕NSI ⋄ ⍵{⍵{⍺{⍺}⍺.##.⎕EX'o'}'o'⍵.##.⎕WC ⍺}⍺.o←⍺.⎕NS''}

Syntactically the right hand side of #.CreateObject is identical to that from ⎕WC. The result from #.CreateObject, however, is an un-named object ref, or you might call it an instance of the class given by the Type property.

If the object ref does not get assigned, or when its assignment is deleted, the object instance will disappear.

Optionally a parent object ref might be given in the left argument:

      )CS #.Samples
#.Samples
      oForm   ←      #.CreateObject'Form'
      oButton←oForm #.CreateObject'Button'
      ⍕oForm
#.Samples.[Form]
      ⍕oButton
#.Samples.[Form].[Button]
      osObject←oForm oButton
      ⍕osObject
 #.Samples.[Form]  #.Samples.[Form].[Button]

In contrast to the conventional concept, un-named window refs have several advantages:

  • The interpreter no longer needs to analyse textual character strings to find the path to an object, and does not have to administer a name tree, both increasing its performance.
  • The graphical layout (skin), the underlying functionality (callbacks), and the localization (language), can be separated in a program more easily:
[0]   Localize Parms;osObject;Language
[1]   osObject Language←Parms
[2]   :Select Language
[3]   :Case 'ENG'
[4]       osObject.Caption←'Sample Form' 'Send'
[5]   :Case 'GER'
[6]       osObject.Caption←'Beispiel-Form' 'Senden'
[7]   :EndSelect

      Localize osObject 'GER'
  • Any desired number of instances, as necessary for MDIs or services, can be generated easily:
OneForm;oForm;oCloseFile;oShowEdit;oTestEdit;oTestButton
oForm oCloseFile oShowEdit oTestEdit oTestButton←1 1 0 1 1 1/CreateForm 1
oCloseFile.onSelect←'_onCloseFileSelect'(,oForm)
oShowEdit.onSelect←'_onShowEditSelect'
oTestEdit.onSelect←'_onTestEditSelect'(oForm oShowEdit)
oTestButton.onSelect←'_onTestButtonSelect'(oForm oShowEdit)
#.Wait

SixForms;osForm;osCloseFile;osCloseAllFile;osShowEdit;osTestEdit;osTestButton
osForm osCloseFile osCloseAllFile osShowEdit osTestEdit osTestButton←⊂[1]⊃CreateForm¨s6
osCloseFile.onSelect←(⊂'_onCloseFileSelect')∘,∘⊂∘,¨osForm
osCloseAllFile.onSelect←1
osShowEdit.onSelect←⊂'_onShowEditSelect'
osTestEdit.onSelect←(⊂'_onTestEditSelect')∘,∘⊂∘,¨osForm,¨osShowEdit
osTestButton.onSelect←(⊂'_onTestButtonSelect')∘,∘⊂∘,¨osForm,¨osShowEdit
#.Wait

The only disadvantage at the moment is the incomplete integration. So, the CreateObject method should exist in every class (might be called CreateChild?), and objects like FontObj, IconObj, SplitObj, should be assignable as refs. The current flaw of the monadic ⎕NS'' needs to be removed, to make it possible to duplicate instances simply by:

osObjects←⎕NS¨6⍴⊂osObject

The introduction of a method like Instantiate, instead of ⎕NS, and a property like Prototype, similar to Visible and Active set to zero, which would get reset by calling Instantiate, would be nice.

Even more, a fill-element (will be a namespace of course) for refs, like blank or 0 for variables, will be mandatory.

Anyway, even with the current implementation, Dyalog has gone a great step towards object abstraction, which might allow APL to become a better object language than all these attempts like the plus-pluses.