#clojure log - Jul 24 2015

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

1:50 J_Arcane: I didn't even know about ##.

2:47 crocket: It seems inline implementations can refer to the type being defined in clojure 1.7

4:07 sagax: hi all

4:08 howto run mycode.clj file in command line?

4:08 run in linux

4:08 TEttinger: sagax: you should really really use leiningen.

4:09 if you want to run a single file, uh I think you can do it using clojure.jar

4:09 sagax: use leiningen it's true way?

4:10 i wish command line because i need output in stdout

4:10 TEttinger: ah!

4:10 java -cp /path/to/the/clojure.jar clojure.main /path/to/your/code.clj

4:10 replacing paths to fit

4:11 sagax: thanks, i will try this

4:11 TEttinger: leiningen is command line unless something is wrapping it

4:11 most people will not know how to run your project if it's a bare clj file, though

4:11 crocket: TEttinger, Don't we have similar tools to leiningeN?

4:11 TEttinger: yeah, boot

4:11 crocket: I heard cake and so on.

4:12 Cake doesn't exist anymore.

4:12 By the way....

4:12 sagax: hm, but now i have only single file .clj and nothing more

4:13 crocket: What is the best way to reduce leiningen repl startup time?

4:14 TEttinger: crocket: probably technomancy's odd-seeming but successful attempt to rewrite the slow parts of lein in OCaml

4:14 http://leiningen.org/grench.html for linux and osx only I think? maybe windows

4:15 failing that, use drip to have a JVM already ready to go when you need one

4:15 https://github.com/josteink/lein-drip

4:16 crocket: Hell

4:16 OCaml starts really fast.

4:17 OSome!!

4:17 TEttinger: https://github.com/technomancy/leiningen/wiki/Faster

4:17 glad to help!

4:18 sagax: java -cp /path/to/the/clojure.jar clojure.main /path/to/your/code.clj

4:18 what mean "clojure.main"

4:18 ?

4:19 ordnungswidrig: safax: thats the classname in which the jvm looks for a main method to run

4:19 TEttinger: that's telling clojure.jar what class to load, the class "clojure.main" in clojure.jar

4:20 sagax: thank, i got it

4:20 TEttinger: and your/code.clj is an argument to clojure.main, so it runs it

4:20 sagax: that's what i need, thanks

4:21 TEttinger: if you don't pass the last argument (don't pass your code), then clojure.main defaults to running an interactive interpreter

4:39 sagax: i must use ide for clojure programming or i can use vim?

4:40 some ide for java or clojure

4:48 ordnungswidrig: sagax: there's vim-fireplace https://github.com/tpope/vim-fireplace

4:48 noidi: http://www.neo.com/2014/02/25/getting-started-with-clojure-in-vim

4:52 xificurC: what would be the correct way to generate a filename from a URL? e.g. input is http://www.example.com/my%20file.txt and output could be "my file.txt"

5:04 ordnungswidrig: xificurC: ,(.getPath (java.net.URI. "http://example.com/foo"))

5:05 xificurC: but beware the URIs can contain characters which are not allowed on your local filesystem

5:06 xificurC: ordnungswidrig: thanks. I'm trying to use itsy for crawling and fighting my way through. Not sure how to save an http request that resolves to a binary file

5:06 e.g. zip, jpg etc

5:07 ordnungswidrig: is there a cross-platform normalizer for that? To convert a string to something allowed as a file name on the local filesystem

5:09 I could save the URIs and wget them but there's surely a clojure way

5:10 ordnungswidrig: xificurC: java.nio.file.Path will test whether a file name is valid

5:49 xificurC: does anyone here know itsy? I'm riddled as it seems the spider (web crawler) spawns a bunch of threads and never checks if it finished its job (i.e. it doesn't stop the threads in the end). How does one then know when to terminate the spider?

6:12 theme: Hi! I am still trying to understand how lisps are "good" languages

6:13 So I have a few questions

6:14 If you are not allowed to write any macros of your own, but you are allowed to use macros someone else wrote, would you still like lisp?

6:15 algernon: yes.

6:15 theme: algernon, why?

6:16 * theme totally didn't expect that answer

6:16 xificurC: theme: if you can only use macros someone else wrote (like the language maintainer) it doesn't really matter whether he uses macros or other facilities, from your POV. So the question could very well be "would you use lisps if there were no macros?"

6:17 theme: ok... lemme rephrase the question

6:17 wasamasa: theme: maybe you should take a look at how much of clojure.core is macros

6:17 theme: wasamasa, that is why I didn't ask it the way xificurC suggested

6:18 algernon: theme: because my choice of lisps (clojure & hy) provide a great deal of benefits even without macros.

6:19 wasamasa: theme: it's ~70

6:19 theme: algernon, such as?

6:19 wasamasa, I allowed using macros *someone else* wrote

6:19 xificurC: I think of macros as a way to extend the expresiveness of the language (is that a good view?). theme - how much do you feel the need to extend insert-already-mature-language-here?

6:20 wasamasa: theme: yes, there's at least 70 of these in clojure

