Skip to content

Instantly share code, notes, and snippets.

@aamedina
Created June 25, 2021 21:46
Show Gist options
  • Select an option

  • Save aamedina/bc82bc543c21fcfae51c6c2071ff5f43 to your computer and use it in GitHub Desktop.

Select an option

Save aamedina/bc82bc543c21fcfae51c6c2071ff5f43 to your computer and use it in GitHub Desktop.
(ns dev.describe
"A Clojure port of the Common Lisp describe function."
(:require
[clojure.pprint :refer [pprint]]
[clojure.repl]
[clojure.spec.alpha :as spec]))
(def hierarchy (make-hierarchy))
(defmulti describe-object
"The multimethod describe-object prints a description of object
to a stream. describe-object is called by describe; it must not be
called by the user.
Users can add methods to describe qualified idents.
e.g. (describe 'hello/world) ; or :hello/world
could be described by a user installing the following method:
(defmethod describe-object 'hello/world
[object stream]...)
Users are encouraged to derive/underive using #'dev.describe/hierarchy to
further customize dispatch behavior."
(fn [object stream]
(if (qualified-ident? object) object (type object)))
:hierarchy #'hierarchy)
(defmethod describe-object clojure.lang.Namespace
[object stream]
(#'clojure.repl/print-doc (#'clojure.repl/namespace-doc object)))
(defmethod describe-object clojure.lang.Var
[object stream]
(#'clojure.repl/print-doc (meta object)))
(defmethod describe-object :default
[object stream]
(if (keyword? object)
(#'clojure.repl/print-doc {:spec object :doc (spec/describe object)})
(pprint object stream)))
(defn describe
"describe displays information about object to stream.
The actual act of describing the object is implemented by
describe-object."
([object]
(describe object *out*))
([object stream]
(binding [*out* stream]
(describe-object object stream))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment