After the introduction to APL in the last post, let's now look in more detail on how APL works.

As the emulated system dows not support entry and display of APL symbols, we will have to use transliterations, eg * for the multiply symbol ×. The code samples below show the original version on the left and the transliterated version on the right. An appendix at the end of this post lists all symbols used and their transliterations.

The interpreter

Similar to the last language we looked at, PIL, when APL starts up it allows you to enter expressions and get results immediately. The prompt is eight leading spaces and results are printed in the first column.

        21 × 2
42  
        21 * 2
42  

Monadic and dyadic functions

We can enter simple arithmetic functions and get results as expected.

        21 + 2
23  
        21 − 2
19  
        21 ÷ 2
10.5  
        21 + 2
23  
        21 - 2
19  
        21 / 2
10.5  

These are all dyadic functions, ie they take a left and right parameter. Many APL functions also have monadic versions which take only one parameter on the right. Let's look at how the four basic arithmetic functions work:

        +21
21  
        −21
−21  
        ×21
1  
        ÷21
0.04761904762  
        +21
21  
        -21
_21  
        *21
1  
        /21
0.04761904762  

Plus and minus work as expected; note that negative numbers are displayed with a leading underscore to represent the symbol. Multiply and divide give more interesting results. Multiply gives the signum of its parameter: -1 if negative, 0 if zero or 1 if positive. Divide gives the reciprocal of its parameter.

The modulus operator ( or $|) works the opposite way around from what you may be used to from other languages, so 10 ∣ 12 is 2.

Order of execution is strictly right to left; using brackets allows you to specify what operators works on what parameters

        2×3+2
10  
        ÷2×3+2
0.1  
        (2×3)+2
8  
        2*3+2
10  
        /2*3+2
0.1  
        (2*3)+2
8  

Variables and types

Values can be assigned to a variable with (=). Variable names need to start with a letter. Underlined letters can also be used; these are transliterated to lower case letters.

        X ← 3
        Y ← 22
        Z ← X × Y
        Z
66  
        X = 3
        Y = 22
        Z = X * Y
        Z
66  

As well as single numbers, you can have vectors of numbers. These are entered by separating the elements with spaces. Operators work on vectors as well.

        X ← 1 2 3
        Y ← 10 100 1000
        X × Y
10  200  3000  
        X = 1 2 3
        Y = 10 100 1000
        X * Y
10  200  3000  

If the dimension of the parameters differ, APL will extend the shorter vector as appropriate - so 1 2 3 × 2 will give 2 4 6.

Strings are introduced using quotes; internally APL treats them as vectors of characters.

Booleans are represented as numbers with a value of 0 or 1. These are returned by comparison functions like equal, greater or equal (=, or =, $GE). Logical operators like and ( or &) can operate on these.

        3 ≥ 2
1  
        (3 ≥ 2) ∧ (2 = 2)
1  
        3 $GE 2
1  
        (3 $GE 2) & (2 $EQ 2)
1  

Vector functions

The rho function ( or $,) gives the dimension of a vector when used moadically. Used dyadically, it can create a matrix from a vector on its right side by giving the shape on the left side.

        ⍴ 10 20 30
3  
        X ← 1 2 3 4 5 6 7 8 9 10
        2 5 ⍴ X
1   2   3   4   5  
6   7   8   9  10  
        $, 10 20 30
3  
        X = 1 2 3 4 5 6 7 8 9 10
        2 5 $, X
1   2   3   4   5  
6   7   8   9  10  

Comma (,) used dyadically is called catenate, and adds to a vector.

        x ← 1 2 3 4 5
        x , 6
1  2  3  4  5  6  
        x = 1 2 3 4 5
        x , 6
1  2  3  4  5  6  

Monadic comma (known as ravel) turns a scalar into a vector

         ,1
 1  
         ,1
 1  

A vector of length 1 looks like a scalar when displayed. We can tell them apart with double rho, which gives the rank.

         ⍴⍴ 1
 0  
         ⍴⍴ ,1
 1  
         $,$, 1
 0  
         $,$, ,1
 1  

Iota (, which can be transliterated as any of $IO, $IN or $.) creates a sequence when used monadically and gives index positions when used dyadically. Square brackets can be used to extract elements based on index positions.

        ⍳ 5
1  2  3  4  5  
        X ← 'ABCDEFGHIJ'
        X ⍳ 'CAFE'
3  1  6  5  
        X ⍳ 'CAZE'
3  1  11  5  
        X[X ⍳ 'CAFE']
CAFE  
        $IO 5
