[racket] Perlin and simplex noise - optimizing Racket code

From: Vincent St-Amour (stamourv at ccs.neu.edu)
Date: Fri Apr 12 11:15:22 EDT 2013

At Thu, 11 Apr 2013 20:14:48 -0400,
JP Verkamp wrote:
> Thanks for the advice! It's certainly been an interesting journey into
> Typed Racket... :)
> 
> Here are the results thus far (for a 256x256 perlin, simplex, and
> colored-simplex image).
> 
> Original:
>   cpu time: 1139 real time: 1134 gc time: 232
>   cpu time: 780 real time: 773 gc time: 124
>   cpu time: 1950 real time: 2044 gc time: 328
> 
> Typed:
>   cpu time: 640 real time: 653 gc time: 110
>   cpu time: 546 real time: 542 gc time: 62
>   cpu time: 1342 real time: 1364 gc time: 218
> 
> So it's definitely a good start.
> 
> Unfortunately, there are a few oddities that I'm not sure how to deal with.
> 
> *1) *Which is more idiomatic / easier for Typed Racket to deal with:
> 
> (: mix (Flonum Flonum Flonum -> Flonum))
> (define (mix a b t)
>   ...)
> 
> (define: (mix [a : Flonum] [b : Flonum] [t : Flonum]) : Flonum
>   ...)
> 
> Right now, I'm using the former, but I'm not sure I'm happy with it.

I tend to use the former, but both are idiomatic, and TR treats both the
same way.

> *2)* How can I deal with integer values (specifically 0) to a function with
> flonum types?
> 
> Specifically, perlin (and simplex) have the type:\
> 
> (: perlin
>    (case-> (Flonum -> Flonum)
>            (Flonum Flonum -> Flonum)
>            (Flonum Flonum Flonum -> Flonum)))
> 
> But if I try to do something like this:
> 
> (perlin (* 1.0 (/ 0 256)))
> 
> I get this error:
> 
> Type Checker: No function domains matched in function application:
> Domains: Flonum Flonum Flonum
>          Flonum Flonum
>          Flonum
> Arguments: Zero
> 
> Basically, (* 1.0 (/ 0 256)) is 0, not 0.0. For the timing tests above, I
> worked around this with real->double-flonum but that seems suboptimal (they
> types are leaking). Is there something I'm missing there?

`(* 0 anything)' is `0', this is a special case in Racket's numeric
tower. It does make reasoning about types a little tricky, because the
normal contagion rules don't apply.

`real->double-flonum' or `fl' is the right thing to use here.

> *3)* How do I type a color% / bitmap%?
> 
> I tried typing noisy-image-test.rkt, but I kept running into this. I can
> use Any, but it seems like objects should be typeable. No luck finding out
> how though.

Typed Racket currently has limited support for classes and objects.
`bitmap%' and `color%' should already have types (in typed/mred), so
maybe that's enough for your needs. Better support for classes and
objects is in the works.

Vincent

Posted on the users mailing list.