# Alternate main() signatures

**URL:** <https://internals.rust-lang.org/t/alternate-main-signatures/1687>\
**Category:** ideas (deprecated)\
**Created:** [March 6, 2015, 1:01am UTC](https://internals.rust-lang.org/t/alternate-main-signatures/1687 "2015-03-06T01:01:07Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![vadimcn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/vadimcn/32/2789_2.png) [@vadimcn](https://internals.rust-lang.org/u/vadimcn)\
**Post date:** [March 6, 2015, 1:01am UTC](https://internals.rust-lang.org/t/alternate-main-signatures/1687/1 "2015-03-06T01:01:07Z")

</div>

As a follow-up to [this](http://www.reddit.com/r/rust/comments/2y2enz/new_microcontroller_that_aims_to_support_rust_as/cp5l611) Reddit thread (but I’ve seen similar complaints several times in other places), how do people feel about supporting alternate signatures for `main()`? I realize, this is only useful for short examples and such, but first impressions _are_ important.

So, what if we allowed using any of the following?: `fn main()``fn main() -> Result<(),u32>``fn main() -> MainResult` // same as above but with a type alias

maybe also these: `fn main(args: env::Args) -> MainResult``fn main(args: env::ArgsOs) -> MainResult`

As a less invasive middle-ground, I suppose we could also create an attribute macro that wraps body of the function in a closure as suggested in [this comment](http://www.reddit.com/r/rust/comments/2y2enz/new_microcontroller_that_aims_to_support_rust_as/cp5nmr2): `#[unwrap_result] fn main()`

---

<div class="post-metadata">

**Author:** ![hauleth](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/hauleth/32/1322_2.png) [@hauleth](https://internals.rust-lang.org/u/hauleth)\
**Post date:** [March 6, 2015, 3:33am UTC](https://internals.rust-lang.org/t/alternate-main-signatures/1687/2 "2015-03-06T03:33:27Z")

</div>

👎

I rather would see more usage of [`and_then`](http://doc.rust-lang.org/std/result/enum.Result.html#method.and_then) and [`map`](http://doc.rust-lang.org/std/result/enum.Result.html#method.map) instead of this.

What I want is sane and stable way to set exit code status.

---

<div class="post-metadata">

**Author:** ![sinistersnare](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/sinistersnare/32/18_2.png) [@sinistersnare](https://internals.rust-lang.org/u/sinistersnare)\
**Post date:** [March 6, 2015, 7:04am UTC](https://internals.rust-lang.org/t/alternate-main-signatures/1687/3 "2015-03-06T07:04:03Z")

</div>

I think having one alternate of the return type `fn main() -> u32` is enough.

Isnt there no life after main, therefore we cant really use Rust types as return stuff? Or am I completly missing the point of life after main?

I like the args input though.

---

<div class="post-metadata">

**Author:** ![vadimcn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/vadimcn/32/2789_2.png) [@vadimcn](https://internals.rust-lang.org/u/vadimcn)\
**Post date:** [March 6, 2015, 10:22pm UTC](https://internals.rust-lang.org/t/alternate-main-signatures/1687/4 "2015-03-06T22:22:00Z")

</div>

> I think having one alternate of the return type fn main() -\> u32 is enough.

The idea was to enable usage of `try!()` in `main()`.

> Isnt there no life after main, therefore we cant really use Rust types as return stuff? Or am I completly missing the point of life after main?

It just means that Rust does not have static constructors/destructors. There absolutely is life between the actual process entry point and `main()`.

---

<div class="post-metadata">

**Author:** ![sinistersnare](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/sinistersnare/32/18_2.png) [@sinistersnare](https://internals.rust-lang.org/u/sinistersnare)\
**Post date:** [March 7, 2015, 7:29am UTC](https://internals.rust-lang.org/t/alternate-main-signatures/1687/5 "2015-03-07T07:29:34Z")

</div>

Youre correct on all counts, but it still feels strange. I feel like there is a better solution, this just seems like a bandaid (in regards to returning result just to use try!)

---

<div class="post-metadata">

**Author:** ![huon](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/huon/32/3698_2.png) [@huon](https://internals.rust-lang.org/u/huon)\
**Post date:** [March 7, 2015, 12:13pm UTC](https://internals.rust-lang.org/t/alternate-main-signatures/1687/6 "2015-03-07T12:13:52Z")

</div>

> [@vadimcn](#):
>
> As a less invasive middle-ground, I suppose we could also create an attribute macro that wraps body of the function in a closure as suggested in this comment:#[unwrap\_result] fn main()

FWIW, this can be simulated via an immediately invoked closure:

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

```

One doesn't need to write out any explicit types (as compared to a separate function), but it does look quite strange.

---

<div class="post-metadata">

**Author:** ![vadimcn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/vadimcn/32/2789_2.png) [@vadimcn](https://internals.rust-lang.org/u/vadimcn)\
**Post date:** [March 7, 2015, 8:36pm UTC](https://internals.rust-lang.org/t/alternate-main-signatures/1687/7 "2015-03-07T20:36:53Z")

</div>

> [@huon](#):
>
> FWIW, this can be simulated via an immediately invoked closure:

Yes, that's what I meant. However, we'd have to explain to developers what this magic macro does, and, IMO, it would look very much like a band-aid.

Hey, here's another idea: Can we restructure `try!` and `FromError` such that the return type no longer has to be specifically a `Result`, and impl `FromError` for `()`? Something like this:

```
macro_rules! try {
    ($expr:expr) => (match $expr {
        $crate::result::Result::Ok(val) => val,
        $crate::result::Result::Err(err) => {
            //was: return $crate::result::Result::Err(
            // $crate::error::FromError::from_error(err))
            return $crate::error::FromError::from_error(err)
        }
    })
}

// back-compat with existing code
impl<T,E,F> FromError<F> for Result<T,E> where E:FromError<F> {
    fn from_error(err:F) -> Self {
        std::result::Result::Err(FromError::from_error(err))
    }
}

impl<E> FromError<E> for () where E:Error {
    fn from_error(err: E) -> () {
        panic!(err.description().to_string());
    }
}

```

Unfortunately, right now '`impl<T,E,F> FromError<F> for Result<T,E>`...' above conflicts with '`impl<E> FromError<E> for E`' from std. I wonder if negative trait impls would help here? I.e. could we re-define the latter as '`impl<E> FromError<E> for E where E:!FromError<E>`' ?

---

<div class="post-metadata">

**Author:** ![NawfelBengherbia](https://avatars.discourse-cdn.com/v4/letter/n/c57346/32.png) [@NawfelBengherbia](https://internals.rust-lang.org/u/NawfelBengherbia)\
**Post date:** [March 7, 2015, 11:03pm UTC](https://internals.rust-lang.org/t/alternate-main-signatures/1687/8 "2015-03-07T23:03:56Z")

</div>

```
(|| {
    ...
}())

```

No dogballs please!! 😛

---

<div class="post-metadata">

**Author:** ![eddyb](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/eddyb/32/8411_2.png) [@eddyb](https://internals.rust-lang.org/u/eddyb)\
**Post date:** [March 8, 2015, 12:37am UTC](https://internals.rust-lang.org/t/alternate-main-signatures/1687/9 "2015-03-08T00:37:41Z")

</div>

You would want to use a different trait than `FromError` for that conversion, although the current name isn’t very clear about what it’s producing (it’s technically `ErrorFromError` or `ErrorToError` or `ErrorConvert`), and so it’s hard to find a good name that’s not `FromError`. That said, `try!` sometimes failing doesn’t seem like great API design - the function author may have merely forgotten to specify a `Result` return type and instead of a nice type error, the function could panic in production.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [March 25, 2019, 8:24am UTC](https://internals.rust-lang.org/t/alternate-main-signatures/1687/10 "2019-03-25T08:24:02Z")

</div>

Closed on March 25, 2019, 8:24am UTC

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
