This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-05-01
Channels
- # aws (1)
- # beginners (237)
- # boot (2)
- # calva (6)
- # cider (16)
- # clara (10)
- # clj-kondo (1)
- # cljs-dev (24)
- # clojure (29)
- # clojure-brasil (2)
- # clojure-dev (20)
- # clojure-europe (1)
- # clojure-italy (56)
- # clojure-japan (1)
- # clojure-nl (16)
- # clojure-spec (12)
- # clojure-uk (12)
- # clojurescript (24)
- # clojureverse-ops (3)
- # core-async (3)
- # cursive (21)
- # datascript (5)
- # datomic (82)
- # devops (5)
- # duct (14)
- # emacs (2)
- # fulcro (2)
- # jobs (6)
- # juxt (7)
- # kaocha (6)
- # leiningen (19)
- # luminus (3)
- # nrepl (51)
- # off-topic (208)
- # other-languages (1)
- # re-frame (8)
- # reagent (9)
- # remote-jobs (6)
- # shadow-cljs (37)
- # spacemacs (6)
- # testing (12)
- # tools-deps (25)
Is there a convention for naming boolean values?
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
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.
Here's the Reddit thread https://www.reddit.com/r/Clojure/comments/b7db39/question_marks_in_clojure/
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.
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): https://www.youtube.com/watch?v=YR5WdGrpoug
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:
https://stackoverflow.com/questions/20136617/clojure-idiomatic-update-a-maps-value-if-the-key-exists
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))
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
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.
Please 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.
@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
@rahul080327 Thank you trying it now
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?
The obvious candidate is Rich Hickey, the one who started Clojure
for me that'd be https://github.com/ztellman https://github.com/tolitius https://github.com/technomancy https://github.com/ikitommi also whatever interesting i find among the clojure conj talks
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@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
sorry, just needed to RTFM http://clojure-doc.org/articles/language/interop.html#clojure-functions-implement-runnable-and-callable
Is there a way to view the api documentation for a library. Like Ruby's rdoc.
Showing the functions etc...
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.
Well, in general you can’t pass macros around like you can fn
s, but it’s easy to wrap in an anonymous fn like (update {:x 1} :y #(or % 345))
@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)
Not just a Clojure struggle for begginers. Getting up and going with some simple tools is a hurdle sometimes.
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?
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
@mario.cordova.862 try ctrl + up
also @sotrhraven don't run emacs in the terminal, use the GUI. it's not like vim's worthless GUI, it's actually worthwhile
Thanks
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
@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
got it
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?
for ex: the four arguments must be supplied but only two are needed for the function definition
I think he was talking about clojure-docs https://clojuredocs.org/clojure.core/add-watch
I would be very careful not to read too much into examples on http://clojuredocs.org
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).
@stuarthalloway mentions in his REPL Driven Development presentation ( https://vimeo.com/223309989 ) 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).
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 first...is 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.
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.
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
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
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?
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)
{"type":"NetworkCollection","collection":[{"type":"NetworkGraph","protocol":"OSVL"}]}
trying to read-str
this valid json string, but for some reason I'm getting actual: java.io.EOFException: 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
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
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.
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 😂
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"
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
Ok. Thanks!
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)
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.
hello does anybody know why this code gives me Unable to resolve symbol n in this context?
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
Yes! I can see it now
thank you!
@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]
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
Tradeoff yes but i really like it, i supose it's just matter of time to no do these mistakes
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
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
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 https://github.com/metosin/reitit/tree/master/examples/ring-spec-swagger 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.
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.
you may also find some helpful information here: https://github.com/clojure-cookbook/clojure-cookbook/blob/master/08_deployment-and-distribution/8-03_war-file.asciidoc
@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"
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.
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
Is there way to subscribe a channel to multiple topics or is my only choice one by one?
(sub publication :account-created subscriber)
(sub publication :user-logged-in subscriber)
you're just one short macro away :)