Goals: This laboratory exercise considers output procedures to aid in the tracing of a program. Since any output procedure produces a side effect, this lab introduces the concept of side effects more generally. Also, as many uses of output procedures occur in the context of other processing, the general concept of the sequencing of expressions is reviewed.
Consider the following procedure to add 2 to each element in a list:
(define simple-add2
(lambda (L)
(if (null? L)
'()
(cons (+ 2 (car L)) (simple-add2 (cdr L))))
)
)
(define simple-add2-trace
(lambda (L)
(display L) (newline) ;;NEW: print out current list on separate line
(if (null? L)
'()
(cons (+ 2 (car L)) (simple-add2-trace (cdr L))))
(display L) (newline) ;;NEW: print out current list on separate line
)
)
Here, display is a procedure that prints out the argument that
follows on your computer screen. newline moves to a new line on
the screen. Thus, in the above code, the current list L will be
shown at the screen on a line by itself, each time
simple-add2-trace is called recursively. (While the textbook uses
writeln for this purpose, writeln is not available in
Chez Scheme -- but display and newline accomplish much of
the same effect.)
Experiment further with display and newline.
(display "this is a test") (display (+ 2 3)) (display 'x) (display x)
(define simple-add2-trace
(lambda (L)
;;; Step 1: print the list on the screen
(display L)
;;; Step 2: move to a new line on the screen
(newline)
;;; Step 3: process L
(if (null? L)
'()
(cons (+ 2 (car L)) (simple-add2-trace (cdr L))))
)
)
This need to execute several steps in a row arises with some frequency in
Scheme. More generally, multiple statements are automatically allowed:
(define simple-add2-trace
(lambda (L)
(begin
;;; Step 1: print the list on the screen
(display L)
;;; Step 2: move to a new line on the screen
(newline)
;;; Step 3: process L
(if (null? L)
'()
(cons (+ 2 (car L)) (simple-add2-trace (cdr L))))
)
)
)
An explicit begin expression is required when our code
involves multiple steps, but where the rules for an implicit begin do not
apply. Such circumstances commonly arise within an if expression,
such as the following:
(if (fire?)
(begin (go-outside)
(call-fire-dept)
)
(begin (get-potato-chips)
(turn-on-tv)
)
)
Here, the if is a special form that requires a single expression
for the then and else parts; a begin must be
used if multiple things must be done.
As a further example, consider the following modification of
simple-add2-trace>.
(define simple-add2-trace
(lambda (L)
(display L)
(if (null? L)
(begin
(display " then clause") (newline)
'()
)
(begin
(display " else clause") (newline)
(cons (+ 2 (car L)) (simple-add2-trace (cdr L)))
)
)
)
)
(define simple-add2-trace
(lambda (L)
(display L)
(if (null? L)
(begin
'()
(display " then clause") (newline)
)
(begin
(cons (+ 2 (car L)) (simple-add2-trace (cdr L)))
(display " else clause") (newline)
)
)
)
)
This document is available on the World Wide Web as
http://www.math.grin.edu/~walker/courses/151/lab-side-effects.html