This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-10-02
Channels
- # beginners (98)
- # bigdata (1)
- # bitcoin (1)
- # boot (32)
- # cider (20)
- # cljs-dev (57)
- # cljsrn (130)
- # clojure (93)
- # clojure-dusseldorf (1)
- # clojure-germany (1)
- # clojure-greece (3)
- # clojure-italy (2)
- # clojure-russia (203)
- # clojure-spec (14)
- # clojure-uk (50)
- # clojurescript (127)
- # css (7)
- # cursive (6)
- # data-science (1)
- # datomic (4)
- # emacs (1)
- # events (1)
- # fulcro (8)
- # funcool (12)
- # graphql (7)
- # jobs (1)
- # lein-figwheel (2)
- # luminus (2)
- # off-topic (7)
- # om (16)
- # onyx (4)
- # parinfer (17)
- # pedestal (6)
- # portkey (36)
- # proton (3)
- # re-frame (10)
- # shadow-cljs (140)
- # spacemacs (12)
- # specter (1)
- # sql (1)
- # vim (10)
- # yada (10)
hi, I read another http server comparison on twitter https://twitter.com/playpausenstop/status/914218443443929089 and decided to reproduce and add clojure to it: https://github.com/razum2um/hello-http-bench and wrk said clj was even faster. I suspect something is wrong, there shouldn’t be such difference. What am I missing?
@U051SA920 ok, but to tell the truth, I’m not a python-guy, took it straight from twitter, can you PR?
Sorry no, I don't think such trivial benchmarks are meaningful. The big techempower benchmark tries to benchmark more real world usage patterns.
@U051SA920 but still, what about such big difference even with rust?
well.. the maintainer is mentioned in the twitter account description. But it seems to be using a daemon that tracks twitter mentions with http://github.com in it, so it seems to be an automated tweet
hi guys Hacktoberfest is here! feel free to contribute to clojure projects: https://github.com/search?utf8=%E2%9C%93&q=label%3Ahacktoberfest+state%3Aopen+type%3Aissue+language%3Aclojure&type=
Guys I created Clojurecademy I hope you like it, feel free to provide feedback
I’ve been programming in Clojure for years, but this one stumped me for a while: Without giving away too much of the solution, why do (pf)
and (f)
return different ranges?
(let [csrng (java.security.SecureRandom.)]
(defn pf
([] (pf csrng))
([rng] (java.lang.Math/abs (.nextLong rng))))
(defn f
[] (java.lang.Math/abs (.nextLong csrng))))
you're closing over the same random generator so getting a new random value every time, independently of which function you invoke
boot.user=> (pf)
545391547
boot.user=> (pf)
1976462804
boot.user=> (pf)
1535096817
boot.user=> (pf)
825017953
boot.user=> (pf)
596938158
boot.user=> (f)
7871239576498841695
boot.user=> (f)
8955889148814316217
boot.user=> (f)
8975201899528191775
boot.user=> (f)
3340060048302527866
boot.user=> (pf)
768712039
It has to do with some type information no propagated properly during the function call. If you type hint they return results of the same magnitude:
(let [csrng (java.security.SecureRandom.)]
(defn pf
([] (pf csrng))
([^java.security.SecureRandom rng] (java.lang.Math/abs (.nextLong rng))))
(defn f
[] (java.lang.Math/abs (.nextLong csrng))))
ah, I guess Math/abs reflective call is picking the abs(Integer) arity rather than abs(Long)
@reborg: correct. But I find it bizarre that in the polymorphic function reflection fails, but not in the “normal” function.
because f
knows the type of csrng, because it is statically determinable, while rng
can be any Object
@bronsa Yes, failure is too strong of a word. But the inability to determine the type, and the unfortunate guess of integer leads to very surprising results. In this case, the range of a crypto function suddenly loses 32 bits of randomness…
I have this for getting fields from a pdf document
(defn get-fields [document]
(->> document
(.getDocumentCatalog)
(.getAcroForm)
(.getFields)))
If I wanted to be able to pass in any of those things to get the fields, what would be the clojure way to do that?@cch1 well guessing the type as anything but object would be a mistake - - that arty is public so you'd be free to invoke it with anything exposing a nextLong method
isn't reflection a runtime decision? doesn't it already have access to the object returned by nextLong at that point?
tossing this out there because I don’t understand: why does first
work on a set? what utility does that have?
though I imagine the reason it works is just because the types fall out that way. but that's one use for it
@bronsa but isn't the Reflector here making a dubious choice? It looks like Math/abs int is taking precedence over the long version, probably because both are "congruent". Shouldn't be the conservative choice to go long?
also I suppose the seq abstraction uses first and rest to iterate over seqs so it is used there, you would just never use it on set a set with more than one element and expect to care about which element you get back
@reborg there's no good pick in this case, you're assuming that the Integer version will behave the same as the Long version but there's no guarantee
How reading through jetty-server source and thinking about how much mutable is all the javax/servlet api. I think about http, sockets, and view templates: given we have immutable structures and (to tell the truth) a lot parts of a http response doesnt change between requests - cannot we leverage the fact and do less allocations flushing into the socket same and same strings(bytes) again (+ probably even doing a writev)?
So I have some code in a -main class that works in the REPL but not with lein run. Is that normal?
@chalcidfly does your -main return a lazy-seq where the repl forces evaluation? (eg. a call to for or map)
Oh, does for
return a lazy seq?
I switched to doseq
and it works. Huh.
it’s a list comprehension for generating data, and yeah, doseq is a drop-in replacement
Thanks again
I think that’s the third time this week
at this point, the main thing I have to offer is recognizing the most frequent problems people have when first starting to use clojure, it’s a pretty predictable list, I should probably make a faq for clojure learners or something
And lazy seqs would be the 1st, 2nd, and 3rd items on it 🙂
Yeah that would be seriously helpful
Official clojurians FAQ would be nice
Or unofficial
> 1) lazy-seqs > 2) lazy-seqs > 3) lazy-seqs > 4) data structures are immutable
A good rule of thumb to bear in mind is that doseq
is for side-effects, for
/`map` etc are for pure functions.
(it's a bit more involved than that but...)
Yep, 4clojure put me in the 100% functional mindspace, but I’m working on something now with a bunch of side effects
Now I’ve got something that works with lein run but not as a standalone jar.
This is the code for anyone who might be able to help: https://pastebin.com/vRjvKZNc
Has to do with setting ns
And a reddit question with more details: https://www.reddit.com/r/Clojure/comments/73w95b/i_can_make_a_file_with_two_nss_using_lein_run_but/
I think you'll need create-ns
/ in-ns
instead of that nested ns
call.
in-ns
causes the same problem
Hmm, I didn't realize in-ns
was also tied to the static namespace management of compilation.
@chalcidfly Looking at the docs for in-ns
, yeah, you're not going to be able to use that either. I think you're going to find that you can't switch namespaces in compiled code.
If you stopped using AOT, you could probably do this (maybe)?
Interesting, I’ll try that! Thanks for your help!
Set :main
to clojure.main
and remove any :aot
and gen-class
stuff.
Then build your uberjar and run it with the -m
option to specify your -main
namespace and see what happens.
Yep, that did it
@seancorfield Is there any I can package it up as a standalone jar without having to do the -m option?
What you could do is write your own -main
in a standalone namespace that only refers to other namespaces dynamically (`require` / resolve
) and have it be the only AOT-compiled piece, and then it can dynamically call your "real" main function.
You need to ensure that AOT doesn't cascade into the code you still need to be dynamically compiled (at runtime).
Clojure's AOT makes this a bit of a pain 😐
Ah, I see. I don’t know if that will be possible here. I tried simply putting the extra ns
call in another namespace but I think the AOT somehow spilled over and compiled it as well.
You can't have any static references from the namespace containing -main
to the rest of your code.
So it would be a small, standalone namespace that only contains your (new) -main
, and that function only contains a require
of your "real" namespace, and then a call via resolve
of your driver function.
(ns compiled.main (gen-class))
(defn -main [& args]
(require 'real.main)
(apply (resolve 'real.main/-main) args))
something like thatAnd make sure only compiled.main
is AOT'd.
Oh, that’s genius, let me try that real quick
I still get that pesky Can't change/establish root binding of: *ns* with set
FWIW in real.main/-main I still have a ns
call inside a function
Well, turns out if you eval the second ns call inside of clojure.main/with-bindings, it works just fine!
Does anyone have experience using the clojure.data.zip and clojure.data.zip.xml member functions together?
I’m running into an issue where I’m always getting one element back when I’m expecting 14 elements and I’m having trouble inspecting it. I went to try to use clojure.data.zip/children but I got back ClassCastException clojure.lang.LazySeq cannot be cast to clojure.lang.IFn clojure.zip/node (zip.clj:67)