[plt-dev] `unsafe-fl' and unboxing
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"
stx
id)))
#`(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>