1 min read

APL a Day #7: Scalar Functions

Scalar functions perform most of the hard labor in an APL program. A scalar function defines a mapping from one or two scalar values to a third value. In math, the addition function maps two numbers to their sum. Many other such functions exist. The following table gives all the built in primitive scalar functions defined in APL:

Symbol Monadic Dyadic
+ Identity Plus (Add)
- Negative Minus (Subtract)
× Direction (Signum) Times (Multiply)
÷ Reciprocal Divide
| Magnitude Residue
Floor Minimum
Ceiling Maximum
* Exponential Power
Natural Logarithm Logarithm
Pi Times Circular
! Factorial Binomial
~ Not $
? Roll $
Enlist $
^   And
<   Less
  Less Or Equal
=   Equal
  Greater Or Equal
>   Greater
  Not Equal
$ Dyadic form is not scalar

Unlike in normal math, APL extends every scalar function to work for any array, not only scalars. When used monadically, a scalar function gives an array whose shape matches the shape of its input. Each element of the result is the value defined on the corresponding element in the input argument. Thus, the negate function computes the negation of each element in its input argument. The value of each element in the result comes only from the corresponding elements of the input arguments. Thus, the following equivalency, where f is a scalar function:

i⌷A f B ←→ (i⌷A) f i⌷B

The above assumes that A and B have the same shape. Unless one is a scalar, A and B must have the same shape to use as inputs to a scalar function. If one input is a scalar, then it behaves as if reshaped to the shape of the other input. The following implications describe this "scalar extension" behavior:

⍬≡⍴A → A f B ←→ ((⍴B)⍴A) f B
⍬≡⍴B → A f B ←→ A f (⍴A)⍴B

Finally, the shape of the result of a scalar function follows this equivalency, where A and B have the same shape:

(⍴A f B) ←→ ⍴A ←→ ⍴B

Other primitive functions follow different rules, but all scalar functions obey the above rules.