Conversation started Dec 20, 2017 at 18:30.
Dec 20, 2017 18:30
Welcome to the APL learning session!
Let's try to finish the functions' marathon, beginning with .
We've met (Greek Rho) in passing before. But now it is the actual subject.
is maybe the most fundamental function in an array language, as it allows the formation of multi-dimensional (high-rank) arrays.
IIRC, is not actually greek rho in unicode,
@Zacharý Right, Dyalog APL only uses the special Unicode APL Rho.
@Zacharý Useful if we ever allow Greek identifiers.
@Zacharý but it resembles one
The Greek letter Rho is has the sound of the letter R, and stands for Reshape.
The right argument of is used in ravel order to fill an array with the dimensions given by the left argument.
The left argument must therefore be a vector (list) of dimension lengths. (Although for ease of use, we do allow a scalar instead of a one-element vector.)
Another way to look at it is that the left argument of is the index of the last element in the resulting array (if you stick to the default ⎕IO of 1).
If you omit the shape (left argument) then the current shape is returned.
⍞←3⍴'a'
@Adám aaa
Dec 20, 2017 18:36
⍞←3⍴'ab'
@Adám aba
⍞←3⍴'abcd'
@Adám abc
⎕←2 3⍴'abc'
@Adám
abc
abc
Dec 20, 2017 18:37
That's two rows and three columns. The order of the left argument is the number of major cells first and of "leaf" cells last.
⎕←3 4 5∘.+10 20 30 40
@Adám
13 23 33 43
14 24 34 44
15 25 35 45
⍞←⍴3 4 5∘.+10 20 30 40
@Adám 3 4
A scalar doesn't have any dimensions, so the corresponding left argument is (or 0⍴0)
⍞←⍬⍴3 4 5∘.+10 20 30 40
@Adám 13
Dec 20, 2017 18:40
@all Good? Questions?
⎕←⍬⍬⍴3 4 5∘.+10 20 30 40
@Zacharý

Rebuilding user command cache... done
Was OFF -trains=box -fns=off
⍎DOMAIN ERROR
 __field_initialize_result_←(⎕NS ⍬).⍎'⎕CY''salt''⋄⎕SE.UCMD''box on -fns=on -trains=tree''⊣enableSALT' ⋄ ⎕←⍬ ⍬⍴3 4 5∘.+10 20 30 40
                                                                                                        ∧

Real time: 1.670 s
User time: 1.513 s
Sys. time: 0.059 s
CPU share: 94.11 %
Exit code: 0
@Zacharý You mean 0 0?
⎕←0 0⍴3 4 5∘.+10 20 30 40
@Zacharý

Rebuilding user command cache... done
Was OFF -trains=box -fns=off

Real time: 1.304 s
User time: 1.118 s
Sys. time: 0.056 s
CPU share: 89.95 %
Exit code: 0
Dec 20, 2017 18:41
yeah left argument must be a vector
@EriktheOutgolfer Simple vector, that is.
@Adám you mean non-nested right
because ⍬⍬ is nested
Right, I didn't cover empty arrays. If one or more dimensions are 0, then the array doesn't have any elements, but it is still there. If it has rank 2 or higher, then it has an empty default display, and the chat bot instead shows the debug info.
@EriktheOutgolfer Yes, in APL lingo, simple means non-nested.
⎕←0⍴1 2 3
@EriktheOutgolfer
Dec 20, 2017 18:43
⎕←0 0⍴1 2 3 4 5 6
@EriktheOutgolfer

Rebuilding user command cache... done
Was OFF -trains=box -fns=off

