[racket] What is the purpose of val-first-projection in contract combinators?

From: Robby Findler (robby at eecs.northwestern.edu)
Date: Sun Feb 8 09:31:37 EST 2015

Yes, that's basically right. One other point: the blame objects that a
val-first projection gets have a #f instead of a negative party, and
so you have to be careful to pass the #:missing-party argument to
raise-blame-error when you discover a contract violation. And if you
pass #f, the contract system builds a val-first projection for you.

FWIW, I think it is still as subject to change as it was when I wrote
that note. :)

The benefit this has is that more work can be done on the "server"
side when putting a contract onto a value. With the standard-style
projections, the blame argument can't be built until the client side,
which means that, for some combinators, there is a bunch of work that
gets duplicated on each different client side that could, in
principle, be done only once, on the server side. In general, the only
thing not known on the server side is the name of the client, so the
val-first projections are set up to take that argument last. Of
course, this works only for "first order" contracts. When a function
takes a function as an argument that contract construction doesn't
happen until much later and so we end up doing more work in that case.

I had hoped that this would turn into a more significant savings for
class/c than it did. I'm still hoping that I think of a better way to
set things up so class/c can benefit more. Somehow.

This is also related to the way that -> and friends have a special
path. They can turn an N-ary function into an N+1-ary function where
that extra argument is the negative party, making for a smoother path
to get into a first-order function.

As far as documentation goes, I hope to document and explain it more
when I'm more sure it is a good idea.


On Sat, Feb 7, 2015 at 11:05 PM, Alexis King <lexi.lambda at gmail.com> wrote:
> The documentation for make-contract and similar functions includes an
> optional #:val-first-projection keyword argument. What is this for? How does
> it differ from the #:projection argument?
> The documentation does include this note:
> The precise details of the val-first-projection argument are subject to
> change.
> I don’t know how long that message has been there, but I somehow doubt that
> the details are still “subject to change”. Could that argument be
> documented? I’d at least like to understand what it’s for and how I’m
> supposed to use it in new contract combinators. Also, what happens if I
> leave it out or pass #f?
> As far as I can tell, the primary difference is that the procedure supplied
> for val-first-projection takes an additional curried argument, the “negative
> party”. This is handled specially for contract failures that fail on this
> “first projection” by passing the argument to raise-blame-error via an
> undocumented keyword argument, #:missing-party. What does this do, exactly?
> Thanks,
> Alexis
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users

Posted on the users mailing list.