[racket] Read-only parameters
On Mon, Feb 11, 2013 at 4:04 PM, Gustavo Massaccesi <gustavo at oma.org.ar> wrote:
> I was trying to define a "read-only" parameter, i.e. a parameter that
> can be "read" and "parameterized", but not "written". I'd want to call
> functions without being worried that the any of them changes that
> parameter, but I want to allow each function to parameterize the
> parameter for internal use.
Perhaps you can use contracts to enforce this?
For example:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#lang racket/base
(require racket/contract)
(define my-curr-out-port (make-parameter (current-output-port)))
(provide (contract-out [my-curr-out-port (-> output-port?)]))
;; For internal use only:
(module* internals #f
(provide (all-defined-out)))
;; Example usage from the outside.
(module* test racket/base
(require (submod "..")
racket/port)
(define (hello)
(displayln "Hello" (my-curr-out-port)))
(define (quietly)
(parameterize ([my-curr-out-port (open-output-nowhere)])
(hello)))
(define (mute)
(my-curr-out-port (open-output-nowhere))) ; I'd want an error here.
(hello) ;---> "Hello"
(quietly) ;---> ""
(hello) ;---> "Hello"
(mute)
(hello) ;---> "" :(
;---
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Access to that parameter is guarded by the contract and enforced at
contract boundaries. If you run this program, you should see a
runtime error at the call to mute.
For those that really need to get at the raw parameter, they must use
a submodule require to the internals module defined there, as in:
(require (submod "name-of-my-module.rkt" internals))