This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-04-07
Channels
- # announcements (5)
- # asami (17)
- # aws (11)
- # babashka (67)
- # beginners (90)
- # calva (13)
- # cider (17)
- # circleci (6)
- # clj-kondo (3)
- # clojure (53)
- # clojure-europe (12)
- # clojure-france (8)
- # clojure-germany (3)
- # clojure-losangeles (1)
- # clojure-nl (4)
- # clojure-norway (4)
- # clojure-spec (15)
- # clojure-uk (8)
- # clojurescript (41)
- # cursive (7)
- # data-science (6)
- # datomic (8)
- # emacs (10)
- # exercism (1)
- # figwheel-main (2)
- # fulcro (5)
- # graalvm-mobile (97)
- # graphql (1)
- # hyperfiddle (7)
- # inf-clojure (6)
- # interop (4)
- # introduce-yourself (5)
- # jobs (3)
- # kaocha (3)
- # malli (8)
- # meander (8)
- # music (3)
- # nrepl (7)
- # observability (1)
- # off-topic (45)
- # overtone (2)
- # polylith (63)
- # portal (2)
- # re-frame (26)
- # reveal (8)
- # ring (3)
- # shadow-cljs (56)
- # tools-build (5)
- # vim (11)
- # xtdb (8)
I've been reading about print-dup a bit and I'm wondering about their relationship to tagged data literals and printing via pr/prn
and reading back through read-string
.
To have a concrete example - https://github.com/clj-time/clj-time/commit/e5c9cce321e923464a3480ae04e4a43abdd4fc7e so it can be printed and read easily :
(pr-str (org.joda.time.DateTime.))
;;=> "#clj-time/date-time \"2022-04-07T09:35:13.158Z\""
(read-string "#clj-time/date-time \"2022-04-07T09:35:13.158Z\"")
;;=> #clj-time/date-time "2022-04-07T09:35:13.158Z"
However, print-dup is not defined for such objects:
(binding [*print-dup* true] (pr-str (org.joda.time.DateTime.)))
Execution error (IllegalArgumentException) at codescene-cloud-web.sign-up.routes/eval128869 (form-init6498231345551227843.clj:118).
No method in multimethod 'print-dup' for dispatch value: class org.joda.time.DateTime
It seems that https://github.com/clj-time/clj-time/commit/e5c9cce321e923464a3480ae04e4a43abdd4fc7e#diff-24500a457f4ccb44854b3f3c6b9f8f8a1b5259c61b52dc1f61b9e3440eb5cc7aR110-R112https://github.com/clj-time/clj-time/commit/e5c9cce321e923464a3480ae04e4a43abdd4fc7e#diff-24500a457f4ccb44854b3f3c6b9f8f8a1b5259c61b52dc1f61b9e3440eb5cc7aR110-R112.
So I'm wondering what's the case of using one or the other or if I should always try implementing both of them.
And/or if there's a different use case when print-dup might be handy.
Here are some of the resources I looked at:
• Can someone explains the difference between print-method and print-dup once and for all?https://groups.google.com/g/clojure/c/R-9Pwk3HcFk
• Serializing Clojure objects: https://groups.google.com/g/clojure/c/5wRBTPNu8qo [2008 discussion with a couple of comments from Rich Hickey]
• Clojure: Next Steps (Stuart Sierra) https://stuartsierra.com/download/2011-11-10-clojure-next-steps.pdf
• #clj-time/date-time is included in clj-time 0.15.0+https://github.com/clj-time/clj-time/commit/e5c9cce321e923464a3480ae04e4a43abdd4fc7e
• time literals for java.time objects: https://github.com/henryw374/time-literals
Which one would you use (conditional add to map) and why: (merge {:a 1} (when true {:b 2}))
or (into {:a 1} (when true {:b 2}))
I offer a third option:
(cond-> {:a 1}
true (assoc :b 2))
(or merge
instead of assoc
if there's more than one item)My IMHO on the above - merge
is about merging maps, and that's exactly what you want. into
is more generic, and in this particular case you don't benefit from it being that way.
Yeah. just semantically you want to merge two maps together. It has the merge rules you most likely want. And can take arbitrarily many maps which into can’t really do without combining the maps yourself in some manner
I am using datomic cloud. I have a list of eids, I want to pull all of them in one query. How do I do that?
So just how magic is the transducing arity of map
? Like how does it make sense for there to be a transducer that takes multiple arguments per step? Is that something that only map can do? Or can other transducers do that too?
I think reading the source of the transducer arity of map
, filter
and cat
can be illustrative and remove the magic
Yeah, I've read them, and it seems like there's just special magic about using sequence
and map
together.
I don't see any particular reason why map in particular should be so magic, like you could conceivably do like (filter <)
or something followed by a map that takes multiple items.
map and sequence are the only paths into multi-source transducers
was there a particular rationale as to why
(comp (filter <)
(map vector))
couldn't be valid? Or is it just that there was no need/request for it?< doesn't take 1 vector though, it takes N args
there is space here for future work. we haven't tried to do that work.
Well yeah, you would call it like (sequence xf [1 2 3] [4 5 6])
and the output would include each pair because the right one is always greater than the left.
it's the same as the multi-source map transducer more or less
The only thing that seems to be missing here is an allegorical arity of filter
that takes multiple sequences, mostly because it's unclear how you could return the value without wrapping it into a vector or similar.
and perhaps the wiring for allowing multiple sources to be maintained between steps in a transducer
that wiring exists in clojure.lang.TransformerIterator
fair enough
it's really an api problem in applying the transducing function
symmetry or something being missing is not necessarily a strong motivating problem statement
there is also some magic for map entries that probably conflicts with some of this
Yeah, I'm not proposing effort be put into this, I have no problem this solves, I was just curious if there was specific thought put into why filter
can't work similarly, just calling the wrapped reducing function with the extra arguments as with apply
, which would allow it to work with the reducing function produced with map
nicely.
although, despite me not thinking it's worth putting significant effort into, it does seem pretty trivial:
(defn filter*
[pred]
(fn [rf]
(fn
([] (rf))
([result] (rf result))
([result input]
(if (pred input)
(rf result input)
result))
([result input & more]
(if (apply pred input more)
(apply rf result input more)
result)))))
The only change between core filter's transducing arity and this one is the inclusion of an additional arity in the resulting reducing functiontransducers extend the history of deciding not to solve this generically with sequences :)
but at some point something may put pressure on this and then we'll figure it out :)
Was there an article somewhere about different strategies for adapting one protocol to another?
I have some stuff in Clojure Applied about it
there are a bunch of strategies with tradeoffs, the best answer is to not do it at all :)
but probably the next best is to use functions wrapping protocols as an opportunity to adapt/reroute
(defprotocol P1 (m1 [_]))
(defprotocol P2 (m2 [_]))
(defn pm1 [o] ;; wrapper for P1/m1
(if (satisfies? P2 o) ;; detect as needed
(m2 o) ;; adapt as needed
(m1 o))) ;; fall back to P1
and beyond that is using extensions to Object mostly
I’m getting back into dev and Clojure/Script. I’m pretty sure I’m into a lot of ineffective anti-patterns in how I’m approaching developing (and always have been, I’m sure). Basic concepts aside (which I definitely need to keep working on) I don’t think I’m working with the repl correctly. I think a set of eyes would immediately identify some major missteps in how I’m going about things. I am wondering if anyone might be willing to look over my approach via Zoom screenshare for any amount of time (even just 10 minutes would be probably really helpful)… I’m camera shy so would just be my editor and voice, probably, and I don’t expect any more than that from you; you wouldn’t even need to share anything from your side. I seem to be addicted to Emacs and Cider but I’m not at all against trying other editors. I know that other editors are quite capable now… I’m still addicted to the fast Emacs bindings. I mention this because I’m also interested in Emacs workflows if anyone has that set up I’d love to learn. The proper thing is for me to post problems and I try my best, but I think what I might be missing at times is the amazing amount one can get if one is in an office where a coworker can notice ridiculous things I’m doing and point them out. These are things I can’t properly ask about since I’m unaware of them. I’m getting into front and back end dev and would be happy if anyone looked at any part of that. I could and will go to live events but I’m taking care of the ailing folks right now so a bit unable to do that, in case you’re wondering why I’m reaching out here. Mentioning this in #cider too, but open to any editor approach. Feel free to DM me here if this would be something you’d be up for… and thanks for the time reading this!
I always found it interesting watching other people code and see their workflows as well. Which is one reason I started creating some video series with live coding. While most are in Norwegian, one is in english here: http://www.parens-of-the-dead.com Maybe that could be of interest? It shows off some cool Emacs and CIDER/refactor-clj tricks.
https://clojure.org/guides/repl/introduction
this guide is quite good
if you rely too much on cider
stuff and want to know stuff under the hoods, maybe consider using something simpler like inf-clojure
or simply stop using most cider
keybindings
Great help! 🙂 Can’t wait to look at parens-of-the-dead… and also inf-clojure (though Cider has been pretty good so far).
If you are already familiar with Emacs + Cider, or even “addicted” I don't see a reason why you should jump onto something else. It's a very powerful combo. Perhaps I can find 20 minutes next week if you are interested.
I would be more than grateful! And yes, a bit addicted… or maybe it’s just that by the time I actually think “time to code” my fingers have already opened Emacs as a reflex. Which is basically the same thing for most the key bindings I know in there. 🙂
I’m open to other thoughts for getting unstuck, btw!
Hey, I'm trying to bind a Java class to a var, so that I can inject it in a function, but for some reason I'm not having success. What I'm doing:
(def my-class MyClass)
(. my-class someStaticMethod) ;; it doesn't work
(. MyClass someStaticMethod) ;; it works
Anyone can help to shed light on what is the current issue with these attempts?Maybe I'm wrong, but I think the .
special operator doesn't evaluate the first argument normally? Like if the symbol doesn't resolve to a class, it will try to call the symbol someStaticMethod
as if it were an instance method on the type of the value referred to by my-class
, and the type of that is Class
, and there's no instance method someStaticMethod
on Class
.
if you want to call a static method from a class that's held as a value, then you should use the reflection API directly.
Nice, thank you @U5NCUG8NR