Fork me on GitHub

is there a way to retain metadata when transforming it eg via seq?


here is an example


(let [xform-meta :prn-xform]
  (meta (->> '[x y]
             (reduce (fn [form param]
                       (conj form (keyword param) param))
                     ^xform-meta ['prn]))))
=> {:tag :prn-xform}
(let [xform-meta :prn-xform]
  (meta (->> '[x y]
             (reduce (fn [form param]
                       (conj form (keyword param) param))
                     ^xform-meta ['prn])
=> nil


By making your own wrapper for seq that preserves it.

Alex Miller (Clojure team)13:11:37

Generally coll fns preserve metadata, seq fns don’t


Warning that nil won’t work with with-meta, so e.g.

user=> (with-meta (seq []) {:foo 1})
Execution error (NullPointerException) at user/eval144 (REPL:1).


(meta (let [result (->> '[x y]
                        (reduce (fn [form param]
                                  (conj form (keyword param) param))
        (with-meta result {:foo 1})))
=> {:foo 1}


it's a hack but I'll take it


my brain is foggy right now. Is there a function in core that given a predicate f and a collection col (X f coll) would return a pair of sequences, the items in coll satisfying the predicate and the items not satisfying the predicate? It’s kinda split-with but not exactly


ah group-by. duckie


would this be a sensible way to exit a go-loop that is doing work until some rare external event happens?


in general, pass the exit-ch or other signal channels in as arguments, rather than generating them within the process launcher


that way your processes are open to orchestration from the outside


but it sounds like you have the right idea: alt over your input channel & the signal channel


passing in the quit channel allows a single channel to signal to possible multiple processes to stop? without hooking up everyone’s bespoke quit-chan to a central source?



👍 1

@dpsutton that's a good idea, as there will potentially be several "loopys" at the same time


it’s ghadi’s idea. i was just fleshing out the reasoning so it was clear why it was a good idea


“open to orchestration from the outside” can either be vague or borderline meaningless or completely clarifying depending on experience level 🙂


another question I have is how to handle a long blocking op inside the go-loop. so far, i've chosen to wrap it in it's own thread: (<! (thread (long-blocking-op ...)))


in my mind, this should park the go-loop thread & make it available again to the underlying threadpool while otherwise blocking.


but to also facilitate loop exit I now have to wrap this in it's own channel again. this is hard to follow for monkey brains


i guess it's still the same tho; everything inside go-loop gets put on one thread initially


Hi, got a dynamic var tryna call set! on it but Can't set! from non-binding thread :thinking_face:


From Currently, it is an error to attempt to set the root binding of a var using set!, i.e. var assignments are thread-local.

Alex Miller (Clojure team)20:11:46

you can only use set! when a value has already been bound on that thread using binding

Alex Miller (Clojure team)20:11:35

there are some cases you commonly see in your repl like (set! *warn-on-reflection* true) - these are actually not different because they have been bound by your repl using binding around the entire repl


Oh wow okay cool. news to me 😄 ty @alexmiller so maybe try and find a place to set! within a binding ?

Alex Miller (Clojure team)20:11:11

well you could maybe just use binding but hard to say without knowing anything else


Ah right on. Yeah I understand. Cool, will try that. ty


probably a question for @borkdude 😉 I’ve been curious whether anyone has looked into writing Clojure on Truffle, the GraalVM. would there be any benefit? I don’t know enough about compiler theory to make an educated guess. I even noticed that there’s a Lisp-y language already implemented using Truffle:


I've looked into a bit, and other have too


From a performance perspective there are some small gains to be made when it comes to numerical things. But I don't expect major gains in terms of general performance since you're trading JIT with Truffle specialization. Truffle languages do compile to native image as well, so it could be interesting to make a thing like babashka but this is more heavy weight: it doesn't yield small binaries and interaction with other classes outside of the graal context can be more complex. There is also Espresso which is a Truffle bytecode interpreter which can be used to interpret the bytecode that the Clojure compiler produces, but currently it is pretty slow both to start up and performance.


There is a thesis from 2015 on this. Also @U02H98RUV3M is currently doing his thesis on this subject.

👍 1

thanks so much for the informative answer, @borkdude!


:^dynamic atoms ended up being a better solution that work with reset!


sounds horrendous


using more than one atom is often a mistake, using reset! is often a mistake, using :dynamic is often a mistake, combining them all, well 😬

👆 1

lol well let's see if i can provide some context and we can brain storm healthier alternatives...

Alex Miller (Clojure team)21:11:29

yeah, I would question that that's the best option. but if you share more, maybe we could help more