One of the great simplifications of Scheme is that a procedure is just
another type of value, and that procedure values can be passed around
and stored in variables in exactly the same way as, for example, strings
and lists. When we talk about a built-in standard Scheme procedure such
as open-input-file
, what we actually mean is that there is a
pre-defined top level variable called open-input-file
, whose
value is a procedure that implements what R5RS says that
open-input-file
should do.
Note that this is quite different from many dialects of Lisp — including Emacs Lisp — in which a program can use the same name with two quite separate meanings: one meaning identifies a Lisp function, while the other meaning identifies a Lisp variable, whose value need have nothing to do with the function that is associated with the first meaning. In these dialects, functions and variables are said to live in different namespaces.
In Scheme, on the other hand, all names belong to a single unified namespace, and the variables that these names identify can hold any kind of Scheme value, including procedure values.
One consequence of the “procedures as values” idea is that, if you don’t happen to like the standard name for a Scheme procedure, you can change it.
For example, call-with-current-continuation
is a very important
standard Scheme procedure, but it also has a very long name! So, many
programmers use the following definition to assign the same procedure
value to the more convenient name call/cc
.
(define call/cc call-with-current-continuation)
Let’s understand exactly how this works. The definition creates a new
variable call/cc
, and then sets its value to the value of the
variable call-with-current-continuation
; the latter value is a
procedure that implements the behavior that R5RS specifies under the
name “call-with-current-continuation”. So call/cc
ends up
holding this value as well.
Now that call/cc
holds the required procedure value, you could
choose to use call-with-current-continuation
for a completely
different purpose, or just change its value so that you will get an
error if you accidentally use call-with-current-continuation
as a
procedure in your program rather than call/cc
. For example:
(set! call-with-current-continuation "Not a procedure any more!")
Or you could just leave call-with-current-continuation
as it was.
It’s perfectly fine for more than one variable to hold the same
procedure value.