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

From: Doug Williams (m.douglas.williams at gmail.com)
Date: Sun Oct 4 18:17:57 EDT 2009

When I was originally thinking about it, I was thinking a macro, too. I like
the real->float as an exported function for simplicity - I think most users
of the science collection would be more comfortable with it in their own
code. But I like the syntax of the following macro.

(define-syntax (with-float stx)
  (syntax-case stx ()
    ((_ (x ...) expr ...)
     (for ((id (in-list (syntax->list #'(x ...)))))
       (unless (identifier? id)
         (raise-syntax-error #f
                             "not an identifier"
     #`(let ((x (if (real? x)
                    (exact->inexact x)
                    (error "expected real, given" x)))
         expr ...))))

It would be used in something like:

(define (test x y)
  (with-float (x y)
    (printf "x = ~a, y = ~a~n" x y)))

The expr's are executed with x and y guaranteed to be floats. So, (test 10
20) prints x = 10.0 y = 20.0 and (test 10+10i 20) errors with expected real,
given 10+10i. Also, the x's must be identifiers or a syntax error is raised
at expansion time.

Can any of the macro gurus comment on whether this make sense? It works, but
for example, there might be a cleaner way than the (syntax->list #'(x ...))
to do the iteration.

On Sun, Oct 4, 2009 at 4:55 PM, Dave Herman <dherman at ccs.neu.edu> 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))]))
> Dave
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/dev/archive/attachments/20091004/b403ddcc/attachment.html>

Posted on the dev mailing list.