[racket-dev] Five feature/limitation interactions conspire to drive mad

From: Neil Toronto (neil.toronto at gmail.com)
Date: Tue Jan 1 19:42:12 EST 2013

On 01/01/2013 03:35 PM, Matthias Felleisen wrote:
> Neil,
> thanks for the user story. We should hear more of those for all kinds of corners in our world.

You're welcome!

> Question: did you start the math library in an untyped form (and switch) or did you go with types from the get-go?

It's all been in Typed Racket from the beginning. This was initially 
because I mostly had floating-point functions planned, and I wanted TR's 
help proving that I never used non-flonums by mistake. Also, I wanted 
the special functions to have performance competitive with C 

When I decided to do arrays, Typed Racket was again the natural choice. 
First, because it's not possible to use `require/typed' to import 
polymorphic struct types. Second, because it allowed me to avoid a lot 
of runtime checks.

I discovered reasons #3 and #4 while I was writing `math/array':

3. Passing around higher-order functions can get confusing. I can't 
speak for anyone else, but when I get something like `array-axis-reduce' 
- which is like a fold but with complicated types - to pass the type 
checker, my code is usually correct.

4. TR's types for Racket's numeric tower, especially the additional 
`Index' type, makes it easy to safely use unsafe indexing. Throughout 
`math/array', values of type `Index' are always either a size (e.g. a 
vector length) or an index that has been proved to be less than a size. 
IOW, if I can get TR to prove j : Index, I'm satisfied that 
(unsafe-vector-ref xs j) is actually safe. Also, if `j' is a loop 
counter, TR can usually compare and increment using unsafe fixnum ops.

There are a bunch of other little things that are like #4 (which is only 
a big thing because indexes are so prevalent in `math/array'). Maybe 
I'll collect those into a separate user story.

Neil ⊥

Posted on the dev mailing list.