#clojure log - Mar 16 2015

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

0:30 bacon198`: question, how do I remove an element from a vector, and return the list with the removed element?

0:30 ,(def x [1 2 3 4])

0:30 clojurebot: #'sandbox/x

0:34 bacon198`: i'm guessing subvec

0:40 TEttinger: I'm pretty proud of this clojure name generator, it had some odd reqs http://ideone.com/zwnFAL

0:40 ,(def x [1 2 3 4])

0:40 clojurebot: #'sandbox/x

0:40 TEttinger: bacon198`, what output do you want?

0:41 l1x: https://www.irccloud.com/pastebin/m2BK6uxa

0:41 does this work for you?

0:41 it does not seem to catch ctrl+c or the printing is not happening for some other reason

0:43 TEttinger: l1x, in the repl ctrl-c would get intercepted by the repl itself

0:43 l1x: this is not in the repl

0:43 TEttinger: then maybe the thread being asleep is preventing it from receiving input?

0:47 l1x: maybe

0:47 anyways i investigate it tomorrow

0:48 thanks

0:48 amalloy: *out* needs to be bound for println to do anything useful, and in a brand-new Thread it isn't. you can fix this by, for example, (let [out *out*] (Thread. #(binding [*out* out] (println ...))))

0:49 TEttinger: (inc amalloy) ; l1x, I love having people who are actually good at clojure here

0:49 lazybot: ⇒ 236

0:50 TEttinger: since I am pretty much not

0:50 l1x: i am a noob

0:50 TEttinger: that name gen has turned out well though

0:50 l1x: not even full time software guy :)

0:50 but amalloy and justin are great

0:50 TEttinger: heh

0:51 I miss technomancy

0:51 l1x: where is he?

0:51 TEttinger: doing charity work

0:51 l1x: ahh

0:51 the unsung here is ztellman

0:51 TEttinger: indeed

0:51 primitive-math is amazing

0:51 l1x: his code is terribly good

0:52 i am using his library to build our new datapipeline

0:55 justin_smith: oh, hi

2:50 egli: l1x: datapipeline? Anything more specific?

4:05 dysfun: ambrosebs: the last message i saw before i reconnected was you saying people think type annotations are documentation. methinks you're setting yourself up for a fight with the entire scala community there ;)

4:28 hrm, any marginalia users around?

4:28 trying to embed code in the documentation of marginalia doesn't look so good

4:28 it's example code so i don't want it to actually go into the library

4:43 michaelr`: Does a hashing function exist which takes any value but produces a configurable number of hash values?

4:46 noidi: dysfun, how about leaving the code in but wrapped in a (comment ...)?

4:47 dysfun: noidi: i wondered why so many people were doing that

4:47 is it because of marginalia?

4:48 noidi: I think it's mostly because that way you can use your editor's structural editing support on the example code

4:48 paredit or what have you

4:49 dysfun: ah yes, paredit. one day i might actually make the time to give it a proper go

4:49 so i came up with a hack for making midje tests intermingle-able with real code and stripping them out for uberjar build

4:50 i'm concerned this is going to clog up the marginalia output too

4:51 noidi: I place something like (comment (gen/sample my-gen)) after each custom test.check generator

4:52 dysfun: ah, i'm using midje

4:52 noidi: I can then see an example of the generator's output by moving the cursor to the commented form and pressing a keyboard shortcut

4:52 otherwise I'd have to either write that form in the REPL myself every time, or copy and paste it from a textual comment

4:56 dysfun: *nod*

4:57 https://gist.github.com/jjl/266e4fd88846ab8674f4

4:57 this is the hack i'm using to make midje autotest work

5:00 if i put those in a comment block, they won't run, obviously

5:01 but since i don't actually use (comment) for any other purpose, perhaps i can just make my hack work on that instead

5:02 noidi: dysfun, have you seen this? https://github.com/marick/Midje/wiki/Production-mode

5:02 dysfun: yes. there's no way to actually use it :)

5:03 marick says there'll be something coming soon

5:03 til then i'm left with this awkward hack

5:06 noidi: ok

5:10 egli: dysfun: not the answer you want to hear, but I've been quite happy with codox

5:11 and markdown format

5:13 dysfun: yeah, but i like marginalia output

5:13 it's pretty

5:13 people like reading pretty documentation that's helpful

5:13 egli: dysfun: yes, looks matter :-)

5:13 dysfun: and given how many times i've gotten writing this library wrong and how many times i've now written it to get it right, it'd be nice if other people didn't struggle to use it

5:41 jonathanj: is there a standard or common markup accepted by tools for use in docstrings?

5:43 dysfun: no. if you choose a documentation generator tool, most of those support structured markup

5:44 i'm quite fond of marginalia

5:45 that embeds markdown

5:46 mpenet: I really don't like it. If you don't care about the code and just want to use the lib it's a too noisy

5:49 dysfun: mpenet: sorry, could you explain that please?

5:49 you mean that you'd prefer *not* to see the code?

5:51 mpenet: yes

5:52 by default at least

5:52 dysfun: oh that's an interesting idea

5:52 mpenet: codox is better imho for doc, you get the signature/docstring and a link to the code if necessary

5:52 less noisy

5:52 less scrolling

5:52 dysfun: i quite like codox output i must say. but i'm very fond of the idea of literate programming

5:53 perhaps codox favours larger libraries and marginalia smaller ones?

5:54 mpenet: I wouldnt be so sure. unless it's a 10 line single namespace lib

5:54 dysfun: this is a small library. less than a hundred lines of code

5:54 mpenet: it's nice to have, but shouldn't be the default doc imo

5:55 dysfun: well i also like that when you go to your code, the docs are there too

5:55 i wonder if you can just generate both

5:56 off to a great start with codox. i get an obscure error about hiccup

5:58 egli: dysfun: you should be able to produce both marginalia and codox doc. Just specify different output dirs

5:59 dysfun: yup. except `lein doc` (codox) throws bizarre hiccup-related errors i'm trying to figure out how to fix

6:01 i give up. any ideas? https://www.refheap.com/98497

6:01 that's me trying with the last-but-1 version because the latest did the same

6:02 mpenet: maybe a conflict with a user profile

6:04 dysfun: well whaddya know?

6:04 clj-ns-browser

6:04 which i haven't been using anyway because it's not very good

6:06 egli: dysfun: *that* was the problem?

6:06 dysfun: yes

6:06 it was in my dev dependencies in my profile

6:12 now i have to go fix my tests before i can generate it. heh.

6:16 hrm. a marginalia-alike with live updating would be awesome

6:17 you could change the docstring and go to your browser to see the updated docs

6:17 without having to trigger a rebuild and hit refresh

6:22 zot: anybody have suggestions on this warning in a loop/recur: "recur arg for primitive local: len is not matching primitive, had: Object, needed: long" actual code here: https://gist.github.com/anonymous/96404337149c10c52439

6:23 dysfun: that sounds like a type error to me

6:23 zot: i found that doing a (long …) cast within the recurs fixes it, but that seems a strange fix

6:24 since the thing being cast is the result of (- foo bar), both of which are numeric

6:24 but i assume autoboxing is transparent, so maybe it's the only way?

6:39 Glenjamin: ^long might work

6:42 dysfun: hrm. i'm writing a library that generally expects to be used in combination with an edn reader (it has lots of symbols and lists in, you'd have to do awkward quoting of things in clojure). do we think it's reasonable to depend on clojure.tools.reader and write a function to scrape edn and read it directly or do we think that enough people might want to feed it from clojure and not want the dep to make not doing so worthwhile?

7:01 mpenet: anyone knows how to run core.async cljs test suite?

7:01 it doesn't seem to be documented anywhere

7:01 noncom: dysfun: i did not understand what you're asking.. :)

7:02 dysfun: noncom: it would be slightly more convenient to have one import and one function call to use this from a file. doing so would make me depend on clojure.tools.reader (which most people will want to use). should i do that or not?

7:04 noncom: hmmm well, maybe i am not the most opinionated person to ask about this, but depending on clojure reader seems fine, since anyway, it is in the standard package?

7:04 and also i think there is no real alternative to clojure.tools.reader

7:04 dysfun: clojure.tools.reader is not standard, it's a pure clojure reimplementation

7:05 noncom: oh, i thought it's already inside...

7:06 dysfun: no. and i specifically want the edn reader

