[racket] sharing an expensive computation required in procedure and its contract?

From: Jon Zeppieri (zeppieri at gmail.com)
Date: Sun Jul 20 13:56:04 EDT 2014

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?

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?

-Jon

Posted on the users mailing list.