Fork me on GitHub
Lucas Barbosa01:05:55

Is there a convention for naming boolean values?

Lucas Barbosa01:05:32

We name predicates with an ending question mark, but what about a key in a hash-map that is supposed to hold a boolean value?


There was a thread on reddit recently talking about this. Go read those comments for a good back and forth. I’d give you a link but I’m on mobile

Lucas Barbosa01:05:43

I'll look for it, thanks!


@lvbarbosa I used to be in the camp of "slap ? on anything that is/returns a Boolean!" but now I'm strictly ? for (`Boolean`) predicates.

❤️ 4

For me, a keyword ending in a question mark just looks really odd because it has "punctuation" at both the beginning and the end :...? which I just don't like from a readability p.o.v. For local bindings, I think an argument can sometimes be made for ? but I think if you need to call out an intermediate value as a Boolean, you probably want to refactor so that you don't need to create a local. For arguments, it's generally good advice in any language to limit the number of Boolean arguments because (foo 42 true false true) is a pretty meaningless piece of code.

❤️ 4

Is spec alpha open in the sense that it allows more data to be exist in the data to be validated without resulting in an error?


Yes. He talks about why he's against closed systems towards the end of this talk (can't find the direct timestamp):


What is the most idiomatic way to do an update if the key exists. I.e. where:

(-> {:a 1 :b 2} (update-if-exists :c inc))
;; {:a 1 :b 2}
There are some answers here: but if feels like there ought to be something out of the box. Is cond-> what I’m looking for?
(def m {:a 1 :b 2})

(cond-> m
   (:c m) (update :c inc))


if a key does not exist, update will pass nil to the update function


right, so in this case, inc will throw an exception which I’d have to handle? But in fact I want to skip inc entirely if the key does not exist

Ivan Koz11:05:44

hashmap lookup is very fast, so

(when (:key my-map)
  (update my-map :key inc))


That should probably be an if instead of when


There's also update-existing and assoc-some from Medley if you don't mind pulling in an external dependency


It’s not clear from the original question what the broader goal is. Typically in situations like this you want to update existing keys by incrementing them, and update missing keys by starting them out at 1 (because this is the first time they have been seen). And the idiomatic way to do that is with fnil:


(update my-map :key (fnil inc 0))


Hi All, I need a help. I am trying to use Leiningen 2.9.1 on windows. I downloaded the latest zip and ranamed it as .jar file. I copied to self-install folder. I updated lein.bat with the latest bat file from the leiningen website. When I run 'lein repl' I am getting some error. Looks like it is related to the upgrade in nrepl in leiningen. I tried adding cider-nrepl plugins to profiles.clj. It did not help.


@manas.marthi try updating [venantius/ultra "0.5.1"] to 0.6.0. Lein from 2.8.3 had major middleware changes around nREPL. I would update all the plugins to latest versions as well.


But the ultra plugin here is most likely the cause


does ultra work with vim-fireplace?


@dharrigan Ultra is mostly meant for a better REPL experience and when youre using lein repl directly. vim-fireplace is supposed to connect vim to the REPL directly hence you wont see the REPL. so i dont think they are related


kk, thanks 🙂


@rahul080327 Thank you trying it now

Andy Nicholson12:05:19

Hello everyone 🙂 I'm a Rubyist considering a deep dive into Clojure & its ecosystem. When new Rubyists asked me who to listen to to level up, I had a list of people I could say "read/watch anything they produce". Who would you put on that list?

rich 4
Lennart Buit13:05:55

The obvious candidate is Rich Hickey, the one who started Clojure

Andy Nicholson22:05:28

Thanks folks! Been watching Rich for years, appreciate the other suggestions :)


@rahul080327 It worked now. I changed the ultra version. The repl started fine. However, cider-connect in emacs showed some errors regarding cider-nrepl. I uncommented :repl's cider-nrepl entries and started the repl and connected from emacs. The original errors are gone. However. I am seeing a different warning now `WARNING: clj-refactor and refactor-nrepl are out of sync. Their versions are 2.4.0 (package: 20190425.1002) and n/a, respectively. You can mute this warning by changing cljr-suppress-middleware-warnings.`


