[Discussion] A perspective on super let: could a related “lift” capability ever belong in Rust’s macro system?
Looking back at Scheme every so often when pondering the design of macro-related functionality certainly can’t hurt. For this syntax-local-lift-expression you’re mentioning, docs seem to be here I haven’t quite figured out yet what exactly the relevance of scoping even is in the context of Scheme. I’d have to look into this more deeply to actually understand how it’s used, I certainly wouldn’t mind any pointers as to where I could read some pre-existing explanations/introductions.[1]
The idea to connect the functionality for super let somehow more closely with macros is certainly one I could find compelling myself. I don’t believe an API exclusive to procedural macros would be the best approach, but that’s probably a minor discussion point & likely could be solved by also offering such functionality to declarative macros with some syntax based on RFC 3086 – Declarative macro metavariable expressions.
I find the mental model of literally “generating a binding in an outer scope” (hygienically), then working with a simple identifier an interesting one that I have never really considered before.
Realistically, I’d believe that gaining actual functionality for modifying AST outside the macro’s invocation isn’t going to happen all that easily, but one could certainly at least pretend , what if it was? How would you use it to solve the problems super let wants to solve? Is this a lot easier to use? And if it does seem like a conceptually or syntactically easier to work with approach, one might be able to get as close as possible for usability without needing any actual general mechanism to truly modify AST outside of your code.
Which probably means coming full-circle (you still need some language syntax that macros actually expand to) but maybe not re-arriving exactly at super let.
One complication with super let is that there’s so many (subtle) existing properties & mechanisms for expressions to determine the (drop) scope of temporary values. If a macro receives some expression, it might want to control where temporary variables within that expressions drop - it might want to define its own values that are supposed to act like temporaries, and define where those drop - it might even want to specify how the macro-call (as an expression) itself interacts with the rules of temporary lifetime extension. Only some of these use-cases can easily be re-interpreted as a simple assignment to an identifier , others not so easily.
If you haven’t seen those already, there are some more recent discussions / design documents around super let that you can find in this Zulip thread.
- I have used Racket/Scheme before; I’m not looking for a beginner tutorial or anything ↩︎
Discussion in the ATmosphere