Snap is limited in the way that mettaprogramming functions currently, the only way to do most metaprogramming is using join and split by blocks. However those have many issues in themselves
The best way to do mettaprogramming right now is to split a script using split by, replace the text area you need. Then join them back together
This isn’t very easy to understand and feels more like a last minute addition to ensure mettaprogramming is possible at all
This also isn’t very good because of the way snap calls variables
A variable isn’t represented as itself, it’s represented by only itself in scope
If you join a variable then try to call it it doesn’t work, this means it’s impossible to call variables programatically or use variables as a part of mettaprogramming functions
All fo these could be fixed with a “call () when ringed”
This block bypasses a ring and calls the value inside inserting it into the ring where it would have been
This fixes almost every issue with mettaprogramming If this is the only block present in a ring or it has no inputs then it will report itself to allow it to be first class
Snaps slogan is “everything first class” and while this would sometimes be an exception to this rule, it’s a necessary one as it is actively a detriment to not have this
This unfortunately isn’t possible to program as a custom block either because of the way first class data works
Not sure what you mean by that. You can bind rings to a context using the block:
What you want reminds me of Scheme's quasiquotes (which I also just learned about today, so correct me if I am getting this wrong), which can be somewhat implemented into Snap as well, which with your example would look like this:
Yes. Jens just wanted to make something work; I am supposed to implement hygienic macros using this low-level tool. One more thing I haven't gotten around to, although this is one I'd actually enjoy!
So I don't think the right thing is to layer a kludge for niladic functions and/or variables on top of the existing kludge. It's to build the right interface in the first place.
Variable shadowing, in this example, combined with the literal objects, is a quite typical solution to emulate hygienic macros. But it's irrelevant to this case, i.e., automatic or runtime-created procedures. The built-in scoping rules prevent incidental variable capture. But we want to actually catch some variables during the "define" phase in a consistent manner.
Your typical test case may now look
.
Update: Ok, this can be simplified to
is a variable marker replaced by value in the generated block
.
It can be further simplified to process every variable referenced from the caller's scope (local or global)