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.

Reply via email to