Something like the following program: #lang racket
(module foomod racket (provide foo) (define/contract (foo arg) (-> string? #t) #t)) (require 'foomod) (provide (contract-out (foo (-> non-empty-string? #t)))) On Tuesday, September 4, 2018 at 9:00:06 PM UTC-4, David K. Storrs wrote: > > > > On Tue, Sep 4, 2018 at 8:55 PM, Matthew Butterick <[email protected] > <javascript:>> wrote: > >> >> On Sep 4, 2018, at 3:54 PM, David Storrs <[email protected] >> <javascript:>> wrote: >> >> Say I have this (possibly from a third-party module): >> >> (define/contract (foo arg) (-> string? #t) #t) >> >> I want to ensure that the argument is always non-empty, so I tighten the >> contract. I could do this: >> >> (set! foo (contract (-> non-empty-string? #t) foo 'foo 'neg)) >> >> Mutating the function is pretty ugly, but I'm not sure of a better way. >> >> >> >> Seems like this technique would break down with imported identifiers, for >> instance: >> >> ;;;;;;;;;;;;;;;;;;;;; >> >> #lang racket >> >> (module foomod racket >> (provide foo) >> (define/contract (foo arg) (-> string? #t) #t)) >> (require 'foomod) >> >> (set! foo (contract (-> non-empty-string? #t) foo 'foo 'neg)) >> >> (foo "") ; error: set!: cannot mutate module-required identifier in: foo >> >> >> >> > Ah, good point. I'd realized that the tighter version would be visible > only in the current module, but I hadn't noticed that you actually can't > mutate imports. Thanks. > > >> I am left with the following questions: >> >> 1) Is there a better way to do this? >> >> >> Why not the old prefix-and-wrap? >> >> ;;;;;;;;;;;;;;;;;;;;; >> >> #lang racket >> >> (module foomod racket >> (provide foo) >> (define/contract (foo arg) (-> string? #t) #t)) >> (require (prefix-in lax: 'foomod)) >> >> (define foo (contract (-> non-empty-string? #t) lax:foo 'foo 'neg)) >> >> (foo "") >> >> > That works. > > >> >> 2) If I use this method in a module other than the one where foo was >> defined, my expectation is that I would affect it only in the current >> module but that other importers would not see the change. Is this right? >> >> >> When you export this new `foo`, it carries the new contract, of course. >> (The old one remains but because your wrapper contract is tighter, any >> contract blame will happen in the new contract) >> > > Great, thanks. This does exactly what I need. > > -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.

