Conversation started Oct 18, 2017 at 17:18.
Oct 18, 2017 17:18
Welcome to everyone here for the APL learning session. We're just waiting for @Mr.Xcoder…
@Adám I am here now. ready!
@Mr.Xcoder Well, speak of the…
I was just pinging you lol
What shall we learn today? I assume you are all on different levels.
Whatever you find suited for all of us.
Oct 18, 2017 17:19
How about an intro to APL's array model?
Fine with me, I'm down for whatever
OK. So the array is APL's fundamental data type.
Arrays are collections of scalars (atomic data units). There are a few types of scalars: numbers, characters, and references (refs).
11 people in the APL room. must be some record
...maybe
btw is this the first lesson, came just in time
Oct 18, 2017 17:22
references are to such things as namespaces (≈JSON objects), GUI objects (WinForms), HTML Renderers, classes, instances, etc. Let's not worry about all those now.
Characters are denoted by single quotes 'a' is a scalar letter a.
APL doesn't really have strings, just lists (vectors in APL lingo) of characters.
In order to write a literal vector (=list) you just write the items next to each other.
Separated by spaces?
@Mr.Xcoder Only if otherwise ambiguous.
So, 'H' 'e' 'y' will render as Hey
Fortunately, there is a shortcut. APL allows you to write 'Hey' and it means the same as 'H' 'e' 'y'.
So a list of numbers need no decorators whatsoever: 1 2 3
You can also nest items. 'Hey' 'you!' is a vector of two elements. Each element is itself a vector.
So it is like [['H', 'e', 'y'], ['y','o', 'u', '!']] in other languages?
@Mr.Xcoder For some languages probably. Many languages do not have scalar chars.
ok, I see
Oct 18, 2017 17:29
E.g. in JSON that would imply an additional "layer" of nesting.
You can also mix data types: 'APL' 360 is a two-element vector. The first element is a three-element vector of chars, the second is a scalar number.
Btw, in APL a number is a number. APL converts between internal representations on the fly, so you never have to worry about such conversions. It even takes care of floating point imprecision for you!
Oh the latter is rather nice
'a'3 is a two element vector. No space needed here.
No space needed in 'APL'360 either, actually.
You can also use parentheses to delimit vectors: (1 2 3)(4 5)
APL handles infinite nesting and mixing of data types.
that's sweet
Oct 18, 2017 17:32
@Everybody on board with APL vectors?
OK, let's up the level!
@Adám how does apl represent arrays containing arrays if an array is "a collection of scalars"?
@EriktheOutgolfer You mean internally?
Oct 18, 2017 17:33
yup
@EriktheOutgolfer A simple array contains the data in plain form in memory. Any non-simple item is instead represented as a pointer to somewhere else in memory where that array is located. If that array isn't simple either, then it consists of pointers too. But that's all hidden from the user. It just works.
so it's using reference scalars
and another question
@EriktheOutgolfer References yes, scalars? Well, it doesn't really have a name when it is internal.
is there any concept of a "mutable array" in apl?
@EriktheOutgolfer Nope. You always (appear to) create a new array when modifying an array. However, internally, APL keeps a ref-count and points multiple names to the same memory location if possible.
However, all the "reference" types are mutable.
Oct 18, 2017 17:38
so it's not pointing to variables where if you change a variable's value every other variable assigned to it would change too
The levels of nesting in APL lingo are called depth. A simple scalar has depth 0. A vector has depth 1. A vector of vectors has depth 2, etc. If the depth is uneven, then we report it as negative.
@EriktheOutgolfer Nope.
Oh, btw, negative numbers in APL are denoted by a high minus (like TI calculators).
You can also use exponential format, so a million is 1E6.
@Adám clarification request: negative as in -1, or as in -(max depth)?
@EriktheOutgolfer -(max depth)
Oct 18, 2017 17:40
so, jelly's ŒḊ-like but negative, alright
¯0 and ¯1 cannot occur for obvious reasons.
(also, ¯0 isn't a thing in APL)
Fair enough
@Adám doesn't something like [[6], 1, 2] have depth -1?
oh wait that's -2 nvm
@EriktheOutgolfer Exactly.
Ok, understood
Oct 18, 2017 17:42
@EriktheOutgolfer but in APL that'd be ((6) 1 2) right?
@J.Salle No, because (6) is just 6
@Adám How would one properly write [[6], 1, 2]?
was going to ask
I wonder why would that be necessary tbh
Oct 18, 2017 17:43
Or a singleton list like [5]?
You can have 1-element vectors, but you have to "create" them rather than write them. The prefix function , (comma) takes an array and makes it into a list. So ,6 is a one-element list.
@Mr.Xcoder (,6)1 2
Of course , doesn't do anything to 1 2 3 as it is already a list.
Now, don't get a chock! APL also has a concept of rank. The rank of an array is the number of dimensions in that array. A scalar has rank 0, a vector has rank 1.
However, we can also have a rank 2 array; a matrix, or table.
Note that rank ≠ depth.
So I can have a matrix where every element is a "string" (i.e. a vector). I can also have a vector of vectors of "strings".
Rank is always flush. Every row in a matrix must have the same number of columns. Every layer in a 3D block of data must have the same number of rows and columns.
ಠ_ಠ Out of 5 messages that appear on my starboard, 4 contain "APL"
sure, that's very weird, considering the room is about apl ;p
Oct 18, 2017 17:48
@Mr.Xcoder Uh, you are in the APL chat room.
Ninja'd
Well we don't have "Jelly" on each starred message in JHT :p
I guess there's an operation that turns a matrix into a vector of vectors?
Each APL implementation has a different max number of dimensions. Dyalog allows 15D arrays. If that isn't enough for you, you may be doing something not quite right.
4
If that isn't enough for you, you may be doing something not quite right - 10/10
@JohnDvorak Yes there is. The monadic prefix function called split does that.
Oct 18, 2017 17:49
If you need more than 4 dimensions you're probably doing something really confusing already
@Mr.Xcoder Well, there I've seen documentation for systems allowing 255 dimensions and J, which is a dialect of APL (and the mother of Jelly) allows for an unlimited (except by memory) number of dimensions.
The reality has 11 dimensions (and yes, it is confusing)
Well, I find it relatively easy to imagine very many dimensions:
@Adám you mean its inspiration; jelly has a father though, not a mother ;-)
Imagine a piece of paper with a grid of letters. So we have rows and columns.
Oct 18, 2017 17:52
@EriktheOutgolfer You are making assumptions :P joke
also it's really python (what it's made of) that allows the many dimensions, jelly just uses that
Each paper is a page in a book.
Each book is numbered on its self.
The shelves are numbered.
There are multiple bookcases next to each other.
And there are several such corridors.
In rooms next to each other.
And the floor has multiple numbered corridors.
On each floor.
I think we got it...
Sounds like MDX, you can have something like 16 dimensions
I got carried away…
Oct 18, 2017 17:54
Although I've never seen anyone use more than 3
...and this shows that if you're using that many dimensions you're already doing something very confusing
@EriktheOutgolfer Yeah, like keeping all the data about your data center in one array!
@Adám and you didn't even get to the floors inside buildings inside neighbourhoods inside cities
@J.Salle along the highway…
New record: 12 people in the APL chatroom
Oct 18, 2017 17:56
Since APL is written in lines of code, we can't (yet – I'm working on that) write a matrix as is.
@J.Salle inside provinces inside countries inside the earth inside the solar system inside the galaxy inside the universe inside the world of parallel universes...
@EriktheOutgolfer You skipped a few steps there.
which, again, shows that you're doing something wrong with so many dimensions at once
Something that's wrong on so many levels
The infix function (Greek letter "rho" for reshape) takes a list of dimension lengths as left argument and any data as right argument. It returns a new array with the specified dimensions, filled with the data.
(If there is too much data, the tail just doesn't get used. If there is too little, it gets recycled from the beginning.)
So we can create a 3-row, 4-column table with 3 4⍴'abcdefghijkl'
Oct 18, 2017 17:59
@Adám ...too little?
@EriktheOutgolfer Yeah, like 3 4⍴'abc'
oh you mean the right argument
that's also how jelly's (mold) works, except that in jelly you use a list with the intended shape, not a list of dimensions
@EriktheOutgolfer Yeah, Jelly doesn't have rank.
Oct 18, 2017 18:02
it does have a "depth" function (ŒḊ) but it's not really the same
Ok, can we move on from dimensions, we're stuck here for about 15 minutes...
APL, J, Matlab, and Mathematica have both, if I understand correctly.
like, mold and reshape?
Well there is no built-in Mathematica does not have anyway
@EriktheOutgolfer depth and rank, I think
Oct 18, 2017 18:03
@EriktheOutgolfer ^
@Adám maybe something like python's """ multiline strings? like [[[1 2 3\n4 5 6\n7 8 9]]]
@Uriel That's very limited. You can't go 7D with that.
So, let's have a look at some of the built-ins (primitives in APL lingo) that deal with rank and depth and shape.
@Adám I wouldn't expect someone to type 7D arrays in his code, but matrices should be legit
Most primitive APL functions have both a monadic (one argument) and a dyadic (two arguments) form. It is always clear from context which one is being applied, as all monadic functions are prefix, and all dyadic ones are infix.
So, we already addressed the dyadic which was "reshape". The monadic is "shape". So it reports back what the shape is.
s/alway/always/
Oct 18, 2017 18:06
CMC: What is the shape of a scalar, like 42?
@EriktheOutgolfer Right.
(note: gotta learn how to do empty array in apl)
@EriktheOutgolfer ⍬
Oct 18, 2017 18:07
So if you have a vector like 1 2 3 and want to "fill" a simple scalar with that data, you can do (0⍴0)⍴1 2 3
And yes, is a shortcut for 0⍴0.
So ⍬⍴1 2 3
Gives 1 of course.
@Adám I'd consider it more like the opposite
@EriktheOutgolfer Why?
0⍴0 would return
is the operator though
@EriktheOutgolfer No they both return an empty list. It is just a way to write it.
Oct 18, 2017 18:09
Why does f←{⍴⍵}⋄ f5 Raise a VALUE ERROR?
@J.Salle No, is not an operator.
@Mr.Xcoder Because names may have multiple chars, so you need a space to distinguish f 5 from f5
@Adám it's not? Is it like a quick in Jelly then?
@Adám it's a function right?
@J.Salle No, it is a constant. Like 5
Oh okay
Oct 18, 2017 18:10
@J.Salle not quick, nilad
@Adám APL does not output [] does it? It outputs an empty string instead right?
(or nothing, actually)
@Mr.Xcoder By default yes. But you can tell APL do to give you more info than that.
I guess my code was correct since f←{⍴⍵}⋄f 2 3 5 gives 3.
Also, you can convert nested lists (no high-rank arrays) to JSON.: Try it online!
that's a string right?
Oct 18, 2017 18:13
@EriktheOutgolfer Yes, the result of ⎕JSON is a simple character vector..
Back to primitive functions.
We mentioned monadic which ups the rank (at the cost of one level of depth).
We can also lower the rank with and thereby gain a level of depth.
what is the builtin to return the rank of an array?
@EriktheOutgolfer There is none, because if you think about it, the rank is the shape (well actually the tally) of the shape.
So is shape. ⍴⍴ is rank. ⍴⍴⍴ is 1.
However, there is a primitive for depth: (you see the layers, right?)
@EriktheOutgolfer Yes.
And the rank really should be scalar. The result of is always a vector.
So there is a different primitive for count (called Tally): it looks like a tallying mark.
so...what is the difference between rank and depth?
Oct 18, 2017 18:19
Depth is the level of nesting. Rank is the number of dimension.
for example [[[1]]] has depth 3 and rank 3 right?
It may seem unnecessary now, but it comes in really handy.
@EriktheOutgolfer No, rank 1. It is a vector.
Matrices have rank 2, "cubes" have rank 3, etc.?
@EriktheOutgolfer There simply isn't any JSON notation for higher rank.
@Adám so what is rank 2, 3, etc.?
Oct 18, 2017 18:21
@EriktheOutgolfer As @J.Salle said.
Blocks are rank 3D. Hyper-blocks (if you want) are rank 4.
so how do we represent a "matrix" or a "cube" in apl, if it's different from just (1 2 3)(4 5 6)...
@EriktheOutgolfer You can either use to reshape the data, or use to exchange depth for rank.
so rank is actually something internal?
(2 3⍴1 2 3 4 5 6) is the same as ↑(1 2 3)(4 5 6)
@EriktheOutgolfer Yes, internally, arrays are stored as rank, shape, data
what is ↑ called?
Oct 18, 2017 18:23
Ups?
@JohnDvorak "Mix", because it mixes elements together to form higher rank arrays. As opposed to "Split", , which splits high-rank arrays into lists of lesser-rank arrays.
Oh makes sense
json kinda fail right
Btw, if you use Chrome on Windows or macOS, may render kind of like ≡/ which is a bug. You may add your voice here.
luckily I'm on ubuntu
Oct 18, 2017 18:26
They do render exactly the same (for my near-sighted eyes at least)
@EriktheOutgolfer Yes, ⎕JSON will refuse to convert things that cannot be represented in JSON.
Yes, they render correctly for me too (macOS)
but you're using safari
@Adám this is why I no longer use Chrome
@J.Salle is supposed to look like but with an additional underscore like
Oct 18, 2017 18:27
Yeah I've seen it on tryapl
I think it's really windows's and mac's fault, since rn I'm using chrome on ubuntu and those two render differently for me
not because of ≢, but because the way bug reports get handled in general.
@EriktheOutgolfer I suspect it is Blink's fault because they render correctly in all other applications on Windows and macOS.
new name for Webkit
Oct 18, 2017 18:30
@EriktheOutgolfer Chromium's rendering engine.
So now we have monadic ↑ ↓ ≡ ≢ ⍴ and dyadic .
because they wanted the webkit- css prefixes to no longer work :P
@Adám forgot monadic in there :p
you specified it above
@EriktheOutgolfer it's there
Monadic always returns a vector. Monadic always returns a scalar. on a matrix returns the number of rows. on a 3D block returns the number of layers, etc.
Oct 18, 2017 18:33
So it's always the number of the 'highest rank' of sorts?
in short: is length
@Everybody has an ok understanding of APL arrays?
@J.Salle Yes.
Ok good.
Oct 18, 2017 18:34
@EriktheOutgolfer Not really, because "length" is not a well defined term for high-rank arrays.
We prefer to call it the tally of "major cells".
The concept of major cells is important when it comes to manipulating and comparing arrays, but we can address that when it comes up.
Let's manipulate some arrays!
Let's do it \o/
@Adám I think I do.
@Adám Sure yay
We already saw how dyadic can reshape things. Dyadic is take. In order to speak about its two arguments easier, we will give them names. The left argument we will call as in the leftmost letter of the Greek alphabet, and the right argument we will call as in the rightmost letter.
So ↑⍵ is monadic and ⍺↑⍵ is dyadic..
⍺↑⍵ takes the first major cells (!) from . E.g. 3↑3 1 4 1 5 is 3 1 4.
CMC: Any guesses (those that don't know) as to how we take from the back instead?
negative ?
Oct 18, 2017 18:39
@EriktheOutgolfer Yes!
3 1 4 1 5 ↑ 3 ?
@JohnDvorak No.
aww :-)
That would make it impossible to know what 3↑4 means.
If you take more than there is, APL will pad with a fill element.
¯3↑3 1 4 1 5 = 4 1 5 ?
Oct 18, 2017 18:40
@J.Salle Yes.
Nice
I guess you won't accept disallowing scalar ↑ scalar? :-)
@JohnDvorak Of course not. All arrays are created equal, and anyway vector ↑ ⍵ is meaningful.
CMC: And any guesses as to how we drop elements?
the down arrow?
Oct 18, 2017 18:42
Correct. And you can remove from the back with negative , of course.
@Adám How is the filler element determined?
@Laikoni Excellent question.
APL arrays have something called prototype. The prototype for numbers is 0 and the prototype for chars is a space. This is really handy in codegolf!
and the prototype for mixed?
@EriktheOutgolfer The first element's prototype.
Oct 18, 2017 18:44
I guess that's quite handy too
For an array of arrays, the prototype is the first element, but with all numbers made 0 and all chars made spaces.
E.g. the prototype of (1'a'2)(3 4) is 0' '0
@Adám you mean with all elements prototyped right?
that is, the prototype of ((1 2'a')3)(1 2 3) is ((0 0' ')0)
@EriktheOutgolfer Yes. the 1 and 2 became zeros, and the a became a space.
@EriktheOutgolfer correct.
Oct 18, 2017 18:47
Are functions first-class citizens in APL?
(If so, what is their prototype?)
I guess they are refs
@Laikoni I could go there, but I think it belongs in a different lesson, as we are doing data here.
I just posted an challenge on Main. What if we try to solve it together now?
1
Q: Am I a golfy array?

Mr. XcoderDefinition and Rules A golfy array is an array of integers, where each element is higher than or equal to the arithmetic mean of all the previous elements. Your task is to determine whether an array of positive integers given as input is golfy or not. You do not need to handle the empty list. ...

@Mr.Xcoder I just saw that, sounds like good exercise
Oct 18, 2017 18:48
@Adám hah ninja
For example, does APL have built-ins for arithmetic mean and prefixes?
btw it would help if there's an average builtin
Give me a min to read it.
in J the average is a train, plus-over divided by count
Oct 18, 2017 18:50
@JohnDvorak Exactly the same in APL, but with nicer glyphs.
but harder to type
@JohnDvorak Not if you have an APL keyboard layout.
(+/÷≢) I guess?
@EriktheOutgolfer Correct.
Although it gives 1 for the empty list.
Wait wut
Oct 18, 2017 18:52
Because 0÷0 is 1 in APL by default (you can change this though).
except that the average of an empty list isn't defined at all :p
@EriktheOutgolfer No, but it would be handy to say it is 0 for that challenge.
Uriel just posted an answer in APl.
But +/÷1⌈≢ works.
but it's not a train anymore is it
Oct 18, 2017 18:54
@Mr.Xcoder Yes, and it uses APL features that may be a bit too advanced for the participants here.
@Adám (kinda unrelated, but anyways) can I install dyalog apl on my windows and my linux distro using the same non-commercial serial number?
@EriktheOutgolfer Yes it is. Any sequence of functions with no data on the right is a train.
@Adám Ok.
@Adám so that is a 4-function train I guess
@J.Salle If you want Dyalog APL for 2 OSs, then apply for two licences. I actually don't know if Karen will give you two serial numbers, but it doesn't matter what you enter into the serial number field upon install :-)
Oct 18, 2017 18:56
@Adám Note that for the purpose of this challenge, we will assume that the average of an empty list ([]) is 0.
@Adám okay, sounds good!
@EriktheOutgolfer It is a 5 "car" train. One "car" is not a function, but it is still a train because there is no data on the right.
I think we should continue with a few more array-manipulation primitives before we try tackling Uriel's solution.
The remaining array manipulation primitives are really simple. Monadic enlists an array. It takes all the data, on all levels of depth and rank and creates a simple vector of depth 1.
Wait so (+/÷≢) is arithmetic mean? I didn't really pay attention for the last few minutes.
@Mr.Xcoder yes
@Mr.Xcoder Yeah. Because +/ is sum. But we have not addressed / yes.
Oct 18, 2017 18:59
@Adám Is the dyadic counter part the element function?
And is length right?
@Mr.Xcoder Yes.
@Laikoni Dyadic counter? or or something else?
We already mentioned monadic , which ravels high-rank (or low rank) arrays. It creates a vector of all elements, but it does not flatten depth.
@Adám I meant "counterpart"
@Adám Can you link me to that page with what each function does again please? Thanks.
@Laikoni I still don't understand.
Oct 18, 2017 19:02
Whether 1 ∊ 1 2 3 yields some truthy value because 1 is an element of 1 2 3.
he probably means dyadic
@Mr.Xcoder I use tryapl.org, the primer section
@J.Salle I know about that one
@Laikoni Yes, it is membership, like in normal math.
except that tryapl has an older version
Oct 18, 2017 19:03
@Mr.Xcoder All primitives
Yes thanks.
@Mr.Xcoder Oo sorry, didn't see you were going over it
@Uriel Nah, we wouldn't have solved it anyway
@Uriel No problem.
@EriktheOutgolfer Exactly. Is there some language issue with "counterpart"? It sounded natural to me.
Oct 18, 2017 19:05
@Laikoni Not at all, I just didn't realise what you meant with "element".
Dyadic , is concatenation.
So 1 2 3,4 5 6 is 1 2 3 4 5 6.
@Adám it then follows that ; is pair right?
It works for any-rank arrays, but they have to conform. You can even concatenate a vector to a matrix, and that will concatenate one element from the vector to each row of the matrix.
@EriktheOutgolfer pair? (and no, ; is special syntax in APL, not a function)
@Adám Oh, I used "element" because of Haskell's elem. In hindsight "member" is the more common term.
oh so it vectorizes
Oct 18, 2017 19:08
@EriktheOutgolfer Yes. And if you try concatenating a scalar to a matrix, it will expand the scalar to concatenate it to each row too.
Yeah APL has auto vectorization
@Uriel Wow 16 bytes is rather impressive given that the Jelly solution is 5 bytes.
@EriktheOutgolfer Now, as you can see, , concatenates horizontally. You can't concatenate two elements to three rows (Check the debug pane of TIO!)
Oct 18, 2017 19:10
I'd expect it to "recycle" though, wouldn't it be more reasonable given how others recycle too?
@EriktheOutgolfer Maybe. But only recycles.
@Mr.Xcoder looking at the jelly explanation, they are practically the same
If you want to concatenate vertically, then you use (comma-bar).
oh that's what means?
I thought it meant rank
@EriktheOutgolfer No, rank is ≢⍴ (the tally of the shape, i.e. how many dimensions)
 
Conversation ended Oct 18, 2017 at 19:12.