Real time: 1.174 s
User time: 1.102 s
Sys. time: 0.039 s
CPU share: 97.24 %
Exit code: 0
In Lesson 1 we covered prototypes, which are a feature of such empty arrays.
If an array has no elements, then will uses its prototype to fill any array it needs to form:
⎕←⍬+⍬
@RosLuP
⎕←2 3⍴⍬
Dec 20, 2017 18:45
@Adám
0 0 0
0 0 0
⎕←⍬+1
@RosLuP
Remember that is just 0⍴0 so it being simple and numeric, its prototype is 0.
@RosLuP Here 1 gets paired with every element of , but there are non, so the result is still and thus the bot gives you an empty line as result.
OK, I think we can move on now.
Monadic is reverses the leaf rank-1 sub-arrays of an array. For a matrix, it means reversing each row (not the order of rows, we'll get there):
⎕←2 4⍴⍳8
@Adám
1 2 3 4
5 6 7 8
⎕←⌽2 4⍴⍳8
Dec 20, 2017 18:48
@Adám
4 3 2 1
8 7 6 5
For a vector, it simply means reversing the vector:
⎕←⎕A ⋄ ⎕←⌽⎕A
@Adám
ABCDEFGHIJKLMNOPQRSTUVWXYZ
ZYXWVUTSRQPONMLKJIHGFEDCBA
Of course, it doesn't affect scalars.
It has a sibling, just like / and \ have and , namely which I usually call "Flip".
reverses the order of major cells, which for a matrix means reversing the order of the rows, i.e. flipping it upside down:
⎕←⊖2 4⍴⍳8
@Adám
5 6 7 8
1 2 3 4
For vectors, it is the same as and again it does nothing to scalars.
For a 3D array, it reverses the order of layers:
⎕←4 2 3⍴⎕A
Dec 20, 2017 18:52
@Adám
ABC
DEF

GHI
JKL

MNO
PQR

STU
VWX
⎕←⊖4 2 3⍴⎕A
@Adám
STU
VWX

MNO
PQR

GHI
JKL

ABC
DEF
Dyadic and do rotations instead of reversals:
⍞←3⌽⎕A
@Adám DEFGHIJKLMNOPQRSTUVWXYZABC
⎕←1⊖4 2 3⍴⎕A
Dec 20, 2017 18:54
@Adám
GHI
JKL

MNO
PQR

STU
VWX

ABC
DEF
Negative rotation amounts just rotate to the other way:
⍞←¯3⌽⎕A
@Adám XYZABCDEFGHIJKLMNOPQRSTUVW
Here is a cool feature of and : If you give them a vector of rotation amounts, they get distributed on the relevant cells:
⎕←3 4⍴⎕A
@Adám
ABCD
EFGH
IJKL
⎕←1 0 2⌽3 4⍴⎕A
Dec 20, 2017 18:56
@Adám
BCDA
EFGH
KLIJ
⎕←1 0 ¯1 0⊖3 4⍴⎕A
@Adám
EBKD
IFCH
AJGL
and also have a cousin named (Transpose). The monadic function does not reverse the major cells or the rank-1 cells, but rather reverses the order of the indices. For matrices this is normal transposing:
⎕←3 4⍴⎕A
@Adám
ABCD
EFGH
IJKL
⎕←⍉3 4⍴⎕A
Dec 20, 2017 18:59
@Adám
AEI
BFJ
CGK
DHL
But for arrays of rank higher than 2 it helps to think of the shape as being reversed:
⎕←2 3 4⍴⎕A
@Adám
ABCD
EFGH
IJKL

MNOP
QRST
UVWX
⎕←⍉2 3 4⍴⎕A
@Adám
AM
EQ
IU

BN
FR
JV

CO
GS
KW

DP
HT
LX
If you look carefully, you can see that the runs like ABCD which originally spanned rows are now spanning layers. Look at the top left corner of each new layer.
So too are the layers now spanning rows. Look how the top left of the layers, A and M are now next to each other in a row.
While the column AEI is still a column, because reversing the shape 2 3 4 (layers, rows, columns) gives 4 3 2 (columns, rows, layers) so the runs spanning rows are in the same position, still spanning rows.
Now you know how to reverse the order of axes, but what if you want an entirely new order. That's what dyadic does. The left argument is the indices of the axes in the desired order.
Therefore, if we reverse the indices of the rank, it is the same as monadic transpose:
⎕←3 2 1⍉2 3 4⍴⎕A
Dec 20, 2017 19:06
@Adám
AM
EQ
IU

BN
FR
JV

CO
GS
KW

DP
HT
LX
But now we can keep the layers and only reverse (i.e. transpose columns/rows):
And the number that the minimum number is depends on ⎕IO, correct>
⎕←1 3 2⍉2 3 4⍴⎕A
@Adám
AEI
BFJ
CGK
DHL

MQU
NRV
OSW
PTX
@Zacharý Yes.
Here is a very cool thing: You can duplicate indices in the left argument. If so, APL will merge the indicated axes, taking only the elements that have equal indices along those two axes. This is the diagonal or diagonal plane, or diagonal 3D array (!), etc.
⎕←3 4⍴⎕A
Dec 20, 2017 19:10
@Adám
ABCD
EFGH
IJKL
⎕←1 1⍉3 4⍴⎕A
@Adám
AFK
⎕←1 1 1⍉2 3 4⍴⎕A
@Adám
AR
⎕←1 1 2⍉2 3 4⍴⎕A
Dec 20, 2017 19:11
@Adám
ABCD
QRST
Here the layers and rows got merged, i.e. 1st row of 1st layer and 2nd row of 2nd layer, while the columns stayed as is.
⎕←1 2 1⍉2 3 4⍴⎕A
@Adám
AEI
NRV
Here we merged layers and columns, i.e. 1st column of 1st layer and second column of 2nd layer.
@Adám yeah, it's out-worldly
@all Quite a mouthful. Any questions? Any brain matter that needs mopping up from the floor?
6
Dec 20, 2017 19:16
@Adám "right left argument" ... I know what you mean, but still
Anyway, dyadic ⍉ is pretty advanced and quite rarely used, but when you need it (and can figure out the correct left argument — experiment!) it is really handy.
Right, now we move on to then.
I can see something like 1 1 ⍉ (or 0 0⍉) gets used a lot
@Zacharý Yeah, diagonals are nifty.
CMC: If I give you a multiplication table, can you tell me what the original numbers were?
E.g. for 3 3⍴9 6 12 6 4 8 12 8 16 the original numbers were 3 2 4.
⎕←3 3⍴9 6 12 6 4 8 12 8 16
@EriktheOutgolfer
 9 6 12
 6 4  8
12 8 16
Dec 20, 2017 19:22
{.5*⍨1 1⍉⍵}
square root along the diag lol
@LeakyNun that
@LeakyNun Ninja'd
@Zacharý Perfect.
Remember how evaluates polynomials and mixed-radix numbers?
btw @Zacharý you can also do it in a more proper way, avoiding reciprocals (well, theoretically at the very least) leading to imprecision
{(*∘2⍣¯1)1 1⍉⍵}
Dec 20, 2017 19:24
⎕←{.5*⍨1 1⍉⍵}3 3⍴9 6 12 6 4 8 12 8 16
@RosLuP
3 2 4
If ∘.×⍨⍣¯1 works (I don't think it does), that would be amazing
⎕←{1 1⍉⍵}3 3⍴9 6 12 6 4 8 12 8 16
@Zacharý I've already requested this.
@RosLuP
9 4 16
Dec 20, 2017 19:26
@EriktheOutgolfer Or {(×⍨⍣¯1)1 1⍉⍵}
@Adám well, I'm trying to make my code readable :p
@EriktheOutgolfer That is pretty readable
Anyhow, also evaluates, but rather than numbers, it evaluates a string representing a line of APL.
⍞←⍎'2+3'
@Adám 5
It works with functions too:
⍞←2(⍎'+')3
Dec 20, 2017 19:28
@Adám 5
And with multiple statements:
⍞←⍎'a←2 ⋄ a←a+3 ⋄ a'
@Adám 5
So, does that mean when interpreting trains, acts like reduce and scan?
@Zacharý What?
Since ⍎ can evaluate functions, is it also an operator?
Dec 20, 2017 19:31
huh
The result of is the result of the last statement, if that has a result. If it doesn't (e.g. it is an empty statement or has a leading {}), then doesn't have a result either.
@Zacharý You mean since it can return functions? No, normal tradfns can return functions too.
Oh, okay, that makes sense.
@Zacharý However, the result of can be a monadic operator:
⍞←≢(⍎'¨')'abc' 'defg'
@Adám 3 4
⍞←≢(⍎'⍎''¨''')'abc' 'defg'
Dec 20, 2017 19:33
@Zacharý 3 4
@Zacharý I remember a while ago being "disappointed" that that doesn't work :p
@Zacharý Here we go; APL pornography.
Um ... can you explain? Is this some sort of in-joke>
@EriktheOutgolfer APLers call unreadable and/or hacky APL pornography.
Dec 20, 2017 19:35
"porn" is an expression used to mean "pleasuring/extreme level/insane"
@Adám Sorry, I meant to type something else
@Adám and PPCG right here is a large example :p
Even something like A←'abcd',0⍴D←1 2 3 4 could be considered pornographic.
⍞←≢((⍎'⍎')'¨')'abc' 'defg'
@Zacharý 3 4
Dec 20, 2017 19:37
@Adám what is the problem with the train (1 1∘⍉,1↑(⍉,⊢))? I get LENGTH ERROR
⍞←(1 1∘⍉,1↑(⍉,⊢))4 4⍴1 2 2 2 2 1 0 0 3 0 1 0 4 0 0 1
@Uriel ERROR: Use ⎕← for a full error report
@Zacharý Yes yes, has all the features of a line of APL. You can run your entire program from . Indeed, when a workspace is loaded, APL automatically does ⍎⎕LX to bootstrap your application.
This is what causes the greeting message when you load a workspace like dfns.
those flags from over russian SO are tiring me...
@Uriel 1↑ returns a 1-row matrix, not a vector.
anyways
@Adám
⎕←⎕LX
Dec 20, 2017 19:39
@EriktheOutgolfer
from RIDE
Dyalog APL/S-64 Version 16.0.30863
Unicode Edition
Wed Dec 20 21:40:08 2017
      ⎕LX
looks like ⎕LX is emptied out after printing the greeting?
@EriktheOutgolfer It is empty in a clear workspace.
@Adám but how do you explain the above? does it have a self-emptying statement in it?
@EriktheOutgolfer No, you just didn't load a workspace that had ⎕LX ≢ ''
@EriktheOutgolfer I'm guessing that message is some built-in, separate from ⎕LX
Dec 20, 2017 19:43
⎕←DISPLAY '1234567', 9,3
@RosLuP

Rebuilding user command cache... done
Was OFF -trains=box -fns=off
⍎VALUE ERROR
 __field_initialize_result_←(⎕NS ⍬).⍎'⎕CY''salt''⋄⎕SE.UCMD''box on -fns=on -trains=tree''⊣enableSALT' ⋄ ⎕←DISPLAY'1234567',9,3
                                                                                                         ∧

Real time: 1.091 s
User time: 1.015 s
Sys. time: 0.042 s
CPU share: 96.92 %
Exit code: 0
@dzaima @EriktheOutgolfer Oh, that's what you mean. That banner is always printed when not in scripting or runtime mode.
⎕←⎕FMT '1234' , 9
@RosLuP
1234 9
@RosLuP You can't use the DISPLAY function if you have not defined it or copied it from somewhere else.
Dyadic is exactly like the monadic, but executes the expression in the namespace named in the left argument.
⎕←0 0⍴a←'base' ⋄ ns←⎕NS⍬ ⋄ ns.a←'sub' ⋄ ⍎'a' ⋄ 'ns'⍎'a'
Dec 20, 2017 19:47
@Adám
base
⎕←0 0⍴a←'base' ⋄ ns←⎕NS⍬ ⋄ ns.a←'sub' ⋄ ⎕←⍎'a' ⋄ ⎕←'ns'⍎'a'
@Adám
base
sub
So here I first set a to 'base' in # (the root namespace), then created the empty namespace ns, populated it there, then evaluated a here (in #) and then in ns.
So monadic is the same as dyadic but with the default left argument of ⎕THIS (this current namespace).
Nowadays, we usually "dot into" namespaces to evaluate there:
⎕←0 0⍴a←'base' ⋄ ns←⎕NS⍬ ⋄ ns.a←'sub' ⋄ ⎕←⍎'a' ⋄ ⎕←ns.⍎'a'
@Adám
base
sub
Same as before, but here I used the "value" of inside ns instead of 's value here.
Dec 20, 2017 19:51
⎕←]display '1234567', 9,3
@RosLuP

Rebuilding user command cache... done
Was OFF -trains=box -fns=off
⍎VALUE ERROR
 __field_initialize_result_←(⎕NS ⍬).⍎'⎕CY''salt''⋄⎕SE.UCMD''box on -fns=on -trains=tree''⊣enableSALT' ⋄ ⎕←]display'1234567',9,3
                                                                                                          ∧

