Conversation started Feb 14, 2018 at 18:30.
Feb 14, 2018 18:30
Welcome to the APL Cultivation!
Last time we learned about APL objects called namespaces.
Today we'll learn about a special case of a namespace called a class.
Remember: All APL objects are namespaces. The ones we just call "namespaces" are the most general ones with no restrictive rules.
Classes can hide stuff from the outside onlooker. Adhering to a set of rules, they can be used to create other objects (instances).
All this should be familiar to you if you've done any OOP (object oriented programming), e.g. in C# or Java.
@all Are you familiar with some non-APL OOP?
Nope...
@H.PWiz Please interrupt me with any questions as we go along. This is supposed to be interactive.
Noted
Remember that we can tell the editor to begin a new namespace with )ed ⍟myns ? We can begin editing a new class with )ed ○myclass .
Of course, that doesn't work with the chat bot or on TIO or TryAPL.
We could also create a new empty namespace with ⎕NS. We can't do that with classes as they need some meta-information. However, we can use ⎕FIX with a script to create a class. That's hard to read though, so I'll link to TIO instead.
Fundamental to a class it that it restricts which of its members can be "seen" from the outside.
By default fields (i.e. variables) and methods (i.e. functions) are "private", but we can make them "public" so that they can be seen.
This is convenient to implement black-box things and create layers of abstraction (for those that like such).
Another feature of fields and methods is whether they are "shared" among all the instances, or whether a separate method/field belongs to each instance. By default, they belong to the instances.
So what is an instance?
An instance is a new object which is based on a class, which is then its base class.
Instances inherit all methods and fields from their base class, but as I wrote above, they may either each have their own or share one (which is then considered as if it remains in the base class).
Enough talking. Let's see some code:
:Class cl
    :field f←'f'
    :field public fp←'fp'
    :field shared fs←'fs'
    :field public shared fps←'fps'
    ∇ r←look
      :Access public shared
      r←⎕NL -⍳9
    ∇
:EndClass
The above is a script for a class called cl.
You can see that it has four fields and one method (function).
the first field, f, has all the defaults, i.e. it is private, and for each instance.
The second field, fp can be seen from outside each instance.
The third, fs, is private, but shared among all instances (and their base class, cl).
The last field, fps is both visible to the outside public, and also shared.
The method, look, is public and shared just like the field fps.
@all So, if, from outside cl, we try looking into cl, which members do you think we can see?
Feb 14, 2018 18:47
fp, fps, look
@Adám btw how do I make members called public or shared?
@EriktheOutgolfer Almost right. We won't be able to see fp because it is "instance", not "shared". So since cl is not an instance, it won't show fp.
@EriktheOutgolfer Oddity. The syntax doesn't clash, since the last word before the or the end of the line is the name of the field. However, for some unknown reason, we don't allow those names as field names. I guess it is a good rule for clarity.
@Adám and what if I want to make 3 members in the same statement :field a b c←'abc'? can I do that?
where a≡'a', b≡'b' and c≡'c'
@EriktheOutgolfer Nope. Sorry. Each needs to be declared on its own. As I said, classes are like namespaces with restrictions.
@Adám uh, looks like :Class c1 is a syntax error, I think I need a tradfn...
@EriktheOutgolfer You can't write :Class anywhere but in a script.
Feb 14, 2018 18:53
@Adám oh uh ooh :/ I guess I'll pull that )LOAD out sometime then
@EriktheOutgolfer However, you can write :field a ⋄ :field b ⋄ :field c and initialise their values elsewhere. We'll get back to that.
@EriktheOutgolfer )LOAD?
@Adám isn't that how I open scripts?
@EriktheOutgolfer No, that's how you load a workspace. To begin the creation of a new class script, do )ed ○c1 or '○' ⎕ED 'c1'.
@Adám different APLs having different meanings of the same term == >_>_<_<
@EriktheOutgolfer GNU APL strikes again?
Feb 14, 2018 18:57
@Adám oh god GNU APL has cursed me
Now, let's step into cl and have a look from inside. We do that by running cl.look. As you can see, look just returns the list of members that it can see.
@all Before you try it, what do you think we'll get?
No guesses?
Already tried it before you asked
@H.PWiz @EriktheOutgolfer OK, can you explain the result?
@Adám suspiciously cl is in there too
Feb 14, 2018 19:01
@EriktheOutgolfer Yes. Just like a function can "see" itself:
 ⎕←f←{⎕NL-⍳9} ⋄ f ⍬
