Fork me on GitHub

can someone is explain what is happening in the arguments in this function?

#(loop [x %1 y %2] (if (zero? y) (first x) (recur (rest x) (dec y))))


is the first argument getting assigned to x?


i’m pretty sure this is true but can someone point me to the doc, i’m unable to find them.


didn’t see anything about assignment with anon functions


@tiotolstoy . and also you can run (doc loop) to get some info about a function


didn’t see anything about assignment with anon functions


This piece of code from The Clojure Workshop book from Packt, intrigues me.

(clojure.string/replace "Hello World" #"\w" 
   (fn [letter] 
         (println letter) 
It produces the output
"!!!!! !!!!!"
My (object-oriented) mind somehow expected it to produce something like
I was thinking the entire anonymous function and do block would get executed for each character in the string. Could someone please help explain to me what i am missing ?


The do block does execute


I am not sure if you made a mistake in typing the program


(println letter "!")


is different from

(println letter) "!"


I think the code is intentionally that way. What is happening is, the println prints each letter immediately, but since the function returns the "!", the whole string becomes "!!!!! !!!!!" and that return value is printed last.


Thanks very much This makes perfect sense now that I think of it 🙂


If the println is replaced with print, I expect to see different outcomes. Since the ln in println is a newline it probably causes the buffer to flush, thus printing the values immediately.

👍 4

Hello, I got this message “.. warnings can be silenced by the --no-warnings (-n) option” at this command clj -e "(+ 2 3)"` .. but when I would like to add this flag -n'` > warnings still there and I get syntax error


I don't see a --no-warnings option for my clj. Strange. Can you share the full command with -n? Maybe seeing the whole command will give me some clue.


And what is the warning you are getting?


Sorry, since my message.. I closed the terminal. If that is interesting I reproduce. Very strange.. yes.


Yes, I can’t see similar option in the official documentation..


command was what I shared.. after this I got this message use --no-warnings or -n option


maybe coming from rlwrap.. what use clojure tool


Any idea how to solve this, hide the warning messages? (That is rlwrap warning)


if you look at the clj script, it is just a wrapper that calls rlwrap with clojure, you could replace it with your own version that supresses the rlwrap warnings, or uses a custom rlwrap config

👍 4

or even use the rlwrap that clj is designed to use(?)

Mario Martinez 10:05:41

Clojure newbie here. I’ve cloned the and using vim with conjure. I start the app and conjure automatically connects to the repl running at port 3333. When I try to evaluate anything from the source files, (e.g. core.cljs ), it says Namespace not found: conduit.core . What am I doing wrong?


Hey! Glad to hear you're using Conjure 😄 so I think your issue will actually be fixed when I next release the develop branch, but until then, can you try ,ef to reload the file?


I think the namespace isn't loaded yet which gets you into a chicken and egg scenario. You can't define the namespace because it uses it to define it, which is super confusing and weird. ,ef should work though! I've fixed this issue on develop in theory.

Mario Martinez 22:05:25

Hi @U38J3881W, thanks for making Conjure. It’s such a great plugin! Turned out my issues were that: 1. I hadn’t run :ConjureShadowSelect app 2. I wasn’t running the web browser.


I'm very glad to hear that! And yeah, with Shadow, you need to select the build. When you connect you have a plain Clojure REPL, it's the selection that sort of swaps the REPL over to ClojureScript mode and bridges the gap between nodejs or your browser and your REPL.


Feel free to drop any questions or opinions in #conjure, myself or any of the other fine folk in there will definitely help out.

👍 4

Maybe #conjure may be able to help?


hello every one, I'm now confused with 4clojure #67 in my repl,my function works well,but not in website

(fn [n]
  ;; take n from primes
  (let [primes (concat 
                [2 3 5 7]
                 (let [primes-from
                       (fn primes-from [n [f & r]]
                         (if (some #(zero? (rem n %))
                                   (take-while #(<= (* % %) n) primes))
                           (recur (+ n f) r)
                           (lazy-seq (cons n (primes-from (+ n f) r)))))
                       wheel (cycle [2 4 2 4 6 2 6 4 2 4 6 6 2 6  4  2
                                     6 4 6 8 4 2 4 2 4 8 6 4 6 2  4  6
                                     2 6 6 4 2 4 6 2 6 4 2 4 2 10 2 10])]
                   (primes-from 11 wheel))))])
  (into [] (take n primes)))


A case of misplaced parentheses. Your let form closes before the final (into .. ) form.


Could have worked in your repl if eg. you had already defined primes earlier in the repl session.


@kraulain the answer is you are confusing two issues - the do definitely prints out the letters individually - note the println in the do statement; however the "!! is what is back substituted into the "Hello World", i.e each letter is substituted for a "!" correctly. When the function ends the phrase "Hello World" is dumped as "!!!!! !!!!!" in the default repl outputs. Not the " "s on each end vs, the letters (which do not have the " "s. You are using a lein repl or clojure.jar to perform the exercise. This easily confuses beginners (esp me 😉) on the onset. If you use a IDE/Editopr (macs/Spacemacs/ or others) you will then discern the differences in out placement. Simply put the process can only dump the function output in the same console that you are executing the repl - The " " is the indicator

👍 4

Thanks That is true, I am using lein repl


@dev.4openid @kraulain alternatively, you can wrap the call in (with-out-str ...) so whatever is printed inside that block is returned as a string I agree that the difference between printing and returning is important (and they look the same in a repl, unless you make some extra effort)

👍 4
Umar Daraz16:05:44

Hi Fellow clojurians. I m new the clojure/clojurescript and trying to make a form in clojurescript. I have experience in React and used to using excellent library for form handling. basically it manages touched/error state for you. and it made create form much much easier. Any recommendation for form handling library for clojurescript, I m using reagent with re-frame for state management. Thanks


You could just use the JS ecosystem libraries. Reagent has good interop with them. My recommendation would be to throw the forms together yourself first and when you get to a point where things become difficult you can reach for a library. Using this approach, I have still not found a need to go to a third party library. Of course, it depends on the complexity of the form your implementing

Umar Daraz16:05:07

Thanks @U6GNVEWQG I will go that route. It also will help me my journey of learning clojurescript.


My ring server is awesome. But, it logs people out seemingly randomly. I have the {: cookie-attrs {:max-age set to a huge number, what else can I do?


how "random" are the logouts? could it be you are accidentally using an in-memory session (the default) instead of a cookie based store?


Good question. I don't know for sure yet, but that could be it!


a cookie would be preferable to in-memory right?


i'm a little fuzzy on what's actually happening


is there a simple way to switch between the two?


wrap-session takes various arguments that set its behavior


I think by default the cookie maps to an id in an in-memory store, so it won't map to any actual data after a server restart


All the secrets, constantly being revealed...


:store (cookie-store) ?


who stored the cookies in the cookie-store? was it @noisesmith ?


Thank you! @noisesmith 🙏:skin-tone-6:

Eric Ihli21:05:09

I just came across a defn syntax that I've never seen before and don't understand. What are the second vectors below the param vectors and above the body? Looking at, I expected to only see a pre/post map in that position. So what is this thing?

(defn default-tx!
  "Default (Fulcro-2 compatible) transaction submission. The options map can contain any additional options
  ([app tx]
   [::app ::txn/tx => ::txn/id]
   (default-tx! app tx {:optimistic? true}))
  ([{:keys [::runtime-atom] :as app} tx options]
   [:com.fulcrologic.fulcro.application/app ::txn/tx ::txn/options => ::txn/id]
   (txn/schedule-activation! app)
   ;;; ,,,


to me it looks like those vectors would just be weird noops - what is => ?


it looks like the => symbol is used in their assertions macro, maybe defn has been extended to accept assertions where you'd usually see pre/post


are you sure that defn is clojure.core/defn ?


Probably some third party lib on top of Clojure that defines that and parses it. I'd look at top of namespace for a :require with :refer followed by defn for which namespace defn is defined in, as it is likely somewhere outside of clojure.core namespace. If it is clojure.core/defn , then those are simply vectors that get evaluated, return the value of the vector, and that returned vector is discarded when evaluating the next form after it.


i think that's ghostwheel maybe?


I have a reagent atom, is there a shorter way to flip a boolean value in a map within the atom?

(defonce app-state (r/atom {:estate-expanded true
                            :estate-heartbeats {:red 6
                                               :amber 11
                                               :green 10}}))
And to toggle :estate-expanded, I do:
(swap! app-state assoc :estate-expanded (not (:estate-expanded @app-state)))
Is their a shorter way?


(swap! app-state update :estate-expanded not)

😁 12
Eric Ihli21:05:27

Aye. Looks like it's ghostwheel or guardrails and the defn was a refactor from a >defn and the vector between the params and body is just treated as a no-op by clojure.


I’m surprised to learn that Clojure allows for partial implementation of protocols. Is that ever a good practice, and if so when?


When you have a use case where you know you don't need all the functions (methods) and the unused ones are hard to implement?

Alex Miller (Clojure team)23:05:14

It’s usually a good sign you should have used 2 protocols instead of 1 :)


That matches my intuition.

Alex Miller (Clojure team)23:05:43

Hypothesis: The ideal number of functions in an interface or protocol is 1

🤯 4
Alex Miller (Clojure team)23:05:33

Double the amount of thought you put into each subsequent method :)


Would you say that if you know in advance that some implementations will be unable to implement all the methods for one reason or another you should definitely break up the protocol?

Alex Miller (Clojure team)23:05:10

I would. What’s the downside?

Alex Miller (Clojure team)23:05:55

I guess messiness on the part of the implementor

Alex Miller (Clojure team)23:05:22

But I find smaller things lead you to better more precise names


This discussion made me go check the protocols in next.jdbc and that confirmed that most of them are single method.

💯 8

I don't use Clojure in anger but, I tried to read the code, and it was quite difficult TBH. Then I saw you announce next.jdbc, and it's been a delight to follow its development. I often point friends to next.jdbc as an exemplar of good Clojure. I haven't seen other libs that explicitly state that they only do fixation and accretion. Thank you for that!


Thank you! Yeah, I couldn't have written next.jdbc without the experience of eight years of maintaining, starting with its original clojure.contrib.sql codebase.

💯 8