Fork me on GitHub
Brandon Olivier01:05:01

I'm working on a re-frame app, and I find myself sprinkling the shape of the app-db all over my reg-sub and reg-event-fx calls. It feels like a smell to me, but I'm not sure if that's just idiomatic for clojure

Brandon Olivier01:05:06

for instance, I have some reg-sub that uses (get-in db [:foo :bar :baz]). Should I be reusing an rf/subscribe call there?


If I recall correctly subscriptions set up state, so it might make things faster. But I wouldn't see it as necessarily "cleaner" from a readability standpoint. Might wanna ask in #re-frame

Brandon Olivier01:05:30

It makes things more difficult in the REPL, but I also don't know if that should be a guiding principle either.


Reusing the subscriptions has the advantage that it will be shared between all the "users" of that (components or other subscriptions), but I agree that it may introduce unneeded ceremony if you're not sharing anything. But who knows what will be shared tomorrow...


If the query target is really shared I think it's safer to capture that, subscription or other wise. The link is visable and updaters should see how the check how query is called. Without the link, no one can. I'm not thinking in reframe though, which is going to be the real arbitrar here.

Daniel Östling05:05:49

For style guide, is this what people use or something else?


That's probably the most widely referenced style guide. I'd suggest looking at some of the linting tools: clj-kondo in particular, but also Eastwood and maybe Kibit.


It's good to read the discussions in the Issues as well, for the style guide @danielostling

Daniel Östling08:05:52

Okay, thanks! :)


Using a recursive spec, the presens of s/and seems to affect the result even though there is just one predicate. I would expect (s/and pred) to be equivalent to pred. Am I missing something?

