Name-Matched Shorthand for Dict Literals and Function Calls
The Problem
Dict key typos are silent bugs:
name = parse_name(raw)
email = validate_email(raw)
# "emial" is a valid string key — no error, no warning
response = {"name": name, "emial": email}
No linter, type checker, or test catches this unless something downstream expects "email" and fails. The bug ships to production.
This happens because dict keys are strings — they bypass the compiler entirely. Meanwhile, a typo in a keyword argument does fail:
create_user(nmae=name) # TypeError: unexpected keyword argument 'nmae'
Both cases share the same root pattern: repeating a variable name as a key or parameter name ("x": x, x=x). This redundancy is everywhere — API responses, template contexts, logging, dataclass construction, config dicts.
The Idea
A soft keyword use that forwards variable names as dict keys or keyword arguments:
# Dict literals
response = {use name email role}
# desugars to: {"name": name, "email": email, "role": role}
# Function calls
create_user(use name email role)
# desugars to: create_user(name=name, email=email, role=role)
One grammar production (use NAME+), two contexts, pure compile-time desugaring. No new runtime behavior.
The dict case turns a string-domain operation into an identifier-domain operation — {use emial} is a NameError because emial isn’t defined. The compiler catches the typo.
Mixing with regular entries
# Dict: shorthand + regular entries
{use name email, "extra_key": 42}
# Call: shorthand + positional args + kwargs
foo(42, use name email, z="extra")
Names are space-separated (not comma-separated) to avoid ambiguity with set literals in dicts and positional arguments in calls.
Relationship to PEP 736
I’m aware PEP 736 (f(x=)) was rejected — the Steering Council found the cost/benefit too low for call sites alone. This idea broadens the scope: the same grammar addition applies to dict literals, where it provides a qualitative safety improvement (catching key typos) beyond just reducing verbosity.
The grammar cost is nearly identical to PEP 736 (one soft keyword, one production). The benefit surface is wider.
Prior discussions
This topic has come up before on this forum:
- Shorthand notation of dict literal and function call (2020) — explored
:firstandvar=syntax for both dicts and calls. - Shorthand dict literal initialization (2024) — proposed
f{var}syntax, got pushback on frozenset ambiguity and low usage stats.
This proposal differs in using a soft keyword with space-separated names (avoiding set/frozenset ambiguity) and leading with compile-time typo detection as the primary motivation rather than keystroke savings.
Prior art
Nix’s inherit keyword does exactly this for attribute sets:
let x = 1; y = 2;
in { inherit x y; }
# equivalent to { x = x; y = y; }
Questions for the community
- Does the dict typo safety angle change the cost/benefit calculus compared to PEP 736?
- Does
useread well, or is there a better keyword? (Alternatives considered:bind,using,=prefix) - Are there contexts beyond dicts and calls where this would be useful?
I have a full draft PEP if there’s interest, but wanted to gauge temperature first.