Fork me on GitHub

Hey everyone 🙂 I was wondering is there an easy way to convert a project that was created with a project.clj file (the project was created with leiningen ) to dep.edn project?


- Hi, recently I am trying to use [react-flow]( in my project and I am really new to cljs 😢. - I am using shadow-cljs in my project and I've install the npm package using npm install react-flow-renderer and put (:require ["react-flow-renderer" :default ReactFlow]) in my core.cljs file - But for the next step I tried to implement this demo in [ React Flow - Overview Example]( page yet didn't know how to start. - In that example page, I know I should probably represent the array of data objects in initial-elements.js using [ js-obj ]( (am I correct ? :rolling_on_the_floor_laughing:) - But next, in the index.js , how could I wrap jsx syntax in cljs, for example , this part:

return (
      snapGrid={[15, 15]}
        nodeStrokeColor={(n) => {
          if ( return;
          if (n.type === 'input') return '#0041d0';
          if (n.type === 'output') return '#ff0072';
          if (n.type === 'default') return '#1a192b';

          return '#eee';
        nodeColor={(n) => {
          if ( return;

          return '#fff';
      <Controls />
      <Background color="#aaa" gap={16} />
- Is there anyone have relevant experience or know how to solve this problem. Thanks in advance! 🍻

Adrian Smith12:05:05

Could probably use reagent to replicate those jsx components using cljs data structures


@UCJCPTW8J Thanks for your kind reply. This is my attempt to translate but it didn't work.


(ReactFlow {:elements elements
             :style graph-styles}))
I believe the problem come from this part but haven't figure out how to solve it.


This is my browser's warnings. Thanks again 🙏


Update: I finally got to solve it by using :> in reagent

Endre Bakken Stovner12:05:19

I am trying to translate the following calls to cljs:

var g = new dagre.graphlib.Graph();
g.setDefaultEdgeLabel(function() { return {}; });
g.setNode("kspacey",    { label: "Kevin Spacey",  width: 144, height: 100 });
My attempt:
(let [g (dagre/graphlib.Graph.)
        _ (g.setGraph (js->clj {}))
        _ (g.setDefaultEdgeLabel (js->clj #(fn [] {})))
        _ g.setNode("kspacey",    { label: "Kevin Spacey",  width: 144, height: 100 });
It fails with

Jakob Durstberger12:05:43

This might be helpful The way to invoke functions is `([func-name] [target] parms) and js->clj us used to convert javascript types into clojure types. You probably want the opposite clj->js I think this should be closer. not sure about the dare/graphlib.Graph though

(let [g (dagre/graphlib.Graph.)
        _ (.setGraph g (clj->js {}))
        _ (.setDefaultEdgeLabel g (fn [] {}))

Endre Bakken Stovner12:05:28

D'oh, I meant the other way around. cljs->js.

Endre Bakken Stovner12:05:33

Thanks for the link.

Jakob Durstberger12:05:01

I’d probably pull the setGraph setDefaultEdgeLabel and setNode into the let body. And you can use -> and thread the calls like so

(-> g
  (.setGraph (clj->js {}))
  (.setDefaultEdgeLabel (fn [] {})))

Endre Bakken Stovner12:05:17

The above worked, thanks!

Jakob Durstberger13:05:14

:thumbsup: no worries 🙂

Endre Bakken Stovner12:05:54

Any tips? Also, is this a question more suited for #clojurescript?

Endre Bakken Stovner12:05:39

Note that I am not trying to use the g object in the hiccup. I am just trying to create it in a let.

Edward Ciafardini12:05:09

Hey there - I am trying to use clojure to separate an integer of variable length (ie 15_5_212518674225 => 1-5-5-2-1-2-5-1-8-6-7-4-2-2-5) into two separate vectors splitting every other number. The int would turn into this after the split: [1 5 1 5 8 7 2 5] and [5 2 2 1 6 4 2] .


(loop [n 155212518674225 xs () ys ()]
  (if (zero? n)
    [xs ys]
    (recur (quot n 10) (cons (rem n 10) ys) xs)))
;; => [(1 5 1 5 8 7 2 5) (5 2 2 1 6 4 2)]

Endre Bakken Stovner12:05:25

Probably not pretty but:

(let [n 155212518674225 n-str (str n)]  [(take-nth 2 n-str) (take-nth 2 (rest n-str))]) ;; [(\1 \5 \1 \5 \8 \7 \2 \5) (\5 \2 \2 \1 \6 \4 \2)]

Jakob Durstberger12:05:45

I think that’s not too bad. My first idea was way worse 😄 You’d probably have to convert the characters back to integers

(let [n 155212518674225
      n-str (str n)
      nums (map #(Integer/valueOf (str %)) n-str)]  
  [(take-nth 2 nums) (take-nth 2 (rest nums))])

👍 3
R.A. Porter14:05:49

Yours are much shorter and simpler than mine, certainly...

(let [n 155212518674225]
    (->> n
         (partition 2 2 [\x])
         (apply map vector)
         (map #(filter #{\0 \1 \2 \3 \4 \5 \6 \7 \8 \9} %))
         (map #(map str %))
         (map #(map (fn [x] (Integer/parseInt x)) %))
         (map vec)))


I'm looking for the equivalent of macrolet for cljs. I found clojure/tools.macro but it only seems to be for clojure not clojurescript.


Hello everyone. How do I use the repl to call a function and use it’s result (an access token) in other functions? In bash I call a login function and save the accessToken to a variable I can use in my other rest calls, what’s the clojure-idiomatic way to do this? I’d like to be able to call (login environment) and then have my following calls use the accessToken from that login result


If I was just messing around in the REPL exploring some api, I'd do (def access-token (login environment)) and use the access-token directly, that would define a var which is a global variable inside that namespace.


When running production code it might be more likely that I had the token as an environment variable and used System/getenv to pull in the variable, possibly in a let block instead to limit it's scope.


Doing something like: export YOUR_TOKEN=topsecret lein repl Will make your token avaliable with (System/getenv "YOUR_TOKEN")


I’ll give it a shot thank you!


@U6T7M9DBR in a production environment if you had to hit another server to get a accessToken, how would you save that variable for use in other rest calls? in this scenario it couldn’t be an env variable because it needs to be fetched


You could use an atom to store it:

(def access-token (atom nil))

(reset! access-token (login environment))

(do-something @access-token)

🙌 3

@U01JYKT6ENL depends - does it need to be renewed under the runtime of the program?


yeah during runtime, it’ll need to be changed/updated depending on the service I now want to hit


Maybe you can stay immutable and not change/update it and make your life easier?


Hm.. I’d like to stay as functional as possible but I want to be able to target different service endpoints on demand. To do that I need the access token for each service-environment. If I were to stay purely functional, I’d have to call login before each request I make which is way too much overhead.

B Treebeard15:05:38

Hello everyone. Why does this snippet

(->> ["A" "B" "C"]
     (map #(println %))
     ((fn [x]
        (println "Done!"))))
produce this output?
I.e., why aren’t A, B and C printed out?

B Treebeard15:05:26

(I’m only looking for some hints so that I can figure out what to Google to understand this behaviour better.)


map is lazy. there's nothing realizing that sequence. the only thing that happens to it is that it's passed to a function, ignored, and "Done!" is printed. So nothing cares about the lazy sequence so it doesn't do any work

B Treebeard15:05:19

Ah, of course! Thanks!

B Treebeard15:05:44

And now…

(->> ["A" "B" "C"]
     (mapv #(println %))
     ((constantly (println "Done!"))))
gives me

B Treebeard15:05:56

Why does the Done! turn up first? :thinking_face:

B Treebeard15:05:15

Presumably it’s something to do with constantly as with ((fn [x] (println "Done!"))) I get the “expected” order in the output.


(constantly (println "Done"!)) will evaluate it's argument, a println which returns nil, and you end up with a function that takes arbitrary input and returns nil

B Treebeard15:05:32

Ah, the println within the constantly is being evaluated when the function that will be returned is being generated. That makes sense, thanks again. 👍


Hi! I'm playing with my own stupid merge sort implementation. And while mesuring performance I noticed a huge difference depending on how I generate numbers. this (repeatedly 1000000 (partial rand-int 1000000)) is 70000x slower than

(def N 1000000)
(repeatedly N (partial rand-int N))


a list comprehension (for [_ (range N)] (rand-int N)) is as slow as the first expression I mentioned


repeatedly returns a lazy sequence. so most likely you are doing 70000x less work and seeing that take that much less time 🙂


or realizing the sequence in some cases and not in others


but the first and second expressions are IDENTICAL except for using predefined constant or not


and the time difference I mentioned applies to clojure.core/sort too, not my function only


what exact forms are you running in the repl?


user=> (time (do (repeatedly N (partial rand-int N)) nil))
"Elapsed time: 0.022722 msecs"
user=> (time (do (repeatedly 1000000 (partial rand-int 1000000)) nil))
"Elapsed time: 0.022792 msecs"
these behave more or less identically for me, and they are very quick as i'm constructing a lazy sequence and not realizing any of it


sorry for bothering you, I can't reproduce the time difference anymore


but it was there


you're most likely seeing the differences in the cached lazy sequence and realizing it.


so sort will realize all of v and then sort it, the other sorts will benefit from having a cached lazy sequence and just do their sorting, rather than computing all of the random numbers and then sorting


but I call time not on combined function but on each sort method separately


and I called it several times changing the let form parameter


and the first function in list - clojure.core/sort produced such different timings


yes. because the first time you access a lazy sequence you have to compute the items in it. subsequent accesses to it use the already computed values


(let [coll (map #(do (Thread/sleep 1000) %) (reverse (range 4)))]
  (time (sort coll))
  (time (sort coll))
  (time (sort coll)))
"Elapsed time: 4014.109926 msecs"
"Elapsed time: 0.008128 msecs"
"Elapsed time: 0.004072 msecs"
(0 1 2 3)


I see now, thanks


I was puzzled because I was changing the source code and evaluating the changed version


does REPL intern such things?


my REPL output changes from yours - I have close times with both subsequent function calls inside the let form


i'm not following


can you post the output?


it's right above yours output


the result of evaluating the let form twice


oh evaluating the left form twice. if you are creating a new lazy seq every time it will be computed every time

👍 3
Geoffrey Gaillard19:05:57

Hello! I'm wondering how to disable clojure.test tests in prod mode. The idiomatic way seems to not include the test folder in the classpath using an alias. But I have a technical constraint that some tests are co-located with the source code. Is there a way to set clojure.test/*load-tests* to false from deps.edn, and ensuring it during AOT compilation?


Are your tests running or you just don’t want to define them?


The best attack will be on the constraint that forces you to put tests and source in the same place


Putting those in separate folders is common practice in clojure and I can't think of another language where that isn't how projects are layed out, maybe C?

Noah Bogart19:05:55

we do it with typescript at my job (thing.ts, thing.test.ts, thing.spec.ts). i hate it, but i don't get to make that decision, lol.


I think Rust has support for same file tests. it's actually quite nice.


sure, you can even do it in clojure, I just mean conventionally most projects don't


yeah. i think it might be a convention in Rust


> However, because unit tests go in the same files as the code


so whatever "technical constraint" there is that is forcing you to co-locate them is likely a misunderstanding or a soft constraint

Geoffrey Gaillard20:05:56

I'd be happy to discuss the technical constraint, it's an interesting one, but since addressing the constraint itself is not an option I'd prefer to make it another thread :)


ok, I'll bite, what is the constraint

Geoffrey Gaillard20:05:11

I agree the constraint is odd, but I don't have control over it. It's a complex design choice with subtle implications. Targeting the constraint seems the best approach at first, but it's just not possible. Tests should not be defined in prod mode. When clojure.test/*load-tests* is false , deftest expands to nil. I just want to find a practical way to set it to false from clojure cli, deps.edn or a similar way. Is there a way to do so?


How are you running your code in production?

Geoffrey Gaillard20:05:34

Using clj with a -main


Any reason you’re not building an uberjar and running it just using java -jar in production?

Geoffrey Gaillard20:05:15

No reason so far, it could perfectly be done with an uberjar.

Geoffrey Gaillard20:05:37

And probably should


you can achieve this with an appropriate -e call right?


i wonder if there would be interest in that being initialized from a jvm property as well

Geoffrey Gaillard20:05:39

If -e has the right precedence it might work, I'll give it a try. How would the jvm property map to *load-tests*? Should I read the property from my -main and set *load-tests* accordingly?


if the dynamic var was initialized to some jvm property otherwise true. No i'm musing about a change i might suggest on ask.clojure

Geoffrey Gaillard20:05:38

Ah! I'm allowed to wrap deftest in a custom macro. So my-deftest could read this property and expand to clojure.test/deftest or nil accordingly. This is another approach I might try.


deftest is already that macro

Geoffrey Gaillard20:05:37

But is decides to expand or not on *load-tests*


If you decide to switch to an uberjar, depstar has a mechanism for a “custom compile” function, so you could provide your own function that invokes compile inside a binding of *load-tests*.


(but I would strongly advise “fixing” the root cause here and arranging for your tests to be in a separate tests folder tree instead of mixed in with your src)

Geoffrey Gaillard20:05:46

This is interesting and seems clean! I'll check depstar. I'll communicate more about the root cause and use case in the near future. @dpsutton @hiredman @nbtheduke and @seancorfield thank you very much for your help and kind advices. I think it unblocked me and I'll be able to move forward.

👍 3

Hello Clojure wizards, please forgive my Clojure baby-talk. Does anyone know how to define a reflexive relation in core.logic? I can define a simple asymmetric relation like this:

(ns logictest.core

(require '[clojure.core.logic.pldb :as pldb])
(require '[clojure.core.logic :as l])
(pldb/db-rel thing t)
(pldb/db-rel relation x y)
(def facts (pldb/db [thing 'a] [thing 'b] [relation 'a 'b]))
When I try to run pldb code to ask the question "what thing is related to 'b"?,
(pldb/with-db facts (l/run* [foo] (relation foo 'b)))
pleasingly, I get back 'a:
but when I run this form to try to ask "what thing is related to 'a,
(pldb/with-db facts (l/run* [foo] (relation foo 'a)))
I get (). But I would like to define relation to be symmetric. Is there a way to do that? I tried to study the code for pldb/db-rel to see if there is a hidden option to make a relation reflexive, but it is a bit beyond me, at my novice level of Clojure.


the way to do that is a conde in your logic program

🙌 3

thank you!!!


(pldb/with-db facts
  (l/run* [foo]
     [(relation foo 'a)]
     [(relation 'a foo)])))


You are the best! This works!

(defn in-symmetric-pair [relation x y] (l/conde [(relation x y)] [(relation y x)]))
(pldb/with-db facts (l/run* [foo] (in-symmetric-pair relation foo 'a)))


Thanks so much.


i have a vector like this [[1 2] [ 6 4]] is there a simple function that can add 1 and 6, and 2 with 4, then generate [7 6]


> (apply map + [[1 2] [ 6 4]])
(7 6)
seems to work

Juλian (he/him)12:05:22

be aware that it returns a list instead of a vector