Is there a technological criterion to decide when to use for vs. map/filter/etc. ? I can see that it's useful for ergonomics e.g. it can soften the blow if one is used to python, but I am specifically not talking about these dx-adjacent criteria "No" is a valid answer π
The intersection is only when iterating over a single flat collection, that's it.
for allows iterating over nested collections, early breaks, intermediate lets.
map allows iterating over multiple collections at once, plus it can create transducers.
Perfect, exactly the answer I was hoping for, thanks :)
The for output is a bit noisy. One benefit of for and doseq is, they provide cartesian production for nested fields, let me provide an example:
(def data {:foo '[a b c]
:bar '[d e f]})
(for [[k items]
data
item
items]
[k item])
([:foo a] [:foo b] [:foo c] [:bar d] [:bar e] [:bar f])Im my code, I have for expressions with 10-15 levels when traversing nested combos of map/vector/map/map/etc
(def data {:foo '[[1 2 3] [4 5 6] [7 8 9]]
:bar '[[a b c] [d e f] [h i j]]})
(for [[k lists]
data
items
lists
item
items]
[k item])
([:foo 1]
[:foo 2]
[:foo 3]
[:foo 4]
[:foo 5]
[:foo 6]
[:foo 7]
[:foo 8]
[:foo 9]
[:bar a]
[:bar b]
[:bar c]
[:bar d]
[:bar e]
[:bar f]
[:bar h]
[:bar i]
[:bar j])for is sql, build some indices, do a query, get results https://gist.github.com/hiredman/7d17d8d2b58c41ce95bf2db305b0f427
oh wow, for is definitely sql
When mapping over a single collection I some times use map, sometimes for, depending on what's more ergonomic for my use case. I generally don't use any of the clever parts of for because I think it easily results in code that's too dense/hard to understand.
For is like a small programming language. I would always use it where it makes sense and where map does not directly work. Especially when you need the :let or :when behaviour, for is good. For me it is a good way to implement things that by their nature are not functional, but you want to implement them functionally. Map is more for problems, that are already functional by their nature.
Haskellers would disagree, but yeah, I think I get the point^^
@p-himik That's probably the best explanation I've ever read for why to use one over the other. Thank you!
whatβs the early break support in for? I know there are some keyword args for it that are seen very rarely. Is that one of those?
Yep, :while. The docstring has an example.
Oh, I forgot to mention Cartesian products that for allows easily.
one argument I've heard against for is that its macroexpansion is surprisingly verbose. Hard to say when that might have actual significance, but fwiw I use map for something like 99% use cases and grab for mostly when I need cartesian products, like mentioned above. Feels like most uses of for I see in our legacy code would be, dare I say, simpler if represented as map + filter etc, which also opens up the possibility to go for transducers.
We have quite a few for expressions in our code at work that could be plain map but are probably easier to read as (for [x coll] expr) than (map #(expr-of-%) coll) or (map (fn [x] expr) coll)
ISTR having a discussion with @hiredman about this at some point.
For example:
(for [news feed]
(assoc news
:profileid id
:profileuuid uuid
:profileusername profile-name))
compared to
(map #(assoc %
:profileid id
:profileuuid uuid
:profileusername profile-name)
feed)Certainly, if you have (for [x coll] (f x)) then (map f coll) makes more sense.
On my mind map is sequence[s] transformation, while for is more sequence "generation". I find map simpler since the resulting cardinality is more predictable (always the same, or the shortest input one). I use for more like for sequence "generation", where I use some sequences as inputs to drive the generation and the for sub-language to generate something, but the focus is on the output, while for map the focus is on the inputs transformation. Although that is more a semantic thing, so maybe not what you were asking for
Applying for's keyword modifiers to cond is really interesting too https://github.com/Engelberg/better-cond
If anyone is looking for a project: I could really use an ATProto sdk in Clojure - https://atproto.com/sdks (or Java - just something JVM)
should be a great fit for #clojuredart considering how much of atproto tooling is in flutter
It covers enough ground to develop an app on top of at proto, it may not be production grade just yet but that may not be too far. I don't have much time to focus on it these days but feel free to evaluate and submit PRs for any missing pieces or even take over evolution/maintenance.
i think @me1740 has been working on https://github.com/atproto-clj/atproto-clj, which is discussed in #atproto
i can't speak to how far along it is, i just remember him posting about it last year
Well @me1740 - lets count this as me annoying you to continue.