pau.cervera
2020-8-22 07:02:53

@pau.cervera has joined the channel


laurent.orseau
2020-8-22 08:54:21

@laurent.orseau has joined the channel


laurent.orseau
2020-8-22 09:00:28

One problem with syntax-parse is that it does a lot, which looks magical at times and confusing for the beginner. syntax-case also does a lot, but less. I still recommend syntax-parse though, but maybe starting with define-simple-macro.


notjack
2020-8-22 09:02:38

agreed, using define-simple-macro whenever possible is good


notjack
2020-8-22 09:03:00

(especially because it automatically adds #:track-literals)


jestarray
2020-8-22 17:02:14

@jestarray has joined the channel


cris2000.espinoza677
2020-8-22 17:56:14

@sorawee @notjack thank you for the fix, i thought the syntax class there was just to suggest what class should the syntax be recognized as… not that it needed to be that syntax class.


zainab.ali.london
2020-8-22 18:07:44

I’ve been working with syntax/parse, but am having trouble controlling the macro expansion search.

Here’s an example to illustrate:

(define-syntax-parser bar [(_ x) #'+]) (define-syntax-parser foo [(_ x) #'(bar x)])

A call to (foo 'a) is expanded into (bar 'a), which is expanded into #<procedure:+>. I want (foo 'a) to instead expand into '+. How can I achieve this without modifying the internals of bar?

A naive attempt A naive attempt would be to quote the call to (bar x):

(define-syntax-parser foo [(_ x) #'(quote (bar x))]) This does not work—it expands to the quoted expression (bar x). This is understandable because the quote form does not expand it’s internals.

Action patterns I suspect that action patterns can be used to solve this. <https://docs.racket-lang.org/syntax/stxparse-patterns.html?q=pattern#%28form._%28%28lib.syntax%2Fparse..rkt%29.~7ebind%29%29|According to the syntax/parse docs>, the ~bind action pattern evaluates it’s expressions and binds them to results. But this still expands to (bar x):

(define-syntax-parser foo [(_ x (~bind [result #'(bar x)])) #'(quote result)]) I could be misusing the pattern, or misunderstanding what is meant by “evaluation” here.

How can I quote the expansion of (bar x)?


laurent.orseau
2020-8-22 18:09:15

[meta] I’m wondering if we shouldn’t avoid having questions about macros on the #beginners channel—apart maybe about real basics of macros. I worry this may confuse and scare actual beginners.


zainab.ali.london
2020-8-22 18:15:18

My apologies—I’ve only been working with racket proper for a few weeks, and can’t gauge the level of difficulty of this question. Please feel free to point me to a better channel. I can remove the message if it causes concern.


sorawee
2020-8-22 18:16:18

#lang racket (require syntax/parse/define) (define-syntax-parser bar [(_ x) #'+]) (define-syntax-parser foo [(_ x) #:with expanded (local-expand #'(bar x) 'expression #f) #''expanded]) (foo 'a)


sorawee
2020-8-22 18:17:33

Use local-expand to force the macro expander to expand a syntax object right away. Then, once you have #'+ in your hand, you can quote it.


laurent.orseau
2020-8-22 18:21:06

No worries at all, my question was not aimed at you, but at those who’ve been her for a while. You can ask this story of questions on #general i suppose (where you may even get better help for these), but again I was wondering more than asserting so it’s all fine :)


zainab.ali.london
2020-8-22 18:24:34

Thank you very much! I think this means that ~bind doesn’t expand it’s expressions. If so, what is meant by “evaluate” in the racket docs?

(~bind [attr-arity-decl expr] ...) Evaluates the exprs and binds them to the given attr-ids as attributes.


zainab.ali.london
2020-8-22 18:26:13

Thank you, that’s good to know


michael.hamel80
2020-8-22 18:34:14

I posted my own macro question to both #beginners and #general, not being sure which was more appropriate. I was actually more worried that my question might be judged too beginner-y for #general, but I guess it’s the other way around.


sorawee
2020-8-22 18:44:21

“Expansion” and “evaluation” are different. When you write #'(bar x), you are constructing a syntax object that is a syntax list, with bar as a first element and x as the second element. It really doesn’t compute anything further because a syntax object is a value. It evaluates to itself. But once you return this syntax object to the macro expander, the macro expander then can expand the syntax object further.

Another way to do things is to write your bar as a procedure at compile-time. Like this:

(define-for-syntax (bar x) #'+) In this case, bar is just a regular procedure (but defined at compile-time), so in foo, you can do something like:

(define-syntax-parser foo [(_ x) #:with evaled (bar #'x) #''evaled]) In the above code, (bar #'x) does computation. It evaluates to #'+.

~bind is a little bit more complicated. One instance where it’s useful is when you are conditionally pattern matching a syntax object (via ~or* or ~optional) and in one branch, you want to conditionally bind a variable to a result of a computation. But it doesn’t expand anything.


samdphillips
2020-8-22 18:45:30

We’ve also gotten some Typed Racket questions that seem a bit beyond beginner (at least to me.)


soegaard2
2020-8-22 18:45:48

I have been thinking the same.


cris2000.espinoza677
2020-8-22 20:11:22

i had the same worry. i actually just posted a question in beginners about macros, though it was more of an specific behavior on syntax-parse. even though, i already posted two questions in general… it’s just upon knowing there was a #beginners channel i just thought that i shouldn’t bother #general


jcoo092
2020-8-22 22:38:50

Over in the F# Foundation’s Slack there is a rule (not strictly enforced) that the beginner’s channel is “A monad-free zone”, since questions about that sort of thing are a bit more advanced and have the potential to scare off beginners with F#.