This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-02-03
Channels
- # beginners (48)
- # boot (26)
- # cider (7)
- # cljsrn (1)
- # clojure (137)
- # clojure-nl (1)
- # clojure-spec (5)
- # clojure-uk (18)
- # clojurescript (26)
- # cursive (8)
- # datascript (4)
- # datomic (4)
- # defnpodcast (11)
- # docker (1)
- # duct (7)
- # figwheel (4)
- # fulcro (7)
- # off-topic (7)
- # re-frame (46)
- # reagent (40)
- # reitit (3)
- # shadow-cljs (4)
reduce
is left to right. is there a generic way to reduce right to left, without a) reversing the collection or b) using the reducers library?
https://stackoverflow.com/questions/16800255/how-do-we-do-both-left-and-right-folds-in-clojure
seems like the answer is, 1) try not to need foldr and 2) use the reducers library
sorry - that is, reversing list or seq is not cheap, you need to consume the whole thing in order to construct it, a vector is cheap because there's a simple way to consume it end to beginning order, rseq
packages that as a feature
i take it it's idiomatic to recursively invoke a function if you are handling multiple arities. can anyone confirm?
e. g.
(defn tax-amount
([amount]
(tax-amount amount 35))
([amount rate]
(Math/round (double (* amount (/ rate 100))))))
because even though the stack frames will be left open, it won't be very deep?
right - it's bounded to one - there's a lot of standard clojure idioms that go deeper than that
user=> (source assoc-in)
(defn assoc-in
"Associates a value in a nested associative structure, where ks is a
sequence of keys and v is the new value and returns a new nested structure.
If any levels do not exist, hash-maps will be created."
{:added "1.0"
:static true}
[m [k & ks] v]
(if ks
(assoc m k (assoc-in (get m k) ks v))
(assoc m k v)))
unless you create an extra local binding to represent the pending parent data structures as you go
because an extra local to capture the pending data structures increases the complexity of the code quite a bit
be wary of get-in
, assoc-in
et. al if you’re trying to write tight loops with high performance, they are fast enough for general use but in those cases they don’t cut it
@U3L6TFEJF what alternative to assoc-in
would you use if you did need the performance?
for me, two options: either https://github.com/nathanmarz/specter, or write a method and unroll it manually
see https://gist.github.com/nathanmarz/b7c612b417647db80b9eaab618ff8d83 for some examples
and gratifying to see confirmation that "querying and transforming nested and recursive data is complex in vanilla clojure"!
if the recursion depth is known at invoke time and is quite small no reason to avoid recursion
maybe it's that with nested maps, in order to add another innermost map, you have to traverse the entire nested structure. and you'd do that every loop, going one level deeper each time
i think you have to keep track of the sequence of keys you used to get to where you are as well as the in-progress, pending result
compared to cons-ing a list together item by item as you go, for example, where there's no need to understand "where you are" in that list
in an imperative style, you'd have a cursor and mutate as you go and have no need to recreate the map as a whole every time
as opposed to either imperative style in place mutation or real recursion, loop/recur
seems to be uniquely difficult