Fork me on GitHub
Jovanny Cruz00:06:32

Hello! Question about Leiningen... How can I declare "global" alises like profiles using ~/.lein/profiles.clj? Is it even possible or aliases can only be declared at project level?


Is it possible to add a dependency into deps.edn and have it available in the repl without restarting the repl?


Like some sort of "refresh"?


there's code that can do it, but it's not part of deps (which exits before your process starts), and it's kind of hacky


it can be added to your project as a dep

Lucy Wang03:06:34

just found the old chat can be found on (not reachable on slack anymore due to the free plan limit), is this a feature provided by zulipchat, or it's something the community builds maually?


The @UFNE73UF4 can be added to any channel here to archive conversations to Zulip. It was built by a community member (who also started the Zulip Clojurians community). It's very useful for searching old conversations 🙂 And it's keyboard-driven, which I love!

💯 3

There is also @U055W814A which archives conversations to -- also built by a community member (the founder of ClojureVerse I think? Or maybe he took it over from the original author?)


Am Teye and a beginner in Clojure and want someone to mentor me


@ics.learncomputer Feel free to ask questions here as you need -- everyone in this channel has opted in to helping beginners!


There is a #mentoring channel but folks will want to see how you interact here first before they'll be willing to volunteer as a mentor. So asking questions here will give folks a good sense of where you are in your journey and what your style of learning is...


I am experiencing an odd behavior with Ubuntu 20.04/JDK 11 (headless) when I run my uberjar. If I reboot the server, and I launch it, it consistently launches between 5 to 10 seconds. Which is good. But when I stop it and try to launch it again without rebooting the server, it takes forever to relaunch (consistently more than 2 minutes). It just took more than 6 minutes to relaunch. Any idea why that is happening? RAM and CPU usage is low (it’s a DigitalOcean instance with 1GB RAM 2GB swap).


What kind of app it is? How do you know it’s up and running?


Is there something in logs?


It’s a Ring app. I am launching it on port 8000. On first launch, it quickly gets launched:

java -jar mypro-0.1.0-SNAPSHOT-standalone.jar
2020-06-28 02:00:29.442:INFO::main: Logging initialized @2886ms to org.eclipse.jetty.util.log.StdErrLog
WARNING: seqable? already refers to: #'clojure.core/seqable? in namespace: clojure.core.incubator, being replaced by: #'clojure.core.incubator/seqable?
2020-06-28 02:00:35.674:INFO:oejs.Server:main: jetty-9.4.28.v20200408; built: 2020-04-08T17:49:39.557Z; git: ab228fde9e55e9164c738d7fa121f8ac5acd51c9; jvm 11.0.7+10-post-Ubuntu-3ubuntu1
2020-06-28 02:00:35.759:INFO:oejs.AbstractConnector:main: Started ServerConnector@4e111e08{HTTP/1.1, (http/1.1)}{}
2020-06-28 02:00:35.762:INFO:oejs.Server:main: Started @9206ms
Started server on port 8000
On second launch I quickly get to:
2020-06-28 02:01:20.112:INFO::main: Logging initialized @2880ms to org.eclipse.jetty.util.log.StdErrLog
WARNING: seqable? already refers to: #'clojure.core/seqable? in namespace: clojure.core.incubator, being replaced by: #'clojure.core.incubator/seqable?
then it gets stuck until it shows the remaining after several minutes.


I just upgraded the server to 8GB RAM 4 CPUs and still have the exact same issue.


Maybe I am missing some settings in

? I don’t have any set.


Picked up JAVA_TOOL_OPTIONS: -Xmx256m <- not helping


How are you stopping the process? A clean shutdown or just killing it?


My guess is you are just killing it, so the kernel entry for the socket you are listening on is still in place, and that kernel state is causing the long start times, and rebooting is clearing the state in the kernel which is why you get short start times


@U0NCTKEV8 I tried both. killall -9 java and systemctl stop/start myproj.service My SystemD entry looks like this:

Description=App server

