Fork me on GitHub
#clojure
<
2022-05-14
>
zackteo06:05:39

Not sure if anyone might be able to help with this :o

p-himik06:05:12

I would try removing the auth from the URL and using this instead, in addition to the proxy: https://github.com/dakrone/clj-http/blob/3ff32c3663c1f540076ec6ec16594e282a756c15/README.org#basic-auth

zackteo06:05:06

Oh! Let me try that :)

zackteo06:05:02

Also could I ask what is "Authorization: Basic <some string>" in the Header for? Is there some common standard for another layer of authorization?

p-himik06:05:02

Note however that even if that works, your credentials will be transferred over HTTP in a readable format. In order to use HTTPS, you'd have to add an implementation to this multimethod with some custom class: https://github.com/dakrone/clj-http/blob/5a5288319abab50141b8785625feca8de5a11dfc/src/clj_http/core.clj#L186

zackteo08:05:01

Okay turns out I needed to use :digest-auth and it works!

👍 1
stephenmhopper13:05:27

Do folks use clojure.core/juxt at all? I keep wanting to use it because it results in clean code, but whenever I run benchmarks, it’s noticeably slower than using a well-defined function.

p-himik13:05:50

How and what exactly did you benchmark?

p-himik13:05:53

Just to show that a superficial benchmark isn't in line with your statement:

=> (use 'criterium.core)
nil
=> (def f1 (juxt :a :b))
#'user/f1
=> (def f2 (fn [m] [(:a m) (:b m)]))
#'user/f2
=> (def m {:a 1 :b 2 :c 3 :d 4})
#'user/m
=> (quick-bench (f1 m))
Evaluation count : 35165796 in 6 samples of 5860966 calls.
             Execution time mean : 17.930086 ns
    Execution time std-deviation : 3.351104 ns
   Execution time lower quantile : 15.312267 ns ( 2.5%)
   Execution time upper quantile : 22.549222 ns (97.5%)
                   Overhead used : 1.723916 ns
nil
=> (quick-bench (f2 m))
Evaluation count : 19842672 in 6 samples of 3307112 calls.
             Execution time mean : 24.931762 ns
    Execution time std-deviation : 5.464756 ns
   Execution time lower quantile : 20.791853 ns ( 2.5%)
   Execution time upper quantile : 33.432507 ns (97.5%)
                   Overhead used : 1.723916 ns
nil
=> 

p-himik13:05:50

And to answer your initial question - I personally do use it. :) Mostly when making id->field maps:

(into {}
      (map (juxt :id :some-field))
      coll-of-maps)

2
stephenmhopper13:05:49

> How and what exactly did you benchmark? I used criterium and quick-bench in a similar fashion to your original example. But I’m mapping the function across a collection (similar to your second example) as opposed to just invoking the function once. juxt results: 40.495425 µs fn results: 17.620704 µs This isn’t the first time I’ve seen differences like this though

stephenmhopper13:05:49

I’m tempted to write a macro that basically writes that fn form for me

p-himik13:05:24

Can you provide the actual benchmarking code? Because I can't reproduce that behavior even when using multiple keys with a collection of hash maps.

p-himik13:05:08

And your results aren't only surprising, but suspicious. juxt is basically that macro you're describing, only it's a function and not a macro. It shouldn't result in a perf drop.

stephenmhopper13:05:18

(def xs (mapv (fn [x]
                {:x x
                 :y (inc x)})
          (range 100)))

(quick-bench
  (->> xs
    (map (juxt :x :y))
    (doall)))

(quick-bench
  (->> xs
    (map (fn [m]
           [(:x m) (:y m)]))
    (doall)))

stephenmhopper13:05:41

Results in: Evaluation count : 51444 in 6 samples of 8574 calls. Execution time mean : 8.226674 µs Execution time std-deviation : 3.430178 µs Execution time lower quantile : 4.137545 µs ( 2.5%) Execution time upper quantile : 11.415239 µs (97.5%) Overhead used : 1.984144 ns Evaluation count : 60156 in 6 samples of 10026 calls. Execution time mean : 4.447924 µs Execution time std-deviation : 162.639343 ns Execution time lower quantile : 4.263218 µs ( 2.5%) Execution time upper quantile : 4.620822 µs (97.5%) Overhead used : 1.984144 ns

