Gofer Functions


Simple Definitions


A simple function definition has the form:
NAME FP ... = EXP
where NAME is the name of the function, FP ... is a list of 0 or more formal parameters, and EXP is a parameterized expression.

A constant definition is just a parameterless function:

> zero = 0
> one = 1
> two = 2
Here are some more examples of simple definitions:
> square x = x * x
> rel_prime x y = gcd x y == 1
> divides n m = rem m n == 0
> add_mod_n x y n = mod (x + y) n
> dist x y = abs (x - y)
> sos x y = x^2 + y^2
> always_0 x = 0
Here is a list of some primitive Gofer functions:
div (aka /), rem, mod, odd, even, gcd, lcm, abs, signum, max, min, ^, ord, chr, &&, ||, not, <, <=, ==, >, >=, +, *

Conditional Definitions


The format of a conditional definition is:
NAME FP ... 
   = EXP, if GUARD 
   = EXP, GUARD 
   etc.
   = EXP, otherwise 
where GUARD is any Boolean-valued expression

Note: EXP, if GUARD is called a guarded expression. All guarded expressions must be to the right of all = signs.

Examples:

>   max_sos x y z 
>      = sos x y, if z < min x y
>      = sos x z, if y < min x z
>      = sos y z, otherwise

>   xor x y
>      = x || y, if (x /= y)  -- not equal
>      = False, otherwise

We can use conditionals to define recursive functions:

>   fact n
>      = 1, if n == 0
>      = n * fact (n - 1), otherwise
Problem: Define
choose m n = # of ways to choose m objects from n objects

Local Definitions


Guarded or simple definitions may use local functions or constants which are defined using a "where" clause:
>   NAME FP ...
>      = RHS
>         where
>         DEF ...
Here are some examples
>   tax income
>      = rate * income
>        where
>        rate = 0.3

>   close x y
>      = dist x y < delta
>        where
>        delta = 1e-20
>        dist x y = abs (x - y)


The Offsides Rule


Warning: Gofer's parser is very clever, but there is one rule programmers must follow: the end of a definition is marked by the first appearance of a character to the left of any equal sign in the previous definition. So the following is a syntax error:
>   area r
>      = pi * r * r
>     where
>        pi = 3.1416
Since the "w" in "where" is one column to the left of the "=", Gofer will assume this is the beginning of the next definition, instead of a where block associated with the previous definition!

Polymorphic Functions


Gofer provides the :t command to compute the types of expressions. Here's a sample transcript:
? :t 42
Int
? :t True
Bool
? :t cube
Float->Float
? :t always_o
a->Int
Notice that the input type of always_0 is a variable, a. This signals that the input to always_0 can belong to any type.

a->Int is called a polytype, and always_0 is a polymorphic function.


Delayed Evaluation


Note that always_0 returns 0 even if its input can't be computed:
? always_0 1/0
0
This is possible because Gofer uses lazy or delayed evaluation.

Functions as Data


Like Scheme, Gofer functions can be the inputs or outputs of other functions. For example:
>   compose f g
>      = h
>        where
>         h x = f g x
Note, compose is a built-in operator in Gofer:
>   compose f g = f . g

Curried Functions


This brings up a curious feature. Note:
? :t sos Float->Float->Float
This says sos expects a single Float as input, and returns a function of type Float->Float as output. For example, if we define:
>   sos2 = sos 2
Then
? :t sos2 Float->Float ? sos2 3 16 ? sos2 2 8
sos2 is a function which expects a single input, y, and returns 4 + y^2 as output.

Higher Order Functions



Data as Functions



Last modified:
Current visitor:
You are the visitor
Return to Index