anyone thought about a precompiler for clojure.pprint/cl-format that accepts an intuitive sexp based grammar rather than "<~a~{~^ ~a=\"~a\"~}~:[~;/~]>~%" — similar to the regex grammar in (common-lisp’s) cl-ppcre?
@alexmiller I've used cl-format more times than refs, agents, and structs combined. Having it in the core is one of the most whimsical and fun decisions in Clojure 🙂
turns out that the hiccup model is a pretty ideal DSL for format strings
and everyone already knows it
ok check out https://github.com/danlentz/clj-format if you're interested. feedback welcome.
what's not intuitive about that?
trollface
cl-format is a strange and wonderful place, but it is at least connected to a https://www.lispworks.com/documentation/HyperSpec/Body/f_format.htm#format. in the fullness of time, maybe this shouldn't have been in core in the first place
its awesome, if a bit long in the tooth. maybe in the early days helped persuade some CL devs. But maybe having in core is good because you don’t have every project trying to build a half-working bespoke version.
ha i’d like to see someone build a clojure.spec for it
maybe that amounts to basically the same thing
this isn’t even sporting with claude. com.github.danlentz/clj-format on the way
oof ok the DSL for this is not pretty
this seems 0% better:
Input: "<~a~{~^ ~a=\"~a\"~}~:[~;/~]>~%"
Output: ["<" :str [:each :stop " " :str "=\"" :str "\""] [:if "/" nil] ">" :nl]
i am now remorseful for going down this path
i dunno. is this useful? ### Left-padded
clojure
(cl-format nil "~10@A" "foo")
(clj-format nil [[:str {:width 10 :pad :left}]] "foo")
;; => " foo"
## Integer Formatting
### Comma-grouped
clojure
(cl-format nil "~:D" 1000000)
(clj-format nil [[:int {:group true}]] 1000000)
;; => "1,000,000"
### Always show sign
clojure
(cl-format nil "~@D" 42)
(clj-format nil [[:int {:sign :always}]] 42)
;; => "+42"
### Zero-padded date
Source: Practical Common Lisp ch. 18
clojure
(cl-format nil "~4,'0D-~2,'0D-~2,'0D" 2005 6 10)
(clj-format nil
[[:int {:width 4 :fill \0}] "-"
[:int {:width 2 :fill \0}] "-"
[:int {:width 2 :fill \0}]]
2005 6 10)
;; => "2005-06-10"
### European-style grouping (dot separator, groups of 4)
clojure
(cl-format nil "~,,'.,4:D" 100000000)
(clj-format nil [[:int {:group-sep \. :group-size 4 :group true}]] 100000000)
;; => "1.0000.0000"
its 100% DSL<->FormatString compatibility at this point. i'm sure there is a lot of AI slop at the moment but wondering if its worth the effort
maybe it would be useful if the language was extended to support ANSI color?
i guess only if you use babashka or something that assumes TTY
https://github.com/danlentz/clj-format/blob/master/doc/examples.md if anyone finds something like this helpful i'll polish it https://github.com/danlentz/clj-format/blob/master/doc/examples.md
this is way better than format strings
actually ill definitely clean this up i would use it 10 times out of 10 over format strings
I have a proxy implementation of Thread which computes some blocking computation, and I am using it interactively during devtime, and running into an issue; specifically, the proxy also implements IDeref to allow effectively getting the returned value of the form used to construct the Thread as a return result from the thread, and this is interacting poorly with the printer.
I can set the .toString implementation to not await, however it appears that this only helps in cases where I call out to str and similar, meanwhile println and the functions used by nrepl (presumably print-method) are calling to the IDeref default implementation for printing the object, which in my case is blocking on the thread to complete.
Is there a way for me to construct a value similar to the method I have been using that will allow print-method to be overridden in a way that allows my code not to block on the thread's completion when using it interactively?
been a bit since i’ve been in this, but have you seen the IPending stuff as well?
this is a way to make sure the printer doesn’t just hang i think
connection=> (print (future (Thread/sleep 2000) (println "done from the thread")))
#future[<pending>]nil
connection=>
done from the thread
which is why this works(time (print (reify clojure.lang.IDeref
(deref [_]
(Thread/sleep 2000)
(println "done from the deref")
:derefed))))
done from the deref
#connection$eval485774$reify__485775[:derefed]
"Elapsed time: 2011.382208 msecs"
vs
(time (print
(let [value (atom nil)]
(reify
clojure.lang.IDeref
(deref [_]
(Thread/sleep 2000)
(println "done from the deref")
(reset! value :derefed)
:derefed)
clojure.lang.IPending
(isRealized [_] (not= nil @value))))))
#connection$eval485780$reify__485781[<pending>]
"Elapsed time: 2.816042 msecs"
nilI had not seen IPending, thanks!