p-himik13:05:39

Interesting. Can't reproduce it at all on Clojure 1.11.1 running on JVM 11 (that's a lot of 1s, heh).

p-himik13:05:11

Same deal on JDK 17. Consistently, juxt manages to somehow be slightly faster.

p-himik13:05:03

Same exact picture if I use a more thorough bench:

user=> (bench (->> xs (map (juxt :x :y)) (doall)))
Evaluation count : 22241040 in 60 samples of 370684 calls.
             Execution time mean : 2.700029 µs
    Execution time std-deviation : 22.607454 ns
   Execution time lower quantile : 2.680236 µs ( 2.5%)
   Execution time upper quantile : 2.771291 µs (97.5%)
                   Overhead used : 6.026732 ns

Found 6 outliers in 60 samples (10.0000 %)
	low-severe	 6 (10.0000 %)
 Variance from outliers : 1.6389 % Variance is slightly inflated by outliers
nil


user=> (bench (->> xs (map (fn [m] [(:x m) (:y m)])) (doall)))
Evaluation count : 17696700 in 60 samples of 294945 calls.
             Execution time mean : 3.361388 µs
    Execution time std-deviation : 25.461269 ns
   Execution time lower quantile : 3.341838 µs ( 2.5%)
   Execution time upper quantile : 3.437842 µs (97.5%)
                   Overhead used : 6.026732 ns

Found 5 outliers in 60 samples (8.3333 %)
	low-severe	 2 (3.3333 %)
	low-mild	 3 (5.0000 %)
 Variance from outliers : 1.6389 % Variance is slightly inflated by outliers
nil
Unless you're optimizing specifically for your setup - OS, JDK, Clojure version, whatever else might affect this - I wouldn't bother with replacing juxt with anything else.

stephenmhopper13:05:22

Interesting. I’m also on JDK 17, Clojure 1.11.1. I have ZGC GC enabled, so maybe that’s impacting it?

p-himik13:05:47

Just tried with ZGC - same deal. There are also a few versions of JDK 17. I'm also running on Linux, which has its specific kernel versions and settings. There are many variables.

p-himik13:05:40

But suppose that criterium.core/bench is indicative of real-life application performance (it might easily not be at all). Why do you care that juxt is twice as slow as fn? Is it in a really tight spot and most of the time is eaten indeed by fn/`juxt` and not by, say, iteration over a lazy collection created by map?

Ben Sless14:05:14

Are you using leiningen or deps?

p-himik14:05:02

I used deps. But how could it be relevant?

Ben Sless14:05:54

Leiningen turns JIT off by default for a REPL. Any benchmarking done is effectively meaningless in that case

😂 1
p-himik14:05:17

Oh. But... why? Why does Lein do that?

Ben Sless14:05:29

Faster start up time in dev

Ben Sless14:05:46

Bit me several times before I learned the hard way

p-himik14:05:43

Heh, that's funny - on my end, clj with -Xint (which presumably disables JIT) starts slower than without it.

Ben Sless14:05:43

Could be a function of jvm versions and the code running until you enter a REPL

p-himik14:05:05

Yeah, sure. Which makes it even more weird that Lein decided to make it the default, when it can slow things down. Oh well, makes me even more content with deps.

Ben Sless14:05:42

Iirc when I tested this assumption with Lein it held true

👍 1
stephenmhopper20:05:38

> Why do you care that juxt is twice as slow as fn? Is it in a really tight spot and most of the time is eaten indeed by fn/`juxt` and not by, say, iteration over a lazy collection created by map? The example I provided was a small, contrived dataset. My initial, local development use case was on a small subset of the production data. But for both cases, the juxt version takes approximately twice as long as the fn version.

stephenmhopper20:05:50

> Iirc when I tested this assumption with Lein it held true So lein is doing JIT which causes some Clojure forms to be slower than they would otherwise be in a production runtime?

p-himik20:05:58