Real time: 0.976 s
User time: 0.911 s
Sys. time: 0.033 s
CPU share: 96.70 %
Exit code: 0
Usually it doesn't matter which "definition" of primitives you pick up, if they have an implicit argument, then it does.
@Adám w...oah?
what special syntax is that
@RosLuP You can't call user commands from within code (which is what the chat bot uses).
]display '1234567', 9,676
Dec 20, 2017 19:53
@RosLuP And no, Stack Exchange chat isn't an APL interpreter. There's just a bot here which looks for incoming messages beginning with ⎕← or ⍞←.
@RosLuP Here you go! However, I would recommend getting a full desktop APL installed.
@EriktheOutgolfer You mean the . syntax? That's OO like in C# and Java. But that'll be for another time.
Let's finish up by covering .
@Adám I mean how can get in there...
@EriktheOutgolfer It doesn't. You're using the that's already in there.
⎕←⍎←+
@EriktheOutgolfer

Rebuilding user command cache... done
Was OFF -trains=box -fns=off
⍎SYNTAX ERROR
 __field_initialize_result_←(⎕NS ⍬).⍎'⎕CY''salt''⋄⎕SE.UCMD''box on -fns=on -trains=tree''⊣enableSALT' ⋄ ⎕←⍎←+
                                                                                                         ∧

