
@alexharsanyi thank you very much!

@sschwarzer Well, those “stack gymnastics” still bothers me. :zany_face:

@skew70 has joined the channel

The only reliable way to get the (almost) latest version of Racket on Linux without any fuss is to use the Racket linux installer.

The versions of Racket that come with Debian-based distros, which use apt
as the package manager, are often too old, especially on the LTS versions of those distros.

Rolling release distros (like Arch) often catch up quickly, but still they can be a little behind



Hi, this is a question about this error message I’m getting: syntax-parse: an ellipsis-head pattern matched an empty sequence
, which I don’t know how to resolve (or what that means?). I have syntax classes that parse sequential pairs of $a
and $b
expressions defined as: (define-syntax-class $a
(pattern [(~literal a) data:string]))
(define-syntax-class $b
(pattern [(~literal b) data:string]))
(define-splicing-syntax-class $ab
#:auto-nested-attributes
(pattern (~seq sf-a:$a sf-b:$b)))
and these work exactly as expected. If I have an expression like (foo (a "X") (b"Y") (a "X") (b "Y"))
, the above will group this into two $ab
expressions. Now, I want to match variable sequences of $a
’s and $b
’s; e.g., in this expression: (foo (a "X") (b "Y") (b "Y") (a "X") (a "X") (b "Y") (b "Y") (b "Y"))
, I would want to group the first $a
and the following two $b
’s into one $ab
, and the remaining two $a
’s followed by the last three $b
’s into a second $ab
. I thought I could add ellipses into my $ab
class to achieve this: (define-splicing-syntax-class $ab
#:auto-nested-attributes
(pattern (~seq sf-a:$a ... sf-b:$b ...)))
…but when I do I get the ellipses-head pattern
error above. I’ve tried nested ~seq
’s and a few other convoluted things, but I keep getting that error. What’s the right way to accomplish this?

Can you make a complete runnable example that gives the error?

Ahh, so as I was putting together a minimal example I realized that there might be something else going on. Here’s an example that shows the error, but there’s more to the expressions I’m trying to handle than my simplified explanation above; these $ab
’s are terminated by a single final expression (which is not an $a
or a $b
). When I removed that, the above actually no longer gives me that error message, but with that last extra
expression, for some reason it no longer works…

Just noticed a small typo: should be (_ group:$ab ... extra:expr)
, with one underscore, not three.

