This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-01-09
Channels
- # announcements (1)
- # atlanta-clojurians (1)
- # beginners (198)
- # calva (4)
- # cider (16)
- # clara (8)
- # cljs-dev (14)
- # cljsrn (4)
- # clojure (204)
- # clojure-europe (3)
- # clojure-gamedev (2)
- # clojure-italy (8)
- # clojure-nl (17)
- # clojure-poland (3)
- # clojure-russia (20)
- # clojure-spec (32)
- # clojure-uk (45)
- # clojurescript (59)
- # community-development (1)
- # core-async (25)
- # cursive (20)
- # datomic (47)
- # emacs (7)
- # fulcro (8)
- # iot (1)
- # iotivity (2)
- # jobs (1)
- # jobs-discuss (8)
- # juxt (11)
- # luminus (5)
- # nrepl (4)
- # off-topic (136)
- # onyx (24)
- # other-lisps (1)
- # parinfer (74)
- # pedestal (1)
- # planck (3)
- # portkey (67)
- # random (1)
- # re-frame (28)
- # reagent (11)
- # reitit (9)
- # remote-jobs (3)
- # ring-swagger (2)
- # rum (3)
- # shadow-cljs (96)
- # slack-help (3)
- # spacemacs (6)
- # tools-deps (3)
- # unrepl (1)
- # vim (4)
Hi all, I'm trying to include a third-party dependency ( https://github.com/Engelberg/better-cond ) for the first time. As per instructions, I've included [better-cond "2.0.2"]
in my Leiningen dependencies, and (:require [better-cond.core :as b])
in my namespace declaration. I restarted the REPL (in Cursive), hoping the dependency would magically resolve, but I'm left with a syntax error: Could not locate better_cond/core__init.class, better_cond/core.clj or better_cond/core.cljc on classpath.
What else do I need to do in this situation? (And what should I read more about to understand this?)
@gsinclair After adding a dependency to project.clj, tell Cursive to "Refresh Leiningen Projects" in the File menu. That will download any deps you need, and Cursive will know about them after the refresh.
@gsinclair What you've done sounds as if it should work. Perhaps ask in #cursive in case this is a Cursive-specific weirdness?
I just tried it with clj
/`deps.edn` at the command-line and it worked
(! 543)-> clj -Sdeps '{:deps {better-cond {:mvn/version "2.0.2"}}}'
Clojure 1.10.0
user=> (require '[better-cond.core :as b])
nil
Thanks Sean.
I just tried command-line lein repl
to see how that would go. Mixed success.
When I ran the command, it gave me this positive sign:
Retrieving better-cond/better-cond/2.0.2/better-cond-2.0.2.pom from clojars
Retrieving better-cond/better-cond/2.0.2/better-cond-2.0.2.jar from clojars
But inside the REPL itself:
aoc.core=> (require '[better-cond.core as b])
Execution error (FileNotFoundException) at aoc.core/eval1526 (form-init5794080410004864811.clj:1).
Could not locate better_cond/core/as__init.class, better_cond/core/as.clj or better_cond/core/as.cljc on classpath. Please check that namespaces with dashes use underscores in the Clojure file name.
😞not as
, :as
it thinks you want a namespace with as
as a component
Oh my goodness, how silly. Thanks @noisesmith.
Works now. I'll follow up with #cursive.
there's a rarely used feature, you can replace (require 'foo.baz)
with (require '[foo baz])
and due to as being a symbol and not keyword clojure was trying to use that syntax
Could not transfer artifact org.apache.ant:ant:pom:1.8.2 from/to central ( ): Received fatal alert: protocol_version
o_Ohello! I have a really beginner level question regarding protocols and implementing methods. I'm just learning the basics and I hit a problem I don't understand. I'm creating a basic protocol and then using defrecord to implement its method. I have this function that creates instances of the Printer class that implements TestProtcol:
(defprotocol TestProtocol
(test-method [this text]))
(defrecord Printer [prefix]
TestProtocol
(test-method [this text]
(println prefix text)))
(defn hello-printer []
(->Printer "hello"))
(test-method hello-printer "me")
When I try to call test-method I get this error in the repl:
IllegalArgumentException No implementation of method: :test-method of protocol: #'hangman.core/TestProtocol found for class: hangman.core$hello_printer clojure.core/-cache-protocol-fn (core_deftype.clj:568)
Can anyone please point me in the right direction to understand what I'm doing wrong?
The
(defn hello-printer []
(->Printer "hello"))
should be
(def hello-printer
(->Printer "hello"))
i thinkyeah so I was playing with this also and this seems to work:
(test-method (->Printer "hello") "me")
No. I would have expected the function called hello-printer would return an instance of that class. and then the test-method call would happen on that instance of the class
hello, I have question about !swap If I have this line (swap! my_atom assoc (:key id) (function-producting-state x y)) In case if swap! decides to run the assoc again (because somebody did update atom, so it wants to do it on the new value) will my function-producing-state will be also executed twice, or the value is "locked" on the first attempt, and it is just applied to the new atom value, in case if it changed?
swap!
is a regular function, its arguments are evaluated eagerly once, so function-producting-state
is guaranteed to run exactly once. assoc
may be re-run multiple times, and this is safe because it's a pure function.
Hi everyone!
I’m just starting with Clojure and already have several problems with Leiningen, for which I couldn’t find any reference online.
I’m running Leiningen 2.8.3 on Java 10.0.2 (OpenJDK), installed with Homebrew on MacOS Mojave.
When running lein repl
I get the REPL starting, but backspaces advance the cursor to le right, rather than deleting the previous character. This is the first problem.
The second problem arises when trying to use the venantius/ultra
plugin. I changed my .lein/profiles.clj
to look like this:
{:user {
:plugins [[venantius/ultra "0.5.2"]]
}}
and when I run lein repl
get this error:
Warning: implicit middleware found: ultra.plugin/middleware
Please declare all middleware in :middleware as implicit loading is deprecated.
[WARNING] No nREPL middleware descriptor in metadata of #'clojure.tools.nrepl.middleware.render-values/render-values, see nrepl.middleware/set-descriptor!
nREPL server started on port 58327 on host 127.0.0.1 -
ERROR: Unhandled REPL handler exception processing message {:id 9268a5a3-6560-4ba3-89fe-62d372d5aef7, :op clone}
java.lang.IllegalArgumentException: No implementation of method: :send of protocol: #'nrepl.transport/Transport found for class: clojure.tools.nrepl.middleware.render_values$wrap_renderer$reify__3621
at clojure.core$_cache_protocol_fn.invokeStatic(core_deftype.clj:568)
at clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:560)
at nrepl.transport$fn__5123$G__5118__5130.invoke(transport.clj:16)
at nrepl.middleware.session$register_session.invokeStatic(session.clj:149)
at nrepl.middleware.session$register_session.invoke(session.clj:142)
at nrepl.middleware.session$session$fn__5712.invoke(session.clj:193)
at nrepl.middleware$wrap_conj_descriptor$fn__5347.invoke(middleware.clj:17)
at clojure.tools.nrepl.middleware.render_values$render_values$fn__3627.invoke(render_values.clj:42)
at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__923.invoke(middleware.clj:22)
at nrepl.server$handle_STAR_.invokeStatic(server.clj:18)
at nrepl.server$handle_STAR_.invoke(server.clj:15)
at nrepl.server$handle$fn__5743.invoke(server.clj:27)
at clojure.core$binding_conveyor_fn$fn__4676.invoke(core.clj:1938)
at clojure.lang.AFn.call(AFn.java:18)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:844)
at which point the REPL hangs and I have to kill
it from another terminal.Any help with any of these issues would be much appreciated, thank you!
(apparently, no one is complaining about those things online… but I can’t figure out what could be wrong in my configuration)
@piero.cornice Im not sure about the first one, but the second issue is caused by oudated code in the ultra
plugin which doesnt work if youre using lein 2.8.2+. See this comment from me: https://github.com/technomancy/leiningen/issues/2497#issuecomment-446631724 and the following thread for more info. Only solution is to remove it or use lein 2.8.1 or wait for a new release.
thank you @rahul080327, I’ll try with lein 2.8.1
Update: Apparently the first problem (backspace not working properly) went away by re-installing Leiningen:
brew uninstall -f leiningen
brew install leiningen
I’m sure I’ve tried that yesterday with no success, but somehow it worked today.I’m a little bit out of my depth here, but it looks to me like def
does not evaluate its first argument, it just takes literally what’s there. Kind of like a macro, except def
is a special form, not a macro. So the error message you’re seeing is saying “`(symbol "my-id")` is not, itself, a symbol.” It’s a form that evaluates to a symbol, but as far as def
is concerned, that’s not the same thing.
@manutter51 Ahh makes sens. THen how could I implement functionality so that if I have user-defined ID, then I can create atom symbol with that ID, and whenver there is state change, then by ID I can perform atomic swap? So I would have something like (swap! user-defined-id (new-state-of-system x y z))
@olekss.janis maybe use a map? {id1 (atom) id2 (atom)}
I think it’s better to have one atom with multiple keys than to have a map with multiple atoms
But if you have atom with multiple keys, then swap function will be assoc function, but I want my actual transformation to be the update function, so that whenver there is value collision, my function is executed again with new - current atom value
can you give an example of the data you want to store? and the transformed state?
I want to store big map of game-state, which contains players, board etc.... So I want that many players can define their game session and play, and each set of such players would have one atom to update, but the update would be transition from one game state into anoter applied player action THe trick here is that because players might make their turns and "submit" them concurrently, I want the atom to take care of 'retry' of game state update because of this, so if P1 and P2 both submit their version of tame, which is transformation from original 1 state (in the atom), then they both will see the different version as they don't see each others version. One of players will succeed, but another one will not, because atom will notice that it is already changed... and I want so that atom automatically applies P2 transformation on the result produced by P1 in retry attempt
It should work correctly. Let’s say you have an atom containing the map {"id-1" "val-1" "id-2" "val-2"}
. Two threads each try to update the map at the same time, one setting id-1
’s value to “val-1a”, the other setting id-2
’s value to “val-2a”. As long as each one calls (swap! my-map assoc "id-1" "val-1a")
or (swap! my-map assoc "id-2" "val-2a")
you’ll end up with your atom containing {"id-1" "val-1a" "id-2" "val-2a"}
. Re-trying with the new value is what atoms are built for.
and I am ok that P2 might get exception, and resubmits explicitly, in case if his version breakes game rules after P1 transformation...
I try to reduce a sequence this way. The keywords basically are names of performance-counters and the values is the # of times. I think this should be an easy task, but I cannot find the right reduce function. Any ideas?
@UCSJVFV35 (merge-with + {:a 1 :b 1} {:a 1} {:b 2} {:c 5})
? Or if its a list: (apply merge-with + [{:a 1 :b 1} {:a 1} {:b 2} {:c 5}])
yeah clojure generally has some tricks up its sleeve 😉
@manutter51 exactly, but now I want those atoms to be defined by game ids... which might come and go... so to have separate atom to each game session, so that on the server there can be many games...
but it would be stupid to update WHOLE array of games, if I know that particular set of players touch only one game
so naturally - one atom per game state, which is then shared and changed by players
Ok, you can do that with nested maps — it sounds more complicated than it is.
A macro would probably be overkill, you can just use assoc-in
or update-in
for nested maps.
It’s easier to use (assoc-in games-atom [game-session player-id] :new-value)
but assoc-in won't work, then it will be too much false-positives... it means, player will re-apply the transformation function to the legit state, just because somewhere else in the map there is update of the game, not related to THIS players game
@rahul080327 can't merge, as, for example, game rule states, that there can't be more than 5 figures on one game room, so merge might break it "outside" legit transformation function which enforces game rules
ah that answer was for another person 😅
I may not be following your train of thought clearly, but assoc-in
should work just fine for updating separate parts of the map separately. If you have :game-1 and :game-2, and each game has :player-1 through :player5, you can safely apply (swap! all-games assoc-in [which-game which-player] new-value)
, and the end result will be the same as if each swap!
happened sequentially instead of concurrently.
Give me a few minutes, I’ll try and come up with a test program to force a collision and see what happens.
If I did that right, I created 2 threads. One tries to do an update that takes 5 seconds to set :sub-1 :a
to 10, the other runs an update that takes 2.5 seconds to set :sub-2 :b
to 20. The quicker thread completes first, causing the first thread to re-try, but it re-tries with the updated map as updated by the quick thread. The net effect is as if both threads ran sequentially, which should be safe enough for your game management.
if you need greater concurrency, make a map of atoms
unless you need consistency across parts, then you get into stm territory
@manutter51 Ok. Now I see the magic... 🙂 Thanks
hi, seeing a strange issue where a function works fine when it’s run in the REPL but when I load it in from a file via load-file
it’s not getting run.
for example, at the repl this works fine:
user=> (for [[k v] {:one 1 :two 2 :three 3}] (println k " -> " v))
(:one -> 1
:two -> 2
nil :three -> 3
nil nil)
but throw this into a file arnoha.clj
:
(ns arnoha)
(defn foobar []
(do
(println "foo")
(for [[k v] {:one 1 :two 2 :three 3}] (println k " -> " v))
(println "bar")))
and then run it
user=> (load-file "arnoha.clj")
#'arnoha/foobar
user=> (ns arnoha)
nil
arnoha=> (foobar)
foo
bar
nil
arnoha=>
where am I going wrong here?for
is lazy
the repl is forcing it’s realization to print it, but nothing is doing that in the function
you could swap for
with doseq
here
many of the “do” functions work with side-effecting things (like println)
The "P" is "print", and printing a lazy sequence causes it to be evaluated.
or at least as much of it as the printing function is configured to print -- there are some print functions that can be configured to stop printing after N elements, and then they would also stop evaluating at that many elements, or perhaps a few more because of "chunking" optimizations used by some lazy sequences.
why doesn't this return a hash-map of values?
(let [foo (atom {})]
(for [x (range 4)]
(swap! foo conj {(keyword (str "value-" x)) x}))
(str @foo))
I get {}.
for
is lazy
I have had the hardest time trial-and-erroring getting lazy values back out...
it's my main stumbling block at this point.
Lazy sequences and side effect-y things like swap! often do not mix well.
Avoiding side effect-y kinds of things in lazy code is one recommendation. Another is that if you want side effect-y things, force the evaluation of the lazy things with something like doall
, or avoid the use of lazy constructs, e.g. in this case replace for
with doseq
this is a simpler version of my effort to generate a dummy hash-map... I'll play with doseq.
well, dang.
ok. that worked. thx!
Here is another snippet of code that produces the same map, as an alternative that avoids the use of atoms/swap!/etc.: (into {} (for [x (range 4)] [(keyword (str "value-" x)) x]))
thanks @andy.fingerhut, was also under the impression that a (do ..)
block would force evaluation of everything, lesson learned
If one or more of the expressions inside (do ...)
returns a lazy sequence, they will not be forced to be evaluated simply because they are inside of the (do ...)
.
If a lazy sequence is returned by the (do ...)
because it is returned from the last subexpression, something outside of the do
might force it to be evaluated later. If a lazy sequence is returned by a subexpression of (do ...)
that is not the last subexpression, nothing will force it to evaluate, ever.
@andy.fingerhut thank you... the 'into' version is way better!
Total noob at deps.edn. Given the following alias section:
:aliases
{:dev
{:extra-deps
{com.datomic/ion-dev {:mvn/version "0.9.176"}}}
:visualizer
{:extra-deps
{hodur/visualizer-schema {:mvn/version "0.1.1"}
com.datomic/client-cloud {:mvn/version "0.8.66"
:exclusions [org.eclipse.jetty/jetty-http
org.eclipse.jetty/jetty-util
org.eclipse.jetty/jetty-io]}}
:main-opts ["-m" "hodur-visualizer-schema.main"
"hodur-example-app.visualizer"]}
…
How do I run it with the visualizer settings?@d4hines -Avisualizer
while that will work, -A:visualizer
is preferred (the alias flags take a concatenated set of alias keywords like -A:a:b:c
)
Now that I'm looking at that, the ability to express extra deps like that is really nice. Seems like a no brainer, but it's sorely lacking from npm. Good work Core team!
Hello everyone, I am trying to learn ClojureScript, and I am having trouble understanding the -> operator. I have looked up the Arrow (Computer Science) and looked up Monads, and I still don't understand what these functions are doing. Does anyone have a good reference?
(-> a (f 1 2) (g 3 4))
becomes (-> (f a 1 2) (g 3 4))
which becomes (g (f a 1 2) 3 4)
its called “thread-first”
If you want to google about it ^^
you'll find erroneous claims that ->
is thrush - it isn't because thrush is a function combinator and ->
is a syntax transform
eg
user=> (->> (+ a b) (let [a 12 b 30]))
42
It's always fun to try googling for punctuation
thats why haskell has hoogle
yeah when they added the [:> component]
to reagent I had a really hard time googling what [:>
meant
here is a discussion of threading macros: https://medium.com/@hlship/confessions-of-a-threading-macro-addict-5a026dae4af7
Does com.billpiel.sayid.nrepl-middleware only work in the context of a project?
What version of Clojure does lein-repl use outside of a project?
Ok the error that I was running into when running lein repl
outside of a project is because of the middleware depending on clojure 1.9+ but I think lein repl
outside of a project may be using Clojure 1.8 or below.
However, I don’t really need to use lein repl outside of a project and when I do there’s always clj
so I’m not going to worry about this further.
What is the best way to concat two vectors together (vec (concat vec1 vec2))
, (into [] (concat vec1 vec2))
, or (reduce conj vec1 vec2)
?
Whoa that is slick. Thanks once again.
Just to note that into can work with pretty much any collection (lists, vectors, hash-maps)
Different types may result in different ordering though right?
Err nvm, I’ll just try it 🙂
Ah. Different types would cast (idk if that's the term) one collection into the other. "into" is also used to turn one collection into another. For example: (into '() [1 2 3]) would return (1 2 3)
Just played with it (into '(1 2 3) '(4 5 6))
=> (6 5 4 1 2 3)
It’s not a problem for me, just wanted to try and connect some dots from other discussions I’ve seen around here.
of note is that the time is O(n) on size of the second collection (whereas concat is O(1))
there are some alternate data structures outside clojure core that are designed for constant time concat of vector like data (indexed) if that’s what you really need
Good to know. I’m just joining a computationally small list of filename and template pairs in a lein template for organizational purposes so not too concerned about performance.
Actually I should back up. Perhaps there’s a better way to architect this problem. Say I’ve got a list of common files, and based on conditionals, append different vectors of files to it. How would you architect it? My instinct is to
(defn common-files
[]
[".gitignore"
"README.md"
"project.clj"]
(defn fig-files
[files]
(into files
["dev/user.clj" "figwheel-main.edn"]))
(defn shadow-files
[files]
(into files
["package.json" "shadow-cljs.edn"))
(defn request-files
[opts]
(cond-> (common-files)
(some #{"+fig"} opts) (fig-files)
(some #{"+shadow"} opts) (shadow-files))
Changed sets of files
-> vectors of files
. That term was misused.
sets and union?
or is order important ^^?
Not for functionality but would be appreciated for debugging\readability.
you could replace into with something that combines the two vectors and uses distinct
into can use a (distinct)
transducer, but that doesn't take the first collection into account
I think for the nature of this problem I’m not worried about duplicates, values will be known ahead of time.
without threading (into (common-files) (concat (when (some ...) fig-file-vec) (when (some ...) shadow-file-vec)))
where those "vec" values are just the file list vector, without the merging logic
yeah, that shadow-files
and fig-files
append feel off to me. As if it is some form of builder-like interface
precisely, hiding data in clojure is usually a sign you are doing it wrong
a possibility: (def additions {"+fig" ["dev/user.clj" "figwheel-main.edn"] "+shadow" ["package.json" "shadow-cljs.edn"]})
(into common-files (vals (select-keys additions opts)))
you can literally look up the files to add based on the opts as map keys
(reduce into common-files-vec (keep some? [(when (some #{"+fig"} opts) fig-files-vec)
(when (some #{"+shadow"} opts) shadow-files-vec]))
But I think your map idea just kicked my ass
I think that keep some? can be replaced with concat - concat has the right behavior (no-op for nil, add to coll for coll input)
but yeah, the map thing removes conditionals altogether
(require '[clojure.set :as set])
(def files
(set/index
#{{:filename ".gitignore" :collection :common-files}
{:filename "README.md" :collection :common-files}
{:filename "project.clj" :collection :common-files}
{:filename "dev/user.clj" :collection :fig-files}
{:filename "figwheel-main.edn" :collection :fig-files}
{:filename "package.json" :collection :shadow-files}
{:filename "shadow-cljs.edn" :collection :shadow-files}}
[:collection]))
(defn request-files
[opts]
(for [collection (cond-> [:common-files]
(some #{"+fig"} opts) (conj :fig-files)
(some #{"+shadow"} opts) (conj :shadow-files))
{:keys [filename]} (get files {:collection collection})]
filename))
Didn’t even know about clojure.set until now.
ohh, so many problems can be solved with proper set math
Thanks for the help. It’s sometimes tough to stop yourself and ask for advice when you have a quick, working solution in mind to a seemingly small problem but you can learn so much so fast!
haha I sometimes feel guilty for asking too much
That’s true, but I feel less guilty when it’s a smaller generalized problem than issues like “Why does framework x.y.z throw InvalidArgumentException when used with this non-standard nREPL middleware?” I suppose you have to find the balance, fortunately this channel is a bit slow atm.
Hi, all. I am nearing the end of the example problems on 4clojure, and am wondering if there are any other resources for practicing that might help me get my head around any of the more advanced features like async, macros, transducers, etc.
clojure for the brave and true ofcourse, I still have clojure applied on my desk, but reading books is not my forte
https://github.com/eccentric-j/book-report is coincidentally a library I made, using macros, to help make learning from books easier 🙂
CftBaT is one of those great books, if you have read Learn You A Haskell, you will like it very much
I've read through the book, but never did the practice problems, so that makes probably the most sense
Clojure for the Brave and True does have good problems for those topics. I never did quite solve the macro exercise for creating an order-of-operations compliant infix macro but I got the machinery working and moved on. Another option is http://clojurekoans.com/.
I must admit, I don’t write macros that often. They don’t play too well with tooling such as Cursive and I am majorly allergic for IDE errors
my perception as a beginner is that they are only really going to be written as the kind of major workhorse of a larger library
many of the stuff you use is macros, if
/`and`/`or`/…
Right. I've been using evaluation properties of the logic macros to shorten my solutions on 4clojure actually
So I guess other than just syntactic sugar, they are useful for when you need to control evaluation?
but it feels like I already can naturally do that with the provided core library pretty well
yes! I was about to type that! Or when you are a library author that wants to have some custom syntax.

thanks all. I'll check out the koans website once I finish up the 4clojure problems. then will probably do the exercises in BaT, and then seek to grab another book that covers whatever I should learn next
(apply str (drop 1 "hello world"))
Is there a better way to achieve that?
Ah thanks. I was looking for something that in clojure.string. So if it receives nil it blows up?
Tried it. Yes it does.
(subs (str x) 1)
? Maybe that will throw index out of bounds?
Throws index out of bounds, but for the use case it should be fine. Thanks
making a wrapper for subs
that handles index out of range and nil without errors is a fun exercise too