Converting `@main` into a macro

I don't have a super concrete idea here, but I'm wondering if it would be possible to change @main into a macro that expands into an @_cdecl("main") thunk.

I'm interested in expanding @main to be able to be apply-able to a top-level function instead of just a type, e.g.:

@main
func goGoGadget() async throws { }

It also opens the door for platform to provide a custom implementation of @main that maybe sets up a custom Main and/or Global executor etc... This is something I'd love in the embedded space and maybe swift-no would be interested here too.

For this use case maybe swiftc could inject a default platform startup module with an implementation of @main so normal swift users would never have to think about this change.

cc @lukasa @al45tair @kubamracek @Erik_Eckstein etc...

1 Like

I would definitely like to see such a thing, specially, the ability to add @main to a top level function.
Since the current approach can sometimes be noisy, for example if I just want a single, main function. (And it also reminds me of OOP and Java, which isn’t necessarily a bad thing… or is it? :man_shrugging:)
But it does also have its benefits such as having a protocol provide the actual main implement that you just conform to (but obviously we aren’t asking to remove this, so we would get the best of both worlds, by supporting both)
But also all the benefits you said about having the platform be able to supply a custom @main implementation also sound nice👍

There may be utility here in test targets as well if we could effectively "disable" the main-ness of the attribute (solving some problems around test targets containing more than one main function.)

2 Likes

It's worth looking at the current pitch for custom executors, since right now that actually uses a compiler flag pointing at a factory type to set the executors, which is a reasonably clean way to do things (the compiler's synthesised main function passes that type to the runtime, which uses a couple of properties to fetch the desired executors).

I think that would be an improvement, personally. It'll require the LSG to buy in to it, but the fact is that

@main
struct Main {
  public static func main() {
    ...
  }
}

is a very verbose way to write things. I think @Ben_Cohen has commented previously that we seem to have ended up with even more ceremony than Java, somehow, so my guess is that he'd be supportive.

1 Like