clojure-europe

simongray 2026-05-13T06:35:37.571619Z

good morning

leifericf 2026-05-13T06:38:20.215009Z

Good morning, fellow Cloj_eu_rians!

plexus 2026-05-13T06:58:18.478849Z

goeiemorgen!

Patrick 2026-05-13T07:23:32.846639Z

good morning, code conjuring folks!

2026-05-13T07:28:48.741419Z

ayup chucks

thomas 2026-05-13T07:47:21.485419Z

Mogge

2026-05-13T07:57:31.300789Z

good mornin’

Rachel Westmacott 2026-05-13T08:01:24.443119Z

morny-morn!

gunnar 2026-05-13T08:50:46.886559Z

morning!

dharrigan 2026-05-13T08:55:13.504759Z

Good Morning!

ray 2026-05-13T09:24:12.829859Z

good humane morning

πŸ’― 1
🀸 2
🧘 1
reefersleep 2026-05-13T10:44:40.454539Z

What better excuse for a walk than to pick up a parcel containing my new A whistle 😁🎢

Johannes F. Knauf 2026-05-13T10:48:47.004989Z

Out of curiosity: What's an "A whistle"? "A" like the reference tuning pitch of 440Hz?

reefersleep 2026-05-13T11:03:26.853449Z

I don't know the hertz - tin whistles are an octave or two higher than the reference, I think - but it's tuned to A major, yes 😊

πŸ‘ 1
teodorlu 2026-05-13T10:49:01.631829Z

morning 🎢 just got in from a lovely little walk β›… ☺️

Safe 2026-05-13T11:27:49.348599Z

Morning! I'm waiting for the biblical rain here in Manchester to slow a little before starting my walk 🌧️

🀞 1
πŸ˜‚ 3
Ed 2026-05-13T12:26:17.754059Z

looks like it's got to this side of the pennines ... #weather-watch

😬 1
cgrand 2026-05-13T12:35:49.377149Z

morning

imre 2026-05-13T12:42:07.490649Z

good morning folks

borkdude 2026-05-13T12:59:10.787479Z

morning

lread 2026-05-13T13:52:23.845549Z

Morning!

gunnar 2026-05-13T13:57:47.893329Z

Making some breaking changes

πŸ˜‚ 6
Dimitar Uzunov 2026-05-18T13:48:09.821959Z

ground breaking!!

πŸ˜„ 2
simongray 2026-05-13T14:00:35.336059Z

That looks fun!

plexus 2026-05-13T14:27:35.473469Z

(transient concrete)

reefersleep 2026-05-13T14:42:34.665639Z

(apply concrete)

Ben Sless 2026-05-13T15:34:25.460859Z

You opted for abstraction over concretion

gunnar 2026-05-13T19:45:17.730459Z

Love the puns πŸ˜„ should be something about breaking the build(ing) as well, but brain capacity is gone. All good fun, except for carrying the stuff outside.

plexus 2026-05-13T15:15:22.593249Z

shame that update-vals / update-keys can't take additional arguments

(update-vals m update-in [:foo :bar] inc)
(swap! a update-vals update-in [:foo :bar] inc)
etc

βž• 5
borkdude 2026-05-13T15:25:16.301549Z

worth an ask.clojure perhaps?

plexus 2026-05-13T15:26:55.144609Z

also sharp edge, calling these on a sorted map does not return a sorted map!

😬 1
seancorfield 2026-05-13T15:27:15.919479Z

(update-vals m #(update-in % [:foo :bar] inc)) doesn't seem much pain, compared to trying to change a core function... πŸ˜„

borkdude 2026-05-13T15:27:31.000019Z

true, but update etc do support it :)

seancorfield 2026-05-13T15:28:02.362499Z