ExecStart=/usr/bin/java -jar /home/app/proj-0.1.0-SNAPSHOT-standalone.jar



Is it a virtual machine?


@UTQEPUEH4 yes, a DigitalOcean instance


Is there any other activity on that virtual machine?


Absolutely nothing


Just the Clojure app/nginx/postgres for the app itself


A wild guess then: it might be something like reading /dev/random


I’d be surprised if killing the process wouldn’t release all (socket) descriptors opened by the process but it’s an interesting idea...


@UAX4V32SZ try perhaps?


Recreating the server now to try that. I got so frustrated I terminated the server a little while ago lol


I've had servers where after stopping server for minutes after you get errors when trying to listen on the same socket


@UAX4V32SZ actually, make it

🙏 3

@UTQEPUEH4 that actually solved the issue!!! I tried restarting 3 times and now it’s restarting in under 15 seconds.


Thanks so much


What does it do?


Glad I could help. Some software (java too, apparently) reads one of /dev/random or /dev/urandom on Linux to initialize their random numbers generators


There's a very widespread misconception that /dev/random is the proper way to do it. That's wrong, but many programs do it anyway. The proper way to do it is actually /dev/urandom.


One of the unfortunate differences is that reading /dev/random may block if there's "not enough entropy" in the system


Since entropy is gathered via "true random" hardware events, it might be problematic on systems with no load (no other activity, no network activity) and/or on virtual machines


That option just tells java to do the right thing and use non-blocking /dev/urandom instead


So some package I am using is reading from /dev/random, or Java itself?


It's Java itself


Does it explain why it works after the restart but the second attempt “fails”?


Yes, there might be a bit more entropy available right after the boot -- because booting a system is a lot of "activity"


Interesting I don’t think I have ever seen this issue before....


One way to discover the root cause could perhaps be running strace.


Yes, strace -f should've shown it


But it's a recognizable issue; I've never seen that with java, but I definitely know the pattern to instantly suspect that it's java doing the /dev/random thing

👍 3

And quick googling then confirmed that it very well could be it


Rebooted the server and tried restarting a few more times and it’s coming up as it should. I still can’t believe it 😄


Btw. It seems that related issue has been solved a long time ago, at least for Linux and Solaris: But here they say that java's SecureRandom class still uses /dev/random for generating seed information:


Maybe Ubuntu 20.04 has not been tested enough yet


Hi guys I'm fairly new to clojure is there a better way of doing the following? My solution works but I feel like there should be a simplier way then combining get and map for what I imagine is a really common task


(map :target (zone :a))


A map and a key both can be called as a function.


oh thats really handy to know, I thought having to use :get all the time seemed pretty verbose


thanks for the help

Stephen Lester18:06:52

I feel dumb but I have been stuck and this is hard to search for.

(ns mynamespace.core
  (:require [hiccup.core :refer :all]
            [hiccup.util :refer :all]))

(raw-string "") ;; "raw-string cannot be resolved"
Same goes for trying hiccup.util/raw-string and I'm not sure what I'm doing wrong here.

Stephen Lester18:06:25

When I inspect it, too, the code doesn't match what is in the repo from 3+ years ago 😮

Stephen Lester18:06:04

/Users/stephen/.m2/repository/hiccup/hiccup/1.0.5/hiccup-1.0.5.jar!/hiccup/util.clj doesn't have any mention of raw-string ...


Why is not able to find most clojure artifacts? I tried "timbre" "datascript" etc. and none of them returned any results ...


many(most?) clojure artifacts are on clojars,


Thanks @U7RJTCH6J. Unfortunately I am not a fan of since the results are sorted terribly... they never put the best-fitting result first


what kind of search are you trying to do?


you may have better luck just searching google/duckduckgo with "clojure <library name>"


or if you're just generally interested in what clojure libraries are out there,

👍 3

If you search for "datascript", the first item in the result is "datascript-transit", if you search for "timbre" the first result is "timbre-logstash"


I can't think of a reason for searching clojars directly


if you just do a web search for "clojure datascript", the first result is the github repo which is probably the best result


