A parameter, as discussed in class, is a procedure which takes zero or one arguments and has internal state: a saved value. If passed zero arguments it returns its saved value. If passed one argument it sets its saved value to that one argument.
While parameters are useful, any change to them immediately and completely throws out their last value. It is sometimes useful to change them only temporarily, while some snippet of code is run, and to restore the old value afterwards.
Write the procedure parameter-while:
(parameter-while parameter value thunk)
where parameter is a parameter, value is any
value, and thunk is a procedure of no arguments. When
parameter-while is invoked,
> (define make-parameter
(lambda (init-value)
(lambda args
(if (null? args)
init-value
(set! init-value (car args))))))
> (define foo (make-parameter 2))
> (foo)
2
> (foo 3)
> (foo)
3
> (parameter-while foo 5
(lambda () (+ (foo) (foo))))
10
> (foo)
3
(define raise
(lambda (v)
(error 'raise "Unhandled exception: ~s" v)))
(define try
(lambda (body-thunk guard-proc handler-proc)
(call/cc
(lambda (k)
(fluid-let ((raise (let ((outer-raise raise))
(lambda (v)
(if (guard-proc v)
(k (handler-proc v))
(outer-raise v))))))
(body-thunk))))))
(try ; returns "got a test exception"
(lambda () (raise 'test-exception))
(lambda (exn) (eq? exn 'test-exception))
(lambda (exn) "got a test exception"))
(try ; returns test-exception
(lambda ()
(try
(lambda () (raise 'test-exception))
(lambda (exn) (eq? exn 'other-exception))
(lambda (exn) "got a test exception")))
symbol?
(lambda (exn) exn))
(try ; prints "Test exception raised" forever
(lambda ()
(try
(lambda () (raise 'test-exception))
(lambda (exn) (eq? exn 'test-exception))
(lambda (exn)
(printf "Test exception raised~n")
(raise 'test-exception))))
symbol?
(lambda (exn) exn))
In one respect the above definition of try does not conform
with Java and most other languages, which use what is sometimes known as
the dynamic wall: an exception handler runs in the dynamic context
that was current before the handler was installed. This prevents the sort
of looping illustrated above in the event that an exception handler raises
its own exception.
try/wall, a version of try that
implements the dynamic wall. For example:
(try ; prints "Test exception raised" and then returns test-exception
(lambda ()
(try/wall
(lambda () (raise 'test-exception))
(lambda (exn) (eq? exn 'test-exception))
(lambda (exn)
(printf "Test exception raised~n")
(raise 'test-exception))))
symbol?
(lambda (exn) exn))
Write your answers to the exercises in a file (with comments, following the proper indentation rules), and send that file to
c311@lakshmi.cs.indiana.eduwith the subject line
10Assuming you've saved your homework in the file ``asgn.ss'' in the current directory, one way to submit is with the command:
Mail -s "10" c311@lakshmi.cs.indiana.edu < asgn.ss
Back to the c311 page
ehilsdal@cs.indiana.edu