Though it is an off-label use of contracts, it can be done. I made something I call "coercion contracts" that mutate & validate the input (or output) argument as part of the contract:
(define/contract (function-that-wants-something-stringlike x) (coerce/string? . -> . coerce/boolean?) (do-things-to x)) Source code is here: https://github.com/mbutterick/sugar/blob/master/coerce/contract.rkt Or do `raco pkg install sugar` and (require sugar/coerce/contract) Please note: I am setting a terrible example. >> I feel like this has come up before, but I can't seem to find the >> discussion in the archive. I have a procedure that needs to perform a >> fairly expensive computation which is needed both for checking the >> inputs and for producing output. I'd like to avoid computing it twice, >> and I'd also like to use contracts to check the inputs. Is there any >> reasonable way to do this? > > > No. The contract system is designed so that the contractual > computations are in principle independent from the 'mutator' > computations. > > >> The code is like this: >> >> (define (do-stuff x y z) >> (define important-value (expensive x y z)) >> ... do stuff with important-value ...) >> >> (provide/contract >> [do-stuff (->i [x ...] [y ...] [z (x y) >> contract-that-depends-on-important-value]) [result ...])]) >> >> >> I could memoize the expensive computation, but that would require >> something like an LRU cache to avoid memory problems, and I'd rather >> not have to worry about that. >> >> Alternatively, I could shift things around so that the contract is on >> the procedure that generates important-value, but then blame reporting >> would be incorrect. >> >> Any ideas? > > > Define a syntactic abstraction that spans contracts and 'mutators'. > > -- Matthias > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users
____________________ Racket Users list: http://lists.racket-lang.org/users