I was looking for the latest version of a particular package


You are right about google in general, however, when I'm trying to be precise I don't want to be misguided by occasional wrong first-results in Google.


i would probably still check the website or github repos for this info, but googling "clojars datascript" will also generally work


yeah that's what I do most of the time. When I'm trying to be precise I go to

👍 3

Too bad is the "official" one when it's closed to useless


clojars has worked great for me, but if you think there's improvements to be made, it's open source,


@U7RJTCH6J Thanks! I should have said it more clearly -- I think clojars is great as a platform and as a tool for publishing clojure packages; my only complaint is that its search engine on its web interface could have been more useful if they could fix the result sorting. I will definitely look into the source code and see if there's anything I can do about it.

👍 3

On the other hand, seems to be able to find all the clojure packages


Is there any quick way to find out which of my deps are outdated, like `yarn upgrade-interactive` for NodeJS?

Tzafrir Ben Ami19:06:11

if you are using lein, you can use the lein-ancient plugin to find outdated dependencies

👍 3

I am using shadow-cljs so I looked up deps-ancient (a port of ancient to deps) and it seems to work


I want to aot compile my project, is it enough if I add the :gen-class directive to my core namespace which contains the main function?


@UJG7AN8LD :gen-class is needed for your main namespace so the -main function gets compiled to a Java main method, but it's not enough by itself to trigger AOT.


What tooling are you using? Clojure CLI? Leiningen?


I am using lein, yes I think I know the remaining steps, add :aot [my-proj.core] to project.clj and then do a lein uberjar


My question was whether I need to add it to any other name spaces


Am I missing any other steps? @U04V70XH6


No. :gen-class is just to cause the -main function to become a Java-callable method. - is the default prefix for methods. If you had (defn -foo [s] (str "Hello, " s "!")) in that namespace, it would be compiled to a Java-callable foo method of the class.


AOT is just calling clojure.core/compile on one or more namespaces. :gen-class signals how a specific namespace should be compiled. Does that help?


(if you omit :gen-class, the namespace will still be compiled but you won't have the special treatment of functions starting with - becoming Java-callable methods)


Thanks a lot for the response, I understood what you said. And I require the main to become a Java-callable method because when I run the jar file, I will have this main method ready as the entry point? Am I understanding it correctly?


The Main-Class specified does not exist within the jar. It may not be executable as expected. A gen-class directive may be missing in the namespace which contains the main method, or the namespace has not been AOT-compiled.
This is what I got when I did a lein uberjar and adding gen-class solved the problem. So I am guessing something is looking for a main class when I run the jar and gen-class created that class and the Java-callable method for me.


Yup, that's right. In a JAR file, Java expects to call a main() method in the main class (your main namespace).


Without :gen-class, the -main function is compiled to class directly with an invoke() method (all Clojure functions are normally compiled that way).


Great! Thanks a lot :)

Kazuki Yokoyama19:06:27

Hello, does anyone have a good resource to learn more about assert-expr of clojure.test? Its documentation seems very scarce. Thank you.


I've found it very confusing when it was used by coworkers, and I recommend avoiding it

😞 3

the tl;dr is that it's a multimethod that lets you make new kinds of is expressions


if your whole team is on the same page about them, they can be a useful way to make tests more idiomatic / easier to write and maintain


Yeah, it's a pretty low-level piece of functionality


And it's weird because it's a multmethod but it behaves like a macro.


the concrete problem I'm referencing when I suggest avoiding it, is that usually when you see (foo x) in a form, you can go in a repl and look at the source or doc of foo


but no, with assert-expr, as @U04V70XH6 says, it behaves like a macro but it's a multimethod extension, so you end up with this weird kind of code you never see anywhere else


in theory, the solution could be educating about and refining that pattern of dispatch, but we have so many great forms of extension, it's easier to just suggest not using this one unless you know you really know what you are doing


if you have collaborators at least


luckily in my case I could find the assert-expr via grep of the source files, and work back from there, but if I was using a library, even that would not be an option


