Built-in Functions (10 of 14)
Contents
APL provides 50 or so built-in functions that do all the conventional operations and some rather sophisticated ones as well. It also provides 5 operators that modify and extend the way the functions work. These functions and operators can be used together very flexibly. Consequently it's possible to do a great deal in APL without ever leaving calculator mode: one APL line can be the equivalent of an entire subroutine in another language.
Arguments
Most APL functions are capable of doing two different but related tasks. The number of 'arguments' the function is given to work on determines which task it will perform. Here's the ⌈ function used first with one argument, then with two:
⌈12.625 13 2 ⌈ 8 8
In the first (monadic or one-argument) form, the function rounded up the number on its right to the next whole number. In the second (dyadic or two-argument) form it selected the bigger of the two numbers.
Here's another example:
÷1 2 3 4 5 1 0.5 0.3333333333 0.25 0.2 100÷1 2 3 4 5 100 50 33.33333333 25 20
In the first example the function ÷ was used with one argument. In this form it yields the reciprocal of the number, or numbers, on the right (i.e. the result of dividing 1 by each number). In the second example it was used with two arguments. In this form it does ordinary division. The left argument, 100, was divided in turn by each number in the right argument.
Execution order
A line of APL may consist of several functions, and arguments. There are therefore two points you must bear in mind:
- Expressions are evaluated from right to left.
- The results of one function become the argument of the next function.
This simple example illustrates both of these points:
50×2-1 50
The expression is evaluated from right to left so 2-1 is evaluated first, giving 1, and 50×1 is evaluated second, giving a final result of 50. The result produced by the subtract function became the right-hand argument of the multiply function.
Numbers or text
Some functions work on numbers only. The arithmetic functions are in this category. You'll get a message saying you've made a DOMAIN ERROR if you try to use any of the arithmetic operators on text data.
Some functions work on either. The ⍴ function, for example, can be used (with one argument) to find how many characters are in a text item, or how many numbers are in a numeric item. Its two-argument form (which you've seen used to shape data into a specified number of rows and columns) also works on either numbers or characters.
The logical functions (logical ^, ∨ and the rest of that family) work on a subset of the number domain. They recognise two states only, true or false as represented by the numbers 1 and 0. If any other numbers or characters are submitted to them, a domain error results.
Shape and size of data
Some functions can be used only on data of a certain shape. Matrix divide (⌹), for example, demands data structured in an appropriate way. Other functions work on data of any shape or size. Arithmetic, for example, can be done on single numbers, vectors of numbers, matrices of numbers, or on numeric arrays of higher rank (up to sixty-three dimensions).
Any two data items involved in arithmetic and certain other operations must, however conform in size and shape, that is, it must be possible for APL to match each element in the left-hand argument with each equivalent element in the right-hand argument. The arguments in this example don't match and an error results:
29 51 60 27÷3 11 LENGTH ERROR 29 51 60 27÷3 11 ^
The reasonable exception to this rule is the case where one argument consists of a single element and the other argument consists of a vector, matrix or multidimensional array:
39 5 91×2 78 10 182
APL simply applies the single element to each element in the other argument. There's no ambiguity about which element matches which, and no error results.
Groups of functions
In the rest of this chapter we take groups of functions that do related things and discuss briefly what each group does. A few examples are given, partly to illustrate particular functions and partly to 'acclimatise' you to APL.
To find out more about any function, see the documentation which came with your copy of APL.
The groupings chosen are:
- Arithmetic functions
- Algebraic functions
- Comparative functions
- Logical functions
- Manipulative functions
- Sorting and coding functions
- Miscellaneous functions and other symbols
- System functions
Arithmetic functions
All the usual arithmetic operations are provided. What makes APL arithmetic interesting is not the functions themselves, but the fact that they can be applied to simple or complicated data.
A multiplication, for example can take place between two numbers. Alternatively every number in one matrix can be multiplied by the corresponding number in a second matrix producing a third matrix of the products. (The scope of operations is extended further by the APL operators, but they are dealt with in the next chapter.)
Remember that each function is capable of two different operations, depending on whether it's used with one or two arguments. The different operations are identified in the table below.
Function |
One-argument form |
Two-argument form |
+ |
Identity (i.e. value) |
Add |
- |
Negation |
Subtract |
× |
Sign of |
Multiply |
÷ |
Reciprocal |
Divide |
⌈ |
Round up to integer |
Bigger of two numbers |
⌊ |
Round down to integer |
Smaller of two numbers |
| |
Make positive |
Residue (remainder) of division |
(Note: the - minus sign represents the negate and subtract functions, the ¯ sign is used to identify negative numbers.)
Examples of arithmetic functions
1. A vector of numbers is multiplied by a single number.
2 6 3 19 × 0.5 1 3 1.5 9.5
2. A vector of numbers is divided by a single number:
3 7 8 11 ÷ 3 1 2.333333333 2.666666667 3.666666667
3. A vector of numbers is divided by a single number. The results are rounded up to the next whole number and are then displayed:
⌈ 3 7 8 11 ÷3 1 3 3 4
4. The same operation as the last example, except that 0.5 is subtracted from each number before it's rounded up in order to give 'true' rounding:
⌈ ¯0.5 + 3 7 8 11 ÷3 1 2 3 4
5. Two vectors containing some negative values are added. × is applied to the resulting vector to establish the sign of each number. The final result is a vector in which each positive number is represented by a 1, each negative number by a ¯1 and each zero by a 0.
×12 ¯1 3 ¯5 + 2 ¯6 ¯4 5 1 ¯1 ¯1 0
6. The remainder of dividing 17 into 23 is displayed:
17 | 23 6
7. The remainders of two division operations are compared and the smaller of the two is displayed as final result:
(3 | 7 ) ⌊ 4 | 11 1
Algebraic functions
These are functions for doing more advanced arithmetic. The ⍟ (Log) function, for example, gives you either natural logarithms or logs to a specified base, while ○ (Circle) gives you access to sine, cosine, tangent and seven other trigonometric functions. Factorials and combinations can be obtained with ! (Factorial) and if you have a simultaneous equation to solve, or want to try a little matrix algebra, ⌹ (Domino) is your function.
Some functions have more everyday uses. The ⍳ (Iota) function will produce a series of numbers from 1 to the number you give it.
The ?(Query, Roll or Deal) function, for its part, 'rolls' you a single random number, or 'deals' you a hand of such numbers.
Function |
One-argument form |
Two-argument form |
⍳ |
Index generator |
|
? |
Random number |
Random deal |
* |
'e' to power |
Any number to power |
⍟ |
Log to base 'e' |
Log to any base |
○ |
pi times |
Sine, cosine, etc |
! |
1×2×3×.. |
Combinations |
⌹ |
Matrix inversion |
Matrix division |
Examples of algebraic functions
1. The numbers 1 to 10 are put in a variable called X.
X ← ⍳10 1 2 3 4 5 6 7 8 9 10
2. 3 random numbers between 1 and 10, with no repetitions.
3?10 2 8 3
3. The logarithm to the base 2 of 2 4 8.
2 ⍟ 2 4 8 1 2 3
4. The number of combinations of 2 items which can be made from a population of 4 items.
2 ! 4 6
Comparative functions
Comparative functions naturally take two arguments. The arguments are compared and if the condition specified by the function ('less than', 'equal to' or whatever) is true, the result is 1. Otherwise the result is 0.
Comparative functions are useful for finding items of data that meet certain conditions (e.g. employees whose sex equals 'M', or whose age is less than 55). They are also useful for making decisions about sequence in user-defined functions. For example, if a variable is greater than a certain value, you may want to branch to a particular point in the function.
Function |
Two-argument form only |
< |
Less than |
≤ |
Less than or equal |
= |
Equal |
≥ |
Greater than or equal |
> |
Greater than |
≠ |
Not equal |
≡ |
Match |
∊ |
Contained in |
⍳ |
Searches for match |
⍷ |
Find (not available in NARS2000) |
Examples of comparative functions
1. Are two given numbers equal? (1 = yes 0 = no)
10 = 5 0 12 = 12 1
2. Are the corresponding characters in two strings equal?
'ABC' = 'CBA' 010
3. Is the first number greater than the second?
10 > 5 1
4. Is each number in the first vector less than the matching number in the second vector?
3 9 6 < 9 9 9 101
5. Is the number on the left in the vector on the right?
12 ∊ 6 12 24 1
6. Is the character on the left in the string on the right?
'B' ∊ 'ABCDE' 1
7. Which numbers in a matrix are negative? (The contents of TABLE are shown first so that you can see what's going on.)
TABLE 12 54 1 ¯3 90 23 16 ¯9 2 TABLE < 0 0 0 0 1 0 0 0 1 0
8. Find the number on the right in the vector on the left and show its position.
13 7 9 0⍳9 3
9. Are two matrices exact matches?
(2 2⍴⍳4) ≡ (2 2⍴⍳4) 1
10. Find the pattern 'CAT' within the characters 'THATCAT'
'CAT ' ⍷ 'THATCAT ' 0 0 0 0 1 0 0
Logical functions
These are also comparative functions, but they work with data composed exclusively of 1s and 0s. Since the comparative functions you've just looked at produce results composed exclusively of 1s and 0s, you'll appreciate that a logical test is often applied to the result of a comparison.
For example, if you've used the comparative function > (greater than) to produce a vector of employees over the age of 25, you'll have a vector in which such employees are represented by a 1. If you've also applied the = (equals) function to your employee data to find cases where sex equals 'M', you'll have a separate vector in which 1s represent males. Now if you were to apply the logical ^ (and) function to these two vectors, it would compare the vectors, and produce a 1 each time both vectors contained a 1 in the equivalent position. The result would be yet another vector in which employees who were over 25 and male were represented by a 1.
Logical comparisons are also used in user-defined functions to control branching.
Function |
One-argument form |
Two-argument form |
~ |
Makes 1 into 0 and 0 into 1 |
|
∨ |
|
1 if either/both 1 (Or) |
^ |
|
1 if both 1 (And) |
⍱ |
|
1 if both 0 (Nor) |
⍲ |
|
1 if either/both 0 (Nand) |
Examples of logical comparison functions
1. ~ used to reverse 1's and 0's:
~1 1 1 0 0 0 1 0 0 0 1 1 1 0
2. The same data submitted to various logical functions:
1 ∨ 0 1 1 ^ 0 0 1 ⍱ 0 0 1 ⍲ 0 1
3. Each element in one vector is compared (^) with the matching element in another.
1 0 1 ^ 0 0 1 0 0 1
4. Two expressions are evaluated. If both are true (i.e. both return a value of 1) then the whole statement is true (i.e. returns a value of 1):
(5 > 4) ^ 1 < 3 1
Manipulative functions
These functions do a variety of useful operations on data.
The one argument form of ⍴ (Rho) enables you to find out the size of data. In its two argument form it enables you to specify how data is to be shaped or arranged. (There were many examples of this in the earlier chapter on data.)
≡ (Depth) tells you about the depth (or degree of nesting) of an array.
, Comma, in its one-argument form, can take a multi-dimensional object like a matrix, and unravel it into a single-dimensional vector. In its two-argument form, it can catenate separate data items to form single larger items, so that two matrices, for example can be amalgamated. The two-argument form of , can also join (or laminate) data items in such a way as to give the data an extra dimension. Two laminated vectors, for example, would form a matrix.
∊ (Enlist) turns any array, even nested arrays, into a simple vector.
⌽ (Rotate) and ⍉ (Transpose) can be used to reverse the ordering of data within arrays.
The ↓ and ↑ (Drop and Take) functions are useful for selecting data. You might, for example, wish to examine the first few members of a list with ↑.
~ (Without) can be used to remove items from a vector.
⊂ (Enclose) will turn arrays into nested scalars, useful for making complicated arrays, whilst ⊃ (Disclose) will reverse the process or select elements from nested arrays.
Function |
One-argument form |
Two-argument form |
⍴ |
Returns dimensions |
Creates vector or array |
≡ |
Depth of an array |
|
, |
Converts matrix or array to vector |
Catenates (joins) data items |
∊ |
Makes into vector |
|
~ |
|
Removes items |
⌽ |
Reverses elements |
Rotates elements |
⍉ |
Transposes columns and rows |
Transposes according to instructions |
↑ |
Takes first element of an array |
Takes from an array |
↓ |
|
Drops from an array |
⊂ |
Encloses an array |
Creates an array of vectors |
⊃ |
Discloses an array |
Picks from an array |
Examples of manipulative functions
1. An enquiry about the size of a character string:
⍴ 'ARLINGTON A.J, 22 BOND RD SPE 32E' 33
2. A three-row four-column matrix is formed from the numbers 1 to 12 and is assigned to 'DOZEN':
DOZEN ← 3 4 ⍴ ⍳ 12 DOZEN 1 2 3 4 5 6 7 8 9 10 11 12
3. The matrix 'DOZEN' is ravelled into a vector:
,DOZEN 1 2 3 4 5 6 7 8 9 10 11 12
4. The matrix 'DOZEN' is first converted to vector form and is then catenated (joined) with the vector 13 14 15):
(,DOZEN), 13 14 15 DOZEN 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
5. The matrix 'DOZEN' is re-formed from the original data in reverse order:
DOZEN ← 3 4⍴⌽,DOZEN 12 11 10 9 8 7 6 5 4 3 2 1
6. Even numbers are removed from a vector.
1 2 3 4 5 6 ~ 2 4 6 1 3 5
7. First 3 characters are selected from a vector:
3 ↑'AWFULLY' AWF
8. An array is made into a nested scalar.
⊂999 34 999 34 ⍴⊂999 34 (empty - no response)
The two element numeric vector is 'enclosed' into a single nested scalar, with an empty shape.
Sorting and coding functions
The sorting functions enable you to arrange data in ascending or descending order. You can either use the computer's collating sequence to determine sorting order, or you can specify your own collation sequence.
When looking at the examples of ⍋ and ⍒ (Grade up and Grade down), bear in mind that they don't produce a sorted version of the data to which they're applied. Instead they produce what is effectively an index which when applied to the original data will sort it into the required order.
The coding functions ⊤ and ⊥ (encode and decode) enable you to take data represented in one system and convert it to the equivalent value in another system. For example, you could convert numbers from hexadecimal (base 16) to decimal.
Function |
One-argument form |
Two-argument form |
⍋ |
Ascending sorted indices |
Sort with specified collating sequence |
⍒ |
Descending sorted indices |
Sort with specified collating sequence |
⊤ |
|
Convert to a new number system |
⊥ |
|
Convert back to units |
Examples of sorting and coding functions
1. To put a vector of numbers into ascending order:
LIST ← 200 54 13 9 55 100 14 82 ⍋LIST 4 3 7 2 5 8 6 1 LIST[4 3 7 2 5 8 6 1) 9 13 14 54 55 82 100 200
2. To sort the same vector as in example 1 with less typing:
LIST[⍋LIST] 9 13 14 54 55 82 100 200
3. To find how certain symbols rank in the collating order (i.e. the order in which APL holds characters internally):
SYMBS ← '"\;,./' ORDER ← ⍋SYMBS SYMBS[ORDER] ,./;\"
(Your result may vary depending on which APL you are using).
4. To convert the hex number 21 to its decimal equivalent:
16 16 ⊥ 2 1 33
Miscellaneous functions and other symbols
Many of these involve the input of data from the keyboard, or affect the way data is displayed or printed.
Function |
|
⎕ |
Accept numbers from keyboard or display result |
⍞ |
Accept characters from keyboard or display data |
⋄ |
Statement separator |
⍕ |
Format data for display |
⍝ |
Comment |
⍎ |
Execute an APL expression |
⌷ |
Index |
⌻ |
Empty numeric vector (Zilde) (Not all APLs support this) |
Examples of miscellaneous symbols
1. To carry out more than one APL statement on a single line, then to format the data (turn a number into its character equivalent) and make up a single character vector using the catenate function:
'TYPE A NUMBER' ⋄ NUM ← ⎕ 'YOU TYPED', ⍕NUM
2. To display each number in a vector in a 6-character field with two decimal places:
6 2 ⍕ 60.333333 19 2 52.78 60.33 19.00 2.00 52.78
3. To index the third item from a vector:
3 ⌷ 1 2 3 4 5 3
System functions
System Functions greatly extend the power of the APL language by making it easy to write code to achieve a number of tasks, for example
- Read and write native files
- Create charts
- Create GUI applications which use windows, menus, etc
- Use SQL databases
- Import and export data in popular formats
- Interface to code written in other computer languages
The choice of available system functions depends on which vendor's APL you are using, so you should consult the appropriate documentation.
NARS2000 Compatability issue