Fork me on GitHub

@nolan.wright.other Can you elaborate on the messages you're seeing? Does clj give you a REPL or just errors and the command prompt again?


(and is this Mac or Linux?)


@seancorfield Hi Sean, thanks for the response. clj gives me just a stack trace and the command prompt again. I’m on Mac. The exact error is: org.eclipse.aether.resolution.ArtifactDescriptionException: Failed to read artifact descriptor for org.clojure:clojure:jar:1.9.0


Maybe a chain or more context is in this stack trace. I'd suggest putting it in a gist so we can see the full stack.


Yeah, you can see from that stack trace that it is rooted in a network connectivity problem


I am behind a proxy, but I normally never have issues. My env vars are set, and things usually just work. Any thoughts on how I might configure proxy settings for clojure?


I haven't dealt with proxy settings with clj. Hrm...


Hello, who knows any up to date version of or anything similar. It should contain cider and other Clojure related thing so ready to work.


Spacemacs is pretty good, but you must add relevant layers to your dotfile after installing it


will Spacemacs give me all the Emacs key bindings it mentions Vim in it's page - is it somehow related?


@masta you can choose between vim and emacs key bindings

Ali Ebadian11:11:21

Hi all, I am using spacemacs to learn clojure. However the repl is just one line at the bottom of the screen. Does anyone know how to have the repl in side window?


Hi, is there a way to serialize a vector of functions, please? I have a map representing a layer in a neural network, consisting of :weights (core.matrix) :biases (vector of numbers) and :activation-functions which is a vector of functions (real number -> real number).


@mm007.emko yes, what are you trying to do?

Ali Ebadian15:11:03

@rakyi Thanks for reply. but when i evaluate the buffer the output doesnt go in the new window, but is printed out in the buffer at the bottom


@ali.ebadian you can use , s e to send an expression to repl. I recommend reading through the Clojure layer docs to familiarise yourself with all the different stuff you can do.


how to describe clojure spec in one sentence?


@sova To save the state of the neural network for later use so it is persistent through a JVM restart. Each layer of it is represented as a map (I plan to change it later) and it has a list of functions which can be lambdas and I'd like to persist the code of the lambda.


@mm007.emko i recommend storing the state of the layer in an atom and using duratoms (that can write atom state to a file and read from file on fresh starts)


the only cerealizing i do is with my granola 😉


Thanks! I'll give it a try.


This brand new project created using lein new library foo chokes whenever I try to run a lein command saying that it doesn't recognise lein-cloverage (and similar for other plugins if I remove that one). I can't even run lein deps to try and fetch them. I'm using a version of lein that supports this plugin syntax, have I goofed somewhere? project.clj attached.

:license {:name "Eclipse Public License"
            :url  ""}
  :dependencies []
  :plugins [[lein-cloverage "1.0.13"]
            [lein-shell "0.5.0"]
            [lein-ancient "0.6.15"]
            [lein-changelog "0.3.2"]]
  :profiles {:dev {:dependencies [[org.clojure/clojure "1.9.0"]
                                  [cider/cider-nrepl "0.18.0"]]}}
  :deploy-repositories [["releases" :clojars]]
  :aliases {"update-readme-version" ["shell" "sed" "-i" "s/\\\\[rocks \"[0-9.]*\"\\\\]/[rocks \"${:version}\"]/" ""]}
  :release-tasks [["shell" "git" "diff" "--exit-code"]
                  ["change" "version" "leiningen.release/bump-version"]
                  ["change" "version" "leiningen.release/bump-version" "release"]
                  ["changelog" "release"]
                  ["vcs" "commit"]
                  ["vcs" "tag"]
                  ["vcs" "push"]]


there's a plugin called lein ancient that can help you see if anything is out of date.


maybe someone else has more knowledge on this particular matter with cloverage


It isn't specific to cloverage. Lein isn't attempting to pull the plugin down and then it's throwing a classpath exception when it can't find it


lein-ancient itself has the same behaviour if I comment out cloverage and shell


gasp. sounds like lein is busted or ...


It's not an issue with lein itself


