[racket] Call by Name
A few minutes ago, J. Ian Johnson wrote:
> If you don't need to dispatch on name at runtime, you can write a
> macro for this and use format-id to construct the identifier naming
> the function. Otherwise you would need to use eval, which is highly
> inadvisable.
A few minutes ago, David Van Horn wrote:
>
> This is a slight variation on Ian's suggestion. It uses a macro
> (id-in name n m) that constructs a list consisting of the elements
> namen ... namem-1.
These suggestions are not too useful, since they both basically
provide an alternative syntax for something that is already in the
code -- for example, the second one works only in cases like
(id-in f 1 4) where you could just as well remove the space and use
`f1'. (Realizing how they're not useful is probably a good exercise
in "getting" macors, or maybe also getting the difference between
macros and `eval' (and fexprs...).)
In any case, here's another thing to consider, which is more likely to
be a good solution when you run into such a problem: build a table
that maps names to functions:
(define function-names (make-hash))
(define (call-by-name name . args)
(apply (hash-ref function-names name) args))
And when you define a function, add it to the table too:
(define (test1) 'foo)
(hash-set! function-names "test1" test1)
(define (test2) 'bar)
(hash-set! function-names "test2" test2)
(call-by-name (format "test~a" (add1 (random 2))))
This is looks verbose -- but that's fixable with a very simple macro:
(define-syntax-rule (define/name (name . xs) body ...)
(begin (define (name . xs) body ...)
(hash-set! function-names (symbol->string 'name) name)))
(define/name (test1) 'foo)
(define/name (test2) 'bar)
(call-by-name (format "test~a" (add1 (random 2))))
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://barzilay.org/ Maze is Life!