Functions
| Contents |

Consider the equation to find
the *y*-value of a point on the line:

y = 5x - 3

First, we assigned values to the slope,
the *x*-value, and the *y*-intercept:

(define m 5) (define x 9) (define b -3)

Once those variables have been created,
we can compute the value of *y*:

(define y (+ (* m x) b)) (inspect y) -> y is 42

Now, suppose we wished to find the *y*-value corresponding to
a different *x*-value or, worse yet, for a different *x*-value
on a different line. All the work we did would have to be
repeated. A *function* is a way to encapsulate all these operations
so we can repeat them with a minimum of effort.

First, we will define a not-too-useful function that
calculates *y* give a slope of 5,
a *y*-intercept of -3, and an
*x*-value of 9 (exactly
as above). We do this by wrapping a function around
the sequence of operations above.
The return value of this function is the computed *y* value:

(define (y) (define m 5) (define x 9) (define b -3) (+ (* m x) b) ;the value of this expression is the return value )

There are a few things to note. The call to the *define*
function indicates
that a variable definition is occurring. The fact that the first
argument to *define* looks like a list indicates that the variable
being defined will be bound to a function and that the variable/function
name is *y*, as it is the first member of that list.
The formal parameters of the function follow the function name;
since there is nothing after the *y*, we don't
need to send any information to this function when we call it.
Together, the first line is known as the *function signature*,
which tells you the name of the function and how many values
it expects to be sent when called.

The expressions after the function name and formal parameters
are called the *function body*; the body
is the code that will be evaluated (or executed) when the
function is called. You must remember this: *the function body
is not evaluated until the function is called*.

Finally, the return value of a function is the value of the last expression evaluated. In the above case, the expression is:

(+ (* m x) b)

Once the function is defined, we can find the value of *y* repeatedly.

(y) -> 42 (y) -> 42

Because we designed the function to take no values when called, we do not place any values between the parentheses.

Note that when we call the *y* function again,
we get the exact same answer.

The *y* function, as written,
is not too useful in that we cannot use it to compute
similar things, such as the *y*-value for a different value of
*x*.
This is because we `hard-wired' the values of *b*, *x*, and *m*,
We can improve this function by passing in the value of *x*
instead of hard-wiring the value to 9.

A hallmark of a good function is that it lets you compute
more than one thing. We can modify our *y* function to *take in* the
value of *x* in which we are interested.
In this way,
we can compute more than one value of *y*.
We do this by *passing* in
an *argument*^{4}, in this case, the value of *x*.

(define (y x) (define m 5) (define b -3) (+ (* m x) b) )

Note that we have moved *x* from the body of the function
to after the function name. We have also refrained from
giving it a value since its value is to be sent to the function
when the function is called.
What we have done is to *parameterize* the function to make it more
general and more useful. The variable *x* is now called a
*formal parameter*.

Now we can compute *y* for an infinite number of *x*'s:

(y 9) -> 42 (y 0) -> -3 (y -2) -> -13

What if we wish to
compute a *y*-value for a given *x* for a different
line? One approach would be to pass in the *slope* and *intercept*
as well as *x*:

(define (y x m b) (+ (* m x) b) )

Now we need to pass even more information to *y* when we call it:

(y 9 5 -3) -> 42 (y 0 5 -3) -> -3

If we wish to calculate using a different line, we just pass in the
new *slope* and *intercept* along with our value of *x*.
This certainly works as intended, but is not the best way. One problem
is that we keep on having to type in the slope and intercept even if
we are computing *y*-values on the same line. Anytime you
find yourself doing the same tedious thing over and over,
be assured that
someone has thought of a way to avoid that particular tedium.
If so, how do we
customize our function so that we only have to enter the slope
and intercept once per particular line? We will explore
one way for doing this. In reading further,
it is not important if you understand all that is going on.
What is important is that you know you can use functions
to run similar code over and over again.

Since creating functions is hard work (lots of typing) and
Computer Scientists avoid unnecessary work like the plague, somebody
early on got the idea of writing a function that itself
creates functions! Brilliant! We can do this for our line problem.
We will tell our creative function to create a *y* function
for a particular slope and intercept! While we are at it,
let's change the variable names *m* and *b* to *slope*
and *intercept*, respectively:

(define (createLine slope intercept) (define (y x) (+ (* slope x) intercept) ) y ; the value of y is returned, y is NOT CALLED! )

The *createLine* function creates a *y* function
and then returns it. Note that this returned function *y* takes
one value when called, the value of *x*.

So our creative *createLine* function
simply defines a *y* function and then
returns it. Now we can create a bunch of different lines:

(define a (createLine 5 -3)) (define b (createLine 6 2)) (a 9) -> 42 (b 9) -> 56 (a 9) -> 42

Notice how lines *a* and *b* remember
the slope and intercept supplied
when they were created.^{5}
While this is decidedly cool, the problem is many languages (
for example C, C++, and Java^{6})
do not allow you to define functions that create other functions.
Fortunately, Scam, Python, and most functional languages allow this.

While this might seem a little mind-boggling, don't worry. The things you should take away from this are:

- functions encapsulate calculations
- functions can be parameterized
- functions can be called
- functions return values

Functions
| Contents |