(seriously tho', it might be interesting to see how widespread update-(vals|keys) with an anonymous fn like that is out in the wild?)

plexus 2026-05-13T15:29:02.899519Z

I'm mostly curious if it's been considered. My guess is it's intentional, given that core stuff tends to be thought through very thoroughly, but maybe not. I really love the "uniform update model" or whatever they call it, stacking swap!/update/update-in etc

yannvahalewyn 2026-05-13T15:30:36.958839Z

@seancorfield anecdotaly, I count about 5-6 of these in a ~40k lines codebase

seancorfield 2026-05-13T15:39:14.391279Z

Okay, made me curious about our work codebase: we have 20 calls to update-vals or update-keys across 150k lines. The ones that have anon fns are all more complex than the extra args would support. So this enhancement wouldn't help us 😞

seancorfield 2026-05-13T15:40:36.845549Z

@borkdude When I searched, this code in taoensso/encore hooks showed up:

(let [{:keys [src alias attrs body]} (hooks/sexpr alias-node)
                  ;; workaround as can't seem to (get) using a token-node
                  ;; and there's no update-keys (yet) in sci apparently
                  [& {:as node-as-map}] (:children alias-node)
                  {:keys [attrs body]} (zipmap (map hooks/sexpr (keys node-as-map))
                                               (vals node-as-map))]
              (hooks/list-node
               [(hooks/token-node 'taoensso.encore/defalias)
                (or alias src) (hooks/token-node src) attrs body]))
Is that still true of sci?

borkdude 2026-05-13T15:54:41.890979Z

it is in bb but not in SCI by default since it supports older versions of clojure but maybe I should give up on that and always support the newest

borkdude 2026-05-13T15:54:49.811329Z

there was a SCI issue about this today

seancorfield 2026-05-13T16:01:19.879799Z

Seems like it could still support older versions of Clojure but have update-keys and update-vals? Or are you concerned about code that defines their own, prior to... 1.11?

borkdude 2026-05-13T16:12:17.212169Z

I don't intend to copy/paste too many functions, I use most directly from the host clojure

seancorfield 2026-05-13T16:13:58.224389Z

I guess I don't understand enough about sci to understand that comment πŸ™‚

borkdude 2026-05-13T16:24:24.005389Z

that's basically one giant hash-map with symbols to copied functions from clojure

imre 2026-05-13T16:53:11.020919Z

> also sharp edge, calling these on a sorted map does not return a sorted map! not even update-vals?

seancorfield 2026-05-13T17:01:40.768669Z

user=> (apply sorted-map (range 100))
{0 1, 2 3, 4 5, 6 7, 8 9, 10 11, 12 13, 14 15, 16 17, 18 19, 20 21, 22 23, 24 25, 26 27, 28 29, 30 31, 32 33, 34 35, 36 37, 38 39, 40 41, 42 43, 44 45, 46 47, 48 49, 50 51, 52 53, 54 55, 56 57, 58 59, 60 61, 62 63, 64 65, 66 67, 68 69, 70 71, 72 73, 74 75, 76 77, 78 79, 80 81, 82 83, 84 85, 86 87, 88 89, 90 91, 92 93, 94 95, 96 97, 98 99}
user=> (update-vals *1 inc)
{0 2, 70 72, 62 64, 74 76, 86 88, 20 22, 72 74, 58 60, 60 62, 24 26, 88 90, 46 48, 4 6, 54 56, 92 94, 48 50, 50 52, 32 34, 40 42, 56 58, 22 24, 90 92, 36 38, 44 46, 6 8, 28 30, 64 66, 34 36, 12 14, 2 4, 66 68, 82 84, 76 78, 68 70, 14 16, 78 80, 26 28, 16 18, 38 40, 98 100, 30 32, 96 98, 10 12, 18 20, 52 54, 42 44, 80 82, 94 96, 8 10, 84 86}
user=> (type *1)
clojure.lang.PersistentHashMap

seancorfield 2026-05-13T17:02:39.936299Z

(same with update-keys, which should be no surprise)

seancorfield 2026-05-13T17:03:08.407599Z

Source:

(with-meta
    (persistent!
     (reduce-kv (fn [acc k v] (assoc! acc k (f v)))
                (if (instance? clojure.lang.IEditableCollection m)
                  (transient m)
                  (transient {}))
                m))
    (meta m)))

seancorfield 2026-05-13T17:03:28.922829Z

I think {} would need to be (empty m) for that to be retained?

imre 2026-05-13T17:04:04.586309Z

I thought they had used empty in update vals

imre 2026-05-13T17:04:21.869599Z

I recall asking Alex about it years ago

imre 2026-05-13T17:04:34.865769Z

Interesting

seancorfield 2026-05-13T17:04:36.164989Z

Maybe there is no transient sorted map?

imre 2026-05-13T17:05:49.024679Z

What does (into (sorted-map) (range ...)) return

seancorfield 2026-05-13T17:05:50.129769Z

Seems likely:

user=> (apply sorted-map (range 100))
{0 1, 2 3, 4 5, 6 7, 8 9, 10 11, 12 13, 14 15, 16 17, 18 19, 20 21, 22 23, 24 25, 26 27, 28 29, 30 31, 32 33, 34 35, 36 37, 38 39, 40 41, 42 43, 44 45, 46 47, 48 49, 50 51, 52 53, 54 55, 56 57, 58 59, 60 61, 62 63, 64 65, 66 67, 68 69, 70 71, 72 73, 74 75, 76 77, 78 79, 80 81, 82 83, 84 85, 86 87, 88 89, 90 91, 92 93, 94 95, 96 97, 98 99}
user=> (transient *1)
Expected IEditableCollection, but was given PersistentTreeMap, at user/eval18728 (REPL:1) - runtime error (unexpected type).
user=> (apply sorted-map (range 100))
{0 1, 2 3, 4 5, 6 7, 8 9, 10 11, 12 13, 14 15, 16 17, 18 19, 20 21, 22 23, 24 25, 26 27, 28 29, 30 31, 32 33, 34 35, 36 37, 38 39, 40 41, 42 43, 44 45, 46 47, 48 49, 50 51, 52 53, 54 55, 56 57, 58 59, 60 61, 62 63, 64 65, 66 67, 68 69, 70 71, 72 73, 74 75, 76 77, 78 79, 80 81, 82 83, 84 85, 86 87, 88 89, 90 91, 92 93, 94 95, 96 97, 98 99}
user=> (transient (empty *1))
Expected IEditableCollection, but was given PersistentTreeMap, at user/eval18732 (REPL:1) - runtime error (unexpected type).
(error messages courtesy of rephrase πŸ™‚ )

imre 2026-05-13T17:05:53.919029Z

Not at the computer

imre 2026-05-13T17:06:15.297399Z

Hah

seancorfield 2026-05-13T17:07:58.016059Z

user=> (into (sorted-map) (partitionv 2 (range 50)))
{0 1, 2 3, 4 5, 6 7, 8 9, 10 11, 12 13, 14 15, 16 17, 18 19, 20 21, 22 23, 24 25, 26 27, 28 29, 30 31, 32 33, 34 35, 36 37, 38 39, 40 41, 42 43, 44 45, 46 47, 48 49}
user=> (type *1)
clojure.lang.PersistentTreeMap

imre 2026-05-13T20:25:15.092749Z

ah hmm

imre 2026-05-13T20:25:38.812969Z

so sorted-map and sorted-set aren't IEditableCollections

imre 2026-05-13T20:25:53.719389Z

Interesting

imre 2026-05-13T20:26:30.210879Z

found my https://clojurians.slack.com/archives/C06MAR553/p1631697606301100?thread_ts=1631652109.282200&cid=C06MAR553, it's only tangentially related as it's about update-keys

seancorfield 2026-05-13T20:29:21.748999Z

The impl of update-keys and update-vals are subtly different: update-keys always uses (transient {}) whereas update-vals will use (transient m) if it is editable.

imre 2026-05-13T20:37:25.904669Z

yeah, that's why it's tangential

imre 2026-05-13T20:38:16.861299Z

but them sorted collections not being editable makes me want to reconsider using them as first args to into vs sorting after into {}

seancorfield 2026-05-13T20:46:17.561609Z

Apparently, we don't use sorted-set or sorted-map anywhere in our code at work...

2026-05-13T21:48:04.770519Z

I made an https://ask.clojure.org/index.php/12107/update-keys-and-update-vals-missing-the-args-from-update?show=12107#q12107 a while back, I think it's not a big deal, but it bugs me a bit that I can't chain them like the other update fns in core. Consider voting for it if you agree πŸ™‚

yannvahalewyn 2026-05-13T22:16:19.074929Z

It also bugs me. However, looking at our codebase of the 5 update-* with anon functions, only 2 would've benefitted from this arity. In @seancorfield’s codebase apparently it was 0 so I personally don't feel the urgency 🫠

seancorfield 2026-05-13T22:32:05.177629Z

I voted for the Ask years ago, but I also upvoted Alex's answer about why they are not variadic πŸ™‚

yannvahalewyn 2026-05-13T22:34:19.756309Z

Β―\(ツ)/Β―

neumann 2026-05-14T00:53:44.872709Z

Please do feel free to add more upvotes on the question in ask or more comments with specific use cases.

neumann 2026-05-14T00:55:43.009229Z

Both of those help raise the priority.

plexus 2026-05-14T08:18:08.782459Z

sorted-map and sorted-set are great, I've really come to appreciate them on our current project. Together with subseq/rsubseq they become powerful in-memory indexes that you can scan from any point in either direction. Great for time series data for instance and for any kind of range queries. The ones in core don't have transients, there's a library that does have them and is otherwise compatible https://github.com/clojure/data.avl

imre 2026-05-14T09:29:29.542909Z

Thanks @plexus, I'm starring that lib

imre 2026-05-14T09:29:55.415239Z

I wonder why core sorted map and set don't support transients though