[racket] Call by Name

From: Eli Barzilay (eli at barzilay.org)
Date: Tue Nov 27 14:57:59 EST 2012

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!

Posted on the users mailing list.