[racket-dev] Removing Xexpr preference from Web Server

From: Robby Findler (robby at eecs.northwestern.edu)
Date: Mon Dec 6 09:45:33 EST 2010

Let's be clear here: our inability to enforce projectionness is in no
way condoning the two coercianlike contracts that you have now
written.

That said, the only value I see to contracts that only signal errors
(or do nothing) is that programmers know what to expect from them. The
downsides you mention are well taken, of course.

In this specific case, your message seems slightly confused: certainly
you should be able to use a contract to ensure that the coercion will
always succeed. Let's assume you have done that and now discuss only
where the coercing bit of the "contract" goes. Is it in a higher order
position? Is it something that describes an interface to your module
or can it be considered an internal detail?

As a possible guide by analogy, consider the path-string? Predicate.
It is the contract on many functions the ultimately is connected to
some kind of a coercion somehwere buried inside the racket primitives
for dealing with the filesystem. Is that like what you want to do? If
so, how would your arguments hold up for that part of our system?

Robby

On Monday, December 6, 2010, Jay McCarthy <jay.mccarthy at gmail.com> wrote:
> These contracts are not thrown "at dynamic places". The contract is always at the module boundary/etc, but its meaning if affected by the dynamic context of the particular boundary crossing. [1]
>
> I'm been thinking about why I want to use contracts for this purpose.
> The alternative is to put an any/c contract in all the places I currently have response/c and as the first thing in all those functions call current-any->response [or as the last thing on returns] on the input argument. I would then have to put a note in all the documentation of those any/c that it doesn't REALLY accept anything, instead in other accepts things that the dynamic current-any->response will turn into a response. If the coercion failed, then I would have to throw an error, which be purely dynamic with no blame information because it would not be associated with a contract boundary.
>
> In contrast, using a contract for this purpose allows me to centralize the documentation and behavior of these arguments, get correct blame on places where the coercion fails, and abstract the coercion out of the code that is using it into its interface. These are all great wins.
>
> In my opinion, if I did not use contracts, the only elegant thing to do would be to recreate something almost exactly like the contract system but called the coercion system. That is absurd to me when contracts already do exactly this.
>
> Am I just not clever enough to think of another elegant way?
> Why is there so much resistance to using the contract system in a perfectly legal way according to its own definition & contracts? [2] [i.e. "projection" functions are not forced to be projections by any means. / contracts already break eq?/equal?-ness / etc]
>
> Jay
> 1. We already have such context-sensitive contracts:
> http://docs.racket-lang.org/xml/index.html#(def._((lib._xml/main..rkt)._permissive/c))
>
> permissive/c exists to allow DrRacket to embed more snips inside the XML boxes, which are otherwise not XML elements.
> 2. make-contract's projection keyword has the contract (-> any/c any/c)
>
> The example of make-contract coerces the procedure by restricting how many arguments rather than checking that when it is given that number of arguments it is used properly, etc.
>
> Only flat and chaperone contracts attempt to enforce projection-ness.
> On Sun, Dec 5, 2010 at 9:31 AM, Matthias Felleisen <matthias at ccs.neu.edu> wrote:
>
> Jay, coercions aka casts in our world are compound words with -> in between them. Why do you need a new name?
>
> (There is an inconsistency in their behavior. To wit
>
> Welcome to Racket v5.0.99.4.
>> (integer->char 1000000000000000)
> integer->char: expects argument of type <exact integer in [0,#x10FFFF], not in [#xD800,#xDFFF]>; given 1000000000000000
>
>  === context ===
> /Users/matthias/plt/collects/racket/private/misc.rkt:78:7
>> (string->number "a10")
> #f
>
> But that is a historical problem.)
>
> ;; ---
>
> I am also reluctant to throw contracts at dynamic places. Contract boundaries should be syntactically distinct, e.g., module boundaries or define/contract.
>
> ;; ---
>
> I think you're really just checking an assertion. So perhaps you want to go with /a as a suffix.
>
>
> -- Matthias
>
>
>
>
> --
> Jay McCarthy <jay at cs.byu.edu>
> Assistant Professor / Brigham Young University
> http://faculty.cs.byu.edu/~jay
>
> "The glory of God is Intelligence" - D&C 93
>
>


Posted on the dev mailing list.