SML’s design for records matured around 1986, with a few tweaks in the 1997 standard.
SML’s Record syntax is superficially like Haskell: { year = 2023, month = 3, day = 7} : {year : int, month : int, day : int}
. (p13 in the standard; :
is how SML spells ::
.) Similar syntax as Haskell in pattern matching, binding a pattern (possibly including vars) to a label within a record.
After that the similarity ends. Its records are:
- First-class/stand-alone/anonymous – that is, not tied to any data type/not needing a data constructor prefix.
- Labels are therefore global scope/can appear in any record.
- Labels don’t give rise to selector functions, so need special syntax
#
to extract by label#month today
. - Free-standing tuples are treated as shorthand for a record with numeric labels:
(2023, 3, 7) ==> {#1 = 2023, #2 = 3, #3 = 7}
. (p22 Derived Form) IOW#1, #2
are likefst, snd
, but not limited to twoples.
Record syntax arrived in Haskell ~1995, as syntactic sugar in data
constructors, to ease the burden of squinting at constructors/patterns with many positionally-defined fields.
Presumably Haskell designers were aware of SML – they at least stole the syntax. There’s a 1999 paper Mark P Jones & SPJ – in the middle of finalising the 1998 standard – proposing Haskell pretty much follow SML/throw out compatibility with the 1998 standard. It mentions a few design difficulties – beyond the incompatibility, but nothing compared to the difficulties we’ve all been suffering for ~25 years.
I can’t find any explanation/rationale for why Haskell’s records are so different vs SML Does anyone know of any refs? Or can give some explanations?