If I run things outside this project, using the contents of ~/.profile/, it's fine


hmm sounds like conflict... how can we pinpoint it


what's the exact error it's spitting out?


@ali.ebadian if you use SPC w v to create a second window first, then , s s will open a buffer in that window


@samcgardner weird. you mentioned that using other profiles has success?


Let me find you my default


 {:plugins [[cider/cider-nrepl "0.18.0"]]
  :dependencies [[jonase/eastwood "0.2.1" :exclusions [org.clojure/clojure]]]}}


and how about the one that won't budge?


I managed to chop off the top and bottom lines with parinfer somehwo


hahaha i have never heard of that before.


well done, you probably saved hundreds of reverse engineering hours


I have absolutely zero idea how I managed to do that


@samcgardener cosmic rays


Hi I have a question, I have a Rum component that I want to use to render over a collection of maps... how can I iterate over the atom bits and bobs? it's easy enough to reference a :title, :contents, :priority by number eg. (get-in @tv-state [:tiles n]) where n is 0, 1, 2, 3 etc.... should I count how many elements are in the list and then do a loop to render them in rum or is there some sort of functional way i can render the map exhaustively


man, my procedural brain takes the wheel all the time. i want to do like map-to-map things ... here's what i've got, maybe someone can show me how to spin it round


I think what you want is a function which will return a view of a single tile (or whatever is an element of the list), then you do something like

[:div (map display-title (:tiles @tv-state))]


awesome, that looks more like clojure


one issue i have is that the @tv-state has {:tiles [ {} {} {} {} {} {} {} {} ] } that is, :tiles is associated with a sequence of maps. shouldn't it still work?


i neglected to update my tv-cell render function to use (:title tile-data)


The solution is nice and clean:


wish i was rich so i could send you a bitcoin! you saved me a lot of time rebooting my brain from procedural to functional @trailcapital


haha, thanks. My only comment on your code, and I've never used rum so maybe I'm wrong on this - I don't think tv-cell needs to defined as a component. It could just be defined with defn. I think that you only need to define it as a component when you want it to re-render when the atom accessed inside of it is changed, but in this case tv-cell is a pure function


that's possible. in the future i may want to invoke will-update methods so i'm going with rum as my defacto

👍 4

How do I get abc here as string? I tried (take 3 "abc xxx") but I am getting a lazy seq.


I also tried (sub ...) but StringIndexOutOfBoundsException is thrown if the string is shorter than 3 chars.


(apply str (take 3 "abc xxx"))


@jaihindhreddy that worked thanks, I actually tried (str (take 3 "abc xxx")) but it didn't work for me. Why it's working with apply?


(take 3 "abc xxx") returns a lazy list of characters - (\a \b \c). Calling str on that tries to convert the list into a string, but with apply each element of the list is passed to str as a parameter

(apply str (\a \b \c)) == (str \a \b \c)

👍 4

An alternative, if the string is s: (subs s 0 (min 3 (count s)))


@somedude314 subs is closer to what you want, and is probably faster.


in general I'd agree that subs is probably faster - but I feel like counting all characters in s could potentially be more costly than just taking the first 3 elements


@trailcapital yeah, seems like count is not constant time for strings. (instance? clojure.lang.Counted "abc xxx")


you could instead do (.length "abc xxx")

parrot 4

user=> (crit/bench (apply str (take 3 "abc xxx")))
Evaluation count : 99799320 in 60 samples of 1663322 calls.
             Execution time mean : 645.599508 ns
    Execution time std-deviation : 65.923780 ns
   Execution time lower quantile : 599.080202 ns ( 2.5%)
   Execution time upper quantile : 798.213006 ns (97.5%)
                   Overhead used : 9.207121 ns

Found 4 outliers in 60 samples (6.6667 %)
	low-severe	 2 (3.3333 %)
	low-mild	 2 (3.3333 %)
 Variance from outliers : 70.3839 % Variance is severely inflated by outliers
