This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-03-12
Channels
- # arachne (1)
- # beginners (26)
- # cljs-dev (53)
- # cljsrn (1)
- # clojure (140)
- # clojure-italy (13)
- # clojure-russia (14)
- # clojure-spec (5)
- # clojure-uk (6)
- # clojurescript (52)
- # datascript (4)
- # datomic (11)
- # dirac (11)
- # emacs (12)
- # hoplon (9)
- # jobs (4)
- # lein-figwheel (1)
- # off-topic (29)
- # om (10)
- # om-next (1)
- # pedestal (3)
- # protorepl (1)
- # re-frame (16)
- # ring (12)
- # rum (27)
- # slack-help (12)
- # spacemacs (27)
- # unrepl (19)
- # untangled (26)
- # yada (8)
Hey fam, I'm using Pedestal to manage 100k HTTP connections to various proxies. I want to route data to a particular proxy. Would you recommend storing an atom of {ip : core-async-channel}
open every connection open that I can then access at will, or is there a more 'functional' way of doing it? I know this is a very broad question 😛
Does anyone know of an easy way to output valid EDN format from Clojure. Basic printing tools generally work fine, but they print things (e.g., rationals) that aren’t actually in the EDN spec and won’t be properly read by other EDN parsers like edn-java
. I can hack around this, but it seems weird (esp. since EDN comes from the Clojure world) that, e.g., clojure.edn
doesn’t have something that will spit out valid EDN. Thanks.
@nicmcphee there isn't a function to automatically convert rationals into floats while converting a structure into a string because there are rationals that do not have an exact finite-length representation as floats. I find it strange that the edn spec doesn't allow for rationals.
When I try to use ring’s jetty adapter, I’m get an error that I can’t get around. The project has [ring “1.5.1”]
as a dependency in the project. If I then run the repl and do (use ‘ring.adapter.jetty)
, I get this error:
> CompilerException java.lang.NoClassDefFoundError: org/eclipse/jetty/http/HttpParser$ProxyHandler, compiling:(ring/adapter/jetty.clj:27:11)
If I create a fresh test project,and add just [ring “1.5.1”]
as a dependency, run the repl, and then try the same use
command, it loads up just fine.
I haven’t any good ideas about why this might be he happening. Anyone here have a clue?
@ezmiller77 have you checked out the deps that are actually being used ( lein deps :tree
) ? it's possible one of your other deps has a transitive dep that conflicts with one of ring's
@mccraigmccraig I had not. Just looked at the output tof that command. Not entirely sure what it all means. At the top of the output there are a lot of suggestions regarding including “exclusions” with a lib called commons-codec
.
Just tried adding it for ring in my dependencies. Then deleted ring in .m2
dir and reinstalled. But still getting the error. That was just a shot in the dark though.
What’s a “transitive dependency”?
@ezmiller77 so your project.clj
lists a bunch of dependencies - those deps themselves have deps etc - it's possible that there are conflicting versions in the transitive set of dependencies
e.g. say your project has deps [A,B]
and project A
has deps [Cv1]
while project B
has deps [Cv2]
... your project now has transitive deps [A,B,Cv1,Cv2]
and lein will have to choose which version of C
to include
sometimes that works out, and sometimes it doesn't
when it doesn't you have to help lein out by specifying manual :exclusions
in your project.clj
however, if the only suggestions you are getting from lein are relating to commons-codec
that doesn't sound like your problem, since you are missing a jetty class
try this @ezmiller77 - specify a top-level :exclusions [commons-codec]
in your project.clj
, then in your :dependencies
manually specify the version of commons-codec
that your desired version of ring/jetty etc depends on
the top-level :exclusions
causes commons-codec
to be removed from any transitive deps included, leaving only the version you manually specify
Will try that. Hard to know, though, what version jetty might be relying on. The whole ring tree toward the end doesn’t seem to mention commons-codec at all:
[ring "1.5.1"]
[ring/ring-core "1.5.1"]
[clj-time "0.11.0"]
[joda-time "2.8.2"]
[commons-fileupload "1.3.1"]
[commons-io "2.5"]
[crypto-equality "1.0.0"]
[crypto-random "1.2.0"]
[ring/ring-devel "1.5.1"]
[clj-stacktrace "0.2.8"]
[hiccup "1.0.5"]
[ns-tracker "0.3.0"]
[org.clojure/java.classpath "0.2.2"]
[org.clojure/tools.namespace "0.2.10"]
[ring/ring-jetty-adapter "1.5.1"]
[org.eclipse.jetty/jetty-server "9.2.10.v20150310"]
[javax.servlet/javax.servlet-api "3.1.0"]
[ring/ring-servlet "1.5.1"]
Unless, it’s related to those libs prefixed with commons-
...
look in your ring-only project - lein deps :tree
there should show any commons-codec
dep ring has
good idea
(`lein deps :tree` will only show the chosen transitive deps, not all of them)
Chosen in the project.clj?
Maybe that’s related to why the tree in the test project for ring looks quite different?
[ring "1.5.1"]
[ring/ring-core "1.5.1"]
[clj-time "0.11.0"]
[joda-time "2.8.2"]
[commons-fileupload "1.3.1"]
[commons-io "2.5"]
[crypto-equality "1.0.0"]
[crypto-random "1.2.0"]
[org.clojure/tools.reader "0.9.1"]
[ring/ring-codec "1.0.1"]
[commons-codec "1.6"]
[ring/ring-devel "1.5.1"]
[clj-stacktrace "0.2.8"]
[hiccup "1.0.5"]
[ns-tracker "0.3.0"]
[org.clojure/java.classpath "0.2.2"]
[org.clojure/tools.namespace "0.2.10"]
[ring/ring-jetty-adapter "1.5.1"]
[org.eclipse.jetty/jetty-server "9.2.10.v20150310"]
[javax.servlet/javax.servlet-api "3.1.0"]
[org.eclipse.jetty/jetty-http "9.2.10.v20150310"]
[org.eclipse.jetty/jetty-util "9.2.10.v20150310"]
[org.eclipse.jetty/jetty-io "9.2.10.v20150310"]
[ring/ring-servlet "1.5.1"]
But you are right, there commons-codec shows up as a trans dep.
But that did it!!
I add the top-level exclusion and then [commons-codec “1.6”]
as shown in the test project ring dep tree.
How bizarre.
Thanks @mccraigmccraig ! Had wasted several hours on that.
yw @ezmiller77 - i usually put :pedantic? :abort
in the top-level of project.clj
which forces you to resolve all transitive dep ambiguities (or it errors)
they can be very tiresome on some projects. i have been known to hanker after npm
but afaics npm style deps are not possible with java or clojure because of the global namespace / lack of first-class packages
@mccraigmccraig you can do npm style via Mr Anderson!
ah, i had forgotten about mr-anderson @dominicm - how well does it work out in practice?
@mccraigmccraig it's got a few small edge cases, but mostly things I'd consider bad code anyway. Most people use it for CIDER without realising
@mccraigmccraig the only real limitation is the fact you can no longer pass objects between libraries. But we operate on data right? :D
what does 'objects' mean in this context @dominicm ?
@mccraigmccraig java objects and maybe records too. Can't have two versions of the same library which create the object, as they'll be different.
So bidi1s vhostmodel is different to bidi2s. If library A gives the model to bidi2, and you created it via bidi1, it won't work.
gotcha - that's not too bad - i'll give mr.a a spin next time i'm scratching my head over dep conflicts
hi! when using CIDER's "go to definition" function, is there a way to skip pressing enter? (eg before actually jumping to the definition is asks you again what symbol you are interested in)
@pwrflx Yes, set cider-prompt-for-symbol
to nil
@dergutemoritz thanks!
I'm trying to understand this behavior of :exclusions
in leiningen dependencies. buddy-auth and transit-clj both have transitive dependencies on com.fasterxml.jackson.dataformat/jackson-core
, with differing versions
:dependencies [,,,
[buddy/buddy-auth "1.4.1"]
[com.cognitect/transit-clj "0.8.297"]
,,,]
[com.cognitect/transit-clj "0.8.297"] -> [com.cognitect/transit-java "0.8.319"] -> [com.fasterxml.jackson.core/jackson-core "2.3.2"]
overrides
[buddy/buddy-auth "1.4.1"] -> [buddy/buddy-sign "1.4.0"] -> [cheshire "5.7.0"] -> [com.fasterxml.jackson.dataformat/jackson-dataformat-cbor "2.8.6"] -> [com.fasterxml.jackson.core/jackson-core "2.8.6"]
and
[buddy/buddy-auth "1.4.1"] -> [buddy/buddy-sign "1.4.0"] -> [cheshire "5.7.0"] -> [com.fasterxml.jackson.dataformat/jackson-dataformat-smile "2.8.6"] -> [com.fasterxml.jackson.core/jackson-core "2.8.6"]
and
[buddy/buddy-auth "1.4.1"] -> [buddy/buddy-sign "1.4.0"] -> [cheshire "5.7.0"] -> [com.fasterxml.jackson.core/jackson-core "2.8.6"]
Consider using these exclusions:
[buddy/buddy-auth "1.4.1" :exclusions [com.fasterxml.jackson.core/jackson-core]]
Leiningen suggests excluding the buddy-auth version, but I actually want to exclude the transit-clj version, but that doesn't work. If I do this
:dependencies [,,,
[buddy/buddy-auth "1.4.1"]
[com.cognitect/transit-clj "0.8.297" :exclusions [com.fasterxml.jackson.core/jackson-core]]
,,,]
it also doesn't show up as a cheshire
dependency when doing lein deps :tree
, even though the above warning shows that it is
$ lein deps :tree
...
[buddy/buddy-auth "1.4.1"]
[buddy/buddy-sign "1.4.0"]
[cheshire "5.7.0"]
[com.fasterxml.jackson.dataformat/jackson-dataformat-cbor "2.8.6"]
[com.fasterxml.jackson.dataformat/jackson-dataformat-smile "2.8.6"]
...
[com.cognitect/transit-clj "0.8.297"]
[com.cognitect/transit-java "0.8.319"]
[com.fasterxml.jackson.core/jackson-core "2.3.2"]
I've "fixed" it by explicitly using loading the right version, but I'd like to understand why :exclusions
doesn't seem to work in this case
it's also strange that the cheshire -> jackson-core dependency doesn't show up in lein deps :tree
, right?
while it's definitely there https://github.com/dakrone/cheshire/blob/master/project.clj#L8
ok, now it's working with :exclusions... not sure what I did wrong before. Thanks for the rubberducking! 🦆
the alternative would be to read from the channel yourself in a loop and apply the function to each value
not an expert on core.async so don't quote me on that, but the transducer version is definitely efficient and idiomatic, it's one of the use cases for which transducers were introduced
it does seem nice, though it also means i have to know what i want to do with a channel when i’m creating it
@qqq You can join the strings: https://clojuredocs.org/clojure.string/join
how can i get a host-independent AST from tools.analyzer? i.e. independent of cljs or cl# or cljvm? Im currently experimenting with clojure.tools.analyzer.jvm
@paulocuneo that's not easy since many macros, forms and builtin sexprs are platform dependent
and analysis happens after macro expansion,
oh ok, will play with clojure.tools.analyzer.jvm for know. Or maybe switch macroexpand-all. Just wanted a macro-expanded/standartrised AST.
i need to call a fn for each complete path in a map. e.g. for
{:foo {:bar {:baz "hello"}}}
call a fn, passing "hello" as arg. what's the best way to do this?i could have a dispatch fn for each level, or i could write a vectorize
fn that turns each path into a vector and dispatch on that. but i'm guessing there's a better way.
or a dispatch map, where the leaves are the fns to apply to the leaves of the data map?
what does complete path means? you mean the leafs of the tree?
i don't need to worry about the non-leaf nodes, although that would be a more complete solution.
knowing the path would be just: (f (get-in tree [:foo :bar :baz]))
right, but i would have to construct the selection vector from the data. that's where a vectorize fn would come in handy.
i'm kinda liking the idea of a dispatch map, e.g.
{:foo {:bar {:baz (fn [x] ...)}}}
@mobileink Is the shape of the data known? Is it a single function for all leafs? What's the required output?
(Not analizing performance )this would flatten the tree.
(flatten
(clojure.walk/prewalk (fn [a] (if (map? a)
(seq a)
a)) {:foo {:bar {:baz "hello"}}})
@yonatanel the data map represents html meta elements, so each leaf will generate a <meta. .. > element. a single fn would work, but would have to be oarameterized by the path.
@paulocuneo hmm. i don't think walking would work, since it does not afaik remember the path. there may be multiple optional keys at each level.
how about something like(didnt test it yet)
(defn merge-apply [dispatch tree]
(merge-with (fn [dispatch tree]
(cond
(map? tree) (merge-with merge-apply dispatch tree)
(map? dispatch) tree ;; handled missing dispatch as identity
:else (dispatch tree)))
dispatch
tree))
@mobileink Can you design a flat map in the first place or is it not feasible?
@yonatanel for example, instead of msapplication-window,
{:ms {:application {:window ... }}}
and similar for :apple etc. it's mostly about aesthetics, and clojurization.@mobileink This is not necessarily beautiful clojure, unless other parts of your code enjoy the nested map
@paulocuneo i'll have to stare at that a while. dunno about the second map? expr.
dispatch map is the map with the fns
tree is the map to witch you want to apply the dispatch map
it may have bugs, since its just a sketch
merge-with is baised to the left map
(if i remember correctly)
@mobileink How do you represent width and height?
the data map is written by the user, for a webpage. the idea is that html meta data should be just like clojure meta data - you express it with a map.
But then you have to remember that :width and :height, though being separate leafs, must go into the same meta tag as a single string
for example:
<meta name='msapplication-window' content='width=800;height=600'>
becomes sth like {:ms {:application {:window {:w 800 :h 600}}}}
@mobileink With how clojure.spec works and the headache of traversing a nested map, it might be more elegant to do something similar to {:ms.application.window/size {...}
i hadn'thought of that. but i'm already namespacing my keywords so i'm not sure that would work. i guess i could put / where you have .
but that would complicate things with spec, i think. just starting to use it. i don't know if it's possible to validate kws with spec.
@mobileink What do you mean validating kws?
@mobileink the code i share you may handle intermediate nodes with a little tweaking
@paulocuneo thank you, i will play around with it.
@mobileink spec isn't meant to check keys that aren't supposed to be there since it might not only be typos but also keys you will support in the future. Adding your own code to check typos is easier than traversing maps. BTW separate namespace words with a dot and put a slash before the keyword.
what about required? can i say in spec that ::html/foo is optional, but if you have it ::html/foo/bar is required?
the problem is that kw names are not really structured, are they? isn't "/" just another char, with no special significance?
Spec is based on predicates, you can do almost anything
yeah, and ::html/foo/bar isn't a keyword 😉
it's :html.foo/bar
@tbaldridge ah, good point!
or something like ::hf/bar
::hf/bar/baz is not a kw? sorry, not at my machine so can't test, but i'm pretty sure i've used / in the name part of kws.
@tbaldridge i'm assumming the elements in s/keys :req [.. ]
must be kws. can they be general predicates (fns)?
not in s/keys
but you can put them in s/and
and under a s/def
@bcbradley Thanks. I realize that you can’t swap between rationals and floats and preserve exact semantics, but I would have hoped that Clojure would have tools for generating valid EDN (or expand EDN to include rationals).
@nicmcphee try converting the rationals to strings and storing them that way
you might need https://clojuredocs.org/clojure.walk/walk and https://clojuredocs.org/clojure.core/ratio_q and http://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html and https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Ratio.java
if I were you and I wanted a general solution, I'd walk through everything and when i found something that satisfies (ratio? ...) I'd replace it with the data structure [::Ratio X], where X is a string version of the ratio that can be converted back later