7:06 (the format makes liberal use of lists and symbols which are very pretty in edn but require quoting and such in clojure code

7:21 noncom: dysfun: hmmm, interesting..

7:52 jonathanj: are there documentation tools that aren't centered around literate programming?

7:53 hrm, when i "lein run" my application on OS X i get a Java dock icon until my code exits

7:54 i'm using flying-saucer-pdf, i'm assuming that someone starts up AWT or similar and the JRE thinks it's running a GUI app? is there a way to stop this?

7:55 dnolen: https://groups.google.com/d/msg/clojurescript/e3gOEUJlkMc/PATUU2JaBl4J

7:55 ClojureScript 0.0-3115 out

8:05 dysfun: jonathanj: codox isn't

8:05 also if you figure out how to stop the dock icon, i'd love to hear. i get it because i spin up netty

8:11 justin_smith: dysfun: maybe use a headless jre?

8:12 noncom: what is the current best option to validate passed function arguments?

8:12 justin_smith: jonathanj: oh yeah, java is really annoying in thinking that if you process something image related, you must want to connect to the GUI

8:13 noncom: I like prismatic/schema for that, but there is also :pre conditions

8:15 * dysfun uses :pre sometimes to clean up code

8:15 dysfun: reminds me of old-fashioned assert()

8:17 jonathanj: justin_smith: any suggestions to get rid of that?

8:19 hrm, how would i do the equivalent of `java -Dfoo=bar` from Clojure?

8:19 dysfun: what do you mean? how do you get access to the definitions? or how do you set them in-process?

8:20 the latter cannot be done but you can work around it by agreeing to only use a wrapper

8:20 jonathanj: hrm

8:20 i was reading http://www.oracle.com/technetwork/articles/javase/headless-136834.html

8:20 noncom: in schema how can i say OR inside a type template?

8:20 dysfun: the former, you do the java way, with clojure syntax

8:21 noncom: like a value can be either [] or nil or keyword

8:21 jonathanj: i'd like to just try -Djava.awt.headless=true as a quick once-off

8:21 but it claims i can use System.setProperty to do the same thing, but apparently that code is broken

8:21 oh, hrm

8:21 that's a static method

8:21 dysfun: how are you launching clojure? like 'lein repl' ?

8:22 jonathanj: dysfun: i'm just using `lein run` at the moment

8:22 dysfun: ah right. well System/setProperty should work

8:22 jonathanj: okay, so (System/setProperty "java.awt.headless" "true") in my main function does what i want (and stops the whole GUI start up thing)

8:22 sorry, i was an idiot and did (.setProperty System ...) initially

8:23 dysfun: heh, i do that often

8:24 justin_smith: jonathanj: I do "env _JAVA_OPTIONS=-DFOO=bar lein ..."

8:26 jonathanj: but you can also do :jvm-opts ["-Djava.awt.headless=true" ...]

8:26 jonathanj: ah, thanks, that would have been useful to at least try this out

8:26 justin_smith: (in project.clj)

8:27 actually I do both - the former if I want to frequently change a def, the latter if it's a dev time def that doesn't change

8:29 jonathanj: how do i manually include a java project in my clojure project?

8:30 so either i have the original Java source or at least a jar, but it's not available on any kind of central repository

8:33 justin_smith: jonathanj: would you be *allowed* to host it if you chose? because putting it in a mvn repo is likely the easy thing

8:33 otherwise you can put it in your repo on the classpath

8:34 (or java-source-path, of course, if you want lein to compile it...)

8:37 jonathanj: justin_smith: it's not my code, the author is just kind of AWOL

8:38 if i use java-source-path, is it automatically compiled with my clojure code and available via (:import)?

8:39 i guess i can just give it a try

8:41 dysfun: ,(inc justin_smith)

8:41 clojurebot: #error{:cause "Unable to resolve symbol: justin_smith in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: justin_smith in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: justin_smith in th...

8:41 dysfun: lol

8:42 clearly i've forgotten the syntax

8:42 agarman: (inc justin_smith)

8:42 lazybot: ⇒ 210

8:42 agarman: (dec dysfun)

8:42 lazybot: ⇒ 2

8:42 jonathanj: justin_smith: thank you!

8:42 agarman: (inc dysfun)

8:42 lazybot: ⇒ 3

8:45 justin_smith: jonathanj: yeah, if you set :java-source-paths [...] lein will compile the classes under that path

8:59 ,(str 'ba (repeat (rand-int 4) 'na))

8:59 clojurebot: "baclojure.lang.LazySeq@c27025f5"

8:59 justin_smith: blergh

8:59 ,(apply str 'ba (repeat (rand-int 4) 'na))

8:59 clojurebot: "ba"

9:00 justin_smith: ,(apply str 'ba (repeat (rand-int 4) 'na))

9:00 clojurebot: "bananana"

9:01 dysfun: :)

9:01 that's actually quite a nice way of introducing simple logic when teaching programming

9:02 stealing that. thanks.

9:02 justin_smith: I'm sure it would go over great in a 5th grade classroom

9:02 heh :)

9:02 dysfun: i taught a friend to program clojure a few months ago that was odd

9:02 gfredericks: ,(apply str 'ba (take-while (fn [_] (< (rand) 0.75)) (repeat 'na)))

9:02 clojurebot: "bana"

9:02 dysfun: he'd not done anything more complex than excel formulae before

9:03 gfredericks: ,(apply str 'ba (take-while (fn [_] (< (rand) 0.75)) (repeat 'na)))

9:03 clojurebot: "banana"

9:03 gfredericks: ,(apply str 'ba (take-while (fn [_] (< (rand) 0.75)) (repeat 'na)))

9:03 clojurebot: "ba"

9:03 gfredericks: ,(apply str 'ba (take-while (fn [_] (< (rand) 0.95)) (repeat 'na)))

9:03 clojurebot: "banananananananananana"

9:03 dysfun: i'm still not entirely sure how clojure has ended up with such a lesser need for parens than other lisps, but it's very noticeable compared to for example LFE

