[racket] Use `set!' or not in this scenario?
Here is what Joe is saying, with fake macros; the first two parts are real:
#lang racket
;; -----------------------------------------------------------------------------
;; an example using lexical scope
(define (f1-lexical-scope x)
(define the-data (sin x))
(define (f2 y)
`(f2 ,(f3 y)))
(define (f3 z)
`(f3 ,(f4 z)))
(define (f4 w)
`(f4 ,the-data ,w))
(f2 10))
(f1-lexical-scope pi)
;; -----------------------------------------------------------------------------
;; the same example with the 'monad' spelled out
(define (f1-monad x)
(define the-data (sin x)) ;;
((f2 10) the-data))
(define ((f2 y) the-data)
`(f2 ,((f3 y) the-data)))
(define ((f3 z) the-data)
`(f3 ,((f4 z) the-data)))
(define ((f4 w) the-data)
`(f4 ,the-data ,w))
(f1-monad pi)
;; -----------------------------------------------------------------------------
;; a sketch of how syntax would hide the monad where needed
;; the following macros are fake, because I don't have time to write them out:
;; see the HtDP language macros for #%app, which register functions too
;; defines the-data and initializes it
(define-syntax-rule (create-store x) (define the-data x))
;; registers f as a store-passer
(define-syntax-rule (define-store-passer (f x) e) (define ((f x) the-data) e))
;; this supplements #%app so that when a registered store-passer f is applied,
;; it picks up the-data in a curried application; other functions work normally
(define-syntax-rule (apply-store-passer f x ...) (old-apply (f x ...) the-data))
;; pick up the-data from secret stash
(define-syntax-rule (access-store) 42)
;; if you had these macros, the above would read like this:
(define (f1-monad.v2 x)
(create-store (sin x)) ;;
(f2 10))
(define-store-passer (f2.v2 y)
`(f2 ,(f3 y)))
(define-store-passer (f3.v2 z)
`(f3 ,(f4 z)))
(define (f4.v2 w)
`(f4 ,(access-store) ,w))
(f1-monad.v2 pi)