Transparent Syntax Extensions

Hello everyone!

My question is: is there a way in Scala 3 to implement transparent syntax extensions from inside the language?

What I mean is I’d like to be able to (somehow) define a new syntax object of arbitrary form (with some kind of a macro, or smth), and transparently use it later in code, without messing with the compiler.

I’ve read something about quotes used to implement DSL’s, but as I understand there are three downsides which I’d like to avoid:

  1. they do NOT allow for arbitrary syntax (not sure about this one, but I believe everything inside qoutes should be valid Scala syntax so that you could do pattern-matching on the structure later)
  2. every usage must be surrounded with quote {…} which makes it stand out from the code around
  3. definitions created for one DSL are not (easily, at least) reusable for other ones

I believe there could be some mechanism for what I want, similar to syntax-case from Scheme, or syntax-parse from Racket (both of which are actually not powerful enough too, but you could get the idea), but couldn’t find anything on the internet.

Any help would be appreciated!

I’m not a deep expert on this subject, but my understanding is that this is 100% intentional. Scala 2’s never-entirely-released macro system was kind of wild-west: it allowed you to do lots of things (since you were essentially plugging into the compiler), but wasn’t all that well-principled and turned out to be a significant maintenance headache. Scala 3’s is somewhat more restricted, but much more official and supported, and basically applies a 90/10 rule: it lets you do most stuff more easily than in Scala 2, but deliberately doesn’t try to be all things to all people.

So basically, yeah, it doesn’t allow completely-arbitrary syntax. The language is flexible enough to accomplish a lot, but you can’t just define a random DSL and assume that the Scala compiler will be able to handle it – that’s not a goal of the language.

Every usage? No, typically not – Scala code in the wild is full of macros, and it’s unusual to need to do that at call sites.

I mean, compatibility is always something you need to think about, in any code. But I don’t see how macros are any different from anything else in this regard.

It might be helpful if you could give some examples of what you’re trying to do – that might help folks give you advice about what’s realistic.

3 Likes