Choose-out:   Conditional Provide
choose-out
1 Choose-Out Renamings
make-choose-out-renaming
choose-out-renaming?
undo-choose-out-renaming
7.0

Choose-out: Conditional Provide

 (require choose-out) package: choose-out

provide-spec

(choose-out proc-expr [true-id false-id] ...)

Exports the names true-id. The expression proc-expr must evaluate at expansion-time to a zero-argument procedure. Each name is bound to a transformer that conditionally expands to true-id or false-id depending on the result of the given procedure in the importing module.

Examples:
> (module struct-math racket
    ; `num` is an internal representation
    (struct num [value])
  
    ; set this to `#t` in modules that use `num` values
    (define-for-syntax num-client? (box #false))
  
    ; addition for `num` values
    (define (num-+ n0 n1)
      (num (+ (num-value n0) (num-value n1))))
  
    ; wrapper: convert `num` addition to Racket addition
    (define (racket-+ v0 v1)
      (num-value (num-+ (num v0) (num v1))))
  
    ; export `num-+` or `racket-+` depending on the importing module
    (require choose-out)
    (provide
      num
      (for-syntax num-client?)
      (choose-out (λ () (unbox num-client?))
        [num-+ racket-+])))
> (module struct-client racket
    ; familiar client, uses the `num` representation
    (require 'struct-math)
    (begin-for-syntax (set-box! num-client? #true))
    (displayln (num-+ (num 2) (num 2))))
> (require 'struct-client)

#<num>

> (module racket-client racket
    ; foreign client: uses Racket numbers
    (require 'struct-math)
    (displayln (num-+ 2 2)))
> (require 'racket-client)

4

Typed Racket uses a similar protocol to decide whether an identifier exported from a typed module should be protected with a contract. A #lang typed/racket module expands (via #%module-begin) to code that sets a flag similar to the num-client? flag in the example above.

1 Choose-Out Renamings

A choose-out renaming is a kind of rename transformer.

procedure

(make-choose-out-renaming rename?    
  true-id    
  false-id)  choose-out-renaming?
  rename? : (-> any/c)
  true-id : identifier?
  false-id : identifier?
Construct a choose-out renaming from a predicate and two identifiers. Adds the 'not-free-identifier=? syntax property to both identifiers.

procedure

(choose-out-renaming? x)  boolean?

  x : any/c
Predicate for a choose-out renaming.

procedure

(undo-choose-out-renaming id)  identifier?

  id : identifier?
If id is bound to a choose-out renaming, returns the source of the renaming. Otherwise, returns id.