Hi everyone,
José Valim suggested I move the discussion here from my PR:
https://github.com/elixir-lang/elixir/pull/15023I've implemented shorthand syntax for atom-keyed maps and keywords:
```elixir
%{user:, conn:} # => %{user: user, conn: conn}
[foo:, bar:] # => [foo: foo, bar: bar]
f(name:, age:) # => f(name: name, age: age)
%{map | a:, b:} # => %{map | a: a, b: b}
```
I know this topic has been discussed many times before:
- Proposal: Short Hand Property Names (2017):
https://groups.google.com/g/elixir-lang-core/c/XxnrGgZsyVc- Consider supporting a map shorthand syntax (2018):
https://groups.google.com/g/elixir-lang-core/c/NoUo2gqQR3I- ES6-ish property value shorthands for maps? (2016):
https://elixirforum.com/t/es6-ish-property-value-shorthands-for-maps/1524- Has Map shorthand syntax caused you any problems? (2018):
https://elixirforum.com/t/has-map-shorthand-syntax-in-other-languages-caused-you-any-problems/15403Most of these discussed the ES6-style `%{a, b}` syntax, which José made clear had "zero chance" of being accepted — mainly because `%{a, b}` vs `{a, b}` differs by one character, making maps and tuples too easy to confuse.
The colon-based syntax `%{a:, b:}` is different. The `:` that signals "this is a key-value pair" stays there. There's no visual confusion with tuples because `{a:, b:}` is not valid Elixir syntax anyway.
José mentioned in the PR that he actually prefers this approach over bare variables, but it was "deemed not acceptable by most people" in a previous discussion. I'd like to understand what the objections were.
Reading through the old threads, I found these concerns:
- "Removing explicitness for the sake of brevity doesn't appeal to me." (Chris Keathley)
- "Shorthand syntax makes that coupling even less obvious" — if you change a key, you need to find all functions that relied on that variable name. (Chris Keathley)
- "This will just add complexity to the language to save a few keystrokes for advanced users." (Matt Widmann)
These discussions happened in 2016-2018. Since then, Ruby 3.1 shipped this exact syntax in December 2021 — almost 4 years ago. The syntax is `{x:, y:}` for hashes and `foo(x:, y:)` for keyword arguments, exactly what I'm proposing for Elixir.
The Ruby reception was mixed at first — Bozhidar Batsov (RuboCop maintainer) was critical (
https://batsov.com/articles/2022/01/20/bad-ruby-hash-value-omission/) but still allowed it in RuboCop defaults. Four years later, the syntax is widely used.
The same pattern (sometimes called "field punning") also exists in Rust and OCaml.
`%{user: user, conn: conn}` is already common in Elixir — this just removes the repetition. The colon stays visible, so it's not as "magic" as the bare variable approach. And Ruby has been using it for 4 years now without issues.
The implementation is ready and all tests pass. I'm curious whether opinions have changed since 2018.