user=> (def s "abc xxx")
user=> (crit/bench (subs s 0 (min 3 (count s))))
Evaluation count : 828073620 in 60 samples of 13801227 calls.
             Execution time mean : 67.874502 ns
    Execution time std-deviation : 2.771871 ns
   Execution time lower quantile : 65.404995 ns ( 2.5%)
   Execution time upper quantile : 73.764511 ns (97.5%)
                   Overhead used : 9.207121 ns

Found 1 outliers in 60 samples (1.6667 %)
	low-severe	 1 (1.6667 %)
 Variance from outliers : 27.0798 % Variance is moderately inflated by outliers

🆒 4

A little under 10 times faster here but as the length of s increases, the other one should take over.


I wonder why rand-int doesn't support a lower range. I have two UNIX timestamps and I want a random number somewhere in-between not starting from zero.


What is the best way to learn clojure very well. I like to solve adventforcode challenges and making websites ?


@somedude314 I'm not sure why rand-int doesn't, but you can accomplish a random integer in a range with (rand-nth (range lower-bound upper-bound))


@roelof I personally used to learn the essentials


Also (+ lower (rand-int (- upper lower)))

👍 4

ah, good point. That's probably better because you avoid the overhead of calling nth on a potentially large sequence


oke, does that one takes litle steps or can I maybe better do for example clojure koans other some other book ?


@roelof I am still a beginner but I found it generally easy to follow despite having zero experience in functional programming. However, I doubt someone can pick up Clojure in less than a week and complete the Advent of Code challenges in time 🙂


o, I did not say that I must learn it in a week


I could begin with for example some older ones


for me it more the challenge to solve it then get high on a leaderboard


for me developing is a hobby


Cool. Brave Clojure book has many exercises as well


I like that


and after the book which framework can learn the best to make website's ?


but first thing first. Install clojure on Windows and find a good ide


some recommendations for a ide which work fine in Windows 10


Cursive is nice, but costs some money past the free trial


There isn't something comparable to Django or Rails in Clojure. I think the simplest start would be with Compojure (think Flask for Python or Sinatra for Ruby): You'll need to understand Ring concepts before though:


VS Code has an extension called Calva which has some nice features too


VS Code with Calva, or Atom with ProtoREPL. Both work well on Windows.


I haven’t managed to get protoREPL working (probably just a PEBKAC) but I have gotten Calva working


I use Atom/ProtoREPL on Windows 10. It's frustrating that I have to use Leiningen or Boot for now. I use the CLI / deps.edn on macOS/Linux where I do my main development.


I use CLI / deps.edn for as much as I can on Windows 10 via Ubuntu on WSL. But you can easily run up a REPL on WSL and use it from Atom on the Windows side because the paths don't match (you can't load files from a Windows path that begins with a drive ID into a REPL running on Linux, even if you use symlinks to get the rest of the path to match).

😩 4
🙂 4
Kari Marttila14:11:13

I had to read a bit regarding this if a real Clojure guru says he is mostly using CLI. Interesting. I should also learn to use basic CLI since in remote hosts there is no IDE - just basic CLI.


We manage an 85k line mono repo code base at work with just deps.edn, clj, and a small shell script 🙃

Kari Marttila16:11:48

Interesting. When I started to learn Clojure I evaluated three different environments: Emacs + Cider, Eclipse + Counterclockwise and IntelliJ IDEA + Cursive. I found IDEA+Cursive to be really fluent and productive. But I should learn to use just CLI + Emacs/Vi as well.

Kari Marttila16:11:20

So, you don't feel that Leiningen or Boot are giving essential value?

Kari Marttila16:11:24

BTW. How much you are using type hints? That is something that I should consider start using.


We started with lein back in 2011, switched to boot at the end of 2015, and just switched to the new tools.


We had outgrown lein. We moved to a monorepo with a central boot build file and lots of subprojects.


Then we wanted to simplify our dev/test pipeline -- and we were running into bugs in boot (one in particular with async pod refresh was just killing us).


I've gone back and forth with emacs. The last two (three?) years I've been using Atom/ProtoREPL.


As for type hints -- we use them only to avoid reflection where performance matters (which is not everywhere).


