clojureclojureclr

Clojure record constructors not first class?


Apparently, you can't call apply with a record constructor:

(defrecord Foo. [id field])

(apply Foo. my-list)

fails at read time because it is not expecting Foo. in that place.

The only obvious workaround I could think of was to add a factory function:

(make-foo [id field] (Foo. id field))

which can be apply'ed of course.

Am I missing anything? I'd expect this from C#/Java but just thought it was a bit disappointing in Clojure...


Solution

  • Circling back on this post-1.3....

    In Clojure 1.3, defrecord creates two generated constructor functions. Given:

    (defrecord Person [first last]) 
    

    this will create a positional constructor function ->Person:

    (->Person "alex" "miller")
    

    and a map constructor function map->Person:

    (map->Person {:first "string"})
    

    Because this is a map, all keys are optional and take on a nil value in the constructed object.

    You should require/use these functions from the ns where you declare the record, but you do not need to import the record class as you would when using the Java class constructor.

    More details: