Go to the first, previous, next, last section, table of contents.

Defining Variables and Procedures

You can define a variable in Scheme using a define:

(define foo 5)

Here we tell Scheme to allocate space for foo, and initialize that storage with the value 5.

In Scheme, you always give a variable an initial value, so there's no such thing as an uninitialized variable or an uninitialized variable error.

Scheme values are always pointers to objects, so when we use the literal 5, Scheme interprets that as meaning a pointer to the object 5. Numbers are objects you can have pointers to, just like any other kind of data structure. (Actually, most Scheme implementations use a couple of tricks to avoid pointer overheads on numbers, but that doesn't show up at the language level. You don't have to be aware of it.)

After the above definition, we can draw the resulting situation like this:

       +-------+
   foo |   *---+--->5
       +-------+

The define expression does three things:

These three things happen when you define variables in other languages, too. In Scheme we have names for all three.

In the picture, the box represents the fact that Scheme has allocated storage for a variable. The name foo beside the box means that we've given that storage the name foo. The arrow says that the value in the box is a pointer to the integer object 5. (Don't worry about how the integer object is actually represented. It doesn't really matter.)

You can define new procedures with define, too:

(define (two-times x)
   (+ x x))

Here we've defined a procedure named two-times, which takes one argument, x. It then calls the addition procedure + to add the argument value to itself, and returns the result of the addition.

Notice the syntactic difference between the variable definition and the procedure definition: for a procedure definition, there are parentheses around the name, and the argument name(s) follow that inside the parentheses.

This syntax resembles the way the procedure is called. Consider the procedure call expression (two-times 5), which returns 10; it looks like the definition's (two-times x), except that we've put the actual argument 5 in place of the formal parameter x.

Here's a bit of programming language terminology you should know: the arguments you pass to a procedure are sometimes called actual parameters. The argument variables inside the procedure are called formal parameters---they stand for whatever is actually passed to the procedure at run time. "Actual" means what you actually pass to the procedure, and "formal" means what you call that on the inside of the procedure. Usually, we'll just talk about "arguments," but that's the same thing as "actual parameters." Sometimes we'll talk about "argument variables," and that's the same thing as "formal parameters."

You can define a procedure of zero arguments, but you still have to put parentheses around the procedure name, to make it clear that you're defining a procedure. You put parentheses around its name when you call it, too, to make it clear that it's a procedure call.

For example, this is a definition of a variable whose initial value is 15:

(define foo 15)

but this is a definition of a procedure foo which returns 15 when called.

(define (foo) 15)
       +-------+
   foo |   *---+--->#<procedure>
       +-------+

This picture shows that when you define a procedure, you're really defining a variable whose value happens to be a (pointer to a) procedure. For now, you don't really have to worry about that. The main thing to know is that now you can call the procedure by the name foo. For example, the procedure call expression (foo) will return 15, because all the body of the procedure does is return the value 15.

Usually, we indent procedure definitions like this, with the body starting a new line, and indented a few characters:

(define (foo)
   15)

This indentation makes it clearer that it's a procedure definition.


Go to the first, previous, next, last section, table of contents.