Do you still have the cider-nrepl package in your plugins? In your profiles.clj ?


This is my latset proflies.clj


Before I uncommented the :plugins section Emacs showed that I should have nREPL 0.4.4 or newer


My project dependencies are :dependencies [[org.clojure/clojure "1.8.0"] [enlive "1.1.6"]]


Ideally you don’t have to use cider connect. You can just remove all the cider related things in your profiles and use cider jack in instead. It injects the correct version automatically


You don’t have to manually use these deps if you’re using cider


oh okay. Possibly because I am starting the repl outside emacs and using cider-connect ?


i am not using cider-jack-in


I wil try that also..


It may have the version issues like the one you’re facing because cider expects certain version of things. Externally installed versions are a bit dicey at times


Also with newer versions of cider these things change and it’s best to let cider handle it automatically


Most of my time I don’t really start an external repl when using emacs


Got it. thank you very much. I will comment the profiles and retry cider-jack-in


@manas.marthi if you're using spacemacs, , ' is cider-jack-in. It even works in org babel buffers (i.e. no project). I can't however seem to get that to work for cljs org babel buffers (using , " to jack in for cljs, which works for my figwheel-main projects)


get rid of org.clojure/tools.nrepl. that version is ancient and lein has a direct dependency on nrepl/nrepl 0.6.0 which is what current CIDER-nrepl needs.


is there an inverse threading macro? It would be cool to e.g.

