Formal Function Definition
This chapter concerns the scheme of formal function definition introduced in Section 1.3. In includes exercise which apply the basic scheme to a number of topics familiar in elementary mathematics. It also extends the basic schemes to include recursive definition, a form of definition which makes it easy to handle the formal definitions such as the quotient of polynomials. Section 10.3 defines a comprehensive set of functions for handling polynomials.
[The point at which each group of exercises can be attempted
is indicated by a marginal note consisting of
a domino (⌹) followed
by the number of the first exercise in the group.
The groups are separated by horizontal lines.]
10.1 Variables in a Function Definition
The expression defining a function may include one or more variables; these variables must, of course, be assigned values before the function is executed. For example:
h:⍺×⍵*n n←2 n←3 3 h 4 3 h 4 48 192 ⌹1
Local variables. Consider the following function definition:
m:1+(⍺-⍵)×2+(⍺-⍵)×3+(⍺-⍵)×4 3 m 1 49
Since the expression ⍺-⍵ occurs repeatedly, it would be convenient to assign a variable name to the result ⍺-⍵ and use it in all positions, as follows:
p:1+x×2+x×3+(x←⍺-⍵)×4 3 p 1 49
The assignment of a value to the variable must be executed before (and therefore occur to the right of) any use of the variable. Thus, the following definition would not work, and attempted use of the function on a computer would invoke a value error message:
A variable which is assigned a value within a function definition is local to the function in the sense that it has meaning only within the execution of the function and has no effect on assignments made outside the function. For example:
x←7 3 p 1 49 x 7 ⌹13
10.2 Recursive definition
A function definition is said to be recursive if the function being defined recurs in the expression defining it. This notion may be familiar from informal definitions. For example, the power function x*n may be said to equal x times x*n-1 , and the factorial function !n may be said to equal n×!n-1 .
Let us attempt to define the factorial function fac in this manner:
To interpret the expression fac 4 we would proceed by substitution as usual:
fac 4 4×fac 3 4×3×fac 2 4×3×2×fac 1
It is clear that this procedure can be terminated meaningfully only if we know the value of fac x for some value of the argument x . In this case, fac 1 is equal to 1 , and with this knowledge we can terminate the interpretation as follows:
In general, it is necessary to know a second expression for the definition (in this case the simple expression 1) and the condition under which it is to be applied (in this case when ⍵=1). The recursive definition of factorial therefore requires the following three pieces of information:
In a formal definition these three data are presented in the foregoing order with colons separating them. Thus:
fac:⍵×fac ⍵-1:⍵=1:1 fac 4 24
A proposition is a function which yields one of two values, 0 (representing false) or 1 (representing true). In a recursive definition the proposition is executed first; its result determines which defining expression is to be used, the primary if the result is 0 , and the secondary if the result is 1 . The secondary expression must not include within it the function being defined.
A more suitable definition of the factorial function would, in fact, include the argument 0 as follows:
A recursive definition of the power function which is equivalent (for non-negative integer arguments) to ⍺*⍵ could be made as follows:
pow:⍺×⍺ pow fac ⍵-1:⍵=0:1
The interpretation of 2 pow 3 would proceed as follows:
2 pow 3 2×2 pow 2 2×2×2 pow 1 2×2×2×2 pow 0 2×2×2×1 8
Many functions which are difficult to define in other ways are easy to define recursively. Moreover, many functions easily defined in other ways may profitably be defined recursively, since the recursive definition may provide better understanding of certain properties of the function.
10.3 Functions for Handling Polynomials
This section is intended to provide further examples of both recursive and non-recursive function definitions, and to illustrate the development of a coherent set of functions for the treatment of a single topic. The topic chosen is that of polynomials expressed in the form introduced in Section 1.5.
The basic notion is to represent a polynomial
in terms of its vector of coefficients.
For example, if the coefficients are
+/3 1 4 2×x*0 1 2 3 37
The definition of the polynomial function (given in a slightly different form in Equation 1.5.1) is therefore:
where n yields the number of elements in its argument, and is defined as follows:
x←2 c←3 1 4 2 n c 4 ⍳n c 0 1 2 3 c p x 37 1 3 3 1 p 2 27
(c p x)+d p x 64
Moreover, the polynomial with coefficients c+d has the same value:
c+d 4 4 7 3 (c+d) p x 64
If the vectors c and d do not have the same number of elements, the expression c+d will not yield the sum; it is necessary to extend one of them by final zeros (which do not change the value of the polynomial represented). Addition of the vectors of coefficients of two polynomials can be performed by the following function:
plus:(ml↑⍺)+(ml←(n⍺)⌈n⍵)↑⍵ c←3 1 4 d←1 2 3 4 5 c plus d 4 3 7 4 5 d plus c 4 3 7 4 5 (c plus d) p 2 150 (c p 2)+d p 2 150
A function for the subtraction of polynomials could be defined similarly, but it is clearer and simpler to use the function plus in its definition:
minus:⍺ plus -⍵ c minus d 2 ¯1 1 ¯4 ¯5
An informal scheme for multiplying polynomials is developed in Section 1.7, and is formalized in Ex 1.74. An equivalent function is provided by the following recursive definition (whose details can be made clear by working through the detailed substitutions of a simpler example):
times:(⍺×1↑⍵) plus 0,⍺ times 1↓⍵:0=n⍵:0 1 2 1 times 1 3 3 1 1 5 10 10 5 1 (1 2 1 times 1 3 3 1) p 3 1024 (1 2 1 p 3)×1 3 3 1 p 3 1024 ⌹24
Division of one polynomial by another is effected by the following function:
into:z,⍺ into 1↓⍵ minus ⍺×z←(1↑⍵)÷1↑⍺:(n⍺)>n⍵:⍳0 a←1 2 1 b←1 5 10 10 5 1 c←0 0 0 0 2 8 d←b plus c d 1 5 10 10 7 9 a into b 1 3 3 1 a into d 1 3 3 1 rem←d minus a times a into d rem 0 0 0 0 2 8
From the foregoing example, it appears that the division performed by into yields a high-order remainder, as defined in Section 1.7. A similar definition could be made for a lower-order division function, but it is easier to define it in terms of into as follows:
linto:⌽(⌽⍺) into ⌽⍵ a linto b 1 3 3 1 a linto d ¯25 23 ¯11 9 rm←d minus a times a linto d rm 26 32 0 0 0 0
Considered as a coefficient vector,
the last result above is equivalent to the
curt:(-+/⌊\0=⌽⍵)↓⍵ curt rm 26 32
A polynomial with coefficients 1 ,
or 1 0 , or
v←20↑1 v 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 a←1 1 ar←a into v ar 1 ¯1 1 ¯1 1 ¯1 1 ¯1 1 ¯1 1 ¯1 1 ¯1 1 ¯1 1 ¯1 1 ar p .5 0.6666679382 ÷a p .5 0.6666666667 b←1 2 1 br←b into v br 1 ¯2 3 ¯4 5 ¯6 7 ¯8 9 ¯10 11 ¯12 13 ¯14 15 ¯16 17 ¯18 br p .5 0.4443969727 ÷b p .5 0.4444444444
The function p:+/⍺×⍵*⍳n⍺ applies only
to a scalar right argument and fails to work properly
on a vector right argument,
for reasons that may be seen in attempting
A corresponding function which applies to a vector right argument may be defined recursively as follows:
pvra:(⍺ p 1↑⍵),⍺ pvra 1↓⍵:0=n⍵:⍳0 1 3 3 1 pvra 2 5 27 216 1 3 3 1 pvra 2 5 7 9 27 216 512 1000
The entire set of functions developed for handling polynomials is collected below:
p:+/⍺×⍵*⍳n⍺ n:+/⍵=⍵ plus:(ml↑⍺)+(ml←(n⍺)⌈n⍵)↑⍵ minus:⍺ plus -⍵ times:(⍺×1↑⍵) plus 0,⍺ times 1↓⍵:0=n⍵:0 into:z,⍺ into 1↓⍵ minus ⍺×z←(1↑⍵)÷1↑⍺:(n⍺)>n⍵:⍳0 linto:⌽(⌽⍺) into ⌽⍵ curt:(-+/⌊\0=⌽⍵)↓⍵ pvra:(⍺ p 1↑⍵),⍺ pvra 1↓⍵:0=n⍵:⍳0 ⌹25
10.4 The Function def
Throughout this text, function definitions have been presented in the ⍺⍵ form introduced in Section 1.3 and elaborated in Section 10.1. In order to make any function so defined available for use on an APL computer it is necessary to fix the definition. The function def has been assumed to perform this function: if it is already available in the computer it may be used as shown in Section 1.4; if not, its definition must itself be fixed before it can be used.
This section discusses the steps necessary to develop and fix the function def . If it is simply desired to fix the definition def as quickly as possible, the reader may follow the summary steps at the end of this section. On the other hand, the section may be studied as a whole for its own interest since it clarifies the important notion of representation, and uses and exemplifies the important technique of “bootstrapping”. This term arises from the paradoxical notion of “pulling yourself up by your own bootstraps”, and is used here to refer to the scheme of using a function already fixed as a tool in developing and fixing the next one.
In the course of this process, several functions are produced which can be used to fix the definitions of certain functions, but all except the function def defined at the end are deficient in some respect, and will fail to work in certain cases. For example, the function is9 will work only on simple (non-recursive) definitions.
The essential service performed by the function def is to transform the ⍺⍵ representation of a function into a form directly usable by the APL computer. Since we will be concerned with different representations of a function, we shall first attempt to clarify the notion of representation, beginning with the more familiar notion of different representations of numbers.
The representation of numbers. Numbers are commonly represented by strings of numeric characters, just as words are represented by strings of alphabetic characters. Thus the numeric characters 1 and 4 and 4 strung together represent the number of items in a gross, just as the letters M and a and r and y together represent a name.
Confusion can sometimes arise if we fail to distinguish a representation from the thing represented. For example, the sentence Mary has four letters could refer either to the volume of a girl’s correspondence or to the length of her name. The necessary distinction is normally made by enclosing the alphabetic characters in quotes when referring to the representation itself. Thus the sentence 'Mary' has four letters is unambiguous, and refers to the length of a girl’s name.
In the case of numbers, the need to distinguish between a number and its representation does not arise very often, and it therefore tends to be particularly confusing when it does. We will also use quotes to enclose numeric characters; thus '144' and '10010000' and 'CXLIV' are each a character string representing the number of items in a gross, the first representation being in decimal, the second in binary (base two), and the last in Roman numerals.
Just as we cannot truthfully say 'Mary' can walk , neither can we add '144' to '1024' , although we can say Mary can walk , and we can add 144 to 1024 . This distinction can be clarified by considering the execute function (denoted by ⍎); applied to a numeric character string it yields the number represented by the string. For example:
(⍎'144')+⍎'1024' 1168 '144'+'1024' DOMAIN ERROR
More generally, the execute function applied to any character string treats it as an APL expression and executes (that is, evaluates) it. For example:
⍎'144+1024' 1168 ⍎'Mary←144+1024' b←⍎'144+1024' Mary b 1168 1168
Just as names can be assigned to numeric quantities, so can they be assigned to character strings. For example:
a←'144' b←'1024' (⍎a)+⍎b 1168
A character string of n characters can be treated much like a numeric vector of n elements (or as a scalar if n is 1). For example, the vectors a and b specified above can be catenated:
a,b 1441024 ⍎'c←',a,'+',b c 1168
Other functions which select from or reshape an array can also be applied to character vectors. For example:
m←'Mary' n←'2157' ⌽n m,n 7512 Mary2157 m[0 3] 2 4⍴m,n My Mary 2157
It should be noted that a character string does not include the quote marks used in entering it. Moreover, a quote mark to be included in a character string must be denoted by a pair of quotes together. Thus if c←'can''t' then c is the contraction of the word cannot, and:
c +/c=c can't 5 ⌹29
Representation of functions. We may now say that a function in the form ⍺⍵ is represented by a character string. For example, the function for the square root called sqrt is represented by the nine-character string 'sqrt:⍵*.5' .
Just as representations other than the decimal may be used for numbers, so other representations may be used for functions. For example, the function represented by f:⍵+⍺×⍵*2 could also be represented by the expression:
together with something which indicates the name of the function and which name in the expression represents the first argument and which the last. This information could be indicated by the string p f c , and the whole could be represented by a matrix:
m←2 7⍴'p f c c+p×c*2' m p f c c+p×c*2
Every function defined in this text (and most functions of interest in mathematics) produce a result. In order to permit the definition of functions which do not produce explicit results (a matter which need not otherwise concern us here), the form of function representation used in an APL computer includes explicit mention of the result. The actual representation for the function f:⍵+⍺×⍵*2 therefore takes the form:
m←2 9⍴'z←p f c z←c+p×c*2' m z←p f c z←c+p×c*2
This form of representation is called a canonical representation.
A function represented in canonical form can be established or fixed (and thus made available for use) by applying the system function ⎕fx to the matrix m which represents the function. Thus:
⎕fx m f 2 f 3 21
The foregoing example shows that in addition to fixing the function represented by its argument m , the function ⎕fx produces as an explicit result the character string which represents the name of the function.
The canonical representation of a monadic function is similar; the left argument is omitted from the first row. For example, the function sub9:⍵ can be established as follows:
n←2 8⍴'z←sub9 yz←y ' n z←sub9 y z←y ⎕fx n sub9 sub9 7 7 ⌹33
Name conflicts. In what follows we will be establishing certain functions for use as tools in defining other functions; the names for these tools must not conflict with the names of functions which we may wish to establish. For example, if one of our tools is called on , and we use it to establish a new function called on , the tool function itself may be destroyed.
For each tool function we will therefore use a name with the digit 9 as the last character and assume that the user of the tool will not try to establish any functions with such a name. The names chosen will otherwise be as mnemonic as possible, such as is9 , and on9 .
The xy form of function definition. We will now consider a third form of function definition which is easy to produce mentally from an ⍺⍵ definition (by simple substitutions) and which is rather easy to translate mechanically (by simple functions which will now be developed) to canonical form and to then fix. This xy form will then be used as a convenient way to define the further functions needed to translate directly from the ⍺⍵ form.
The xy representation of a function called plus which sums its arguments is simply:
'plus' is9 'x+y'
The translation from ⍺⍵ form to the xy form is obvious:replace each ⍺ by x and each ⍵ by y , enclose the prefix (which precedes the colon) and the suffix (which follows the colon) each in quotes, and replaced the colon by is9 .
We will now develop and fix a function is9 which will perform as required. This function can achieve its purpose in the following steps:
Step 1 can be performed by the function
In xy form this becomes:
'on9' is9 '(2,m9)⍴(m9↑x),(m9←(+/x=x)⌈+/y=y)↑y'
The matrix m obtained by step 1 would be:
m on9 (2,m9)⍴(m9↑x),(m9←(+/x=x)⌈+/y=y)↑y
However, we do not yet have the function is9 established, and we must somehow produce the matrix m using neither is9 nor on9 . This can be done by entering the following expression:
Step 2 in the establishment of the function on9 must also be performed using neither is9 nor on9 . This can be done by first specifying a matrix q as follows:
q←2 6⍴' yz←x z← ' q yz←x z←
The expression n←2⌽q,m will now make n the canonical representation of the function on9 :
n z←x on9 y z← (2,m9)⍴(m9↑x),(m9←(+/x=x)⌈+/y=y)↑y
The function on9 can now be established:
⎕fx n on9
Since the function on9 is now established it can, and will, be used in what follows.
The function on9 performed step 1, and it remains to treat steps 2 and 3. The treatment of step 2 is suggested by the matrix q used in defining on9 , but this matrix contains the character x and is suited only for dyadic functions. We begin, therefore, by defining a matrix ar9 (for argument and result names) as follows:
ar9←3 7⍴' z← y z← y z←x ' ar9 z← y z← y z←x
If g9←'xy' ,
then the expression ⌈/g9∘.=y yields a two element vector;
the first element is 1 if the character x
occurs in y and zero otherwise,
the second is 1 if the character y
occurs in y .
Therefore the expression +/⌈/g9∘.=y
determines the number of arguments in the
expression represented by the vector y .
Consequently, the expression
Step 2 (producing the canonical form)
can now be achieved by the
g9←'xy' m←'can9' on9 '3⌽ar9[1 0×+/⌈/g9∘.=y;],x on9 sub9 y'
The function can9 may now be fixed and used as follows:
⎕fx 3⌽ar9[2 0;],m can9 'pol' can9 '+/x×y*⍳+/x=x' z←x pol y z← +/x×y*⍳+/x=x
It should be recalled that the function sub9 used in the definition of can9 above (and defined earlier) yields its argument unchanged. The point of including it in can9 is that sub9 will later be redefined to substitute x for ⍺ and y for ⍵ , and the other functions to be defined (which use can9) will then work on definitions in the ⍺⍵ form.
We now complete the process by defining, and illustrating the use of, a dyadic function is9 which takes two arguments, a function name and the defining expression, and fixes the appropriate definition:
c←'is9' can9 '⎕fx x can9 y' ⎕fx c is9 'pol' is9 '+/x×y*⍳+/x=x' pol 1 3 3 1 pol 4 125 ⌹40
The function is9 takes two arguments, the name and the defining expression. We will now define a function sdef9 (for simple as opposed to recursive definitions) that applies to an argument which is in the ⍺⍵ form except that the characters ⍺ and ⍵ are replaced by x and y . We begin by defining (and illustrating) a prefix function p9 and a suffix function s9 which select the parts of an expression preceding and following the first colon. We will use the variable h9 to denote a colon:
h9←':' 'p9' is9 '(+/⌊\y≠h9)↑y' p9 's9' is9 '(1++/⌊\y≠h9)↓y' s9 y←'hyp:((x*2)+y*2)*.5' p9 y hyp s9 y ((x*2)+y*2)*.5 (p9 y) is9 s9 y hyp 3 hyp 4 5
The scheme used for defining the function hyp above suggests the following definition for sdef9 :
'sdef9' is9 '(p9 y) is9 s9 y' sdef9
sdef9 'plus:x+y' plus 3 plus 4 7 ⌹41
Recursive definitions. The expression y←'f:y×f y-1:y=0:1' represents a recursive definition of the factorial function in xy form. The three components can be selected by using the prefix and suffix functions p9 and s9 :
p9 y p9 s9 y f y×f y-1 p9 s9 s9 y s9 s9 s9 y y=0 1
The following expression will execute the third component (y=0) and use the result to select the second (y×f y-1) or the last (1) for execution:
If we underscore the parts taken from the original expression, this appears as:
and makes clear that the five unadorned portions are symbols added to the original expression. These five additions may be entered as variables as follows:
a9←'⍎((0=' d9←')/''' b9←')/''' e9←'''' c9←'''),(0≠'
These variables may now be used to define a function form9 which forms the required expression:
c←'form9:a9,(p9 s9 s9 y),b9,(p9 s9 y),c9' c←c,',(p9 s9 s9 y),d9,(s9 s9 s9 y),e9' sdef9 c form9
y←'f:y×f y-1:y=0:1' form9 y ⍎((0=y=0)/'y×f y-1'),(0≠y=0)/'1'
The function rdef9 (for recursive definition) can now be defined rather simply:
sdef9 'rdef9:(p9 y) is9 form9 y' rdef9
rdef9 y f f 5 120 ⌹43
All definitions. We now have a function sdef9 which treats simple definitions and a function rdef9 which treats recursive definitions. The can now be used to define a function adef9 which treats all definitions:
rdef9 'adef9: sdef9 y:3=+/h9=y:rdef9 y' adef9
adef9 'div:x÷y' div 3 div 6 0.5 adef9 'g:y×g y-1:y=0:1' g g 6 720
Recall that the variable h9 was specified by h9←':' .
The ⍺⍵ form. In order to make the function adef9 apply to definitions in the ⍺⍵ form it is necessary to substitute x for ⍺ and y for ⍵ . A function in9 will first be defined as:
c←'in9:x in9(q9↑y),(1↓x),(1+q9)↓y:(+/y=y)=q9←+/⌊\y≠1↑x:y' adef9 c in9
'+ plus ' in9 '3+4×5+6' 3 plus 4×5 plus 6
For each occurrence in the right argument of the first element of the left argument, this function substitutes the remainder of the left argument.
The obvious substitutions can be carried out
by the expression
i9←'⍺x' j9←'⍵y' k9←'⍺⍵' adef9 'sw9:k9 in9 y:1≠+/⌈/k9∘.=y:y' sw9 adef9 'sub9:i9 in9 j9 in9 sw9 y' sub9
sw9 'f:⍺×⍺' f:⍵×⍵ sw9 'f:⍺×⍵' f:⍺×⍵ sub9 'f:⍺+⍵' f:x+y sub9 'f:⍺×⍺' f:y×y adef9 'f:⍺+⍵' f 2 f 5 7 ⌹45
Argument conflicts and spaces. Names ending in 9 have been chosen for all of the functions and variables developed as tools. This avoids conflict with names used for the functions to be defined by them. There remains a potential conflict with the names x , y , and z used for arguments and results in the canonical forms of the functions defined.
Respecifying the values of i9 and j9 as:
i9←'⍺ x9 ' j9←'⍵ y9 '
causes the names x9 and y9 to be substituted for ⍺ and ⍵ rather than x and y . Moreover, the spaces before and after these names ensure that a space will separate them from other names even though such separation does not occur in the given expression, as in f:⍵×f⍵-1:⍵=0:1 .
The variable ar9 must also be respecified to provide the appropriate names for the canonical form:
ar9←3 9⍴' z9← y9z9← y9z9←x9 ' ar9 z9← y9z9← y9z9←x9
With these changes the function adef9 will perform properly.
Character input. The function def was assumed to perform as follows:
def f:⍺+⍵ 3 f 4 7
The function adef9 differs in two respects:
The symbol ⍞ (pronounced quote-quad) is simply replaced by the following entry considered as a character string. For example:
x←⍞ abcd x,⌽x abcddcba
The function def may therefore be defined as follows:
adef9 'def:0⍴adef9 ⍞' def
def fib:z,+/¯2↑z←fib⍵-1:⍵=1:1 fib 7 1 1 2 3 5 8 13 ⌹47
The function def developed in this section will handle all of the functions discussed in Chapters 1 to 9. However, it does not localize variables as discussed in Section 10.1, and it fails to properly treat recursive definitions which include explicit quote marks.
Schemes for modifying the function def to handle local variables are discussed in exercises. However, problems due to the failure to localize variables can be largely avoided by choosing distinctive names for variables that should be localized, as was done with the choice of m9 in the definition of the function on9 . Problems due to quotes can be avoided by first assigning names to quoted strings so that the quotes do not appear explicitly in the function definition, as was done for h9 , and a9 , and others.
Summary. The steps required in the definition of the function def are collected together on the following page, where they are shown together with the expected responses. If the expected response is not received, steps should be taken to obtain the correct response before proceeding further. Remember that if any error messages are printed it may be necessary to enter the symbol → alone on a line one or more times before proceeding.
)clear clear ws ⎕io←0 ⎕fx 2 8⍴'z←sub9 yz←y ' sub9 m←2 34⍴(34↑'on9'),'(2,m9)⍴(m9↑x),(m9←(+/x=x)⌈+/y=y)↑y' ar9←3 7⍴' z← y z← y z←x ' ⎕fx 3⌽ar9[2 0;],m on9 g9←'xy' m←'can9' on9 '3⌽ar9[1 0×+/⌈/g9∘.=y;],x on9 sub9 y' ⎕fx 3⌽ar9[2 0;],m can9 ⎕fx 'is9' can9 '⎕fx x can9 y' is9 h9←':' 'p9' is9 '(+/⌊\y≠h9)↑y' p9 's9' is9 '(1++/⌊\y≠h9)↓y' s9 'sdef9' is9 '(p9 y) is9 s9 y' sdef9 a9←'⍎((0=' b9←')/''' c9←'''),(0≠' d9←')/''' e9←'''' m←'form9:a9,(p9 s9 s9 y),b9,(p9 s9 y),c9' m←m,',(p9 s9 s9 y),d9,(s9 s9 s9 y),e9' sdef9 m form9 sdef9 'rdef9:(p9 y) is9 form9 y' rdef9 rdef9 'adef9:sdef9 y:3=+/h9=y:rdef9 y' adef9 c←'in9:x in9 (q9↑y),(1↓x),(1+q9)↓y' c←c,':(+/y=y)=q9←+/⌊\y≠1↑x:y' adef9 c in9 i9←'⍺ x9 ' j9←'⍵ y9 ' k9←'⍺⍵' adef9 'sw9:k9 in9 y:1≠+/⌈/k9∘.=y:y' sw9 adef9 'sub9:i9 in9 j9 in9 sw9 y' sub9 ar9←3 9⍴' z9← y9z9← y9z9←x9 ' g9←'⍺⍵' adef9 'def:0⍴adef9 ⍞' def
Originally appeared in the Elementary Functions, IBM Corp., 1974, Chapter 10, then in Elementary Analysis, APL Press, 1976, Chapter 10.