Class with user defined fields or properties

General APL language issues

Class with user defined fields or properties

Postby paulmansour on Thu Aug 03, 2017 11:55 pm

I want to confirm something I think is true:

There is no way to have a user-defined name/value stuffed into a class, that the class itself can know about. That is if I have an instance T of a class, and I do:

      T.MyMadeUpName←7


There is no way for a public or private method of T to see MyMadeUpName.

Is this correct?
paulmansour
 
Posts: 420
Joined: Fri Oct 03, 2008 4:14 pm

Re: Class with user defined fields or properties

Postby gil on Fri Aug 04, 2017 7:28 am

I recently found a way to do this but wasn't sure if it was a bug, so reported it to Dyalog but they are still investigating.

From an instance of a class I use the dyadic execute to access the attached namespace like this:
      ⍝ external access from instance
∇r←ListExternal
:Access Public Instance
r←⎕THIS ⍎'⎕NL 2'


∇name SetExternal value
:Access Public Instance
name(⎕THIS{⍺⍺⍎⍺'←⍵'})value
gil
 
Posts: 71
Joined: Mon Feb 15, 2010 12:42 am

Re: Class with user defined fields or properties

Postby paulmansour on Fri Aug 04, 2017 2:12 pm

Oh boy, that probably is generating some internal discussion!

The reason I ask this is that I am pondering a data structure for name/value pairs (similar to a k dictionary), and considering a simple namespace, with external functions that operate on it, verses a class with methods. I want direct, non quoted dot access to the names, and since we don't know what they are ahead of time, cannot use public fields or properties.

The latter would only work with the trick you note above, which seems a bit dodgy. I'm leaning towards a simple namespace.
paulmansour
 
Posts: 420
Joined: Fri Oct 03, 2008 4:14 pm

Re: Class with user defined fields or properties

Postby gil on Fri Aug 04, 2017 6:49 pm

For what it's worth, I also settled for a normal namespace with external functions. I was experimenting with a thin layer to deal with objects shared with JavaScript where some keys are invalid apl names. Using a keyed default property I can mimic JavaScript's syntax:
      ns['$exists' 'name']←(⊂'true')'Gil'


While still being able to use it as a normal namespace.
      ns.name←'Gilgamesh'


Being able to access those external names was key to be able to serialize it, but it just got too awkward compared to a solution using a couple of external functions.

I'm still curious to hear what Dyalog makes of my findings. As you say, it is hard to explain the difference in behaviour between using execute monadically.
gil
 
Posts: 71
Joined: Mon Feb 15, 2010 12:42 am

Re: Class with user defined fields or properties

Postby JohnD|Dyalog on Wed Aug 09, 2017 8:37 am

The following is taken from a document I've been working on which will (hopefully) be the basis of some future documentation.

Names in the Dyalog OO Model.

"Grey Boxes" and Symbol Tables


A namespace in Dyalog APL includes a list of symbols (AKA names). We refer to this list of symbols as a “Symbol Table”.

In order to provide encapsulation of symbols in the Dyalog OO model, an instance of a class is implemented as a single namespace with multiple symbol tables. There is a single symbol table for each level in the instance’s class hierarchy. At Dyalog we sometimes refer these symbol tables as "grey boxes" (as per diagrams that have been drawn for internal use over the years). In addition, there is a symbol table that is not associated with any base class. This symbol table is used to store arbitrary names from outside the class hierarchy. Previous documents referred to this symbol table as the “APL Execution Space”, internally we sometimes refer to it as the "white box". Typically, symbols in a box are visible to code that is defined by the same class, and are not visible (i.e. are "private") to code defined in other boxes (:Access public makes a symbol visible across boxes)

Consider then a class A, and an instance a

:class A
:field Private first←'john'
∇r←get_first
:access public
r←first

:endclass


a←⎕new A

The name "first" in the class is private. Expected OO behaviour means that "first" is hidden from the outside world:

a.first
VALUE ERROR

But also that a should behave as if A.first does not exist. This means that

a.first←'andy'

Should work. And indeed, it does, because this assignment creates a symbol "first" in a different "box" (i.e. a different symbol table) to the one that the class code is operating in.

