Status
Accepted
Context
Slug maps support multiple key types, most notably symbols and strings:
{ :name: "Bob" }
{ "name": "Bob" }
Explicit map lookup uses bracket syntax:
m[:name]
m["name"]
These lookups are type-exact and do not perform coercion. However, this creates developer friction when working with mixed data sources (e.g. JSON), where keys are typically strings while idiomatic program data often prefers symbols.
This mismatch can lead to subtle usability issues:
- Developers must remember whether a map uses
"name"or:name - External data (JSON, DB results) often differs from internal conventions
- Simple field-style access becomes unnecessarily fragile
Slug aims to maintain explicit semantics while also providing a smooth developer experience.
Decision
Slug introduces tolerant dot lookup for maps, while keeping bracket lookup strict.
Exact Lookup (Unchanged)
Bracket lookup remains explicit and exact:
m[:name] // symbol key
m["name"] // string key
Rules:
- No coercion
- No fallback
- Key type must match exactly
Dot Lookup
Dot syntax provides ergonomic field-style access:
m.name
Resolution order:
- Attempt lookup with the symbol key
:name - If not present, attempt lookup with the string key
"name"
If neither key exists, normal missing-key behaviour applies.
Precedence
If both keys exist:
val m = {
:name: "symbol",
"name": "string"
}
Dot lookup resolves to the symbol key:
m.name == "symbol"
Scope of the Rule
This tolerant behaviour applies only to dot lookup.
Bracket lookup remains strict and unchanged.
Consequences
Positive
- Improves developer experience when working with mixed key types.
- Simplifies interaction with JSON and other external data sources.
- Preserves strict, explicit behaviour for bracket lookup.
- Aligns map field access with structs and modules (
value.fieldsemantics). - Maintains clear control when exact key types matter.
Negative
- Dot lookup semantics differ from bracket lookup semantics.
- Developers must understand symbol precedence when both key types exist.
Neutral
- JSON decoding can remain string-keyed without affecting usability.
- Runtime implementations may add a small fallback check for dot lookup.