On Tue, Jun 29, 2021 at 12:04 PM Jonathan Simpson <jjsim...@gmail.com> 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 racket-users+unsubscr...@googlegroups.com.
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