This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # bangalore-clj (1)
- # beginners (29)
- # boot (13)
- # braveandtrue (5)
- # clara (5)
- # cljs-dev (42)
- # cljsrn (7)
- # clojure (55)
- # clojure-france (46)
- # clojure-nl (11)
- # clojure-portugal (1)
- # clojure-russia (268)
- # clojure-spec (26)
- # clojure-uk (32)
- # clojurescript (173)
- # clr (2)
- # core-async (46)
- # cursive (22)
- # datomic (33)
- # devcards (1)
- # emacs (5)
- # events (8)
- # figwheel (2)
- # flambo (4)
- # instaparse (8)
- # jobs (11)
- # klipse (46)
- # lein-figwheel (3)
- # london-clojurians (2)
- # nrepl (1)
- # off-topic (29)
- # om (4)
- # om-next (8)
- # pedestal (3)
- # rdf (4)
- # re-frame (51)
- # reagent (104)
- # remote-jobs (1)
- # rum (4)
- # schema (2)
- # specter (19)
- # untangled (16)
- # vim (52)
I’m reading Aphyr's post - https://aphyr.com/posts/306-clojure-from-the-ground-up-state
And have a problem with the exercise #5 (at the bottom of the page). Here is my current solution:
NullPointerException with it. But, when I replace
delay it work fine.
Answer is correct in both cases.
Any ideas why do I get
NullPointerException when using
future and do not have it when using
you are reading @work outside the
dosync transaction so it could be emptied by the time you enter the transaction. In that case,
(ensure work) returns
first will return nil, and then
+ will throw an NPE - is that what you’re seeing?
Also wondering is it ok to execute
recur inside the
Does that mean that the transaction will be started on the first function call and terminated only after the last call? Does this have some performance problems?
(defn do-work  "Take the first element of `work` and add it to `sum`, until all of the `work` is done(empty)" (dosync (when-not (empty? @work) (alter sum + (first (ensure work))) (alter work rest) (recur))))
olessavluk: there might be a minimal performance overhead. You should be able to move the dosync out of the recursion reasily
@ordnungswidrig I disagree, every time you go into a dosync you have to re-lock all the refs.
Oh really? I thought it would only check for an existing lock but you’re right, the scope can be different.
The only problem with doing more work inside a dosync (transaction) is that you have to throw out more work in the case of a conflict
but summing a few integers is likely to be a small enough amount of work that you might as well just do it that way
but call to recur mean that there will be a conflict with a 100% probability, isn't it?
this all being said, STM is very rarely used in production Clojure code. 99.99% of the time the better route is a atom:
yes, but this is just an exercise to better understand how the refs works and when to use them or atoms
understanding them is fine, I'm just saying don't worry if you don't "get" them right away. I've been programming Clojure professionally for almost 5 years, and I've never seen them in use, or at least in a use that required them.
hm, I thought this is one of the coolest things in clojure so most of the time atoms are enough or you don't even need to share the memory for writing?
> no, conflicts happen with other threads, you only have one thread here I’m running this function in two threads:
(full code - https://clojurians.slack.com/archives/beginners/p1486947230008234) So in my case I will calculate every transaction two (or even more times) because I have recur which will modify refs inside a dosync? Is that correct?
(defn calc  "Calculate `sum` using two workers" (let [a (future (do-work)) b (future (do-work))] @a @b) @sum)
I would guess that one thread would get done first, update
work, and then the other thread would retry with an empty
work and basically do nothing. Is that what you're seeing?
I feel like the Clojure STM is underrated, but on the other hand I’ve never encountered a situation where an atom didn’t suffice either ¯\(ツ)/¯
Yea, it is underrated, but I see it as a example of how much leverage you can get out of other models, CAS (atoms) + immutable data are just so powerful and simple, they often trump other more complicated methods.
Never underestimate the performance you can get out of a single thread when it is properly optimized, and unconstrained cross-thread synchronization.
having some trouble thinking through a java interop issue, would love some input. newish to the jvm so pardon me for working out the kinks in my mental model.
I need to implement an instance that satisfies an interface with a single method. this instance will then be passed to a method that expects a
in an ideal world I’d love to be able to pass the body of the function in at instance creation time, as opposed to specifying it in advance
I initially reached for invoking
reify, but it seems like reify doesn’t actually return a class instance. if there’s a way to cast it to a class that would be ideal.
based on https://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/ I then figured
defrecord would be the ideal function to use.
my q is: can I avoid creating a defrecord for each invocation of a different function body? in a situation like:
I would assume that each invocation of
(defn make-an-instance [my-func] (defrecord MyRecord  my.interface (interface-method [this] (my-func))))
make-an-instancecreates a new MyRecord object that won’t get garbage collected – I hope I’m wrong about that. would appreciate any insight that anyone can provide