Invisible link to canonical for Microformats

ADR-029 Tolerant Dot Lookup for Map Keys


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:

  1. Attempt lookup with the symbol key :name
  2. 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.field semantics).
  • 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.