Hi Philip

Thank-you for sharing your version: each example and variation is helping
me understand the machinery better.

I agree that clarity in error reporting is also vital, and it's been made
clear to me that it is feasible to hook into the contract system and take
advantage of its facilities, which is great.

Once I've made another pass I'll include the error messages for critical
discussion.

On the subject of turning down contracts for performance and then being
bitten, believe me, I hear you: my preference is to have the maximum
checking I can afford. But when I'm really writing stringent
post-conditions (or invariants) they can get *really* expensive, negatively
impacting on user experience, which takes us into the land of pragmatic
trade-offs.

If I don't have a way to turn them off I'm either not going to write them
at all or comment them out, and then regret not using them on smaller test
scenarios.

Dan





On Wed, May 3, 2017 at 1:51 PM, Philip McGrath <phi...@philipmcgrath.com>
wrote:

> Here's the "quick" way I'd write the real-sqrt in Racket, combined with an
> illustration of one of the advantages of using the established contract
> combinators: here they gracefully report a kind of error that in the
> original would have caused an error in the error-checking code.
>
> (define/contract (real-sqrt x)
>   (->i ([x (>=/c 0)])
>        [rslt (x)
>         (if (= 0 x)
>             (=/c 0)
>             (and/c (>=/c 0)
>                    (λ (rslt) (<= (abs (- x (* rslt rslt))) error))))])
>   "not even a number")
>
>
> The part of what you describe that has the least support in the Racket
> system is controlling the level of safety through a mechanism
> like pre-conditions-on/post-conditions-on. It would be easy enough to
> create a contract that is always satisfied if e.g. pre-conditions-on (which
> might be most Rackety to right as a parameter) is non-false, but I would
> suspect, at least in a case like this, you would already have paid most of
> the cost by getting into the contract system in the first place.
>
> The most typical solution, as Matthew illustrates, is to attach the
> contract at a module boundary with contract-out rather than a function
> boundary with define/contract, perhaps ultimately to attach it only to the
> public API of your library rather than for internals, and to leave off
> checks on the domains of functions (with the "any" contract) once you know
> they behave properly. Personally, though, having been annoyed once too
> often in tracking down an error that turned out to result from having
> changed the number of values a function returned, I'm happy to pay the
> price for good errors and trust the wonderful Racket implementers to keep
> the price as cheap as possible.
>
> Interestingly I had some trouble getting the nicely specific error
> messages you had in your example: I'll post about that separately.
>
> -Philip
>

-- 
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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to