I’m failing to find a documented example of a return type-hint + a docstring on a function. The compiler tells me this is wrong:
(defn foo ^Long
"I do nothing"
[^Long x] x)
;; Syntax error: Metadata can only be applied to IMetas
It compiles if the type hint is moved after the docstring, but I’m not sure if that is annotating the correct thing. Any advice for dong this right?That’s correct - it goes before the arg vector
Gotcha. Thanks @alexmiller!
where’s the log for this slack?
Whoa. Nice. For some reason I earlier just assumed information was gone, unless I captured it somehow. Didn’t occur to me someone was saving things. Things I learn. 🙂
@mattias504 look for either @logbot and/or @zulip-mirror-bot in a channel. If they’re there, messages are being saved. If not, you can /invite
them to a channel and new messages from that point will get saved.
Going through the Reagent documentation and an example is provided for updating state using "on-change" for an input.
(ns example
(:require [reagent.core :as r]))
(defn atom-input [value]
[:input {:type "text"
:value @value
:on-change #(reset! value (-> % .-target .-value))}])
(defn shared-state []
(let [val (r/atom "foo")]
(fn []
[:div
[:p "The value is now: " @val]
[:p "Change it here: " [atom-input val]]])))
This mostly makes sense to me, but I am struggling picking apart this specific line:
:on-change #(reset! value (-> % .-target .-value))}])
Searching the web for "->" and ".-" has not yielded great results as you might imagine@michaellan202 There are two places: https://clojurians-log.clojureverse.org/ and https://clojurians.zulipchat.com/#narrow/stream/180378-slack-archive
Thank you!
The former is purely a readonly searchable index/log. The latter is also a chat community, that has a one-way mirror of nearly all channels here and is searchable with no limits (because it is on Zulip’s free open source plan).
.-foo
is a JavaScript field selection in ClojureScript. ->
is the “thread first” macro.
@esciafardini You’ll probably find this helpful: https://clojure.org/guides/weird_characters
(-> % .-target .-value)
will macroexpand to (.-value (.-target %))
if that helps: get the target
field from the anonymous function’s argument, and then get the value
field from that.
(you may also find the #reagent channel helpful, if you’re not already a member)
I made a namespace that should generate a java class with (:gen-class
This worked all right until I made an edit to the namespace in question. Since then (even if I revert the changes to the code that worked earlier) lein just refuses to aot it anymore, giving me java.lang.ClassNotFoundException
What can cause this?
I've tried the "usual" candidates like clearing target and even wiping my .m2
Even if I explicitly try to run lein compile app.class-namespace
Hmm it finally re-compiled it once I removed every reference to the class from other places in the source first
is there a way to test side-effects of functions, for example the output of println? or should I make the function return the string instead of printing and call println with on the result of the function?
(with-out-str (fn-with-side-effects)) ;; => "printed string"
but I would try to avoid side effects as much as I can. so return a string to be printed sound right for me
it's a text based game, so printing is an essential part of it 😅
but thanks for the answer
I don’t meant to say “avoid it completely” ) I should say “keep it as far from core functionality as possible”.
just had a thought during my lunch run.. maybe I want to reuse the code for a different interface, for example a webpage. that would be easier then, too. thanks for the hint
Hey everyone, I am looking to dissoc some keys from a list of maps. How do I go about passing the current iteration of a map function to a dissoc?
(def final-map (map (dissoc <I need the current iteration here>[:uselessKey1 :uselessKey2]) (vals items)]))
You want an anonymous function there: (def final-map (map #(dissoc % :uselessKey1 :uselessKey2) (vals items)]))
(Also no square brackets around the keys you want to dissoc
from the map)
What is the significance of #
in this context? I see this a lot in Clojure but can't find a doc for this. What is the terminology?
That’s one of the two ways of writing an anonymous function. It’s basically just a shorthand way to throw together a quick anonymous function for use with things like map
and filter
and reduce
and so on.
The %
means the first arg to the function, and if you have more args than that, the second arg is %2 and the third is %3 and so on.
it is often recommended in designing clojure programs to have a pure core and then a "runner" that performs the side effects. There are some really great talks about this: https://www.youtube.com/watch?v=ZQkIWWTygio https://www.youtube.com/watch?v=JvGXyNXky0Q see also, re-frame's dispatch
I think this talk was also pretty good about strategies on how to pull apart effects from the rest of your codebase: https://www.youtube.com/watch?v=IZlt6hH8YiA
Hi, which of the following for this is a better option? Are there any better than these?
;; option 1
(defn update-user [users id user]
(update-in users [id]
#(if (nil? %)
(throw (IllegalArgumentException. (str "User " id " does not exist")))
user)))
;; option 2
(defn update-user-contains [users id user]
(if (contains? users id)
(assoc-in users [id] user)
(throw (IllegalArgumentException. (str "User " id " does not exist")))))
(update-user
{:one {::first-name "Agatha" ::last-name "Christie" ::email "<mailto:agatha.christie@mail.com|agatha.christie@mail.com>"}}
:two
{::first-name "Prabu"
::last-name "Rajan"
::email "<mailto:prabu.rajan@mail.com|prabu.rajan@mail.com>"})
Second will have nicer stacktrace
I agree. I prefer the 2nd one too in terms of simplicity. I was just wondering in terms of performance, which one would be better, but it turns out that both take almost similar time, but I have not really measured it for large maps
what is the preferred idiom of using a defn- vs a letfn. I understand the scope, but asking for style
In general, I think top-level functions should be defn-
letfn is mostly useful inside functions, particularly when making something recursive
kind of for "functions private to a function"
but generally even for things like that, I mostly just make defn- as they are easier to test, doc, etc
letfn is also good for closing over local variables without having to pass them in
both of those answers are appreciated
Hi, what are Clojure editor usage statistics?
https://clojure.org/news/2020/02/20/state-of-clojure-2020#_deep_dives
second graph in that section
note this is not a true editor usage statistics but editor usage statistics of people who responded to the state of clojure survey. Hopefully it is representative of the community at large but that's not a certainty
it's ~2500 responses so probably a good enough sample (tracks with prior years)
Looking to find the clojure docker image to run in production. I found https://github.com/Quantisan/docker-clojure/blob/99e09867b734efda57f117a1a266bcb2dce25a33/target/openjdk-11-buster/lein/Dockerfile, is there a tag without lein? or what is the recommended version?
@munichlinux my standard procedure is to build a jar then put it in a plain JDK container
I never ship lein
to prod
that is what I was expecting to do.
clojure is "just a library"
my prod containers call java -cp the.jar clojure.main -m my.entrypoint.namespace
as entrypoint
I thought there is some version with just jdk 11. I guess I should look in the openjdk docker.
adoptopenjdk or corretto are my goto containers
Nice https://hub.docker.com/r/adoptopenjdk/openjdk11/ has alpine.
@ghadi Thank you.
fyi alpine isn't "official" until after 11
(I think, JDK 14 gave real support for it?)
everyone uses it, but YMMV
I am looking at this https://github.com/AdoptOpenJDK/openjdk-docker/blob/master/11/jdk/alpine/Dockerfile.hotspot.releases.full
right -- the JDK didn't officially support Alpine in 8 or 11
some people still put together artifacts for alpine -- just not supported
I see, what would you recommend?
I also see debian.
the debian based one is fine
if you want alpine you should use latest (16)
ya, clojure LTS says it supports 11.
and look into jlink
, which is a better way of stripping down a JVM for smaller artifact sizes
will do