Skip to content

Commit ca5d24c

Browse files
malli the metadata, add content
1 parent 331c5a9 commit ca5d24c

File tree

13 files changed

+905
-417
lines changed

13 files changed

+905
-417
lines changed

clay.edn

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,9 @@
66
:remote-repo {:git-url "https://github.com/timothypratley/clojurecivitas"
77
:branch "main"}
88
:hide-info-line true
9-
:hide-ui-header true}
9+
:hide-ui-header true
10+
:aliases {:markdown {:render true
11+
:base-target-path "site"
12+
:format [:quarto :html]
13+
:run-quarto false
14+
:hide-info-line false}}}

content/ideas/clojure/plus/print/objects/objects_and_protocols.clj

Lines changed: 15 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -19,29 +19,22 @@
1919

2020
;; [clojure-plus](https://github.com/tonsky/clojure-plus) provides print-methods to improve printing many things.
2121

22-
(require 'clojure+.print)
23-
^:kind/hidden
24-
(clojure+.print/install-printers!)
25-
26-
;; Once activated, we can print functions, atoms, namespaces, and more sensibly
27-
28-
inc
29-
(atom {})
30-
*ns*
22+
(comment
23+
(require 'clojure+.print)
24+
(clojure+.print/install-printers!))
3125

26+
;; Once activated, we can print functions, atoms, namespaces, and more sensibly.
3227
;; Clojure Plus adds printers for many types,
3328
;; but no printer is provided for Object,
3429
;; which remains as Clojure's default printing method.
3530
;; There are plenty of objects left over that print messily.
36-
;; Going back to our channel example, it still prints the same:
37-
38-
(async/chan)
3931

4032
;; It's not hard to provide an Object print-method:
4133

4234
(defmethod print-method Object [x ^java.io.Writer w]
43-
(.write w "#object ")
44-
(.write w (.getName (class x))))
35+
(.write w "#object [")
36+
(.write w (.getName (class x)))
37+
(.write w "]"))
4538

4639
(async/chan)
4740

@@ -93,60 +86,26 @@ inc
9386

9487
;; Looking better, I can actually see the (strange) name of the functions.
9588

96-
;; Notice now that the string is not a valid symbol?
97-
;; That's a problem if we follow the style of `clojure-plus` because it prints as tagged literals.
98-
;;
99-
;; `#object clojure.plus.print.objects.objects-and-protocols/%%/%%%` is not a valid Clojure expression.
100-
;; In a sense it doesn't matter much if we are just printing, but it tends to confuse tools (and people).
101-
;; So I recommend replacing all slashes after the namespace delimiter with `$` instead.
102-
;; While we are at it... the namespace isn't helping us at all here.
103-
;; Let's just show the name without the namespace.
104-
105-
(defn format-class-name [s]
89+
(defn format-class-name ^String [s]
10690
(let [[ns-str & names] (-> (remove-extraneous s)
10791
(str/split #"/"))]
10892
(if (and ns-str names)
109-
(str/join "$" names)
110-
s)))
93+
(str (str/join "$" names))
94+
(-> s (str/split #"\.") (last)))))
11195

11296
(-> (((fn aaa [] (fn bbb [] (fn ccc [])))))
11397
(class-name)
11498
(format-class-name))
11599

116-
;; That's really all we need.
117-
;; Notice there is no `/` slash if we don't show the namespace, but we still can't use `/` because functions can nest arbitrarily.
118-
119-
;; Side note about including or omitting the namespace.
120-
;; There are many ways to get whatever representation you want,
121-
;; so changing the printing behavior doesn't prevent anything.
122-
;; The question is just would you like to see it or not?
123-
;; I would argue that it's almost never useful, just a distraction.
124-
;; On the other hand, the current behavior for printing vars is fully qualified.
125-
;; Whatever your preference on showing the namespace, it should probably be consistent across printers.
126-
127-
;; I'll assume you prefer including the namespace
128-
129-
(defn format-class-name [s]
130-
(let [[ns-str & names] (-> (remove-extraneous s)
131-
(str/split #"/"))]
132-
(if (and ns-str names)
133-
(str ns-str "/" (str/join "$" names))
134-
s)))
135-
136100
;; Let's hook this up to the print-method for Object:
137101

138102
(defmethod print-method Object [x ^java.io.Writer w]
139-
(.write w "#object ")
140-
(.write w (-> (class-name x) (format-class-name))))
141-
142-
;; Notably this doesn't change function etc... because they are still using the `clojure-plus` print-method:
103+
(.write w "#object [")
104+
(.write w (-> (class-name x) (format-class-name)))
105+
(.write w "]"))
143106

107+
*ns*
144108
(((fn aaa [] (fn bbb [] (fn ccc [])))))
145-
146-
;; In my opinion, the fn and multi print-methods of `clojure-plus` should be changed to the cleaner output.
147-
148-
;; But it matters for our reify example:
149-
150109
(stats/create-flow)
151110

152111
;; What is this? It's a reified object that implements protocols.
@@ -228,36 +187,17 @@ inc
228187
;; But we can improve the print-method to show protocols,
229188
;; bearing in mind it is a performance concern.
230189

231-
(defmethod print-method Object [x ^java.io.Writer w]
232-
(let [class-name (.getName (class x))
233-
r (str/includes? class-name "$reify")
234-
p (when r (first (protocol-ns-match-names x)))]
235-
(.write w (if p
236-
"#reify "
237-
"#object "))
238-
(.write w (if p
239-
(str p)
240-
class-name))))
241-
242-
(stats/create-flow)
243-
244190
;; Showing the reified protocol isn't a big improvement, and probably not worth the performance.
245191
;; Probably not worth including in `clojure-plus`.
246192

247193
;; Even if we don't care to improve reify (due to performance),
248194
;; I think the Object printer should still be improved to align with the other printers.
249-
;; Let's go back to the basic Object print-method without protocol detection.
250-
251-
(defmethod print-method Object [x ^java.io.Writer w]
252-
(.write w "#object ")
253-
(.write w (-> (class-name x) (format-class-name))))
254195

255-
;; O.K.
256196
;; Are we giving up anything?
257197
;; Remember we removed the unique identifiers like `/evalNNNNN/`.
258198
;; When would those be useful?
259199
;; Hold onto your hats!
260-
;; We are about to try to find an Object by it's class-name:
200+
;; We are about to try to find an Object by a class-name:
261201

262202
(defn find-class [class-name]
263203
(try

0 commit comments

Comments
 (0)