[racket-dev] Removing Xexpr preference from Web Server

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Mon Dec 6 10:33:10 EST 2010

(This is a SE sermon, general but hopefully not opaque as Matthew and Robby think my emails often are: 

Separating the contract from the functionality of a function/method/etc is a matter of stating the interface clearly and as such a matter of documentation. So use contracts for that purpose. 

In some cases, however, we just don't know how to write performant contracts and we have to give up for now until compilers and runtime systems are better.) 





On Dec 6, 2010, at 10:23 AM, Jay McCarthy 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.
> 
> 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.