1  2  3  4  5  
        X = 'ABCDEFGHIJ'
        X $IN 'CAFE'
3  1  6  5  
        X $IN 'CAZE'
3  1  11  5  
        X[X $IN 'CAFE']
CAFE  

More APL functions

There are over 50 APL functions so it would be difficult to go through them all here, but let's take a brief tour to show some of them in action.

Ceiling ( or $CE, $MA) and floor ( or $FL, $MI) rounds up/down when used monadically and finds the max/min when used dyadically

         ⌈ 2.3
 3  
         ⌊ 2.3
 2  
         3 ⌈ 2
 3  
         $CE 2.3
 3  
         $FL 2.3
 2  
         3 $CE 2
 3  

Factorial (!) means take m of n when used dyadically:

        !5
120  
        2 ! 4
 6  
        !5
120  
        2 ! 4
 6  

Rotation (, $RO):

        ⌽ 1 2 3
3  2  1  
        2 ⌽ 1 2 3
3  1  2  
        $RO 1 2 3
3  2  1  
        2 $RO 1 2 3
3  1  2  

Take (, $TA) and drop (, $DR):

        3 ↑ ⍳ 10
1  2  3  
        3 ↓ ⍳ 10
4  5  6  7  8  9  10  
        3 $TA $IO 10
1  2  3  
        3 $DR $IO 10
4  5  6  7  8  9  10  

Grade up ( or $GU) gives sorted indices, with grade down doing sort in reversed order.

        X ← 2 14 1 42
        ⍋ X
3  1  2  4  
        X[⍋ X]
1  2  14  42  
        X = 2 14 1 42
        $GU X
3  1  2  4  
        X[$GU X]
1  2  14  42  

? used monadically is known as roll, producing a random number between 1 and the right hand argument. Used dyadically, it is known as deal: x ? y means take x unique items at random from the population 1 .. y.

        ?6
3  
        ?6
5  
        3 ? 6
6  2  3  
        3 ? 6
3  4  5  
        ?6
3  
        ?6
5  
        3 ? 6
6  2  3  
        3 ? 6
3  4  5  

Decode ( or $DE, $BA) converts bases. Encode ( or $EN, $RP) goes the other way. Below we show 2 hours 30 minutes decoded into number of minutes and then re-encoded.

        60 60 ⊥ 2 30
150  
        60 60 ⊤ 150
2  30  
        60 60 $DE 2 30
150  
        60 60 $EN 150
2  30  

Operators

An operator in APL differs from a function in that it takes a function on its left hand side. One example is reduction (/ or %): in the example below we give it the plus function which will sum up the elements on the right

        +/ 1 2 3 4
10  
        +% 1 2 3 4
10  

Let's try it with -:

        -% 1 2 3 4
-2
        -% 1 2 3 4
_2  

Why does it return -2? This is due to the right to left associativity of APL: we coild expand this as 1 - (2 - (3 - 4)).

Defining your own functions

You can define your own functions with del ( or "), Starting a line with del creates a function: the rest of the line specifies the variable that will contain the return value, the function name and its parameters. On subsequent lines, APL will prompt you for the next statement with the line number. A del on its own will close the function. A simple example for a monadic function called INCR that increments its right hand side:

        ∇ C ← INCR A
<1>     C ← A + 1  
<2>     ∇  
        INCR 3
4  
        " C = INCR A
<1>     C = A + 1  
<2>     "  
        INCR 3
4  

Dyadic functions are created by giving variables before and after the function names. For example, the hypotenuse function:

        ∇ C ← A HYP B
<1>     C ← ((A⋆2) + (B⋆2)) ⋆ 0.5  
<2>     ∇  
        3 HYP 4
5  
        " C = A HYP B
<1>     C = ((A@2) + (B@2)) @ 0.5  
<2>     "  
        3 HYP 4
5  

Apart from the parameters, any variables used in defined functions will be global by default. To set up local variables, add a semicolon and the variable names on the function definition line.

        ∇ Z ← X FOO Y; A
<1>     A ← X + Y  
<2>     Z ← A + 2  
<3>     ∇  
        3 FOO 5
10  
        " Z = X FOO Y; A
<1>     A = X + Y  
<2>     Z = A + 2  
<3>     "  
        3 FOO 5
10  

Flow control in a function can be introduced with the branch function ( or $GO), which takes the line number to branch to on the right hand side. Branching to line number 0 is equivalent to returning from the function: we saw the in part 1 of this series with the line

→ 2 × N < 5
$GO 2 * N $LE 5

which would branch to line 2 if N was less than 5, else return from
the function.

After defining a function, you can list its contents by entering del, the function name, quad ( or #) in square brackets then del, all on the same line.

∇FOO[⎕]∇
"FOO[#]"

You can edit or append lines in a function by replacing quad in the above example with a line number. Line numbers can include decimal points, eg to insert a line between current lines 1 and 2 you'd do ∇FOO[1.5]∇

To delete an entire function you need to use the erase system command with the function name, eg )ERASE FOO.

System commands and workspaces

System commands, starting with ), manipulate the APL environment. )OFF will quit APL, )FNS and )VARS will list currently defined functions and variables respectively.

