This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-04-29
Channels
- # announcements (4)
- # architecture (1)
- # beginners (113)
- # boot (17)
- # calva (40)
- # cider (9)
- # clara (1)
- # cljs-dev (21)
- # cljsrn (21)
- # clojure (47)
- # clojure-dev (8)
- # clojure-europe (2)
- # clojure-italy (46)
- # clojure-nl (10)
- # clojure-spec (1)
- # clojure-turkiye (1)
- # clojure-uk (46)
- # clojurescript (102)
- # core-async (21)
- # cursive (35)
- # data-science (1)
- # datomic (7)
- # emacs (2)
- # graphql (1)
- # lumo (15)
- # nrepl (4)
- # nyc (1)
- # off-topic (5)
- # overtone (3)
- # pathom (10)
- # quil (6)
- # re-frame (30)
- # reagent (7)
- # reitit (33)
- # rewrite-clj (1)
- # shadow-cljs (37)
- # spacemacs (73)
- # test-check (3)
- # testing (2)
- # vim (59)
If I want to execute 2 statements in each branch of an if statement, I can wrap them in do:
(if x
(do (a!) (b x))
(do (c!) (d x))
To me this seems a bit ugly. Is there a preferred way to do this?
I could wrap each branch in it’s own function?its not ugly, just format like that, so each expression on its expected place
(if x
(do (a!)
(b x))
(do (c!)
(d x)))
Wrapping each in a function could be nice if you give each function a descriptive name. That way your if
can become almost documentation in itself.
Say I have a map and I'm destructuring like so: (let [{prefix :prefix suffix :suffix} config] (do (println (or suffix ".html")) (println (or prefix "foo/"))))
, I was wondering if there was a more idomatic way of "defaulting" values for keys that aren't set. I see that destructuring, you can use ":or", but that seems to work only once.
you can merge defaults in. (let [{:keys [prefix suffix]} (merge inputs defaults)] ... )
:or should work for more than one key. Also, I think you should merge the input into the defaults.
(let [{prefix :prefix :or {prefix "foo"} suffix :suffix :or {suffix "bar"}} config]....
I think the merge would end up being cleaner, as although my example only has two keys, I actually need a config map of about 10 or so options, with defaults for each
how to use threading macro ->>
with something like dissoc
?
@cybersapiens97 What are you trying to do? Pass in a list of keys to be dissoc
'd?
(->> stats
(filter #(= (:isalbum %) 1))
(dissoc :id :userid :isalbum)
(clojure.set/rename-keys {:medianame :title}))
dissoc
needs hashmap as first argument
so does clojure.set/rename-keys
@cybersapiens97 are you sure that you want the updated stats as the last argument of rename-keys
? I think you want it as the first arg?
(-> stats
(->> (filter #(= (:isalbum %) 1)))
(dissoc :id :userid :isalbum)
(clojure.set/rename-keys {:medianame :title}))
seems more likely correctSo I would probably do this:
(-> (filter #(= (:isalbum %) 1) stats)
(dissoc :id :userid :isalbum)
(clojure.set/rename-keys {:medianame :title}))
Ah, good point @dpsutton
that's the problem, i think i can't use threadring macro on this situation
You want to map those things over the list. Use a transducer 🙂
well, didn't thought about map
on this situation i think it's better
thanks
good practice to write it with the thread macro and then make a transducer version right after
(->> stats
(filter ...)
(map #(-> % (dissoc :id :userid :isalbum) (set/rename-keys {:medianame :title}))))
how about that?I'd probably write a function for the data cleanup and then it would be (->> stats (filter ...) (map cleanup-media))
yeah i'll do it later because right now i'm finishing some handler functions from Ring
but i realized that it wasn't a good idea handling data transformation directly in handlers
i'll hand this to the specific components and pass directly the http requests that i receive to them. so i can receive the data in the correct shape directly on the handlers
otherwise my handlers end up being a complete mess
very sad because i'll have to refactor a lot of code, but this was a great insight
Doing some cljs interop and I found myself writing this:
(->> (.. js/document (createElement "div"))
(#(.. js/document -body (appendChild %))))
It always feels ugly to do (#(.. js/document -body (appendChild %))
. Is there a cleaner way to do this that I am just not seeing?(->> (.. js/document ...) appendChild (.. js/document -body))
- ->> isn't semantic, it's syntactic, so it doesn't matter that appendChild has no meaning outside the .. call
the compiler sees the right thing in the output
also I think (->> js/document (.-body) (.appendChild (.createElement js/document "div"))
is equivalent, I don't have a cljs to test it on right now though
Thanks! I will give those a try 🙂
For a vector
say [0 0 0 1 0 1 0 0 0 0 1 0 0]
, I would like to return a vector
with occurrences of >=3 0s
trimmed to 00
Played around with frequencies, subvec, remove, take-while. filterv
, still not cutting it...
@simon i don't understand what you are trying to say, provide sample input->output data
YOLO first attempt.
above as transducer + minor optimizations
(def v1 [0 0 0 1 0 1 0 0 0 0 1 0 0])
(def x-trim (comp (partition-by identity)
(mapcat (fn [s]
(if (and (zero? (first s))
(>= (count s) 3))
[0 0]
s)))))
(transduce x-trim conj v1)
remove the flatten, use mapcat instead of map.
(into [] (x-trim) v1)
might work faster, it uses a transient data-structure when appending.
@vincent.cantin tested with criterium, for 1,10,1000k elements barely any difference
(map #(criterium.core/quick-bench (into [] (x-trim) %)) [ve3 ve4 ve6])
Execution time mean : 198.320130 µs
Execution time mean : 2.201093 ms
Execution time mean : 218.993782 ms
(map #(criterium.core/quick-bench (transduce (x-trim) conj %)) [ve3 ve4 ve6])
Execution time mean : 256.688980 µs
Execution time mean : 2.587495 ms
Execution time mean : 259.473071 ms
Also, x-trim does not have to be a function. A simple def
is fine too.
there is no difference because we create a new trie so transients do nothing, they are useful for updates
not sure how into
can utilize that feature
oh i remember, transient collection uses extended tail node, so there is minor boost
What is the go-to method of adding gradual typing to Clojure? I assume there aren’t any tools to add actual static types? Just type hints and such? Similar to Python and Elixir?
Which one is that? https://github.com/clojure?utf8=%E2%9C%93&q=spec&type=&language=
note that there’s now a spec2 under active development. lots of things are still in flux. and spec is definitely not intended to replace types
spec is designed as a testing tool. spec somewhat replaces types if you believe generative testing can replace a type system
yeah i'm not arguing, i just think type systems and data verification\\contracts overlap in their nature
I'm not sure i'd agree that spec replaces (static) typing
it's runtime, right?
right on
hope that didn't come across as a pile on. 🙂 i agree there's overlap there
np, words are hard to master, always had a problem of choosing right words, my mind is more objective\abstract
@UCF779XFS I think considering spec as a "testing tool" is overly narrow. Our biggest use of spec at work is definitely in production code rather than testing code.
I agree that spec doesn’t need to be only a “testing tool”, but the design has favored that use case (e.g., requiring generators for fn arguments)
and it feels like I’m working against the language/library when using specs for runtime “type” checking
to be fair, it’s under development. but the direction of spec2 doesn’t seem to be different
We're using spec very heavily in production -- and have been for a long time -- and we have a branch running on spec2, ready to go as soon as Alex signals it is "stable".
We're looking at schema
/`select` as a way to consolidate several current layers of specs -- they should share a common schema
and then have specific select
variants in different parts of the code.