Re: [racket-users] How to call a macro on each element of a list
> On Mar 31, 2016, at 3:31 PM, cna...@cs.washington.edu wrote: > > On Thursday, March 31, 2016 at 1:00:55 AM UTC-7, cna...@cs.washington.edu > wrote: >> On Wednesday, March 30, 2016 at 5:37:08 PM UTC-7, Neil Van Dyke wrote: > > I found a solution to my problem. I realised that it was better to use a > function instead of a macro to generate the code. I created a list and > appended the different parts of the code I wanted to generate in bottom up > manner. eval-ing the list can run the code. Speaking *only for myself*: In a situation such as the one you describe, I’m about 86% confident that there’s no need for ‘eval’ *or* a macro. As Neil points out, ‘eval’ comes with substantial risks and development costs. Naturally, if you’ve got something that works, I understand that it may make more sense to stick with that. John Clements -- 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.
Re: [racket-users] How to call a macro on each element of a list
I found a solution to my problem. I realised that it was better to use a function instead of a macro to generate the code. I created a list and appended the different parts of the code I wanted to generate in bottom up manner. eval-ing the list can run the code. If that works for you, good. But you might later find that there are better ways to do what you want (the *what* is still unclear to me). Here is the `eval` FAQ, from "http://lists.racket-lang.org/users/archive/2014-July/063597.html": Q: How do I use eval? A: Don't use eval. Q: But don't so many academic books feature eval prominently, so doesn't that mean I should use try to eval? A: Those books use eval for pedagogic reasons, or because the author is enamored of some theoretical appeal of eval, or because the author wants to watch the world burn. Don't use eval. Q: But, but, but, I am just starting to learn, and eval seems to do what I need. A: Eval is almost certainly not what you want. Learn how to use the other basics effectively. Don't use eval. Q: I now am very comfortable with the language, I am aware that I should avoid eval in almost all cases, and I can tell you why eval is actually the right thing in this highly unusual case. A: Cool, that's why eval is there. See also "http://lists.racket-lang.org/users/archive/2014-July/063612.html;. Neil V. -- 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.
Re: [racket-users] How to call a macro on each element of a list
On Thursday, March 31, 2016 at 1:00:55 AM UTC-7, cna...@cs.washington.edu wrote: > On Wednesday, March 30, 2016 at 5:37:08 PM UTC-7, Neil Van Dyke wrote: > > Does either the below `fun-now` or `make-fun-for-later` do what you want? > > > > BEGIN CODE > > #lang racket/base > > > > (define conditional-actions > >(list (cons (lambda () (= 2 (+ 1 1))) > >(lambda () (display "first!\n"))) > > (cons (lambda () (= 42 (* 2 21))) > >(lambda () (display "second!\n") > > > > (define (fun-now lst) > >(for-each (lambda (pair) > >(and ((car pair)) > > ((cdr pair > > lst)) > > > > (display "fun-now...\n") > > (fun-now conditional-actions) > > > > (define (make-fun-for-later lst) > >(lambda () > > (for-each (lambda (pair) > > (and ((car pair)) > > ((cdr pair > >lst))) > > > > (display "make-fun-for-later...\n") > > (define fun-later (make-fun-for-later conditional-actions)) > > (display "fun-later...\n") > > (fun-later) > > END CODE > > > > BEGIN OUTPUT > > fun-now... > > first! > > second! > > make-fun-for-later... > > fun-later... > > first! > > second! > > END OUTPUT > > > > I gave this kind of example of using procedures because I don't know > > whether you're already familiar with how to use procedures/closures like > > this. > > > > Neil V. > > yes this is the effect I was looking for, but fun-now and fun-later are > interpreting the conditional actions while I wanted to generate the code for > them. I found a solution to my problem. I realised that it was better to use a function instead of a macro to generate the code. I created a list and appended the different parts of the code I wanted to generate in bottom up manner. eval-ing the list can run the code. -- 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.
Re: [racket-users] How to call a macro on each element of a list
On Wednesday, March 30, 2016 at 5:37:08 PM UTC-7, Neil Van Dyke wrote: > Does either the below `fun-now` or `make-fun-for-later` do what you want? > > BEGIN CODE > #lang racket/base > > (define conditional-actions >(list (cons (lambda () (= 2 (+ 1 1))) >(lambda () (display "first!\n"))) > (cons (lambda () (= 42 (* 2 21))) >(lambda () (display "second!\n") > > (define (fun-now lst) >(for-each (lambda (pair) >(and ((car pair)) > ((cdr pair > lst)) > > (display "fun-now...\n") > (fun-now conditional-actions) > > (define (make-fun-for-later lst) >(lambda () > (for-each (lambda (pair) > (and ((car pair)) > ((cdr pair >lst))) > > (display "make-fun-for-later...\n") > (define fun-later (make-fun-for-later conditional-actions)) > (display "fun-later...\n") > (fun-later) > END CODE > > BEGIN OUTPUT > fun-now... > first! > second! > make-fun-for-later... > fun-later... > first! > second! > END OUTPUT > > I gave this kind of example of using procedures because I don't know > whether you're already familiar with how to use procedures/closures like > this. > > Neil V. yes this is the effect I was looking for, but fun-now and fun-later are interpreting the conditional actions while I wanted to generate the code for them. -- 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.
Re: [racket-users] How to call a macro on each element of a list
Does either the below `fun-now` or `make-fun-for-later` do what you want? BEGIN CODE #lang racket/base (define conditional-actions (list (cons (lambda () (= 2 (+ 1 1))) (lambda () (display "first!\n"))) (cons (lambda () (= 42 (* 2 21))) (lambda () (display "second!\n") (define (fun-now lst) (for-each (lambda (pair) (and ((car pair)) ((cdr pair lst)) (display "fun-now...\n") (fun-now conditional-actions) (define (make-fun-for-later lst) (lambda () (for-each (lambda (pair) (and ((car pair)) ((cdr pair lst))) (display "make-fun-for-later...\n") (define fun-later (make-fun-for-later conditional-actions)) (display "fun-later...\n") (fun-later) END CODE BEGIN OUTPUT fun-now... first! second! make-fun-for-later... fun-later... first! second! END OUTPUT I gave this kind of example of using procedures because I don't know whether you're already familiar with how to use procedures/closures like this. Neil V. -- 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.
Re: [racket-users] How to call a macro on each element of a list
On Wednesday, March 30, 2016 at 2:21:52 PM UTC-7, Neil Van Dyke wrote: > cna...@cs.washington.edu wrote on 03/30/2016 05:11 PM: > > I still need to explicitly pass all the arguments to mysyn such as: > > (mysyn 1 2 3). Is there a way to pass a list l by its name and not its > > values. > > For instance, If l is '(1 2 3) > > I want to be able to call the macro as (mysyn l) and not (mysyn 1 2 3). Is > > this possible? > > > > What do you *ultimately* want to do? Can you give a example or more > concrete description of that? > > (I'm not sure that syntax extension is the way. So this toy example > might be confusing things.) > > Neil V. The ultimate goal is to generate code for a function whose body is a conditional. So, basically, I wanted to create a macro that would take as argument a function name and a list of pairs. It will generate a conditional for each pair in the list. The first element of a pair used for checking a condition and the second element of the pair is the action to be taken if the condition is true. -- 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.
Re: [racket-users] How to call a macro on each element of a list
> However, my problem is still not resolved because in all the suggestions > above, I still need to explicitly pass all the arguments to mysyn such as: > (mysyn 1 2 3). Is there a way to pass a list l by its name and not its > values. > For instance, If l is '(1 2 3) > I want to be able to call the macro as (mysyn l) and not (mysyn 1 2 3). Is > this possible? Yes, it is possible, but not precisely in the way you describe. Macros run at compile-time, so if you create a definition (which exists at runtime), it will not be available when the macro runs (simply because that code has not been run yet!). However, you can define arbitrary values at compile-time using define-syntax, not just macros, and you can use this with the syntax-local-value function to access the value. Try something like this: (define-syntax (mysyn stx) (syntax-case stx () [(_ els-id) (with-syntax ([(el ...) (syntax-local-value #'els-id)]) #'(begin (displayln el) ...))])) (define-syntax l '(1 2 3)) (mysyn l) Notice (define-syntax l ...) and the call to syntax-local-value. -- 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.
Re: [racket-users] How to call a macro on each element of a list
cna...@cs.washington.edu wrote on 03/30/2016 05:11 PM: I still need to explicitly pass all the arguments to mysyn such as: (mysyn 1 2 3). Is there a way to pass a list l by its name and not its values. For instance, If l is '(1 2 3) I want to be able to call the macro as (mysyn l) and not (mysyn 1 2 3). Is this possible? What do you *ultimately* want to do? Can you give a example or more concrete description of that? (I'm not sure that syntax extension is the way. So this toy example might be confusing things.) Neil V. -- 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.
Re: [racket-users] How to call a macro on each element of a list
On Wednesday, March 30, 2016 at 1:45:09 PM UTC-7, Robby Findler wrote: > Perhaps we should improve the syntax-parse documentation? I found the > overview and examples to be pretty good, tho. > > Robby > > > On Wed, Mar 30, 2016 at 3:42 PM, Neil Van Dykewrote: > > Oops, I usually end up typing one of the names wrong. Summary: > > > > * syntax-case -- good one to start with, smooth path to syntax-parse > > > > * syntax-parse -- best thing ever, but documentation is intimidating, so > > maybe start with syntax-case instead > > > > * syntax-rules -- old, limited, no smooth path, you probably don't want to > > ever use this, though you'll occasionally you'll see an old-timer use it > > when they're in a hurry > > > > > > Neil V. > > > > -- > > 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. Thank you for the feedback. Indeed I am not using macros just for learning them but for generating code that I will run later. The example I gave here was a toy one. However, my problem is still not resolved because in all the suggestions above, I still need to explicitly pass all the arguments to mysyn such as: (mysyn 1 2 3). Is there a way to pass a list l by its name and not its values. For instance, If l is '(1 2 3) I want to be able to call the macro as (mysyn l) and not (mysyn 1 2 3). Is this possible? -- 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.
Re: [racket-users] How to call a macro on each element of a list
Robby Findler wrote on 03/30/2016 04:45 PM: Perhaps we should improve the syntax-parse documentation? I found the overview and examples to be pretty good, tho. When the goal is to teach syntax extension, maybe it would make sense to pick *one* syntax extension form to introduce to people, and stick with it throughout all the teaching. (I have never understood the approach of throwing a few of the different forms at people in rapid-fire, changing syntax/convention/model on people before they hardly have any experience. "First, let's show you *this* way; and then, when you want to do something more powerful, forget what you know, and do it this *other* way; and, hey, let me show you these other tools that are out there, isn't this all great." Then they sit down to start experimenting, and they get confused and discouraged for no good reason, over trivia of all the different tools that happen to exist. Latest data point is this person, who was stumbling over quasisyntax in syntax-rules. That's just discouraging for the person, when what I'd prefer to see is constructionist immersion, and learning the more more important ideas about application of syntax extension.) Neil V. -- 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.
Re: [racket-users] How to call a macro on each element of a list
Oops, I usually end up typing one of the names wrong. Summary: * syntax-case -- good one to start with, smooth path to syntax-parse * syntax-parse -- best thing ever, but documentation is intimidating, so maybe start with syntax-case instead * syntax-rules -- old, limited, no smooth path, you probably don't want to ever use this, though you'll occasionally you'll see an old-timer use it when they're in a hurry Neil V. -- 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.
Re: [racket-users] How to call a macro on each element of a list
A few things: 1. You're mixing elements of `syntax-rules` and `syntax-case` / `syntax-parse`. The former has an implicit template in its right-hand side, so you don't need the `#``, whereas you do with `syntax-case` / `syntax-parse`. 2. If you want this to define a function (as I'm guessing from the name `fun`), you should add parentheses around the name you're defining. 3. Because you're not trying to *match* the name `fun`, but only expanding to it, you don't need it in the literal list. Here's a version that should do what you want: (define-syntax mysyn (syntax-rules () [(mysyn element ...) (define (fun) (display element) ...)])) (mysyn 1 2 3) Or, using the simpler `define-syntax-rule`: (define-syntax-rule (mysyn element ...) (define (fun) (display element) ...)) Of course, it's usually best to use functions wherever possible, and only use macros as a last resort. Assuming you're planning to use the code (i.e., you're not using it to learn about macros), I'd write it like this: (define (fun . args) (for-each display args)) Functions compose more easily, and are easier to understand and to debug. Vincent On Wed, 30 Mar 2016 15:06:24 -0500, cna...@cs.washington.edu wrote: > > Consider a toy macro defined as: > > (define-syntax mysyn > (syntax-rules(fun) > [(mysyn element ...) >(begin > #`(define fun > (display element)...))])) > > and a list: > (define l '(1 2 3)) > > Is there a way to call the macro like so: (mysyn l). When I try this, the > syntax object created looks like: '(define fun (display l)). > What I want it to look like is: > > '(define fun >(display 1) >(display 2) >(display 3)) > > > In other words, my question is whether/how I can pass the entire list to the > macro and let the macro be expanded on each element of it. > > -- > 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.
Re: [racket-users] How to call a macro on each element of a list
You had the right idea, if you're using `syntax-rules`, but there were a few small problems: BEGIN #lang racket (define-syntax mysyn (syntax-rules () ((_ NAME ELEMENTn ...) (define (NAME) (display ELEMENTn) ... (mysyn fun 1 2 3) (fun) END But, if you expect to be doing more macro work in the future, you probably want to learn `syntax-case` instead of `syntax-rules`. (Because `syntax-rules` is an old legacy form that has some major restrictions that get too cumbersome for many nontrivial purposes. `syntax-case`, on the other hand, is much more powerful, and `syntax-case` also provides a smooth path to the crazy-awesome `syntax-rules`, once one is ready to not be too intimidated by `syntax-rules` documentation.) Neil V. -- 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.