> But for both cases, the juxt version takes approximately twice as long as the fn version. Right, but if it's 1% or 0.5% from the overall run time - why care? Or is it the choke point? > So lein is doing JIT which Seems like it's the opposite, at least potentially. JIT makes frequently running things faster.

stephenmhopper21:05:46

Yeah, I’m not sure what was happening earlier, but I’m not able to reproduce the issue after starting a new REPL. FWIW, I’m starting my REPL using Cursive in Intellij. This invokes Java which calls clojure.main. I re-ran the previous benchmark and performance is roughly equivalent between the two approaches. However, just for fun, I started up a lein repl and the performance was about 3x slower than java clojure.main. So that’s fun. Anyhow, I guess I’ll happily continue using juxt then. Thanks for the help!

🎉 1
jumar07:05:54

@UK0810AQ2 I don't see an evidence for this claim when running lein repl https://clojurians.slack.com/archives/C03S1KBA2/p1652538774360309?thread_ts=1652533347.157599&amp;cid=C03S1KBA2 > Leiningen turns JIT off by default for a REPL this shows nothing althought I'm running a few lein repls (JDK 8, JDK 11) using leiningen 2.9.8

ps aux | grep -E 'Xint' 
When I try on a minimal deps.edn project and run clj such a project shows up:
{:aliases {:dev {:jvm-opts ["-Xint" "-XX:+PrintCompilation"]}}}
ps aux | grep -E 'Xint'

java -Xint -XX:+PrintCompilation -Dclojure.basis=.cpcache/2459096959.basis -classpath src:/Users/jumar/.m2/repository/org/clojure/clojure/1.10.3/clojure-1.10.3.jar:/Users/jumar/.m2/repository/org/clojure/core.specs.alpha/0.2.56/core.specs.alpha-0.2.56.jar:/Users/jumar/.m2/repository/org/clojure/spec.alpha/0.2.194/spec.alpha-0.2.194.jar clojure.main

jumar07:05:36

I really only see this

java -classpath ... -Dfile.encoding=UTF-8 -Xss8m -Djdk.attach.allowAttachSelf=true -Xmx4g -Dclojure.compile.path=.../target/classes -D...version=0.1.0-SNAPSHOT -Dclojure.debug=false clojure.main -i /private/var/folders/hn/tgwyrdmj1tb5pmmbdkd1g_qc0000gn/T/form-init18004889263590279266.clj
Of those, we specify -Xmx , -Xss and -Djdk.attach.allowAttachSelf explicitly in our project.clj

Ben Sless08:05:59

@U06BE1L6T starting a lein repl from the command line without any project:

-Dfile.encoding=UTF-8
-Dmaven.wagon.http.ssl.easy=false
-Dmaven.wagon.rto=10000
-Xbootclasspath/a:/home/bsless/.lein/self-installs/leiningen-2.9.5-standalone.jar
-Xverify:none
-XX:+TieredCompilation
-XX:TieredStopAtLevel=1
-Dleiningen.input-checksum=
-Dleiningen.original.pwd=/home/bsless
-Dleiningen.script=/home/bsless/.local/bin/lein

Ben Sless08:05:12

If you have :jvm-opts set they can override it

jumar14:05:26

Aha, so it's not that it runs in the interpreter mode but that the tiered compilation stops at the first levep

Ben Sless14:05:26

Iirc level 1 is still interpreted

jumar14:05:58

That's client compiler - I don't understand all the details but it's definitely not the same thing as purely interpreted mode

Ben Sless15:05:19

Right, I was wrong; 0: Interpreted code 1: Simple C1 compiled code 2: Limited C1 compiled code 3: Full C1 compiled code 4: C2 compiled code https://www.oreilly.com/library/view/java-performance-the/9781449363512/ch04.html

jumar09:05:57

I did a very naive experiment with both clj and lein repl and I cannot explain the difference. UPDATE: I probably mixed them up - did another test and it seems it's clj that is significantly faster

clj

user=> (System/getProperty "java.version")
"17.0.2"

user=> (time (dotimes [i 100000000] (* i i)))
"Elapsed time: 1211.51349 msecs"

user=> (time (reduce + (range 100000000)))
"Elapsed time: 2808.390173 msecs"
lein repl