it undermines the normal self-documentation and inspectability you get with clojure


It is only useful if you're writing extensions to clojure.test. I had to learn how to use it when I wrote expectations.clojure.test but it's not easy to use properly.


right - I was thinking for a moment, what if more code was written that way? but I don't think that would be a good thing :D

Kazuki Yokoyama19:06:50

And the way to learn it is try and error? It is for a personal project, I see it as an opportunity to learn (and practice a little macro)

Kazuki Yokoyama19:06:58

And what should I use instead to turn the tests more idiomatic?

Kazuki Yokoyama19:06:34

I'll take a look at that! Thank you


I did it so I can write (expect ::some-spec (some-expr)) and under the hood it expands to (is (=? ::some-spec (some-expr))) which then goes through assert-expr (for the =? smart equality operator)

Brian Amadio19:06:00

Hi all, I’m a total Clojure noob, and new to the Slack as well. Looking forward to learning from you all and building some fun projects!

Brian Amadio19:06:12

I’m also new to lisps and functional programming, but have a lot of experience with C++, Python, and Go. Any tips on learning materials for newbies would be great!


I am somewhat of a beginner too and have been doing clojure for the past 7 months professionally. The REPL is your best friend when learning clojure and also while doing anything else.


I mean apart from all resources Sean Corfield has listed below


Yup, big +1 on the REPL since you can use doc and source to look at how core functions work.

Brian Amadio20:06:46

@U014BBTEFK6 What kind of projects do you build with Clojure?


A lot of our microservices run in clojure. From powering a CMS to wrapping elastisearch to analytics

Brian Amadio20:06:10

Nice! Have you built microservices in Golang or Python before? I’m curious about the differences in developer experience and productivity

Brian Amadio20:06:23

I’m building full-stack tools for Data Scientists at my company, and I really like the idea of being able to do the backend and UI in the same language with clojurescript

Brian Amadio20:06:44

Currently we write backend in Golang/Python and UI in Javascript but I’d prefer if I never had to write another line of Javascript again

practicalli-johnny22:06:38 has free learning content for Clojure (and a bit of ClojureScript). Includes videos and online books

👍 3

@U0166NHED3M No I havent used them before for microservices. Clojure is really beautiful and makes you really productive, the only caveat is that I miss the auto documentation of types sometimes. Hopefully spec is able to help here


Free online stuff includes Clojure for the Brave and True, and Clojure from the Ground Up.


Good books to get started include Living Clojure. If you prefer video material, I think Eric Normand has some free stuff on (his paid courses are excellent).


There's also the @jr0cket stuff (I haven't looked at that so I'm not sure what he offers, but I know he does a lot of good learning material).


There's also a lot of good stuff linked from


This page in particular is a treasure trove of resources

Brian Amadio20:06:14

Alright! Thanks for all the links and tips!

Stephen Lester22:06:01

Anyone have an idea? 😞


clj -Sdeps '{:deps {hiccup {:mvn/version "1.0.5"}}}'
Clojure 1.10.1
user=> (require 'hiccup.core 'hiccup.util)
user=> (apropos "raw-string")
user=> (apropos "raw")
doesn't seem to be any raw-string function. what leads you to believe there is one?


also, its pretty uncommon to see :refer all these days. require things with an alias


ah. the latest release is 1.0.5 from 2014. 2.0.0 has been in alpha since 2017. if you use the latest alpha, you will have the function.

clj -Sdeps '{:deps {hiccup {:mvn/version "2.0.0-alpha2"}}}'
Downloading: hiccup/hiccup/2.0.0-alpha2/hiccup-2.0.0-alpha2.pom from clojars
Downloading: hiccup/hiccup/2.0.0-alpha2/hiccup-2.0.0-alpha2.jar from clojars
Clojure 1.10.1
user=> (require 'hiccup.util)
user=> (apropos "raw-string")
(hiccup.util/raw-string hiccup.util/raw-string?)

Stephen Lester22:06:40

"alpha since 2017" explains a whole lot, thanks so much. Not enough coffee today.