This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-09-17
Channels
- # aleph (3)
- # bangalore-clj (2)
- # beginners (76)
- # boot (37)
- # braid-chat (7)
- # business (1)
- # clara (1)
- # cljsrn (45)
- # clojure (36)
- # clojure-android (1)
- # clojure-austin (2)
- # clojure-dusseldorf (4)
- # clojure-spec (2)
- # clojure-uk (2)
- # clojurebridge-ams (4)
- # clojurescript (79)
- # clr (1)
- # community-development (5)
- # core-async (1)
- # cursive (4)
- # data-science (1)
- # funcool (3)
- # hoplon (3)
- # om (107)
- # om-next (6)
- # other-lisps (1)
- # overtone (1)
- # planck (2)
- # reagent (24)
- # rum (1)
- # specter (7)
- # yada (46)
How do you assoc a key at the end of a map?
@snoonan is correct. If you want to do ordering or filtering of a map you can use sorted-map
or keys
.
Note that sorted map will keep the entries sorted by key, it does not mean map that keeps the order entries were inserted. If you want to keep that kind of order just use a vector of pairs
:thinking_face: my repl was working fine yesterday but now it won't load, apparently because of SLF4J
failing to load... I have no idea what that is. didn't add any new dependencies.
It was... code? something in my code was causing it to fail... commented out everything except static definitions and now it works. š
if you're ok with just stubbing, i.e. replacing the call with a canned response, than with-bindings
is probably enough. You probably have a wrapper function that does the actual API call, so redefine that in your test
sorry, I meant with-redefs
https://clojuredocs.org/clojure.core/with-redefs
(deftest my-test
(with-redefs [do-api-call (constantly {,,, some canned response ,,,})]
(is (= ,,, ))
))
if you really want mocking, i.e. being able to assert how many requests are made, with which args, etc, then something like memocks might help https://github.com/siilisolutions-pl/memocks
---- Compiler Warning on <cljs form> line:1 column:2 ----
Use of undeclared Var cljs.user/doc
1 (doc map)
^---
---- Compiler Warning ----
#object[TypeError TypeError: Cannot read property 'call' of undefined]
nil
the clojure repl includes these in the user
namespace, I would expect ClojureScript repls to do the same for cljs.user
, but apparently not
@filipecabaco (into [] (remove #(rem? % step)) acc)
instead of (doall (remove #(rem? % step) acc))
brings the time down another 50% for me
Interesting...
FWIW, Planckās doc
macro is referred into cljs.user
iff you are starting a REPL by doing this at startup (require '[planck.repl :refer-macros [apropos dir find-doc doc source pst]])
@plexus Yes. But, for example, if you ārunā a cljs
file using Planck (so that it essentially doesnāt go into interactive REPL āmodeā), this is skipped.
ClojureScript REPLs do this: https://github.com/clojure/clojurescript/blob/7e90ad51452ec5edd8ee7f2b7af9c7e7fb759c97/src/main/clojure/cljs/repl.cljc#L823-L824
I'm using figwheel over nREPL, maybe that's the problem, let me compare with a regular lein figwheel
hmmm nevermind, works just fine after a restart, both on a terminal and over nREPL. Not sure what I was doing before.
@vjunloc as long as you're in the cljs.user
namespace it should work. If it doesn't then something is wrong and you'll have to tell us some more about your setup
@petterik any idea why it improves performance so much?
xposting here - this may be newb question. https://clojurians.slack.com/archives/cursive/p1474128934000362
@filipecabaco to understand the performance improvements, check out transients and transducers
definitely advanced topics you needn't care about as a beginner š
Will check, get amazed and then go back to basics š
@filipecabaco it might have to do with chunked sequences, but I'm not sure. If you look at (source filter)
(which remove
uses), you'll see that there's a special case for (chunked-seq? (seq coll))
. The coll
in your case is what's returned from take
which is not a chunked seq: (chunked-seq? (seq (take 1 [1])))
=> false
In the sieve using (into [] (remove ...))
, we're using the transducer api instead of the sequence api, avoiding seq's and chunked-seq's all together (for lack of a better explanation).
@filipecabaco Also, this is just a guess. I leave it to you to find out if this is the case š
@plexus I am not sure of the exact term, but basically as you type in the repl and you provide a closing parenthesis ")" the repl sort of matches it with it's corresponding opening parenthesis
I don't think any terminal based repl will give you that. If you run it inside emacs you can use show-parens-mode (I think that's what it's called)
And my boot-cljs setup is nothing fancy, i simply followed this guide - https://github.com/magomimmo/modern-cljs/blob/master/doc/second-edition/tutorial-01.md
@petterik thanks for the explanation and yep will check the way! That's half the fun :)
@vjunloc Iād encourage you to set up https://github.com/bhauman/lein-figwheel/wiki/Using-the-Figwheel-REPL-within-NRepl, and use your editor of choice to interact with it. REPL Driven Development is great, and setting up your environment like this will definitely pay off in the end
Iām a bit confused with recurās description at https://clojuredocs.org/clojure.core/recur, and I read, that clojure wonāt do proper tail call optimisation unless I explicitly use recur, is that correct? Does that mean, I have to use recur, to do arbitrary recursion (self function) calls in clojure?
Naive, classic factorial example I came up with wonāt do TCO, right:
(defn factorial[n] (if (= n 0) 1 (* n (factorial (dec n)))))
as opposed to the example presented at recur docs:
(def factorial
(fn [n]
(loop [cnt n acc 1]
(if (zero? cnt)
acc
(recur (dec cnt) (* acc cnt))
; in loop cnt will take the value (dec cnt)
; and acc will take the value (* acc cnt)
))))
Yeah I shouldāve followed this: http://clojure.org/reference/special_forms, thereās more to it:
"Note that recur is the only non-stack-consuming looping construct in Clojure. There is no tail-call optimization and the use of self-calls for looping of unknown bounds is discouraged. recur is functional and its use in tail-position is verified by the compiler.ā
I think this answers my question
Correct, direct recursion does not use TCO. recur
essentially replaces the call with a loop under the hood, rebinding the arguments.
loop
/ recur
is a similar construct.
Note that Clojure only lets you use recur
where it can convert it to a loop, i.e., only in a valid tail recursive position. That means that if recur
is legal, you are guaranteed you get the optimization. This makes things much more predictable than languages that attempt to do automatic TCO because you can see from the code directly whether or not you have a recursive call or an optimized-to-loop call ā and you canāt "force" TCO where it isnāt possible.