c3c icon indicating copy to clipboard operation
c3c copied to clipboard

Anonymous macros

Open lerno opened this issue 8 months ago • 7 comments

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;
     }();
}

lerno avatar Mar 28 '25 10:03 lerno

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
};

joshring avatar Mar 29 '25 12:03 joshring

This seems like it might be a bit like the {||} expression blocks, a very niche feature

joshring avatar Mar 29 '25 16:03 joshring

The reason why the anonymous macros might be okay, is because we already have lambdas. And these are the macro counterpart.

lerno avatar Mar 29 '25 22:03 lerno

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.

BWindey avatar Jun 14 '25 17:06 BWindey

Semantics are unclear @BWindey... maybe

lerno avatar Jun 14 '25 22:06 lerno

I'm inclined to drop this feature as it is fairly big.

lerno avatar Jun 21 '25 22:06 lerno

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.

Book-reader avatar Jun 23 '25 22:06 Book-reader

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

Book-reader avatar Jul 04 '25 08:07 Book-reader