Real time: 1.047 s
User time: 0.990 s
Sys. time: 0.030 s
CPU share: 97.46 %
Exit code: 0
is really quite simple. It returns a simple character vector or matrix which displays exactly as if its argument had been displayed:
⍞←1 2 3 4
Dec 20, 2017 19:58
@Adám 1 2 3 4
⍞←⍕1 2 3 4
@Adám 1 2 3 4
⍞←≢1 2 3 4
@Adám 4
⍞←≢⍕1 2 3 4
Dec 20, 2017 19:59
@Adám 7
⎕← x←]display '1234567', 9,676
@RosLuP

Rebuilding user command cache... done
Was OFF -trains=box -fns=off
⍎VALUE ERROR
 __field_initialize_result_←(⎕NS ⍬).⍎'⎕CY''salt''⋄⎕SE.UCMD''box on -fns=on -trains=tree''⊣enableSALT' ⋄ ⎕←x←]display'1234567',9,676
                                                                                                            ∧

Real time: 1.035 s
User time: 0.966 s
Sys. time: 0.034 s
CPU share: 96.61 %
Exit code: 0
@RosLuP You still can't use user commands (those that begin with ]) here. Use the link to TIO that I gave you.
@RosLuP on top of that, you can't assign variables to user commands
⎕→((⎕NS⍬).⍎'⎕CY''salt''⋄enableSALT')']display ''1234567'', 9,3'
Dec 20, 2017 20:01
@RosLuP Or if you really want:
⎕←⎕SE.UCMD'display ''1234567'', 9,676'
@Adám
┌→────────────┐
│1234567 9 676│
└+────────────┘
⎕←((⎕NS⍬).⍎'⎕CY''salt''⋄enableSALT')']display ''1234567'', 9,3
@Zacharý
line(1,135) : error AC0607: unbalanced quotes detected "(⎕NS⍬).⍎'⎕CY''salt''⋄⎕SE.UCMD''box on -fns=on -trains=tree''⊣enableSALT'⋄⎕←((⎕NS⍬).⍎'⎕CY''salt''⋄enableSALT')']display ''1234567'', 9,3"
                                                                                                                                                                                               ^