6:20 theme: xificurC, for some languages, not much

6:20 algernon: theme: higher order functions, the concurrency stuff (core.async), the REPL, homoiconicity, to name a few.

6:20 theme: or maybe nothing

6:21 algernon: repl-driven development is incredibly useful for what I do. being able to shape data *and* code the same way, too.

6:21 xificurC: theme: the same way there's not much need of it here. It's a nice benefit though

6:22 wasamasa: seqs as abstraction allow describing very common problems in little code

6:22 theme: Quote from the book "On Lisp": "Language and program evolve together...In the end your program will look as if the language had been designed for it. And when language and program fit one another well, you end up with code which is clear, small, and efficient."

6:22 How true is that quote? ^

6:22 wasamasa, I have iterators in some languages

6:23 wasamasa: theme: which are totally not the same thing

6:23 algernon: theme: that quote is very true.

6:23 theme: wasamasa, they aren't?

6:23 algernon, can you give an example?

6:23 wasamasa: theme: what good are iterators if your language support for higher order functions sucks (as in python)

6:24 algernon: theme: any of the lisp DSLs. I think core.logic is an incredible example, and so is overtone.

6:24 theme: algernon, let me check that out

6:24 sagax: howto i print list with - for and range?

6:24 like this

6:24 1

6:24 2

6:24 3

6:25 theme: wasamasa, iterators are probably just as good as seqs if the languages supports higher order functions well

6:26 Bronsa: theme: iterators are mutable though, seqs aren't

6:26 wasamasa: theme: have fun writing java 8 then

6:26 * theme didn't have java in mind

6:27 wasamasa: it has iterators and lambdas, so if you believe that's all for it to not feel like an abomination, be my guest

6:28 for the record, ruby is probably the closest language if you want something that feels like lisp

6:29 sagax: Java and clojure I still very unclear for me

6:29 theme: wasamasa, java isn't a horrible language, but not my favorite language either

6:29 wasamasa, heh... so I wasn't the only person who feels ruby is similar to lisp

6:30 sagax, I believe that a "for loop" is the wrong tool for that

6:31 wasamasa: ,(for [x (range 3)] (println x))

6:31 clojurebot: (0\n1\n2\nnil nil nil)

6:31 * wasamasa scratches head

6:31 theme: lol

6:32 oh wait, I confused for with do

6:32 sagax, ignore me

6:34 wasamasa, so core.logic is prolog in clojure?

6:35 wasamasa: theme: sure sounds so

6:35 core.match is also neat

6:35 theme: ok.... so macros can emulate a lot of features from other languages

6:37 Why people get confused in a dynamic-typed system?

6:37 *don't get*

6:38 wasamasa: why do some people climb mountains without ropes?

6:39 theme: When I write a function, one of the very first things I think is "What are the arguments' types? What can I do with them?"

6:39 As a result, I often write out the types even in languages where type signatures are optional

6:41 wasamasa: well, typed clojure is a thing if you want to reap these benefits

6:42 theme: wasamasa, is your thought process different or something?

6:42 wasamasa: theme: yup

6:42 theme: I rather think about how functions transform their inputs

6:42 Aang4chi: wasamasa: isn't it the same thing?

6:42 wasamasa: Aang4chi: well, no, in java I'd be rather thinking about the types

6:43 theme: I sometimes attempt to use an array index in place of the data in the array

6:44 even C's rudimentary type system can catch that

6:44 Aang4chi: wasamasa: oh, by saying "how function transmorms arguments" you mean actual implementation, not the mapping from inputs to outputs?

6:44 wasamasa: Aang4chi: well, yes

6:44 Aang4chi: Interesting.

6:44 wasamasa: I also use the built-in datatypes way more than custom ones

6:44 * theme is confused

6:46 Aang4chi: theme: the problem with modern type systems is that they are usually not expressible enough. I see types as a design tool, not as a development tool which helps you spot a typo or something like that. I think minor mistakes like the one you've described are rather rare and are non that important.

6:46 theme: When I try to write a recursive function in python, I sometimes get into confusing bugs, (such as appending a list of lists to a list of numbers)

6:46 I find that very annoying

6:47 Aang4chi, what do you mean by "modern type systems"?

6:49 Aang4chi: theme: the ones we have in Haskell\Ocaml\Scala\etc

6:49 theme: Aang4chi, and that's not expressive enough?

6:49 O_o

6:50 Aang4chi: Well, yes.

6:51 theme: btw quite a large portion of my bugs involves doing the right thing with the wrong variable

6:52 Aang4chi, what do you want to express that you find those type systems not expressive enough?

6:56 algernon: theme: recursive functions are much more clear when you don't mutate random stuff.

6:57 theme: algernon, I don't mutate random stuff -_-

6:58 most of my functions mutate only local variables

6:59 Aang4chi: theme: well, it's not about me in particular. For example, in ocaml it's not very convenient to work with polymorphic definitions due to lack of type classes. In Scala... Do we even have dependent types in scala? Haskell... Try defining plus = (+). The list goes on and on.

7:01 theme: Aang4chi, what's wrong with "plus = (+)"?

