clojure-dev 2026-10-28

Is there a reason why selector returns a function?

Alex Miller (Clojure team) 2026-10-28T11:07:15.165469Z

What else could it return?

Alex Miller (Clojure team) 2026-10-28T11:08:30.191559Z

Are you looking for more of a 1-shot use?

Yes, it could take 2 arguments and return the result. Like select-keys.

((selector destructure-map-literal) data-map)

➕ 1
Alex Miller (Clojure team) 2026-10-28T13:59:19.296389Z

The reason it returns a function instead doing a single job is that the compiler is doing a bunch of work to make the selector, and the common case is to apply it to many pieces of data ala map, so it makes sense to do that once while making the selector function, not repeatedly in a one-shot mechanism

Alex Miller (Clojure team) 2026-10-28T14:00:18.359409Z

Sean, note that destructure-map there must be a literal

Yes, it was just easier to type that on my phone 🙂

Updated it now 🙂

What's the likelihood spec1 will see further development? Will all future focus be on spec2?

Alex Miller (Clojure team) 2026-10-28T19:16:48.089779Z

I would say spec2 will likely not see further development, and we have plans for some work in spec1, probably in 1.14 timeframe

😮 8

Useful to know, thanks. I've been patching a few internals of spec at work for performance/functionality purposes. I was contemplating "just" forking spec to release them, but it seems unlikely to be a good approach. We have some tweaks to the multi-spec and keys generators to make them more override friendly and safer respectively. I can release it as a library I think. That just doesn't work well with specs you don't control, but that doesn't happen to us much.

For me this would be more useful:

(defmacro select
  ([destructure-map-literal]
   (let [sel (gensym)
         miss (gensym)
         as (gensym)
         exc (gensym)
         destructure-map-literal (assoc destructure-map-literal
                                        :select sel
                                        :missing miss
                                        :as as
                                        :excess exc)]
     `(fn [data-map#]
        (let [~destructure-map-literal data-map#]
          {:select ~sel
           :missing ~miss
           :as ~as
           :excess ~exc}))))
  ([destructure-map-literal data-map]
   `((select ~destructure-map-literal) ~data-map)))

(select {:keys! [a b]})               ; a function
((select {:keys! [a b]}) {:a 4 :c 7}) ; a result
(select {:keys! [a b]} {:a 4 :c 7})   ; a result
Not sure if this works in all situations. At least for me it would be more comfortable, because I don't have to pass a directive. I always get everything, including :as. And it has already currying. So I can have a function when I want.

Alex Miller (Clojure team) 2026-10-28T19:49:50.878559Z

well now you have it :)

@hbrng.computer Don't forget to add :all to that. :as does not include any defaults from :or, whereas :all does.

👍🏼 1