Formal Function Definition
Kenneth E. Iverson
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:
q:1+(x←⍺-⍵)×2+x×3+x×4
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:
fac:⍵×fac ⍵-1
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:
4×3×2×1
24
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:
The primary expression | : | | ⍵×f ⍵-1 |
A proposition | : | | ⍵=1 |
A secondary expression | : | | 1 |
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:
fac:⍵×fac ⍵-1:⍵=0:1
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.
⌹16
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
and x←2 , then the value
of the polynomial is given by:
+/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:
p:+/⍺×⍵*⍳n ⍺
where n yields the number of elements
in its argument, and is defined as follows:
n:+/⍵=⍵
For example:
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
If d←1 3 3 1 then the sum
of the polynomials with coefficients c and d
is given by:
(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
vector 26 32 .
It may be convenient to define a function
which will curtail any vector by dropping all final zeros:
curt:(-+/⌊\0=⌽⍵)↓⍵
curt rm
26 32
A polynomial with coefficients 1 ,
or 1 0 , or 1 0 0 ,
etc., has the value 1 for all values of its argument.
Hence a polynomial which is (for small values of its argument)
an approximate reciprocal of a given polynomial,
can therefore be obtained by dividing the given polynomial
into a polynomial of the form 1 followed by zeros.
For example:
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
to evaluate 1 3 3 1 p 2 5
or 1 3 3 1 p 2 5 7 9 .
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:
c+p×c*2
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:
1. | |
Form the arguments into a two-rowed matrix by placing
the first on top of the second.
|
2. | |
Append the symbols z and ← and y
and (if the function is dyadic) x so as to
form the canonical representation of the specified function.
|
3. | |
Apply the function ⎕fx to the resulting
matrix so as to fix the desired function.
|
Step 1 can be performed by the function
on9:(2,m9)⍴(m9↑⍺),(m9←(+/⍺=⍺)⌈+/⍵=⍵)↑⍵
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:
m←2 34⍴(34↑'on9'),'(2,m9)⍴(m9↑x),(m9←(+/x=x)⌈+/y=y)↑y'
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.
⌹36
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 ar9[1 0×+/⌈/g9∘.=y;]
selects from ar9 the matrix appropriate
to the number of arguments.
For example, ar9[1 0×2;]
yields a matrix similar to the matrix q
used in the definition of on9 .
Step 2 (producing the canonical form)
can now be achieved by the
expression 3⌽ar9[1 0×+/⌈/g9∘.=y;],m
where m is the result of step 1.
The representation of the necessary
function (can9)
itself is therefore given by:
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.
⌹38
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
For example:
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:
⍎((0=y=0)/'y×f y-1'),(0≠y=0)/'1'
If we underscore the parts taken from the original
expression, this appears as:
⍎((0=y=0)/'y×f y-1'),(0≠y=0)/'1'
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
For example:
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
For example:
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
For example:
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←':' .
⌹44
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
For example:
'+ 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 '⍺X' in9 '⍵y' in9 y .
However, in the case where y defines a monadic
function but contains only ⍺ but not ⍵ ,
it is first necessary to swap ⍵ for ⍺ .
The whole can be done as follows:
i9←'⍺x'
j9←'⍵y'
k9←'⍺⍵'
adef9 'sw9:k9 in9 y:1≠+/⌈/k9∘.=y:y'
sw9
adef9 'sub9:i9 in9 j9 in9 sw9 y'
sub9
For example:
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:
1. | |
It products and prints the name of the function defined.
This can be avoided by using the expression 0⍴adef y .
|
2. | |
It requires that the expression be enclosed in quotes
and accompany it on the same line.
This can be avoided by using the expression adef9 ⍞ .
For example:
0⍴adef ⍞
d:⍺-⍵
6 d 4
2
|
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
For example:
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.
⌹48
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
Exercises
10.1 | |
Consider the following set of functions:
i) | | fti:12×⍵ |
ii) | | itf:(÷12)×⍵ |
iii) | | ytf:3×⍵ |
iv) | | yti:fti ytf ⍵ |
v) | | f:12×3×⍵ |
vi) | | g:⍵ |
vii) | | h:fti itf ⍵ |
viii) | | k:itf fti ⍵ |
ix) | | l:(fti itf ⍵)÷⍵ |
x) | | m:36+0×⍵ |
a) | |
For each function above, show its interpretation in detail
by applying it to some argument. For example:
fti 7
12×7
84
(This part need not be done for functions whose meaning is clear.)
|
b) | |
State clear but informally what each function does.
For example, fti converts from measurements
expressed in feet to measurements expressed in inches.
|
c) | |
Determine which among the functions are equivalent.
For example, g and h are equivalent.
|
d) | |
State clearly any other relations you observe
among the functions; for example, fti
is the inverse of itf ,
and (f ⍵)÷g ⍵ equals the constant
function m ⍵ .
|
|
10.2 | |
Repeat Ex 10.1 for the following functions
(all of which concern conversions
between units of measurements).
i) | | itc:2.54×⍵ |
ii) | | cti:(÷2.54)×⍵ |
iii) | | ctf:32+1.8×⍵ |
iv) | | ftc:(÷1.8)×(-32)+⍵ |
v) | | f:ctf ftc ⍵ |
vi) | | g:⍵ |
|
10.3 | |
Define functions for each of the following conversions of units:
a) | | Hours to minutes |
b) | | Minutes to hours |
c) | | Days to hours |
d) | | Days to minutes |
e) | | Minutes to seconds |
|
10.4 | |
a) Which of the functions in Ex 10.3 are equivalent?
b) Do an interpretation of the function f
of Ex 10.2 to show that it is equivalent to g .
|
10.5 | |
Repeat Ex 10.1 for the following functions
(which concern measures of simple geometric figures).
i) | | as:⍵*2 |
ii) | | ar:⍺×⍵ |
iii) | | at:.5×⍺×⍵ |
iv) | | vc:⍵*3 |
v) | | vsqpy:(÷3)×⍺×⍵*2 |
vi) | | ps:4×⍵ |
vii) | | pr:2×⍺+⍵ |
viii) | | sac:6×⍵*2 |
|
10.6 | |
Repeat Ex 10.1 for the following functions
(which concern measures of circles and spheres):
i) | | pitimes:3.14159×⍵ |
ii) | | ac:pitimes ⍵*2 |
iii) | | pc:2×pitimes ⍵ |
iv) | | dc:2×⍵ |
v) | | f:ptimes dc ⍵ |
vi) | | g:(÷4)×ac ⍵ |
|
10.7 | |
The monadic function ○ is defined
(in Sec 4.10) as pi times its argument,
that is, ○⍵ is (approximately) equivalent
to pitimes ⍵ as defined
in Ex 10.6.
a) Redefine each of the functions in Ex 10.6
replacing the function pitimes by ○ .
b) Use the function ○ to define
the following functions:
i) | | Volume of a sphere |
ii) | | Surface of a sphere |
iii) | | Volume of a circular
cylinder (with first argument for height and second for radius). |
iv) | | Function of
part iii with arguments reversed. |
v) | | Volume of a sphere
using the function of part ii in its definition. |
|
10.8 | |
Repeat Ex 10.1 for the following functions,
all of which concern geometric figures:
i) | | v:×/⍵ |
ii) | | p:+/⍵ |
iii) | | sp:.5×p ⍵ |
iv) | | ttest:⌊/⍵≤ sp ⍵ |
|
10.9 | |
a) Apply the function ttest of Ex 10.8
to vectors l←2 5 4
and r←2 5 2 ,
and then try to construct triangles with lengths
specified by l and by m .
b) Will ttest serve to check
the suitability of a set of lengths for the sides
of a polygon, i.e., for an argument
of any number of elements?
c) Modify ttest to exclude degenerate
polygons which enclose no area;
for example, ttest 2 5 7
yields 1 ,
although these dimensions do not yield a proper triangle.
|
10.10 | |
a) Define a monadic function asc which
applied to a scalar argument yields the surface
area of a cube of dimension given by the argument.
b) Define a monadic function as which,
when applied to a 3-element vector yields
the surface area of the box represented by the vector.
c) Compare the results of asc n
and as n,n,n for various values
of the scalar n .
|
10.11 | |
a) Compare the function as defined in Ex 10.10
with the function a:2×+/⍵×⍵[1 2 0] .
b) Rewrite the expression for a in part a
using the rotation function defined in Sec 5.8
instead of indexing.
|
10.12 | |
Evaluate the function scale:r×⍵ for several
arguments first with the ratio r←2.54 ,
and then with r←12 .
|
|
10.13 | |
a) Identify the class of triangles whose sides
are given by applying the following function
to non-negative integer arguments:
alrt:(|-/z*2)(+/z*2),2××/z←⍺,⍵
b) State the purpose of the following function:
testrt:(+/⍵*2)=2×(⌈/⍵)*2
c) The semi-perimeter function sp
of Ex 10.8 can be used in Hero’s formula
for the area of a triangle in terms of the lengths
of its sides:
Hero:(×/(s-⍵),s←sp ⍵)*.5
Evaluate Hero 3 4 5
and Hero 1 1 1
and check that the results do represent the areas.
d) Show that the following function
is equivalent to the function testrt
of Ex 10.13:
q:(Hero ⍵)=.5×(×/⍵)÷⌈/⍵
|
10.14 | |
Repeat Ex 10.1 for the following functions:
si:+/z←1+⍳⍵
sis:+/z×z←1+⍳⍵
sic:+/z×z×z←1+⍳⍵
a:(⍵×⍵+1)÷2
b:(⍵×(1+⍵)×1+2×⍵)÷6
c:(a⍵)*2
|
10.15 | |
Use the following expressions to demonstrate
why functions si and a of
Ex 10.14 are equivalent:
x←1+⍳5
x ⌽x
+/x +/⌽x
(+/x) + +/⌽x
x+⌽x
+/x+⌽x
(See Ex 1.68 for the definition of the
reversal function ⌽).
|
|
10.16 | |
Show that the functions tn:⍵+tn ⍵-1:⍵=0:0
and sn:+/1+⍳⍵ are equivalent.
|
10.17 | |
Repeat Ex 10.1 for the following functions
applied to positive scalar integers:
i) | | gcd:(⍺|⍵) gcd ⍺:⍺=0:⍵ |
ii) | | red:(⍺,⍵)÷⍺ gcd ⍵ |
iii) | | test:(⍺÷z)gcd ⍵÷z←⍺gcd⍵ |
iv) | | lcm:(⍺×⍵)÷⍺ gcd ⍵ |
|
10.18 | |
Repeat Ex 10.1 for the following functions
applied to non-negative scalar integers:
i) | | bin:(z,0)+0,z←bin⍵-1:⍵=0:1 |
ii) | | sum:+/bin ⍵ |
iii) | | p:+/(bin⍺)×⍵*⍳⍺+1 |
iv) | | q:2*⍵ |
v) | | r:(⍵+1)*⍺ |
|
10.19 | |
a) For each function f of Ex 10.17,
define a monadic function fv which,
when applied to a two-element vector argument,
is equivalent to f .
For example, redv v must
equal v[0] red v[1]
b) For various values of a two-element argument a
evaluate redv a and compare the
values of ÷/a and ÷/redv a .
c) Discuss the statement: The function redv
reduces a fraction to lowest form.
|
10.20 | |
The expression fib n yields
a vector of the first n Fibonacci numbers
if fib is defined as follows:
fib:z,+/¯2↑z←fib⍵-1:⍵=1:1
a) Show that fib 10 yields the
vector: 1 1 2 3 5 8 13 21 34 55
b) Give an informal statement of the rule
for generating Fibonacci numbers.
c) The function pr:(1↓⍵)÷¯1↓⍵ yields
the pairwise ratio of successive elements
of its vector argument.
Evaluate pr fib 10 .
d) The ratio determined in part c appear to be
approaching a limiting value;
this value is called the golden mean,
and is given by the expression .5×1+5*.5 .
Compare the golden mean with the ratio of a
few Fibonacci numbers.
|
10.21 | |
The signum function defined
by sg:(⍵>0)-⍵<0 is a monadic
function also denoted by × ;
it yields ¯1 or 0 or 1
according to whether the argument is negative, zero,
or positive.
Discuss the following statements and illustrate
them for the case where f:⍵*2 and n←5 :
a) The equation n=f ⍵ has a root
in the interval a[0] to a[1]
if a s n has the value 1 ,
where s:1≠×/×⍵-f ⍺ .
b) The function m:.5×+/⍺ yields the midpoint
of any interval to which it is applied.
c) If a s n has the value 1 ,
then either (a[0],m a)s n is 1 ,
and therefore n=f ⍵ has a root in one
of the narrower intervals a[0],m a
or a[1],m a .
d) If a s n equals 1 ,
then the equation n=f ⍵ has a root in one
of the narrower intervals a ni n ,
where:
ni:⍺[(⍺[1],m⍺)s ⍵],m⍺
|
10.22 | |
The root-finder function rf
is based on the results of Ex 10.21 and is designed
to yield a root of the equation n=f x
in the interval from a[0] to a[1] ,
that is, if x←a rf n ,
then f x is (approximately) equal to n ,
the tolerance in the approximation being determined
by the tolerance function t :
rf:(⍺ni⍵)rf⍵:t⍵-f m⍺:m⍺
t:1e¯8≥|⍵
a) If f:⍵*2 ,
show that 1≠×/×12.25-f 2 4
b) Show that 2 4 rf 12.25
yields 3.5 ,
and verify that f 2 4 rf 12.25
equals 12.25 .
c) Evaluate 1 2 rf 2 and check
the result by applying f to it.
d) Redefining the function f
as f:+/3.75+(¯4.25×⍵)+⍵*2 ,
evaluate 1 2 rf 0 .
e) Show that f 1 2 rf 0 is 0 .
f) Evaluate 2 4 rf 0 .
|
10.23 | |
All possible divisors of an integer k are
included in the vector 1+⍳k .
a) For d:0=(1+⍳⍵)|⍵ ,
evaluate the expression d k
for various values of k ,
and state clearly how the result identifies the
actual divisors of k amongst
the elements of 1+⍳k .
b) The function f selects from
its right argument those elements identified by 1’s
in its left argument, in the manner suggested by part a:
f:((1↑⍺)↑⍵),(1↓⍺)f 1↓⍵:0=n⍵:⍳0
n:+/⍵=⍵
Show that 0 1 1 0 1 1 f 1+⍳6
yields 2 3 5 6 .
c) State the effect of the
function divs:(d⍵)f 1+⍳⍵ .
d) Show that k÷divs k
is equivalent to ⌽ divs k .
e) k is called a perfect number
if k=+/¯1↓divs k .
Show that 6 and 28 are perfect numbers,
and state in words the definition of a perfect number.
|
|
10.24 | |
Use the function plus , minus ,
and times of Section 10.3 to evaluate
the expression c plus d
and c minus d
and c times d
for the following pairs of c and d :
c | | d |
1 2 1 | | 1 3 3 1 |
1 1 | | 1 2 1 |
1 1 | | 1 ¯1 1 ¯1 1 |
|
|
10.25 | |
Use the function into
and linto of Section 10.3 to evaluate
the expression a into b
and a linto b .
Check the results by computing the corresponding remainder:
a | | b |
1 3 3 1 | | 1 5 10 10 5 1 |
1 3 2 | | 2 4 1 5 7 |
2 1 3 | | 2 4 1 5 7 |
|
10.26 | |
Let v←20↑1 . Then evaluate
and compare the two expressions in each part:
a) 1 ¯1 into v
+\v
b) 1 ¯2 1 into v
+\+\v
c) 1 ¯3 3 ¯1 into v
+\+\+\v
|
10.27 | |
Use the functions pvra and p
of Section 10.3 to show complete interpretations of the
expressions 1 3 3 1 pvra 2 5
and 1 3 3 1 p 2 5 ,
making clear why the evaluation of the latter
cannot be completed.
|
10.28 | |
Redo part d of Ex 10.22 with f:3.75 ¯4.25 1 pvra ⍵ .
|
|
10.29 | |
Evaluate the following:
a←'abcdefghijklmnopqrstuvwxyz '
b←'coffee'
d←'0123456789'
n←'1776'
a[2 0 1]
a[8 26 18 8 13 6 26 14 5]
j←2 14 5 5 4 4
a[j]
b=a[j]
⌊/b=a[j]
d[1 7 7 6]
⍎n
⍎d[1 9 7 6]
|
10.30 | |
Using the variables specified in Ex 10.29, evaluate:
a) d∘.=n
b) +/d∘.=n
c) a∘.=b
d) +/a∘.=b
e) an←a,d
f) +/an∘.='224 East 25th St'
|
10.31 | |
Using the results of Ex 10.30, comment on
the following statements:
a) The function cl:+/a∘.=⍵
gives counts of the letters and spaces in its argument.
b) The function cd:+/d∘.=⍵ gives
counts of the digits in its argument.
|
10.32 | |
Using the results of Exercise 10.29
it is clear that the function f:a[⍵]
yields b when applied to j .
a) Show that the function if:+/⌊\⍵∘.≠a
is inverse to f ;
in particular, show that if b
yields j .
b) Show that the function ig:+/⌊\⍵∘.≠d
is inverse to the function g:d[⍵] ;
in particular, show that ig '1776'
yields the vector 1 7 7 6 .
c) Compare the function v:+/(ig⍵)×10*⌽⍳+/⍵=⍵
with the execute function ⍎ ;
in particular, show that v '1776'
equals ⍎'1776' .
|
|
10.33 | |
a) Show that the following:
h←'z←x q y '
i←'z←x×y+x-2'
m←2 9⍴h,i
⎕fx m
fix the function q:⍺×⍵+⍺-2 .
b) Show that 3 q 4 yields 15 .
|
10.34 | |
Recalling that the quote character itself is represented
by a pair of adjacent quotes,
show that the expressions:
h←'z←cd y '
i←'z←+/''0123456789''∘.=y'
m←2 20⍴h,i
⎕fx m
fixes the function cd of Ex 10.31b.
|
10.35 | |
Write expressions
to establish each of the
functions cl , f , if , g , ig ,
and v of Exs 10.31-32.
|
|
10.36 | |
Show that the expression:
⎕fx 'z←x q y' on9 'z←x×y+x-2'
fixes the function q of Ex 10.33.
|
10.37 | |
Write expressions using the function on9
to establish each of the
functions cl , cd , f , if , g , ig ,
and v of Exs 10.31-32.
|
|
10.38 | |
a) Evaluate:
'q' can9 'x×y+x-2'
and show that it yields a representation
of the function q of Ex 10.33.
b) Show that the expression:
⎕fx 'q' can9 'x×y+x-2'
fixes the definition
of the function q of Ex 10.33.
|
10.39 | |
Repeat Ex 10.37 using the function can9
instead of on9 .
|
|
10.40 | |
Repeat Ex 10.37 using the function is9
instead of on9 .
|
|
10.41 | |
Assuming that:
a←'minus:x-y'
b←'ab:cde:fghi'
evaluate the following:
a) p9 a
b) s9 a
c) p9 b
d) s9 b
e) p9 s9 b
f) s9 s9 b
|
10.42 | |
Repeat Ex 10.37 using the function sdef9 instead of on9 .
|
|
10.43 | |
Carry out the detailed steps in the execution
of the expression:
rdef9 'f:y×f y-1:y=0:1'
to show that it establishes the definition of f
as the factorial function.
|
|
10.44 | |
Carry out the detailed steps in the establishment
of the functions g and f
by the following expressions:
a) adef9 'g:x÷y'
b) adef9 'f:y×f y-1:y=0:1'
(Use the results of Ex 10.43.)
|
|
10.45 | |
Evaluate the following:
'+ and ' in9 'May+June+July'
'Mmay ' in9 '+ and ' in9 'M3+M14'
|
10.46 | |
Using the definition:
adef9 'sub9:i9 in9 j9 in9 sw9 y'
for the function sub9
state the result or effect of each of the following
expressions:
a) sub9 'p:+/⍺×⍵*⍳+/⍺=⍺'
b) adef9 'p:+/⍺×⍵*⍳+/⍺=⍺'
c) adef9 'f:⍵×f ⍵-1:⍵=0:1'
|
|
10.47 | |
Show examples of the use of the function
established by:
def
sqrt:⍵*.5
def
hyp:sqrt(⍺*2)+⍵*2
|
|
10.48 | |
The remaining exercises develop modifications
to the function def which localize names
which precede a specification arrow as specified
in Sec. 10.1.
In the canonical representation,
names are localized by adding them to the first row,
each preceded by a semicolon.
For example, if f is defined by:
def
f:⍺+z×z←ab+ab←⍵*2
then its canonical representation is:
z9←x9 f y9;z;ab
z9←x9+z×z←ab+ab←y9*2
In what follows assume that the semicolon sc ,
the empty vector ev ,
and the alphabet a are specified as follows.
sc←';'
ev←''
a←'abcdefghijklmnopqrstuvwxyz'
Consider the functions fixed by each
of the following individual responses
to the function def :
bsa:(+/⌊\⍵≠'←')↑⍵
asa:(1++/⌊\⍵≠'←')↓⍵
fn:(+/⌊\⌈/⍵∘.=A)↑⍵
ln:⌽fn⌽⍵
n:sc,z:0=+/z=z←ln bsa ⍵:ev
nl:(n⍵),nl z:0=+/z=z←asa⍵:ev
Examine the behaviour of these functions
by applying them to one or more arguments,
including arg specified as:
arg←'f:⍺+z×z←ab+ab←⍵*2'
For each function state its behaviour in words,
and choose an appropriate name for it.
For example: bsa might be called
“before the specification arrow”.
|
10.49 | |
Modify the function can9 so as to append
the first row of the matrix it produces
the list of local names produced by the
function nl of Ex 10.48.
Verify that this modification causes the function def
to localize the names as desired.
|
Originally appeared in the Elementary Functions,
IBM Corp., 1974, Chapter 10,
then in Elementary Analysis, APL Press, 1976, Chapter 10.
created: | 2010-07-31 16:15 |
updated: | 2012-08-27 23:10 |
|