I think, if I can patch ProtoREPL to pass a *nix style path instead, without a drive (as an option in the settings) then it can be a really nice way to work.


yeah I’ve only done cursory development on Windows. Many of my coworkers use it but we use leiningen at work


oke, maybe I try first VSCode


probably best to stick with leiningen on windows for now until we get true Windows CLI / deps.edn support


and then try that on the first chapter of the brave book


The problem I'm outlining is to do with Windows Subsystem for Linux -- if you run your REPL on Windows, instead of WSL, you're fine. With both VS Code and Atom.


Calva on VS Code is good but I couldn't get the jump to definition working which was a deal breaker so I switched to Cursive.


oke, thanks for the explanation


then I think I will ask for a personal licence because im only doing personal work


I can't remember ever using jump to definition, to be honest (in eight years of Clojure development).


Maybe because you are an expert 🙂


I'm curious as to why it was a deal breaker?


disadvantage is that if I want to use cursive. I have to download Idea and that is slow on Windows


CMD + click to go to the function definition is super, super convenient. For example, I still can't make the distinction between -> and ->> without looking at the docs. I can simply cmd+click to verify.


Atom/ProtoREPL has a hot key to show the docstring inline in the editor.


And it can show the source code with a hot key too.


Yep, I saw it in ProtoREPL. The other benefit is navigating the code to make edits on my own functions. That's said, the creator of Calva was offering me more help to get it working at #calva-dev than what someone would get from paid product. I just gave up.


Editors/IDEs are very personal, very subjective. Different folks prefer different options. I keep trying VS Code but I just can't quite get to like it. I have it on both my Windows and Mac machines. I'll probably keep trying. It concerns me that ProtoREPL isn't being very actively developed compared to Calva.


I feel like things like jump-to-definition and other language features are a little more complex to get right in Clojure


a lot of the plugins for editors rely on connecting to your application to support those, which brings with it some additional setup and complexity


plus 1 for jump to definition. vim-fireplace enables this and I use it all the time - as well as the source and doc hotkeys


Nearly all of the IDEs/plugins work by using a running REPL to evaluate queries against your code 🙂 The compliment library is used for autocompletion in almost everything, for example.


That's the power of Lisp: reflecting on the code via a REPL.


yep. but is also brings with it certain complexities; it requires a dependency to be loaded in your application


Not necessarily.


at the very least, you need a remote REPL


We run bare Socket REPL servers on several production processes. No code needed. Just a JVM option.


most things (e.g. Calva, CIDER, proto-REPL) require additional dependencies


Calva’s author was lamenting yesterday that he suspects many people try Calva and end up giving up due to using the wrong cider/nrepl version (or not using it at all)


I had my own issues with the update to nrepl 0.18 and a bunch of middleware (that I had no idea I had installed! thanks spacemacs) broke my ability to do Clojure dev


You can do a lot with a bare REPL -- you can even load new code in ... which is how unravel/unrepl works. It loads the compliment library in over the wire, for example (as an option).


I'm not a fan of how big nREPL/CIDER is. I hope we'll see simpler tools with the prepl in Clojure 1.10.


I had hoped more people would follow unravel's lead -- but CIDER/nREPL is very deeply entrenched at this point.


yeah. I’m sure there are improvements to be made to the way REPLs are handled (AFAICT nREPL is kind of cumbersome to use from an editor perspective) but it’s a dream to use with CIDER and it’s well-tested


That's why the nREPL library has moved into the CIDER organization for future maintenance...


I guess the biggest bummer is that none of these REPL protocols seem to be compose


The problem is that nREPL is a protocol in the first place.


like, at least right now, you can’t have tooling that uses nREPL go over unrepl or prepl


and I’m just ignorant enough about all of these REPL protocols to not have the foggiest if that’s even possible


I get the impression the the Clojure/core team aren't happy about the way the nREPL protocol has been so deeply embedded in tooling.


In theory, you could load nREPL over a bare REPL and then start an nREPL server inside the app and then upgrade to nREPL for interaction.


I havn't check prepl yet, but I love unrepl. The idea to start with a simple socket connection and enhance it as you go is great