(s/def ::list (s/+ (s/cat :s symbol? :r (s/? ::list))))
(s/conform ::list '[a [b]]) ;; => :clojure.spec.alpha/invalid
(s/explain-str ::list '[a [b]]) ;; => "([b]) - failed: Extra input in: [1] spec: :user/list\n"

(s/def ::list-and (s/+ (s/cat :s symbol? :r (s/? (s/and ::list-and)))))
(s/conform ::list-and '[a [b]]) ;; => [{:s a, :r [{:s b}]}]

👍 1

I think this is due to s/? being a sequence regex and when you wrap s/and around ::list-and like that, you're essentially saying "this is a sub-spec" and it doesn't get "unrolled" by s/? like a plain spec or predicate would.


It would be like wrapping something in s/spec (which can be used to prevent unrolling of sequence regex forms).


use s/& to prevent that


So (s/? (s/& ::list-and))


i dont follow. s/& yields the same error as the ::list spec

(s/def ::list-amp (s/+ (s/cat :s symbol? :r (s/? (s/& ::list-amp)))))
  (s/explain-str ::list-amp '[a [b]])
  ;; => "([b]) - failed: Extra input in: [1] spec: :user/list-amp\n"


Yes, that's what Alex was saying was equivalent. If you want [b] to be valid, wrap ::list in s/spec (which is what I said would behave like s/and). It wasn't clear which behavior you wanted...


ok, so to do recursion you need something that “marks” the recursive step as a sub-spec? s/spec, s/and etc..


It's not about recursion, it's about whether you want a sequence regex unrolled or not. You haven't said which behavior you want.


Do you want (s/conform ::list '[a [b]]) ;; => :clojure.spec.alpha/invalid or do you want that to conform/succeed?


I want it to conform. Think I have enough to figure it out now. Thanks very much for the help!

Cas Shun13:05:28

I recently saw an interesting string building "trick" of (->> ["Line 1", "Line 2", "Line 3"] (str/join \newline)) (for multiline strings) I'm curious if there's any other similar common idioms for string templating/building.

👍 1

Anyone used Java Lombok annotated class from Clojure? My code does not seem to find the accessors. The class is here: It inherits from AbstractClientApplicationBase which has the Lombok annotations. The code I am trying to run,

(def client
  (-> (PublicClientApplication/builder "<client_id>")
      (.authority "")
The error I am getting: No matching method authority found taking 1 args for class$Builder Decompiled AbstractClientApplicationBase: Decompiled PublicClientApplicaton:


private String authority;
I wouldn't expect this to be available to any clojure code without reflection hacks


oh I see there's also a public authority override lower down - I don't know enough about java to go much further than that


never mind, the AbstractClientApplicationBase is the one that matters here and its authority method is public


Somehow Clojure is not seeing the methods inherited from the abstract base class.


clojure doesn't use the java source, it just goes by the bytecode, so anything java can find, clojure should find too


but I admit I'm not a java or lombok expert


I now don't think it is related to Lombok at all. Lombok did it's thing and generated the Java class.. Maybe I am doing something very silly.


it might help to make this work via very simple java code first then translate?


agreed that lombok shouldn't be making a difference here


Hello, I want to introduce clojure spec to validate API endpoints. The parsed response naturally does not have namespaced keywords. How do I go about validating the data? Should I simply use unqualified keys? Where should I keep my spec?


you can use s/keys with :req-un for unqualified keys


Hey guys, a few days ago I found this tweet and I came up with a solution for clojure

(defn printxy [x]
  (dotimes [n x] (println
                  (apply str
                          (repeat n "X")
                          (repeat (- x n) "Y"))))))
I'm just curious what are other approaches to solve this?


@lukas.block I believe your solution is incomplete, since I believe the question asks for every permutation


:thinking_face: ur right the output has to get reverted



  #(apply str %)
  (clojure.math.combinatorics/selections ["x" "y"] 10))


😝 sort of cheating, but works


(map #(apply str %) (clojure.math.combinatorics/selections [“x” “y”] 4)) => (“xxxx” “xxxy” “xxyx” “xxyy” “xyxx” “xyxy” “xyyx” “xyyy” “yxxx” “yxxy” “yxyx” “yxyy” “yyxx” “yyxy” “yyyx” “yyyy”)


Don’t run it with a high number, your CPU will 🤯 lol


seems like you aren't "testing your programming language's expressiveness" any longer


can't you do this with standard doseq?


@noisesmith not sure… that variable “n” length is the issue I think


yeah - fiddling with it a bit I think we need nested for plus distinct


and I don't think clojure can do this idiomaticallywithout self-call recursion either


This is sort of a bit masking problem… wonder if you can use something with bits to do it… that would be from Java


you can use bits in clojure


right you would built a permutation out of a range of N! numbers from 0 up


then use bit-shift-left of 1 recursively to build the "flag checks" that tell you if a given position is "X" or "Y"


bitwise is the easy way to do this for sure


@raspasov the other trick is we need to use bigints for this as the original post specifies not being limited to some maximum input size


I think we’re beyond the #beginners channel here lol


(import (java.math BigInteger))

(defn xys
  (let [permutations (.shiftLeft BigInteger/ONE n)
        values (->> BigInteger/ZERO
                    (iterate #(.add % BigInteger/ONE))
                    (take permutations))]
    (doseq [bitfield values
            index (range n)]
      (print (if (.testBit bitfield index)
               'X 'Y))
      (when (= index (dec n))


why not, I made hinted versions of xys and an alternate xys-loop that uses recursion instead of collection ops

(import (java.math BigInteger))

(defn xys
  (let [permutations (.shiftLeft BigInteger/ONE n)
        values (->> BigInteger/ZERO
                    (iterate #(.add ^BigInteger % BigInteger/ONE))
                    (take permutations))]
    (doseq [bitfield values
            index (range n)]
      (print (if (.testBit ^BigInteger bitfield index)
               "X" "Y"))
      (when (= index (dec n))

(defn xys-loop
  (let [target (.shiftLeft BigInteger/ONE n)]
    (loop [^BigInteger permutation BigInteger/ZERO]
      (when (< permutation target)
        (loop [index 0]
          (if (= index n)
            (do (print (if (.testBit permutation index)
                         "X" "Y"))
                (recur (inc index)))))
        (recur (.add permutation BigInteger/ONE))))))
the performance is only slightly better without collections
(cmd)user=> (time (binding [*out* (io/writer "/dev/null")] (xys-loop 20)))
"Elapsed time: 10609.954857 msecs"
(cmd)user=> (time (binding [*out* (io/writer "/dev/null")] (xys 20)))
"Elapsed time: 11120.227152 msecs"

👍 1

(the rebinding of *out* factors out some of the overhead time in printing, and avoids needing to do impossible scrollback)