This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-07-13
Channels
- # bangalore-clj (1)
- # beginners (40)
- # boot (22)
- # clara (19)
- # cljs-dev (265)
- # clojure (160)
- # clojure-dev (6)
- # clojure-italy (5)
- # clojure-russia (47)
- # clojure-spec (10)
- # clojure-uk (63)
- # clojurescript (88)
- # core-async (8)
- # cursive (54)
- # datomic (48)
- # emacs (32)
- # garden (3)
- # graphql (29)
- # hoplon (54)
- # jobs (1)
- # klipse (4)
- # luminus (5)
- # lumo (21)
- # mount (5)
- # off-topic (16)
- # om (2)
- # pedestal (10)
- # play-clj (1)
- # portkey (32)
- # re-frame (21)
- # reagent (48)
- # rum (1)
- # spacemacs (4)
- # sql (3)
- # unrepl (5)
Hi, does task defined using mount (https://github.com/tolitius/mount) ‘s defstate
and started using mount/start
running in a new thread or in the main thread? Can I defstate
a function that blocks the thread ? Thanks.
@hiredman and others: Thanks for the great hints regarding integration-testing and databases! I think docker sounds like an interesting approach.
I have a data_readers.clj
in my source dir which looks like {kh/test kleinheit.pg.impl/maybe-map}
but when I try it out in the REPL I just get
dev=> #kh/test {:a 1 :b 2}
java.lang.IllegalStateException: Attempting to call unbound fn: #'kleinheit.pg.impl/maybe-map
clojure.lang.LispReader$ReaderException: java.lang.IllegalStateException: Attempting to call unbound fn: #'kleinheit.pg.impl/maybe-map
so, I need a function that takes a nested data structure (only concerned with maps right now) like {:a {:b {:c 1} :d 2}} and returns all the paths to leaves: [[:a ::b :c] [:a :d]]… not sure where to start
I’ve been using Clojure for a long time now and one question randomly popped into my head:
(macroexpand '(let [{:keys [foo]} 1]))
=>
(let*
[map__43828
1
map__43828
(if (clojure.core/seq? map__43828) (clojure.lang.PersistentHashMap/create (clojure.core/seq map__43828)) map__43828)
foo
(clojure.core/get map__43828 :foo)])
that is so very interesting… it’s important to think about if your inputs are unpredictable/dynamic
if your inputs are unpredictable you're screwed, add a layer that makes them predictable 😛
yeah definitely, if you have uncertain input then use tools that are made for validating it as data (spec, schema, clojure data functions etc)
yea… I was just calling some JavaScript APIs from ClojureScript, so I assume everything there is unpredictable 😝
so actually… as long as: 1. the things you’re passing are not literals (which I’ve never done in real program) 2. and you don’t type hint an unpredictable dynamic thing (highly unlikely but possible to do) … it seems that {:keys […]} is actually “safe” from throwing exceptions
not saying that you should rely on it lol… I tried looking and I couldn’t find any place where it’s stated that it’s safe… so I assume it can be considered an implementation detail? someone pls correct me if you know better 🙂
if it's not documented otherwise then you should consider the behaviour of something when you pass it an unexpected value to be "undefined"
i'm not sure its the keys part that is throwing. I think you're just doing something Clojure doesn't allow in typehinting :
user> (let [^long x 1]
x)
CompilerException java.lang.UnsupportedOperationException: Can't type hint a local with a primitive initializer, compiling:(*cider-repl employee-resizer*:67:7)
@schmee - I ended up using postwalk with core.match
@cpmcdaniel nice! mind sharing the solution?
I suppose the map should be mapv
hmm, not sure how this is actually working without that 😉
oh, and the outer seq needs to be there because our tree may have multiple paths, duh
ok, I have a bug when adding another path in the tree. I’m flattening at the wrong place
here’s my attempt with Specter:
(def TreeValues
(s/recursive-path [] p
(s/if-path map?
[(s/collect-one s/FIRST s/FIRST) s/MAP-VALS p]
s/STAY)))
user => (s/select TreeValues m)
[[:a :b :c 1] [:a :b 2]]
user => (s/select TreeValues {:a {:fields {:b {:options [{:label "foo" :value "bar"}]}}}})
[[:a :fields :b :options [{:label "foo" :value "bar"}]]]
map over the results with butlast
@cpmcdaniel Here's one implementation.
(defn all-paths [m]
(letfn [(step [acc current-path x]
(reduce-kv (fn [acc k v]
(let [path (conj current-path k)]
(if (map? v)
(step acc path v)
(conj acc path))))
acc, x))]
(step [] [] m)))
(all-paths {:a {:b {:c 1} :d 2}}) ;=> [[:a :b :c] [:a :d]]
thanks, I’ll try that on my data set
https://stackoverflow.com/questions/21768802/how-can-i-get-the-nested-keys-of-a-map-in-clojure
sweet, there you have a working version of what I was trying to do:
(def TreeValues
(s/recursive-path [] p
(s/if-path map?
[s/ALL (s/collect-one s/FIRST) s/LAST p]
s/STAY)))
user=> (map butlast (s/select TreeValues {:a {:b {:c 1} :d 2}}))
((:a :b :c) (:a :d))
depends on what your needs are, but you should look at https://github.com/cognitect/transit-format
hey, has anybody ever had trouble requiring clj-time.types in a ns? I have the latest version from clojars but I get an exception when I compile complaining the ns clj-time.types doesn't exist or can't be found on the class path.
the namespace clearly exists tho in the github repo
there are also a few clj-time artifacts on clojars, are you sure you are using the one that maps to the github repo you are looking at?
if any of your dependencies require one of these other clj-time artifacts (which unfortunately likely have the same namespace names) you will get all kinds of weird behavior
I followed the clojars link on github, maybe they just didn't push a newer artifact to maven?
clojars
that's exactly
could be, you also haven't shared the exception you are getting, clj-time.types could be failing to load because something is
Nah, the last push to clojars was in Dec. 2016, the change I want was added in march 2017
crisis averted, I guess.
@janetacarr We'll be releasing a new clj-time
very soon. I've been meaning to get to that for a week or two!
@seancorfield , oh cool, I didn't even realize you we're in this channel! 😛
Here's all the fun new stuff https://github.com/clj-time/clj-time/compare/86acab8a122e3229a2e5337075f52b6f75ae4584...master -- I think I'll make it 0.14.0 when I do it (hopefully in the next few days).
clojure and jdbc... there seem to be 2 libs: clojure.java.jdbc
and clojure.jdbc
. Anyone any experience reports? Reasons why using one over the other? ...?
@kurt-o-sys I'm the maintainer of the standard (contrib) one: clojure.java.jdbc
and we use it extremely heavily at work (with MySQL) for large volumes of data/queries.
It's also tested against MS SQL Server (both MS driver and jTDS), PostgreSQL (both Postgres and Impossibl drivers), and H2, SQLite, Derby etc. There are Oracle and Terabase(?) users of it too. It's what most other JDBC wrapper libraries use under the hood.
If you run into any issues with it, feel free to ask in the #sql channel.
Right... Thx.
You can also see from this initial commit that the author basically copied clojure.java.jdbc
(without permission and without attribution -- I took him to task on the mailing list for that!): https://github.com/funcool/clojure.jdbc/commit/dfb16894734c2a95838cd5f5b3fef3e63ac1c4bf
In later commits he added some acknowledge of code he'd taken from clojure.java.jdbc
and he did, over time, substantially rewrite the code base.
(but, yeah, years later I'm still pretty annoyed about it)
a list isn’t IAssociative, but I want to update a list with deeply nested values somehow like:
(def L '( '( '( :a :b '( :c :d '( 'needs-updating )))))
(update-in L [0 0 1 1] fn)
now it’s easy to do if the lists are vectors… but given that most-everything defaults to a list after running some process (map filter reduce etc.), I wonder whats the better way to do this that works for a more general seq
?if you need associative updates, don’t use lazy operations for modification - map, filter, etc all provide transducers that can make vectors
@janetacarr clj-time
0.14.0 is available https://github.com/clj-time/clj-time/releases/tag/v0.14.0
@lwhorton right - but especially when chaining operations into with composed transducers is a better option
and I don’t think it’s vec-*, it’s *v
(and not all of the foov exist - but filterv and mapv do at least)
@seancorfield awesome!
no - vectors cannot be lazy
by composing transducers you avoid creating intermediate data (which does nothing but create gc churn)
hm, not totally following you but that’s okay. i know (comp a b c)
will produce a transducer. are you saying there’s a way to do into [] some-fn
where it doesnt use a transducer?
no - and comp doesn’t generate a transducer unless its args are transducers
if you call (filterv pred? (mapv f coll))
that generates a vector you don’t need
if you use (into [] (comp (map f) (filter pred?)) coll)
you get the same result without creating a data structure nobody uses
you can still get the right answer without composing the transducers, and it’s easy to change once you know how they work
but back to the original question, if you need to do updates by index, keep things in associative collections, there are good options for making them but you don’t need to do it the optimal way on the first pass through
I tend to use tools.logging on top of log4j2. it works great, just about every other routing framework can be rerouted to log4j2
the dependencies for that are something like
[org.apache.logging.log4j/log4j-core "2.8"]
[org.apache.logging.log4j/log4j-slf4j-impl "2.8"]
[org.apache.logging.log4j/log4j-jul "2.8"]
[org.clojure/tools.logging "0.3.1"]
since you were asking about pedestal logging on irc, last I checked(years ago), it was a simple wrapper on log4j
when accessing nested maps, do you guys prefer (-> a-map :a :d :c) or (get-in a-map [:a :d :c]) ?
get-in
->
is a syntax short cut, it is gone at runtime, get-in
is actually a function and will run and exist at runtime
I'll add one consideration: keyword accesses add quite a bit of bytecode (-> :a :b :c :d)
@lwhorton you can do that with specter very easily:
(def L '(((:a :b (:c :d (10))))))
(transform (nthpath 0 0 2 2 0) inc L)
;; => (((:a :b (:c :d (11)))))
I prefer get-in
because it makes the intention clear, we know that the first argument is a map, and that the second argument is a path. That information is lost with ->
, also, that means you can't pull the path, [:b :c :d]
from a data source or generate it without your own macro, because you can't apply to ->
if it is constant and known at compile time (which it seems like it almost always is) then keeping it around at runtime is (admittedly an insignificant) waste
specter keeps popping up here and there with some nice solutions.. i’ll have to look more closely around its api
https://aws.amazon.com/lambda/faqs/ <-- java is listed as supporrted language; does this mean one can do "clojure -> java" for lambda instead of "cljs -> js" ?
Both clj and cljs can be used, but yeah, startup times become a thing.
just a lot of the use cases I can think of for lambda, a very fast starting VM such as the js vm is more appropriate than jvm+clj
to be clear, by java they mean jvm, clojure doesn't compile to java like clojurescript compiles to javascript
and with the incredible support cljs has for the node ecosystem these days... I would choose whichever vm makes the most sense for the scenario. which is a pretty amazing thing to be able to choose while keeping the language constant 🙂
@qqq @bfabry the data from this talk suggest it might not be as big of a deal as you'd assume (if you are running lambdas frequently enough to limit cold starts): https://www.youtube.com/watch?v=GINI0T8FPD4
https://github.com/clojure/clojurescript/wiki/Differences-from-Clojure just gets larger and larger
@eriktjacobsen yes! true. my assumption is that most people using lambda are using it for reasonably infrequent operations (to take advantage of paying for only what you use). but if that's not the case then clj could be perfectly fine
somethings I know are different between clojure and clojurescript because I follow the jira issues aren't even on the list yet
i.e. if my problem can be decomposed into an 'obviously parallel' setup, then AWS just scales everything for me
depends on the license of the source library. If you aren't distributing their library, you might be able to license it however you want. Not something that can be answered in the abstract