[racket] Read-only parameters
Thanks to all!
I prefer the Eli's method because the "read-only" effect can be
enforced from definition of the "parameter".
With some minor modification, so parameterize/ro can use parameters
and parameters/ro:
(define-syntax-rule (parameterize/ro ([p v] ...) b ...)
(parameterize ([(if (param/ro? p) (param/ro-p p) p) v] ...) b ...)))
Gustavo
On Tue, Feb 12, 2013 at 3:39 AM, Eli Barzilay <eli at barzilay.org> wrote:
> Two hours ago, Matthew Flatt wrote:
>> I don't think there's currently a way to have a read-only parameter.
>
> ... because there's no way to know when a parameter is used to change
> its value as part of parameterize, or as part of a side-effect thing.
> So another option is to make up a new kind of parameters that do that:
>
> #lang racket/base
>
> (module param/ro racket/base
> (provide make-param/ro parameterize/ro)
> (struct param/ro (p) #:property prop:procedure (λ (rop) ((param/ro-p rop))))
> (define (make-param/ro v) (param/ro (make-parameter v)))
> (define-syntax-rule (parameterize/ro ([p v] ...) b ...)
> (parameterize ([(param/ro-p p) v] ...) b ...)))
>
> (require 'param/ro racket/port)
>
> (define my-curr-out-port (make-param/ro (current-output-port)))
>
> (define (hello)
> (displayln "Hello" (my-curr-out-port)))
>
> (define (quietly)
> (parameterize/ro ([my-curr-out-port (open-output-nowhere)])
> (hello)))
>
> (define (mute)
> (my-curr-out-port (open-output-nowhere))) ; I'd want an error here.
>
> ;; constrain any mutation of `my-cur-out-port' to the dynamic
> ;; extent of `thunk':
> (define (limit thunk)
> (parameterize/ro ([my-curr-out-port (my-curr-out-port)])
> (thunk)))
>
> (hello) ;---> "Hello"
> (limit quietly) ;---> ""
> (hello) ;---> "Hello"
> ;; (limit mute) <-- arity error
> (hello) ;---> "Hello" :)
>
> --
> ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
> http://barzilay.org/ Maze is Life!