I could not find any plans to introduce a map! macro, similar to vec!. Perhaps it's been pitched under a different name. I would like to get input on this, as I think the usefulness is perhaps obvious; I was a a bit surprised to see a lack of optics on this already.
I think this is just not as often needed as vec![], and with const generics we have From impls that are just as short, and don't require any macro: HashMap::from([("key", "value"), ("k2", "v2")]);
I'm going to contest the idea it's not needed as often. Maps and Vecs are the standard of common data structures. Think of the relative pervasiveness of {} and [] in python.
The same syntax you mention is just as short and exists for Vec (Vec::from(...)) but yet we have the vec! macro. I agree it is not as popular as Vec, but I think it deserves the macro. Behind Vec, HashMap would be the 2nd most important and used data structure.
I know this could lead to a slippery slope of "Now we need a btreemap! and a heap!", but for the time being, I think the prevalence of HashMap would justify such a macro into prelude/std.
Talk me out of it. But I still like the idea of this as a macro in the prelude.
Except in python, everything is a map (dict). A majority of {} uses in python shouldn't be hashmap!{} in rust, but rather Struct {}.
Two reasons for vec! to exist that don't apply to hashmap!:
We have array literals, and vec is the growable array type, so should have equivalent syntax.
vec! existed before const generics did, so Vec::from([T; N]) was limited to 32 elements.
The biggest argument is the former imho: array literals have a known syntax, but we don't have an existing syntax for maps. As such, there's multiple possible syntaxes for a map! macro: { key: val } struct-like, { key => val } match-like, [ (key, val) ] collect-like, etc.
I think I end up using BTreeMap more myself. In my experience, I have vectors of static data in literal code way more than maps. And the times I do, the from family of functions work fine (though vectors of tuples can be better if it can keep the data in a few cache lines instead of spread in a web across the heap). How big of a "map literal" is being considered here?
The syntax is also up for debate. Python-like :, PHP-like =>, or something else completely?
Also, it's worth noting that a lot of people are moving to support the opinion that you should prefer an ordered collection over an unordered one until performance metrics indicate that the performance benefit of (effectively) nondeterministic iteration order outweighs the downsides of unpredictable ordering.
Having hashmap! but not indexmap! or btreemap! hinders this.
Ultimately what I find myself falling back to as the appropriate macro is instead based on collect/FromIterator.
... but also with how little that macro does, it's not really worth having the macro over just using from or from_iter instead, which have the benefit of the inbuilt type hint.
(FromIterator is added to the prelude by edition 2021.)
However what you said last I don't agree with, particularly "how little that macro does, it's not really worth having the macro". A majority of people probably don't want to touch Rust macros with a 50 foot pole. Rust and Rust Macros are literally two different languages.
To be clear, what I'm suggesting isn't for people to rewrite the macro, but just to call from or from_iter instead. It's literally the difference between
let _: IndexMap = collect![("a", "b"), ("c", "d")];
// the type hint is required
and
let _ = IndexMap::from([("a", "b"), ("c", "d")]);
// or maybe it requires
let _ = IndexMap::from_iter([("a", "b"), ("c", "d")]);
It would be nice to have a const map though. You can make your own without too much effort, I guess (if performance or ergonomics don't matter too much)
There is an example of this in the examples section of hashmap, but perhaps it should be part of the first example. Similarly in the book, hash maps are only constructed via mut/insert.
And honestly other than repeated clones vec! could just be Vec::from([a, b, c]) most of the time. I can certainly understand where someone could get the ideas that
to construct a Vec: use the magic/convenient vec! macro
to construct a Map: use mut and a bunch of verbose inserts (why is it this inconvenient)