beluchin
beluchin

Reputation: 12692

why records are not functions?

Unlike maps, records are not functions. Why?

;; maps are functions of the keys
({:a 1} :a) ;; 1
({:a 1}) ;; error
({:a 1} 1) ;; nil

;; records? no, records are not functions
(defrecord T [t])
((->T 1) :t) ;; error: T cannot be cast to clojure.lang.IFn
(:t (->T 1)) ;; 1

Upvotes: 2

Views: 179

Answers (2)

lnostdal
lnostdal

Reputation: 438

Others have answered this, but here's how you make one of your defrecord types implement the IFn interface:

user> (defrecord Blah
          [x y]

        clojure.lang.IFn
        (invoke [o arg] (arg o)))

user> (let [obj (->Blah 1 2)]
        [(obj :x) (obj :y)])
[1 2]

Upvotes: 5

Thumbnail
Thumbnail

Reputation: 13483

In deftype and defrecord, Rich writes "defrecord provides a complete implementation of a persistent map ...". So records ought to work as functions?

NO. IPersistentMap, the interface for persistent maps, does not implement IFn, the interface for Clojure functions.

However, consistency would be nice: converting maps to records ought to produce as few surprises as possible. Having said that ...

  • We use records only where the keys are known keywords, hence the keyword-as-function syntax has always been available.
  • Creating a record is nothing like creating a map. This is a bigger inconsistency, I think.

I hope this meandering maundering helps.

Upvotes: 2

Related Questions