State & Computational Effects

Store

Store-Passing Specifications

In store-based language, any expression may have an effect. To specify these effects, we need to describe what store should be used for each evaluation and how each evaluation can modify the store.

Effect-full

In a store-passing specification, the store is passed as an explicit argument to value-of and is returned as an explicit result from value-of. Thus we write (value-of exp1 ρ σ0) = (val1,σ1). This asserts that expression *exp*1, evaluated in environment ρ and with the store in state σ0, returns the value *val*1 and leaves the store in a possibly different state σ1.

Effect-free

Thus we can specify an effect-free operation like const-exp by writing (value-of (const-exp *n*) ρ σ) = (*n*,σ) showing that the store is unchanged by evaluation of this expression.

Implementation

We represent the state of the store as a Scheme value, but we do not explicitly pass and return it, as the specification suggests. Instead, we keep the state in a single global variable, to which all the procedures of the implementation have access.

;; the-store
(define the-store ’uninitialized)

;; empty-store : () → Sto 
(define empty-store (lambda () ’()))

;; get-store : () → Sto 
(define get-store (lambda () the-store))

;; initialize-store! : () → Unspecified
(define initialize-store! (lambda () (set! the-store (empty-store))))

;; reference? : SchemeVal → Bool 
(define reference? (lambda (v) (integer? v)))

;; newref : ExpVal → Ref 
(define newref 
	(lambda (val) 
		(let ((next-ref (length the-store)))
			(set! the-store (append the-store (list val))) next-ref)))

;; deref : Ref → ExpVal 
(define deref (lambda (ref) (list-ref the-store ref)))

;; setref! : Ref x ExpVal → Unspecified
(define setref!
  (lambda (ref val)
    (set! the-store
       (letrec ((setref-inner
									(lambda (store1 ref1)
			               (cond ((null? store1) (report-invalid-reference ref the-store)) 
													 ((zero? ref1) (cons val (cdr store1)))
					                 (else (cons (car store1) (setref-inner (cdr store1) (- ref1 1)))))))) 
					(setref-inner the-store ref)))))