[racket] The function that returns closure and symbols leaking

From: Eli Barzilay (eli at barzilay.org)
Date: Sat May 14 23:05:33 EDT 2011

10 minutes ago, Kazimir Majorinc wrote:
> I want to write the function "counted" that generates closures in
> Scheme; I want that after this
>     (define f (counted '(x) '(+ x x)))

Why do you want it to be a function?

> f behaves like I wrote
>    (define f (let((i 0))
>                (lambda(x)            ;first argument
>                  (set! i (+ i 1))
>                  (display i)
>                  (+ x x))))          ;second argument
> and to avoid symbols leaking which happens if I call
>     (define f (counted '(i) '(+ i i)))
> How would you do that "idiomatically"?

The idiomatic way would be to use a macro.

    (define-syntax-rule (counted (x ...) body ...)
      (let ([i 0])
        (lambda (x ...)
          (set! i (add1 i))
          (printf "~s\n" i)
          body ...)))

> Is it possible to avoid symbol leaking relying only on lexical
> scope, without explicit alpha-conversion (gensym, built in or
> manual) and without macros?

You could probably create the function as you want (most likely with
`eval', and all the problems that that gets you), then wrap the
resulting function as a counted version:

    (define (counted args body)
      (let ([f (...eval horror...)]
            [i 0])
        (lambda (x)
          (set! i (add1 i))
          (printf "~s\n" i)
          (f x))))

But calling that "idiomatic" is pretty meaningless now.

          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!

Posted on the users mailing list.