This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-01-31
Channels
- # announcements (1)
- # aws (4)
- # babashka (40)
- # beginners (89)
- # calva (13)
- # cider (3)
- # clj-kondo (36)
- # cljdoc (16)
- # clojure (74)
- # clojure-boston (1)
- # clojure-dev (7)
- # clojure-europe (30)
- # clojure-new-zealand (1)
- # clojure-nl (17)
- # clojure-uk (5)
- # clojurescript (16)
- # core-async (9)
- # cursive (16)
- # datahike (3)
- # datalog (6)
- # datascript (7)
- # datomic (15)
- # emacs (38)
- # events (2)
- # figwheel-main (3)
- # fulcro (6)
- # google-cloud (18)
- # graalvm (6)
- # gratitude (1)
- # honeysql (1)
- # introduce-yourself (1)
- # jobs (1)
- # leiningen (5)
- # lsp (6)
- # malli (11)
- # meander (2)
- # off-topic (4)
- # re-frame (6)
- # reitit (8)
- # releases (2)
- # remote-jobs (3)
- # reveal (4)
- # shadow-cljs (200)
- # sql (8)
- # tools-deps (16)
In IntelliJ i want to have tests “auto runner” toggle button which when enabled, will execute tests automatically when I change a test or source file. But I don’t see it as you see on first screenshot. Second picture shows my IntelliJ test runner configuration. How can I see “auto runner” toggle button?
Hello! How to split text by empty lines?
text1
text1
text2
Text2
So I would have 2 pieces. first:
text1
text1
and second:
text2
text2
Thanks in advance!I think it's just 2 newlines in a row, so:
(clojure.string/split text #"\n\n")
might work?Might want to account for possible carriage returns as well, so perhaps something like #"\r?\n\r?\n"
could be an improvement.
Or if you'd rather think in terms of sequences of individual lines, something like
(->> text
(clojure.string/split-lines)
(partition-by clojure.string/blank?)
(remove #(= % '(""))))
could do the trick. (edit: basically what Mno said :))Hey everyone, I have a function which return a vector like this [#object[sun.nio.fs.UnixPath 0x51cb8962 "My-File"]
I have this saved in an edn file with prn-str
but when I attempt to read this edn, I run into an error No reader function for tag object user
I do not understand readers well enough yet. Anybody knows how I should go about mapping this data-readers?
(edn/read-string (slurp "files.edn") {:readers {'object <>)})
#object
is used for many things that don't print readably, if you need to round-trip a path object it's better to give it a custom reader and custom writer. but do consider that it's probably more straightforward to write the string of the path, and then recreate it later
data-readers expects a hash-map from the tag symbol to the function that creates the data type
@U01V7GEU89J you got the argument order to read-string wrong - the opts come before the string to read
working example:
(cmd)user=> (defn as-path [s] (java.nio.file.Paths/get s (into-array String [])))
#'user/as-path
(cmd)user=> (clojure.edn/read-string {:readers {'user/path user/as-path}} "#user/path \"foo\"")
#object[sun.nio.fs.UnixPath 0x37095ded "foo"]
using print-method
to create a custom writer so you can round trip:
(cmd)user=> (defmethod print-method java.nio.file.Path [p w] (.write w (str "#user/path \"" p "\"")))
#object[clojure.lang.MultiFn 0x73877e19 "[email protected]"]
(cmd)user=> (clojure.edn/read-string {:readers {'user/path user/as-path}} (pr-str (as-path "foo")))
#user/path "foo"
I have comma-separated string "Hello,World,Three"
and I want to replace this with comma separated values present in list of hash map like def maps [{:name "Hello" :value "1"} {:name "World" :value "2"} {:name"Three" :value "3"}]
. Expected output 1,2,3
.
So, to summarise: 1. Split on delimiter (here ,
) 2. Look up each resulting item in maps
and take the corresponding :value
3. Join results with delimiter
Note: step two above is easier if you can model your data structure (`maps`) differently: instead of vector of maps, can the data be modeled as a single map? (`{"Hello" "1", "World" "2", ...}`)
Well, given the recipe above, can you come up with the parts required for the solution? 🙂
The process could look something like the following:
(->> (split text #",")
(map lookup-value)
(join ","))
Where you'll have to do a bit of work for lookup-value
and for split
and join
you might find something under clojure.string
🙂
Given the above, it should be a function from a comma-separated value of the input string (eg. "Hello"
) to the desired comma-separated output value (`"1"`).
Yes I have written that function which will do compare on :name
but the second parameter how should I pass that ?
(map #(when (= (:name %) str) (:value %)) [{:name "Hello" :value "1"} {:name "World" :value "2"}])
I suggest you map over the result of splitting your input on ,
, instead of mapping over your maps
collection.
Where lookup-value
could actually be a Clojure map (the persistent collection, not the function) if you modeled your data as (def lookup-value {"Hello" "1", "World" "2", "Three", "3"})
`
Otherwise, you'll need lookup-value
to first find the correct element in maps
and then get it's :value
component.
But generally if you're in control of how the data is structured, your best bet is to reshape the structure so that it's easy to work with.
So how should I convert [{:name "Hello" :value "1"} {:name "World" :value "2"}]
into one that you told. Is there any way to do it in clojure ?
Is the data static? If it is, then just (def data {"Hello" "1", "World" "2"})
instead of (def data [{:name "Hello", :value "1"}, ...])
If not, then there are various ways to iterate over the data, eg. the following:
(def lookup-value
(->>
(for [{:keys [:name :value]} maps]
[name value])
(into {})))
So I'm trying to add a field to the first item of my list, and the last map in a list,
[] => []
[{:id 1}] => [{:id 1, :hasPrevious false, :hasNext false}]
[{:id 1}, {:id 2}] => [{:id 1, :hasPrevious false}, {:id 2, :hasNext false}]
[{:id 1}, {:id 2}, {:id 3}] => [{:id 1, :hasPrevious false} {:id 2} {:id 3, :hasNext false}]
The code I came up with so far is... not great 😅 (see 🧵)As input
is finite (and smallish), you should be able to just count
it. With that in mind, you should be able to do something like (map-indexed special-cases input)
. The implementation of special-cases
could add the necessary metadata if it's given an index of 0
or (- (count input) 1)
.
I've thought about map-indexed too; but i'm not sure it'll be much cleaner :thinking_face:. I'll give it a go in a sec
In the meanwhile I spun the functions out; and instead of 1fn, i expose 2 as part of the API.
(defn add-has-previous [edges]
(concat (when-let [x (first edges)]
[(assoc x :hasPrevious false)])
(rest edges)))
(defn add-has-next [edges]
(concat (butlast edges)
(when-let [x (last edges)]
[(assoc x :hasNext false)])))
Using an index with assoc-in also doesn't seem great;
(defn do-the-thing [input]
(let [last-item (dec (count input))
input' (assoc-in (vec input) [0 :hasPrevious] false)]
(when (nat-int? last-item)
(assoc-in input' [last-item :hasNext] false))))
The map-indexed approach seems pretty clean actually 😮
(defn do-the-thing [input]
(map-indexed (fn [idx item]
(assoc item
:hasNext (not= idx (dec (count input)))
:hasPrevious (not (zero? idx))))
input))
How about this?
(map-indexed (fn [idx val]
(cond-> val
(= 0 idx)
(assoc :hasPrevious false)
(= (- (count items) 1) idx)
(assoc :hasNext false)))
items)
(edit: fixed threaded assoc usage)Welcome. To be honest, I might prefer your latest version over mine. But anyhow I think either version is quite a bit clearer than what we started out with. 🙂

hmm I didn’t think I was a beginner but definitely feel like one right now. I’m looking at https://kit-clj.github.io and seeing the 2 lines to install it
first one is:
clojure -Ttools install com.github.seancorfield/clj-new '{:git/tag "v1.2.381"}' :as new
This is what I get:
Error building classpath. Unknown tool: tools
I have the latest clojure cli tools , on macos 12 (1.10.3.1069). Just in case I’ve removed my ~/.clojure dir to have a fresh one generated. I’m sure I’m missing something obvious.. Could anyone point me in the right direction please?
The same command worked for me on the same version (on Ubuntu) Check the version using clojure -Sdescribe
to check its using the version you think it should be using.
Alternatively, try adding an alias to the user level configuration, ~/.config/clojure/deps.edn
or ~/.clojure/deps.edn
This is an example from https://github.com/practicalli/clojure-deps-edn/
:project/new
{:replace-deps {com.github.seancorfield/clj-new {:mvn/version "1.2.381"}}
:exec-fn clj-new/create
:exec-args {:template lib :name practicalli/playground}
:main-opts ["-m" "clj-new.create"]}
Then call the alias with the -T
option (this is not the same as installing, this is just using the library as a tool)
clojure -T:project/new
Arguments will be key value pairs (but not in a map)If you cannot get any tools to install, suggest asking in the #tools-deps channel for help.
thanks @U05254DQM, while that did help somewhat, I got some more errors after that.. Let me check with #tools-deps for further help
$ clojure -T:project/new create :template io.github.kit-clj :name pat/pat
Unqualified function can't be resolved: create
(that’s after it downloaded clj-new deps)for anyone following here, the issue is due to macports not including tools.edn in its installed distribution of clojure. extracting tools.edn from an official tgz and copying it to /opt/local/lib/clojure/ (and keeping it in ~/.clojure/tools/ as well, but by default it will be copied there when using clojure -Ttools the first time), resolved it.. at least until the next time clojure gets updated.
Is there a nice way to test if something is a collection, to return the first element, or if not a collection, just return the original var, i.e., (if (sequential? thang) (first thang) thang))
?
my strong recommendation would be to not do this and just always take one or the other
but I don't know of a better way to write it
code like this is often needed when acquiring data from a badly designed API, always convert once (at the point of acquisition).
otherwise the test for single item vs. collection becomes contagious and spreads to all the code that ends up touching the data (the principled way to handle that is a protocol or multimethod, but it's much better to simply convert once at the boundary of your app)
also, most of the time if an API provides data that is sometimes an X and sometimes a sequence of X, the right way to handle it is to turn the bare item into a one element vector
How to do java interop with nested interfaces? An example from a library does this: PlcReadRequest.Builder builder = plcConnection.readRequestBuilder();
how can you implement this in clojure?
nested classes are not actually nested, in the vm (and therefore for clojure interop) Foo.Bar becomes a class called Foo$Bar. But you don't need to reference the nested class to translate the code in your example: (.readRequestBuilder plcConnection)
Hi I'm trying the learn-clojurescript book lesson 5. It says to add
{:aliases
{:new {:extra-deps {seancorfield/clj-new
{:mvn/version "1.1.243"}}
:exec-fn clj-new/create
:exec-args {}}}}
And then run
clj -X:new :template figwheel-main :name learn-cljs/weather :args '["+deps" "--reagent"]'
But then I get
WARNING: Specified aliases are undeclared: [:new]
No function found on command line or in :exec-fn
What do I do?where are you adding it, in your ~/.clojure/deps.edn?
Yes so this might be where I have it wrong. The book says to have a deps.edn file, and then it says to add the alias to a /.clojure/deps.edn, and I might have done that wrong. I'll show you what I have
for deps.edn:
{:deps {org.clojure/clojurescript {:mvn/version "1.10.773"}}
:paths ["src"]
:aliases
{:dev {:main-opts ["-m" "cljs.main"
"--compile" "my-cljs-project.core"
"--repl"]}}}
for /.clojure/deps.edn I just added a directory called .clojure in vscode, then added a file called deps.edn:
{:aliases
{:new {:extra-deps {seancorfield/clj-new
{:mvn/version "1.1.243"}}
:exec-fn clj-new/create
:exec-args {}}}}
It's all within the same project folder
This is my file tree
ah. You need that .clojure/deps.edn
to be in your root directory, not just in a random directory
~/.clojure/deps.edn
vs ~/some/random/project/.clojure/deps.edn
. It is your user’s own specified aliases and options
Oohhhhhhh ok!
Hey guys, I hope you are doing well! I wrote a macro in which I use a transducer like this
(defmacro dbg []
(let [xf (comp (filter odd?) (take 5))
s [1 2 3 4 6 6 7 8 8 9 7]]
`(transduce ~xf conj [] ~s)))
(dbg)
but when I try to evaluate (dbg) I get an Exception
1. Caused by java.lang.IllegalArgumentException
No matching ctor found for class clojure.core$comp$fn__5825
Any help to resolve this is greatly appreciated :)full error msg
2. Unhandled java.lang.ExceptionInInitializerError
(No message)
NativeConstructorAccessorImpl.java: -2 jdk.internal.reflect.NativeConstructorAccessorImpl/newInstance0
NativeConstructorAccessorImpl.java: 77 jdk.internal.reflect.NativeConstructorAccessorImpl/newInstance
DelegatingConstructorAccessorImpl.java: 45 jdk.internal.reflect.DelegatingConstructorAccessorImpl/newInstance
Constructor.java: 499 java.lang.reflect.Constructor/newInstanceWithCaller
Constructor.java: 480 java.lang.reflect.Constructor/newInstance
Compiler.java: 5000 clojure.lang.Compiler$ObjExpr/eval
Compiler.java: 7180 clojure.lang.Compiler/eval
Compiler.java: 7136 clojure.lang.Compiler/eval
core.clj: 3202 clojure.core/eval
core.clj: 3198 clojure.core/eval
interruptible_eval.clj: 87 nrepl.middleware.interruptible-eval/evaluate/fn/fn
AFn.java: 152 clojure.lang.AFn/applyToHelper
AFn.java: 144 clojure.lang.AFn/applyTo
core.clj: 667 clojure.core/apply
core.clj: 1977 clojure.core/with-bindings*
core.clj: 1977 clojure.core/with-bindings*
RestFn.java: 425 clojure.lang.RestFn/invoke
interruptible_eval.clj: 87 nrepl.middleware.interruptible-eval/evaluate/fn
main.clj: 437 clojure.main/repl/read-eval-print/fn
main.clj: 437 clojure.main/repl/read-eval-print
main.clj: 458 clojure.main/repl/fn
main.clj: 458 clojure.main/repl
main.clj: 368 clojure.main/repl
RestFn.java: 1523 clojure.lang.RestFn/invoke
interruptible_eval.clj: 84 nrepl.middleware.interruptible-eval/evaluate
interruptible_eval.clj: 56 nrepl.middleware.interruptible-eval/evaluate
interruptible_eval.clj: 152 nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn
AFn.java: 22 clojure.lang.AFn/run
session.clj: 218 nrepl.middleware.session/session-exec/main-loop/fn
session.clj: 217 nrepl.middleware.session/session-exec/main-loop
AFn.java: 22 clojure.lang.AFn/run
Thread.java: 833 java.lang.Thread/run
1. Caused by java.lang.IllegalArgumentException
No matching ctor found for class clojure.core$comp$fn__5825
Reflector.java: 288 clojure.lang.Reflector/invokeConstructor
LispReader.java: 1317 clojure.lang.LispReader$EvalReader/invoke
LispReader.java: 853 clojure.lang.LispReader$DispatchReader/invoke
LispReader.java: 285 clojure.lang.LispReader/read
LispReader.java: 216 clojure.lang.LispReader/read
LispReader.java: 205 clojure.lang.LispReader/read
RT.java: 1879 clojure.lang.RT/readString
RT.java: 1874 clojure.lang.RT/readString
REPL: 260 lhrb.words.solver/eval152134873
NativeConstructorAccessorImpl.java: -2 jdk.internal.reflect.NativeConstructorAccessorImpl/newInstance0
NativeConstructorAccessorImpl.java: 77 jdk.internal.reflect.NativeConstructorAccessorImpl/newInstance
DelegatingConstructorAccessorImpl.java: 45 jdk.internal.reflect.DelegatingConstructorAccessorImpl/newInstance
Constructor.java: 499 java.lang.reflect.Constructor/newInstanceWithCaller
Constructor.java: 480 java.lang.reflect.Constructor/newInstance
Compiler.java: 5000 clojure.lang.Compiler$ObjExpr/eval
Compiler.java: 7180 clojure.lang.Compiler/eval
Compiler.java: 7136 clojure.lang.Compiler/eval
core.clj: 3202 clojure.core/eval
core.clj: 3198 clojure.core/eval
interruptible_eval.clj: 87 nrepl.middleware.interruptible-eval/evaluate/fn/fn
AFn.java: 152 clojure.lang.AFn/applyToHelper
AFn.java: 144 clojure.lang.AFn/applyTo
core.clj: 667 clojure.core/apply
core.clj: 1977 clojure.core/with-bindings*
core.clj: 1977 clojure.core/with-bindings*
RestFn.java: 425 clojure.lang.RestFn/invoke
interruptible_eval.clj: 87 nrepl.middleware.interruptible-eval/evaluate/fn
main.clj: 437 clojure.main/repl/read-eval-print/fn
main.clj: 437 clojure.main/repl/read-eval-print
main.clj: 458 clojure.main/repl/fn
main.clj: 458 clojure.main/repl
main.clj: 368 clojure.main/repl
RestFn.java: 1523 clojure.lang.RestFn/invoke
interruptible_eval.clj: 84 nrepl.middleware.interruptible-eval/evaluate
interruptible_eval.clj: 56 nrepl.middleware.interruptible-eval/evaluate
interruptible_eval.clj: 152 nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn
AFn.java: 22 clojure.lang.AFn/run
session.clj: 218 nrepl.middleware.session/session-exec/main-loop/fn
session.clj: 217 nrepl.middleware.session/session-exec/main-loop
AFn.java: 22 clojure.lang.AFn/run
Thread.java: 833 java.lang.Thread/run
the issue here is that a macro needs to serialize data into the form it generates, and some arbitrary objects (including this transducer) don't round trip cleanly
you've already solved it by quoting the construction of the transducer of course