[racket-dev] Removing Xexpr preference from Web Server

From: Robby Findler (robby at eecs.northwestern.edu)
Date: Mon Dec 6 11:25:57 EST 2010

On Mon, Dec 6, 2010 at 9:23 AM, Jay McCarthy <jay.mccarthy at gmail.com> wrote:
> Yes, since I am allowing users to customize the coercion behavior, I could
> either have them provide two functions: a coercion-applies? function and a
> coercion function; OR I could have them just provide the coercion function
> and I will check the answer and re-run it inside of the function body.
>
> The other issue is that finding all the places where I should apply the
> coercion inside the body of the function is difficult, because I need to do
> it at every place where a response/c could flow in (relatively easy) and
> every place where a response/c could flow out (much hard, esp. with
> continuations). Contracts on functions are very nice in their ability to do
> stuff to inputs and outputs.


I think I need more help to understand the programming problem better.
Why are your users supplying you a contract that you are using to
protect your functions? That is how can you use anything about that
contract to avoid errors in your programs?

Robby

> Jay
>
> On Mon, Dec 6, 2010 at 8:19 AM, Matthias Felleisen <matthias at ccs.neu.edu>
> wrote:
>>
>> The string->number primitive is probably closer to what Jay wants to do.
>>
>> The only contract I can think of for string->number is
>>
>>  ;; Number -> Boolean
>>  (define (string->number-able? x)
>>    (number? (string->number x)))
>>
>> So the real problem is a performance problem, which a lazy interpretation
>> of contracts by the compiler might be able to eliminate.
>>
>> Is this the true problem Jay -- Matthias
>>
>>
>>
>>
>>
>>
>>
>>
>> On Dec 6, 2010, at 9:45 AM, Robby Findler wrote:
>>
>> > 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
>> >>
>> >>
>>
>
>
>
> --
> 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.