Is Scheme call-by-value?

Chapter: Is Scheme call-by-value?

Just exactly how does Scheme make that association between formal parameters and actual arguments? For example, suppose we have the following.

(define foo
  (lambda (x)
    (printf "entering foo x is ~s~%" x)
    (set! x 23)
    (printf "exiting foo x is ~s~%" x)))
(define y 14)
(define x 12)

Let's look at various ways we can call foo.

Q. 1
Do any of the following have any substantial effect on the data accessible at Scheme's top level? Try them out in a scheme window.

(foo 12)
(foo (* 12 (+ 3 5)))
(foo (if (> 5 (* 2 3)) 4 6))
(foo '(a b c))
(foo y)
(foo x)
(foo #\a)
(foo #t)
(foo (vector 1 2 3))


In each of the above cases, Scheme evaluates the actual argument, and makes it possible for foo to refer to the evaluated argument by the name x. That's what you see from the first (printf .. x). When (set! x 23) is executed, the local name x is made to refer to the atom 23. Nothing in the top-level data area is affected.

x is a local variable initially referring to the value of the actual argument. set! just changes this binding of the local variable x.

Q. 2
Suppose you have the following definitions.

(define bar1
  (lambda (x)
    (printf "entering bar1 x is ~s~%" x)
    (vector-set! x 1 23)
    (printf "leaving bar1 x is ~s~%" x)))

(define bar2
  (lambda (x)
    (printf "entering bar2 x is ~s~%" x)
    (set-car! (cdr x) 23)
    (printf "leaving bar2 x is ~s~%" x)))
(define y (vector 1 2 3))
(define x '(a b c d))

Run some experiments. At the very least, apply bar1 to y and bar2 to x. Can calls to bar1 and bar2 modify the data accessible at top-level?


In this sense, Scheme appears to call by reference. When structured data is passed to a function, the formal parameter of the function is bound to the same data structure as exists in the caller's area. If you set! the formal parameter, you don't affect the caller's area at all -- you merely bind a new value to the local variable. But the more "surgical" operations, like set-car! and vector-set! can have effects visible in the caller's area.


Exercise 1

Design an experiment to find out how Scheme passes strings. Does it pass purely by value (as demonstrated in Question 1) or is there an element of passing by reference (as demonstrated in Question 2)?

Hand in a description of your experiment, your Scheme code for the experiment, your results, and your conclusions.



rhyspj@gwu.edu