let's say I have 3 threads that will modify some vec. The threads can add or change stuff in it. Whenever vec reaches a certain size, I want to do some side effects and reset it to be empty. I tried this with an atom to hold the vec and add-watch
to fire the side effect and reset!
, but it seems that the threads might see the atom in its old state after the side-effect is performed but before the atom is reset
yeah, watchers are not synchronous to the change so that's not a viable option. really if you need to trigger side effects atoms aren't going to work. maybe an agent would be an option?
so I do the side effect and reset the agent inside a send
?
You could also use compare-and-set! on the atom instead of swap!
And if you successfully cas in the empty vector do the side effect
how can use clojure with clojurescript? I know I can just create files and stuff, but how would I create a lein project that uses both clojure and clojurescript
create your clojure project with leiningen then use leiningen's plugins such as lein-cljsbuild
, or figwheel
for managing your clojurescript codes
can you give like an example? if possible? like lein new compojure hello-word
and then?
@mavbozo forgot to tag
@sunchaesk you can use luminus template https://github.com/luminus-framework/luminus-template to create clojure & clojurescript based webapp in a leiningen project. lein new luminus my-project +cljs
.
the function distinct
will give me the sequence with duplication removed. How can I find the actual duplicates? Of course I can write a function to do this, but it seems there should be a sister-function to distinct
can't recall whether sister-function to distinct
exists, but maybe frequencies
helps you get there
yes group-by
probably does have n log(n) complexity while my recursive approach has n^2 complexity
converting n^2 to n log(n) is worth making the code less readable.
Currently I have just written a local function:
(find-duplicates [items]
(loop [items items
duplicates []]
(cond (empty? items)
(distinct duplicates)
(member (first items) (rest items))
(recur (rest items)
(conj duplicates (first items)))
:else
(recur (rest items)
duplicates))))
I'm not really concerned about performance as this code is only called in an error message. However, if there's a simple way to do it the code will of course be more understandable when I look at it again in a few months.
BTW, member
is defined elsewhere as
(defn member
"Like cl:member. Determines whether the given target is an element of the given sequence."
[target items]
(boolean (cond
(nil? target) (some nil? items)
(false? target) (some false? items)
:else (some #{target} items))))
i use frequencies
to get the duplicates like this
(->> (frequencies [1 2 3 1 3 4 3 2])
(remove (fn [[k v]] (= 1 v)))
(map (fn [[k v]] k)))
;; ;; => (1 2 3)
is that the same as?
(->> (frequencies [1 2 3 1 3 4 3 2])
(remove (fn [[k v]] (= 1 v)))
(map first))
(partition-by identity [1 2 2 2 3 4 4 1 1 1])
((1) (2 2 2) (3) (4 4) (1 1 1))
if the succession is important - I think this is more like an alternative approach to dedupe
Yes, which is the same as:
(->> (frequencies [1 2 3 1 3 4 3 2])
(remove (comp #(= 1 %) val))
(keys))
the function <http://clojure.java.io/delete-file|clojure.java.io/delete-file>
apparently accepts a string, naming a file, and attempts to delete the file. Is there such a function while will tell me whether the file exists? I'm not so gifted in interfaces into the mysterious java world.
Am I the only one who believes that that snippet does not express the intent: find-duplicates
??
somewhat reminiscent of Perl coding from the 1990s.
( ($h{$_}++ == 1) || 0)
($l=join("",<>))=~s/.*\n/index($`,$&)>=$[||print$&/ge;
(defn exists? [f]
(.exists (<http://clojure.java.io/file|clojure.java.io/file> f)))
using https://docs.oracle.com/javase/7/docs/api/java/io/File.html#exists()
IMO that snippet reads fine to me unlike that perl code :P
I go back to perl whenever my company has code golfing tournaments
I’d use group-by
With identity
this seems like spam, especially for the beginners channel
mapping over the same collection multiple times can be space-inefficent, right? for example (->> xs (map f1) (map f2))
. if so, is sequence
a solution? eg (sequence (comp f1 f2) xs)
(map (comp f2 f1) xs)
should work as well
oh, that's great news. thank you!
also (comp (map f1) (map f2))
i'm not sure this works the way you might expect
because (map f1)
doesn't return a function that takes a collection, applies f1
to every element
it returns a transducer (i think)
((comp (map inc) (map dec)) [1 2 3])
;; => #function[clojure.core/map/fn--5847/fn--5848]
in other functional languages, i would expect (map f1)
to essentially do partial application.
I think I meant (map (comp (map f1) (map f2)) xs)…that is you can compose the transducers, which is suppose to be more efficient then ->> solutions.
(map (comp (map inc) (map dec)) [1 2 3])
;; => (#function[clojure.core/map/fn--5847/fn--5848]
;; #function[clojure.core/map/fn--5847/fn--5848]
;; #function[clojure.core/map/fn--5847/fn--5848])
???I’m messing up the correct way to compose and use transducers…let me look into it
it's really counter-intuitive! IMO
(def xf (comp (map inc) (map inc)))
(into [] xf (range 1000))
My understanding is that there is no intermediate collection created between the maps, so its as memory efficient as possible
also look into the “transduce” function
how do you understand the difference between into
and sequence
? sequence
is lazy?
sequence is lazy, yes
so if i expect the entire transformed collection to be consumed, sequence
may be overkill? and i should favor into
?
usually transducers are used in situations where you want to avoid laziness, so in practice sequence is very rarely used
I'd start with your use case - do you need indexed lookup? do you need fast membership testing?
and pick the data structure that performs best for your usage
i don't need those things, no. all i want to do is apply a series of map
s and mapcat
s over a vector to create a new vector. normally i'd use (->> xs (map f) (mapcat g))
and not worry about the inefficiency
i'm not sure i quite follow why the data structure question is relevant? can you put it another way?
that mapcat won't return a vector
the first question is what data structure you need, if all that matters is that the result be ordered (lazy seq or vector) then you can look at secondary concerns
and finally efficiency may or may not be a concern
... on reflection, i don't need my results to be ordered. and duplicate elements in the collection aren't meaningful to me. i was using the term vector
carelessly.
in that case you might want (into #{} ...)
what are you doing with the resulting collection?
... i'll use it to test membership - like i said i didn't need. if an element in present in the resulting collection, that will influence how i handle another set of values.
thank you @noisesmith and @steven.katz
!
If I have the following data set, how to I get the totals for each country in a map with each countries total (without writing a loop-recur preferably)
[{:date "10-10-2020" :england 3665 :scotland 821 :wales 56 :northern-ireland 821}
{:date "09-10-2020" :england 5593 :scotland 833 :wales 194 :northern-ireland 888}
{:date "08-10-2020" :england 11601 :scotland 845 :wales 486 :northern-ireland 1029}
{:date "07-10-2020" :england 13871 :scotland 1019 :wales 724 :northern-ireland 1087}
{:date "06-10-2020" :england 13997 :scotland 1195 :wales 708 :northern-ireland 846}
,,,
]
So the output wold look likke
{:england 43343 :scotland 44343 :wales 3232 :northern-ireland 343}
Huh, so you actually have 4 data points per row
And the date field "doesn't count"
?
dissoc :date and merge-with +
Smart
hcl in lt
@rakyi ah, this seems to work (apply merge-with + (map #(dissoc % :date ) data))
Is that what you meant? data
is the data set above
yes
I thought you’d easily figure it out given the hints 🙂
A more long-winded approach, based on a whitelist.
Anybody make any apps for android via cljs?
I love this solution purely for the number of core functions you manage to use together :)
I want to make a "native app" using CLJS... wondering if I can use any react-ish library and package it somehow ?
React Native and ClojureScript seems to be the most common approach... That way you also should get other mobile devices supported too..
Take a look at these resources...https://cljsrn.org/
There is also a #react-native and #clojure-android channels in case your request gets lost in the general beginners channel
react-native was once the choice for that, might still be
Hi! I'm implementing a negamax search (https://en.wikipedia.org/wiki/Negamax ) to use in combination some reinforcement learning. I just brute-forced it with a recursive function, but was wondering if people could give some feedback on obvious ways to improve it. Speed is my main concern, but happy to learn about anything that is an anti-pattern/not clojure-onic also:
(defn negamax
[q-values game-state depth]
(cond
(pol/finished-game? game-state) (pol/reward game-state)
(= depth 0) (pol/get-value q-values game-state)
:else (let [actions (pol/get-available-actions game-state)
depth (dec depth)]
(apply
max
(map
(fn [action]
(- (negamax q-values
(pol/apply-action game-state action)
depth)))
actions)))))
q-values
is a neural-net, game-state
the position in the game (in tictactoe e.g.)
Not core to the function I think, but finished-game?, reward, apply-action and get-available actions are methods of a protocol:
(defprotocol GameState
(finished-game? [this] "Tests if game is finished")
(reward [this] "Gives reward for state")
(get-available-actions [this] "Gives all available actions from this state")
(apply-action [this action] "creates new state through action"))
Hope I'm posting this in the right place! 🙂So the first thing to consider is whether some sort of alpha/beta cutoff would work for you. That can hugely reduce the search space.
I also assume you can memoise some of the GameState functions (in chess engines you build transposition tables because different sequences of actions can lead to the same position)
In terms of Clojure stuff, you could look at parallelising stuff a bit more. Given that you’re just exhaustively searching to a certain depth this should work well.
Thanks! alpha/beta was going to be my next step, but thought asking this with the basic negamax was clearer. Are there any clojure related changes that could help? I've never used type hinting for example, useful here?
parallelising seems like a good idea indeed! A very naive memoising the whole function didn't seem to help (not sure why, the inputs being too complex?), but something to try to improve
Type hints definitely can help, have a look at https://clojuredocs.org/clojure.core/warn-on-reflectionhttps://clojuredocs.org/clojure.core/warn-on-reflection. Also worth turning on warnings for boxed math(s): https://insideclojure.org/2014/12/15/warn-on-boxed/