Basic syntax

Functions and arguments

APL has two-argument, infix functions. These are called dyadic functions.

      3 × 5
15

      3 - 5
¯2

Some functions map between elements of their left and right argument arrays. It is easy to add lists of numbers together:

      1 2 3 + 4 5 6
5 7 9

Negative numbers are written with a high minus ¯ to differentiate between negation (-3) and literal negative numbers (¯3).

      1 2 3 - 1 0 ¯1
0 2 4

There are also one-argument, prefix functions. These are called monadic functions.

      - 5 ¯3 0 ¯4 2
¯5 3 0 4 ¯2

      ⌽ 1 2 3 4 5
5 4 3 2 1

Some symbols represent both a monadic and a dyadic function, but these are often closely related. As we will see later, even user-defined functions can be monadic, dyadic or even both (ambivalent).

Singleton extension

Dyadic functions can map between a single value and an array of values.

      3 × 1 10 100
3 30 300

      3 = 1 2 3 4 5
0 0 1 0 0

Try this: Replace the functions in the previous two expressions with: ⌈ ⌊ <

While experimenting, you may cause a LENGTH ERROR:

      1 2+3 4 5
LENGTH ERROR: Mismatched left and right argument shapes
1 2+3 4 5
∧

Functions such as + × ⌈ apply between elements of two arrays of the same shape, or between one element and many if one of the arguments is a single value. However, if the arrays are of two different shapes, it is not clear how the function should be applied. Of course, you may want to apply a function between all combinations of elements of the left and right argument, but that will be addressed soon enough.

Order of execution

Expressions are executed from right to left.

      10×⍳2+5
10 20 30 40 50 60 70

Show me step-by-step

To start, there is a literal number 5:

            5
5

Next, there is a plus + with a number 2 to its immediate left, so it is evaluated as two plus five:

          2+5
7

Then the symbol iota ⍳. To its left is another function, times ×, not a value. So the function is called monadically. The monadic form of ⍳ is the index generator, which generates an integer array of length defined by its right argument.

         ⍳2+5
1 2 3 4 5 6 7

Lastly, another dyadic function, we multiply our list by ten:

      10×⍳2+5
10 20 30 40 50 60 70

The expresssion above is "ten times the indices from 1 to two plus five, or in short: "ten times iota two plus five". We can make it clearer using (superfluous) parentheses ().

      10×(⍳(2+5))
10 20 30 40 50 60 70

Of course, we can change the order of execution using different parentheses.

      (10×⍳2)+5
16 17

Show me step-by-step

Beginning from the right, there is a literal number 5:

      (10+⍳2)+5
5

Then there is a plus symbol +. Before we can decide if it is being called monadically or dyadically, we must look to the left.

            )+5

A right parenthesis. We must evaluate the contents of the parentheses to see if it is a function or a value.

      (10+⍳2)

This expression evaluates to the list 11 12. Since it is a value, it is used as the left argument to our plus function.

      (10+⍳2)+5
(11 12)+5
16 17

Infix (dyadic) functions have a short left scope and long right scope. This means that they take the result of everything to their right hand side as their right argument.

If there is one, the left argument is the value to the immediate left.

However, juxtaposed values form lists before any functions are applied. This is called stranding and lets us write very natural expressions, such as:

      1 2 3 + 4 5 6
5 7 9

but this can lead to some surprises if we are not aware:

      2 + 2 2 + 2
6 6

Show me step-by-step

First, there is a literal number 2

                2
2

Then there is a symbol +. What, if any, is the value to its immediate left?

          2 2 + 2

It is a 2-element vector 2 2. The plus function maps between these elements and the single number on the right:

          2 2 + 2
4 4

Finally there is another addition. The overall evaluation looks like the following:

      2 + 2 2 + 2
2 + 4 4
6 6

Anything after a lamp symbol ⍝ is ignored.

      ⍝ nothing happens on this line
2 × 3 ⍝ 4 5
6

      'A'   ⍝ lamp is not an "A"
A

The reduction operator

Adding a list of numbers could become very tedious...

      1+2+3+4+5+6+7+8+9+10+11+12+13+14+15
120

The reduce operator F/ inserts the function F to its left between parts of the right argument array.

      +/1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
120

It is called reduce because it reduces the number of dimensions of its argument. In the example above, we have a vector (1 dimensional, list) argument and return a scalar (0 dimensional, single value) result.

The index generator

The index generator ⍳⍵ generates integers up to the integer right argument ⍵

      ⍳10
1 2 3 4 5 6 7 8 9 10

So we can do an arithmetic sum as follows

$$\sum_{n=1}^N n$$ +/⍳N

What do these errors mean?

While experimenting, you are very likely to come across these:

      ⍳¯4
DOMAIN ERROR
⍳¯4
∧

The DOMAIN ERROR means that APL cannot compute what you are asking for. In this case, it cannot generate indices up to a negative number. Negative numbers are outside the domain of the index generator function. How might you generate integers from 1 to negative four?

      1+
SYNTAX ERROR: Missing right argument
1+
∧

