This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-09-17
Channels
- # announcements (47)
- # calva (10)
- # catalyst (5)
- # cider (9)
- # clj-yaml (4)
- # clojure (36)
- # clojure-europe (13)
- # clojure-norway (7)
- # clojure-uk (1)
- # cursive (1)
- # datomic (11)
- # dev-tooling (1)
- # emacs (18)
- # hyperfiddle (36)
- # inf-clojure (21)
- # polylith (3)
- # portal (3)
- # reagent (55)
- # reitit (1)
- # releases (3)
- # shadow-cljs (14)
- # solo-full-stack (1)
- # squint (6)
- # tools-build (12)
Any idea what this would mean for clojure’s performance? https://www.infoworld.com/article/3704272/openjdk-plan-would-add-computed-constants-to-java.html
Seems like it’s solving a problem we mostly don’t have. There’s not a lot of cases of on demand holder or dcl in compiled classes (I’m struggling to think of any), so not sure this would help anything. Var initialization is the important thing and that’s not final so not helped by this (constant dynamic added in 11 is more relevant there)
I'd like to format some generated clojure code. I was thinking of using zprint
but it seems very heavy and pprint
seems good enough:
user=> (pprint '(defmacro when "Evaluates test. If logical true, evaluates body in an implicit do." {:added "1.0"} [test & body] (list (quote if) test (cons (quote do) body))))
(defmacro
when
"Evaluates test. If logical true, evaluates body in an implicit do."
{:added "1.0"}
[test & body]
(list 'if test (cons 'do body)))
nil
user=> (zprint '(defmacro when "Evaluates test. If logical true, evaluates body in an implicit do." {:added "1.0"} [test & body] (list (quote if) test (cons (quote do) body))))
(defmacro when
"Evaluates test. If logical true, evaluates body in an implicit do."
{:added "1.0"}
[test & body]
(list (quote if) test (cons (quote do) body)))
nil
user=>
any advice?(
(:require
[clojure.edn :as edn]
[clojure.pprint :as pp]))
(defn pprint-code
"Pretty print clojure code."
[code-sexp]
(let [process-file (with-out-str
(pp/write
(edn/read-string (str "[" code-sexp "]"))
:dispatch
pp/code-dispatch))]
(subs process-file 1 (- (.length process-file) 1))))
Here's what I have, probably copied it from somewherere "heavy"
user=> (time (require 'clojure.pprint))
"Elapsed time: 0.229852 msecs"
nil
user=> (time (require 'zprint.core))
"Elapsed time: 4912.318311 msecs"
nil
user=>
wth is it doing for 5 seconds?
yes, and is it worth solving here?
Does pprint work reliably with code?
still wondering why zprint is taking so long here
there's some constants that may clip code, see implementation of pprint
(def ^{:private true} write-option-table
{;:array *print-array*
:base 'clojure.pprint/*print-base*,
;;:case *print-case*,
:circle 'clojure.pprint/*print-circle*,
;;:escape *print-escape*,
;;:gensym *print-gensym*,
:length 'clojure.core/*print-length*,
:level 'clojure.core/*print-level*,
:lines 'clojure.pprint/*print-lines*,
:miser-width 'clojure.pprint/*print-miser-width*,
:dispatch 'clojure.pprint/*print-pprint-dispatch*,
:pretty 'clojure.pprint/*print-pretty*,
:radix 'clojure.pprint/*print-radix*,
:readably 'clojure.core/*print-readably*,
:right-margin 'clojure.pprint/*print-right-margin*,
:suppress-namespaces 'clojure.pprint/*print-suppress-namespaces*})
> yes, and is it worth solving here?
Only you can answer that since it depends on your needs.
If pprint
perfectly satisfies them, then using anything else is not worth it.
pprint
prints objects. If the code that you have can be represented in a [usefully] printable way, then pprint
is fine.
E.g. printing #inst "2023"
will turn it into a much longer string.
I'll go with pprint
for now at least. Thanks for the help 🙂
> still wondering why zprint is taking so long here It's just Clojure's compiler compiling all that code. Clojure's source code is quick to require exactly because it's been AOT'ed for you, and the results of that are in the JAR.
@U05H8N9V0HZ If you are really concerned about speed, you might also want to check out https://github.com/brandonbloom/fipp.
Future/threading/chunking question. 🙏 I'm trying to start a future that uses babashka/process to read lines from stdin, process them, and swap! the results to an atom as they come in. That works fine, except for the chunking behavior. I'd like to take the laziness out of this, but can't figure out how. Code in thread.
(def tcpdump-future
(future (with-open [rdr (io/reader (:out tcpdump-stream))]
(binding [*in* rdr]
(while (nil? (:exit tcpdump-stream))
(when-let [line (read-line)]
(swap! tcpdump-matches (comp vec #(remove nil? %) conj) (tcpdump-parse-line line))))))))
It seems to be getting chunked. I've tried a few variations, like loop/recur instead of while, but get the same behavior.
I suppose it is documented in so far as to/reader says it returns a BufferedReder 🙂 Strangely, when I try to replace the atom with a ref, it goes back to chunking.
(dosync (alter tcpdump-matches (comp vec #(remove nil? %) conj) (tcpdump-parse-line line)))
Maybe I need to go read up on core.async.I've looked at the source of http://clojure.java.io and I don't see how setting buffer-size would affect your example
Here's the whole thing. I can run that last deref
over and over, and the ports show up in blocks. Just to test, I had a loop in bash just creating a new connection one a second for tcpdump to see. I must be doing something silly.
(def tcpdump-matches (ref []))
;16:31:18.577179 enp4s0 Out IP 192.168.2.101.58886 > 192.168.2.112.443: tcp 0
(defn tcpdump-parse-line [s]
(let [[ts iface dir _ src _ dest proto _] (split s #" ")
[_ _ _ _ destport] (split dest #"\.") ]
(when (= "Out" dir) (read-string destport))))
(def tcpdump-stream
(process {:err :inherit
:shutdown destroy-tree}
"sudo tcpdump -qn -iany '((tcp[tcpflags] & tcp-syn) != 0 or (ip6 and (ip6[13 + 40] & 2) == 2))'" ))
(def tcpdump-future
(future (with-open [rdr (io/reader (:out tcpdump-stream) :buffer-size 1)]
(binding [*in* rdr]
(while (nil? (:exit tcpdump-stream))
(when-let [line (read-line)]
(dosync (alter tcpdump-matches (comp vec #(remove nil? %) conj) (tcpdump-parse-line line)))))))))
(deref tcpdump-matches)
What I meant is that :buffer-size
isn't really an argument that gets handled in io/reader
I believe