This is an attempt to redesign and clarify the design of the OverloadedRecordFields extension, in order to develop a plan for implementation. It has benefited from the extensive discussion surrounding Nikita Volkov's record library. The following design choices are not set in stone, but are intended as a concrete proposal for further discussion. For reference, here is the previous design.
Bare field names in expressions refer to the selector function only if unambiguous, so how are we want to select and update overloaded fields? We need some way to refer to write fields in expressions in a way that allows them to be overloaded. This is provided by the OverloadedLabels extension.
We propose three essentially orthogonal additions to GHC:
an extension DuplicateRecordFields to permit the same field name to be used multiple times in the same module;
an extension OverloadedLabels to enable the #x syntax, interpreted with the IsLabel typeclass;
typeclasses with special-purpose constraint solving behaviour to enable polymorphism over record fields.
The OverloadedRecordFields extension is then defined as the combination of OverloadedLabels and DuplicateRecordFields.
These are all useful independently, but complement each other:
DuplicateRecordFields is perfectly sensible without OverloadedLabels: it allows duplicate field names provided they are not used ambiguously.
OverloadedLabels uses the special typeclasses through the instance for IsLabel x (r -> a), but is also useful when used at other types (e.g. we could give an instance IsLabel x (Proxy x) to allow implicit values to represent Symbol proxies).
Without either of the extensions, the special typeclasses allow users to write code that works for all datatypes with particular fields (albeit without a nice built-in syntax).
While we might choose to add anonymous records later, they are not central to the design. In particular, this means that
all existing features of Haskell datatypes, such as multiple constructors, strictness and unpacking, are supported unchanged;
abstraction and representation hiding work just as in normal Haskell: if a field selector is not exported, client code cannot observe it;
application code can use DuplicateRecordFields even with libraries that do not;