Re: [racket-users] How to call a macro on each element of a list

2016-04-04 Thread 'John Clements' via Racket Users

> 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

2016-03-31 Thread Neil Van Dyke
 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

2016-03-31 Thread cnandi
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

2016-03-31 Thread cnandi
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

2016-03-30 Thread Neil Van Dyke

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

2016-03-30 Thread cnandi
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

2016-03-30 Thread Alexis King
> 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

2016-03-30 Thread Neil Van Dyke

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

2016-03-30 Thread cnandi
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 Dyke  wrote:
> > 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

2016-03-30 Thread Neil Van Dyke

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

2016-03-30 Thread Neil Van Dyke

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

2016-03-30 Thread Vincent St-Amour
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

2016-03-30 Thread Neil Van Dyke
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.