7:02 Aang4chi: theme: https://www.refheap.com/106911

7:03 theme: Aang4chi, eh??

7:03 lazybot: theme: Uh, no. Why would you even ask?

7:04 theme: Aang4chi, works on ghc.io

7:05 weird

7:06 Aang4chi, oh great... "The restriction is turned on by default in compiled modules, and turned off by default at the GHCi prompt (since GHC 7.8.1)."

7:06 Aang4chi: theme: well, I'm not really following Haskell so I can't tell you whether they did something to the inference algorithm in later versions of ghc or it depends on compilation options.

7:06 theme: https://wiki.haskell.org/Monomorphism_restriction

7:06 Aang4chi: Yeah, that's the link I wanted to paste too, lol.

7:07 theme: Aang4chi, you can turn it off, so it doesn't sound like a fundamental problem with types

7:08 Aang4chi: Well, obviously it's just one minor special case. The point is that type systems are still not sophisticated enough.

7:11 I should point out that I think types are awesome and really cool and all that stuff. I imagine someday we will have formal description of every API and protocol on the web, and implementations will be checked statically to conform to it. But we're not there yet.

7:16 TMA: and we won't ever be there, APIs and protocols are made faster than formal descriptions thereof

7:19 Aang4chi: TMA: well, they are writing documentation after all, aren't they?

7:21 TMA: that too is unfortunately lagging behind the implementation

7:22 * TMA personally can produce say N pages of something per day -- be it pages of code or documentation, the total amount is roughly constant

7:25 TMA: a given chunk of functionality takes M pages of code -- i can cram more features in if I forgo documentation or testing or formal specification or ...

7:27 most people are not motivated enough to improve on their work once the product is labeled "WORKSFORME" in their heads; I think that the problem is with human psychology

7:27 if it can be shipped without X it eventually will be

7:28 noncom|2: Aang4chi: probably we have to make an AI to do that since as I see it, human factors will never avail to it, unless someone employs specifically OCD-enabled people for that, but that's not very likely too

7:28 TMA: Aang4chi: unless there is a way to make the formal specification mandatory for using the product, the specs won't exist in general

7:30 noncom|2: yeah, coding takes too much thought and dedication. no one cares much for the mere narrative letters when they can code... something else has to come and fill the space for this to work.

7:32 TMA: and to add insult to injury: the people responsible for shipping might just strip the formal specification from the documentation, because they do not understand it ad therefore it is some unnecessary fluff

7:33 after several years of a system being in production we have received formal specification of the interface. On a special request. As an _exceptional_ courtesy. Even though it was available (and acurate, unlike the provided documentation) since the very start.

7:34 noncom|2: TMA: are you talking about some system you use?

7:34 some 3rd party one?

7:34 TMA: noncom|2: yes

7:35 noncom|2: heh

7:37 TMA: the programmer of the 3rd party system has told me, that he has this formal description for every version he made, because it makes HIS life easier; We have spent a week with each version by recreating it (to make our lives easier) via reverse engineering

7:43 Aang4chi: TMA: so bitter

7:43 If Shakespeare was a programmer, I'm sure he'd written something along these lines

7:44 In the end both your and 3rd party teams would kill themselves out of desperation.

7:46 Seriously though, if SPAs will be dominating and servers will just serve raw data, I imagine search engines could do something to politely force people to maintain specs to their data.

7:46 It's very, very speculative, but you get what I mean.

7:53 wiruzx: Hi everyone

7:55 Do you know, why leiningen says to me that Don't know how to create ISeq from: clojure.lang.Keyword when I'm adding :source-paths ["src/clj"] into a project file?

7:55 Sorry for the stupid question though

7:56 Aang4chi: wiruzx: paste the whole project.clj

7:56 oddcully: wiruzx: could you put your projects.clj on refheap, pastebin, ... please?

7:56 wink: wiruzx: maybe it should be [["src/clj"]]

7:56 wiruzx: I tried, but it didn't work

7:57 wink: ok, then see what the others said ;)

7:57 wiruzx: Basically it's just an empty compojure template

7:57 With only added :source-paths

7:57 just a sec, i'll create gist

7:57 oddcully: the problem could be, where you have added it

7:57 wiruzx: https://gist.github.com/wiruzx/b329e9081e3a8b01548f

7:58 oh crap

7:58 sorry

7:58 i'm very stupid

7:58 oddcully: rubberducking worked?

7:58 wiruzx: You were absolutely right

7:58 oddcully: (inc rubberduck)

7:58 lazybot: ⇒ 3

7:58 clojurebot: Cool story bro.

7:58 wiruzx: Thanks

7:58 Aang4chi: Lol.

7:59 wiruzx: I need more cofee

7:59 snowell: Never heard that term before…now I will use it more than I should :D

8:01 Aang4chi: snowell: same here, lol.

8:06 wink: https://en.wikipedia.org/wiki/Rubber_duck_debugging yea

8:06 but my experience is more like typing it out into irc helps best.

8:06 the more people in the channel the better

8:07 irctc: Hi, I want to use an atom in a multithreaded application to save some state

