Here's something in the ballpark.

#lang racket

(define-namespace-anchor nsa)
(define ns (namespace-anchor->namespace nsa))

(let ((xyz 1))
  (for ((name '(x y z)))
    (namespace-set-variable-value! name (lambda () (displayln (format "~a:
~a" name xyz)) (set! xyz (add1 xyz))) #f ns)))

(eval '(x) ns)

On Tue, Aug 9, 2016 at 5:20 PM, 'John Clements' via Racket Users <
racket-users@googlegroups.com> wrote:

>
> > On Aug 9, 2016, at 4:46 PM, David Storrs <david.sto...@gmail.com> wrote:
> >
> > In Perl it's possible to generate main-namespace functions like so:
> >
> > perl -E 'my $z = 1; for (qw/foo bar baz/) {my $x = $_; *$_ = sub{ say
> "$x: ", $z++ }};  foo(); bar(); baz();'
> >
> > This outputs:
> > foo: 1
> > bar: 2
> > baz: 3
> >
> >
> > Note that it is generating top-level subroutines that can be called from
> elsewhere in the program (including other modules) and that those
> subroutines close over existing lexical variables.
> >
> >
> > I tried to do this in Racket and haven't been able to figure it out:
> >
> > First attempt, only partial solution:
> > $ racket
> > -> (for ((name '(x y z))) (define name (lambda () (displayln "foo"))))
> >
> > ; /Applications/Racket_v6.3/collects/racket/private/for.rkt:1487:62:
> begin
> > ;   (possibly implicit): no expression after a sequence of internal
> definitions
> > ;   in: (begin (define name (lambda () (displayln "foo"))))
> > ; [,bt for context]
> >
> >
> > I found 'eval', but that doesn't close over lexical variables (
> https://docs.racket-lang.org/guide/eval.html: "The eval function cannot
> see local bindings"):
> >
> > $ racket
> > Welcome to Racket v6.3.
> > -> (let ((xyz 1)) (for ((name '(x y z))) (eval `(define ,name (lambda ()
> (displayln (format "~a: ~a" ,name ,xyz) (set! xyz (add1 xyz))))))))
> >
> > -> (x)
> > (x)
> > ; xyz: undefined;
> > ;  cannot reference undefined identifier
> > ; [,bt for context]
> >
> >
> > What have I not found?
>
> Racket is essentially a lexically scoped language. That is: it should be
> possible to look at a piece of code and figure out where the binding for a
> given variable is. It does have a dynamic binding mechanism, but the names
> that are bound dynamically … can be determined lexically.
>
> This might seem to prevent the kind of code that you’re talking about, but
> Racket compensates for this with an extraordinarily flexible macro system,
> and a very permissive notion of what exactly constitutes “compile-time.”
> It’s certainly possible to dynamically generate a piece of code using
> macros. Once generated, though, this piece of code is going to behave
> dependably.
>
> How does this affect your particular example? Well, it’s extremely easy to
> write a macro that does what you describe:
>
> #lang racket
>
> (define-syntax makefuns
>   (syntax-rules ()
>     [(_ name ...)
>      (begin (define name (lambda () (displayln "foo")))
>             ...)]))
>
> (makefuns x y z)
>
> (x)
>
> (y)
>
> (z)
>
>
>
> Does this solve your problem? If not, why not? It’s going to depend a lot
> on what exactly you want to do.
>
>
> Hope this helps, apologies for telling you anything that you already knew.
>
> John
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to