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:
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)
every usage must be surrounded with quote {…} which makes it stand out from the code around
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.
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.