>> Perhaps you want to organize your programs in something like this fashion:
Yes, I agree that's the better approach. It's also easier to automate — for
instance, this macro makes the fast version of func available by default
through (require module), and then the safe version as (require (submod module
'safe)).
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#lang racket/base
(module+ safe (require racket/contract))
(define-syntax (define+provide+safe stx)
(syntax-case stx ()
[(_ (proc arg ... . rest-arg) contract body ...)
#'(define+provide+safe proc contract
(λ(arg ... . rest-arg) body ...))]
[(_ name contract body ...)
#'(begin
(define name body ...)
(provide name)
(module+ safe
(provide (contract-out [name contract]))))]))
(define+provide+safe (func x)
(expensive/c . -> . expensive/c)
(do-things x))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
On Feb 21, 2014, at 6:00 PM, Matthias Felleisen <[email protected]> wrote:
>
> On Feb 21, 2014, at 2:38 PM, Matthew Butterick wrote:
>
>>> Rewriting to avoid a dependency does work, but usually only if you can
>>> avoid some large subsystem (such as the contract system) completely.
>>
>>
>> Contracts are a good example. Here's the vexing pattern that I've run into
>> frequently
>
>
> Perhaps you want to organize your programs in something like this fashion:
>
> #lang racket
>
> (module server racket
>
> (provide
> (contract-out
> (f (natural-number/c . -> . natural-number/c))))
>
> (module fast-server racket
> (provide
> ;; Nat -> Nat
> f)
>
> (define (f i)
> (- i 1)))
>
> (require (submod "." fast-server)))
>
> (module safe-client racket
> (require (submod ".." server))
> (with-handlers ((exn:fail:contract? (compose displayln exn-message)))
> (displayln (f 0))))
>
> (module fast-client racket
> (require (submod ".." server fast-server))
> (displayln (f 0)))
>
> (require 'safe-client)
> (require 'fast-client)
____________________
Racket Users list:
http://lists.racket-lang.org/users