> On Aug 9, 2016, at 4:46 PM, David Storrs <[email protected]> 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 [email protected].
For more options, visit https://groups.google.com/d/optout.
signature.asc
Description: PGP signature

