Fork me on GitHub

What's the most idiomatic way to rename a key in a map? I'm working with datomic and I'd like to rename all instances of :db/id to :server/id. Right now I'm throwing a dissoc and then an assoc at it like this.

(defn entity->client [entity]
   (fn [entity]
     (if-let [server-id (:db/id entity)]
       (-> entity
           (dissoc :db/id)
           (assoc :server/id server-id))


I'd go for clojure.core/update-keys or clojure.set/rename-keys.


You'd still have to do the postwalk though, as those won't perform nested updates.


Alternatively, I think you could do the rename as part of a pull query, if a pull query is something you'd be willing to consider.


perfect, rename-keys is exactly what I was looking for! Thank you! I am already using a pull query, I think in this instance I would prefer to keep it generic, but I wasn't aware you could rename keys as part of a pull. That being said, I could picture that coming in handy later, any chance you could give me a quick example of the syntax?


Sorry, on my mobile phone atm so not really. I think might have just what you need though.


Fair enough, thanks for the pointer!


Come to think of it though, I'm inclined to agree that having the rename as a generic postprocessing probably makes more sense.

๐Ÿ‘ 1
Jim Newton10:08:59

hi, can someone help me remember the name of a library I can't seem to find. it was created by a group in Finland (if I recall) research-group or company, it allows you to recognize sequences based on types in sort of a regular-expression-ish way. it was very much like work I've done, and i'm getting ready to try to understand the similarites and differences.

lispyclouds11:08:42 I guess is what you're looking for?

delaguardo11:08:44 does it looks like what you are looking for?


also there is #find-my-lib channel for such questions.

Jim Newton13:08:24

that's the one. thanks.

Jim Newton11:08:33

similar work has been done several times, each time with very different naming.


Hello, i got an i think a code that would fit macro but i have no idea how to make it. So

(sh "aws"
                      "--log-group-name" "sis"
                      "--log-stream-name" log-stream-name
                      "--region" "eu-west-1"
                      "--start-time" start-time
                      "--end-time" end-time
i am using to execute some command and if you've used this command before you get next-token from the response for next batch of logs. So i am using
(sh "aws"
                      "--log-group-name" "sis"
                      "--log-stream-name" log-stream-name
                      "--region" "eu-west-1"
                      "--start-time" start-time
                      "--end-time" end-time
                      "--next-token" next-token)
(the only difference is that there is --next-token as cli argument. Right now i do a recursive calls with
(if next-token
                  (sh "aws"
                      "--log-group-name" "sis"
                      "--log-stream-name" log-stream-name
                      "--region" "eu-west-1"
                      "--start-time" start-time
                      "--end-time" end-time
                      "--next-token" next-token)
                  (sh "aws"
                      "--log-group-name" "sis"
                      "--log-stream-name" log-stream-name
                      "--region" "eu-west-1"
                      "--start-time" start-time
                      "--end-time" end-time
which is not good ๐Ÿ™‚ is there a way so that i can make it clear/nicer/better?


(apply sh "aws" "log" "..." (cond-> [] next-token (conj "--next-token" next-token))) (you can do that for every optional arg). Alternatively, build an option map in clojure and then transform it into a vector for a more generic/flexible code.

๐Ÿ‘ 1

I would probably look at iteration for turning chains of these sorts of calls into a seq

๐Ÿ‘ 1

I think this is basically the motivating example for why ghadi implemented that function


oh yeaa nice i forgot about that one. But apply works great for my example. Thanks!


they meant that you could implement iteration on top of the solution, so that you get a lazy seq of log, which will automatically fetch the next page once you consume the current one

๐Ÿ‘ 1

Potentially odd question but is there any way to evaluate an expression in the repl without it mutating *1 *2 etc?


Those are a function of how a particular REPL works so the short answer is "no" -- but can you explain a bit more about why you want to do this and what you're trying to avoid?


I'm trying to wrap some expressions in cider to attempt to load the malli dev namespace (and instrument it) without parsing the clojure expression string or messing up the *1 etc bindings. So far it's all via cider but I suspect it could be cleaner / work as I wanted if I did a custom nrepl middleware instead


Yeah, you're sort of battling CIDER at that point, unfortunately. You could eval (do (your-expr) *1) which would at least leave *1 with the same value, but *2 would also be that value and *3 would become the old *2 value...


I must admit, I never use those unless I'm doing some really simple stuff manually in the REPL (because I never type into the REPL for "work" stuff -- I only eval code from my editor -- so those shortcut vars are irrelevant there).


Yeah, I don't use anything but *1 and that's really just because cider-inspect-last-result uses it


I've basically landed on conceding *2 and being done with it


Anyway, thank you for the thoughts!

ahungry21:08:31 (also core/server.clj in same repo) - I tried seeing if there was any way to mess with the implementation in there (other than keeping the history yourself) - I couldn't find a good way (like shadowing set! or the *1 binding itself)

๐Ÿ‘€ 1

unfortunately, despite it mentioning in the doc that *1 is the last thing "printed" to the repl, the magic isn't happening in a user definable print function, but the core repl fn itself (although a small update to the source could easily add a condition to set/not set those, if support to evaluate in repl "invisibly" was desired and then approved/added by clojure team)

๐Ÿ‘ 1

Appreciate you sharing the context ๐Ÿ™‚


was a fun dive into some clojure internals ๐Ÿ˜‚


Cider knows how to multiplex repls to the same jvm process (or at least it used to). So you could always try running cider-connect evaling whatever you want and disconnecting again. I would have thought that *1 etc would be specific to each REPL connection ... (I've not tried this, I'm on my phone)

Roee Mazor22:08:56

Hello, Whatโ€™s the Clojure way to transform a to a standard Clojure map? even when it has nested vectors and in it. postwalk seems to fail due to not updating the type of the map when updating it (into {}) - fails to the nesting. motivation: weird behaviors of the the proto map

Ben Sless05:08:14

Write your own postwalk? There are only three cases to consider

๐Ÿ™ 1
Roee Mazor05:08:34

was hoping to avoid that, but will do soon ๐Ÿ™‚

Ben Sless05:08:35

Send it here if you want another pair of eyes. Should be no more than 5 lines ๐Ÿ™‚

Roee Mazor02:09:29

(defn back-to-clojure [i]
    (sequential? i) (map back-to-clojure i)
    (map? i) (reduce-kv #(assoc %1 %2 (back-to-clojure %3)) {} i)
    :else i))
definitely not a masterpiece, but seems to work ๐Ÿ˜„

Ben Sless04:09:43

A. That's great, actually B. Maybe use mapv and not map C. Why are you posting code at 6am local time?

๐Ÿ™ 1
Roee Mazor08:09:34

A. Thx B. Will do C. I just woke up at 1 AM and started working :(

Evan Z23:08:31

I think I have a really straight forward question thatโ€™s driving me a bit nuts. I get

% npx shadow-cljs watch :app
shadow-cljs - config: /x/shadow-cljs.edn
shadow-cljs - server version: 2.19.9 running at 
shadow-cljs - nREPL server started on port 53741
shadow-cljs - watching build :app
[:app] Configuring build.
[:app] Compiling ...
[:app] Build failure:
The required namespace "machine-monitor.core" is not available.
and in src/machine-monitor/core.cljs`` I have
(ns machine-monitor.core
  (:require [helix.core :refer [defnc $]]
            [helix.hooks :as hooks]
            [helix.dom :as d]
            ["react-dom" :as rdom]))
and in shadow-cljs.edn I have

 [[lilactown/helix "0.1.7"]

 {:app { :target     :browser
                     :output-dir "public/scripts/"
                     :asset-path "/scripts/"
                     :modules    {:core {:init-fn machine-monitor.core/run}}}}

I canโ€™t figure out whatโ€™s going on here, what file paths itโ€™s trying, etc.


I'm also a beginner, so I may be off track here. But I noticed that when I create namespaces in Cursive it always names the file with an underscore instead of a dash. You could try moving your directory to src/machine_monitor/core.cljs

Evan Z23:08:11

that did it. How frustrating. Thank you for the help!


Great! Glad it worked :thumbsup: