# ⍴⌽⊖⍉⍎⍕#

## Reshape ⍴#

We’ve met ⍴ (Greek Rho) in passing before. Let’s cover it in more depth. ⍴ is maybe the most fundamental function in an array language, as it allows the formation of multi-dimensional (high-rank) arrays. Note that ⍴ is not actually the Greek Rho in Unicode. Dyalog APL only uses the special Unicode APL Rho.

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'
3⍴'ab'
3⍴'abcd'
2 3⍴'abc'

aaa

aba

abc

abc
abc


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
⍴3 4 5∘.+10 20 30 40

13 23 33 43
14 24 34 44
15 25 35 45

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

13


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. If an array has no elements, then ⍴ will uses its prototype to fill any array it needs to form:

2 3⍴⍬

0 0 0
0 0 0


Recall that ⍬ is just 0⍴0 so it being simple and numeric, its prototype is 0.

## Reverse ⌽#

Monadic ⌽ is reverse. It reverses the leaf rank-1 sub-arrays of an array. For a matrix, it means reversing each row:

2 4⍴⍳8
⌽2 4⍴⍳8

1 2 3 4
5 6 7 8

4 3 2 1
8 7 6 5


For a vector, it simply means reversing the vector:

⎕A
⌽⎕A

ABCDEFGHIJKLMNOPQRSTUVWXYZ

ZYXWVUTSRQPONMLKJIHGFEDCBA


Of course, it doesn’t affect scalars.

## Reverse first ⊖#

⌽ has a sibling, just like / and \ have ⌿ and ⍀, namely reverse first, ⊖, 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

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
⊖4 2 3⍴⎕A

ABC
DEF

GHI
JKL

MNO
PQR

STU
VWX

STU
VWX

MNO
PQR

GHI
JKL

ABC
DEF


Dyadic ⌽ and ⊖ do rotations instead of reversals:

3⊖⎕A
1⊖4 2 3⍴⎕A

DEFGHIJKLMNOPQRSTUVWXYZABC

GHI
JKL

MNO
PQR

STU
VWX

ABC
DEF


Negative rotation amounts just rotate to the other way:

¯3⊖⎕A

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
1 0 2⌽3 4⍴⎕A
1 0 ¯1 0⊖3 4⍴⎕A

ABCD
EFGH
IJKL

BCDA
EFGH
KLIJ

EBKD
IFCH
AJGL


## Transpose ⍉#

⌽ 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
⍉3 4⍴⎕A

ABCD
EFGH
IJKL

AEI
BFJ
CGK
DHL


For arrays of rank higher than 2 it helps to think of the shape as being reversed:

⍉2 3 4⍴⎕A

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. Whilst 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

AM
EQ
IU

BN
FR
JV

CO
GS
KW

DP
HT
LX


Now we can keep the layers and only reverse (i.e. transpose) columns/rows:

1 3 2⍉2 3 4⍴⎕A

AEI
BFJ
CGK
DHL

MQU
NRV
OSW
PTX


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
1 1⍉3 4⍴⎕A
1 1 1⍉2 3 4⍴⎕A
1 1 2⍉2 3 4⍴⎕A

ABCD
EFGH
IJKL

AFK

AR

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

AEI
NRV


Here we merged layers and columns, i.e. 1st column of 1st layer and second column of 2nd layer. 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.

Here’s an example. Given a multiplication table, what were the numbers that generated it?

3 3⍴9 6 12 6 4 8 12 8 16 ⍝ A multiplication table

 9 6 12
6 4  8
12 8 16


In this case, the answer is 3 2 4:

∘.×⍨3 2 4

 9 6 12
6 4  8
12 8 16


We can ‘reverse engineer’ this by finding the square root of the diagonal elements:

1 1⍉3 3⍴9 6 12 6 4 8 12 8 16       ⍝ main diagonal
0.5*⍨1 1⍉3 3⍴9 6 12 6 4 8 12 8 16

9 4 16

3 2 4


## Execute ⍎#

Execute, ⍎, evaluates a string representing a line of APL. This can be any valid APL expression, including functions and multiple statements:

⍎'2+3'
2(⍎'+')3
⍎'a←2 ⋄ a←a+3 ⋄ a'

5

5

5


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. The result of ⍎ can be a monadic operator:

≢(⍎'¨')'abc' 'defg'

3 4


⍎ 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.

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'

base

sub


Here we first set a to 'base' in # (the root namespace), then we created the empty namespace ns, populated it there, then evaluated a here (in #) and then in ns. In other words, 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'

base

sub


Same as before, but here we used the “value” of ⍎ inside ns instead of ⍎’s value here.

## Format ⍕#

Format, ⍕, is really quite simple. It returns a simple character vector or matrix which displays exactly as if its argument had been displayed:

]display 1 2 3 4   ⍝ numeric vector
≢1 2 3 4

]display ⍕1 2 3 4  ⍝ convert to character vector
≢⍕1 2 3 4

┌→──────┐
│1 2 3 4│
└~──────┘

4

┌→──────┐
│1 2 3 4│
└───────┘

7


If you give ⍕ a left argument, it will display numeric values with that many decimals, rounding 5 up:

4⍕2÷3    ⍝ character vector of 2÷3 rounded to 4 dp
4⍕1 2 3÷3

 0.6667

 0.3333 0.6667 1.0000


If you give it two values as left argument, it will use the first as “field width” and the second as the number of decimal places:

20 4⍕1 2 3÷3

              0.3333              0.6667              1.0000


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

    0.3333                   1            1.0