hmm yeah. I could imagine that would ameliorate some of issues people have with using nREPL/cider actually


esp. dependency issues. if you’re not jacking in (and having the editor start the REPL itself) then it’s quite annoying


Also, as much as at first you think you'd rather have static analysis in your tools. Once you try the repl, you get addicted. I actually feel in Cursive, which doesn't make use of the repl. A lot of people don't develop a repl driven workflow, and they suffer for it on the long run


eh, I see your point but not sure I agree


it sucks when your REPL tooling isn’t working quite right and now you’re basically dead in the water


there’s definitely power in having both static analysis and REPL available


e.g. linting and code formatting pretty much requires static analysis, I haven’t seen a successful REPL-based approach


Eastwood and cljfmt do pretty good jobs on both of those, IMO. Do you find them lacking?


mainly that most of my day job is ClojureScript 🙂

Ali Ebadian20:11:35

Guys I am going through Clojure fundamentals on Safaribooks online, I don't understand the symbols in clojure. What are they and what are they used for?


I think the Clojure docs does an okay job at explaining it:


basically they usually appear in code as a way to refer to a value



(def foo "bar")
this is defining the symbol foo to refer to the value "bar"

Ali Ebadian20:11:03

Say in in java we have int i = 0; is i here the symbol?

Ali Ebadian20:11:35

as in variable names?


symbols can be that plus more


symbols are usually used for referring to values, but this isn’t a property of the symbol itself, though. it’s basically like assigning a global hashmap where the key is the symbol foo and the value is "bar"


so you can for instance pass symbols around as values


(def foo "bar")

(println foo) ;; using the symbol as a reference to the value "bar"
=> "bar"

