Working with Classes in Clojure

Web Technology   Digital Transformation Technology Artificial Intelligence Technology   Natural Language Processing Technology   Semantic Web Technology   Deep Learning Technology   Online Learning & Reinforcement Learning Technology  Chatbot and Q&A Technology   User Interface Technology   Knowledge Information Processing Technology   Reasoning Technology  Clojure Programming

Composing ClojurScript, considering integration with OOP platforms such as Java, and even the aforementioned Crala requires an understanding of the operation of classes in Clojure.

Clojure’s “Data Types: deftype, defrecord, and retify” states that the motivation for providing class functionality is “to provide a powerful and flexible abstraction and data structure definition mechanism without compromising the host platform mechanism. The host platform here refers mainly to Object Oriented (OO) platforms such as java, and the mechanism is to make the data consistent with the data handled in those platforms.

First, let’s talk about deftype and defrecord. Both of them are similar to defstruct in that they generate data structures with named fields. defstruct allows you to define the structure of map data as shown below, and then generate data according to that structure. These only generate the structure data, not the class, and do not support OO.

(defstruct person :name :age :height)
(struct person "george" 22 115)
;;-> {:name "george", :age 22, :height 115}

The difference between deftype and defrecord is that deftype is a low-level function and defrecord is constructed on deftype. The difference between deftype and defrecord is that deftype is a low-level function and defrecord is constructed on top of deftype. The difference between deftype and defrecord is that deftype is a low-level function and defrecord is constructed on deftype. defrecord is therefore mainly used for general class usage, for example, the following class is generated.

(defrecord Person [fname lname address])
(defrecord Address [city state zip])

There are multiple ways to create an instance using these as follows.

(def sniper (new Person "bob" "swagger" (Address "Baltimore" "Maryland" 21080))
(def sniper (->Person "bob" "swagger" (Address "Baltimore" "Maryland" 21080))
(def sniper (Person. "bob" "swagger" (Address "Baltimore" "Maryland" 21080))

To access these data, do the following as in the normal map.

(:lname sniper)
;;-> "swagger"
(-> sniper :address :city)
;;-> Baltimore"
(assoc sniper :fname "Lee")
;;#:user.Person{:fname "Lee", :lname "swagger", :address #:user.Address{:city "Baltimore", :state "Maryland", :zip 21080}}

In order to define the methods required for the OOP class, the protocol (interface) defined in defprotocol is first inherited by defrecord, and then the methods are defined. Specifically, the code is as follows.

(defprotocol WereCreature
   (full-moon-behavior [x])
(defrecord WereWolf [name title]
    WereCreature
      (full-moon-behavior [x]
         (str name " will howl and murder")))
(full-moon-behavior (map->WereWolf {:name "Lucian" :title "CEO of Merodrama"}))
;;-> "Lucian will howl murder"

In addition, there are several other points to consider, such as using extend to inherit or override classes, defrecord does not have a constructor to describe the initialization process, and a function for initialization must be defined beforehand.

コメント

タイトルとURLをコピーしました