beginners

Ramin Soltanzadeh 2026-04-09T15:53:51.514709Z

I've been using this pattern quite a lot in my code, but it looks really ugly to me:

(some #(when (= (:id %) foo-id) %) foos)
The JavaScript equivalent feels a lot less messy:
foos.find(f => f.id == foo-id)
Is there a more idiomatic way to do this? I could always write my own find, but there's no way that's the idiomatic way to do it. filter + first would be an alternative, but that too seems too verbose.

2026-04-09T15:55:12.394459Z

depends on what you are doing, but I would start by asking if you actually need more than one call to some

2026-04-09T15:56:22.207669Z

e.g. should it be something like (->> ... (map ...) (filter ...) (keep ...) (mapcat ..) (some ...))

Ramin Soltanzadeh 2026-04-09T15:57:34.926289Z

I am simply getting the foo from my vector of foos in various places in my app. The reason foos is a vector and not a map is because order matters. I could denormalize the state and have both but that's way overkill I feel.

2026-04-09T15:58:35.981939Z

🤷 if you have a pattern you wish was more concise write a function

âž• 1
dpsutton 2026-04-09T15:58:37.256879Z

you can also write your own find . i also get annoyed at the some pred return object paradigm. but trivial to make your own

Ramin Soltanzadeh 2026-04-09T16:00:14.052659Z

I just want to emulate what the Clojure elite does rather than make my own home-grown solutions at this point. Surely doing O(n) searches in vectors isn't that uncommon in Clojure even if we all love maps here?

dpsutton 2026-04-09T16:02:45.764719Z

the clojure elite make home grown solutions

dpsutton 2026-04-09T16:03:35.827639Z

but seriously. the find function in js there is a fine one. It doesn’t exactly mash well with some of the sequence operations which might be why it’s not in the core namespace

2026-04-09T16:22:35.525689Z

most of the time, (first (filter ...)) is good enough for me

2026-04-09T16:23:29.142279Z

if i'm in a performance sensitive spot, i'll use (reduce (fn [_ cur] (when (pred cur) (reduced cur))) nil coll) (which is how find-first is implemented)

Ramin Soltanzadeh 2026-04-09T16:33:47.406399Z

How come that's more performant? Does first not leverage the laziness benefits of filter?

2026-04-09T16:35:13.399259Z

reduce has fast path impls for some things

2026-04-09T16:37:29.793539Z

This is one of those sticklers that the Clojure team has where they just refuse to put an O(n) find function in core. There's been many who asked or debated, and so on. The grown up approach is to write your own. I would say, if your list is sorted though, and it's a vector, you can implement a binary search find and get O(logN)

2026-04-09T16:38:04.622009Z

lazy seqs allocate and require additional computation to traverse, while reduce+reduced doesn't, reduce has fast impls for certain sequence types, clojure's laziness can do chunking which will compute additional elements in the seq before selecting the 'first'

2026-04-09T16:39:57.578969Z

It's hard to explain, but the simplest variant is that lazy seqs will wrap the elements in batches of 32. That wrapping/unwrapping adds a little bit of overhead. Reduce iterates the list without this wrapping.

âž• 1
Ramin Soltanzadeh 2026-04-09T16:40:50.857809Z

I see, thanks. I suspect I will decide on going the "overkill" route (which I mistook for denormalization) and manage a map for the lookup and a separate id vector for the ordering. Maybe that's a good pattern to follow in general even for tiny vectors due to separation of concerns.

solf 2026-04-09T20:18:00.486359Z

Since nobody has mentioned it so far, maybe I'm the weird one? I use filter+first but for the pred I like comp + set literal:

(first (filter (comp #{foo-id} :id) foos))

exitsandman 2026-04-09T20:34:48.143049Z

reduce is technically more general than seq traversal too

yuhan 2026-04-10T04:12:30.400119Z

I use this oneliner in lots of places, easy to drop into a util lib or letfn

(defn key= [k v] #(when (= (k %) v) %))
Which lets you write eg.
(some (key= :id "foo-id") foos)
which I find more readable than a lot of the alternatives - and also composes nicely with keep , filter , some-fn etc.

âž• 1