a.first is a different symbol to the "first" symbol that get_first has access to.


The Dyalog interpreter switches between symbol tables at appropriate times, for example, we switch to the grey box associated with "A", when get_first is called. Generally, the APL programmer has no way to switch boxes other than by calling code defined in the relevant class.


The APL Execute primitive, ⍎

Monadic execute executes an expression in the current namespace, by extension it executes the expression in the current "grey box" (i.e. with access to the current symbol table). So, if we had:

⍎'first'

Inside get_first then, the result would be 'john'.

Dyadic execute however, executes the expression in the space provided by the left argument. There is no way to specify the "grey box" in which the expression should be executed, so it is done in the "white box" for the space, so the result will be 'andy'.

Note also, that other "dotted" uses of ⎕THIS (and ⎕BASE) are more aware of the "grey boxes". For example, from within get_first:


⍎'first'
john
⎕this ⍎'first'
andy
⎕this.⍎'first'
john
User avatar
JohnD|Dyalog
 
Posts: 74
Joined: Wed Oct 01, 2008 9:35 am

Re: Class with user defined fields or properties

Postby kai on Wed Aug 09, 2017 2:31 pm

Oh dear
User avatar
kai
 
Posts: 137
Joined: Thu Jun 18, 2009 5:10 pm
Location: Hillesheim / Germany

Re: Class with user defined fields or properties

Postby gil on Thu Aug 10, 2017 6:43 am

Thanks for the explanation John. I must admit that I thought the dyadic execute would be identical to monadic execute where the left argument is a reference and not a name (text string).

It doesn't sound like you are planning to change this behaviour. What is your recommendation? "Don't exploit this, we will probably change/fix this." or "This is the way to access the white box, we are documenting it for future reference."?
gil
 
Posts: 71
Joined: Mon Feb 15, 2010 12:42 am

Re: Class with user defined fields or properties

Postby paulmansour on Thu Aug 10, 2017 5:03 pm

John, thanks for the detailed explanation. I second Gil's question for recommendations. My gut feeling is that one should probably avoid looking at stuff in the white space from within the class, unless of course one is doing something special, which is what I was looking at doing.

I think it is all pretty clear, and if it is documented and not subject to change, it all looks good to me.

While is is a little confusing that ⎕This.⍎ is a different than ⎕This⍎, if it is made clear that the latter is essentially special syntax for entering the white space from within the instance, it is all clear. I assume that is a valid way to phrase it?
paulmansour
 
Posts: 420
Joined: Fri Oct 03, 2008 4:14 pm

Re: Class with user defined fields or properties

Postby Morten|Dyalog on Thu Aug 10, 2017 8:43 pm

I don't think it is correct to describe (⎕THIS⍎expr) as some kind of work-around that allows you to access the white box. Dyadic ⍎ is supposed to view an object "from the outside", and run the expression "in the white box". I would argue that this does not need special documentation, or a "guarantee" that it won't stop working.

On the contrary, it is the the "ref.expr" syntax that is providing special behaviour when the ref points to a grey box that you are already in. In this case, instead of doing the "normal" thing and giving you the outside / white box / view of the object, the DOT decides you probably want to stay where you are and runs the expression using monadic ⍎ in the current box. "⎕BASE." is even more special syntax, which allows you to invoke an overridden method of a base class.

If I were to argue for a change in behaviour, I think it would be that (⎕THIS.expression) should ALSO run in the white box.
User avatar
Morten|Dyalog
 
Posts: 453
Joined: Tue Sep 09, 2008 3:52 pm

Re: Class with user defined fields or properties

Postby Morten|Dyalog on Fri Aug 11, 2017 6:55 am

Having slept on this, I think it is correct to say that "⎕BASE." also presents an outside view of the base class, only giving access to public names from it. So it is only "⎕THIS." that is a special case. I am not sure it is practical to change this now, but my feeling is that it would be more correct and more useful if that also gave you the white box view. You don't need the current behaviour of "⎕THIS.blah", you could just write "blah"?
User avatar
Morten|Dyalog
 
Posts: 453
Joined: Tue Sep 09, 2008 3:52 pm

Next

Return to Language

Who is online

Users browsing this forum: No registered users and 1 guest