#lang racket
(require syntax/parse/define)
(begin-for-syntax
(define-syntax-class $a
(pattern [(~literal a) data:string]))
(define-syntax-class $b
(pattern [(~literal b) data:string]))
(define-splicing-syntax-class $ab
#:auto-nested-attributes
(pattern (~seq sf-a:$a ... sf-b:$b ...)))
(displayln (syntax-parse (syntax (a "X"))
[x:$a #'x]))
(displayln (syntax-parse (syntax (b "Y"))
[x:$b #'x]))
(displayln (syntax-parse (syntax ((a "X") (b "Y")))
[(xy:$ab) #'xy]))
(displayln (syntax-parse (syntax ((a "X") (a "Y") (b "X") (b "W")))
[(xy:$ab) #'xy])))

outputs

#<syntax:/Users/soegaard/tmp/hzafar.rkt:16:36 (a "X")>
#<syntax:/Users/soegaard/tmp/hzafar.rkt:19:36 (b "Y")>
#<syntax ((a "X") (b "Y"))>
#<syntax ((a "X") (a "Y") (b "X") (b "W"))>
#<syntax:/Users/soegaard/tmp/hzafar.rkt:16:36 (a "X")>
#<syntax:/Users/soegaard/tmp/hzafar.rkt:19:36 (b "Y")>
#<syntax ((a "X") (b "Y"))>
#<syntax ((a "X") (a "Y") (b "X") (b "W"))>

I notice that your pattern (pattern (~seq sf-a:$a ... sf-b:$b ...))
matches a bunch of $a’s followed by a bunch of $b’s.

Your example (foo (a "X") (b "Y") (a "X") ...)
however mixes the order.

My intention in the definition of the foo
macro was that it should parse that as multiple $ab
groups. So, with the example file above if I remove extra:expr
from the definition of foo
, the expression (foo (a "X") (b "Y") (a "X") (b "Y") (b "Y"))
produces '(("X" "Y" extra) ("X" "Y" "Y" extra))
for me.

I think I misunderstood where my error was coming from; it seems the issue might really be that extra expression at the end… But why does that cause a problem for syntax-parse?

I am not sure. (displayln (syntax-parse (syntax ((a "X") (b "Y") extra))
[(_ group:$ab extra:expr)
#'(list )]))
also produces syntax-parse: an ellipsis-head pattern matched an empty sequence

The patten $ab is (define-splicing-syntax-class $ab
#:auto-nested-attributes
(pattern (~seq sf-a:$a ... sf-b:$b ...)))

And I expect sf-a:$a ...
to match (a "X")
and for sf-b:$b ...
to match (b "Y")

Wait - the _ should not be there in my examples.

Weirdly, that actually works for me (screenshot in thread) ?


My examples run without the foo macro. This (displayln (syntax-parse (syntax ((a "X") (b "Y") (a "Z") (b "W")))
[(group:$ab ... )
#'(group ...)]))
prints #<syntax:/Users/soegaard/tmp/hzafar.rkt:30:19 (((a "X") (b "Y")) ((a "Z") (b "W")))>

Yeah, sorry ignore the foo definition at the bottom of the screen; the displayln is just printing the syntax as in your example, without using foo.

Ah - but you remembered to remove the _ . I didn’t…

And you right adding something after: (displayln (syntax-parse (syntax ((a "X") (a "Y") (b "X") (b "W") 42))
[(group:$ab ... 42)
#'(list)]))
gives the error.

So let’s think for moment. An “ellipsis head pattern” is a pattern that comes before an ellipsis.

Oh! Does $ab match 42 ?

In (define-splicing-syntax-class $ab
#:auto-nested-attributes
(pattern (~seq sf-a:$a ... sf-b:$b ...)))

if both sf-a:$a ... sf-b:$b ...
matches empty sequences we have the problem.

(Sorry, completely unrelated) Is there a (standard?) way to make a macro generate code depending on a debug ‘mode’ (e.g., errortrace is loaded or not)? I have a macro for define
that would generate a big macro with lots of error checking when in debug mode, but a short macro otherwise.

Don’t know.

@zafar.huma I am thinking, one can use ...+
instead of ...
to match at least one a followed by a least one b.

Another possible distinction: drracket compilation vs command line raco compilation. Though I don’t really want it to be tied specifically to drracket

Or use (~and same-pattern-as-before (~not ())).

Ah, didn’t know ...+
existed!

If that’s a legal pattern (that is).

Thanks, let me try that…

Or if you just want to match a sequence of as and bs in any other use (~or $a $b) ...

Maybe @greg knows? If possible, he might have seen it in connection with racket-mode.

@soegaard2 replacing the ellipses with ...+
in for the $ab pattern worked! Thanks a lot! :slightly_smiling_face:

@wanpeebaw As far as I know, the common idea is that if the stack depth you’re working with is >3, you should refactor. :slightly_smiling_face: I think if not beyond 3, the “stack gymnastics” isn’t too bad.

Yes I was referring to the teaching language. thanks!

@laurent.orseau IIRC errortrace-lib is used via an eval-handler: Something parameterizes current-eval
. Typically that handler checks compiled-expression?
and doesn’t instrument if true. So, I think this is about run time not compile time. That is, your define
macro would need to expand to the definition of a function that does a runtime test, and uses either the checked or unchecked branches. I think?

As for compilation by drracket vs. raco make, idk. Again I think that’s a runtime check? What to check, idk except something hacky like having a current-load/use-compiled
handler checking if the zo path is compiled
or compiled/drracket
(or whatever the latter is)?

I’m definitely not sure either of these are the most correct and/or best answers. I only chimed in because I got @
-ed. :slightly_smiling_face:

Thanks for the insights - my initial reaction was that there were no way of detecting it at all - but seeing what you have done with racket-mode, I wasn’t sure at all.

Well I’m not sure there’s a “standard” way, as Laurent put it — meaning official or reliable or correct. But OTOH there is also “detectable”, and “good enough for a tool where people understand the caveats/limits”.

I guess mainly I wanted to point out that errortrace isn’t about rewriting code at expansion time, instead it’s at eval/run time, IIUC.

errortrace is more like the rewriting that the step-debugger does — at least in quality if not quantity

Here is an example, not quite readable. https://prog21.dadgum.com/33.html\|https://prog21.dadgum.com/33.html

https://gather.town/app/wH1EDG3McffLjrs0/racket-users Agenda. (more of a set of suggestions and talking points than a strict agenda) 1. What have you been working on? 2. Papers/package for discussion: Take your pick…we are going _macro crazy_ for this meetup! 3. Stuck macro: Predictable Macros for Hindley-Milner http://davidchristiansen.dk/pubs/tyde2020-predictable-macros-abstract.pdf\|paper and http://davidchristiansen.dk/pubs/tyde2020-predictable-macros.webm\|video by Langston Barrett, David Thrane Christiansen & Samuel Gélineau. 4. <https://cs.brown.edu/~sk/Publications/Papers/Published/sk-automata-macros/paper.pdf|Automata via Macros (Functional Pearl) by Shriram Krishnamurti> 5. resyntax
<https://pkgs.racket-lang.org/package/resyntax|: An experimental refactoring tool for Racket built on top of syntax-parse by Jack Firth>

Very interesting post, thank you!