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 <dher...@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 > >
_________________________________________________ For list-related administrative tasks: http://list.cs.brown.edu/mailman/listinfo/plt-dev