On Jul 22, 2012, at 7:42 PM, Warren Lynn wrote:
> I plan to change all my major data structures to records instead of plain maps. Since record has everything a map provides, I figure there won't be any harm. But is that really so? Would appreciate the opinions from people who know better.
I know I'm in the minority but I happen to prefer maps to records, and in fact I really like struct-maps which I gather may (?) not be long for this world. Nonetheless, since you asked, following are two old messages in which I attempted to point out some of the things that I like about struct-maps as opposed to records.
------------------
On Jul 28, 2011, at 8:19 PM, Alex Osborne wrote:
> The main use cases for the old structs feature on the other hand are
> completely replaced by records and it is recommended that new code use
> defrecord instead of defstruct.
I had some code using structs and, following advice like this, replaced it with code using records.
The result was more complicated, uglier and not noticeably faster.
I reverted to the struct version.
I like structs, and I hope they are retained!
-Lee
PS for anyone who is curious the struct version of the code in question is as follows (with push-types having a value like '(:exec :integer :float :code :boolean :auxiliary :tag :zip)):
(defmacro define-push-state-structure []
`(defstruct push-state ~@push-types))
(define-push-state-structure)
(defn make-push-state
"Returns an empty push state."
[]
(struct-map push-state))
The record version that I came up with is:
(defn keyword->symbol [kwd]
"Returns the symbol obtained by removing the : from a keyword."
(read-string (name kwd)))
(defmacro define-push-state-record-type []
"Defines the pushstate record type. The odd trick with read-string was a hack to
avoid namespace qualification on the pushstate symbol."
`(defrecord ~(read-string "pushstate") [~@(map keyword->symbol push-types)]))
(define-push-state-record-type)
(defmacro make-push-state
"Returns an empty push state."
[]
`(pushstate. ~@(map (fn [_] nil) push-types)))
Maybe there's a better way -- I wouldn't doubt it -- but the struct version was simple and worked exactly like I wanted it to, so I decided to stop tinkering.
-----------------
On Aug 29, 2011, at 2:57 PM, Tassilo Horn wrote:
>
> I guess the problem with that is that you need to have an instance of
> the record before you can use `keys'. And to create an instance, at
> least you have to know the number of keys.
>
> However, you can inspect the record's constructor using reflection:
Or, if structs will do for your application, then you can do this more simply:
user=> (defstruct mystruct :a :b :c)
#'user/mystruct
user=> (keys (struct-map mystruct))
(:a :b :c)
-Lee
----------------------
On Jan 18, 2011, at 7:21 PM, Chas Emerick wrote:
> You might find my minor sugar for defining records whose slots have default values:
>
>
http://cemerick.com/2010/08/02/defrecord-slot-defaults/
Nice -- I do think it'd be good for something like this to be built in.
> Also worth noting is the further enhancement by Michael Fogus (linked to in the comments on the above post) that adds support for kwargs to the factory function for the defined record.
Oh yes, keyword args are another nice thing about struct-map that I'd forgotten about but which have also been important to me in some contexts, e.g. when there are lots of args.
> I also like a few aspects of what structmaps provide vs. regular maps (in particular, documentation of intent), but records have too many far more significant advantages and are too easy to add sugar to to reclaim the minor bits structmaps offer to not use IMO.
If the above conveniences get baked in then I'll probably agree.
----------------------