Edit: Sorry if this is a bit rambly; it’s hot and I only just woke up. Brain might not be in completely working order just yet.
I think it would be a mistake to have
? behave differently in
main. All that does is trade the possibility that some copy+paste coding will work versus now having to explain that the behaviour of
? is context-dependent, and having the behaviour of
? be context-dependent.
If this is principally based around helping new users and people who are copy+pasting code from examples without understanding what’s going on, and then being confused when it doesn’t work, then I don’t think any of the proposals actually address that.
First of all, let’s say we allow
main to have a different signature that permits errors to be returned. Given a user who is blindly copy+pasting code, or trying to write error handling without understanding how error handling works, how do they know they need to change the signature of
main? This is almost the same as just using a
try_main function and having
main call that: it only works if you know to do it.
If we give
main special, magical properties (which includes giving
? magical properties inside
main), we now have a new problem: the moment the user tries to move code that works in
main to some other function, it’ll stop working. At that point, we’re back to square one again. Plus, we now need to explain this magic behaviour, and users need to remember it.
Any solution to this needs to be global and consistent across all functions: it cannot just affect
main. It also has to be something that requires no knowledge or action from new users.
Given that, I can only think of one solution to the novice user problem (that doesn’t involve completely changing how error handling works): add a diagnostic that specifically detects “tried to use
? in a function without a
Result return type” and tells the user what to do. As in, it flat-out tells the user the return type they should use, as accurately as possible. The user should be able to copy+paste from the error message into their code. This should work everywhere, no matter the function, not just
At that point, having
main allow for
Result<(), _> as a return type is a logical next step, so that users can act on what the diagnostic tells them. I also think it should be
Result: even if the compiler internally uses some trait to wire this up, we should probably only ever mention
Result to new users, or it might confuse matters (“so I can return
main instead of
Result, why can’t I do that for other functions?”).
That said, I think the important part is the diagnostic. Changing the return status of
main is a nice little improvement, but it only improves one function, and only helps in the specific case of trying to blindly copy error handling code into
main as opposed to any other function the user may be writing.