8:07 But I have the following problem: http://pastebin.com/pqD6WPGy

8:08 I want to check if a value is in the collection , and if not, add it there and do some calculations.

8:08 Problem is that between the contains? check and the swap!, another swap! may have happened

8:08 So do I need to use a ref to coordinate updates to a single state?

8:10 Aang4chi: Either use ref, or perfom check and modification in one function.

8:13 irctc: If I do the check and modification in one function, using swap, then the new value of the collection is returned. But I would have to do another deref to check if the calculations need to be done

8:14 I dont see how to do this with swap

8:17 I got it to work like this: calculations only happen once. But it seems there is a simpler way: http://pastebin.com/HjsgGBt2

8:34 ordnungswidrig: iref: why not (swap! collector (fn [c] (if (contains c n) c (conj c n))))

8:37 irctc: whoops, that was meant for you, not iref

9:20 crocket: hi

9:21 Do we benefit a lot from dependency injection in clojure?

10:03 yoyo: hi

10:18 jefelante: Is there a more idiomatic way to write this function? it feels like I have some redundant blocks but it took me a lot of tries to get it to work since I don't quite understand go-loop and alt! https://gist.github.com/anonymous/a7c47cd7b38c2e71a9bd

10:47 tim: jefelante: yes, when you close a channel it starts delivering nil after all pending puts are delivered

10:48 so drop the alt!, and the off-chan. Just close the in-chan when you're done

10:48 jefelante: oh

10:49 well i guess i over thought that one

10:49 thanks! :)

10:52 ericbmerritt: I have a, hopefully, straightforward ring question that is stumping me.

10:52 for various reasons I am stuck deploying as a war. I am using sierra's component library.

10:52 I want to initialize the components once and then use them in the handlers.

10:53 but the ring init function doesn't take advantage of a return value, there there isn't any way to set state (which is a good thing generally, but I am trapped by the war).

10:53 is there a way around this, or do I just have to move away from the component model?

10:56 gfredericks: ericbmerritt: you should be able to use a var as a piece of global state

10:56 so the ring handler can be a var, and the init function can set it with alter-var-root

10:57 ericbmerritt: gfredericks: aren't vars all thread-local though (I am getting up to speed on clojure).

10:57 gfredericks: ericbmerritt: nope, that's just ^:dynamic vars

10:57 normally named *with-earmuffs*

10:58 stuartsierra: Prior to Clojure 1.3, all Vars were optionally bindable as thread-local.

10:58 gfredericks: clojure 1.3 is the oldest clojure ever

10:58 ericbmerritt: gfredericks: thanks. that should solve my problem. I wish I had asked two days ago :P

10:59 gfredericks: ,(def my-handler nil)

10:59 clojurebot: #'sandbox/my-handler

10:59 ericbmerritt: stuartsierra: thanks for components, I was missing 'apps' from my erlang projects and that replaces it well

