Structs in Clojure

Clojure’s structs are also used to group data together to form records. Here’s how you can translate the provided code into Clojure.

; Define a struct (record) for a person with name and age fields.
(defrecord Person [name age])

; A function to create a new person with a given name.
(defn new-person [name]
  (let [p (->Person name 42)]  ; Creates a new person with name and default age 42.
    p))                         ; Return the created person.

(defn -main []
  ; Create a new struct (record).
  (println (->Person "Bob" 20))

  ; You can name the fields when initializing a struct.
  (println (map->Person {:name "Alice" :age 30}))

  ; Omitted fields will be nil.
  (println (map->Person {:name "Fred"}))

  ; The Clojure equivalent of taking a pointer and printing it
  (println (new-person "Jon"))

  ; Access struct fields with a dot.
  (let [s (->Person "Sean" 50)]
    (println (:name s)))

  ; Dereference structs can be done automatically in Clojure.
  (let [sp (new-person "Ann")]
    (println (:age sp)))

  ; Struct (record) fields are mutable in that new instances can be created with changes.
  (let [sp (assoc (new-person "Julie") :age 51)]
    (println (:age sp)))

  ; Anonymous struct example.
  (let [dog (struct-map (create (symbol "dog")) :name "Rex" :isGood true)]
    (println dog)))

; To run the program use: (-main)

To run the program, put the code in a file, say structs.clj, and use the Clojure command line tools.

$ clj -m user
{:name "Bob", :age 20}
{:name "Alice", :age 30}
{:name "Fred", :age nil}
#user.Person{:name "Jon", :age 42}
Sean
42
51
{:name "Rex", :isGood true}

Here is the explanation matching the code structure provided:

  1. Define a Struct: The Person record is defined with fields name and age.
  2. Constructor Function: The new-person function demonstrates how to create a new instance of the Person record with a given name.
  3. Creating Instances: Instances of Person can be created both by position or by naming the fields.
  4. Omitted Fields: Fields that are not specified will be nil.
  5. Field Access: Fields can be accessed using the dot notation or keyword get.
  6. Mutable Fields: Records (structs) in Clojure are immutable by default. However, new instances can be created with changes.
  7. Anonymous Structs: Anonymous structs can be created using struct-map.

By following these conventions, you can work with records in Clojure in an idiomatic way.