Fork me on GitHub
Souler T08:05:23

- 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

Souler T13:05:13

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

Souler T13:05:19

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

Souler T13:05:11

This is my browser's warnings. Thanks again 🙏

Souler T14:05:41

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))])

👍 1
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.

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

👍 1

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?


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


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


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?


Using clj with a -main


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


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


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


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


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


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)


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.

👍 1

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

🙌 1

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.