This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-06-28
Channels
- # babashka (10)
- # beginners (140)
- # cider (6)
- # clj-kondo (10)
- # cljs-dev (39)
- # cljsrn (6)
- # clojars (1)
- # clojure (23)
- # clojure-europe (2)
- # clojure-spec (7)
- # clojure-uk (6)
- # clojurescript (1)
- # conjure (16)
- # cursive (3)
- # datomic (3)
- # emacs (6)
- # fulcro (13)
- # graalvm (3)
- # malli (8)
- # meander (4)
- # off-topic (43)
- # pathom (1)
- # pedestal (15)
- # re-frame (13)
- # reagent (3)
- # sci (25)
- # shadow-cljs (26)
- # sql (9)
- # testing (34)
- # tools-deps (80)
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?
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
just found the old chat can be found on https://clojurians.zulipchat.com/ (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!
There is also @U055W814A which archives conversations to https://clojurians-log.clojureverse.org/ -- also built by a community member (the founder of ClojureVerse I think? Or maybe he took it over from the original author?)
yeah I think the code is https://github.com/clojureverse/clojurians-log-app
hello
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).
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)}{0.0.0.0:8000}
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.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:
[Unit]
Description=App server
After=network.target
[Service]
WorkingDirectory=/home/app
EnvironmentFile=-/home/app/.env_vars
SuccessExitStatus=143
ExecStart=/usr/bin/java -jar /home/app/proj-0.1.0-SNAPSHOT-standalone.jar
User=myuser
[Install]
WantedBy=multi-user.target
@UTQEPUEH4 yes, a DigitalOcean instance
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 -Djava.security.egd=file:/dev/urandom
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
@UTQEPUEH4 that actually solved the issue!!! I tried restarting 3 times and now it’s restarting in under 15 seconds.
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
Yes, there might be a bit more entropy available right after the boot -- because booting a system is a lot of "activity"
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
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: https://bugs.openjdk.java.net/browse/JDK-4705093 But here they say that java's SecureRandom class still uses /dev/random for generating seed information: https://security.stackexchange.com/questions/40633/java-securerandom-doesnt-block-how
Hi guys I'm fairly new to clojure is there a better way of doing the following? https://pastebin.com/zpuj5nBc 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
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.When I inspect it, too, the code doesn't match what is in the repo from 3+ years ago 😮
/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
... https://github.com/weavejester/hiccup/blob/master/src/hiccup/util.clj#L67
Why is https://search.maven.org 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, https://clojars.org/
Thanks @U7RJTCH6J. Unfortunately I am not a fan of http://Clojars.org 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, https://www.clojure-toolbox.com/
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
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 https://mvnrepository.com/
Too bad http://Clojars.org 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, https://github.com/clojars/clojars-web
you may also find the api useful, https://github.com/clojars/clojars-web/wiki/Data
@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.
On the other hand, https://mvnrepository.com/ 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?
if you are using lein, you can use the lein-ancient
plugin https://github.com/xsc/lein-ancient to find outdated dependencies
I am using shadow-cljs so I looked up deps-ancient (a port of ancient to deps) and it seems to work https://github.com/slipset/deps-ancient
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 :)
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
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 https://clojuredocs.org/clojure.test/assert-expr
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
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)
And what should I use instead to turn the tests more idiomatic?
Feel free to look at https://github.com/clojure-expectations/clojure-test/blob/develop/src/expectations/clojure/test.clj#L113-L117
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)
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!
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.
@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
Nice! Have you built microservices in Golang or Python before? I’m curious about the differences in developer experience and productivity
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
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
https://practicalli.github.io/ has free learning content for Clojure (and a bit of ClojureScript). Includes videos and online books
@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 http://PurelyFunctional.tv (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 https://clojure.org/guides/getting_started
Adding to Sean’s resources https://github.com/functional-koans/clojure-koans
This page in particular is a treasure trove of resources https://clojure.org/community/resources
Alright! Thanks for all the links and tips!
Anyone have an idea? 😞
clj -Sdeps '{:deps {hiccup {:mvn/version "1.0.5"}}}'
Clojure 1.10.1
user=> (require 'hiccup.core 'hiccup.util)
nil
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)
nil
user=> (apropos "raw-string")
(hiccup.util/raw-string hiccup.util/raw-string?)
user=>
"alpha since 2017" explains a whole lot, thanks so much. Not enough coffee today.