Function are objects of type Mapping. In this section we demonstrate some library operations from the packages MappingPackage1, MappingPackage2, and MappingPackage3 that manipulate and create functions. Some terminology: a nullary function takes no arguments, a unary function takes one argument, and a binary function takes two arguments.
We begin by creating an example function that raises a rational number to an integer exponent.
power(q: FRAC INT, n: INT): FRAC INT == q**n
Type: Void
power(2,3)
8
Type: Fraction Integer
The twist operation transposes the arguments of a binary function. Here rewop(a, b) is power(b, a).
rewop := twist power
theMap(MAPPKG3;twist;MM;5!0)
Type: ((Integer,Fraction Integer) -> Fraction Integer)
This is 2^3.
rewop(3, 2)
8
Type: Fraction Integer
Now we define square in terms of power.
square: FRAC INT -> FRAC INT
Type: Void
The curryRight operation creates a unary function from a binary one by providing a constant argument on the right.
square:= curryRight(power, 2)
theMap(MAPPKG3;curryRight;MBM;1!0,0)
Type: (Fraction Integer -> Fraction Integer)
Likewise, the curryLeft operation provides a constant argument on the left.
square 4
16
Type: Fraction Integer
The constantRight operation creates (in a trivial way) a binary function from a unary one: constantRight(f) is the function g such that g(a,b)= f(a).
squirrel:= constantRight(square)$MAPPKG3(FRAC INT,FRAC INT,FRAC INT)
theMap(MAPPKG3;constantRight;MM;3!0)
Type: ((Fraction Integer,Fraction Integer) -> Fraction Integer)
Likewise, constantLeft(f) is the function g such that g(a,b)= f(b).
squirrel(1/2, 1/3)
1
-
4
Type: Fraction Integer
The curry operation makes a unary function nullary.
sixteen := curry(square, 4/1)
theMap(MAPPKG2;curry;MAM;2!0,0)
Type: (() -> Fraction Integer)
sixteen()
16
Type: Fraction Integer
The * operation constructs composed functions.
square2:=square*square
theMap(MAPPKG3;*;MMM;6!0,0)
Type: (Fraction Integer -> Fraction Integer)
square2 3
81
Type: Fraction Integer
Use the ** operation to create functions that are n-fold iterations of other functions.
sc(x: FRAC INT): FRAC INT == x + 1
Type: Void
This is a list of Mapping objects.
incfns := [sc**i for i in 0..10]
[theMap(MAPPKG1;**;MNniM;6!0,0), theMap(MAPPKG1;**;MNniM;6!0,0),
theMap(MAPPKG1;**;MNniM;6!0,0), theMap(MAPPKG1;**;MNniM;6!0,0),
theMap(MAPPKG1;**;MNniM;6!0,0), theMap(MAPPKG1;**;MNniM;6!0,0),
theMap(MAPPKG1;**;MNniM;6!0,0), theMap(MAPPKG1;**;MNniM;6!0,0),
theMap(MAPPKG1;**;MNniM;6!0,0), theMap(MAPPKG1;**;MNniM;6!0,0),
theMap(MAPPKG1;**;MNniM;6!0,0)]
Type: List (Fraction Integer -> Fraction Integer)
This is a list of applications of those functions.
[f 4 for f in incfns]
[4,5,6,7,8,9,10,11,12,13,14]
Type: List Fraction Integer
Use the recur operation for recursion:
g := recur f means g(n,x) == f(n,f(n-1,...f(1,x))).
times(n:NNI, i:INT):INT == n*i
Type: Void
r := recur(times)
theMap(MAPPKG1;recur;2M;7!0,0)
Type: ((NonNegativeInteger,Integer) -> Integer)
This is a factorial function.
fact := curryRight(r, 1)
theMap(MAPPKG3;curryRight;MBM;1!0,0)
Type: (NonNegativeInteger -> Integer)
fact 4
24
Type: PositiveInteger
Constructed functions can be used within other functions.
mto2ton(m, n) ==
raiser := square^n
raiser m
Type: Void
This is 3^(2^3).
- mto2ton(3, 3)
- 6561
- Type: Fraction Integer
Here shiftfib is a unary function that modifies its argument.
shiftfib(r: List INT) : INT ==
t := r.1
r.1 := r.2
r.2 := r.2 + t
t
Type: Void
By currying over the argument we get a function with private state.
fibinit: List INT := [0, 1]
[0,1]
Type: List Integer
fibs := curry(shiftfib, fibinit)
theMap(MAPPKG2;curry;MAM;2!0,0)
Type: (() -> Integer)
[fibs() for i in 0..30]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597,
2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418,
317811, 514229, 832040]
Type: List Integer