Records are not the same thing as hash-tables. A record, or struct, is a single unit value, while a hash-table, or map, is an aggregate container. There is an implicit contract in place; a record is guaranteed to have JUST the fields it's defined to have, while a map can grow at run time (are you going to test for the fields you want and ignore the rest? quack quack! you can't add fields to a record at runtime, so the two are NOT interchangeable. Equality is a transitive relation, while duck-typing is not.)
A record is a generalization of the concept of "value" beyond data types immediately representable by machine. While a hash-table is a generalization of arrays, an aggregate of values, addressable by an index (hash-tables remedy the silly assumption that an index must be of an integral value.)
To give an analogy; it's like asking what's the best way to group a bunch of papers (folder, envlope, binder) and then hearing someone suggest "bookshelf!".
Again, OK short-term, but stinks. Fix the structs; even C has dot and arrow notations, making the field names clear.
user> (defrecord Foo [x])
user.Foo
user> (assoc (Foo. 1) :y 2)
#:user.Foo{:x 1, :y 2}
user> (defstruct foo :x)
#'user/foo
user> (assoc (struct-map foo :x 1) :y 2)
{:x 1, :y 2}I will announce this great news to a few of my closest friends :-)
You can think of them as a Java class that has certain fields (it's named fields) and also implements the Map interface for additional expandability. Records provide "accessor" methods for their named fields that provide bare-metal JVM performance.