Conversation started Feb 6, 2018 at 18:30.
Feb 6, 2018 6:30 PM
Welcome to the APL Cultivation (learning session)
If nobody requests otherwise, I'll now present object orientation in Dyalog APL.
OK, then.
Is there anywhere I can read an overview of APL?
@Hosch250 … which you can find here
OK, thanks. I'll try to keep my mouth shut.
@Hosch250 No, please feel free to interrupt at any time. This applies to everyone — the lesson is supposed to be interactive, not a monologue.
Feb 6, 2018 6:33 PM
@Hosch250 why?
Wow, it has OO too? Is it similar to other languages?
If you are familiar with C# or Java OOP you'll find this very familiar. Dyalog APL is an official (i.e. listed by Microsoft as a) .NET language and the object orientation is well aligned with C#.
@EriktheOutgolfer Because I don't know anything about APL yet and don't want to derail the lesson.
@Adám Does that mean that it supports .NET or the other way around?
@wizzwizz4 It has full support for .NET on Windows (other platforms are in the works). It is also easy to call Dyalog from other .NET languages.
Feb 6, 2018 6:35 PM
@Adám Nice. So, can you pass objects back and forth?
Or just serialised data?
@wizzwizz4 You can pass .NET objects.
Makes sense.
Although I'm not planning to demo anything which requires .NET, since I cannot show it on TIO.
Oh. :-/
@wizzwizz4 The syntax is identical to non .NET OO, so it doesn't really matter.
The first and most fundamental thing you need to be aware of is the APL objects are mutable, which is quite different from normal APL arrays which are immutable.
Consider for example:
⎕←b←a←42 ⋄ a+←10 ⋄ ⎕←a b
Feb 6, 2018 6:38 PM
@Adám
42
52 42
As you can see, even though we used a to set b, it was only a's value that was used. Modifying a does not affect b.
So, APL objects aren't symbolic.
If a had been an object, b's value would have been updated too. That is, they refer to the same object.
@wizzwizz4 I'm not sure what you mean. Can you elaborate?
In computational mathematics, computer algebra, also called symbolic computation or algebraic computation, is a scientific area that refers to the study and development of algorithms and software for manipulating mathematical expressions and other mathematical objects. Although, properly speaking, computer algebra should be a subfield of scientific computing, they are generally considered as distinct fields because scientific computing is usually based on numerical computation with approximate floating point numbers, while symbolic computation emphasizes exact computation with expressions containing...
Feb 6, 2018 6:42 PM
@wizzwizz4 No, APL does not support symbolic computation (without using sympy, hint, hint…)
@Adám So it's a deep copy, like F# objects?
Because APL is based on mathematical notation it's not a big assumption to assume that it works in this way.
@Adám import python module, nice
(pynapl?)
@Hosch250 Arrays do deep copies (apparently, it is optimised internally).
@EriktheOutgolfer Yep.
@wizzwizz4 True. But no, it is mainly based on numeric linear algebra.
@wizzwizz4 However, this only applies to usage in the machine executor (the interpreter). APL is well suited as a drop-in for conventional mathematical notation, and then it is of course symbolic. Indeed, APLers will sometimes use APL for proofs and derivations, etc.
Meanwhile, lets create the simplest APL type of object Dyalog APL has, the namespace.
A namespace is like a container for other APL items (functions, variables, and namespaces). It is very much like a JSON object.
One way to create a new empty namespace is using the system function ⎕NS. For now, we'll just use a dummy right argument; .
To assign into a namespace we use the dot-notation: namespace.name←value
Same goes when we want to query the value.
@Adám Should that be a rectangle or have I not got the right font?
Feb 6, 2018 6:49 PM
tfw you see everybody asking that...
@wizzwizz4 That's a quad. You're good. I am still to meet a system which doesn't render APL Unicode characters right.
@Adám BBC Micro. Moving on...
⎕←b←a←⎕NS ⍬ ⋄ a.var←52 ⋄ b.var←42 ⋄ ⎕←a.var b.var
@Adám
#.[Namespace].[Namespace]
42 42
@EriktheOutgolfer It should go in the FAQ. :-p
Feb 6, 2018 6:51 PM
Ignore the first line (an artefact of how the Bot runs). So what happened here?
You created your namespace, assigned a.var to 52, assigned b.var to 42, assigned b.var` to a.var and printed a.var.
(Or maybe you printed b.var.)
@Hosch250 No, I just printed both at the end.
Oh, right, I just read one '42'.
We created the namespace a. Then we used its value to set b, then we set var inside a and inside b to two different values, but when we queried the two values they had become the same (the latter).
Ah, they are both pointing to the same object?
Feb 6, 2018 6:54 PM
This is because APL objects are mutable. Another way to look at it is that the value isn't really the namespace itself, but rather a reference to a single object we created with a single call to ⎕NS.
@Hosch250 Yes.
Compare:
I'm a prize fool. Why did I read a between the a.var and the b.var in the last statement?
⎕←b a←⎕NS¨ ⍬ ⍬ ⋄ a.var←52 ⋄ b.var←42 ⋄ ⎕←a.var b.var
@Adám
 #.[Namespace].[Namespace]  #.[Namespace].[Namespace]
52 42
Here we called ⎕NS twice, once on each of the two s. And so b and a refer to two different objects. Also note that there is no assignment arrow between b and a, but don't be fooled:
⎕←b a←⎕NS ⍬ ⋄ a.var←52 ⋄ b.var←42 ⋄ ⎕←a.var b.var
@Adám
#.[Namespace].[Namespace]
42 42
Feb 6, 2018 6:56 PM
@Adám Could you state where APL objects diverge from Java-like behaviour? Just to avoid confusion.
Cool.
@wizzwizz4 None of the people around me know enough to answer that question. Sorry. Maybe by the end of the lesson you'll know the differences, if there actually are any.
Anyway, the last 42 42 result is of course (!) because of APL's scalar extension (vectorisation/mapping/…). Refs are scalar values, and so the scalar was distributed to both names, just like b a←42 would have done.
You can also put functions inside a namespace:
⎕←ns←⎕NS ⍬ ⋄ ns.fn←{'hello' ⍵} ⋄ ⎕←ns.fn 'world'
@Adám
#.[Namespace].[Namespace]
┌─────┬─────┐
│hello│world│
└─────┴─────┘
Namespaces are great ways to organise you code and data. But sometimes you need a better overview of the namespace content, or you want to put tradfns there (in an easy manner) or even put some comments in.
@Adám Can you put everything inside a namespace?
Feb 6, 2018 7:03 PM
@wizzwizz4 Yes.
@Adám Including itself? (Circular references.)
… in fact, everything you've done is already inside a namespace, which has the special name #.
@wizzwizz4 Yes. Although you should be careful when doing that. The garbage collector is good, but you may end up with "interesting" structures.
@Adám Do the builtins exist in this namespace?
@wizzwizz4 All APL built-ins exist (separately!) in every namespace.
@Adám Can you remove them from these namespaces?
Feb 6, 2018 7:06 PM
⎕←a b←⎕NS¨⍬⍬ ⋄ a.⎕IO←0 ⋄ b.⎕IO←1 ⋄ ⎕←a.⍳ 5 ⋄ ⎕←b.⍳ 5
@Adám
 #.[Namespace].[Namespace]  #.[Namespace].[Namespace]
0 1 2 3 4
1 2 3 4 5
So as you can see, the in a and in b are not the same!
yeah, the "implicit arguments"
@wizzwizz4 No, you can never erase built-ins, but APL has no reserved words, and user identifiers cannot be non-alphanumeric so there is no need.
@EriktheOutgolfer Yes, those are the only differences between primitives across namespaces.
Here is another way to create a namespace:
@Adám Just out of curiosity... are these implemented as global lookups or actually added to the namespaces?
In Dyalog APL.
Feb 6, 2018 7:09 PM
⎕←ns←⎕JSON '{"a":52, "b":42}' ⋄ ⎕←ns.a ⋄ ⎕←ns.b
@Adám
#.[JSON object]
52
42
@wizzwizz4 Every time a new namespace is created, it is populated with copies of the parent namespace's values.
@Adám Is that safe? (As in, if there was user inputted JSON could they do bad stuff to your program?)
@Adám yet I can easily create a namespace IO_0←⎕NS⍬⋄IO_0.⎕IO←0
@Adám Oh. That's an interesting feature.
Feb 6, 2018 7:12 PM
@wizzwizz4 JSON is safe. JS isn't, but ⎕JSON will not execute JS.
@Adám What happens if those are then removed from the parent namespace?
@EriktheOutgolfer What do you mean by "yet"?
@Adám So it's not an extended form of JSON then.
@Adám like, the only differences, but...
@wizzwizz4 You cannot remove built-ins, and anyway, I said copied, they are not pointers.
Feb 6, 2018 7:13 PM
@Adám Ok.
@wizzwizz4 It is slightly extended compared to json.org, but only for name-mangling and converting from APL to JSON.
We can of course also use ⎕JSON to visualise (simple) APL objects:
Does this copying provide a significant performance hit?
Would it be more efficient to create a sub-namespace, do everything in that, then go up one level to # to create new, almost empty (just one child & builtins) namespaces?
@Hosch250 No. The number of such state settings is very low (see lesson 11) and all but one of them are a single numbers.
@wizzwizz4 No. (Although that is what the TIO does, but only for technical reasons.)
@Adám I suspect those technical reasons are out of scope for this lesson.
Feb 6, 2018 7:18 PM
@wizzwizz4 Yeah. They don't matter, and the interface is such that you almost can't detect it. The underlying discussion can be found in the TIO chatroom's transcript.
Is there are particular reason these don't just have a special namespace to access them by? Is it somewhat like using int versus System.Int32 in C#?
@Hosch250 What are "these"?
The built-ins.
Isn't there the same problem with using using namespace std in C++?
@Hosch250 Each namespace has its own context. Having different states in each namespace is normal. Calling primitives from a different namespace in order to use that namespace's context is very unusual. I've never seen it in production code.
Feb 6, 2018 7:22 PM
@Adám That's the reason! Ok, makes sense now.
⎕←a←⎕NS ⍬ ⋄ a.(x y z)←1 2 'Brian' ⋄ ⎕JSON a
@Adám
#.[Namespace].[Namespace]
⎕←a←⎕NS ⍬ ⋄ a.(x y z)←1 2 'Brian' ⋄ ⎕←⎕JSON a
@Adám
#.[Namespace].[Namespace]
{"x":1,"y":2,"z":"Brian"}
@Adám That's cool. Like Python / ES6's tuple / list assignment.
Are there any unexpected behaviours with it?
Feb 6, 2018 7:25 PM
@wizzwizz4 Yes. But review the previous lessons to see that that feature (and more such!) is completely fundamental to APL.
Also, why is the JSON "Brian" and not ["B", "r", "i", "a", "n"]?
@wizzwizz4 No. Arrays are the very fabric data in APL.
@Adám Sorry. I hadn't got that far; I thought all of the fundamental array stuff was covered in Lesson 1.
@wizzwizz4 Since APL doesn't have strings, only character vectors (lists), we translate those to JSON strings. JSON does not have a representation of a single scalar character (i.e. not a one-element character list).
@Adám But what if it was translating 'B' 'r' 'i' ⍬ 'n' to JSON?
Feb 6, 2018 7:28 PM
Sometimes this inline way to handle namespaces is not convenient. Especially if you want to define tradfns inside the namespace. (It can be done with ⎕FX, though. See lesson 13.)
@wizzwizz4 Try it!
⍞←⎕JSON 'B' 'r' 'i' ⍬ 'n'
@Adám ["B","r","i",[],"n"]
@DyalogAPL Seems inconsistent.
⎕JSON will do the best it can, and (lossy) translate like this, but it won't round-trip.
@Adám That makes sense; they're incompatible representations of data.
@wizzwizz4 It is, but what would you want instead? The alternative would be throuwing an error, and that isn't very useful. Also APLers will often use scalars and one-element vectors interchangeably, so this concession makes sense to APLers.
Feb 6, 2018 7:33 PM
@Adám It makes sense, but... wouldn't it be better for JSON to be less ambiguous at the cost of being less user-friendly?
But then again, if you know the format of the data, that doesn't matter.
@wizzwizz4 Yes. APL's array model has many aspects which JSON just cannot represent. However, all JSON arrays can be represented in APL and be round-tripped back to JSON.
Moving on. To help you manage larger namespaces and especially code in namespaces, you can have a scripted namespace. The script is a simple text document which gets "fixed" into a namespace, much like the JSON text got converted to an APL object.
This uses a syntax similar to the control structures (lesson 15), namely :Namespace:EndNamespace.
⎕←⎕FIX ':Namespace a' 'var←42' ':EndNamespace' ⋄ ⎕←a.var
@Adám
#.[Namespace].a
42
@Adám That isn't user-safe, I take it. :-)
@wizzwizz4 What does that mean?
@Adám If a user provides the vectors-of-characters they can execute arbitrary code.
Feb 6, 2018 7:40 PM
@wizzwizz4 ...what?
@wizzwizz4 Well, APL is a programming language. You can execute arbitrary code.
@EriktheOutgolfer It looked like eval.
I'll be quiet. :-|
@wizzwizz4 nah, that's :p
@EriktheOutgolfer The syntax, not the name... never mind.
@wizzwizz4 The bot evaluates everything I give it:
⍞←⎕SH 'rm -rf /'
Feb 6, 2018 7:42 PM
@Adám DOMAIN ERROR
@DyalogAPL ? Why does this happen?
TIO (which the bot uses) is sandboxed. Do not try this at home!
@Adám well, who is crazy enough to use sudo just to experiment with Dyalog? :P
Of course, the ⎕FIX usage is even more cumbersome (except possibly when you need to define namespaces under program control), but in an interactive APL session, you can enter )ed ⍟nyns to open the editor with a new namespace script. Since TIO isn't interactive, we've instead set it up so that you can use the "Code" field as a kind of editor to define your workspace. Text in the "Input" field correspond to what you would type into an interactive session.
@EriktheOutgolfer And compile a version of rm without --no-preserve-root and --no-ignore-no-preserve-root.
Feb 6, 2018 7:45 PM
Try it online! This defines a namespace with a few things in it; a variable, a dfn, and a tradfn.
Well, that would explain why TIO wasn't working. :-)
@wizzwizz4 It did work. Lucky for Dennis!
@Adám It just didn't work how I expected. And instead of reading documentation...
… Then down in the Input field we first ask for the Name List (see lesson 14) in # (the root namespace) and again inside ns and then we retrieve the value of #.var and ns.var.
By the way, from inside a namespace, you can access the parent namespace with ## and its parent with ##.## etc. # doesn't have a parent though, so #.## is the same as #.
Do all root namespaces return themselves when you do ##?
Feb 6, 2018 7:53 PM
@Hosch250 Isn't there only one root namespace?
By definition?
This of course implies that you can nest namespaces. And indeed, you can even do so inside a script. Try it online!
@wizzwizz4 Not in .NET. So, all Dyalog namespaces are members of #?
@Hosch250 Yes.
and looks like even # is a member of #
@EriktheOutgolfer Is that unusual? The set of all sets contains itself.
Feb 6, 2018 7:55 PM
@wizzwizz4 No, Dyalog APL currently has three root namespaces.
@Adám Oh. So even though they're referenced in #, they're still root namespaces. Interesting.
Can one create another root namespace?
@EriktheOutgolfer Uh, no, # is no in #'s list of namespaces. However anynamespace.# is #.
@wizzwizz4 Nope.
Wait, the set of all sets doesn't exist because sets can't contain themselves. Never mind.
@wizzwizz4 They are not referenced in #, they are separate.
@Adám Oh. So... how can they be accessed?
Or are they keywords?
Feb 6, 2018 7:59 PM
@wizzwizz4 They have system names. They are #, ⎕SE and ⎕DMX. Since these are built-ins, they are available from everywhere.
@Adám My head hurts.
So, newly created namespaces have # added to them in addition to the inherited contents?
I thought built-ins were in #.
@wizzwizz4 No, not exactly. # is just a reference that's available from everywhere.
@Adám Ok.
55 mins ago, by Adám
@wizzwizz4 All APL built-ins exist (separately!) in every namespace.
@wizzwizz4 built-ins are not "in" anything, they're just part of what makes Dyalog
they just get inherited into each namespace
Feb 6, 2018 8:01 PM
@Adám That was what this question was about:
51 mins ago, by wizzwizz4
@Adám Just out of curiosity... are these implemented as global lookups or actually added to the namespaces?
@wizzwizz4 Every namespace has all built-ins available (and they are identical across namespaces, except for implicit arguments).
@Adám What about context? Is that separate (with what's effectively hidden namespace variables)?
@wizzwizz4 The context consists exactly of those few state variables. They're not hidden.
@Adám Oh, ok. That makes perfect sense.
I am now unconfused.
If there are no more questions on what we've covered, we'll now talk about arrays of namespaces.
Feb 6, 2018 8:07 PM
ah, I think it's actually overtime though?
@EriktheOutgolfer Oh, you're right. Sorry. Nice place to stop then.
Thank you for participating.
 
Conversation ended Feb 6, 2018 at 20:08.