[racket] contracts on liberal function inputs: avoiding duplicate effort
> To ensure that an input string represents a valid address, the contract
> needs to parse the string. The constructor for the address structure
> also needs to parse the string to get the data, so it's redundant.
>
> (I didn't come up with a nice solution though)
BTW it's not that I want to abuse contracts — on the contrary, contracts are such a handy & distinctive idiom that I keep wanting to fold more of my input & output processing into them. For instance, I've thought about creating a pattern like this:
(define/lambda-contract (f x)
(in/lc . -> . out/lc)
(do-stuff-to x))
That expands into something like this:
(out/lc (do-stuff-to (in/lc x))
Where each "lambda contract" embodies both a data-conversion step and traditional contract-checking step:
(define in/lc (lambda (x) (in-processing (in/c x))))
(define out/lc (lambda (x) (out/c (out-processing x))))
So (f x) ultimately evaluates to this:
(out/c (out-processing (do-stuff-to (in-processing (in/c x)))))
The contracts are still at the function boundaries, where they need to be.
But there's an obvious problem on the input side, because in-processing wants x, not the result of (in/c x).
(And probably other obvious problems I'm not considering, because I haven't figured out how to cure that one.)