Complete: 1 error.
DOMAIN ERROR: There were errors processing the script
 '#'⎕NS ⎕FIX'file:///home/runner/.bin.tio.dyalog'
⎕←((⎕NS⍬).⍎'⎕CY''salt''⋄enableSALT')']display ''1234567'', 9,3'
@Zacharý
┌────────────────────────┬───────────────────────┐
│SALT is already enabled!│]display '1234567', 9,3│
└────────────────────────┴───────────────────────┘
Dec 20, 2017 20:02
@EriktheOutgolfer You mean capture the result of user commands? Yes you can, with x←⎕SE.UCMD or ]x←command
If you give a left argument, it will display numeric values with that many decimals, rounding 5 up:
⍞←4⍕2÷3
@Adám  0.6667
⍞←4⍕1 2 3÷3
@Adám  0.3333 0.6667 1.0000
And if you give it two values as left argument, it will use the first as "field width" and the second as decimals:
⍞←20 4⍕1 2 3÷3
@Adám               0.3333              0.6667              1.0000
Dec 20, 2017 20:06
in The Nineteenth Byte, 2 hours ago, by DJMcMayhem
CMC: (possibly to main later) A simple number, is a number whose only prime factors are 2 and/or 3. For example, 4, 8, 9, and 12 are all simple, but 10, 15, 17, and 21 are not. Given an integer n>=2, return the distance to the nearest simple number.
You can also use twice as many elements on the left as there are leaf cells on the right, and it will pair each two on the left to each one on the right:
⍞←10 4 20 0 15 1⍕1 2 3÷3
@Adám     0.3333                   1            1.0
@LeakyNun Wrong room?
@all I think that covers it. Any questions?
well, that matter would take some time to get correctly, but no questions
@EriktheOutgolfer Which matter?
Dec 20, 2017 20:08
@Adám no
@Adám well, I get the same feeling as if I had to study subject matter for school exams
OK, this concludes the lesson, and our APL functions' marathon. Thank you all for participating.
 
Conversation ended Dec 20, 2017 at 20:09.