This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-04-08
Channels
- # announcements (8)
- # aws (2)
- # babashka (11)
- # babashka-sci-dev (39)
- # beginners (62)
- # calva (5)
- # cider (1)
- # clj-kondo (50)
- # cljdoc (2)
- # cljs-dev (6)
- # clojure (52)
- # clojure-austin (22)
- # clojure-czech (13)
- # clojure-europe (88)
- # clojure-nl (1)
- # clojure-norway (5)
- # clojure-uk (6)
- # clojuredesign-podcast (13)
- # clojurescript (45)
- # community-development (3)
- # core-typed (31)
- # cursive (12)
- # datahike (2)
- # datalevin (7)
- # datomic (5)
- # events (1)
- # exercism (11)
- # fulcro (27)
- # gratitude (1)
- # holy-lambda (3)
- # hoplon (2)
- # introduce-yourself (2)
- # jobs (1)
- # lambdaisland (3)
- # lsp (110)
- # malli (2)
- # meander (4)
- # music (2)
- # off-topic (50)
- # overtone (1)
- # pathom (13)
- # polylith (26)
- # re-frame (4)
- # releases (2)
- # rewrite-clj (3)
- # ring (12)
- # shadow-cljs (20)
- # specter (4)
- # tools-deps (8)
- # xtdb (40)
Morning!
Good morning!
Working on a Bauhaus-inspired, mildly skeuomorphic aesthetic today for one of my frontends
måning
Trying to be faster, I discovered this little gem https://clojurians.slack.com/archives/C03S1KBA2/p1649401401958449
Say you have two lists (of data retreived from a database) and you want one list. Which is more idomatic to use - concat, conj, merge....?
pros: cheapest concat you can think of, no risk of lazy sequence explosion, etc cons: results aren't cached
You can rely on Ben to provide a performant answer :) There is a great discussion at https://chouser.us/apply-concat/ (Concat https://stuartsierra.com/2015/04/26/clojure-donts-concat if you have more than 2 colls but you don't).
Good morning
concat
works … the into []
is only needed if you want to force the resulting collection to be a vector. No?
I would also choose concat
. Like @raymcdermott, I only use into
when I need to enforce a collection type (or when reifying output from a transducer).
The implementation of the laziness of concat
was problematic, can’t remember if it ever got fixed so I tend to stick with into
I also use concat, but some awareness around the pitfalls may be good: https://stuartsierra.com/2015/04/26/clojure-donts-concat
bah - if concat
has been cancelled, I’m still unreconstructed
In Clojure we're doing quite a lot of work that is probably done by compilers in other more sophisticated languages ;)
(inspired by the latest #defnpodcast with @ben.sless;))
It’s the FFS pattern … for f
’s sake use a transducer
yeah if you still want concat/mapcat in the mix you can do something over the top with transducers (into [] (mapcat identity) [[1] [2] [3]])
[1 2 3]
I'm a bit confused about what I've done wrong here:
(sequence cat [0 1 2] [3 4 5])
Execution error (ArityException) at user/eval15916 (REPL:68).
Wrong number of args (3) passed to: clojure.core/cat/fn--8851
(sequence (mapcat identity) [0 1 2] [3 4 5] [6 7 8])
Execution error (ArityException) at user/eval15920 (REPL:74).
Wrong number of args (3) passed to: clojure.core/identity
so your fn will be called with as many args as you have sequence arguments minus the xf
(sequence (map (fn [x y z] [x y z])) [0 1 2] [3 4 5] [6 7 8])
;; ([0 3 6] [1 4 7] [2 5 8])
sequence map with multiple collections is doing what I expect it to (getting the first then the second then the third from each collection)
ok, this makes sense to me now at least
(sequence (comp
(map (fn [x y z] [x y z]))
cat)
[0 1 2] [3 4 5] [6 7 8])
;; (0 3 6 1 4 7 2 5 8)

Good morning! I’ve recently come to realise that it can be hard to talk about the code in Clojure, as I’m pairing with someone essentially completely new to it. What seems simple to me can be troublesome to explain to them.
I mean, it’s probably the same for all programming languages. Having the same basic structure in most code, that is, (function-call arg1 arg2)
, helps a little bit, but there are so many exceptions to that.
(I’ve “taught” Clojure to people before, but this is a special case)
I am experiencing a bit of the opposite: New developers – and that's the difference: New and unbiased – struggle hard with all the stuff you need to know when learning a classic(?) language like Java or C#. Topics we can skip entirely for Clojure.
Like objects and classes?
I helped my girlfriend when she was doing a course in C#, and she never really understood objects and classes, despite my desperate attempts at coming up with real world analogies 🙂
Yes, Objects and Classes, this
, "By Value" and "By Reference" and based on this: Clone, Shallow Copy, Deep Copy, Shallow Equal, Deep Equal. Value types, reference types, maybe boxing… the list goes on and on.
It’s worse than I recall.
Yeah, I remember being amazed when I learned Clojure that =
just works as you’d expect. That’s incredibly powerful.
With a single =
that is. 🙂
The difference between =
, ==
and ===
(e.g. in JavaScript) is also something to learn and understand.
I try to grow the next generation of developers for over 20 years now. It's really a lot to learn. We – the let's say senior developers – tend to underestimate the sheer amount of knowledge we gained over years.
I bet! It becomes implicit to our work, especially if you never have to explain it to anyone.
There is nothing wrong with concat. Contrary to into or anything with a transducer concat won't allocate a new collection/sequence. It's just a cheap lazy seq wrapper. And you can reduce that cheaply too. Just don't use it to iteratively stack up collections. apply concat
is fine, reduce concat
is not.
Why is apply fine but reduce is not? Because reduce
would nest calls to lazy-seq
ending with one per collection, while apply
has just a single one?
That's actually a good question 🙂 looking at the implementation I'm not sure, they both seem to generate nested lazy-seqs, but somehow the apply
version doesn't exhibit the same stackoverflow behavior
The problem with reduce is that you end up with (concat (concat (concat (concat a) b) c) d)
. Each wrapping is a lazy-seq, which means that realizing that seqs conumes a stackframe. To get to the first element of a
it needs to realize all of the seqs, and thus the stack blows up.
Whereas it seems the apply
version will only realize the outer lazy-seq, until it actually gets to past the first collection, after which the next lazy-seq gets realized. At least that's my guess after starting at the code for a few minutes 😄
I stopped at clojure.lang.IFn#applyTo
😅