syntax-class composed of literals

28 views
Skip to first unread message

Dan Liebgold

unread,
Nov 16, 2016, 6:11:26 PM11/16/16
to Racket Users
Hi,

A couple questions about literals in syntax-parse:

1. I'd like to make a syntax-class that is just a set of literals (with a clear error for something not matching any literal). Is there a better way than this:

http://pasterack.org/pastes/86722

I need to ignore the bindings for those identifiers, and I need to preserve the syntax context.

2. Is there any plan or easy way to implement #:datum-literal-sets for syntax-classes? It'd be nice to share a list of literals (with ignored bindings) among multiple classes.

Thanks,
Dan

Ryan Culpepper

unread,
Nov 16, 2016, 6:47:41 PM11/16/16
to Dan Liebgold, Racket Users
Literal sets can include datum-literals:

(define-literal-set lits #:datum-literals (a b c) (d e))

For question 1, that's probably the best way. If you want to suppress
the printing of all of the datum literals in error messages, you can
mark the syntax class as `#:opaque`.

In principle, you could also use `literal-set->predicate`, but I just
discovered it ignores the datum literals. I'll push a fix.

Ryan

Dan Liebgold

unread,
Nov 16, 2016, 7:42:21 PM11/16/16
to Racket Users, dan_li...@naughtydog.com
>
> Literal sets can include datum-literals:
>
> (define-literal-set lits #:datum-literals (a b c) (d e))
>

Ah, oops I missed that keyword parameter.

> For question 1, that's probably the best way. If you want to suppress
> the printing of all of the datum literals in error messages, you can
> mark the syntax class as `#:opaque`.
>

I was more wanting to avoid keeping two lists of the literals in the source... I *do* want the error to enumerate possibilities.

> In principle, you could also use `literal-set->predicate`, but I just
> discovered it ignores the datum literals. I'll push a fix.
>

I saw that... assuming it worked, I'm not sure how/where I would put that..

Vincent St-Amour

unread,
Nov 16, 2016, 7:51:44 PM11/16/16
to Dan Liebgold, Racket Users
FWIW, Eric Dobson wrote a very nice `define-literal-syntax-class` macro
that is used extensively inside TR.

https://github.com/racket/typed-racket/blob/master/typed-racket-lib/typed-racket/utils/literal-syntax-class.rkt

Its companion `define-merged-syntax-class` is quite nice too.

https://github.com/racket/typed-racket/blob/master/typed-racket-lib/typed-racket/optimizer/utils.rkt#L110

I've used those in other projects as well, and like them a lot.

Ryan: Would you consider adding them (or something like them) to
syntax/parse?

Vincent
> --
> 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...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Dan Liebgold

unread,
Nov 16, 2016, 8:24:12 PM11/16/16
to Racket Users, dan_li...@naughtydog.com, stam...@eecs.northwestern.edu
> FWIW, Eric Dobson wrote a very nice `define-literal-syntax-class` macro
> that is used extensively inside TR.
>
> https://github.com/racket/typed-racket/blob/master/typed-racket-lib/typed-racket/utils/literal-syntax-class.rkt
>

Hmm... I can't quite figure that one out. Maybe with some examples? How does the ":spec" in the pattern work? It's just a class specified....

The examples in TR seem to declare classes one literal at a time?

I was just looking for exactly that... very useful.

Ryan Culpepper

unread,
Nov 16, 2016, 10:32:10 PM11/16/16
to Dan Liebgold, Racket Users
Something like this:

(define-literal-set var-type-lits ....)

(define-syntax-class var-type
(pattern x:id
#:fail-unless
((literal-set->predicate var-type-lits) #'x)
"unrecognized var-type"))

But then you wouldn't get the enumeration of the literals in errors either.

Ryan

Ryan Culpepper

unread,
Nov 16, 2016, 10:44:19 PM11/16/16
to Vincent St-Amour, Racket Users
On 11/16/2016 07:51 PM, Vincent St-Amour wrote:
> FWIW, Eric Dobson wrote a very nice `define-literal-syntax-class` macro
> that is used extensively inside TR.
>
> https://github.com/racket/typed-racket/blob/master/typed-racket-lib/typed-racket/utils/literal-syntax-class.rkt
>
> Its companion `define-merged-syntax-class` is quite nice too.
>
> https://github.com/racket/typed-racket/blob/master/typed-racket-lib/typed-racket/optimizer/utils.rkt#L110
>
> I've used those in other projects as well, and like them a lot.
>
> Ryan: Would you consider adding them (or something like them) to
> syntax/parse?

I could add a `#:define-syntax-class name` option to
`define-literal-set` that would additionally define `name` as a
syntax-class matching any of the literals. I would want to wait to add
that until I implement the backtracking-aware handling of
disappeared-uses, which I just haven't gotten to yet.

For `define-merged-syntax-class`, I don't think I would put it in core
syntax/parse, but maybe as a library in syntax/parse/lib/*.

Ryan

Ryan Culpepper

unread,
Nov 16, 2016, 10:50:17 PM11/16/16
to Dan Liebgold, Racket Users
On 11/16/2016 08:24 PM, Dan Liebgold wrote:
>> FWIW, Eric Dobson wrote a very nice `define-literal-syntax-class` macro
>> that is used extensively inside TR.
>>
>> https://github.com/racket/typed-racket/blob/master/typed-racket-lib/typed-racket/utils/literal-syntax-class.rkt
>>
>
> Hmm... I can't quite figure that one out. Maybe with some examples?
> How does the ":spec" in the pattern work? It's just a class
> specified....

Suppose you have

(define-syntax-class sc #:attributes (a b) ....)

The pattern x:sc or (~var x sc) binds x, x.a, and x.b.
The pattern :sc or (~var || sc) binds just a and b (no prefix).
The pattern _:sc or (~var _ sc) binds nothing.

Note that || is a way of writing the 0-length identifier in Racket.

Ryan

Vincent St-Amour

unread,
Nov 17, 2016, 12:06:13 PM11/17/16
to Ryan Culpepper, Vincent St-Amour, Racket Users
On Wed, 16 Nov 2016 21:42:14 -0600,
Ryan Culpepper wrote:
>
> On 11/16/2016 07:51 PM, Vincent St-Amour wrote:
> > FWIW, Eric Dobson wrote a very nice `define-literal-syntax-class` macro
> > that is used extensively inside TR.
> >
> > https://github.com/racket/typed-racket/blob/master/typed-racket-lib/typed-racket/utils/literal-syntax-class.rkt
> >
> > Its companion `define-merged-syntax-class` is quite nice too.
> >
> > https://github.com/racket/typed-racket/blob/master/typed-racket-lib/typed-racket/optimizer/utils.rkt#L110
> >
> > I've used those in other projects as well, and like them a lot.
> >
> > Ryan: Would you consider adding them (or something like them) to
> > syntax/parse?
>
> I could add a `#:define-syntax-class name` option to
> `define-literal-set` that would additionally define `name` as a
> syntax-class matching any of the literals. I would want to wait to add
> that until I implement the backtracking-aware handling of
> disappeared-uses, which I just haven't gotten to yet.

Sure, that works.

> For `define-merged-syntax-class`, I don't think I would put it in core
> syntax/parse, but maybe as a library in syntax/parse/lib/*.

Yeah, that one is just a nice-to-have. It's pretty easy to express using
the existing syntax-parse API.

Vincent
Reply all
Reply to author
Forward
0 new messages