To manage sets of functions and variables, APL has the concept of workspaces. The current set can be saved to a named workspace, eg FOO by the user with the command )SAVE FOO and then loaded later with )LOAD FOO. APL will also automatically save the current set to the workspace CONTINUE on exit and load it again at startup. To wipe out the current running set, use )CLEAR; to delete from disk user )DROP ws.

There are also system workspaces, organised into libraries identified by numbers. Use )LIB n to see the workspaces in library n and then )LOAD n ws to load a names workspace. For example, let's look at the workspace APLCOURSE in library 1. This defines a function DESCRIBE which explains its contents.

        )LIB 1
ADVANCEDE  
APLCOURSE  
CLASS  
NEWS  
PLOTFORMA  
TYPEDRILL  
WSFNS  
EIGENVALU  
BRFNS  
        )LOAD 1 APLCOURSE
SAVED  16.13.05 08%08%68  
        )FNS
B1X     CHECK   DESCRIBE        DIM     DRILL   DYAD1   DYAD2   EASY  
EASYDRILL       FORM    FUNDRILL        GET     INPUT   QUES    RANDOM  
REDSCAPATCH     REPP    TEACH  
        DESCRIBE

THE MAIN FUNCTIONS IN THIS LIBRARY WORKSPACE ARE:  

                         TEACH  
                         EASYDRILL  

ALL OTHER FUNCTIONS ARE SUBFUNCTIONS AND ARE NOT  
SELF-CONTAINED.  
SYNTAX                         DESCRIPTION  
______                         &#95;&#95;&#95;&#95;&#95;&#95;&#95;&#95;&#95;&#95;&#95;  
TEACH           AN EXERCISE IN APL FUNCTIONS USING SCALARS  
                AND VECTORS.  THE FUNCTION PRINTS OUT THE  
                CHOICES AND OPTIONS AVAILABLE.  EXAMPLES  
                ARE SELECTED AT RANDOM WITH A RANDOM  
                STARTING POINT.  

EASYDRILL       THIS IS THE SAME AS TEACH EXCEPT THAT THE  
                PROBLEMS SELECTED ARE GENERALLY SIMPLER IN  
                STRUCTURE.  PROBLEMS INVOLVING VECTORS OF  
                LENGTH ZERO OR ONE ARE EXCLUDED.  

Workspace 6 contains a resource management game called KINGDOM.

In the next post we'll look at implementing a real program in APL.

Further information

This post has only scratched the surface of APL. See the Further Information section in the APL introduction post for more resources to learn about APL.

Appendix: Transliterations

This is a copy of the table UM Computing Center Memo 382, excluding characters that are marked as not in use.

Meaning APL Symbol Transliteration
And &
Branch $GO $>
Ceiling $CE $MA
Circular functions $$ $CI $PI
Comma , ,
Comment / lamp $* $CO
Compression / %
Compression axis 1 $C1
Deal / random ? ?
Decode $DE $BA
Del "
Delta Δ $"
Delta underlined $U"
Divide ÷ /
Drop $DR $DO
Encode $EN $RP
Equal = $EQ
Expansion \ $%
Expansion axis 1 $X1
Exponentiation @
Factorial ! ! $FA $BC
Floor $FL $MI
Grade down $GD
Grade up $GU
Greater or equal $GE
Greater than > $GT
Ibeam $IB $SY
Iota $IO $IN $.
Less or equal $LE
Less than < $LT
Locked function $L"
Logarithm $@ $LO $LN
Membership $EP $ME
Minus -
Modulus | $MO
Multiply × *
Nand $N&
Negation / overbar _ $-
Nor $N| $WR
Not ~ $NO
Not equal $NE
Null $:
Or | $OR
Period . .
Plus + +
Quad #
Quad-quote $#
Quote ' '
Random ? ?
Rho / dimension $, $RH $DI
Rotation $RO $RV
Rotation axis 1 $R1
Semicolon ; ;
Specification =
Take $TA $UP
Transposition $TR
Underlined letters A - Z a - z _A - _Z