hara.extend macros for extensible objects

Author: Chris Zheng  (z@caudate.me)
Date: 29 June 2017
Repository: https://github.com/zcaudate/hara
Version: 2.5.10

hara.extend provide additional functionality on top of defrecord and defmulti/defmethod.

1    extend.abstract

Add to project.clj dependencies:

[im.chit/hara.extend.abstract "2.5.10"]

hara.extend.abstract provides the implementation for the abstract container pattern



extend-abstract ^

creates a set of abstract multimethods as well as extends a set of protocols to a given type

v 2.1
(defmacro extend-abstract
  [typesym protocolsyms & {:as options}]
  (list `keep `identity
        (cons `concat
              (map #(protocol-all typesym % options)
                   protocolsyms))))
link
(extend-abstract Envelope [IData] :select - :suffix -env :prefix nil :wrappers {-data (str "hello " %)} :dispatch :type :defaults {nil ([this & args] (Exception. "No input")) -data ([this] (:hello this))}) (data-env (map->Envelope {:hello "world"})) => "world" (-data (map->Envelope {:hello "world"})) => "hello world"

extend-implementations ^

creates a set of implementation functions for implementation of protocol functionality

v 2.1
(defmacro extend-implementations
  [protocolsyms & {:as options}]
  (vec
   (mapcat #(protocol-implementation % options)
           protocolsyms)))
link
(extend-implementations [IData] :wrappers (fn [form _] (list 'str form " again"))) (data (map->Envelope {:hello "world"})) => "hello world again"

2    extend.all

Add to project.clj dependencies:

[im.chit/hara.extend.all "2.5.10"]

hara.extend.all promotes code reuse by providing a template for extend-type

hara.extend.all



extend-all ^

transforms a protocl template into multiple extend-type expresions

v 2.1
(defmacro extend-all
  [proto ptmpls & args]
  (let [types (partition 2 args)]
    `(do
       ~@(mapcat #(extend-entry proto ptmpls %) types))))
link
(macroexpand-1 '(extend-all Magma [(op ([x y] (% x y)) )] Number [op-number] [List Vector] [op-list])) => '(do (clojure.core/extend-type Number Magma (op ([x y] (op-number x y)))) (clojure.core/extend-type List Magma (op ([x y] (op-list x y)))) (clojure.core/extend-type Vector Magma (op ([x y] (op-list x y)))))