A SYNTAX ERROR means that the expression which you tried to execute does not make sense. In the case above, it is because functions always either take a single argument to their right or two arguments, one to the right and one to the left. Functions never take a single argument to their left.

      a
VALUE ERROR: Undefined name: a
a
∧

A VALUE ERROR means that there is nothing associated with the name provided. We have not seen any named functions or variables yet; nothing has been assigned to the name a, so trying to use it in an expression is meaningless.

Problem Set 1

1. The average daily temperatures, in degrees Celcius, for 7 days are stored in a variable t_allweek.

t_allweek ← 11.7 8.6 9.7 14.2 6.7 11.8 9.2

Use APL to compute the follwing:

1. The highest daily temperature
2. The lowest daily temperature
3. The range of (difference between the largest and the smallest) temperatures
4. Each temperature rounded to the nearest whole number

1.       ⌈/t_allweek
14.2
2.       ⌊/t_allweek
6.7
3.       (⌈/t_allweek)-⌊/t_allweek
7.5

You may have found the correct answer using the following expression:

      ⌈/t_allweek-⌊/t_allweek
7.5

but this is less efficient because it does more subtractions than it needs to. Recall the right-to-left evaluation:

      ⌈/      t_allweek                 - ⌊/ t_allweek
⌈/      t_allweek                 - 6.7
⌈/ 11.7 8.6 9.7 14.2 6.7 11.8 9.2 - 6.7
⌈/ 5 1.9 3 7.5 0 5.1 2.5
7.5

if we use parentheses () to force APL to compute the maximum of the list before doing subtraction, we only do a single subtraction instead of 7:

      ( ⌈/t_allweek ) - ⌊/ t_allweek
( ⌈/t_allweek ) - 6.7
(     14.2    ) - 6.7
7.5

4. To round to the nearest whole number, either add 0.5 and round down:
      ⌊0.5+t_allweek
12 9 10 14 7 12 9

or subtract 0.5 and round up:

      ⌈t_allweek-0.5
12 9 10 14 7 12 9

2. A Mathematical Notation

Use APL to evaluate the following

1. $$\prod_{n=1}^{12} n$$ (multiply together the first twelve integers)

2. $$\sum_{n=1}^{17}n^2$$ (add together the first seventeen squared integers)

3. $$\sum_{n=1}^{100}2n$$ (add together the first one hundred positive even integers)

4. $$\sum_{n=1}^{100}2n-1$$ (add together the first one hundred odd integers)

5. In TMN, the following equation equals 0, why does the following return 70?

      84 - 12 - 1 - 13 - 28 - 9 - 6 - 15  
70

1.       ×/⍳12
479001600
2.       +/(⍳17)*2
1785
Without parentheses we get the sum of the first 289 integers, instead of the first 17 integers squared.

TMN APL
$$\sum_n^{17^2} n$$ +/⍳17*2
$$\sum_n^{17} n^2$$ +/(⍳17)*2

3.       +/2×⍳100
10100
4. We can either subtract 1 from the even numbers:
      +/(2×⍳100)-1
10000

or we can add negative 1:

      +/¯1+2×⍳100
10000
The high minus denotes a literal negative, whereas the hyphen indicates subtraction.
5. Remember the right-to-left rule: functions take everything to their right, and the first thing to their left. We can add unnecessary parentheses to show how APL evaluates our expression.
      (84 - (12 - (1 - (13 - (28 - (9 - (6 - 15)))))))
70

3. Pyramid Schemes

1. Sugar cubes are stacked in an arrangement as shown by Figure 1.

This stack has 4 layers and a total of 30 cubes. How many cubes are there in a similar stack with 467 layers?

2. Now consider the stack in Figure 2.

The arrangement in Figure 2 has 4 layers and 84 cubes. How many cubes are there in a similar stack with 812 layers?

3. Now look at Figure 3.

The stack in Figure 3 has 3 "layers" and 36 cubes in total. How many cubes are there in a similar stack with 68 "layers"?

1. Each $$n$$th layer has $$n^2$$ cubes. There are $$34,058,310$$ cubes in a stack with $$467$$ layers.
    +/(⍳4)*2
30

    +/(⍳467)*2
34058310
2. Each $$n$$th layer has $$(2n-1)^2$$ cubes. There are $$713,849,500$$ cubes in a stack with $$812$$ layers.
    +/(¯1+2×⍳4)*2
84

    +/(¯1+2×⍳812)*2
713849500
3. Each $$n$$th layer has $$n^3$$ cubes. There are $$5,503,716$$ cubes in a stack with $$68$$ layers.
    +/(⍳3)*3
36

    +/(⍳68)*3
5503716

4. Rewrite the following expressions so that they do not use parentheses.

1. (÷a)×b
2. (÷a)÷b
3. (a+b)-5
4. (a+b)+5
1. Multiplication is commutative, so we can write b×÷a
2. $${{{1}\over{a}}\div{b}} = {{1}\over{a\times{b}}}$$ so we can write ÷a×b
3. Use a literal negative five:¯5+a+b
4. No parentheses needed: a+b+5