# Lists carry an optional dotted tail rather than a separate improper-list variant

Every target dialect has dotted pairs / improper lists (`(a . b)`, `(a b . c)`) — AutoLISP builds association lists from them, LFE and the Lisp core rely on them. We represent this with a single `List { delim, items, tail: Option<Box<Datum>> }` variant where `tail: None` is a proper list and `tail: Some(_)` is improper, rather than a separate `DottedList` variant. This keeps one code path for "iterate a list's items and read its head" (what `cccc`'s special-form dispatch and any future serializer both want), matches `lexpr`'s cons-based internal representation, and treats a proper list as the natural special case of the general one; the type-safety benefit of a distinct variant is low because `cccc` can ignore the dotted tail entirely for complexity purposes.

## Addendum (0.5.0): the dot separator carries its own span

The `List` variant gains a fourth field, `dot: Option<Span>`, the byte span of the `.` separator itself (surfaced as `Datum::dot_span()`). `dot` is `Some` exactly when `tail` is `Some`. The tail *datum* alone was not enough for a **text-based** consumer: Emacs's indenter treats a lone `.` as an alignable token, so a continuation line of the tail in the `'(eval . FORM)` font-lock idiom aligns under the `.`, not under the car. Without the separator span the only route was to re-scan the source between the last item's end and the tail's start for the `.` — re-doing work the reader already did when it consumed the token. Recording the span the reader already has closes that gap.

This is a **breaking change** (a new field on a non-`#[non_exhaustive]` struct variant breaks exhaustive `List { delim, items, tail }` patterns and constructions), taken deliberately in 0.5.0. `DatumKind` stays exhaustive on purpose — code-vs-data walkers and formatters want the compiler to force a match arm per kind — so the field is added outright rather than hidden behind `#[non_exhaustive]`.