10:59 gfredericks: ,(alter-var-root #'my-handler (constantly (fn [req] {:body "Got it."})))

10:59 clojurebot: #object[sandbox$eval47$fn__48 0x2a195a95 "sandbox$eval47$fn__48@2a195a95"]

10:59 gfredericks: ,(my-handler {})

10:59 clojurebot: {:body "Got it."}

10:59 stuartsierra: ericbmerritt: You're welcome!

11:02 thein5Oh: Why we're at it... I was always wondering: shouldn't the functions in component be called start! and stop!, that is, with exclamation marks? Is this convention still relevant?

11:02 stuartsierra: thein5Oh: the `!` convention isn't very well-defined. Some people use it to mean "has side effects" while others use it to mean "modifies state," e.g. swap!

11:03 Even Clojure is inconsistent in this regard, e.g. swap! vs alter-var-root.

11:04 `start` and `stop` in Component don't necessarily have side effects, although they usually do. It's up to the user.

11:05 thein5Oh: stuartsierra: I always thought it was safe to use in stm transactions vs not safe to do so (thus send but swap!). On the other hand, it may not be that practical to make such a general convention to depend on one particular language construct...

11:06 So yeah, I see - there is no single convention actually.

11:09 stuartsierra: My personal convention is to name side-effecting functions as verbs, pure functions as nouns.

11:18 dstockton: what if a word is both a noun and a verb

11:19 address, credit, charge, answer

11:19 total chaos

11:20 TimMc: I use Cyrillic homoglyphs for side-effecting functions.

11:21 for example, copy vs сору

11:22 rpaulo: do you program alone?

11:22 TimMc: Funny you should ask!

11:22 But in the end, does not everyone program alone?

11:32 justin_smith: stuartsierra: let's not forget the "! means not safe in a transaction" convention

12:17 kwladyka: what do you think about parameters in functions? (defn foo [[cols rows] queen rook bishop king knight] ...) or (defn foo [[cols rows] [queen rook bishop king knight]] ...) or map with :queen 2 :king 3... from one side (defn foo [queen rook bishop king knight] ...) tell programer exactly what he need to write, but from other hand it is less readable, because in many cases i have to pass this as it is to other function

12:17 oh and (defn foo [board-size pieces] ...) <- which is the most readable

12:17 but dont tell coder how exactly parameters look

12:18 because Clojure doesn't have strong types

12:22 gfredericks: does anybody know why my cljs program logs an error in the browser console trying to load "../goog/base.js" but then otherwise works fine?

12:23 kwladyka: gfredericks, what error?

12:28 gfredericks: oh man I didn't look closely enough

12:28 my html file explicitly tries to load it; I'll just delete that line since apparently I don't need it

12:28 oddcully: switched builds? stale stuff?

13:13 gfredericks: is anybody nontrivially using test.check in cljs?

13:50 noncom|2: is derefing an atom considered an expensive operation to be avoided when possible ?

13:51 (apart from other implications of derefing an atom)

13:52 gfredericks: noncom|2: I don't think so

13:52 noncom|2: besides from the time taken for the actual pointer works, afaik it can block for a little while if the atom is currently being changed... no?

13:52 justin_smith: deref of an atom is cheap

13:52 noncom|2: no, there is no blocking of deref

13:52 noncom|2: ah

13:53 timvisher: ,(let [x (throw (Exception.))] ["ohai" x])

13:53 clojurebot: #error {\n :cause nil\n :via\n [{:type java.lang.Exception\n :message nil\n :at [sandbox$eval25 invoke "NO_SOURCE_FILE" -1]}]\n :trace\n [[sandbox$eval25 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java" 6792]\n [clojure.lang.Compiler eval "Compiler.java" 6755]\n [clojure.core$eval invoke "core.clj" 3079]\n [clojure.core$eval3$fn__4$fn__14 invoke "NO_SOURCE_FILE" 0]...

13:53 noncom|2: timvisher: what did you expect with that?

13:53 tbaldridge: right, deref will never bock. Although swap! will "spin lock" as every swap competes for access to the atom

13:54 noncom|2: okay, very good, so if I only have 1 thread working on atoms, reading and writing them, then there will be no real cost for that

13:55 tbaldridge: correct. not a significant one. There's some low-level CPU communication that has to happen, but you probably won't notice it

13:55 timvisher: noncom|2: we're having a very weird issue with cheshire 5.5.0 where we can't catch a parse exception

13:55 justin_smith: tbaldridge: right, but you don't need to wait for the swap!s to stop spinning before getting a value (for better or worse), if you want that kind of linearity an agent with await might help

13:55 timvisher: but it behaves exactly as i'd expect to it in every other context

13:55 we thought because of some repl weirdness that the let was eating the exception and somehow binding it to the symbol

13:56 but that's obviously not the case

13:56 noncom|2: timvisher: maybe you could post a sample on refheap?

13:56 timvisher: and i just verified it

13:56 noncom|2: let me see if we can

13:59 noncom|2: hmmmm, stumbled upon a fun thing:

13:59 ,{[] [] (int-array 1) [] (int-array 1) []}

13:59 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Duplicate key: (int-array 1)>

14:00 noncom|2: the macro checks for the appearence...

14:00 gfredericks: it's not the macro, it's the reader

14:00 ,'{[] [] (int-array 1) [] (int-array 1) []}

14:00 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Duplicate key: (int-array 1)>

14:00 gfredericks: ^ you can't even quote it

14:00 Bronsa: noncom|2: the '(int-array 1) list appears twice as key at read-time

14:00 justin_smith: noncom|2: ##(hash-map Double/NaN 0 Double/NaN 1 Double/NaN 2 Double/NaN 3)

14:00 lazybot: ⇒ {NaN 0, NaN 1, NaN 2, NaN 3}

14:00 noncom|2: i thought thats the reader macro

14:01 justin_smith: ,{Double/NaN 0 Double/NaN 1}

14:01 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Duplicate key: Double/NaN>

14:01 noncom|2: hehe

14:01 gfredericks: justin_smith: cute

14:01 noncom|2: gotta keep an eye on all that

14:01 special cases

14:01 justin_smith: ##(get (hash-map Double/NaN 0 Double/NaN 1 Double/NaN 2 Double/NaN 3) Double/NaN)

14:01 noncom|2: happen :)

14:01 lazybot: ⇒ nil

14:02 Bronsa: justin_smith: wait what

14:02 justin_smith: it's hilarious, isn't it?

14:02 Bronsa: ah yeah NaN is not a special symbol

14:02 (╯°□°)╯︵ ┻━┻

