[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

``Update functions'' in Scheme.




>  > The key point here is that Scheme already has enough power to express
>  > the abstract relationship between accessors and mutators; there is no
>  > need to "extend" the language to provide this feature.
>  
>  If this is true, then please tell me how you would do the following
>  using the method you described.
>  
>  Suppose I want to write a new print function that involves a ``print length''.
>  The function (print-length) should serve both as an accessor and as a
>  mutator for the actual print length.  That is,
>  
>     (print-length)
>  
>  simply returns the current print length, while
>  
>     (set! (print-length) 20)
>  
>  should be used to change the print length (changing it would include some
>  kind of sanity check).
>
>  . . . 
>  
>  How would you do something like this using the method you proposed
>  without employing a global variable?

We can get a version of PRINT-LENGTH without using a global variable
to hold the state as follows:

; --------------------------------------------------------------------------
; Wrap up the print-length state variable into a "generating"
; procedure that can provide us with both the accesor and mutator

(define print-length-maker
  (let ((*print-length* 100)) ; This state is local to the following procedure
    (lambda (m)
      (cond ((eq? m 'accessor) 
	     (lambda () *print-length*))
	    ((eq? m 'mutator)  
	     (lambda (new-val) (set! *print-length* new-val))) 
	     ; Could also include "sanity check" here
	    (else (error "Don't understand!"))))))

; Now define the accessor . . .
(define print-length (print-length-maker 'accessor))

; . . . and insert the mutator into the SETTER table we defined before.
(table-insert! *setter-table* print-length (print-length-maker 'mutator))

; Test it out:
(print-length)
;Value: 100

((setter print-length) 20)
;Value: 100

(print-length)
;Value: 20

; --------------------------------------------------------------------------

Note that the same idea could be used to get rid of the global
*setter-table* as well.

- Lyn -