(println 'foo) ;; adding a qoute before the symbol makes it just a value, it skips the referencing
=> foo

Ali Ebadian20:11:09

why would ever want that?


You will want this to do metaprogramming. When you wanna write code that manipulates and generates code.

Ali Ebadian20:11:53

either use the variable name, for whatever value you need


various reasons. you can use them as keys in a map. you can pass them around and then look them up later


it also allows you to write macros


for instance, using the new CLI tools and deps.edn, your dependencies are written as maps with symbols as the keys:

{:deps {org.clojure/clojure {:mvn/version "1.10.0-beta1"}}


this is a totally valid Clojure EDN data structure


symbols look nicer than keywords in this case ¯\(ツ)

Ali Ebadian20:11:45

thats effectivly a map of maps, right?


:deps is a keyword, org.clojure/clojure is a symbol, and { ... } means they’re inside a map

Ali Ebadian20:11:38

how would you refer to org.clojure/clojure?


not quite sure what you mean. in this case org.clojure/clojure isn’t referring to a value, it’s just a key used in a map


so you could do e.g.:

(def deps-edn {:deps {'org.clojure/clojure {:mvn/version "1.10.0-beta1"}})

(get-in deps-edn [:deps 'org.clojure/clojure :mvn/version])
=> "1.10.0-beta1"

Ali Ebadian20:11:16

ok, why is it better than `(def deps-edn {:deps {:org.clojure/clojure {:mvn/version "1.10.0-beta1"}}) (get-in deps-edn [:deps :org.clojure/clojure :mvn/version])`


proper names are just usually symbols


as a practice

Ali Ebadian20:11:37

sorry if I am being stupid here. I just cant see what additional power its giving me that was missing by variable name, class names and keywords


sure. one power it gives you, is the ability to refer to things that will be defined later:

(defn print-foo []
  (println foo)) ;; ERROR! foo hasn't been defined yet

;; second try
(defn print-foo []
  (println (resolve 'foo)))

(def foo "bar")

=> "bar"
another thing you can do since symbols are values is dynamically create Clojure code:
(defn make-foo []
  (list 'def 'foo "bar"))

(eval (make-foo))

(println foo)
=> "bar"


the primary use case for having symbols as values, and using them to refer to variables/parameters/classes/etc., is that last case - the ability to create evaluable Clojure code using data


does that make more sense?

Ali Ebadian21:11:40

the first case yes, in a crude analogy you're getting around nulls.


so cursive a is good choice for a beginner ?

👍 4
Ali Ebadian21:11:04

@lilactown Thanks I think I have a bit more to go on.

👍 4
Ali Ebadian21:11:01

when we do (+ 1 2) is + here a symbol?

Ali Ebadian21:11:46

so I can override it?

Ali Ebadian21:11:42

well what could possibly go wrong


@ali.ebadian there is actually another layer of indirection called a var. (def a 1) maps the symbol a not to the value 1, but to a var which has the value 1.


And you can change it by doing (alter-var-root #'a inc).


now a evaluates to 2.

Ali Ebadian21:11:56

but your a didnt have ' before it

Ali Ebadian21:11:17

how is it a symbol?

Ali Ebadian21:11:15

im a compelete newbie so I have no idea what the # or inc are doing


When you type a into the REPL, you are asking it to evaluate it. And symbols evaluate to whatever value is associated with them in the symbol table, in this case being a var that has the value 1.


Whereas typing 'a into the REPL is equivalent to typing (quote a), and this evaluates to the symbol a, and no lookup in a symbol table is done.

Ali Ebadian21:11:05

ok so this is what i dont get


inc is a function that increments a number i.e, (inc 1) will evaluate to 2. And alter-var-root takes a var and a function and modifies the value of the var to the value return value obtained by applying that function to the current value of the var.


Just FYI in case you do try to override + in particular. In Clojure + and a few other functions are treated specially by the compiler by inlining them. This means that attempting to redefine them won't always have the effect you want. If you want to experiment with redefinitions in various ways, you may be less confused if you do those experiments with something other than such an inlined function.

Ali Ebadian21:11:52

@andy.fingerhut what if i exlude + from my namesapce?


I am not sure of the answer in that case. I don't have all the rules in my head -- just wanted you to be aware that inlined functions may give different behavior than not-inlined functions when trying to redefine them.

Ali Ebadian21:11:54

@jaihindh.reddy could you explain the difference between vars and symbols?

Alex Miller (Clojure team)21:11:22

Vars are boxes for values

Alex Miller (Clojure team)21:11:53

Symbols refer to vars in the scope of a namespace


@ali.ebadian I highly recommend watching Clojure for Java Programmers. It cleared up a lot of things for me.

Ali Ebadian21:11:30

dont vars themselves live in the scope if namessapce?


I believe that in the context of Alex's answers, vars (the boxes for values) do not themselves live in a namespace. They are usually named with symbols that have namespaces as part of the symbol.


If you know the right incantation, you can create vars without names.


(not something that most Clojure programmers do, though)

Ali Ebadian21:11:40

it might be the lack of vitamin D in London, as now im just confused.

Ali Ebadian21:11:30

Im gonna watch the video @jaihindh.reddy recommended. thanks guys

👍 4

Is it possible to change the behaviour of lein-repl so that it returns to the usual repl prompt rather than hanging until it receives a ^C input when an exception is thrown?


mine doesn't hang after an exception

test-repl.core=> (throw (ex-info))

ArityException Wrong number of args (0) passed to: core/ex-info  clojure.lang.AFn.throwArity (


Mine only seems to do it when being passed input via nREPL


So it's possible this is an nREPL question


It isn't hanging


It just isn't redrawing the prompt


Back to screaming at vimscript for me


Hi all. Has anyone tried monitoring the stdout of a long running process?


I.e. I don't want to wait for the process to finish in order to get what it's printed to stdout


I tried using conch but not sure what I'm doing wrong. I don't get the output back until the process completes


(defn download [url] (with-open [s (] (let [proc (future (lsh/stream-to (lsh/proc "youtube-dl" url) :out s))] (str s) (loop [done? false] (.flush s) (if done? (print (str s)) (do (print (str s)) (Thread/sleep 500) (recur (future-done? proc))))))))


If there are any options for "buffering" or "auto-flush", enabling auto-flushing, or disabling buffering, would probably help.


In your code, if it is the print calls that are not having an immediate effect, and you want them to, you can follow them with a call to (flush) and you may get better results.