This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-11-05
Channels
- # bangalore-clj (5)
- # beginners (77)
- # boot (29)
- # cider (11)
- # clojure (110)
- # clojure-dev (5)
- # clojure-greece (1)
- # clojure-poland (1)
- # clojure-russia (11)
- # clojure-spec (1)
- # clojurescript (143)
- # clojurex (1)
- # core-async (1)
- # css (1)
- # cursive (40)
- # data-science (1)
- # datomic (6)
- # figwheel (4)
- # fulcro (45)
- # immutant (5)
- # off-topic (4)
- # onyx (8)
- # portkey (9)
- # re-frame (112)
- # shadow-cljs (30)
- # spacemacs (3)
I see there are quite a few ways to convert strings to numbers. Is there a best practice for this? The strings I want to convert are always, in this case, going to be numeric strings.
My approach right now is using cljs.reader/read-string
@tkjone It may depend on the details of what you want. But, generally speaking, I'd recommend you stick to the most restrictive thing that works. In this case, that might be Integer/parseInt
/ Double/parseDouble
.
read-string
does a lot of different things, which can lead to some unexpected bugs later on down the line.
yeah, thats what I was worried about. Thanks! I will update to Integer
@tbaldridge Thanks!
Hey guys, this might be a stupid question-what are "special forms"?
I looked up pieces of clojure syntax like def and let, and I see in the clojure docs that they are called "special forms".
But I'm wondering what they are under the hood. Are they functions? Are they macros? Or is there something more "special" about them?
special forms are implemented in java as part of the compiler
they are outside the normal things that are all implemented as regular java classes or as clojure code - they are special symbols the compiler looks for that guide the compilation of code
eg. let (or really let* which let uses) because it can create bindings, if because it can select which things execute at runtime, fn (actually, fn* which fn uses) because it can bind and capture values and make code that runs later
also do and quote
intersting, so is it possible for me to write custom special forms in my clojure project?
not really, you’d have to fork the main clojure project to do so
the good news is that you don’t need to
everything else in clojure is defined in terms of the special forms and the basic rules for evaluation (eg. numbers evaluate to themselves)
if you’ve never read through https://github.com/clojure/clojure/blob/clojure-1.9.0-beta4/src/clj/clojure/core.clj
it’s kinda neat watching the language bootstrap itself from such few primitives
even defn
isn’t a special form
interesting. thanks!
Is there some turnkey solution for attaching debug messages to functions down a call-chain, but adding extra context I only have up the call chain? Maybe something like dire
lib, but having more context than the original args. Kinda like a reverse exception.
For example, I have a corralation-id
that I'd like included in all messages, but I don't want to propagate it everywhere.
Is there a quick way to reset a namespace in nREPL using Emacs and Cider?
I am writing some ClojureScript and I have run something every few seconds. My current implementation is using js/setInterval
but I wanted to know if there is a more idiomatic way of doing this?
@lvbarbosa when you are in the repl, hit ,
and you should see a menu pop up. there should be an option for ,refresh
. in addition there is cider-refresh
which should do what you are asking I think
hi…
is there an easy way to get the field??
(pr-str (:pred %1)) "clojure.core/contains?")
the value from pred is (clojure.core/fn [%] (clojure.core/contains? % :phone))
the full of spec (explain-data) is {:path [], :pred (clojure.core/fn [%] (clojure.core/contains? % :phone)), :val {:type "company", :document {:number "123", :x 1}}, :via [:atrium.company.validator/company], :in []}
hey guys, I would expect this code to print "hi 1", "hi 2", ...
But it just prints "hi " nil, and I'm not sure why.
(map (prn "hi " %) [1 2 3 4 5])
The code you’ve putted above throws an error, here is the code
(map #(prn "hi" %) [1 2 3 4 5])
Interesting, what is the reason for adding the #? Does it have to do with map returning a lazy seq?
ahhhh ok true.
but then if I do (map (fn [& args] (prn "hi " %)) [1 2 3 4 5])
it doesn't print the numbers anymore
like this?
(map (fn [& args] (prn "hi " (get args 0))) [1 2 3 4 5])
get won't work on a list, you'll need nth
+user=> ((fn [& args] (get args 0)) "a" "b" "c")
nil
+user=> ((fn [& args] (nth args 0)) "a" "b" "c")
"a"
or eg. first if you just want the first arg, or destructuring if you want to bind multiple args to names by position
@rcustodio also #() isn't a macro for (fn [& args]) - it decides how many args to create based on how many you use in the body
+user=> '#(do %)
(fn* [p1__165#] (do p1__165#))
+user=> '#(do % %2 %3)
(fn* [p1__168# p2__169# p3__170#] (do p1__168# p2__169# p3__170#))
+user=> '#(do % %2 %3 %&)
(fn* [p1__173# p2__174# p3__175# & rest__176#] (do p1__173# p2__174# p3__175# rest__176#))
so really the translation there is (fn [x] (prn "hi" x)) or #(prn "hi" %)
or, another valid translation if you want to try a classic fp style is (partial prn "hi") which returns a function that adds all args to the arg list of prn and then calls it
+user=> (map (partial prn "hi") [1 2 3])
("hi" 1
"hi" 2
"hi" 3
nil nil nil)
atrium.core=> (string/join " " (re-find #":[a-z_-]+" "(clojure.core/contains? % :email)"))
": e m a i l"
why is doing that?@rcustodio Not sure what you're asking there -- which part of the result don't you understand?
(map #(string/join " " (concat (map (fn [x] (str x)) (:path %1)) (str (re-find #":[a-z_-]+" (pr-str (:pred %1)))))) (filter #(string/includes? (pr-str (:pred %1)) "clojure.core/contains?") (:clojure.spec.alpha/problems (validator/assert {:type "company" :document {:number "123" :x 1}}))))
I will use concat to get the “path” in nested, but when I use join , this happens
(": c o r p o r a t e _ n a m e" ": c o u n t r y" ": b i l l i n g _ a d d r e s s" ": a d d r e s s" ": e m a i l" ": p h o n e" ":document : t y p e")
thanks guys that helps. Although, when I do (map (fn [x] (println "hi " x)) [1 2 3 4 5])
I see that it returns the strings but doesn't print anything to the console.
map
is lazy: it's only meant to be used with pure functions. for side-effects (like println
), use run!
or mapv
@U2UJ5Q8LD
(let [foo (map (fn [x] (println "hi " x)) [1 2 3 4 5])])
nil
(let [foo (run! (fn [x] (println "hi " x)) [1 2 3 4 5])])
hi 1
hi 2
hi 3
hi 4
hi 5
nil
thanks!
@rcustodio (str/join " " "Hello!")
will produce "H e l l o !"
re-find
produces a string, not a collection. str/join
expects a collection so it implicitly calls seq
on its argument.
Right, and str/join
would work on that -- but you don't have that. You have a string, not a collection.
Use re-seq
instead of re-find
and you'll get a sequence.
boot.user=> (str/join " " (re-find #":[a-z_-]+" "(clojure.core/contains? % :email)"))
": e m a i l"
boot.user=> (str/join " " (re-seq #":[a-z_-]+" "(clojure.core/contains? % :email)"))
":email"
This feels like a dumb question but how do you express this js in clojurescript var map = new mapboxgl.Map({container: 'map',style: '
You might something like this
(def map (Map. mapboxgl #js {:container "map" :style ""}))
Thanks for the help, but it’s still not working. A potential problem is that I am just pulling the js in a html script tag and trying to call the functions as no one has made a cljsjs of mapbox yet.
@matt.a.renfro Okay, I was able to get it to work like this:
(def newmap (.-Map js/mapboxgl))
(newmap. #js {:container "map" :style ""})
If you still want to assign it to map like in your js example of var map = ...
. you would do this:
(set! js/map (newmap. #js {:container "map" :style ""}))
For future reference, CLJS should be able to call any global/namespaced JS code. This is one of its strengths.
The part that confuses me, and maybe someone else could provide an answer, is how to call the constructor Map
in one line. So how would one make this line work:
(set! js/map (Map. js/mapboxgl #js {:container "map" :style ""}))
The issue is with Map.
but I am not quite sure how to make it work, which is why I broke it into something I knew would work