...code…)
On Jul 8, 2019, at 10:41 AM, David Storrs <david....@gmail.com> wrote:Nothing specific that I'm aware of, but others could answer this better. If there are then they're probably related to speed.Personally, I'm quite fond of them because they eliminate the need for a lot of tests and make the code much more self-documenting.Function contracts are detailed here: https://docs.racket-lang.org/reference/function-contracts.html In the left-hand navbar you'll see a bunch of related topics, like data-structure contracts.
On Mon, Jul 8, 2019 at 12:56 PM Greg Hendershott rac...@greghendershott.com wrote:
- The return value is `any` -- not even `any/c`, just `any`. Effectively
don't check the return value(s).
If I use define/contract
, does any
restore tail-recursion?
You could also move some definitions into a sub-module, and contract the
provide from there.
I’m very excited about #:unprotected-submodule which could generate an unsafe submodule, and let clients pick a version they want to use. Note that it’s not in Racket 7.3, but presumably is going to be in Racket 7.4.
In general, though, I wish there are contract exporting combinators. E.g., a combinator that suppresses post-condition checking, or a combinator that approximates a higher-order contract into a first-order contract. contract-out
then can generate multiple submodules with different contracts according to these combinators.
In any case, the nice thing is that you can use or create any boundary
you prefer to put the contract on.
It’s nice indeed, but I wish switching boundaries could be easier. Changing (define/contract ...)
to (provide (contract-out ...)) (define ...)
(and vice versa) is not fun. A macro that facilitates this switching in the stdlib would be nice.
But in a call chain we can end up verifying a value repeatedly and wouldn’t it be marvelous if we could somehow pass it’s certification in syntax (no, I don’t know what I’m talking about, just dreaming) so that verification would only happen once and when needed?
That’s what Typed Racket does. As I understand, in untyped modules, Racket also elides pair checking when it’s safe to do so.
Gustavo’s work-in-progress addition to the Chez Scheme compiler introduces the kinds of optimizations that he has long built and maintained in the current Racket implementation. For example, (f (car x) (cdr x)) can be optimized to (f (car x) (unsafe-cdr x)). These optimizations are particularly helpful for structure-field access and update, and preliminary measurements suggest that the optimizations can provide about half of the performance benefit of unsafe mode (so, typically 5-10%) without the unsafety.
But yes, eliding contract checks in general is my dream as well.