Skip to content

proposal: rename std.AutoHashMap to std.HashMap #22155

@robbielyman

Description

@robbielyman

This proposal stems from the meat of a blog post I wrote while reflecting on what I learned from Rust and from Zig doing Advent of Code problems. Everything relevant to the Zig project is reproduced below, but I wanted to flag the duplication.

One thing I love about Zig is that it has great default implementations of all of the standard container types.
They're just named poorly. One instance of poor name choices is already being corrected for Zig 0.14. I discuss that at the end of the blog post. Here I'd like to argue for another change towards better defaults.

In Zig, here is the signature of std.HashMap:

pub fn HashMap(comptime K: type, 
	comptime V: type, 
	comptime Context: type, 
	comptime max_load_percentage: u64,
) type { ... }

The Context type is responsible for actually hashing keys of type K and determining when two keys are the same.
You can write a Context type yourself without crying too much; for Advent of Code 2023, I did—for the simple and sad reason that this type has the best name, while the type that actually deserves the best name does not.

As of Zig 0.13, I will confidently assert that the type you want maybe 90% of the time you reach for a std.HashMap
is actually one of std.AutoHashMapUnmanaged(K, V), std.AutoArrayHashMapUnmanaged(K, V),
or in the particular case of string keys, std.StringHashMapUnmanaged or std.StringArrayHashMapUnmanaged.

The Unmanaged issue, as I alluded to earlier, is being fixed already. If the issue of the Auto prefix is not already being changed, I'd like to propose that it should be.

Here Auto means "use a best guess at a default hashing function". (Array means store keys and values contiguously so that iterating over them is fast and ergonomic. I read somewhere that even iterating once is enough to justify reaching for this type.) It's great that Zig allows you to swap out the default (or even std-provided) methods for hashing with your own. The "ground" types HashMapUnmanaged and ArrayHashMapUnmanaged are well thought through in terms of API design. My issue with them is that for a beginner, they shadow the correct type to reach for first.

I propose that current std.HashMap should become std.HashMapWithContext and that std.AutoHashMap should become std.HashMap. I'm happy to defer to the core team's expertise on how to manage the transition period.

Now, to be sure, the core of this proposal could be summarily dismissed as a "skill issue". On the one hand, reading documentation or the std library code quickly reveals the existence of the Auto... types. And on the other, learning to write reasonably useful hashing functions is a skill that will serve a budding programmer well.

I think this dismissal is a mistake. In my personal experience, Zig's extremely legible standard library code and thoughtful approach to default implementations has helped me grow as a programmer in ways I never anticipated. By providing friction in the right places, the language has steered me towards better design and more correct code. In this particular instance, I think juice, while worth an eventual squeeze, might come at an off-putting price for a beginner. To wit, I didn't learn to comfortably reach for hash maps from Zig; I learned it from Rust.

This is more of an addendum, but I'd like to also propose the addition of std.HashSet(T) as well, as in #6919. My reason for doing so, though, is different. For example, I would be happy to see a simple implementation like

pub fn std.HashSet(K) type {
    return std.ArrayAutoHashMapUnmanaged(K, void);
}

The reason I would like to ask for this addition to the standard library is not functional but pedagogical: again, realizing that you can implement a HashSet type by creating a HashMap type with a zero-sized value type is a beautiful realization that I don't want to deny a beginner Zig programmer; the challenge is that coming to that realization on one's own is nontrivial.

Metadata

Metadata

Assignees

No one assigned

    Labels

    breakingImplementing this issue could cause existing code to no longer compile or have different behavior.proposalThis issue suggests language modifications. If it also has the "accepted" label then it is planned.standard libraryThis issue involves writing Zig code for the standard library.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions