# RFC Mentoring Opportunity: Permit \`?\` in \`main()\`

**URL:** <https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600>\
**Category:** Uncategorized\
**Created:** [January 12, 2017, 2:51pm UTC](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600 "2017-01-12T14:51:35Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)\
**Post date:** [January 12, 2017, 9:51pm UTC](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600/21 "2017-01-12T21:51:35Z")

</div>

Yea.

I’m not sure exactly what Rust does after main (possibly just process exit 0?). One thing is that this provides a code organization for users to define an “after main” behavior, so they can throw errors to the top level and then `?` them there, calling into the `terminate` they’ve defined locally.

I’m not sure if this is something people writing applications want (I don’t know what the patterns are right now around what to do with errors once you’ve surfaced them to main), but I think we could meet those users’ needs as well as making code examples nicer.

---

<div class="post-metadata">

**Author:** ![m4b](https://avatars.discourse-cdn.com/v4/letter/m/df705f/32.png) [@m4b](https://internals.rust-lang.org/u/m4b)\
**Post date:** [January 12, 2017, 10:02pm UTC](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600/22 "2017-01-12T22:02:25Z")

</div>

After main is right here iirc: [https://github.com/rust-lang/rust/blob/master/src/libstd/rt.rs#L62](https://github.com/rust-lang/rust/blob/master/src/libstd/rt.rs#L62)

---

<div class="post-metadata">

**Author:** ![nikomatsakis](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nikomatsakis/32/5410_2.png) [@nikomatsakis](https://internals.rust-lang.org/u/nikomatsakis)\
**Post date:** [January 12, 2017, 10:09pm UTC](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600/23 "2017-01-12T22:09:19Z")

</div>

> [@cuviper](#):
>
> Someday impl Trait will land, then perhaps we can just write: fn main() -\> impl Terminate. Not completely explicit, but still clear to the type system and consistent with how other functions are written.

Yeah, I thought of this. I was afraid that it would fail because in practice one tends to be returning many possible errors that all have to be coerced to `Box<Error>` (via a `From` impl that is induced as part of the `?` sugar). But we might be able to make it work at some point.

---

<div class="post-metadata">

**Author:** ![nikomatsakis](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nikomatsakis/32/5410_2.png) [@nikomatsakis](https://internals.rust-lang.org/u/nikomatsakis)\
**Post date:** [January 12, 2017, 10:10pm UTC](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600/24 "2017-01-12T22:10:32Z")

</div>

Hmm, yes, maybe not as clear as I thought at first.

---

<div class="post-metadata">

**Author:** ![m4b](https://avatars.discourse-cdn.com/v4/letter/m/df705f/32.png) [@m4b](https://internals.rust-lang.org/u/m4b)\
**Post date:** [January 12, 2017, 10:25pm UTC](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600/25 "2017-01-12T22:25:27Z")

</div>

So for my tests I want them to mirror their production usage as closely as possible - this means using ?

Because I am forced by the compiler to use the `fn() -> ()` signature, I am then forced to unwrap (not how used in prod) or pattern match explicitly (extremely tedious, can make a mistake easier with assert, and rarely used in prod).

Not to mention I can’t even use ? in example rust code… Which seems to me the biggest way to encourage new users to not unwrap, when it isn’t present in every example for a result returning function…

Lastly, and this is less of an issue before ? came into being, converting code in functions that use ? for testing the implementation is a annoying to rewrite everything with unwrap.

---

<div class="post-metadata">

**Author:** ![Wyverald](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/wyverald/32/2060_2.png) [@Wyverald](https://internals.rust-lang.org/u/Wyverald)\
**Post date:** [January 12, 2017, 11:30pm UTC](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600/26 "2017-01-12T23:30:07Z")

</div>

Maybe I’m missing something, but my immediate reaction to this (given that we don’t have `catch`) is to just wrap the part that returns a `Result` in a separate function.

```rust
fn run() -> Result<(), Box<Error>> {
    some_stuff()?
}
fn main() {
    run().unwrap() // or deal with the Result in some other way
}

```

This doesn’t seem all that unergonomic to me, and avoids introducing some special case for `main()`. Or does everyone think this is too much?

---

<div class="post-metadata">

**Author:** ![leonardo](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/leonardo/32/1344_2.png) [@leonardo](https://internals.rust-lang.org/u/leonardo)\
**Post date:** [January 13, 2017, 12:33am UTC](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600/27 "2017-01-13T00:33:29Z")

</div>

> [@Wyverald](#):
>
> This doesn't seem all that unergonomic to me, and avoids introducing some special case for main(). Or does everyone think this is too much?

Yes, this is the "do nothing", and it should be considered. Keeping the language simpler has significant advantages in 15+ years.

---

<div class="post-metadata">

**Author:** ![jethrogb](https://avatars.discourse-cdn.com/v4/letter/j/43a26b/32.png) [@jethrogb](https://internals.rust-lang.org/u/jethrogb)\
**Post date:** [January 13, 2017, 12:53am UTC](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600/28 "2017-01-13T00:53:53Z")

</div>

Alternatively:

```rust
fn main() {
    (||{
        some_stuff()?
    })().unwrap()
}

```

But that might be too much magic syntax.

---

<div class="post-metadata">

**Author:** ![Screwtapello](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/screwtapello/32/1076_2.png) [@Screwtapello](https://internals.rust-lang.org/u/Screwtapello)\
**Post date:** [January 13, 2017, 7:52am UTC](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600/29 "2017-01-13T07:52:43Z")

</div>

When I first encountered Rust, I was annoyed that `main()` didn’t take command-line arguments and return an exit code, it seemed gratuitously limited. When I learned how serious Rust was about cross-platform support, it made a lot of sense: for example, Unix gives each process an array of command-line arguments, but Windows gives each process a single big string. Unix lets each process return a `u8` exit code, while Windows exit codes are `u32`. Embedded platforms often don’t have a concept of “arguments” or “exit codes” at all.

It seems dishonest (in a way the Rust stdlib has avoided dishonesty in the past) to give `main()` some particular signature when we know it may not be sensible or even possible on every platform, in the way that C and C++ have done. On the other hand, because of C, most platforms will have _some_ story for command-line arguments and exit codes, so maybe it’s not a terrible idea.

Perhaps we can have per-platform main wrappers in the stdlib. For example, `std::os::unix::main_wrapper()`:

```rust
fn<F> main_wrapper(f: F) -> ()
    where F: FnOnce(args: &[&str], environ: &[&str]) -> Result<u8, Error>

```

…and also `std::os::windows::main_wrapper()`:

```rust
fn<F> main_wrapper(f: F) -> ()
    where F: FnOnce(args: &str) -> Result<u32, Error>

```

…and maybe even `std::os::generic_main_wrapper()`:

```rust
fn<F> generic_main_wrapper(f: F) -> ()
    where F: FnOnce() -> Result<u8, Error>

```

…that does not promise your exit code will actually go anywhere, but it should be implementable everywhere.

…and then code examples could look like:

```rust
use std::os::unix;

fn main() {
    unix::main_wrapper(|_. _| {
        "sasquatch".parse::<u32>();
    })
}

```

That’s a bit of extra boiler-plate, but hopefully not too difficult to explain or hand-wave in introductory texts… especially if the generic `main_wrapper()` is in the prelude.

---

<div class="post-metadata">

**Author:** ![repax](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/repax/32/1342_2.png) [@repax](https://internals.rust-lang.org/u/repax)\
**Post date:** [January 13, 2017, 1:04pm UTC](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600/30 "2017-01-13T13:04:31Z")

</div>

Here’s an alternative alias to `Throws<T>`:

```rust
fn main() -> Fallible<()> {
    try_something()?
}

```

or even:

```rust
fn main() -> Fallible {
    try_something()?
}

```

where `T: ()`

I believe that the meaning of `Fallible` should be clear as well as _searchable_ for novices.

An alternative to `catch` can be `recover`.

---

<div class="post-metadata">

**Author:** ![nikomatsakis](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nikomatsakis/32/5410_2.png) [@nikomatsakis](https://internals.rust-lang.org/u/nikomatsakis)\
**Post date:** [January 13, 2017, 3:22pm UTC](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600/31 "2017-01-13T15:22:56Z")

</div>

Yes, I like the name `Fallible`. I hadn’t thought of the `()` default. That’s nice, actually. =)

---

<div class="post-metadata">

**Author:** ![nikomatsakis](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nikomatsakis/32/5410_2.png) [@nikomatsakis](https://internals.rust-lang.org/u/nikomatsakis)\
**Post date:** [January 13, 2017, 3:27pm UTC](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600/32 "2017-01-13T15:27:50Z")

</div>

> [@Screwtapello](#):
>
> It seems dishonest (in a way the Rust stdlib has avoided dishonesty in the past) to give main() some particular signature when we know it may not be sensible or even possible on every platform, in the way that C and C++ have done.

There is nothing dishonest going on here. Having a `main()` that returns a `Terminate` value is portable to all platforms. All platforms support `unwrap()`, and `main()` is already invoked from a wrapper; it just happens that the wrapper expects `main()` return `()` right now.

---

<div class="post-metadata">

**Author:** ![tupshin](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tupshin/32/2573_2.png) [@tupshin](https://internals.rust-lang.org/u/tupshin)\
**Post date:** [January 13, 2017, 4:29pm UTC](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600/33 "2017-01-13T16:29:02Z")

</div>

FWIW, I brought up this general idea in [Modeling \<strike\>exceptions\</strike\> thread panics with!](https://internals.rust-lang.org/t/modeling-strike-exceptions-strike-thread-panics-with/4572/8)

---

<div class="post-metadata">

**Author:** ![tupshin](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tupshin/32/2573_2.png) [@tupshin](https://internals.rust-lang.org/u/tupshin)\
**Post date:** [January 13, 2017, 4:41pm UTC](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600/34 "2017-01-13T16:41:06Z")

</div>

[https://docs.rs/error-chain/0.7.2/error\_chain/macro.quick\_main.html](https://docs.rs/error-chain/0.7.2/error_chain/macro.quick_main.html) makes that very easy, but both the manual and the macro versions require a new user to be aware of the issue before they start implementing main(). That initial cognitive overhead is the main thing we need to address.

---

<div class="post-metadata">

**Author:** ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)\
**Post date:** [January 13, 2017, 9:24pm UTC](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600/35 "2017-01-13T21:24:47Z")

</div>

I didn’t know this, but I just checked and discovered that `main` can be called like any other function. It seems to me that you should never do this. But since it _is_ just a function, I’m a little concerned with a proposal that lets its return type be omitted unlike every other function.

---

<div class="post-metadata">

**Author:** ![cuviper](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cuviper/32/1897_2.png) [@cuviper](https://internals.rust-lang.org/u/cuviper)\
**Post date:** [January 13, 2017, 9:44pm UTC](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600/36 "2017-01-13T21:44:20Z")

</div>

We could call it from above like some parameterized `main: F where F: FnOnce() -> T, T: Terminate`, and both `()` and `Fallible` implement `Terminate`. You’d still have to explicitly write which return type you want.

---

<div class="post-metadata">

**Author:** ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)\
**Post date:** [January 13, 2017, 9:59pm UTC](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600/37 "2017-01-13T21:59:43Z")

</div>

I don’t think you understood, this is a valid Rust program:

```rust
fn main() { }

fn foo() { main() }

```

If we allow users to return something other than `()` without providing a return type, as some of these proposals would have us, that could become a type error without the signature of main explicitly changing.

---

<div class="post-metadata">

**Author:** ![cuviper](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cuviper/32/1897_2.png) [@cuviper](https://internals.rust-lang.org/u/cuviper)\
**Post date:** [January 13, 2017, 10:03pm UTC](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600/38 "2017-01-13T22:03:11Z")

</div>

I’m suggesting we still require an explicit signature, just with more possibilities. So `fn main() {}` would still work as today, and `fn main() -> Fallible {}` would be used when you want to use the `?` operator. In the latter case, `foo()` has to update as well.

---

<div class="post-metadata">

**Author:** ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)\
**Post date:** [January 13, 2017, 10:04pm UTC](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600/39 "2017-01-13T22:04:04Z")

</div>

Sure. There are a lot of proposals being thrown around, and I’m raising a concern about some of the proposals.

---

<div class="post-metadata">

**Author:** ![Ixrec](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ixrec/32/6754_2.png) [@Ixrec](https://internals.rust-lang.org/u/Ixrec)\
**Post date:** [January 14, 2017, 12:03am UTC](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600/40 "2017-01-14T00:03:31Z")

</div>

An important point I didn't see anyone mention yet is what should actually happen at runtime when a program "returns an error from main" as opposed to panicking or returning ().

I can think of two options:

1. Do what panicking in main does today.
2. Print the error value we got, then exit normally.

I am strongly in favor of not doing #1, because it would put a giant asterisk on the claim that "? and Result are better than .unwrap() and panics" if ? does the same thing as panic in the simplest possible case. Plus, as useful as backtraces are in the general case, a real error value designed by other humans is likely to be far more useful to the person who needs to debug whatever just happened.

* * *

As for the details of how this should work, if we go back to how Niko framed the problem...

> I see two basic approaches to solving it:

> 1. Allow main() to return more kinds of things (in particular, results).
> 2. Change the ? means when it is used in main().

As described in Niko's original post, these seem not so much different approaches as extreme ends of a spectrum, and I believe the optimal solution is probably somewhere in the middle.

The "Fallible" suggestion made above, at least the way I interpreted it, is exactly what I'd want. The main() function does change signature, but only in the simplest possible way (there is exactly one new signature, only one type in that signature, no sigils besides "-\>", and no invisible/magic bits). The ? semantics also change slightly since it has to convert to this "Fallible" type instead, but conceptually it's still doing the same thing. The possibility that "Fallible" is just one concrete type with no parameters or bounds or `impl` keyword seems like a really nice touch, since this is supposed to help novices.

* * *

Of course, all of that assumes it's really feasible for all "sane" error types that one might try to use ? on in main() to be implicitly converted to a single Fallible type that can then be used to print all the information provided by that error. I think it is, because "implements the Error trait" seems like a good definition of "sane error type", and the conversion to Fallible could just be calling description() and cause() repeatedly to make a big String. Maybe the Fallible type is nothing more than a String with a special print method?

[Previous page](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600.md?page=1)

[Next page](https://internals.rust-lang.org/t/rfc-mentoring-opportunity-permit-in-main/4600.md?page=3)
