Working with structs

Here are some examples working with the Clojure API.

Here I look at various functions based on StuctMaps. The Clojure website says that records are now usually a better option. StructMaps have faster accessors that regular maps.

Here are some examples with defstruct:

user=> (defstruct pres-name :fname :lname)
#'user/pres-name
user=> (def gw (struct-map pres-name :fname "George" :lname "Washington"))
#'user/gw
user=> gw
{:fname "George", :lname "Washington"}
user=> (def ja (struct-map pres-name :fname "John" :lname "Adams" :number 2))
#'user/ja
user=> ja
{:fname "John", :lname "Adams", :number 2}
;; use accessor to make a function to get the presidential first name
user=> (def pres-fname (accessor pres-name :fname))
#'user/pres-fname
user=> (pres-fname gw)
"George"
user=> (pres-fname ja)
"John"
user=> (class pres-fname)
clojure.lang.PersistentStructMap$1
user=> (class ja)
clojure.lang.PersistentStructMap

Here are some examples with create-struct (pretty much the same):

user=> (def pres-name (create-struct :fname :lname))
#'user/pres-name
user=> (def gw (struct-map pres-name :fname "George" :lname "Washington"))
#'user/gw
user=> gw
{:fname "George", :lname "Washington"}
user=> (def ja (struct-map pres-name :fname "John" :lname "Adams" :number 2))
#'user/ja
user=> ja
{:fname "John", :lname "Adams", :number 2}
user=> (def pres-fname (accessor pres-name :fname))
#'user/pres-fname
user=> (pres-fname gw)
"George"
user=> (pres-fname ja)
"John"
user=> (class pres-fname)
clojure.lang.PersistentStructMap$1
user=> (class ja)
clojure.lang.PersistentStructMap

If you create instances with “struct” instead of “struct-map”, you can list the args in order without the keys.

user=> (defstruct pres-name :fname :lname)
#'user/pres-name
user=> (def tj (struct pres-name "Thomas" "Jefferson"))
#'user/tj
user=> tj
{:fname "Thomas", :lname "Jefferson"}
;; can't leave out keys with struct-map
user=> (def reverse-tj (struct-map pres-name "Jefferson" "Thomas" ))
#'user/reverse-tj
user=> reverse-tj
{:fname nil, :lname nil, "Jefferson" "Thomas"}
user=> (def reverse-tj (struct pres-name "Jefferson" "Thomas" ))
#'user/reverse-tj
user=> reverse-tj
{:fname "Jefferson", :lname "Thomas"}
;; you can't add extra fields with struct
user=> (def jmad (struct pres-name "James" "Madison" "Montpillier"))

CompilerException java.lang.IllegalArgumentException: Too many arguments to struct constructor, compiling:(form-init4378589884523203908.clj:1:11) 
 
user=> (def jmad (struct-map pres-name :fname "James" :lname "Madison" :house "Montpillier"))
#'user/jmad
user=> jmad
{:fname "James", :lname "Madison", :house "Montpillier"}
user=> (class jmad)
clojure.lang.PersistentStructMap
user=> (class tj)
clojure.lang.PersistentStructMap
user=> (class reverse-tj)
clojure.lang.PersistentStructMap
user=> (:fname jmad)
"James"
user=> (:lname tj)
"Jefferson"
user=> (:lname reverse-tj)
"Thomas"
user=> (:house jmad)
"Montpillier"
user=> (:house tj)
nil
user=> (def pres-fname (accessor pres-name :fname))
#'user/pres-fname
user=> (pres-fname tj)
"Thomas"
user=> (pres-fname reverse-tj)
"Jefferson"
;; you can leave keys out
user=> (def jmon (struct-map pres-name :fname "James"))
#'user/jmon
user=> jmon
{:fname "James", :lname nil}
user=> (def jqad (struct pres-name "John"))
#'user/jqad
user=> jqad
{:fname "John", :lname nil}

 

You’re welcome.