# [plt-dev] `unsafe-fl' and unboxing

Dave Herman wrote:
>>* ;;; (real->float x) -> inexact-real?
*>>* ;;; x : real?
*>>* ;;; Returns an inexact real (i.e., a float) given real x. Raises an
*>>* error if x
*>>* ;;; is not a real. This can be used to ensure a real value is a float,
*>>* even in
*>>* ;;; unsafe code.
*>>* (define (real->float x)
*>>* (if (real? x)
*>>* (exact->inexact x)
*>>* (error "expected real, given" x)))
*>>*
*>>* I'll use it to protect unsafe code. I'm sure it's more overhead than
*>>* putting it in-line, but hopefully not too much. Putting a contract on
*>>* it would probably not make much sense.
*>*
*>* I feel a little dirty suggesting it, but you could also do:
*>*
*>* (define-syntax-rule (real->float exp)
*>* (let ([x exp])
*>* (if (real? x)
*>* (exact->inexact x)
*>* (error "expected real, given" x))))
*>*
*>* I'm not sure whether the mzscheme compiler obeys the Macro Writer's Bill
*>* of Rights in optimizing the case where exp is just a variable reference.
*>* If not, you could do the optimization yourself:
*>*
*>* (define-syntax (real->float stx)
*>* (syntax-case stx ()
*>* [(_ x)
*>* (identifier? #'x)
*>* #'(if (real? x)
*>* (exact->inexact x)
*>* (error "expected real, given" x))]
*>* [(_ exp)
*>* #'(let ([x exp])
*>* (real->float x))]))
*
No! 'identifier?' does not check whether a syntax object represents a
variable reference, given 1) identifier macros and 2) #%top transformers
for unbound variables. If you really, really want to check if something
is a variable reference, 'local-expand' it and look at the result.
But even if it is a variable reference, there's no guarantee that there
isn't another thread holding a reference to it, waiting to change it
from a real to, say a complex number right after the 'real?' check is done.
Ryan