[racket-dev] Removing Xexpr preference from Web Server
On Mon, Dec 6, 2010 at 11:19 AM, Jay McCarthy <jay.mccarthy at gmail.com> wrote:
>
>
> On Mon, Dec 6, 2010 at 10:16 AM, Robby Findler <robby at eecs.northwestern.edu>
> wrote:
>>
>> Who should be blamed if the coercion does not return a response?
>
> The provider of the coercion should be blamed, but that is not possible [I
> think] so the positive party of the whole dynamic/c is blamed.
Can you show us an example use of this contract from the web server?
>> Is there a contract on current-response/c? (I assume that the "/c"
>> there is a misnomer and it really is a parameter that holds a
>> contact/coercion, not a contract.)
>
> current-response/c is contracted with (parameter/c contract?)
> The /c is not a misnomer, you are just parsing it wrong. Read it as
> (parameter (contract response)) not (contract (parameter response)), where
> /c is the post-fix syntax for (contract x) and current- is the pre-fix
> syntax for (parameter x)
Ah. I see.
Robby
>
>>
>> Robby
>>
>> On Mon, Dec 6, 2010 at 10:55 AM, Jay McCarthy <jay.mccarthy at gmail.com>
>> wrote:
>> > Maybe dynamic/c isn't clear enough... its definition is pretty short:
>> > (define (dynamic/c pre parameter post)
>> > (define pre-ctc (coerce-contract 'pre pre))
>> > (define post-ctc (coerce-contract 'post post))
>> > (make-contract
>> > #:name (build-compound-type-name 'dynamic pre-ctc parameter post-ctc)
>> > #:projection
>> > (λ (b)
>> > (define pre-proj ((contract-projection pre-ctc) b))
>> > (define post-proj ((contract-projection post-ctc) b))
>> > (λ (x)
>> > (define dyn-proj
>> > ((contract-projection (coerce-contract 'dynamic (parameter)))
>> > b))
>> > (post-proj
>> > (dyn-proj
>> > (pre-proj
>> > x)))))))
>> > The system provides pre and post, so it can offer protection to the
>> > coercion
>> > as well as receive protection FROM the coercion. But the coercion comes
>> > from
>> > a parameter which is exposed to the user.
>> > The one I use in the web-server is:
>> > (dynamic/c any/c current-response/c response?)
>> > where response? is the data structure predicate that the internal
>> > plumbing
>> > uses.
>> > Jay
>> > On Mon, Dec 6, 2010 at 9:51 AM, Jay McCarthy <jay.mccarthy at gmail.com>
>> > wrote:
>> >>
>> >> That's why dynamic/c has a pre/c and post/c. Before it uses the user's
>> >> contract, it applies pre/c. After it applies post/c. This ensures that
>> >> the
>> >> user's contract actually coerces to a response?
>> >> Jay
>> >>
>> >> On Mon, Dec 6, 2010 at 9:25 AM, Robby Findler
>> >> <robby at eecs.northwestern.edu> wrote:
>> >>>
>> >>> 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
>> >>> >
>> >>
>> >>
>> >>
>> >> --
>> >> 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
>> >
>
>
>
> --
> 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
>