Fork me on GitHub

Hi everyone! I am using emacs cider for Clojurescript. After cider-jack-in-clojurescript, I cannot get any autocompletion for js/ (I would expect some candidates like js/Document). It could be due to this issue ( Does anyone know how to get around this problem?


@haoyuan80s Since that's a pretty specific question, you might get a more useful answer in the #cider and/or #shadow-cljs channels.


(although, reading that issue, I suspect that rolling back to shadow-cljs 2.9.x would solve the problem @haoyuan80s?)


Awesome, thank you!


is there a way to get to ignore leading indentation/whitespace when the input is pretty-printed? I don't have control over the input, not all input is indented, and I get it as a byte[] from a queue initially so I was trying to avoid processing as text to trim prior to parsing if there's some way to get it done by the parser.


Alternatively, I guess I'd like to filter all elements of the form "\n " in the :content of all tags in the parsed map. (various numbers of spaces and arbitrary levels of tag nesting)

Alex Miller (Clojure team)12:07:13

There are some parser options you can set on parse - I think of you set :coalescing to true maybe that does what you want?


thanks, I tried :coalescing true but didn't seem to make a difference. currently using clojure.walk/postwalk to remove indentation strings from the parsed content, but not sure if there's a more idiomatic/performant way to go about it.


current approach looks roughly like

(comment (->> (io/input-stream (rand-from-corpus))
              (clojure.walk/postwalk #(cond (and (string? %) (re-matches #"^\n\s*$" %)) nil ; remove indentation
                                            (seq? %) (keep identity %) ; remove the nils created by removing indentation
                                            :else %))


Is there a shorthand for negation? Now I just do (* -1 x)


Thanks! Right, 1-arity minus negates the argument.


If I have 3 vecs -- x, y, z, what's the idiomatic way to create this new vec? [x1 y1 z1 x2 y2 z2 x3 y3 z3]


Is that interleave?


absolutely. caveat read the docstring about their lengths


ah, its not in the docstring. evaluate (interleave [:a :b] (1 2 3))

Michaël Salihi15:07:26

@dpsutton Little typo here, the missing quote I think (interleave [:a :b] '(1 2 3))


yeah thanks

👍 3
Andrew Doolittle15:07:30

Why does this output nil?

(= nil (if (nil? 0)
          [:a :b :c]))
;; nil


it doesn't it returns true


and nil isn't equal to 0


(= nil (if (nil? 0)
         [:a :b :c]))
yeah i get true

Andrew Doolittle15:07:25

hmm. my REPL outputs nil, which is why I'm confused


what are you confused about?


(nil? 0) is false so (if false [:a :b :c]) returns nil


then (= nil nil) is true, which explains why you are getting true in your repl


and i'm confused why you asked earlier "why does this output nil?"


and then you say your repl says true


I think it's trying to teach you that 0 isn't nil, but doing it in a very weird way


That is telling you that the if expression will equal nil

Andrew Doolittle15:07:47

that was a typo, my REPL outputted nil


it's odd to have = nil and nil? in the same code

Andrew Doolittle15:07:04

that link is the solution branch. I'm working on the fill-in-the-blank branch


I've seen it in a lot of tutorials as just a way to show you what the concept they are teaching will result in.

Andrew Doolittle15:07:40

I played around and it wasn't clear to me until now that nil is the default output if the output for a false condition isn't explicitly stated. (if (boolean? "not a boolean") true) ;; nil (if (boolean? "not a boolean") true false) ;; false


FWIW if treats nil the same as false, and that's what matters most of the time in application logic (very rarely does one explicitly need false)

👍 3
Andrew Doolittle16:07:39

Thanks for the help and clarification everyone.


in many languages 0/nil/false are all the same value, in clojure they are three different values


user=> (boolean 1)
user=> (boolean 0)


@papachan haha, I responded to your snippet before you shared it :D

😄 3

the boolean of all values that are not nil or false is true


this isn't machine language


yeah @noisesmith understand. i was expecting some logical response by casting to boolean 0 or "" But its right.


what is the programmatic way to check if my dependencies have newer versions released?


For Leiningen there's lein-ancient and for deps.edn there's Depot so you can look at the code for those.


I think you could also just use tools.deps.alpha directly and use "RELEASE" as the version in the coordinate... I'm not sure what in that library exposes the actual version resolved tho'


that's a long way to say there isn't one


hah, but it's untrue, Depot is unmaintained but it links


thanks 🙂


(I know he says that in the README but he's been updating the code quite a bit lately -- so that's a bit of a contradiction 🙂 )


Well, let's not argue the semantics of when would we say unmaintained 🙂


in any case, through your pointer, I think I found what I needed, thanks again!


My problem with Depot (since 1.8.4) and with projects like antq is that they assume they can just read your project file and figure out everything from that alone -- which just isn't true.


What do you mean? I just want to know if someone published a newer version of a dependency


We had to stop using Depot because of that (and we wouldn't be able to use antq either) -- which is why I suggested using t.d.a. directly.


Because deps.edn alone doesn't provide the full story, e.g., if you're using aliases to :override-deps from a user-level file (as most folks with monorepos do -- using CLJ_CONFIG to treat a master deps file in the repo as the "user-level" file to combine with the project deps file).


I am coming from javascript. We had a package.json. If it wasn't in a package.json, it wasn't part of the project. I do not intend to change this practice transitioning to clojure


You can ignore the user-level deps.edn file by specifying -Srepro -- and then your project-level file is the whole world.


good to know, thanks


btw and fyi 🙂 I am using your dot-clojure with tiny modifications as my $HOME/.clojure/deps.edn I think you had some tutorial with it on youtube, good stuff


so it had the outdated alias for depot all this time, and I was wondering why my copy paste shows a linting error :D


Ah, yeah. It uses 1.8.4 because that version actually relied on t.d.a. to process dependencies, just like clojure/`clj` would. In the 2.x version, it tries to just read the file (which doesn't work for us).


the castings polymorphisms for nil are a bit wierd and seem arbitrary at first • nil is cast to empty list by cons and conj • nil is treated as a false value by if and all the macros built on it

👍 6

I think the nil/false/0 vs. nil/falsey/() split is about Algol vs. LISP heritage, and most languages used today are descended from Algol


and java shares bits of each side


and clojure takes that and tweaks it some more to be lispier

Alex Miller (Clojure team)16:07:23

"cast" is the wrong word here. it is better to think about it as "how does operation X work polymorphically on nil"

👍 3

thanks, that's a good point

Alex Miller (Clojure team)16:07:08

and "nil is treated as a false value by `if` and all the macros built on it" is really about the definition of logical truth in Clojure, not "treated as false"

Alex Miller (Clojure team)16:07:01

logical truth of an expression = false if value is nil or false, true in all other cases


but even here you use "false" twice


(with two senses, which I wasn't clear enough about distinguishing myself)

Alex Miller (Clojure team)16:07:32

boolean is the function that represents logical truth

Alex Miller (Clojure team)16:07:22

that is a coercion from <any> to true/false


but even that doesn't reflect the behavior of if - they two diverge for instances of "false" that are not the static Boolean/FALSE (which of course doesn't matter as long as you never use the constructor for Boolean)

Alex Miller (Clojure team)16:07:32

well, I'm happy to ignore the case you should never use


hi, is there a way to get the index of an element when using reduce ? I have a vector [[:a 5][:b 6][:x 0][:label "foo"][:y :g][:label "bar"]] And I'm trying to get a map out of labels and locations that would have {"foo" 3 "bar" 5} that I can use as a lookup later. I have

(reduce (fn [a i] (if (= :label (first i))
                      (assoc a :i)
                      a)) foo)
I was hoping i could put something like (reduce (fn [a i ix] ... ) foo (range)))but no 😞


(reduce (fn [a [i ix]] ...) init (map vector (range) coll))


(map-indexed vector coll)


i do the map vector because i always forget which order the index and the item are in for map-indexed


brilliant! thank you 😄


also, often the real solution is to rearrange your data or your algorithm so you don't have to switch between indexed and sequential representations/access


another nice trick is to create a map from position of element to element: (zipmap (range) coll)


user=> (pprint (zipmap (range) [:a :b :c :d :e :f :g :h :i :j :k :l]))
{0 :a,
 7 :h,
 1 :b,
 4 :e,
 6 :g,
 3 :d,
 2 :c,
 11 :l,
 9 :j,
 5 :f,
 10 :k,
 8 :i}

👍 3

thanks for the help and tips guys 🙂


I presume you guys use the repl a lot. Do you run into issues where you end up losing code, or having to scroll way back up a lot, or are you continunally copying and pasting from the repl into your soure file as soon as its right? Or is their a workflow I'm missing here?


As has been mentioned already, using the editor is typically more productive. The most common editors seem to be


I do most work in my editor, only working directly in the repl for raw experimentation (seeing how some API works etc.)


some people swear by never typing directly into the repl


you can copy into the repl from editor, and most editors have shortcuts for sending to a repl


though I prefer integrations that have a true repl session showing all inputs and results


what editor do you use?


that's a personal choice, but I use neovim with the neoterm plugin for sending code to an embedded terminal


any decent code editor should have some feature


emacs (CIDER) and Intellij (Cursive) are quite popular


@qmstuart Try to develop a workflow where you never type into the REPL: use your editor, eval code into the REPL from there. That way you always have all your code saved for future use.


Watch Stu Halloway's presentations "Running With Scissors" and "REPL-Driven Development".


If you don't mind paying for an online course, look at Eric Normand's "REPL-Driven Development" on


oooh, i've bought a couple of videos of, bought his DSLs one and one on re-frame. THey were both really good.


I'll have a look at his repl one


The REPL one is excellent! I loved it!


do you know if he covers intelliJ use in it?


Im finding intellij mouse hover over a command and I get a pop up with the clojure docs to be EXTREMELY useful


What he teaches is applicable to all editors. I don't remember whether/how much he covers IntelliJ.


the documentation story in cursive is extremely nice. control-j and alt-space are just fantastic


I use Atom with Chlorine and I get popups as I type that show vars and functions, with their arglists inline and their docs below the suggestions.


I can also see docs inline in the code with a hot key if I want them onscreen to read while coding.


Example: as I typed (ass I get possible completions and can move the cursor up/down to see arglists and docstrings inline.


Arglists and docstrings show up as I move the cursor down the list:


I get similar, but also get what seems a lot of information that isnt' all that helpful :S


assert-valid-fdecl, dont think i can even call that


I'm surprised it shows private functions. I shouldn't be surprised it shows all the Java stuff, being IntelliJ. You can call private functions, with #' in front of them, BTW.


Hi, I am learning clojure, coming from nodejs/typescript. And I have a question, what is the idiomatic way to implement code below in clojure?

type Balance = {
    amount: number;

interface IPayment {
    sendMoney(balance: Balance): Promise<Balance>;

class PaymentServiceA implements IPayment {
    async sendMoney(balance: Balance) {
         // do something
         return balance;

class PaymentServiceB implements IPayment {
    async sendMoney(balance: Balance) {
        // do something
        return balance;


It kind of depends, there isn't really a single thing promises map to, if you are using clojure and not clojurescript, you might even not do anything at all and just block a thread (you can have many threads for cheap)


As far as polymorphic dispatch, there many choices there as well, multimethods are a decent starting point


Although this looks like protocols would fit here as well


I'd suggest not using protocols


yes, I think my question was more into protocols, how to implement it properly, and make sure the correct data returned by functions sendMoney in my example above


as beginner, coming from a language like typescript you are likely to reach for defining new types too often, and protocols just sort of make that worse


I used to define interfaces and then use them instead of actual classes in usecases


you can use protocols without defining new types now, but for a long time that has not been the case, so most of the documentation etc. you see for protocols will show it used with defining types


and use invertion of control


Yeah, I mean protocols are still quite different from deftype and whatnot


so for example, if sendMoney is actually the same for all payment services, and all paymentservices are just a map with a balance key


I see as well spec, maybe can use it in additional to that


not sure how to combine all together in clojure way


then the polymorphism disapears and you just have a single function that takes any map with the right key


that's true. How you would design this heavily depends on what it's actually supposed to be


Optimally you wouldn't define any protocols and just model it with pure data, I agree


real example is way more complex, here just posted simple one, to have an idea.


in what ways do the implementations for sendMoney differ?


actually it would be different services


like Paypal and DeutscheBank for example


and there could be a lot


then using interface I want to be sure that other services implement it correctly


And the function results in some request over the network with authorisation and everything?


In that case I'd also recommend looking at multimethods first. Chances are this can be done nicely with a multimethod that takes a map representing the service and the money. Something like this:

(defmulti send-money (fn [service amount] (:type service))

(defmethod send-money :paypal ...)
(defmethod send-money :btc ...)
And then you would pass a map like this as the first arg:
{:type :paypal
 :auth {...}
 :whatever-else "is needed"}


is it make sense to use spec in addition to this?


Sure, you could make specs for the service map. I've personally never used spec but depending on the properties all services share and so on it may surely make sense.


I'd be similarly cautious with spec as you would be with protocols and records - they aren't a type system and aren't really something to declare for every function like you would types, they work best as something to validate things that cross system boundaries

💯 3

I think in my case it would be just 1 spec and each implementation should follow it


> @hiredman: I’d suggest not using protocols I’m curious, what is the motivation behind this recommendation?


because this is #beginners and the original asker mentioned coming from typescript, and refuges from typed langues tend to reach for types and type based polymorphism over using simple datastructures like maps, sets, and vectors


that makes sense!


@vasergen then your code isn't polymorphic


not sure what does it means. I just want to implement a special usecase and make sure that schema of input/output between different services the same


so you want polymorphism between services


and want a single spec across the implementations


guess so, like an interface in typescript, where I have defined input/output


I guess I find this strange because one of my first design rules for crossing system boundaries is that I keep the crossing points as simple and narrow as possible. If I'm not crossing a boundary I usually don't need a spec. If I am crossing one I know the precise data that is needed / accepted and do conversions to match on each side.


one thing that might be missing / implicit here is that there's a strong preference in clojure to use a small set of data types (mainly the ones that are built in) with a large number of functions on them


it's alien when coming from a lang like ML or typescript or whatever, but there is a logic to it


yes - this is actually what I want to learn


I think the best clojure book for this is Zach Tellman's Elements of Clojure


but I think there are other resources from common lisp / scheme that others could recommend


thanks ,will take a look. I am reading living clojure right now


eg. I think I picked up the "small number of data types with a large number of functions" idea from SICP, but it's been long enough that I'm not sure


I see this idea a lot in clojure community

Raymond Ko20:07:32

Is this a known ClojureScript limitation? Functions don't get spec validation when they are references at the same scope level of the namespace, or am I doing something wrong?

(defn f [x] (+ 1 x))
(spec/fdef f :args (spec/cat :x int?))
(def m {"foo" f})

;; properly fails spec validation
(f "bar")

;; does not fail spec validation
((get m "foo") "bar")


I would have been surprised if that worked - spec attaches to the metadata, the function itself isn't used to store the metadata (at least on jvm clojure)


Hello. I am trying to do something with spec but I am having toruble when it comes to generators. I have the function and spec

(defn lowest-val
  "Given two keys x and y, returns the key with the lowest associated value in
  m. Returns nil if the values are =."
  [m x y]
  (let [m (select-keys m [x y])]
    (case (compare (-> m first val) (-> m second val))
      -1 (-> m first key)
      0 nil
      1 (-> m second key))))
(s/fdef lowest-val
  :args (s/and (s/cat :m (s/map-of keyword? integer?) :x keyword? :y keyword?)
                #(contains? (:m %) (:x %))
                #(contains? (:m %) (:y %)))
        :ret any?)

(s/exercise-fn `lowest-val)
but when I call exercise-fun I get "Couldn't satisfy such-that predicate after 100 tries.", I assume because the generator does not try to generate keywords for x and y that are in m. Is there a way to do this with a custom generator? I couldn't figure out how to feed the incoming m to with-gen so it knows that keys to generate.

Alex Miller (Clojure team)21:07:42

you can do this with a custom generator using gen/fmap

Alex Miller (Clojure team)21:07:03

first generate a tuple of x, int, y, int, then fmap to make a vector containing a map of that stuff, plus x and y


by wrapping the first s/and with s/with-gen it is possible to generate the whole argument list at once as a vector?


i’ve got an httpkit server running with compojure, and one route leads to a websocket handler


but i’m not sure how to connect to it with an aleph client


so i have (routes (GET "/" [] ws-handler) (GET "/other" [] http-res))


i can do http/get /other no problem, but connecting to / hangs


(with http/websocket-client


you can't do websockets through compojure


got it. could you suggest an alternative?


(httpkit recommended compojure for this case 😞 )


oh, maybe they do something special to make it work


in general compojure's expectation is when it returns the handler is done running


your hanging might be because you are trying to keep running without letting the handler return


yes i’d like to keep the connection open


which is not the same thing as not returning from the handler

Mario C.21:07:26

I got an API that uses timbre for logging. I log various things throughout the request life-cycle. There are some logs that don't include some useful bits of information that I would like to add to the logs. But I am not liking the idea of having to refactor code to pass through information that will ultimately be only be used for logging. Is it possible to set up the logger with a context on a per request basis? So that for each log during that request it logs some basic information associated with that request. There appears to be a function called with-context but not sure if thats exactly what I want


@hiredman sorry could you elaborate?


you have to return from your wshandler, the return value is the result of the as-channel function


if ws-handler is something like (defn ws-handler [req] (while true (println "loop forever")) ...) then you would get a hang


understood, thank you

Ruy Valle22:07:21

Any tips on REPL-driven development in VSCode, preferably using Boot? The appeal to me of Boot is that I can make single-file programs, without needing any directory structure and while specifying my dependencies in my program. I’ve only written very small Clojure programs so far. I’ve tried using Calva but haven’t figured out how to “jack in”. So for now my code and my REPL have not been connected. Conversely, is it possible to specify dependencies within my program and without putting my code in a src directory when using Clojure CLI?


@ruyvalle With Calva you can start your boot repl in some terminal (VS Code's terminal views work fine) and then use Connect instead of Jack in. If you use the project type Generic you should get away without needing any directory structure or anything like that.


(Also have a look at babashka if your Clojure coding is script like.)

Ruy Valle22:07:45

thanks, I’ll give that a shot


@ruyvalle Yes, src is just a convention -- the default value of :paths is ["src"] but you can specify that to include other directories, including "." if you want.


You can also just say clojure script.clj to run a Clojure script in the current directory:

(! 820)-> ls -l
total 8
-rw-r--r--  1 sean  staff  19 Jul  7 16:02 hello.clj
(! 821)-> cat hello.clj 
(println "Hello!")
(! 822)-> clojure hello.clj 
(! 823)-> 


If you're on Linux/macOS, you can also do this:

(! 826)-> cat bin/ 
#!/usr/bin/env clojure -Sdeps {:deps,{clj-time,{:mvn/version,"0.14.2"}}}
(require '[clj-time.core :as t])
(println (str "Time is now " (t/now)))
(println (str "Java version is " (System/getProperty "java.version")))
(! 827)-> bin/ 
Time is now 2020-07-07T23:03:46.105Z
Java version is 14

👏 6
Ruy Valle23:07:09

nice! I didn’t think of putting -Sdeps on the #! line

Ruy Valle23:07:00

I guess I was doing something wrong a few days ago, because I definitely tried clojure script.clj


I have tried writing a custom generator for my earlier spec problem but I am running into the same problem - the generator still cannot meet the spec

(s/def ::key-int-map (s/and (s/map-of keyword? integer?)))

(defn lowest-val
  "Given two keys x and y, returns the key with the lowest associated value in
  m. Returns nil if the values are =."
  [m x y]
  (let [m (select-keys m [x y])]
    (case (compare (-> m first val) (-> m second val))
      -1 (-> m first key)
      0 nil
      1 (-> m second key))))
(s/fdef lowest-val
  :args (s/with-gen (s/and (s/cat :m (s/map-of keyword? integer?) :x keyword? :y keyword?)
                           #(contains? (:m %) (:x %))
                           #(contains? (:m %) (:y %)))
          (fn [] gen/fmap
            #(let [s (seq %)]
               [% (-> s rand-nth key) (-> s rand-nth key)])
            (s/gen ::key-int-map)))
  :ret any?)


I assume I am doing something wrong when it comes to generating the whole argument list together, but I am not sure what 😕


I suspect that code would be easier to work on if the (s/with-gen ...) were pulled into its own def or s/def, similarly with the fn that should return the generator


and as I looked closer to enumerate the things that needed abstracting out, I see this: > (fn [] gen/fmap #(...) (s/gen ...))


that takes no args, discards gen/fmap (doing nothing with it), discards an anonymous function (doing nothing with it) and finally returns the s/gen that didn' twork in the first place


which is surely your bug


yes I think that is it, thank you!


but back to the original point, things like that are easier to see when you don't throw so much nesting into one form


especially anonymous functions that aren't closing over locals, can be moved into proper functions


yeah I have a bad habit of writing big forms and then only pulling them apart once they work


that gen was in a seperate form but I couldn't quite get it wrapped in a function correctly


Strangely I tend to go the other way - I like to “name” every little discrete step in my logic (by putting it in its own fn), then afterwards I look for all the silly little “don’t add any value” fns and move them inline. 😉


But then I have a terrible memory, so have trouble holding large blocks of logic, and how the data changes “shape” through it, in my head.


huh, I generally look for things I've used more than once in a function and tput them into lets, and then find repeated logic across functions and give them their own function


+ split up forms that get a bit too nested

👍 3