14:03 (http://dev.clojure.org/jira/browse/CLJ-1074)

14:05 gfredericks: #clojure is place where Bronsa listens to WTFs about clojure and points people to existing jira tickets

14:17 vas_: If i specify :ring {:handler ph.core/app, :port 4004} in project.clj everything works fine, but changing the port to 80 does not let the app run... possible to run my app on port 80?

14:18 stuartsierra: vas_: Most operating systems require special privileges (e.g. root) to allow binding to port 80.

14:25 vas_: stuartsierra: awesome, that helps a lot... reading about it, it seems that people bind to something like 8080 and reroute via iptables... some people prefer to use nginx

14:33 timvisher: noncom|2: i think we've got it solved. it turned out to be a strange noir middleware issue.

14:34 essentially we weren't the ones throwing the exception we were seeing

14:34 the strangest bit of it though is that we have stack traces that show our code as being the thrower

14:34 but we can't reproduce it anymore, and don't have time for a bisect :(

14:41 noncom|2: timvisher: yeah, such thing happen :)

16:37 justin_smith: ERROR - increase :queue-size if this happens often

16:37 java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@46883bf4 rejected from java.util.concurrent.ThreadPoolExecutor@232dcbe[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 14768]

16:38 a coworker got this (it's intermittent) - where is the :queue-size this message mentions? The stack trace shows we are inside a ThreadPoolExecutor

16:39 which in turn was invoked by http-kit (but I don't know if this is an http-kit :queue-size option or what

16:41 OK, I found the error message in http-kit, so clearly she was overloading http-kit's ring-handler somehow https://github.com/http-kit/http-kit/blob/0e53d3d883901a229c189c263b2a4f6c07e66a0e/src/java/org/httpkit/server/RingHandler.java#L165

16:44 oh wait, it was here... https://github.com/http-kit/http-kit/blob/0e53d3d883901a229c189c263b2a4f6c07e66a0e/src/java/org/httpkit/server/RingHandler.java#L244 - now I see it was an error on close... never mind.

16:52 gfredericks: dnolen: do you know what this line does? https://github.com/clojure/test.check/blob/f3dc5aed2141205dc320255bbc9e839653019279/resources/run_tests_dev.html#L5

16:52 in my browser the file isn't found but everything runs fine anyhow

16:53 so the error in the console is a little annoying and I'm wondering if I can delete the line

17:08 {blake}: OK, I feel foolish I don't know this, but I want to create a lazy-sequence that reference a function, and terminates when the function returns nil. Like, if reading a text file, it'd be read(1) and reads the first line, read(2) returns the second, etc., and then read(n) returns nil if there is no line n.

17:08 tom``: how does compojure behave when being sent a request with the host containing a subdomain? It seems I can work with example.com/hello just fine but subdomain.example.com/hello never responds. (GET "/hello" request (println "hi")) works without the subdomain, but with a subdomain, I just get nothing back. Am I supposed to match (GET "/subdomain/hello" ...)?

17:08 Or is there something else going on?

17:10 tbaldridge: {blake}: https://github.com/clojure/clojure/blob/clojure-1.7.0/src/clj/clojure/core.clj#L2751

17:10 hiredman: tom``: what webserver do you have sitting in front of this?

17:10 tbaldridge: that's a rather simple example ^^

17:10 hiredman: my guess is you don't have it setup to respond correctly on the subdomain

17:10 tom``: none

17:11 hiredman: tom``: I would double check all the configuration before you get to compojure, because while compojure can do routing stuff based on domains, you have to explicitly make it, without that all the routing is just based on the path part of the request

17:11 tom``: ok

17:12 hiredman: check the dns, check the webserver, etc

17:12 tom``: is it typical practice to put like nginx and port forward to the compojure application?

17:13 {blake}: tbaldridge: That looks good. Thanks!

17:13 (inc tbaldridge)

17:13 lazybot: ⇒ 22

17:14 hiredman: I suspect it is, but I dunno, I think in general that is an easy solution to a few issues

17:15 e.g. ops can have an easier time terminating ssl at nginx

18:23 TimMc: There's no good way to ask compojure for a listing of its routes, yeah?

18:26 justin_smith: ,(defn stupid-power-of-two [n] (/ (apply / (take (+ 2 n) (repeat 2)))))

18:26 clojurebot: #'sandbox/stupid-power-of-two

18:26 justin_smith: ,(map stupid-power-of-two (range))

18:26 clojurebot: (1 2N 4N 8N 16N ...)

18:32 justin_smith: ,(defn uncanny-power-of-two [n] (reduce (rand-nth [/ *]) (repeat n 2)))

18:32 clojurebot: #'sandbox/uncanny-power-of-two

18:32 justin_smith: ,(map uncanny-power-of-two (range))

18:32 clojurebot: (1 2 4 8 16 ...)

18:33 justin_smith: wait that's totally wrong

18:34 it works only for even numbers

18:34 nope, not even then

18:35 perplexa: justin_smith: i dont'get it

18:35 justin_smith: perplexa: the uncanny one is totally broken and a sign I should go home for the weekend

18:35 the stupid one works

18:35 perplexa: or.. did it just pick the 2nd item of the vector 5 times in a row? :|

18:36 (rand-nth [/ *]) shouldn't that be / or *

18:36 or is it only evaluated once and then passed into reduce, instead of every time?

18:36 justin_smith: it's random on every call

18:36 and it doesn't do what I wanted

18:38 the "stupid" one uses the behavior of / when used with a single arg to invert a series of halvings to do doubling

18:38 the other one doesn't do that so it doesn't work

18:57 perplexa: fixed it

18:57 ,(defn uncanny-power-of-two [n] (let [o (rand-nth [* /])] (o (reduce o (repeat (+ n (Math/floor (o (o (o 1/2))))) 2)))))

18:57 clojurebot: #'sandbox/uncanny-power-of-two

18:57 justin_smith: ,(map uncanny-power-of-two (range))

18:57 clojurebot: (1 2N 4 8N 16 ...)

18:57 justin_smith: you can tell when / got picked from the N

18:58 ,(map uncanny-power-of-two (range))

18:58 clojurebot: (1 2N 4 8N 16 ...)

18:58 justin_smith: ,(map uncanny-power-of-two (range))

18:58 clojurebot: (1 2N 4 8 16 ...)

19:19 perplexa: justin_smith: gz :>

20:17 weebz: Is there a way to call ~@ outside of a quoted expression?

20:18 So I can do (somefunc [1 2 3]) and have it transformed to (somefunc 1 2 3), without doing (eval `(somefunc ~@[1 2 3]))

20:53 lodin_: ,(doc apply)

20:53 clojurebot: "([f args] [f x args] [f x y args] [f x y z args] [f a b c d ...]); Applies fn f to the argument list formed by prepending intervening arguments to args."

20:54 lodin_: weebz: ^^^

20:55 tmtwd: can anyone help me ? CompilerException java.lang.Exception: Found lib name 'honeysql.core' containing period with prefix 'quote'. lib names inside prefix lists must not contain periods, compiling:(yesql_examples/honey.clj:1:1)

20:55 http://pastebin.com/mp9x0vSb

21:13 justin_smith: tmtwd: you have a ' in your ns declaration, and it should not be there

21:14 tmtwd: justin_smith, you mean when I am using it in the repl?

21:15 justin_smith: tmtwd: no, that error happens when you have (ns foo.bar (:require 'honeysql.core))

21:15 it happens because of the '

21:15 tmtwd: but I'm not doing that

21:15 in the ns

21:15 justin_smith: OK, somewhere require call has an extra '

21:16 the usual case is in ns

21:16 tmtwd: there are no ' at all in the file

21:16 justin_smith: can you share a paste of the ns form?

21:17 tmtwd: http://pastebin.com/mp9x0vSb

21:17 sorry the error is now CompilerException java.io.FileNotFoundException: Could not locate honeysql/core__init.class or honeysql/core.clj on classpath: , compiling:(yesql_examples/honey.clj:1:1)

21:18 justin_smith: OK, so you fixed the first error already?

21:20 because if you simply have a different error when calling use a second time, that's because clojure will no-op when asked to load an ns a second time via use or require

21:21 even if there was an error the first time, it simply doesn't try the second time

21:22 tmtwd: oh

21:22 ok

21:23 I'll just switch to yesql and get help with someone irl

21:26 smandy: hi all - how do I get leiningen to use my local ~/.m2 repo as a source of artifacts. :local-repo "local-m2" doesn't seem to work? ( Referenced here https://github.com/technomancy/leiningen/blob/stable/sample.project.clj)

21:34 justin_smith: smandy: leiningen should always look at ~/.m2/ before looking for an artifact remotely. Are you sure you haven't customized your repo location, and you are looking for the right version id?

21:35 if you specify "local-m2" it will literally look for a folder called local-m2 which would have your local cache

21:48 celwell: Is there a better pattern than "(doall (map " for performing side-effects on each item in a sequence?

21:48 justin_smith: celwell: do you want the result?

21:49 celwell: no

21:49 justin_smith: if you are using 1.7, run!

21:49 celwell: Just something like sending an sms to every number in seq

21:49 justin_smith: (doc run!)

21:49 clojurebot: "([proc coll]); Runs the supplied procedure (via reduce), for purposes of side effects, on successive items in the collection. Returns nil"

21:49 justin_smith: it's just like map but for side effects

21:50 if not using 1.7, there's doseq

21:50 celwell: That looks good. Is there any breaking changes in 1.7 from 1.6 (should I just upgrade now?)?

21:51 justin_smith: very few if any

21:51 it's a great upgrade

21:51 celwell: Ok, thanks.

21:52 smandy: justin_smith: thanks for reply. Sorry was away :-)

22:04 lodin_: celwell: I have projects that define a function "update" which now clashes with clojure.core, so to avoid warnings I needed to exclude clojure.core/update when upgrading. Not breaking, but annoying.

22:07 It would be good if you should specify clojure.core version in the ns form. If present it would import based on the the :added key in the metadata.

22:08 If specified version is larger than the currently used clojure version, then you could get a sane error message.

23:14 tolstoy: Is there a clojure.core function kinda like repeatedly, but each "repeat" of the function call takes the value of the previous function call?

23:15 map-indexed (is what I was sorta wanting)

23:19 justin_smith: tolstoy: iterate

23:19 ,(iterate inc 0)

23:19 clojurebot: (0 1 2 3 4 ...)

23:19 tolstoy: Ah! ;)

23:20 I knew there was something like that. ;)

23:20 justin_smith: tolstoy: also, if you want to learn lazy-seqs, iterate is an easy one to do from scratch using the lazy-seq function

23:20 tolstoy: Must be time for my annual read clojure.core docs top to bottom.

23:20 justin_smith: tolstoy: be sure to also check out http://conj.io

23:23 tolstoy: Lately I've been revisiting things after years away. Vague memory issues. ;)

23:23 For instance, binary twiddling. Zach Tellman's gloss, binary-streams, etc, etc, are a great help.

23:25 TEttinger: Zach Tellman's existence is a great help

23:26 tolstoy: Aleph is quite nice.

23:26 TEttinger: I'm very glad primitive-math made it into clojure itself, in a way

23:28 IIRC in a game I was writing in clojure, rewriting boxed arithmetic to prefer primitive arithmetic wherever possible (which was made easy to spot when it was needed by primitive-math) allowed a rather significant speedup

23:29 blkcat: i've been working with a lot of his stuff lately. gloss is a lifesaver

23:29 TEttinger: (I fixed a lot of stuff at the same time due to revisiting a lot of stuff, so I can't be sure that was all of it, but there were 400+ boxing math ops in a rather modestly sized program)

23:30 was someone here working on a native clojure? clojure to C or something like it? I seem to recall justin_smith being involved maybe?

23:30 justin_smith: err

23:31 there's pixie, if that's what you were thinking of

23:31 TEttinger: no, I'm aware of that, there was an attempt at least of a C Clojure

23:31 ... hm

23:34 tolstoy: I think tbaldridge had something going along those lines before pixie.

23:34 TEttinger: I'm just kinda wondering about language stuff. I really like LuaJIT's approach to a lot of things, not sure if I personally could do half as well as Pixie even using an existing state-of-the-art JIT

23:41 so I'm just sorta pondering. I really like clojure, the seq abstraction is great, the API is really, truly well-designed, but certain things I'm not as happy about.

23:42 it's too difficult to reason about performance. There are limitations of the JVM, like the heaviness of objects and the unusual behavior differences between primitives and objects

23:42 2d, 3d and higher-dimensionality arrays remain extremely hard to deal with

23:46 justin_smith: TEttinger: what do you think of core.matrix?

23:49 ,(defn whatami [n] (let [o (rand-nth [* /])] (o (reduce o (repeat (+ n (Math/floor (o (o (o 1/2))))) 2)))))

23:49 clojurebot: #'sandbox/whatami

23:49 justin_smith: ,(map whatami (range))

23:49 clojurebot: (1 2 4N 8N 16N ...)

23:50 justin_smith: TEttinger: how do you like that headscratcher?

23:55 TEttinger: hm?

23:55 justin_smith: TEttinger: the whatami function I defined above

23:55 TEttinger: hmmmmm

23:55 justin_smith: fun bit of obfuscation, I thought

23:55 TEttinger: ,(re-find #"\ufeff" ",(defn whatami [n] (let [o (rand-nth [* /])] (o (reduce o (repeat (+ n (Math/floor (o (o (o 1/2))))) 2)))))")

23:55 clojurebot: nil

23:56 TEttinger: ,(re-find #"\uffef" ",(defn whatami [n] (let [o (rand-nth [* /])] (o (reduce o (repeat (+ n (Math/floor (o (o (o 1/2))))) 2)))))")

23:56 clojurebot: nil

23:56 TEttinger: hm

23:56 just checkin'

23:56 justin_smith: hahaha

23:56 no no, each part really does what it looks like

23:56 the weird part is that it works

23:56 ,(map whatami [8 16 32 64])

23:56 clojurebot: #<ArithmeticException java.lang.ArithmeticException: integer overflow>

23:56 justin_smith: argh

23:57 mostly works!

23:57 ,(map whatami [8 16 32 63])

23:57 clojurebot: #<ArithmeticException java.lang.ArithmeticException: integer overflow>

23:57 justin_smith: :P

23:57 ,(defn whatami [n] (let [o (rand-nth [*' /'])] (o (reduce o (repeat (+ n (Math/floor (o (o (o 1/2))))) 2)))))

23:57 clojurebot: #<RuntimeException java.lang.RuntimeException: Invalid token: /'>

23:57 TEttinger: ,(* 1/2)

23:57 clojurebot: 1/2

23:57 TEttinger: ,(/ 1/2)

23:57 clojurebot: 2N

23:57 justin_smith: ,(defn whatami [n] (let [o (rand-nth [*' /])] (o (reduce o (repeat (+ n (Math/floor (o (o (o 1/2))))) 2)))))

23:57 clojurebot: #'sandbox/whatami

23:57 justin_smith: ,(map whatami [8 16 32 63])

23:57 clojurebot: (256N 65536N 4294967296 9223372036854775808N)

23:58 TEttinger: ,(* (* 1/2))

23:58 clojurebot: 1/2

23:58 justin_smith: ,(map whatami (range 8 32))

23:58 TEttinger: ,(/ (/ 1/2))

23:58 clojurebot: (256N 512N 1024N 2048 4096N ...)

23:58 1/2

23:58 TEttinger: ahhhh

Logging service provided by n01se.net