I think Erlang records syntax is neat. Expressive, tight and consistent. A bit repetitive sometimes, yes. There is still a big problem with Erlang records. Not with the syntax but with record declarations shared between modules in .hrl files. This is fixed in teeterl.
teeterl now supports (partially) a new breed of records called 'named tuples'. Named tuples and records are very similar - at some point both are mapped to tagged tuples. The true difference is that named tuples are never declared. The inner structure of a named tuple is inferred from its use. No declarations, no .hrl files, no need to recompile.
Named tuple has a separate syntax from records but this is not of essence. Examples:
%% create a tuple named 'car' with fields 'model' and 'mpg'
Car1 = {car#model <- "Lexus", mpg <- 30},
%% create another tuple named 'car'; name is inferred
%% from use in the previous line
Car2 = {model <- "Honda"},
%% get index of the field in the tuple; needed for keyfind()
%% and the likes
Index = car#mpg,
%% access named tuple field; again name is inferred,
%% the alternative is Car1.car#mpg
Mpg = Car1.mpg,
Values:
Car1 = {car,"Lexus",30}
Car2 = {car,"Honda,undefined}
Index = 3
Mpg = 30
The trick is that field offsets of a named tuple are assigned during module loading not during preprocessing or some other compilation step. Thus the layout of a given named tuple may be different in different VMs.
Now if you need another field in a named tuple just assign a value to the field. Send the extended tuple to the old code and you will not break anything. Modules are compiled in complete isolation, no worry about record versions. Plus information about fields is accessible during runtime. And all these goodies come with no performance penalty. Named tuples work at exactly the same speed as conventional records.
EDIT: the teeterl's source code is on GitHub