[plt-scheme] rename-out with contract?

From: Carl Eastlund (cce at ccs.neu.edu)
Date: Wed Feb 13 18:13:16 EST 2008

On Feb 13, 2008 4:34 PM, Chongkai Zhu <czhu at cs.utah.edu> wrote:
> If you only want to attach the contract on the module interface, then
> it's impossible to meet both requirement 1 and 2.
> One option is to you attach the contract to f itself:
> #lang scheme
> (provide f)
> (provide (rename-out [f g]))
> (define/contract f
>   (number? . -> . number?)
>   (lambda (n) n))
> But that means calls to f in the module is also contracted.

This also gets the blame wrong.  This will get all the blame right:

#lang scheme
(define contract-for-f CONTRACT-EXPR)
(define f FUNCTION-EXPR)
  [f contract-for-f]
  [rename f g contract-for-f])

That way, f will be exported as both f and g, with the same contract,
but without writing or evaluating the contract expression more than
once (only the name contract-for-f is duplicated).  The contract will
be associated with the module boundary as usual.

Alternately, you could write a new macro for it:

#lang scheme
(define-syntax provide/contract/names
  (syntax-case stx ()
    [(_ original (name ...) expr)
     (syntax/loc stx
         (define the-contract expr)
           [original the-contract]
           [rename original name the-contract] ...)))]))
(define f (lambda ...etc...))
(provide/contract+other-names f (g h) (-> ...whatever...))
;; This will provide f by its original name, plus g and h, always with
the same contract, evaluated once.

Carl Eastlund

Posted on the users mailing list.