Anonymous macros
It could be possible to have this:
macro @foo($val, #foo)
{
#foo($val);
}
fn void test()
{
int x = 3;
@foo(4, macro ($i) => io::printn($i + x));
}
Other uses:
fn void test()
{
int y = foo();
int x = macro int() {
if (y > 0) return 4;
return y * 2;
}();
}
An interesting application: defining an adhoc combined scope with a single layer of nesting
// nested macro defined in-line
macro(db_type* db; @body)
{
@pool()
{
// example user defined macro
@with_transaction(db)
{
@body();
};
};
}(&db)
{
... // Singly nested outer scope here
};
This seems like it might be a bit like the {||} expression blocks, a very niche feature
The reason why the anonymous macros might be okay, is because we already have lambdas. And these are the macro counterpart.
Would these anonymous macros also be assignable to a compile time variable?
A use-case being that you have quite a long function and you need to do the same action ~5 times, then creating a mini-macro to do that could be nice, and keeping the implementation close to that only place that it's used could be a plus.
No idea how useful that is though.
Semantics are unclear @BWindey... maybe
I'm inclined to drop this feature as it is fairly big.
this could be useful in some incredibly niche cases for creating a custom switch construct. for example with my tagged union library:
tu::@match(my_tagged_union,
FOO, macro (val) {
io::printfn("was FOO with val %s", val);
},
BAR, macro () => return NOT_FOUND?,
default, macro () => unreachable("unexpected %s", tu:tag(my_tagged_union));
);
but that's likely to be eventually brought into the language as a feature so maybe not the best usecase.
there was also some other usecase I had for it a few weeks ago when prototyping a http server framework using custom attributes with @tag for routing, but I don't remember it anymore unfortunately.
another use for anonymous macros is to define a constant using some level of conditions without needing to create a separate macro for it:
const Foo[] FOO = macro ()
{
Foo[*] $res = {};
var $foos = @get_foos();
$foreach $foo : $foos:
$if @some_cond($foo):
$res = $res +++ {$foo};
$endif
$endforeach
return $res;
}();
and also in a less good way, to define a macro that can be called via an uppercase name:
const INC = macro (x) => x + 1;
int a = INC(1);
but this is just another hack for my tagged unions library so probably not very compelling.
I'm not too worried if this doesn't get added, I'm just writing every time I encounter a situation where these would be useful