Object initializer as function only argument

I'm curious whether this has been suggested before. The suggestion is, one or more colon-separated pair within a call argument makes it an object initializer. For example, we've this function:

struct Options {
    x: f64,
    y: Option<f64>,
}

fn takes_1_arg(options: Options) {
}

Then, instead of:

takes_1_arg(Options {
    x: 56,
    y: None,
});

One could write:

takes_1_arg(
    x: 56,
);

If there were ambiguity the punctuator could be := instead, but I guess : is available anyway.

What if there's multiple parameters?

#[derive(Default)]
struct Options {
    x: f64,
    y: Option<f64>,
}

fn takes_1_arg(options: Options) { ... }

...

use takes::Options;

takes_1_arg(Options {
    x: 56,
    ..default()
})

This is about the closest you can get currently without macros. The closest I would probably ever want that still explicitly involved a struct would be

takes_1_arg(_ {
    x: 56,
    ..default()
})

With function defaults I would expect to be able to do this without ever defining an Options struct at all, and be able to write has_default_args(x = 56, ..default()) or even has_default_args(x=56). But these latter two forms have a whole lot of other implications.

1 Like

With field level defaults, it could even be

takes_1_arg(_ { x: 56, .. })
4 Likes

My suggestion would be for a single-parameter function.

The _ {...} syntax isn't supported: play.rust-lang.org. Is it a proposal?

Yeah, there's a few schools of thought for named arguments:

  1. Use structs / builders, but make them easier to use. That's what _ was - it's a proposal to apply type inference to type names when constructing them. There are other proposals in this realm too, like the .. syntax proposal mentioned by CAD97.

  2. Allow names to be given to parameters. There's a lot of options here about ordering, public vs private names, overloading, interactions with the type system, etc.

  3. Adding anonymous structs. Basically we have structs with fields (named & labeled/fields) and tuple structs (named & ordered), and tuples (unnamed & ordered) right now. If we added a unnamed type with labeled values instead of ordered values, then we could use those in the type signatures of methods. This has it's own bag of worms too.

Almost all of these proposals have to deal type ascription on nightly, ha ha. And you could probably get several distinct proposals out of #2

4 Likes

One question: why? Except for being l'art pour l'art syntactic sugar, I don't see how this would accomplish anything that is not possible with today's Rust. And we definitely don't need more syntactic sugar that doesn't solve real problems. "It could work like this" is not a justification.

The reason is verbosity. But instead of taking an object as single parameter, we could apply the way 2) that @samsieber described, which instead allows to pass parameters by name... That could work well.

Typing a single identifier doesn't count as verbosity by any reasonable definition.

2 Likes

Python and Dart (e.g., Flutter) support the same, it's a common feature.

@Klaider The answer to this question is huge and complicated. Most of the context is summarized in this other thread, linked earlier. There is some agreement and some disagreement about which facets of this feature should ultimately be included, and there are a number of technical limitations that make it more than just picking some syntax. It's unfortunate, but I don't think you're going to get a satisfactory answer that isn't gigantic.

2 Likes

At the request of the OP, we're closing the thread