This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-04-12
Channels
- # announcements (1)
- # aws (1)
- # beginners (182)
- # boot (33)
- # calva (87)
- # cider (3)
- # clj-kondo (2)
- # clojure (108)
- # clojure-dev (73)
- # clojure-europe (2)
- # clojure-italy (27)
- # clojure-nl (22)
- # clojure-norway (1)
- # clojure-spec (1)
- # clojure-uk (122)
- # clojurescript (78)
- # cursive (5)
- # datomic (17)
- # duct (2)
- # emacs (25)
- # events (3)
- # figwheel (1)
- # figwheel-main (1)
- # fulcro (88)
- # kaocha (6)
- # leiningen (2)
- # luminus (1)
- # lumo (4)
- # nrepl (4)
- # off-topic (37)
- # onyx (1)
- # re-frame (35)
- # reagent (1)
- # reitit (4)
- # shadow-cljs (8)
- # spacemacs (22)
- # specter (2)
- # sql (19)
- # tools-deps (12)
- # vim (11)
Morning
@jr0cket what about asking someone like Carin Meier?
@yogidevbear we have invited Carin to speak many times and hope she is able to speak again. If you have any specific people in mind who are great speakers like Carin, please let us know.
Bore da
To set expectations, I think it's unlikely Carin will come across for ClojureX. Especially, with it being to close to Christmas but it's always worth a try!
Noob question of the day: Why do we actually require stuff vs just using the fully qualified name?
(clojure.data.json/write-str edn :key-fn ->snake_case_string)
vs
(:require [clojure.data.json :refer [write-str]])
(write-str edn :key-fn ->snak_case_string)
Other than readability etc?
Is there a technical reason?if you haven't required it
you might luck out in dev
but not in prod
and there's a bunch of other processing that happens
vars and namespaces get created
defmethod
attach to their defmulti
s etc
there are stateful mutations that happen as a consequence of require
def
being the biggest one
@guy a global namespace is the work of the devil - i would be much happier if it just wasn't possible to use the fully qualified name
(that would then offer at least the possibility of having multiple versions of a particular namespace loaded at the same time, and a similar solution to node's for resolving jar-hell)
can you wrangle java ClassLoaders hierarchies to achieve this?
given the underlying java namespacing by ClassLoaders, clojure would have to wrangle ClassLoaders to achieve this
it's obvs never going to happen - the global namespace thing is baked into clojure and unchangeable now
but everytime i find myself in jar-hell i look at npm and it's reified non-global packages and wonder why i can't have that
I imagine that could get fiddly though
@guy: require
is the complecting of load
https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/load and refer
https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/refer for the common easy case.
loading compiles and builds the namespace and executes its side effects. refer lets you access vars in another namespace. alias
does something similar but is basically what backs the :as
behind require
.
practical question... I need to design a GET method that gets multiple ID's.. how would you do this? as query params?
&status=1&status=2&status=3
query params can be multi valued
ring will give you a sequence of them if you do that
though people do comma sometimes comma separate them… but you can save yourself having to parse/decode them
yeah most web frameworks have a way to handle it
thank you for your help @rickmoynihan
this does work indeed in Spring: public String method(@RequestParam(value="phone") String[] phoneArray)
ok I think the former is part of http standards… the latter is just quite common but non-standard
Quick question... If you had a vector of vector pairs, like this:
[[4.640824 48.998544] [4.624537 48.994391] [4.62473 48.99418] [4.625631 48.9938] [4.641167 48.997896] [4.640824 48.998544]]
And you needed it to be a string, like this:
"4.640824 48.998544, 4.624537 48.994391, 4.62473 48.99418, 4.625631 48.9938, 4.641167 48.997896, 4.640824 48.998544"
would you use (reduce ...)?(I am trying to stop myself from seeing every transformation as a nail, what with me having this big Reduce Hammer)
(I have a working reduce, well except that my string will have a comma on the end that I need to trim off after the reduce. Yes, commas and whitespace in the resultant string are meaningful)
user> x
[[4.5 4.8] [4.5 4.8] [7.8 9.5]]
user> (flatten x)
(4.5 4.8 4.5 4.8 7.8 9.5)
user> (clojure.string/join " "(flatten x ))
"4.5 4.8 4.5 4.8 7.8 9.5"
user>
Thanks @jasonbell 🙂
I get this:
(clojure.string/join ", " (first testvec))
"[4.640824 48.998544], [4.624537 48.994391], [4.62473 48.99418], [4.625631 48.9938], [4.641167 48.997896], [4.640824 48.998544]"
Yay, result!
(clojure.string/join ", " (flatten (first testvec)))
"4.640824, 48.998544, 4.624537, 48.994391, 4.62473, 48.99418, 4.625631, 48.9938, 4.641167, 48.997896, 4.640824, 48.998544"
Thanks so much @jasonbell - I REALLY need to raise my "do stuff without using reduce" game when it comes to Clojure, so this is VERY helpful 🙂
A pleasure @maleghast
(apply str (interpose ", " (flatten x)))
=>
"4.640824, 48.998544, 4.624537, 48.994391, 4.62473, 48.99418, 4.625631, 48.9938, 4.641167, 48.997896, 4.640824, 48.998544"
Alternative 👀 maybe?I'd say using reduce
is almost always a good idea unless you can use map
/`filter` and friends. Most of clojure is around using those basic tools for working with seq-able or channel shaped things
(def x [[4.640824 48.998544] [4.624537 48.994391] [4.62473 48.99418] [4.625631 48.9938] [4.641167 48.997896] [4.640824 48.998544]])
(->> x
(interpose ",")
flatten
(clojure.string/join " "))
"4.640824 48.998544 , 4.624537 48.994391 , 4.62473 48.99418 , 4.625631 48.9938 , 4.641167 48.997896 , 4.640824 48.998544"
@maleghast I always avoid flatten
as it leads to all sorts of antipatterns, as it’s unconstrained on depth so can gloss over underlying problems; e.g. leave you producing data in the wrong way then flattening it to tidy it up.
I’d normally prefer something like:
(str/join ", " (mapcat identity [[1 2] [3 4]]))
a heuristic is that code with a flatten
near the end can often be fixed by replacing an earlier map
with a mapcat
.
generally it’s much better to fix a problem upstream
would it lower the tone to suggest?
(str (reduce (fn [^StringBuilder sb [x y]]
(doto sb (.append x)
(.append \space)
(.append y)
(.append \,)))
(StringBuilder.)
[[1 2] [3 4]]))
that buys you an unwanted trailing comma of course
if you want to do it efficiently and correctly then you’re best transducing
(transduce (comp (mapcat identity) (interpose ", "))
(fn
([] (StringBuilder.))
([x] (str x))
([^StringBuilder sb s] (.append sb s)))
[[1 2] [3 4]])
oh sorry I misplaced the commas… but the point still applies
arity 0 constructs the starting value (a string builder) arity 1 is called when its finished, and converts the string builder into a string arity 2 appends as per reduce
won't (apply str
be just as efficient?
^^^ its a reducing fn
take a look at https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/completing
you can’t do this with a stringbuilder though, as you need to convert it back to a string
I like the theoretical purity of specifying the initial value in the zero-arg reducing fn
but I usually specify the initial value into the transducer
you can equally pass it as the starting value of reduce
yeah either works — whatever floats your boat 🙂
I was assuming you’d break the anon function out into a lib function though
e.g. rf-append
I always forget about that… mapcat identity
has been ingrained into my brain since pre clojure 1.0 🙂 1.7 is so hipster
though right enough that’s a pure transducer function
yeah, same here, I have something triggering when I see mapcat identity
:thinking_face: in a transducer and then I remember of the cat
As of the completing
suggestion, it looks nice:
(transduce
(comp cat (interpose ", "))
(completing
(fn [^StringBuilder sb s] (.append sb s))
str)
(StringBuilder.)
[[1 2] [3 4]])
@reborg: :thumbsup: Though I think this corrects my misread of the spec:
(transduce
(comp (map (partial clojure.string/join " "))
(interpose ", "))
(completing
(fn [^StringBuilder sb s] (.append sb s))
str)
(StringBuilder.)
[[1 2] [3 4]])
outputs ;; => "1 2, 3 4"
Unix/Ops question:
How do people here wait in a shell script for a HTTP service to start… looking for something smarter than sleep 15
, i.e. something that will poll a service until it comes up and returns 200
then unblock… or after a certain configurable timeout return an error I can trap exit on.
Looking for some unix command line tool I can just apt-get
I’ve written bash
/`curl` scripts that loop in the past waiting for the 200; but never bothered trying to terminate after a timeout and return a non-zero status code…
ahh thanks… looks like what I want. Also looks like it wraps the timeout stuff in bash I mentioned
oooo TIL: bash has a timeout
builtin
https://unix.stackexchange.com/a/149053
thanks that looks great