> On Jan 22, 2018, at 7:22 PM, Matthew Flatt <[email protected]> wrote:
>
> I think I've never considered `splicing-parameterize` because
> parameters can be mutated, but a `splicing-parameterize` form does make
> sense. I imagine that it would be implemented by creating a
> parameterization once, then pushing the parameterization over multiple
> expressions using `call-with-parameterization`.
IIUC, to use `call-with-parameterization`, each expression needs to become the
body of a thunk. This works for expressions that return a value. But forms like
`define` and `require` can't be used as the body of a thunk. So one has to
specially pluck them out. The example below works, albeit brutally. Is there a
more elegant pattern for picking out identifiers that cannot appear as the body
of a thunk?
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#lang racket/base
(require racket/splicing
(for-syntax racket/base racket/syntax))
(define-syntax (splicing-parameterize stx)
(syntax-case stx ()
[(_ ([PARAM VAL] ...) . BODY)
(with-syntax* ([PZATION (generate-temporary)]
[NEW-BODY (map (λ (stx)
(syntax-case stx ()
[(ID ARG0 . ARGS)
(memq (syntax->datum #'ID) '(define
define-values)) ; ... and others
#'(ID ARG0 (call-with-parameterization
PZATION (λ () (begin . ARGS))))]
[(ID . ARGS)
(memq (syntax->datum #'ID) '(require
provide splicing-let)) ; ... and others
#'(ID . ARGS)]
[OTHER #'(call-with-parameterization
PZATION (λ () OTHER))])) (syntax->list #'BODY))])
#'(splicing-let ([PZATION (parameterize ([PARAM VAL] ...)
(current-parameterization))]) . NEW-BODY))]))
(define my-param (make-parameter 0))
(splicing-parameterize ([my-param 42])
(add1 (my-param))
(sub1 (my-param))) ; prints 43 and 41 to repl
(splicing-parameterize ([my-param 42])
(define x (my-param))
(check-equal? x 42)
(define-values (y z) (values (add1 (my-param)) (sub1
(my-param)))))
(splicing-parameterize ([my-param 42])
(require rackunit))
(check-equal? x 42)
(check-equal? y 43)
(check-equal? z 41)
--
You received this message because you are subscribed to the Google Groups
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.