Does anyone know of any good ways to visualise codebase as a call graph?
There seams to be https://github.com/skinkade/clj-auto-call-graph. I'm pretty sure there was something more sophisticated but I can't remember and couldn't find it. I also created https://github.com/jpmonettas/clindex which indexes entire Clojure and ClojureScript codebases whith all dependencies into Datascript (basically a graph), so you can query what you need or navigate the graph with the api although there is nothing there to automatically generate a graph visualization. There is also https://github.com/jpmonettas/clograms to help you create graph visualizations from your code base. It is like a diagrams editor that knows about your codebase deps, functions, namespaces, etc
A previous question like that with some answers in its thread: https://clojurians.slack.com/archives/C03S1KBA2/p1749199747045169
does anyone see a reason my error message is not being printed like I expect? It's printing as clojure.lang.LazySeq@... rather than as the values in the lazy list.
(defmacro weighted-case
"E.g., (weighted-case 50 :a
20 :b
30 :c)
Randonmly one of the clauses and evaluate its body.
The random selection is biased so that each clause is selected
with the given probability. In this example :a is selected 50%
of the time, :b 20% of the time, and :c 30% of the time.
"
[& args]
(assert (even? (count args)))
(let [pairs (partition 2 args)
percent (reduce + 0 (map first pairs))
args (mapcat (fn [[p body]]
[p `(fn [] ~body)])
pairs)]
(assert (= 100 percent)
(format "does not sum to 100: %s" (doall (map first pairs))))
`(weighted-case-impl ~@args)))That's how lazy sequences print by default. doall realizes the sequence but it is still a lazy sequence.
hmm, how can it be lazy and also realized?
format is coercing a seq to a string via Object.toString()
control the conversion directly: (format "....%s" (pr-str (map ...)))
via the print system ( pr-str and friends)
@ghadi, got it. thanks.
user=> (type (map inc [1 2 3 4]))
clojure.lang.LazySeq
user=> (type (doall (map inc [1 2 3 4])))
clojure.lang.LazySeq
A realized lazy sequence is still a lazy sequence, by type.Expanding on that:
user=> (type (seq (map inc [1 2 3 4])))
clojure.lang.ChunkedCons
user=> (str (map inc [1 2 3 4]))
"clojure.lang.LazySeq@f0c03"
user=> (str (doall (map inc [1 2 3 4])))
"clojure.lang.LazySeq@f0c03"
user=> (str (seq (map inc [1 2 3 4])))
"(2 3 4 5)"And as Ghadi noted:
user=> (pr-str (map inc [1 2 3 4]))
"(2 3 4 5)"
user=> (pr-str (doall (map inc [1 2 3 4])))
"(2 3 4 5)"
user=> (pr-str (seq (map inc [1 2 3 4])))
"(2 3 4 5)"> hmm, how can it be lazy and also realized? you already had that, the way it prints isn't caused by being unrealized, it prints that way to avoid realizing lazy seqs unnecessarily