[racket-dev] What are single flonums good for?

From: Neil Toronto (neil.toronto at gmail.com)
Date: Wed Sep 12 10:31:29 EDT 2012

I ask because I'm tired of worrying about them. More precisely, I'm 
tired of Typed Racket (rightly) making me worry about them.

I'm also a little bit tired of this:

(: foo (case-> (Single-Flonum -> Single-Flonum)
                (Flonum -> Flonum)
                (Real -> Real)))
(define (foo x)
   (cond [(double-flonum? x)  (flfoo x)]
         [(single-flonum? x)  (real->single-flonum
                               (flfoo (real->double-flonum x)))]
         [else  (flfoo (real->double-flonum x))]))

I'm annoyed by the prospect of doing something similar to subtypes of 
Real-Distribution. It's nice right now that a probability is always a 
Flonum. Changing it would make things slower, more complicated, and more 
error-prone.

They can't be for speed. I just ran some tests. With TR's optimizer off 
or in untyped Racket, the performance gain using single flonums is 
negligible. With TR's optimizer on, doubles are at least twice as fast.

Compatibility with old code? No, they were enabled in 5.1.1.

Compatibility with C code? Why not have the FFI convert them?

Save space? I can see that. It won't help much if they're sent to math 
library functions, though. Those will convert them to flonums and 
usually box the converted values.

They make it easy to write wrong code, because it's easy to use 
`exact->inexact' when you really should use `real->double-flonum'. Plot, 
for example, fails to render functions that return single flonums. I'm 
surprised it doesn't segfault.

I'm sure plot isn't the only one. Every use of `exact->inexact' in the 
standard library is suspect. If followed by applying an unsafe op, it's 
wrong.

Why do we have these things?

Neil ⊥


Posted on the dev mailing list.