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. 

But FWIW I just looked over some old code and see that records also made things 
more complicated in my application because my defstruct/defrecord is produced 
by a macro expansion and that was simpler to arrange with defstruct. At least 
how I was able to see how to do it. Perhaps some will think this is some form 
of macro abuse, but in the context in which I conduct my runs it does the job. 
I'll bet some of you will also see much better ways for me to do the record 
version :-)

Also BTW I saw no clear performance improvement (relative to the overall 
runtime of my system); some numbers on that are also below.

For the morbidly curious (only) I'll include some details below.

Thanks,

 -Lee

;; Some details from my code at https://github.com/lspector/Clojush

;; Here's a var that has a value that may be used in a couple of places 
including the struct/record definition:

(def push-types '(:exec :integer :float :code :boolean :auxiliary :tag :zip))

;; Here's the way I define things as struct-maps:

(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))

;; To switch to records I ended up doing something with a few more 
complications in a couple of places:

(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)))

;; My performance tests are big stochastic messes but still they give a basic 
picture.
;; For each condition I start with a fresh JVM launch and then run the same 
test 3 times.

;; here's what I get with structmaps:
;1:3 clojush=> (time (stress-test 100000))
;:no-errors-found-in-stress-test
;"Elapsed time: 59194.123 msecs"
; more runs:
;"Elapsed time: 52389.016 msecs"
;"Elapsed time: 54706.127 msecs"

;; here's what I get with records:
;1:3 clojush=> (time (stress-test 100000))
;:no-errors-found-in-stress-test
;"Elapsed time: 57673.781 msecs"
; more runs:
;"Elapsed time: 57682.971 msecs"
;"Elapsed time: 55129.614 msecs"

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to