On Tue, Jun 29, 2021 at 12:04 PM Jonathan Simpson <[email protected]> wrote:
>
> On Monday, June 28, 2021 at 10:25:36 PM UTC-4 Sam Tobin-Hochstadt wrote:
>>
>> On Mon, Jun 28, 2021 at 9:46 PM Jonathan Simpson wrote:
>> >
>> > On Sunday, June 27, 2021 at 10:29:55 AM UTC-4 Robby Findler wrote:
>> >>
>> >> Replacing ` (~r x #:precision 1)` with `(number->string x)` and ditto for 
>> >> `y` eliminates the overhead of contracts and brings about another 4x 
>> >> speedup on my machine.
>> >
>> >
>> > This is because the compiler is able to remove the contract checks, not 
>> > because number->string doesn't have a contract, correct? If it is the 
>> > compiler, is there any rule of thumb to determine when the compiler will 
>> > likely remove the contract checks? Using typed 'for' iterators seems to be 
>> > one case that the compiler optimizes, but can we rely on others?
>>
>> There are two possible meanings for "contract checks" here. One is
>> "does it check that it gets the right kind of arguments, and raise an
>> error if not". In that sense, every function that is not "unsafe" has
>> contracts, certainly including `number->string`. The other meaning is
>> "uses the `racket/contract` library". The `~r` function has a contract
>> in that sense, while `number->string` does not, and that's a
>> significant source of overhead. On my laptop, just removing the
>> contract on `~r` in the source of the `racket/format` library speeds
>> up Bogdan's revised program from 600ms to 200ms.
>>
>> Most of the time, the compiler does not remove either kind of contract
>> check. Sometimes the first kind of contract check can be removed in
>> the simplest of cases; the second kind is basically never removed by
>> the compiler. There are other cases where macros can generate code
>> that omits contract checks, as with the `for` forms when used with
>> sequence generators like `in-list`, but that is again for simple
>> checks.
>>
>> Sam
>
>
> Thanks for the reply. I was under the impression that all of the racket 
> provided functions had full racket/contract contracts implemented at the 
> module boundary, which is what I thought was generating errors of the form:
> ---
> (number->string "aa")
> ; number->string: contract violation
> ;   expected: number?
> ;   given: "aa"
> ---

That error message is generated here:
https://github.com/racket/racket/blob/master/racket/src/cs/rumble/number.ss#L364

It uses the term "contract", and the exception is an instance of
`exn:fail:contract`, but it is not generated by the `racket/contract`
library.

> I take it that the contract error above was generated by a lower-level 
> contract then. I've only glanced at contracts, so I assume this is documented 
> somewhere. Is this section of the Reference referring to the simple contracts 
> that you mention? From https://docs.racket-lang.org/reference/contracts.html:
> ---
> Contracts come in two forms: those constructed by the various operations 
> listed in this section of the manual, and various ordinary Racket values that 
> double as contracts, including...
> ---

That whole section of the reference is about the `racket/contract`
library, and thus the second kind of contracts that I mentioned.

Sam

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAK%3DHD%2BYVJbsqvBzT-52meaoj8vV9XkdXXPFC%3DgL1JTCVxNTizA%40mail.gmail.com.

Reply via email to