hara.extend macros for extensible objects

Author: Chris Zheng  (z@caudate.me)
Date: 11 February 2018
Repository: https://github.com/zcaudate/hara
Version: 2.8.2

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

1    extend.abstract

Add to project.clj dependencies:

[zcaudate/hara.extend.abstract "2.8.2"]

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)
(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}]
   (mapcat #(protocol-implementation % options)
(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:

[zcaudate/hara.extend.all "2.8.2"]

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


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)]
       ~@(mapcat #(extend-entry proto ptmpls %) types))))
(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)))))