Skip to content

Instantly share code, notes, and snippets.

@kernelp4nic
Forked from gsinclair/tag.clj
Created February 10, 2023 15:03
Show Gist options
  • Save kernelp4nic/691493601a9d2c0911f6785755faa67f to your computer and use it in GitHub Desktop.
Save kernelp4nic/691493601a9d2c0911f6785755faa67f to your computer and use it in GitHub Desktop.
"
Usage:
In code:
(tag> value) or (t> form arg1 arg2 ...) to tag a value to stdout.
(tagseq> 20 x) or (ts> 20 form arg1 arg2 ...) to tag a sequence, printing 20 items.
Note: the value of a (tag>) or (t>) or (tagseq>) or (ts>) form is always the complete
value, so it can be inserted into code without a problem.
At the REPL:
(tv) to see most recently tagged item.
(tv 7) to see eigth most recently tagged item.
(tag-vals) to see all tagged items with their indices.
(tag-vals-summary) to see a precis of the above (index and `type`).
(clear-tag-vals) to empty the tag-list.
Example:
(defn foo [f x y]
(tag> [x y])
(->> (iterate f x)
(t> map :age)
(reduce +)))
"
(def __tag-vals__ (atom '()))
(defn tag-val
([] (first @__tag-vals__))
([n] (nth @__tag-vals__ n)))
(def tv tag-val)
(defn tag-vals []
(doseq [[i val] (reverse (map vector (range) @__tag-vals__))]
(printf "-- %d --\n" i)
(println val)
(println)))
(defn tag-vals-summary []
(doseq [[i val] (reverse (map vector (range) @__tag-vals__))]
(printf "[%2d] %s\n" i (type val)))
nil)
(defn tag-count []
(count @__tag-vals__))
(defn clear-tag-vals []
(def __tag-vals__ (atom '()))
nil)
(defn tag>
([x]
(println "tag>" x)
(swap! __tag-vals__ conj x)
x)
([n coll]
(println "tag>" (take n coll))
(swap! __tag-vals__ conj coll)
coll))
(defn tagseq>
([xs]
(println "<tag>")
(doseq [x xs] (println " " x))
(println "</tag>")
(swap! __tag-vals__ conj xs)
xs)
([n xs]
(println "<tag>")
(doseq [x (take n xs)] (println " " x))
(println "</tag>")
(swap! __tag-vals__ conj xs)
xs))
(defmacro t> [& args]
`(tag> ~args))
(defmacro ts> [& args]
`(tagseq> ~args))
;; Other ideas for tag-related functions/macros.
;;
;; (tagmsg> "message" value) (tmsg> "message" form arg1 arg2 ...)
;; (tagfn> display-function value) (tfn> display-function form arg1 arg2 ...)
;; *tag-display-number*
;; Tag into a separate store, for special debugging:
;; (tagspecial> TAGS value) -- where TAGS is a user-created atom.
;; + (tsp> TAGS form arg1 arg2 ...)
;;
;; (taggeneral> :special TAGS :fn display-fn :message "..." value)
;; + (tgen> :special TAGS :fn display-fn :message "..." form arg1 arg2 ...)
;; (Optionally provide all those specs in a map.)
;;
;; Tagging into a map? That way repeated tags could overwrite old values, which may be
;; desired sometimes.
;; (tagmap> :key value) (tmap> :key form arg1 arg2 ...)
;;
;; Tagging iff a condition is true. (Selective debugging.)
;; (tagiff> true-false value) (tiff> t/f form arg1 arg2 ...)
;;
;; Silent tagging, where you want to record a value for later inspection but you know
;; it would be too huge to bother printing.
;; (tagsilent> value) (tsilent> form arg1 arg2 ...)
;; The output could be "tag> (silent) [clojure.lang.PersistentArrayMap]" or something...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment