Datatypes and Protocols in Clojure
Clojure is built on the idea of abstractions. While its core collections (lists, vectors, maps, sets) are immutable and powerful, sometimes developers need to define custom data structures and extend them with polymorphic behavior. This is where datatypes and protocols come in. They provide a way to create efficient, extensible abstractions directly in Clojure without dropping down to Java. Clojure liveBook O'Reilly
🏛️ Datatypes in Clojure
Datatypes are user-defined structures that allow you to create new kinds of objects with fields and methods. They are defined using deftype or defrecord.
Defrecord
- Provides a map-like structure with named fields.
- Automatically supports Clojure’s associative operations (
get,assoc).
(defrecord Person [name age])
(def p (->Person "Alice" 30))
(:name p) ;; => "Alice"
(:age p) ;; => 30
Deftype
- Lower-level than
defrecord. - Does not automatically behave like a map.
- Useful for performance-critical code.
(deftype Point [x y])
(def pt (Point. 10 20))
(.x pt) ;; => 10
(.y pt) ;; => 20
🔄 Protocols in Clojure
Protocols are similar to interfaces in Java but more flexible. They define a set of functions that can be implemented by different datatypes.
Defining a Protocol
(defprotocol Shape
(area [this])
(perimeter [this]))
Implementing a Protocol
(defrecord Circle [radius]
Shape
(area [this] (* Math/PI radius radius))
(perimeter [this] (* 2 Math/PI radius)))
(defrecord Rectangle [width height]
Shape
(area [this] (* width height))
(perimeter [this] (* 2 (+ width height))))
Usage
(def c (->Circle 5))
(area c) ;; => 78.5398...
(perimeter c) ;; => 31.4159...
(def r (->Rectangle 4 6))
(area r) ;; => 24
(perimeter r) ;; => 20
✨ Why Datatypes and Protocols Matter
- Performance: They provide efficient, JVM-level implementations.
- Polymorphism: Protocols allow multiple datatypes to share behavior.
- Extensibility: You can add new datatypes or extend existing ones without modifying original code.
- Abstraction: Encourages programming to interfaces rather than concrete implementations.
📖 Conclusion
Datatypes and protocols in Clojure give developers the ability to define custom structures and shared behaviors while staying true to the language’s functional and immutable philosophy. They combine the flexibility of Lisp with the performance of the JVM, making Clojure suitable for both high-level abstraction and low-level efficiency.
No comments:
Post a Comment