(macroexpand '(<<- (filter is-even (map inc x)))
to convert in the editor


what would this do?

Ivan Koz12:05:10

looks magical


result would be

(->> x (map inc) (filter is-even))


cursive and cider-refactor and clojure-lsp all have refactoring to do this


@rahul080327 All working okay now after I commented the cider-nrepl in profiles and started the repl using cider-jack-in. Thank you very much..


@dougkrieger I am not using spacemacs.. It is too slow behind the corporate proxy


my use case would be as follows: I'm a vim guy, I often like to "ysabba[function name]" to wrap an sexp in a function. Once I do that enough, I'd rather use the threaded form. @dpsutton I'll have a look at cider-refactor then, thanks


@dpsutton any philosophical (or technical) insight as to why that's implemented as an elisp function instead of a clojure macro? My assumption is that it's because even if there were a clojure macro, there would likely still be an elisp function to automate inserting macroexpand and quoting the sexp, but I'm curious if there's another reason


well as a macro in clojure it doesn't really make sense. because if it unwinds it into a threading macro, the next step is to macroexpand that which would undo that (which is what the threading macro does) so it would be an expensive no-op. this is done in elisp because you might want to change the source code and elisp is the language of emacs extensibility


I also want my editor to be able to do as much as possible "offline", without having to start a clojure process


dpsutton that makes a lot of sense. and solf, that's a good point that occurred to me as well


Is there a core function like apply that doesn’t take a list of parameters. i.e. #(%1 %2)


@dougkrieger did that make sense? Macros "run to completion". So if you had a macro form A that expanded to B, if you made something that would turn B into A, it would immediately macroexpand itself back into B


yeah, I wasn't thinking about that initially, but I got your point. macroexpand-1 could be used instead, but the points about eliminating repl dependency and enabling emacs-native extensibility still hold


@ben606 do you mean something akin to the es6 js spread operator? if so, I'd be curious about that too


why not just use the function itself?


(#(%1 %2) f x) is the same as (f x)


i'm guess its in something like (map invoke [inc dec] [1 2]) or something similar


where invoke is the function desired


ah, that makes sense


well, it's easy enough to define


(defn invoke
  ([f x] (f x))
  ([f x & args] (apply f x args)))


do clojure functions implement Java Runnable interface?


(context: Trying to understand (Thread. (fn [] (do-something! @some-atom) .start)


Is there a way to view the api documentation for a library. Like Ruby's rdoc.


Showing the functions etc...

Lucas Barbosa15:05:20

Is the slingshot library still in use, even though it was last updated in 2015?


is there a way to pretty print when evaling to a comment (e.g. in emacs)? I try (->> thing-to-log pprint with-out-str) but it gives me \n instead of literal newlines Edit: turns out cider provides cider-pprint-eval-defun-to-comment and several other cider-pprint-[suffix] commands


Hi! I'm wondering why the following code doesn't work:

(update {:x 1} :y or 345))
I get WARNING: Can't take value of macro cljs.core/or at line 1 <cljs repl>


or is a macro, so you can’t pass it in as an argument to the update fn.


That's what I figured. Are no macros allowed in update?


I guess the macro would just have to properly expand


Well, in general you can’t pass macros around like you can fns, but it’s easy to wrap in an anonymous fn like (update {:x 1} :y #(or % 345))

👍 4

@sotrhraven if you're in emacs, M-x cider-browse-ns


@dougkrieger I am using nightcode and very seldom vim. I should give spacemacs another go.


I recently switched from vim to spacemacs because of org-mode, rarely do I pop into vim (mostly for diffs and cases where I'm more familiar with fugitive than magit and need to quickly get something done)


fireplace probably has something similar to cider-browse-ns though


Not just a Clojure struggle for begginers. Getting up and going with some simple tools is a hurdle sometimes.


tpope is good about writing docs for his plugins


:help Fireplace will probably give answers


yeah I hear you about struggling getting clojure tooling up, I've been doing it for the past few days


I will give spacemacs another try in a bit. Emacs is a better fit for a lisp language.


emacs is objectively better software than vim, vim has a far better editing interface. spacemacs does a good job of emulating vim in emacs, so it's best of both worlds imo


tinkering w/ emacs lisp is what got me curious about clojure, and most of the spacemacs bindings I'd gotten used to for working with emacs lisp work in the spacemacs clojure layer too, it's been really nice


do you use jj for esc?

Mario C.15:05:11

Does figwheel repl have capability for command history such as up arrow?

Mario C.15:05:53

When I do that, all i get is escape characters


jk. spacemacs defaults to fd I believe, but jk puts the cursor where it started if you're already in normal mode. (setq-default evil-escape-key-sequence "jk") in the dotspacemacs/user-config section of .spacemacs. open .spacemacs for editing using SPC f e d


also @sotrhraven don't run emacs in the terminal, use the GUI. it's not like vim's worthless GUI, it's actually worthwhile

Mario C.15:05:16

It doesn't work but I would also like to be able to alt + <- or -> to move between words in the line


I use figwheel-main ("figwheel" sans "-main" is deprecated), but I use it from emacs/cider. ctrl+up works in that context. I'd highly recommend setting up your editor to run figwheel-main repl rather than running it from CLI

Mario C.15:05:55

Let me try that out


@sotrhraven I forgot to mention, re: spacemacs, your best bet is to use the HEAD of the develop branch. The master branch release cycle is painfully slow, and develop has been pretty stable in my experience. There are definitely breaking changes between them, so it took some readjusting when I switched from master to develop


So hiccup converts [:p {:id "foo"} "foo"] to <p id=\"foo\">foo</p> which is not valid html, what's the workaround here?


what is the meaning of the '_arg' convention? e.g. `(fn [_key _atom old new] (println old new))` is it just used when you want to avoid clobbering an existing symbol?


@dougkrieger where do you saw that?


examples section for add-watch docs


I guess is marking the args as unused


for ex: the four arguments must be supplied but only two are needed for the function definition


the official docs(the doc string on the function) don't have an example sections


the function takes a function of four args


so it is very likely the idiosyncratic style of some random person on the internet


@hiredman the doc for add-watch says `The watch fn must be a fn of 4 args`


but it doesn't include examples, and doesn't have underscore parameter names


I think he was talking about clojure-docs


but yeah, no need to mark unused args with _


and those examples are things random people on the internet have contributed


so not really indicative of commonly used style

👍 4

I would be very careful not to read too much into examples on


good to know, I though they were some curated examples


they may be curated, but then the question is curated by who


by "experts" but looks like anyone can edit without review


and looking at the other examples provided by the authors of that example, none of them use a "_" prefix anywhere, so it seems like random noise


I still like my theory that it's to avoid overwriting a symbol... Thanks for pointing out that the examples are not necessarily curated.;


shadowing built ins in arg lists is pretty common, especially key in my experience


it's not overwriting anything to be clear - just hiding


Trying to learn how to right effective tests, along with spec any of you have a resource, blog, book or something that walks through that process (I read Clojure for the Brave and True and it doesn't have anything about testing).

Kari Marttila17:05:49

@stuarthalloway mentions in his REPL Driven Development presentation ( ) that he never writes code in REPL but he writes all experimental Clojure code in one file (and he starts a new file every month). And I understood that clojure professionals often have three source directories under their projects: src (production code), test (tests) and dev (development kind repl stuff?). Stuart's experimental code apparently cannot be in "dev" directory since he has one active experimental file which he uses across all projects, right? I was wondering if there is a good example project in Github which has these concepts in deps.edn? I'm learning to use deps.edn and also learning effective REPL workflow. And BTW, thanks @stuarthalloway - the presentation is great, I have promoted the presentation in my corporation among the few clojurists (hopefully more in the future).


I don't think it is as formal a system as you seem to be looking for


for example I keep a few different "scratch.clj" files, which are similar to what stu describes, but are not source controlled and generally not part of a project in such a way that the tooling (like deps.edn) knows about them


they are just scratch files full of snippets of code that I copy and paste into the repl from time to time


Follow up, I often have lots of destructuring or let statements. When trying to run things in the REPL, I have to make a million defs or lets that normal?


IE in that talk he mentions running different sections, but I get lots of not defined errors when I try to do that.

Kari Marttila18:05:24

I believe Stuart's experimental code file location is in deps.edn since I understood from his presentation that he automatically sends the code snippets to REPL for evaluation. Of course, I'm not sure. Hopefully Stuart explains this here. 🙂


@kari.marttila By way of comparison, we have a convention at my company of putting personal files under a /personal directory at the same level as the /src directory, and then in our project.clj (we’re still on leiningen), we include the /personal directory as a sources root for dev builds, but not for prod/uberjar builds.


that depends on repl integration with your editor, and not deps.edn


the most straightforward translation is likely (let [{:keys [a b c]} foo] ...) to (let [{:keys [a b c]} foo] (def a a) (def b b) (def c c)) - this would be terrible to do in real code, but when reproducing something for debugging it's fine


seems like that wouldn't be hard to write a macro for actually... - but not a good macro to use in non-debug code :P


if my scratch file has multiple expressions that depend on each other, then I just have to remember to copy and paste them all n the repl


sometimes I wrap it all in a do


a lot of stuff is a single expression


If every function is pure, you could just arbitrarily copy sexps out to top level, wrap in a let providing inputs and eval defun -- I think with cider you can essentially narrow to the sexp to cut out the "copy" step. I've noticed the way I structure code has adapted to be more easily runnable in the repl, which has a nice effect of reducing the complexity of the code


there is a very different character from my personal scratch.clj and my work scratch.clj. my personal scratch.clj has more multi-expression snippets, and includes things like bits of code people have asked about in slack or irc that I pasted in there to reformat and edit. also any crazy little thing I think of usually starts in there.


my work scratch.clj tends to be more operational and more small expressions that do one thing. for example we have some queues in a particular server that have given us issues in the past, and while I have a ticket in to add some monitoring to them I haven't done it yet, so I have a little code snippet that if I repl in to the server I can check the queue length. So more little things to tweak and monitor running systems.


it is also not uncommon for our source files at work to have a (comment ...) block at the bottom with similar kinds of things that might go in a scratch.clj file, but we want to check in and share

Kari Marttila18:05:20

Ok. Thanks for sharing. Is this scratch.clj file e.g. under dev in your project and you have the dev directory in deps.edn as path?

Kari Marttila18:05:12

Ok. Sorry, you already mentioned that you copy-paste stuff from scratch.clj to repl?


my personal scratch.clj is in /src/scratch.clj on my laptop, and my work scratch.clj is /scratch.clj on the vm I use for work


I have mostly stopped using editor integrations (the main one for me would be cider on emacs)


(this is due to frustrations with cider and finding I get by fine without it)


{"type":"NetworkCollection","collection":[{"type":"NetworkGraph","protocol":"OSVL"}]} trying to read-str this valid json string, but for some reason I'm getting actual: JSON error (end-of-file) and I have no clue as to why


assuming you copied and pasted it from rich text source (a web page, slack, etc) I would check to make sure the quotes are quotes and not some weird unicode quotes


Actually the read-str is working fine, JSON error must be coming from else where, useless stacktrace is useless

Kari Marttila18:05:53

Ok. I use IntelliJ IDEA and Cursive and I just love it.


I dunno how restrictive cursive is on sending code to repls, like if it only lets you send code to a repl if the repl is launched from a given project and it can tell the source file is in that project

Kari Marttila18:05:15

I haven't tried that actually - I have always sent code only from my project files to repl in Cursive. I must try that once I get everything configured with deps.edn (learning).


In Cursive, the scratch files are shared between projects, and you can send snippets directly to the REPL from scratch files.


They’re also available in the Project tab if you open up Scratches and Consoles -> Scratches at the bottom of the panel.

Kari Marttila18:05:42

Thanks @manutter51! I didn't know that.


I’d been using Cursive for quite a while before I noticed the Scratches and Consoles thing — I had like 17 scratch files that I’d closed and thought were gone forever 😂

Kari Marttila18:05:13

I just created a scratch file in IDEA / Cursive, but for some reason Cursive does not recognize it: "Namespace name does not correspond to filesystem hierarchy"

Kari Marttila18:05:51

I guess I have to add the scratches directory as source?


is that message there because you used an ns form?


My scratch files don’t have any (ns ...) at the top


It’s just snippets


I have Cmd-Shift-Enter keybound to “Send form before cursor to REPL”, and I just use that to send individual snippets to the REPL

Kari Marttila19:05:17

Yep. Works now. 🙂


tbh I didn’t know the (ns ...) form would be a problem until @noisesmith mentioned it — credit where due 😉


instead of an ns form in a scratch file you usually want individual require forms (for whatever the scratch code might need)

Kari Marttila19:05:45

I wonder if I'm able to change the scratch files location in Intellij IDEA. Now it's in ~/.IntelliJIdea2019.1/config/scratches If I upgrade to next IDEA version I don't want to lose my scratch snippets...


having an ns implies external code that is built on this code, which to me is incompatible with the premise of a scratch file


I’ve kept my scratch files across multiple upgrades, including major version upgrades.


As long as you say “Yes, import settings from previous version” when the installer asks you, you should be fine.

Jiří Rejman19:05:28

hello does anybody know why this code gives me Unable to resolve symbol n in this context?


it looks like you are trying to do multiple arities, that syntax is wrong

❤️ 4

you have (defn foo [x] ... [x y] ...) and it should be (defn foo ([x] ...) ([x y] ...))


it's treating what you want to be an arg vector as a no-op vector literal with an unbound symbol in it

Jiří Rejman19:05:00

Yes! I can see it now


@rejmank1 I also suspect '(from) isn't what you want - it will create a list containing the symbol from, and not the value in that context


if you want a one element collection containing the value of from, use [from]

Jiří Rejman19:05:07

thanks 🙂 doing the 4clojure and the error message was little bit cryptic.

👍 4

though your usage of conj means you might want (list from) but that's less idiomatic


@rejmank1 making this point more clear:

(ins)user=> (conj (list 1) 2)
(2 1)
(cmd)user=> (conj [1] 2)
[1 2]
- reading your code I think you actually do want [from] as you want conj to add to the end not insert at the front


@rejmank1 clojure has so few syntactic rules that it would need to read your mind to give an accurate message in many cases

Jiří Rejman19:05:19

Tradeoff yes but i really like it, i supose it's just matter of time to no do these mistakes

Jiří Rejman19:05:36

not the messages, the simplicity


and the errors make more sense as time goes on as well - 4clojure uses an old version of clojure for fairness reasons, and newer clojure versions are better

👍 4

amap question: I tried to follow the example in the docs. What am I doing wrong here?


Seems to be something with Math/log because when I replace that with something else, it works


do you need to convert that Math/log result to a long? I think amap wants to produce the same kind of array it consumed...


Ohhh, I wondered if that might be the case. (Strange error message if so, though, no?) No, I want a double.


yeah, it starts by cloning your array, you can't just switch datatypes unless the array is a supertype...


and makign the array a supertype means you box each value which removes much of the benefit of using the arrays in the first place


Gotcha. That’s still fine—using pmap over the long-array was still quite zippy compared to just range, because the main bottleneck was the laziness of range. Thanks!


maybe areduce is closer to what you want


is noprompt/garden the go-to CSS generator? I'm using Reagent fwiw


I’m using Sass and lein-sassc actually


If I were going to generate CSS in Clojure, I’d probably use garden


would you say most use sass/less as opposed to garden? the ability to "componentize" styles using garden/clojure alongside reagent seems appealing, but if the wisdom of the masses says "no", I'll try to restrain myself


In my case I'd say it's more likely inertia: I'm already familiar with a Sass-based workflow and just never really gave garden a fair go.


Howdy y'all!! I'm using reitit for routing. Lein ring server runs ok but when i create an uberwar none of the paths work. I just tried to create an uberwar for this example project and i'm facing the same problem. Any advice on troubleshooting this issue


@dougkrieger There is a #garden channel if you want to try reaching out to anybody more familiar with it than I -- it's low-volume, but sometimes people are just waiting for someone else to start a conversation.


@kbosompem Hmm, it's been a while since I've worked with WARs as opposed to JARs, but I seem to recall something about there being an extra component in the URL with WARs.

👍 4

Like if you're configuring a "foo" application to run in a WAR, your URL's will be "/foo/home" instead of "/home"


It's been a long time since I've worked in that area though, so my memory could be unreliable there.


Are you deploying to immutant or something similar?


There's another low-volume channel for #immutant where you might post your question.


@manutter51 that was super helpful! created a catch all route and i see the following :path-info "/api/v1", :context "/ooo", :uri "/ooo/api/v1"


but the api's themselves are not working


I think the next thing I'd try would be to copy the existing routes and duplicate them inside a /ooo route, with the same middleware and handler functions. If that worked, then I'd try to figure out some better way to use the /ooo routes inside the uberwar, and regular routes with the plain old ring server.

👍 4

Maybe even just try one route, like make a copy of /api/v1/foo route and change the path to /ooo/api/v1/foo and see if it goes thru.


@manutter51 no luck with any specific routes. only the catch all works. I just tried compojure instead or reitit and the /ooo/ooo works there but not reitit

Mario C.21:05:41

Is there way to subscribe a channel to multiple topics or is my only choice one by one?

Ivan Koz22:05:09


(sub publication :account-created subscriber)
(sub publication :user-logged-in  subscriber)

Mario C.22:05:19

That works but thats why I meant by going one by one

Alex Miller (Clojure team)22:05:54

you're just one short macro away :)


Gday guys. Is anybody familiar with Neovim's acid plugin for Clojure? 🙂


I have trouble getting the repl to autoconnect, or to show the prompt to connect to a new one.


@nxtk Thanks, will do!