Option shorthand pre-pre-rfc

Recently, I made a pre-rfc about potential optional fields in methods. The general feedback was that the syntax should be more generic, and be applicable to more places.

This is one idea that stemmed from it, which I think would be quite useful in a variety of cases. There's another one that I'm still debating whether to do, as it was suggested lots to split it into two parts (it's sugar for Option)


Into syntactic sugar

You can use the postfix ! operator to automatically .into() an expression.

Uses

  • (Directly from the original pre-RFC) Configuration structs, or structs with many Options. When using these with struct literals, doing foo: 3! is a lot more readable imo and less verbose than foo: Some(3)
  • Functions that take in Into as an argument, to accept more types. This means, in the function, you can use the input parameter with !. I'm also considering whether we should have this operator in patterns, so a function could take foo!: Into<Bar>, say, and foo would be of type Bar
  • Functions that don't take Into as an argument, to convert your types without specifying .into() everywhere

Rationale

  • Signifies intent clearly
  • Does not reduce readability

Won't this get confused with macros?

This was one of my concerns when I thought of this idea; however, macros can only be called with brackets afterwards. In most cases where you'd use this, you wouldn't be specifying brackets afterwards, and as such, that will attempt to invoke a macro instead.

Of course, if there's a more suitable operator to use, please say.

1 Like

This has already been proposed and rejected.

3 Likes

That's a shame, didn't see that. Thanks.

You can't have Into<Fn> or Into<fn> without type ascription, so foo!() and foo!{} can never be Into. But, there's always an edge case, like macro_rules! foo {}.

In any case tho, Into has always been clunky to use, and that's probably not gonna change anytime soon. Personally we do use plenty of into except for Some/etc, e.g. in tests we have this:

    let tree = Value::M(vec![
        ("projects".into(), Value::M(vec![
            ("385e734a52e13949a7a5c71827f6de920dbfea43".into(), Value::M(vec![
                ("https://soniex2.autistic.space/git-repos/ganarchy.git".into(), Value::M(vec![
                    ("HEAD".into(), Value::M(vec![
                        ("active".into(), Value::B(true)),
                    ].into_iter().collect())),
                ].into_iter().collect())),
            ].into_iter().collect())),
        ].into_iter().collect())),
    ].into_iter().collect());

I'll note that I'm not certain that the feedback was that it necessarily should be more generic. At least in my case, I'm usually asking questions in a Socratic sense: the answer is probably "no, that's a bad idea" for most of those follow-ups, but exploring why it's a bad idea in those other situations is helpful as a way to see whether those same reasons apply to the specific proposal.

4 Likes