module code functionality management

Author: Chris Zheng  (z@caudate.me)
Date: 27 November 2018
Repository: https://github.com/zcaudate/hara
Version: 3.0.2

1    Introduction

hara.module provides methods and data structures to link and package code into modules

1.1    Installation

Add to project.clj dependencies:

[hara/base "3.0.2"]

All functions are in the hara.module namespace.

 (use (quote hara.module))

2    API



extend-abstract ^

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

v 3.0
(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-all ^

transforms a protocl template into multiple extend-type expresions

v 3.0
(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)))))

extend-implementations ^

creates a set of implementation functions for implementation of protocol functionality

v 3.0
(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"

include ^

imports all or a selection of vars from one namespace to the current one.

v 3.0
(defmacro include
  [& [opts? & sources]]
  (let [[opts sources] (if (map? opts?)
                         [opts? sources]
                         [{} (cons opts? sources)])]
    `(copy/copy (quote ~sources)
                ~opts)))
link
(include (hara.core.base.check atom? long?)) (eval '(long? 1)) => true (eval '(atom? 1)) => false (include {:fn (fn [ns sym var] (intern ns sym (fn [x] (@var (bigint x)))))} (hara.core.base.check bigint?)) (eval '(bigint? 1)) => true (include {:ns 'clojure.core} (hara.core.base.check bigint?)) => [#'clojure.core/bigint?]

link ^

creates links to vars that can be resolved in a controllable manner

v 3.0
(defmacro link
  [& [opts? & sources]]
  (let [[opts sources] (if (map? opts?)
                         [opts? sources]
                         [{} (cons opts? sources)])]
    `(link-sources (quote ~sources)
                   ~opts)))
link
(link {:resolve :lazy} (hara.core.base.check atom?)) (meta #'atom?) => {:name 'atom?, :ns *ns*}

registered-link? ^

checks if a link is registered

v 3.0
(defn registered-link?
  ([^Link link]
   (let [sink     (.sink link)
         registry (.registry link)]
     (= link (get @registry sink)))))
link
(registered-link? -lnk-) => false

registered-links ^

returns all registered links

v 3.0
(defn registered-links
  ([]
   (registered-links +registry))
  ([registry]
   (keys @registry)))
link
(register-link -lnk-) => #'hara.module.base.link-test/-lnk- (registered-links) => (contains [(exactly #'-lnk-)])

resolve-links ^

resolves all unresolved links in a background thread

v 3.0
(defn resolve-links
  ([]
   (resolve-links +registry))
  ([registry]
   (future
     (mapv (fn [v]
             (try
               (bind-resolve @v)
               (catch Throwable t
                 (println "LINK RESOLVE ERROR:" @v))))
           (unresolved-links registry)))))
link
(resolve-links)

unresolved-links ^

returns all unresolved links

v 3.0
(defn unresolved-links
  ([]
   (unresolved-links +registry))
  ([registry]
   (keep (fn [[k link]]
           (= :unresolved (link-status link))
           k)
         @registry)))
link
(unresolved-links)