==================================================================== Mapping Package ==================================================================== 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