Nameless structs

Today I thought it would be kind of nice to be able to do something like this:

let logger_configs = (
    trace: LoggerConfig {
        ...
    },
    warn: LoggerConfig {
        ...
    },
    ...
); // basically a map of compile time variable names to LoggerConfig values

start_logger(logger_configs.trace); // usable like this
start_logger(logger_configs.warn);
...

The type would be (LoggerConfig, LoggerConfig, ...).

This would be useful for structuring code and grouping variables inside of functions, without having to declare a whole new struct explicitly. Nameless Structs would only be used once, the type could be seen as unique to that variable.

Obviously such structures also could not leave the current scope directly, as they are unnamed and can not be used by any kind of type signature. There are also no references to unnamed types. They are basically just a useful syntax feature.

What do you think of this idea? How do you think would this interact with the rest of the language?

This can already be accomplished today by using e.g. a HashMap or BTreeMap. As an added bonus, since maps are owned values, you can pass them to any scope you like.

Yes, but that would require me to use a runtime datastructure which stores the keys. The syntax would have a lot of redundant information and it would be harder to optimize.
Even when using this macro below, the underlying runtime would still require actual runtime values as keys.

macro_rules! map(
    { $($key:expr => $value:expr),+ } => {
        {
            let mut m = ::std::collections::HashMap::new();
            $(
                m.insert($key, $value);
            )+
            m
        }
     };
);

fn main() {
    let names = map!{ 1 => "one", 2 => "two" };
    println!("{} -> {:?}", 1, names.get(&1));
    println!("{} -> {:?}", 10, names.get(&10));
}

I do not want to store this kind of map anywhere, but only want to use it to make my code more readable and usable. I think there are a lot of use cases where this would come in handy.
For comparison:

let logger_configs = map!(
    "trace" => LoggerConfig {
        ...
    },
    "warn" => LoggerConfig {
        ...
    },
    ...
);
start_logger(logger_configs.get("trace")); // not as nice and slower
start_logger(logger_configs.get("warn"));

A quick search on crates.io turned up this:

But I can't vouch for how well it works.

3 Likes

Ah, very nice :slight_smile:

Although the anon! may suffice for the most simple cases, @rodrimati1992 's ::structural crate offers genericity over these anonymous structs.

Finally, ::frunk is another crate that seems to offer features related to anonymous structs.

3 Likes

Thank you for sharing! They go right to my bookmarks!