9:04 justin_smith: &(frequencies (repeatedly 100 #(apply str 'ba (take-while (fn [_] (< (rand) 0.75)) (repeat 'na)))))

9:04 lazybot: ⇒ {"banananana" 4, "bananananananana" 5, "banananananananananananananananananana" 2, "banana" 14, "banananananananananana" 1, "banananananananananananana" 2, "bananananananananana" 2, "ba" 22, "banananananana" 4, "bananananana" 8, "bana" 21, "banananananananana" 3, "bananana" 12}

9:04 justin_smith: wow, it fit in one output!

9:04 dysfun: :)

9:05 agarman: (str (apply str (repeat (rand-int 16) 'na)) " " 'batman)

9:05 ,(str (apply str (repeat (rand-int 16) 'na)) " " 'batman)

9:05 clojurebot: " batman"

9:05 jonathanj: hrm, how would i have lein include some loose jar in my project?

9:05 justin_smith: jonathanj: put it in your :resource-paths

9:05 then it ends up on the classpath in the generated (uber)jar

9:05 agarman: ,(str (apply str (repeat (rand-int 16) 'na)) " " 'batman)

9:05 clojurebot: "nanananananananananana batman"

9:05 jonathanj: justin_smith: and for use during development?

9:05 thheller: @dnolen: if you call .disableThreads on the closure compiler the System/exit is not required as there will not be a lingering thread. the threaded model provides no benefit so there really is no downside to it.

9:06 justin_smith: jonathanj: yes, it will also be on the classpath while developing

9:06 jonathanj: but consider that it could also be pushed to a maven repo

9:06 jonathanj: do you mean inadvertently?

9:07 justin_smith: no, I mean if you put it in a maven repo then you can use it like you would any other dep

9:07 dnolen: thheller: the threads are created to modify the stack size for Java 6, granted we are on Java 7 I rather not bother with it

9:07 jonathanj: yeah, it did occur to me, i guess i'll aim for that later on

9:09 thheller: @dnolen just never liked the System/exit call, just saw your wiki edit to add it. thought I mention it

9:09 dnolen: thheller: sure but it doesn't matter much and System/exit is fine here

9:10 thheller: dnolen: yeah I guess so

9:31 jonathanj: justin_smith: hmm, so i have :resource-paths ["src/main/resource"] and my .jar in that same directory (relative to project.clj) but (:import) fails with java.lang.ClassNotFoundException

9:32 the failed path matches the package name and class name i'm expecting, is there some way i can debug this? (determine whether the jar is being included, etc.)

9:33 i'm just using `lein run` to run my main (which imports the java class), hopefully that's not the issue

9:33 cnb_: is it possible to use definterface without the class being defined as final ?

9:34 justin_smith: jonathanj: oh, my bad, you need to add the jar itself to the resource-paths

9:34 jonathanj: justin_smith: yay!

9:34 justin_smith: jonathanj: that worked?

9:35 jonathanj: is src/main/resource the convention for resource-paths?

9:35 justin_smith: usually it is just resources/

9:35 jonathanj: justin_smith: yes, that worked

9:35 justin_smith: awesome

9:36 jonathanj: there isn't really a convention for embedding jars, because the "proper" way to do it is create a pom and upload it to a maven repo and use it as a regular dep

9:38 jonathanj: justin_smith: is there some recommended reading regarding uploading jars to maven?

9:39 cnb_: is it possible to use definterface without the class being defined as final ?/

9:39 justin_smith: jonathanj: the mvn command can do this, there are some guides on sonatype too http://central.sonatype.org/pages/producers.html

9:40 cnb_: so you need an interface that isn't final?

9:40 cnb_: yes

9:40 justin_smith: yes

9:41 justin_smith I mean the class than implements the interface using the webservice annotations is being declared as final

9:42 jonathanj: justin_smith: thanks again, you've been a tremendous help!

9:42 justin_smith: cnb_: so you need other interfaces to inherit from it? for normal usage of implementing the interface should be fine

9:42 jonathanj: ,(inc justin_smith)

9:42 clojurebot: #error{:cause "Unable to resolve symbol: justin_smith in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: justin_smith in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: justin_smith in th...

9:42 justin_smith: jonathanj: the , isn't used for karma

9:42 jonathanj: (inc justin_smith)

9:42 lazybot: ⇒ 211

9:43 cnb_: justin_smith this one is being created as final (deftype ^{WebService {:targetNamespace "o.m.g"}} FooService []

9:43 If I look at the .class the class generated is final, I do not want to be final

9:43 justin_smith: OK, than really what you care about is the deftype creating a final class

9:43 *then

9:43 cnb_: yes

9:44 justin_smith: yes, that is the problem

9:44 justin_smith: maybe you need gen-class instead of deftype?

9:45 one moment

9:46 cnb_: this flow chart from cemerick is helpful http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/

9:46 dysfun: hrm, i wonder if marginalia would be better served by inverting the order of functions in the source

9:46 justin_smith: cnb_: notice you are definitely inside the "interop zone"

9:46 dysfun: it seems to me that if you're doing user facing stuff, you'll put the function that has the neat api at the bottom to avoid having to put a (declare) at the top

9:47 justin_smith: cnb_: looks like if an instance of an anonymous type suffices you could get away with reify / proxy

9:48 dysfun: trufax

9:48 cnb_: justin_smith thank you very much

9:49 dysfun: justin_smith: i guess it depends whether you hate your users or not ;)

9:49 justin_smith: cnb_: np, I use that flow chart a lot

9:50 dysfun: at this point my reading of a clojure file usually consists of a quick skim at the top to decide if I should read more from there or (at least 76% of the time) jump straight to the bottom and read from there up

9:50 noncom: are there any good tutorials or examples on clojure.tools.reader?

9:50 dysfun: heh

9:50 do you use marginalia?

9:50 justin_smith: dysfun: some exceptions from the read-from-the-bottom thing - if there is a defmethod or defprotocol encompassing the functionality, that will be at the top, and that is the main thing to know about

9:51 dysfun: I've played with it, I wish it were more flexible

9:51 s/defmethod/defmulti of course

9:51 dysfun: i'm quite fond of it, but obviously i'm going to have to build my own because yaks always need shaving

9:52 jonathanj: returning an OutputStream doesn't seem very clojure-like, is there a better alternative?

9:52 (i'm using a Java library that has InputStream and OutputStream parameters)

9:53 dysfun: justin_smith: tbh i tend to avoid multiple dispatch. i understand it can become a performance bottleneck in heavy throughput use cases

9:54 justin_smith: jonathanj: seems fine to return an OuputStream, it's easy enough to slurp from it or use with-open or whatever

9:55 dysfun: multimethods aren't much slower than fns, and if you do them right protocol functions will be faster than regular fns

9:55 dysfun: i use protocols

9:55 justin_smith: s/protocol functions/protocol methods/

10:00 noncom: how do i get line/column info from the clojure.tools.reader?

10:01 dysfun: if you use read it should supply it

10:01 as metadata

10:02 Bronsa: noncom: use an indexing reader (either indexing-push-back-reader or source-logging-push-back-reader) and line/col info will be attached as metadata to the forms you read

10:04 noncom: http://sprunge.us/jQFL?clj

10:16 noncom: Bronsa: thank you!

10:17 Bronsa: what is the difference between indexing and source-logging?

10:18 Bronsa: noncom: a source-logging reader adds to the form metadata a :source key mapping to a string that represents the original source form, where possible

10:19 noncom: wow, so the metadata contains the source the form was built from? that's nice..

10:19 you said "where possilbe" - what are the cases when this is not possible?

10:20 Bronsa: noncom: http://sprunge.us/aQdB?clj

10:21 noncom: well, when the form read is not an IMeta you can't possibily attach that info as metadata

10:21 jonathanj: are OutputStreams also InputStreams?

10:21 noncom: you mean that #_foo is missing metadata ?

10:22 jonathanj: i'd like to pass the output of one function as the input to another

10:22 justin_smith: jonathanj: no, but a pair can be connected somewhat like a pipe

10:22 Bronsa: noncom: no, #_foo is just a comment

10:22 justin_smith: jonathanj: yeah, I have a project where I do that, one moment

10:22 Bronsa: noncom: I mean that in "#_foo 1", there's no way to preserve the #_foo comment

10:22 noncom: got it

10:22 Bronsa: while in "#_foo [1]" it's preserved in the :source info of [1]

10:23 noncom: that is an interesting detail..

10:23 why was it made to be preserved?

10:24 Bronsa: noncom: the more we can preserve of the original source, the better. the source-logging reader is used for source-maps support in cljs

10:24 dysfun: yes, i thought that form was supposed to 'guarantee' complete removal

10:25 i realise it's just a source map, but hrm.

10:26 noncom: well, source map is used for cueues... obviously cueuing is better with most things preserved..

10:26 i guess..

10:29 justin_smith: ,(let [bytes (java.io.ByteArrayOutputStream.) _ (.write bytes (.getBytes "hello")) in (java.io.ByteArrayInputStream. (.toByteArray bytes))] (slurp in))

10:29 clojurebot: "hello"

10:29 justin_smith: jonathanj: ^

10:30 jonathanj: I think it is also possible without doing the toByteArray method call so that you get a proper pipe style setup

10:32 jonathanj: with a bit of research, it looks like a circular buffer is a nice way to do that

10:32 noncom: Bronsa: what is the recommended way to read a source file of clojure with tools.reader? i assume that the source file contains many clojure forms, but readers read only the first one. ofcourse i know how to make it work manually, but probably there is an existing facility for that?

10:33 jonathanj: justin_smith: i see there's also Piped{Input,Output}Stream

10:34 justin_smith: jonathanj: yes, but you should not use both in the same thread

10:34 Bronsa: noncom: no, readers don't read only the first one http://sprunge.us/fFOE?clj

10:35 noncom: ah, so they keep note of the progress...

10:35 until we hit EOF i guess..

10:35 Bronsa: yes

10:35 noncom: cool :)

10:35 myguidingstar: anyone please help explain why this core.async code doesn't print out anything? https://gist.github.com/af9128f7c9a092d7f87c

10:35 justin_smith: noncom: yeah, readers are stateful, you can even bookmark, rewind or fastforward (not that you would want to for something like this)

10:35 Bronsa: noncom: so you can either read the whole file in a string and use that or you can pass an InputStream to an input-stream-push-back-reader

10:36 noncom: that's really cool. i keep being fascinated by all this clojuric stuff and things you do, guys!

10:37 Bronsa: note that the input-stream reader is not an indexing reader so if you want to use it and get source info you'll have to compose it with an indexing reader, e.g. (indexing-push-back-reader (input-stream-push-back-reader my-input-stream))

10:38 dnolen: myguidingstar: that code is going to stall on (>! ch j)

10:39 myguidingstar: thanks dnolen

10:41 dnolen, what's your advice for a minimal additional code to make it work?

10:43 dnolen: myguidingstar: stop reading and writing to ch in the same loop

10:44 myguidingstar: okay

10:46 noncom: what is the best way to know my reader has nothing else to read? catching an EOF does not seem to be the best way around this..

10:50 stuartsierra: noncom: `read` takes extra arguments to specify an EOF value.

10:51 noncom: really.. just have to first read the docs and the source i guess :)

11:11 tbaldrid_: myguidingstar: you have a race condition in that code. It's quite possible for the middle go to write a value to ch and then read it right back in again

11:11 actually that will always happen, I have no clue what that code is supposed to do,

11:12 myguidingstar: tbaldrid_, that's what I intended to do

11:13 actually it was a simplified version of my other real code

11:15 ambrosebs: dysfun: woah woah. I said people think type *hints* are documentation. They say almost nothing.

11:15 type annotations are documentation.

11:18 dysfun: hehe. i disagree :)

11:18 i don't disagree they're useful, i just think from a documentation pov, docstrings are more useful

11:19 sadly not seeing a lot of that in scala

11:23 Glenjamin: type annotations are useful but not always sufficient, perhaps?

11:29 dysfun: yes

11:29 i'd go with 'almost always insufficient' actually

11:30 ambrosebs: dysfun: erm doc + type is way better than just doc

11:30 especially when talking about clojure.core

11:30 I never said type is sufficient

11:31 dysfun: *shrug* i don't mind reading a textual description. "Args: [foo bar]. foo is a map, bar is a value to look up in the map"

11:31 Glenjamin: that's a type annotation

11:31 just an unchecked one :p

11:31 dysfun: heh

11:31 an imprecise one perhaps

11:32 however, you have the freedom to divert from the specific to the more easily understandable

11:33 i like type systems, but i'm not convinced that it should be automatically what shows in the documentation

11:34 ambrosebs: dysfun: here is my perfect documentation http://crossclj.info/fun/clojure.core/*.html

11:36 a few examples would make that perfect :)

11:36 dysfun: hrm, see i don't like the type signature there

11:36 to me that should read number -> number and note in the docstring that it will perform conversion rules

11:37 otherwise, that's pretty good

11:38 i guess a lot of it is taste

11:38 ambrosebs: I don't know how to put it more precisely than in the type if you want to know more than just "conversion rules"

11:39 dysfun: i guess i'd like to see a simplified type signature. you could click to see a full type signature

11:39 ambrosebs: dysfun: agreed

11:39 dysfun: i get this for free with marginalia and codox because it just prints the signature without types and the text to describe it underneath

11:40 ambrosebs: well you get no type signature right?

11:40 dysfun: indeed. but i find the argument names and a bit of text describing them more helpful

11:41 it's a problem of expression i think. how to express what it does concisely

11:42 i think type signatures an inexpressive way to describe a process

11:42 ambrosebs: well I don't know if argument names help, but prose + examples is definitely helpful

11:43 dysfun: yes, i find argument names much more helpful than type signatures

11:44 ambrosebs: really? sure if you can read the actual source it's all you need.

11:45 dysfun: those type signatures are extremely confusing. what's the * doing in the middle?

11:45 and the union symbol looks too close to a 'u'

11:45 ambrosebs: the * is like a kleene star

11:45 0 or more types

11:46 so the type sig that you might want is [Number * -> Number]

11:46 as in 0 or more numbers

11:47 dysfun: oh i see, it's indicative of arity?

11:47 ambrosebs: yes it says this function can take any number of arguments

11:47 (even if it is implemented with 4 arities)

11:48 so here's my favourite annotation in core.typed http://crossclj.info/doc/org.clojure/clojure/latest/clojure.core.html#_swap%21

11:49 tough to read at first but really captures swap! precisely

11:49 Bronsa: the some-fn one looks scary

11:49 ambrosebs: Bronsa: it's also stupid :)

11:50 Bronsa: any sort of repeating pattern in a type that grows downwards is a TODO :)_

11:50 yea some-fn is a ridiculous annotation

11:50 LOL

11:50 dysfun: ambrosebs: but now i've looked at that i'm struggling to have a clue what it does.

11:51 ambrosebs: dysfun: you're familiar with swap! ?

11:51 dysfun: yes, i use it, but for a moment it was like i didn't.

11:52 ambrosebs: dysfun: so the ... notation allows you to capture a sequence of arguments

11:52 (All [b ...] [b ... b -> [b .... b -> Any]]) just returns a function that takes the same arguments

11:52 there's an example somewhere..

11:53 http://crossclj.info/doc/org.clojure/clojure/latest/clojure.core.html#_memoize

11:53 so memoize takes a function and returns a function with the same interfact

11:53 *interface

11:53 does that make sense?

11:54 Bronsa: ambrosebs: I'm totally ignorant wrt core.typed, is there a reason why some-fn looks that scary while other combinators e.g. partial don't? is it about the "conditional" nature of some-fn?

11:54 dysfun: i understand what it's doing. but it doesn't help that you use mathematical symbols where words would do

11:55 and the b ... b is a very verbose way of saying 'potentially many b'

11:55 how do you for example map alternating repeating groups?

11:56 ambrosebs: eg?

11:56 dysfun: (assoc {} :foo 1 :bar 2)

11:56 ambrosebs: well that works with HMaps

11:56 that's of type '{:foo (Val 1) :bar (Val 2)}

11:56 ah

11:56 sorry

11:57 that is specifically a hack at the moment

11:57 but that's possible

11:57 you need an Assoc type

11:57 and there's a core.typed branch where this is actually implemented

11:57 let me find the type

11:57 dysfun: some days i actually wonder whether haskell got it right banning variable arity

11:58 ambrosebs: https://www.irccloud.com/pastebin/DWEEV49b

11:58 that's the prototype syntax for assoc

11:59 as in it takes a map m, at least 1 key and value pair, then a bunch of c's that must be even in number

11:59 dysfun: okay. so you've correctly annotated that behaviour. you have but one problem: augh my eyes

11:59 ambrosebs: dysfun: I'm open to suggestions

12:00 as I said, it works but isn't merged because I'm unhappy with the syntax

12:00 dysfun: heh, i'll let you know. i've been doing my own mapping of edn data to semantics the last week so i know exactly how hard it is

12:00 clojure is pretty flexible so you have to model in that flexibility, sure.

12:01 ambrosebs: https://www.irccloud.com/pastebin/xTWjWznc

12:01 that's one idea I had

12:02 dysfun: hrm. it's a lot more concise for sure

12:03 ambrosebs: anyway the thing I like about swap! annotation is the b ... b for the second argument must agree with the b ... b you use after the function

12:03 note that b * would be less accurate since that's a kleene star. b ...b expands to something like `Number Boolean Foo`

12:03 dysfun: yes. this is one of the things scala struggles with a little

12:03 obviously it doesn't have variable arity

12:04 ambrosebs: does scala support rest parameters?

12:05 I assumed it did

12:05 or is it the variable arity polymorphism (ie. the dots) that it doesn't support?

12:06 justin_smith: ambrosebs: http://stackoverflow.com/a/1008836/2258453 this looks like a yes

12:07 ambrosebs: oh heh it uses the * syntax

12:07 dysfun: oh, i stand corrected

12:07 * justin_smith polishes his "best googler" trophy.

12:08 ambrosebs: justin_smith: gold star!

12:08 I'm guessing it's just an array like java varargs

12:09 justin_smith: my hunch was that it would support varargs, because it attempts to be an ungodly union of java and haskell to every last detail

12:09 right

12:09 (union in the conjugal and mathematical senses here)

12:09 jonathanj: uh, i might be stupid but why does (.write System/out (.getBytes "arst")) actually produce anything on stdout from the repl?

12:10 justin_smith: jonathanj: it does in mine, but won't in cider

12:10 ambrosebs: Bronsa: even partial is a big hack. Real annotation should (somehow) be: (All [r a ... b ...] [[a ... a b ... b -> r] a ... a -> [b ... b -> r]])

12:10 justin_smith: jonathanj: probably won't in fireplace.vim either

12:10 ambrosebs: you can see the first few cases of a ... a are manually added then we give up

12:10 jonathanj: i'm just running `lein repl`

12:11 justin_smith: then yes, that should print

12:11 ambrosebs: it's not obvious how to work with two dots next to each other

12:11 jonathanj: weird

12:11 justin_smith: jonathanj: try adding a \n to that string

12:11 because newline buffering is the default iirc

12:13 jonathanj: is (.write an-output-stream array_of_byte) the correct thing to do?

12:13 ambrosebs: Bronsa: the reason some-fn is so utterly ridiculous is that 1) it has the same problem as partial in that there is a repeating pattern with no way to abstract over them 2) ((some-fn number? symbol?) a) has to know what's true if it returns true or false

12:13 jonathanj: spit writes something like [B@6dd57b86 to stdout

12:13 ambrosebs: that involves digging into the type of number? and symbol? for some inner information

12:13 which is currently disgusting to do

12:13 justin_smith: jonathanj: that's the toString of the array...

12:14 because spit expects a string

12:14 you could also use (spit (String. array_of_byte))

12:14 ,(String. (.getBytes "hello"))

12:14 clojurebot: "hello"

12:15 hiredman: jonathanj: you likely need to flush after you write, or write a new line (many buffered streams flush on new line)

12:28 dreampilot: Hello everyone, can anyone point me to some examples or tutorials of how to call clojure code from java?

12:29 mpenet``: ,(== (hash ["a"]) (hash (java.util.ArrayList. ["a"])))

12:29 clojurebot: false

12:29 mpenet``: and hours where lost on this one again :|

12:29 justin_smith: mpenet``: value based hashes don't make much sense for mutable objects

12:29 mpenet``: were*

12:30 justin_smith: just like you wouldn't want value based identity for mutable objects

12:30 mpenet``: well I am not sure I'd agree, at least in this case

12:31 muraiki: dreampilot: http://www.braveclojure.com/java/

12:31 justin_smith: mpenet``: consider what happens if you used it as a key in a hash-map

12:31 mpenet``: in theory yes, but you encouter issues because of it all the time in the wild

12:31 exactly

12:31 justin_smith: if you want value based hash, use an immutable type?

12:32 mpenet``: not my choice, it's a db driver that returns nested DS with arraylists in that case

12:32 yes, I can walk them and convert all the values to ensure proper hash equality, but it's not free

12:33 ,(= ["a"] (java.util.ArrayList. ["a"]))

12:33 clojurebot: true

12:35 mpenet``: for some background on it: http://dev.clojure.org/jira/browse/CLJ-1372?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=38184#comment-38184

12:36 justin_smith: dreampilot: I'm not sure if this is still the best way, but it will work http://clojure.github.io/clojure/javadoc/clojure/java/api/package-summary.html#package_description

12:40 andyf: justin_smith: Regarding mpenet's issue, your argument about mixing mutable and immutable would be stronger if Clojure did not treat them as =, but it does.

12:42 justin_smith: andyf: yeah, that's a contradiction, but I think the answer lies in not treating mutables as equal to immutable, rather than using a value based hash-code for mutable objects

12:42 ,(= (java.util.ArrayList. ["a"]) ["a"])

12:42 clojurebot: true

12:42 andyf: Unfortunately changing = that way would be breaking change for some code out there, almost certainly

12:43 justin_smith: that's true

12:43 we could join php in having an ever unfolding variety of equality comparators

12:56 bbloom: ambrosebs: type signatures are only documentation until you get up the haskell's lens package

12:56 then you need fake/simplified type signatures to document your type signatures :-P

12:56 ambrosebs: bbloom: truth

12:56 love the scala fake map annotation

12:57 or9ob: is there a way to clear/reset a ns in cider?

12:57 ambrosebs: I should get in the business of fake annotations

12:57 or9ob: My tests refer all fns from the ns under test and I have renamed things in there - but cider still complains about the old name

12:59 justin_smith: or9ob: you can manually destroy the ns with remove-ns, or use something like clojure.tools.namespace/refresh

13:00 or9ob: ah, thanks justin_smith

13:00 justin_smith: (doto 'my.ns remove-ns require) perhaps

13:01 or9ob: this may leave other namespaces that used / required that ns in a weird state though

13:02 muraiki: has anyone here used jclouds with clojure? I'm considering using it but haven't found much in terms of experiences

13:02 I'd be using it with openstack in particular

13:07 Bronsa: yay. http://dev.clojure.org/jira/browse/CLJ-1232 pulled into 1.7

13:08 justin_smith: cool

13:13 stuartsierra: Just 'remove-ns' doesn't tell `require` that the namespace hasn't been loaded, so you have to force reloading.

13:13 justin_smith: stuartsierra: oh, thanks

13:13 stuartsierra: tools.namespace hacks into the internal machinery of `require` to make this work.

13:13 justin_smith: (inc stuartsierra)

13:13 lazybot: ⇒ 19

13:13 ajmagnifico: Let's say I have a vector xs with 1,000,000 values in it. Let's say I have another vector indices with about 500,000 0-based index values in it. I want to select indices from xs. What would be the most efficient way to do that?

13:15 justin_smith: ajmagnifico: the first thing I would try is to map or mapv the vector over the indexes. Though a reduce may perform better.

13:15 ,(mapv [:a :b :c :d :e] [1 2 3 2 1 0])

13:15 clojurebot: [:b :c :d :c :b ...]

13:16 justin_smith: ,(reduce #(conj % (get [:a :b :c :d :e] %2)) [] [1 2 3 2 1 0])

13:16 clojurebot: [:b :c :d :c :b ...]

13:18 sm0ke: hello i am seeing a lot of `async-dispatch-...` threads in waiting state when using core.async

13:19 Anyone else faced this?

13:19 justin_smith: sm0ke: what are they waiting on?

13:20 sm0ke: the dump says waiting on condition [0x00...]

13:20 is it intelligible?

13:21 OldTree: Does the :source-paths option of Leiningen allow namespaces within a directory structure like src/clj/project_name/file1.clj to have ns names like project-name.file1? I ask because I am adding Clojurescript to this project and I changed the directory structure without changing the namespace names.

13:21 justin_smith: if they were waiting on a read or a lock, that would be an issue with your code. Waiting on a condition should be the normal thing in core.async right?

13:21 sm0ke: hurmm i dont know, i have a lot of problem with core.async and threads in general

13:22 eli-se: hi

13:22 sm0ke: one of my production system is bleeding threads profusely

13:22 justin_smith: sm0ke: well, core.async go blocks use a pool where they get reused...

13:22 sm0ke: are you using thread / Thread. extensively?

13:22 sm0ke: justin_smith: well the thread pool is famous numcores*2+42

13:23 but i am getting 12k threads

13:23 justin_smith: right, but it's not a leak if it's a constant amount

13:23 or am I grabbing the wrong part of what you are saying here?

13:23 ajmagnifico: justin_smith: Brilliant. (map xs indices) is blazing fast compared to the junk I was writing. I had forgotten that vectors can be used as functions. Thanks!

13:23 (inc justin_smith)

13:23 lazybot: ⇒ 212

13:24 justin_smith: ajmagnifico: remember to compare it in a situation where the lazyness is forced of course :)

13:24 sm0ke: i am thinkng of giving aleph a try instead

13:24 ajmagnifico: will do, justin_smith, thanks

13:25 justin_smith: sm0ke: so aleph with manifold for the async dispatch?

13:25 jonathanj: can i access a private static inner class from clojure?

13:25 sm0ke: dont know much about the jargon here, mainfold?

13:25 justin_smith: jonathanj: via reflection, sure. But it's not guaranteed not to break things when you do stuff like that :)

13:26 sm0ke: manifold is what aleph does for async dispatch, so it's something you can actually compare to core.async

13:26 aleph itself is more comparable to ring-jetty-adaptor or http-kit

13:26 sm0ke: ah i see

13:27 justin_smith: s/does/uses

13:27 sm0ke: justin_smith: did you had a good experience wth core.async?

13:27 Guest8609: I've seen some comments that middleware is often not a good idea and I'd like to read something about it, anyone a recommendation?

13:28 justin_smith: sm0ke: yes, but I've only used it in production a couple of times

13:28 sm0ke: i find it very compelling to use but in reality it causes a lots of problems

13:28 justin_smith: Guest8609: what kind of middleware? what's the context here?

13:29 Guest8609: justin_smith: I guess what I saw was in the context of http handlers but I didn't have a specific area in mind

13:30 justin_smith: Guest8609: I have yet to see a clojure project that doesn't use middleware with http handlers, what was the argument against middleware?

13:30 that is, if they use http handlers, middleware gets used in every case I remember seeing

13:30 jonathanj: if i need to extend a java class and be able to call super, what are my options?

13:31 i read that chart linked earlier but it doesn't seem to really account for this

13:31 justin_smith: jonathanj: proxy + proxy-super

13:31 jonathanj: oh cool

13:32 Guest8609: justin_smith: I don't exactly remember, which is partly why I'm asking

13:33 justin_smith: I equally see middleware being used everywhere so the position seemed unpopular, got me curious

13:35 justin_smith: Guest8609: without any of the arguments or context I don't really have much I can say about it? I mean I guess the biggest problem would be you would have to implement all the middleware features by hand, and use them explicitly in each endpoint, and that just seems silly

13:39 cnb_: could I use annotations in a gen-class method parameter ?

13:39 Guest8609: justin_smith: yeah nevermind then, thought someone might have seen the same thing or something

13:52 Glenjamin: https://twitter.com/fogus/status/575712574815125504

13:53 justin_smith: ahh, that's likely the one

13:53 cnb_: I need to generate a coded deftype using gen-class but as my deftype uses annotations I do not know how to implement them using gen-class

14:03 jonathanj: i don't know if i'm going crazy but this error makes no sense to me:

14:03 Caused by: java.lang.ClassNotFoundException: org.apache.fop.apps.FopFactoryBuilder

14:03 https://github.com/apache/fop/blob/fop-1_1/src/java/org/apache/fop/apps/FopFactoryBuilder.java

14:03 fop is a dependency in my project.clj and i can import other classes in that package

14:06 hiredman: jonathanj: just because you can see it on github that doesn't mean the version you are using has it

14:06 jonathanj: how can i actually verify that my dependency has it?

14:07 hiredman: find the source code for the version you have specified

14:07 (or open the jar and look)

14:07 jonathanj: where do i get the jar from?

14:07 hiredman: what version are you depending on?

14:08 jonathanj: [org.apache.xmlgraphics/fop "1.1"]

14:08 i was wondering if there was some way to have lein fetch the jar for me and put it somewhere i can look at it

14:09 hiredman: do you have the whole tracktrace? how are you trying to use it? how do you know you have imported other classes from that package?

14:10 hellofunk: is there any reason to prefer one of these idioms over the other: (into [] (for [x (range 10)] x)) vs. (vec (for [x (range 10)] x))

14:10 jonathanj: yes, i have the whole traceback but it's mostly pottering around clojure's internals

14:11 hiredman: i imported something else from a repl

14:11 => (import '[org.apache.fop.apps FOUserAgent])

14:11 org.apache.fop.apps.FOUserAgent

14:11 amalloy: jonathanj: if someone asks you for a full stacktrace, "i have it but i won't give it to you" is the wrong answer

14:11 it may be useless ot *you*, but hiredman knows a lot about clojure's internals

14:12 jonathanj: http://hastebin.com/omucubiyij.txt

14:12 amalloy: (i suspect this particular one won't be very illuminating, but i would be interested to see what hiredman expects to get from it)

14:12 jonathanj: i didn't say i wouldn't give it to anyone

14:13 i just didn't think anyone would find it particularly useful

14:13 amalloy: jonathanj: i'm with hiredman: whatever version of the library you're getting doesn't have this class in it

14:13 hiredman: jonathanj: what happens when you do the same import in the repl for FopFactoryBuilder?

14:14 jonathanj: hiredman: pretty much what you'd expect:

14:14 => (import '[org.apache.fop.apps FopFactoryBuilder])

14:14 ClassNotFoundException org.apache.fop.apps.FopFactoryBuilder java.net.URLClassLoader$1.run (URLClassLoader.java:366)

14:15 justin_smith: that's not a stack trace

14:15 amalloy: justin_smith: nah, but we already got a stacktrace

14:15 justin_smith: oh, never mind :)

14:15 hiredman: so lein, like maven, fetches jars and stashes them in ~/.m2

14:16 `lein classpath` will actually should you the jars

14:16 you might try `lein deps :tree` just to see if you are getting the wrong version of the library for some reason

14:17 jonathanj: so indeed, the jar doesn't seem to include a .class file for that class

14:22 it looks like whatever is on maven is the thing tagged as fop-1_1old in git and fop-1_1 is some thing that apparently never made it to maven

14:22 terrific

14:23 hiredman: sounds like an apache project

14:26 djames: Any favorite hosted services for private Maven repos?

14:29 This page doesn't list hosted options: http://maven.apache.org/repository-management.html

14:30 sdegutis: What seq-based function would you use to split "foo bar quux" into ["foo", "bar", "quux"]?

14:32 justin_smith: I wouldn't use a seq-based function, because that is a string. clojure.string/split

14:32 Bronsa: sdegutis: why seq-based? that's what clojure.string/split is for

14:32 sdegutis: I'm trying to practice writing a recursive function that would do it.

14:32 But I don't know how the algorithm should wokr.

14:32 Bronsa: ,(clojure.string/split "foo bar quux" #"\s+")

14:32 postpunkjustin: I guess you could use reduce?

14:32 clojurebot: ["foo" "bar" "quux"]

14:32 postpunkjustin: If that's really what you want

14:33 sdegutis: So I'm looking into what function would typically do this so I can see how it's implemented.

14:33 I thought maybe it's group-by or partition or something, but no.

14:33 Closest is partition-by.

14:33 postpunkjustin: Oh yeah, maybe partition-by (complement clojure.string/blank?)

14:34 Not 100% sure

14:34 sdegutis: But partition-by leaves the ' ' inthere.

14:34 postpunkjustin: just filter it after?

14:34 This is a super weird way to do it

14:34 sdegutis: ,(partition-by #(= % \space) "foo bar quux")

14:34 clojurebot: ((\f \o \o) (\space) (\b \a \r) (\space \space \space) (\q \u \u \x))

14:35 sdegutis: Isn't there a pretty recursive algorithm to do this

14:40 justin_smith: the recursive version is ugly

14:40 ,(loop [s "foo bar baz" part "" strs []] (if (empty? s) (conj strs part) (if (= (first s) \space) (recur (subs s 1) "" (if (empty? part) strs (conj strs part))) (recur (subs s 1) (str part (first s)) strs))))

14:40 clojurebot: ["foo" "bar" "baz"]

14:49 turbofail: (defn split-by [pred s] (if (empty? s) s (cons (take-while (complement pred) s) (split-by pred (rest (drop-while (complement pred) s))))))

14:52 ToBeReplaced: any way to check if getting the next item of a seq would block?

14:53 turbofail: no. you can check if a value is available for a lazy seq, which will tell you that it for sure won't block

14:54 ToBeReplaced: turbofail: how? that's exactly what i want to do

14:54 turbofail: use "realized?"

14:56 ToBeReplaced: okay, wasn't what i was looking for, that's okay; makes sense that you can't do what I want, just figured i'd ask in case i missed an obvious pattern

14:56 justin_smith: ,(realized? (range))

14:56 clojurebot: false

14:56 justin_smith: ,(realized? (doall (range 10)))

14:56 clojurebot: true

14:57 paulswilliamsesq: Whoop, big win today on my introducing Clojure to where I work. Paired on a simple refactoring with a really well respected maths grad today, and he started raving about how easy Clojure is to understand and change.

14:57 justin_smith: nice!

14:57 arrdem: good goooooood

14:57 ToBeReplaced: i can always just put the seq to a channel, since that's really what I'm doing, and then take with a timeout

14:57 turbofail: huh. did you use a structural editor?

14:57 i don't feel like it's all that easy to change without it

14:59 ambrosebs: paulswilliamsesq: congrats

15:00 jonathanj: hrm, is there any reason that (.write (output-stream ...) bytes) would be different to (.write System/out bytes)?

15:00 paulswilliamsesq: ambrosebs cheers, I get frustrated by my slow progress in learning Clojure due to less frequent than I'd like exposure.

15:01 justin_smith: jonathanj: well, it's a PrintStream, dunno how much difference that makes

15:01 paulswilliamsesq: ambrosebs Jay Field's talk at QCon London a couple of weeks earlier helped too :-)

15:01 justin_smith: jonathanj: the class heirarchy is OutputStream -> FilterOutputStream -> PrintStream

15:02 jonathanj: hrm

15:03 justin_smith: $javadoc java.io.PrintStream

15:03 lazybot: http://docs.oracle.com/javase/6/docs/api/java/io/PrintStream.html

15:03 justin_smith: jonathanj: the docs indicate that PrintStream adds things like auto-flushing that OutputStream does not have

15:05 jonathanj: if i render this PDF and write it to System/out (and redirect it to a file in my shell) i get this weirdly broken PDF (it's totally blank but it has pages defined)

15:05 if i write it to a file from clojure then it's fine

15:06 justin_smith: odd

15:06 jonathanj: very

15:08 arrdem: justin_smith: ping

15:08 justin_smith: yello

15:08 dysfun: Bronsa: which reader do i want to create to read edn from a file recording the line numbers?

15:10 Bronsa: dysfun: an indexing-push-back-reader

15:11 arrdem: Thinking about Grimoire editing.. current plan is that each "artifact" (documented Maven artifact) will somehow indicate where it's sourced from and if the where is github I can generate fork and pr links to edit content.

15:11 dysfun: Bronsa: thanks

15:12 arrdem: comments/complaints welcome I'm stressing over how to make the "edit link" thing extensible although fundamentally it may not be.

15:13 I guess it just isn't because examples and notes are fundamentally Grimoire's data not docs which could be vendored.

15:13 justin_smith: arrdem: I guess you could have the app create pull requests, and the config would indicate which repo to make them on? But it may be easier to create a queue of proposed changes in a db.

15:14 a wiki model might make more sense than a source control model

15:14 arrdem: meh..

15:14 a wiki may make more sense but I don't want to join Raynes in dealing with auth and spammers.

15:15 justin_smith: makes sense

15:15 arrdem: GH gives me auth at the cost of a longer workflow.

15:15 justin_smith: arrdem: you can make it create refheap pastes out of submissions, and track the URLs heh

15:15 arrdem: lol that'd be nice..

15:16 jonathanj: hrm, i think the problem here is that my bytes are being encoded to UTF-8 or something

15:16 justin_smith: arrdem: ahh, so someone would use their own github account to push button create a pr for the doc update?

15:16 arrdem: justin_smith: bingo.

15:16 same as I was doing back ~Grim 2.x

15:16 jonathanj: is it possible to just write plain bytes to stdout?

15:19 justin_smith: jonathanj: if this were c, the normal thing would be to reopen stdout with different parameters (raw vs. cooked mode, buffering, etc.)

15:20 I don't know if there is a java equivalent of this actually

15:22 jonathanj: output written directly to a file: https://pb.codehash.net/444fdc3368a042b2a6d8dddb321f195c

15:22 output redirected to a file: https://pb.codehash.net/d517012d69854973b2a13c9a6e133dbe

15:22 it's kind of bizarre, i've never actually seen this before

15:24 someone just pointed this out:

15:24 >>> name('efbfbd'.decode('hex').decode('utf8'))

15:24 'REPLACEMENT CHARACTER'

15:24 so it's definitely some kind of encoding trainwreck but i have no idea what's introducing it

15:24 justin_smith: jonathanj: it could be that the jvm thinks your stdout cannot accept those characters

15:25 but you'd think it would notice a file redirect and handle that differently...

15:25 jonathanj: how do i get the JVM to mind its own business?

15:30 amalloy: jonathanj: write bytes instead of characters, probably

15:31 jonathanj: i'm pretty sure i am writing bytes

15:31 amalloy: this behavior makes me think you have a bytestream you want to write, and you're converting it to a string as if via (String. the-bytes) and then writing that

15:32 jonathanj: what does the writing code for your "directly to file" look like vs "written to stdout"?

15:33 jonathanj: amalloy: well, i'm just giving an OutputStream to Flying Saucer's ITextRenderer.createPDF method

15:33 so the difference is whether i pass System/out or whether i pass (output-stream "xxx.pdf")

15:34 i guess i could use a ByteArrayOutputStream and write the bytes to System/out to see if it makes a difference

15:34 amalloy: jonathanj: System/out is a PrintStream, though

15:35 which has a write(byte[]) method, which should work, but it's possible this createPDF thing has an overload for PrintStreams that does something dumb

15:35 eg, i expect if you passed (PrintStream. (output-stream "xxx.pdf")), you would get similarly broken behavior

15:37 jonathanj: hrm

15:37 https://pb.codehash.net/34e68111fa894f049b8c249e6e1645fa

15:37 this still produces the weird output

15:47 sigh

15:48 so if i write (.toByteArray byte-array-stream) to (output-stream "xx.pdf") and to System/out (via the write method) then i get two results

15:48 xx.pdf is intact and whatever was redirected is broken

15:49 amalloy: beats me, jonathanj. i don't think that's supposed to happen. if i try writing a byte-array with invalid utf-8 in it to System/out, i seem to get those bytes appearing as expected

15:54 eg, if i take some bytes from your "good" output, and write them to stdout via a simple program containing only (.write System/out (byte-array (map unchecked-byte [0xe2 0xe3 0xcf 0xd3]))), then my stdout contains those four bytes unmolested

15:55 perhaps your shell is mangling them? try running this program and see what output you get: https://www.refheap.com/92f7edb8dcc2542cb3f659492

15:56 jonathanj: a bunch of replacement characetrs

15:56 amalloy: okay, so in lieu of further evidence i am blaming your shell

15:56 clojurebot: Excuse me?

15:56 justin_smith: termcap?

15:56 amalloy: clojurebot: in lieu of further evidence i am |blaming| your shell

15:56 clojurebot: Alles klar

16:01 jonathanj: jonathan@Callisto ~/Coding/documint> python -c 'import sys; sys.stdout.write("\xe2\xe3\xcf\xd3")' | xxd

16:01 0000000: e2e3 cfd3 ....

16:06 Frozenlock: ah! I just discovered dash.el to bring many clojure goodies into emacs.

16:06 (for the curious https://github.com/magnars/dash.el)

16:11 jonathanj: amalloy: this also outputs the original bytes unadulterated: https://pb.codehash.net/9c58bb20462c4e3cbea445a4b7b53ee7

16:15 amalloy: wait, how are you running your code? lein repl?

16:15 jonathanj: `lein run`

16:17 java -jar /Users/jonathan/.m2/repository/org/clojure/clojure/1.6.0/clojure-1.6.0.jar -e '(.write System/out (byte-array (map unchecked-byte [0xe2 0xe3 0xcf 0xd3])))' | xxd

16:17 0000000: e2e3 cfd3 ....

16:18 amalloy: so taht version works fine, and lein run doesn't. what about lein trampoline run?

16:20 jonathanj: yeah, that works

16:21 amalloy: jonathanj: look for related issues in the leiningen repo, and if you can't find one i'd file a new bug

16:21 well, i guess try updating to latest lein first

16:22 jonathanj: Leiningen 2.5.1 on Java 1.7.0_45 Java HotSpot(TM) 64-Bit Server VM

16:23 i'm not sure how to determine the newest version, but i see the master project.clj is 2.5.2-SNAPSHOT

16:29 justin_smith: jonathanj: if java -jar works properly, that should at least be enough for the pragmatics - lein is better as a build tool rather than a launcher. Still good to track down the root of the issue of course

16:37 * akkad ponders if there are any tools to help make sense of a hung jvm stacktrace from jstack

16:38 justin_smith: akkad: what I typically do is look for anything "suspicious" or unusual in the stack traces, and check the process CPU usage and the results of multiple jstack calls to see if something is in a tight loop

16:38 akkad: what are the symptoms? just the process sitting there not exiting, or are you also not seeing output you would expect?

16:39 akkad: stops responding to http requests

16:39 justin_smith: akkad: as in connection refused, or timing out with no response?

16:47 dysfun: hrm. lein can't find my gpg key for some reason. any ideas?

16:48 i get this error https://www.refheap.com/98522

16:53 akkad: justin_smith nginx timesout

16:53 talking to clojure backend

16:54 crash_ep: does Clojure support heredocs or any form of string literal that doesn't require escaping quote individual quote characters?

16:56 jonathanj: justin_smith: yeah, unfortunately `java -jar` is kind of an inconvenient way to run my app while i'm developing it

16:57 justin_smith, amalloy: thank you for your help and patience, i filed a bug with lein

16:57 (for reference, <https://github.com/technomancy/leiningen/issues/1857>)

16:58 justin_smith: jonathanj: a workaround: lein cp > class_path; java -cp $(cat class_path) clojure.main -m my.ns

16:59 if you don't change your project.clj, you don't even need to run lein cp next time

16:59 though of course, having lein fixed would be better

17:01 amalloy: justin_smith: java -cp `lein classpath` ...

17:01 but really, lein trampoline run is better than that

17:02 justin_smith: amalloy: I suggested my version because you can skip lein the second time

17:02 amalloy: especially with LEIN_FAST_TRAMPOLINE=yes_please

17:02 justin_smith: and because $() is provably superior to ``

17:02 amalloy: justin_smith: LEIN_FAST_TRAMPOLINE actually skips lein the second time too, and is better at remembering whether you've changed project.clj than you are

17:03 justin_smith: amalloy: fair point on that one

17:07 expez: What does it mean when (println my-map) prints #<PersistentArrayMap {:foo "bar"}> instead of {:foo "bar"}?

17:08 snowstalker: expez: it means it's a small map, it shouldn't affect your usage of it though

17:08 hiredman: it means someone has been mucking with your print methods, or you are running multiple clojure runtimes

17:08 expez: snowstalker: to get "bar" I can't do (:foo my-map) or (get my-map :foo), but (-> my-map first second) works fine

17:08 snowstalker: expez: oh, see what hiredman said

17:09 hiredman: multiple clojure runtimes, which, how you could do that accidentally I have no idea

17:09 expez: hiredman: the latter is true, the code runs inside classlojure

17:09 hiredman: yeah

17:10 expez: hiredman: how did you know, what does #<..> mean?

17:10 hiredman: it is how unknown objects are printed

17:10 Bronsa: were* :P

17:10 hiredman: sure sure

17:10 Bronsa: speaking of which hiredman clojurebot behaves weirdly in this regard

17:10 hiredman: pams are a known object, so for them to print as known, it means that pam is not the pam of the clojure runtime where println was called

17:11 Bronsa: ,)

17:11 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

17:11 Bronsa: ,(Exception. "")

17:11 clojurebot: #error{:cause "", :via [{:type java.lang.Exception, :message "", :at [sandbox$eval47 invoke "NO_SOURCE_FILE" -1]}], :trace [[sandbox$eval47 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compiler.java" 6784] [clojure.lang.Compiler eval "Compiler.java" 6747] [clojure.core$eval invoke "core.clj" 3078] [clojure.core$eval25$fn__26$fn__36 invoke "NO_SOURCE_FILE" 0] ...]}

17:11 Bronsa: ,(throw (Exception. ""))

17:11 clojurebot: #error{:cause "", :via [{:type java.lang.Exception, :message "", :at [sandbox$eval71 invoke "NO_SOURCE_FILE" -1]}], :trace [[sandbox$eval71 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compiler.java" 6784] [clojure.lang.Compiler eval "Compiler.java" 6747] [clojure.core$eval invoke "core.clj" 3078] [clojure.core$eval49$fn__50$fn__60 invoke "NO_SOURCE_FILE" 0] ...]}

17:11 Bronsa: shouldn't the first one print like the other two?

17:12 expez: hiredman: aha! but why is it affecting the code? The keywords have been namespaced and :foo isn't was it once was?

17:12 hiredman: the first exception is actually happening in a different version of clojure of course

17:12 Bronsa: of course

17:12 hiredman: expez: the Keyword type from the different clojure runtimes is not the same

17:13 expez: hiredman: that makes perfect sense. Thanks a bunch!

17:13 (inc hiredman)

17:13 lazybot: ⇒ 75

17:15 dysfun: ugh. can i test signing a jar without doing a lein deploy?

17:48 justin_smith: dysfun: you could run a repl with the lein deps, and call leiningen.deploy/sign directly

17:48 after loading your project file manually etc.

17:49 with leiningen.core.project/read

18:11 akuttruff: Hello all -- I'm new to Cider and am trying to (println (str request)). Where can I see these?

18:12 nullptr: akuttruff: i believe these typically show up in the repl view (C-c C-z)

18:12 justin_smith: akuttruff: nullptr: if it doesn't show up in the repl window, it will be in the buried *nrepl server* buffer

18:12 or whatever it is called these days

18:13 this happens because the print is happening from a thread that has not inherited your main thread's value of *out*

18:14 akuttruff: see my answer to this question on SO http://stackoverflow.com/questions/26743958/why-cant-i-print-from-background-threads-in-clojure-cider-repl-in-emacs/26744113#26744113

18:14 akuttruff: thank you! I appreciate the help

18:29 patchwork: (inc justin_smith)

18:29 lazybot: ⇒ 213

18:33 {blake}: So, a while back I moved this utility routine (map-function-on-map-values) from my various source namespaces (it was in more than one) to a "utility" namespace.

18:33 This is a web-based app. And when I change the code, it forces me to re-login.

18:34 But sometimes, since I moved this function over, instead of forcing me to login, it just plotzes: Unable to resolve symbol:map-function-on-mapvals in this context.

18:34 I can hit refresh and get past this, but it won't have the new code, it'll be running the old code.

18:36 hiredman: because you are using lein-ring with its bizzaro code reloading

18:36 {blake}: hiredman: Yes, I am. I did not know it was bizarro. But I find that somewhat reassuring, I guess.

18:37 So, this is like a dead parrot thing? "Yes, it'll do that."

18:39 hiredman: I dunno, I don't use it, I sort of took a shot in the dark

18:39 if I want to load/replace/run code I do it via a repl

18:39 not by saving a file and crossing my fingers

18:40 {blake}: Aw, crap, I forgot to cross my fingers.

19:06 freddd: hey, all. i was explaining clojure's immutable data structures to my friend, and he asked me for real-world examples of where they are a benefit. i could only come up with two examples: how you don't have to worry about the data changing if there is some long-running computation that needs to be done, and how perhaps in updating/rendering, if you know the value of the root node, you can simply do cheap pointer equality checks to dete

19:06 can anyone offer some other concrete examples of their benefits?

19:07 amalloy: freddd: you never have to call clone. you can just share pointers to your data freely

19:07 and trust that data someone else gave you won't suddenly evaporate in the middle of working on it

19:08 johnmendonca: freddd: concurrent access, no need to worry about order of mutation by multiple threads

19:08 {blake}: freddd: And you don't need a long-running computation. Pass a collection of objects to any routine and you really don't know what you're going to get back.

19:09 freddd: amalloy: ok. i think that's perhaps a better, more general version of my first example. thanks.

19:09 {blake}: good point!

19:09 ToxicFrog: freddd: you get infinite undo (for editors, etc) basically for free

19:09 nullptr: freddd: i did a presentation on immutability targeted at c#/.net developers which attempts to make a case (may be nsfw depending on your "w") https://docs.google.com/presentation/d/1DlqP8Yil13RMbOc4OA4n-juuYQt5-YuN-YKIwH1H9HE/edit?usp=sharing

19:09 amalloy: freddd: another example: java.lang.String

19:10 try replacing every use of String in your programs with StringBuffer, and see how much harder it makes things for you to be correct

19:10 ToxicFrog: I mean, you have to spend the memory for the history, but structure sharing means that it's cheap and immutability means it doesn't really take any extra work to keep the history intact

19:10 freddd: johnmendonca: yeah, i mentioned that, but he was looking for more concrete. i think substantial threading is not nearly as popular, so he (and i, quite frankly) are not super-familiar with where this would be an obvious win.

19:11 ToxicFrog: yes, very true. i did mention that. thanks!

19:11 nullptr: that's great, as c# is his primary language, though I typically stay away, but will definitely the link.

19:11 ToxicFrog: (and substructure sharing means that doing this is much cheaper than cloning on every edit as you would in something where the state is mutable)

19:12 {blake}: fredd: You could check out Ants. That's kind of a cool short example with lecture by Rich Hickey and everything.

19:13 TEttinger: yeah, I'm going to be rolling my own "atomic updates to a single unified state variable" thing in C# to get infinite undo

19:14 I think knowing how clojure does it may help :)

19:14 freddd: {blake}: I have watched that, but forgot about it. i kept hashing out examples that seemed similar in retrosepct, but would then realize it was atoms/agents that were doing the most benefit, not so much the data structure.

19:14 brehaut: TEttinger: step one: create an F# project...

19:15 TEttinger: I asked in the F# channel and got no response!

19:15 nullptr: TEttinger: ms distributes first class immutable collections these days for all .net langs, so this shouldn't be terribly difficult

19:16 {blake}: freddd: Well, I think the interesting thing about that is that you don't normally use atoms/agents. Most of your functions will be pure. So when it comes time to deal with the state, you give it the appropriate respect.

19:16 TEttinger: nullptr: huh, I hadn't thought of using those. I'm currently making heavy use of C5, which is an expanded set of data structures for C#/CLR

19:16 {blake}: There is a mindset thing going on here.

19:21 brehaut: {blake}, TEttinger: do any of those collections do structural sharing?

19:21 {blake}: brehaut: Which collections? AFAIK, in Clojure, they all do. =P

19:22 brehaut: {blake}: the .net ones. obviously im aware that clojure does

19:22 {blake}: the .net immutable collections specifically

19:23 nullptr: brehaut: yes

19:23 brehaut: nullptr: cool, thaks

19:23 TEttinger: brehaut: that's what I'm implementing, effectively... the idea is to make some sort of way to update a data-holding class by giving it a new state that's partially filled

19:23 {blake}: nullptr, brehaut: Be interesting to see immutable collections that didn't. They'd end up having to clone everything, which presents some interesting problems.

19:24 brehaut: and sorry {blake} i accidentally addresse you instead of nullptr

19:24 {blake}: brehaut: np

20:22 raspasov: hey guys, has anyone here used https://github.com/mcohen01/amazonica ?

20:54 bostonaholic: no, but I have used https://github.com/weavejester/clj-aws-s3 (only for s3)

20:55 I haven't needed everything that amazonica provides, so I stuck with the smaller lib

21:03 raspasov: bostonaholic: thanks for input!

21:33 Morgawr: I have a question, I've been getting my hands on prismatic schema. The prismatic defrecord is nice if I want to have some sanitization/validation of inputs in my functions, however I noticed that it does not allow me to use maps that are supersets of the specified record type

21:34 for example if I declare a record type to have :a :b and :c keys, if I pass a record with {:a X :b Y :c Z :d K} it will be invalid (where X Y Z K are whatever values)

21:34 I can use optional keys if I know what their name is going to be, however I will not know that in advance and all I care about is for the primary keys specified in the original record to be there, is there a way to do that?

21:45 Jabberz: so what's the choice validation library out there today -- formative? bouncer? validateur? red tape?

23:47 bcm: Morgawr: You can do that.

23:48 if you write a schema like (def a-and-anything {:a s/Str, s/Keyword s/Any})

23:48 i think that will work

23:51 looks to work on my box, anyway.

23:51 Now I have a question! I have a curl that is pretty involved. What's the best way to turn it into a function using something like http-kit client or clj-http?

23:52 also, there's some clojure-talk going on now on HN: https://news.ycombinator.com/item?id=9214603

23:52 raspasov: what do you mean by "curl that is pretty involved" ?

Logging service provided by n01se.net