@Adám
{⎕NL-⍳9}
⎕←f←{⎕NL-⍳9} ⋄ ⎕←f ⍬
@Adám
{⎕NL-⍳9}
┌─┐
│f│
└─┘
@Adám Since look is inside cl, it has access to private fields?
@H.PWiz Right, so everything that's shared (i.e. non-"instance") can be seen, and also the class itself.
This is useful if you work with a class and need to inspect what's going on inside. You can just trace into any public function, and then leave the system suspended. Now you can work from inside the class.
When you're done, just execute →0 to quit the function.
OK, now let's try to create our first instance of cl. We do that using the system function ⎕NEW. It takes cl as right argument and returns an instance: inst←⎕NEW cl.
@all If we then call inst.⎕NL -⍳9 , what do you think we'll see?
Feb 14, 2018 19:06
cl fps fs look and fp somewhere?
fps & look?
@EriktheOutgolfer Let's see. cl is the base class, but it isn't a member of itself. So there's nothing for inst to inherit.
fps is given. It was there already, and is visible.
ugh, can people just stop it with the flags >_< don't you see stuff is going on here‽
@EriktheOutgolfer fs is shared alright, but remember that we're on the outside. It isn't public.
Yes, we can see look, because it is public. (Shared too, but that doesn't matter.)
@EriktheOutgolfer And fp. We couldn't see before because it is an instance field. But now we do have an instance, and is is public too, so yes, we can see it.
@all Understand the result?
Feb 14, 2018 19:11
@all OK, last challenge: Say we create the instance inst←⎕NEW cl and then run inst.look . What do we get?
∪ of the above :P
Try it online!: cl fps fs look
I already saw, but I was expecting to see f
@H.PWiz OK, I can understand that. But were you surprised to see cl?
Not really, although that may be due not fully understanding what it means for cl to be in the output. Can inst create new instances?
Feb 14, 2018 19:15
@EriktheOutgolfer Actually, let me correct that. The reason you can't see cl isn't because it isn't inherited, but because it isn't public.
@H.PWiz I was. I realised ^.
Ugh, OOP is hard.
OK, what does it really mean that inst can "see" cl
@H.PWiz Hm, actually, I'm missing something here. I don't quite see why f isn't in the list.
@H.PWiz Strange concept really. I guess we could say that because inst is a cl then it can see its own clness or something.
@H.PWiz In practice, it doesn't really matter. You should definitely not refer to a base class by its name. If the base class changes name, then your code will break. This is just like code in a namespace shouldn't refer to its parent namespace by absolute path, but rather use ##.
However, ## in an instance is the containing namespace, while the base class maybe situate somewhere else entirely. To refer to members of the base class, use the syntax ⎕BASE.member .
@H.PWiz Ah, yes. The reason look cannot see f is because f isn't public. But we're inside, you say? Yes, but inside what? Remember that look is a shared method. This means that it resides in cl, not in inst. And from inside cl, the private fields of inst are invisible. Clear?
To test this, we modify the class:
:Class cl
    :field f←'f'
    :field public fp←'fp'
    :field shared fs←'fs'
    :field public shared fps←'fps'
    ∇ r←look
      :Access public
      r←⎕NL -⍳9
    ∇
:EndClass
@Adám Excellent, while confusing, that does make perfect sense
The only difference here is that look is now an instance method. This means that we can't do cl.look. However, we can do inst←⎕NEW cl ⋄ inst.look: Try it online!
Finally, we can see everything. Ah, the clarity!
Feb 14, 2018 19:31
I'm eating now, so Ill catch up later :)
@EriktheOutgolfer Next up are some of the things we can do with classes. Are you up for that now, or should we finish early and do it next week?
OK, I'll stop here.
Thank you for participating in this short, but intense, session.
 
Conversation ended Feb 14, 2018 at 19:33.