user=> (System/getProperty "java.version")
"17.0.2"

user=> (time (dotimes [i 100000000] (* i i)))
"Elapsed time: 74.241762 msecs"

user=>  (time (reduce + (range 100000000)))
"Elapsed time: 609.163893 msecs"
4999999950000000
So lein repl looks much faster - can somebody see why it's so?

jumar09:05:37

Oh, gosh - now it's the other way around!

jumar09:05:56

Although it's a very artificial benchmark the results look very different.

Ben Sless11:05:04

Here's another example for the performance impact: https://github.com/bsless/clj-fast/issues/19

Shuky Badeer13:05:30

Hi guys, a quick question: When executing

lein jar
It gives the following warning:
Warning: The Main-Class specified does not exist within the jar. It may not be executable as expected. A gen-class directive may be missing in the 
namespace which contains the main method, or the namespace has not been AOT-compiled
Which leads to a question i wanted to ask a while ago: What is gen-class for? Do we always add it in each namespace we create? If not, when do we add it to a namespace? Thanks a lot!

p-himik13:05:00

> What is gen-class for? To create a specifically named class with desired methods. > Do we always add it in each namespace we create? If not, when do we add it to a namespace? No, only when you need such a class. To run a JAR by itself, you either have to rely on the clojure.main class to run your code (https://clojure.org/reference/repl_and_main#_clojure_main_help) or to compile your own class with a proper main Java method. That's where you need gen-class.

Shuky Badeer13:05:03

Oh ok thanks for the info @U2FRKM4TW! On a different topic, I wanted to ask if you know any good tutorial for releasing lein project as clojars package?

p-himik13:05:08

Sorry, no clue. I've stopped using lein years ago.

👍 1
Ben Sless14:05:21

I'm not saying how I did it is the best way, but you can refer to one of my projects as an example https://github.com/bsless/more.async/blob/master/.circleci/config.yml#L50

👍 1
Shuky Badeer04:05:38

@UK0810AQ2 thanks for the tip i'll look into it! @U2FRKM4TW Out of curiosity, what do you use now instead of lein? You mean deps.edn?

Ben Sless05:05:44

Deps is pretty simple to get into. I need to migrate my projects to it (and github actions)

p-himik05:05:20

Yeah, I meant deps.

pinkfrog13:05:22

Hi. Normally what’s the toggle that indicates the code is in dev or prod mode?

p-himik13:05:08

What's the difference between the dev mode and the prod mode?

pinkfrog13:05:28

Do not run some code.

pinkfrog13:05:56

Not specific to app logic. Just disable some debugging stuff.

pinkfrog14:05:04

Similar to goog.DEBUG as in cljs.

pinkfrog14:05:24

I will go add a java property. But dunno if there is already a conventional one.

p-himik14:05:24

I don't think there's a convention for that, given that this ticket is still open: https://clojure.atlassian.net/browse/CLJ-250

pinkfrog14:05:26

I ask this question is, it might be possible that the java compiler could do some optimization like dead code elimination or something else I do not konw.

p-himik14:05:00

There's little sense in DCE on JDK, unless your JAR has really tight size constraints.

p-himik14:05:16

But straight up not executing some code in run time will of course be faster than executing it.

pinkfrog14:05:05

> But straight up not executing some code in run time will of course be faster than executing it. Yes. Not about size. But might help correct branch predication.

p-himik14:05:37

Overall, there are two main ways: • Create a macro that returns its body when some "debug" system property is set and returns nil otherwise • Have a different classpath between prod and dev. E.g. prod version of my.ns/log is a no-op but a dev version of it that's in a different file would be a proper implementation.

practicalli-johnny07:05:50

Not a toggle, but a common way to separate is to put development only code into (comment ,,,) expressions This code is evaluated by the developer and skipped when running the code https://practical.li/clojure/repl-driven-development.html#rich-comment-blocks---living-documentation dev/user.clj is a file that defines a user namespace loaded at REPL startup, include in the classpath when developing but not during production https://practical.li/clojure/clojure-cli/projects/configure-repl-startup.html

denik17:05:06

I’ve been looking for a simple Dockerfile for Clojure + ClojureScript (w/ npm, shadowcljs) but haven’t found one. Any pointers?

p-himik17:05:53

shadow-cljs is just an optional npm i + an entry in your depenencies. Regarding NPM - I ended up just installing it within a CLJ container. And after working with that for a week, I ended up building the bundle on the dev machine and then simply copying it into a plain Clojure container. :D Much less hassle that way - after all, I already use npm + shadow-cljs locally.

👍 1
denik17:05:03

thanks @U2FRKM4TW the former is pretty much what I’m doing

dvingo17:05:35

whatup Dennis! 😎 circle ci has some nice images https://github.com/CircleCI-Public/cimg-clojure#nodejs

👋 1
🙏 1
emccue17:05:37

What are folks' Key-Value store of choice? Looking for something which has easy setup in a cloud and locally

denik17:05:24

can’t recommend #datalevin enough!

❤️ 1
denik17:05:01

have been using it in prod and hobby for 2+ years

emccue17:05:34

how would I set that up in a cloud environment though?

emccue17:05:02

With dynamo i can say "oh yeah i want a db please", but local setup requires docker + nonsense

denik17:05:18

it’s not plug and play for sure

denik17:05:32

but it ships with a server mode that’s quite easy to install

denik17:05:27

FWIW for deployment my dockerfile is < 30 LoC. locally I just use tools.deps

emccue17:05:26

For context I'm thinking of making use of the domain I own - mccue.link - to make a tinyurl service

emccue17:05:48

and make/publish a full tutorial as part of that

emccue17:05:40

conceptually its a good fit for nosql - well defined data model, read heavy, no issues with consistency, etc

denik17:05:03

honestly, datalevin is a great candidate

denik17:05:32

my setup is a little more involved but not too bad

denik17:05:53

and host on digital ocean

emccue17:05:50

considering heroku is on fire this is useful info

emccue17:05:20

what platforms is dokku runnable on?

emccue17:05:54

while correct, i'm more asking about AWS

denik17:05:55

it’s basically self-hosted heroku for docker but it also supports heroku configs using herokuish

emccue17:05:51

I need to read more

denik18:05:03

$0.12*24*30 = $86.4 overpriced

denik18:05:30

I can get away with $20 on digital ocean and it’s quite portable should you need to move to AWS

emccue18:05:52

so okay lets say we have dokku spun up on some machine

emccue18:05:55

step 1 is done

emccue18:05:02

what does dokku do exactly?

emccue18:05:08

does it provision new machines?

denik18:05:04

it’s a PaaS like heroku

denik18:05:19

so it allows you to deploy apps through git remotes

denik18:05:27

manages nginx for you

denik18:05:49

there are plugins for ssl certs so that’s taken care off as well

denik18:05:09

best of all, you can beef up the machine and run multiple apps at once

p-himik18:05:01

@U3JH98J4R What do you mean by "heroku is on fire"?

emccue18:05:09

--------------
| BLANK NODE |
--------------
| v
-----------------
| NODE W/ DOKKU |
-----------------
| v
observe --> -----------------
     |         | NODE W/ DOKKU | -> Build docker image -> Deploy to ...
     |         -----------------
     |
     |
------------
| GIT REPO |
------------

emccue18:05:27

I won't say im good at ascii diagrams, but ive definitely made more than i wanted to

emccue18:05:51

so when it observes your git repo and manages nginix - what machine does that actually happen on

emccue18:05:09

@U2FRKM4TW Their security leak

emccue18:05:34

I have sites on heroku where now they wont auto deploy from github because github doesnt trust heroku anymore

denik18:05:34

the dev experience is very similar to heroku

emccue18:05:02

Also my infra friend sent me this

denik18:05:04

I’m not sure deploying from GH is supported with dokku. I just push to the dokku remote instead

emccue18:05:12

Btw I deleted < PERSONAL PROJECT > from Heroku and closed my account.

Given their numerous security failures recently (looks like their passwords got breached, probably the whole core db was hacked) I don't even remotely trust it. Also the fact that Salesforce owns them lol

I know you're a fan of it, but I'd do the same if I were you tbh

emccue18:05:40

so general impression - on fire

p-himik18:05:04

Seems like they have resolved it though. At least, judging by their own claims. And you can still deploy - although not from GitHub but from Git, by pushing to the Heroku's remote. Not that related, but personally I've switched to a deployment via Docker and the whole experience now is much nicer. > numerous security failures recently Actually, I haven't heard about any other issues before. All I could find was a vulnerability discovered and fixed almost 10 years ago. Are there any links to their other security failures? > Also the fact that Salesforce owns them lol What's wrong with that? Have there been some shady practices coming from Salesforce? I'm genuinely curious about all that as I've been using Heroku myself for quite some time now. But I'm still highly skeptical that a switch to anything else would be worth it. In part because an absence of a security hole report doesn't mean that there isn't a security hole. But there are of course multiple other factors.

emccue18:05:07

the github deploys broke specifically an app i made for a friend where they edited a file in github's editor as their database

emccue18:05:13

ghetto, but got the job done

Kovas Palunas18:05:03

I'm working on a project where I'd like to build my code for different platforms (specifically node.js and google apps script). These platforms expect different things from my code (e.g. some names provided by one are not provided by the other). Therefore, I'd like to somehow use macros to change the way my code is built for each platform. For instance, I'd like to do something like:

((if built-for-node node-func apps-script-func) args)
Then, my final built js artifacts would look like (node-func args) when my code is built for node and (apps-script-func args) when my code is built for apps script. Does something exist like this for clojure? I realize my project is specific to CLJS, but this seems like the kind of thing that would be provided by the base language.

emccue18:05:12

Yep, so depends on how you are buildng your code exactly - but you can make a sort of reader macro-like thing fairly easily

emccue18:05:29

(defmacro env-switch [{:keys [node app-script]}
  (case (System/getenv "SOMETHING")
    "NODE" node
    "APP_SCRIPT" app-script))

(env-switch {:node 3
             :app-script (do (something))})

Kovas Palunas19:05:17

ok cool, this looks like exactly what i'm looking for! I was just trying it out, and I'm still getting some name errors, specifically with this code:

(defn ^:dev/after-load refresh []
  (env-switch
    {:node
      (do (prn "Hot code Remount")
          (dev/start! {:report (pretty/reporter)}))  ; Check all malli function schemas
     :app-script nil}))
the dev/start! macro is only available in the node environment. when I try to compile for app-script, I get this error:
clojure.lang.ExceptionInfo: failed compiling file:/home/kovas/cljs_clamp/src/autojournal/core.cljs {:file #object[java.io.File 0x504862b5 "/home/kovas/cljs_clamp/src/autojournal/core.cljs"], :clojure.error/phase :compilation}
	at cljs.compiler$compile_file$fn__3895.invoke(compiler.cljc:1724)
  ...
	at user$eval1000$iter__1048__1052$fn__1053$fn__1079.invoke(form-init10693697271746039342.clj:1)
	at user$eval1000$iter__1048__1052$fn__1053.invoke(form-init10693697271746039342.clj:1)
  ...
	at clojure.main.main(main.java:40)
Caused by: clojure.lang.ExceptionInfo: null #:clojure.error{:source "/home/kovas/cljs_clamp/src/autojournal/core.cljs", :line 30, :column 11, :phase :macroexpansion, :symbol malli.instrument.cljs/collect!}
	at cljs.analyzer$macroexpand_1_STAR_$fn__2622.invoke(analyzer.cljc:3923)
	... 55 more
Caused by: java.lang.IllegalArgumentException: no conversion to symbol
	at clojure.core$symbol.invokeStatic(core.clj:596)
	... 279 more
Subprocess failed

emccue19:05:32

the macro likely needs to go in a clj file

emccue19:05:50

(self hosted cljs is a thing, but it doesn't sound like thats what you are using)

emccue19:05:08

and the env variable - whatever it is - should be set

Kovas Palunas19:05:37

i'm just hardcoding the env var to "APP-SCRIPT" for now to test

emccue19:05:49

still put the macro in its own clj file

emccue19:05:13

and then require it with refer-macros

emccue19:05:28

[whatever.ns :refer-macros [env-switch]]

emccue19:05:16

idk all the rules and there might be a simpler way - but that will work

Kovas Palunas19:05:30

i'm still getting errors with this code

Kovas Palunas19:05:50

Caused by: clojure.lang.ExceptionInfo: No such namespace: autojournal.env-switching, could not locate autojournal/env_switching.cljs, autojournal/env_switching.cljc, or JavaScript source providing "autojournal.env-switching" (Please check that namespaces with dashes use underscores in the ClojureScript file name) in file /home/kovas/cljs_clamp/src/autojournal/sheets.cljs {:tag :cljs/analysis-error}

emccue19:05:14

it is - i'm a bit confused too

emccue19:05:36

try making it a cljc file and doing

#?(:clj (defmacro env-switch [{:keys [node app-script]}]
  (case "APP_SCRIPT"
    "NODE" node
    "APP_SCRIPT" app-script)))

Kovas Palunas19:05:54

that seemed to compile without errors!

emccue19:05:30

yeah follow up in #clojurescript with people who know more than me to understand why, but that is hopefully a start for you

Kovas Palunas19:05:51

ok sounds good, thanks

Kovas Palunas01:05:16

i did run into one issue with this solution, and that is if i want to do some repl-driven development and execute some code that uses the macro in cljs, it fails because the env-switch name is not available in cljs

Kovas Palunas01:05:51

this suggests to me that a macro here wouldn't really work, because AFAIK all cljs macros are actually run in clj code (and my repl is running cljs)

Kovas Palunas01:05:20

i'm using a plan def now, passing it anonymous functions to execute for :node and :apps-script

Fredy Gadotti12:05:16

Not sure if this is what you are looking for: https://clojure.org/guides/reader_conditionals

emccue12:05:14

@U033YE56GCV both branches use cljs, so there wouldnt be a reader conditional to use

Fredy Gadotti12:05:58

I just noticed after sent the message 😅

denik19:05:40

in tools.deps’ deps.edn using git deps, is there a way to specify a branch and implicitly the latest commit?

pinkfrog23:05:24

I was thinking on the exact question as you’ve posted here. My use case was to track the latest add-lib3 branch of tools.deps.alpha. But checking the docs of deps, seems it is impossible.

👀 1
Alex Miller (Clojure team)19:05:34

no, ether full sha or tag+partial sha

Alex Miller (Clojure team)19:05:54

branches are not stable versions so we don't support those

Alex Miller (Clojure team)19:05:08

if you're doing active dev on something, it's usually better to use a :local/root dep to the project on disk instead

👍 2
dealy66320:05:17

Hi, guys, I’m having a bit of trouble crafting a macro and was hoping someone could offer some pointers. I’m trying to construct a function name in the macro based on params and then executing it. This is the macro (defmacro log-msg [level & messages] `((symbol (str “clojure.tools.logging/” (name ~level))) “\n\t*------->>>” (apply str ~@messages))) (macroexpand ’(su/log-msg :info “foo”)) => ((clojure.core/symbol (clojure.core/str “clojure.tools.logging/” (clojure.core/name :info))) “\n\t*------->>>” (clojure.core/apply clojure.core/str “foo”)) Which looks kinda like what I was intending, but it doesn’t execute the log/info function

lukasz20:05:53

Any reason you can't call clojure.tools.logging/logf directly? eg.

(require '[clojure.tools.logging :as l])

(l/logf :info "foo %s" 1) 

dealy66320:05:06

nope, just me not being aware of logf I guess

dealy66320:05:12

That looks like it will do what I need, wish I asked about this a day or two ago! THanks

caleb.macdonaldblack23:05:51

Is there a better way of doing this?:

(->> [{:id 1 :label "A"} {:id 2 :label "B"}]
     (group-by :id)
     (map (fn [[k [v]]] [k v]))
     (into {}))

=> {1 {:id 1, :label "A"}, 2 {:id 2, :label "B"}}

p-himik23:05:13

(into {} (map (juxt :id identity)) items)

Ben Sless04:05:17

I'm at the point where I want to be able to pass rf to group-by