2015-03-16
| 00:30 | bacon198` | question, how do I remove an element from a vector, and return the list with the removed element? |
| 00:30 | bacon198` | ,(def x [1 2 3 4]) |
| 00:30 | clojurebot | #'sandbox/x |
| 00:34 | bacon198` | i'm guessing subvec |
| 00:40 | TEttinger | I'm pretty proud of this clojure name generator, it had some odd reqs http://ideone.com/zwnFAL |
| 00:40 | TEttinger | ,(def x [1 2 3 4]) |
| 00:40 | clojurebot | #'sandbox/x |
| 00:40 | TEttinger | bacon198`, what output do you want? |
| 00:41 | l1x | https://www.irccloud.com/pastebin/m2BK6uxa |
| 00:41 | l1x | does this work for you? |
| 00:41 | l1x | it does not seem to catch ctrl+c or the printing is not happening for some other reason |
| 00:43 | TEttinger | l1x, in the repl ctrl-c would get intercepted by the repl itself |
| 00:43 | l1x | this is not in the repl |
| 00:43 | TEttinger | then maybe the thread being asleep is preventing it from receiving input? |
| 00:47 | l1x | maybe |
| 00:47 | l1x | anyways i investigate it tomorrow |
| 00:48 | l1x | thanks |
| 00: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 ...)))) |
| 00:49 | TEttinger | (inc amalloy) ; l1x, I love having people who are actually good at clojure here |
| 00:49 | lazybot | ⇒ 236 |
| 00:50 | TEttinger | since I am pretty much not |
| 00:50 | l1x | i am a noob |
| 00:50 | TEttinger | that name gen has turned out well though |
| 00:50 | l1x | not even full time software guy :) |
| 00:50 | l1x | but amalloy and justin are great |
| 00:50 | TEttinger | heh |
| 00:51 | TEttinger | I miss technomancy |
| 00:51 | l1x | where is he? |
| 00:51 | TEttinger | doing charity work |
| 00:51 | l1x | ahh |
| 00:51 | l1x | the unsung here is ztellman |
| 00:51 | TEttinger | indeed |
| 00:51 | TEttinger | primitive-math is amazing |
| 00:51 | l1x | his code is terribly good |
| 00:52 | l1x | i am using his library to build our new datapipeline |
| 00:55 | justin_smith | oh, hi |
| 02:50 | egli | l1x: datapipeline? Anything more specific? |
| 04: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 ;) |
| 04:28 | dysfun | hrm, any marginalia users around? |
| 04:28 | dysfun | trying to embed code in the documentation of marginalia doesn't look so good |
| 04:28 | dysfun | it's example code so i don't want it to actually go into the library |
| 04:43 | michaelr` | Does a hashing function exist which takes any value but produces a configurable number of hash values? |
| 04:46 | noidi | dysfun, how about leaving the code in but wrapped in a (comment ...)? |
| 04:47 | dysfun | noidi: i wondered why so many people were doing that |
| 04:47 | dysfun | is it because of marginalia? |
| 04:48 | noidi | I think it's mostly because that way you can use your editor's structural editing support on the example code |
| 04:48 | noidi | paredit or what have you |
| 04:49 | dysfun | ah yes, paredit. one day i might actually make the time to give it a proper go |
| 04:49 | dysfun | so i came up with a hack for making midje tests intermingle-able with real code and stripping them out for uberjar build |
| 04:50 | dysfun | i'm concerned this is going to clog up the marginalia output too |
| 04:51 | noidi | I place something like (comment (gen/sample my-gen)) after each custom test.check generator |
| 04:52 | dysfun | ah, i'm using midje |
| 04: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 |
| 04:52 | noidi | otherwise I'd have to either write that form in the REPL myself every time, or copy and paste it from a textual comment |
| 04:56 | dysfun | *nod* |
| 04:57 | dysfun | https://gist.github.com/jjl/266e4fd88846ab8674f4 |
| 04:57 | dysfun | this is the hack i'm using to make midje autotest work |
| 05:00 | dysfun | if i put those in a comment block, they won't run, obviously |
| 05:01 | dysfun | but since i don't actually use (comment) for any other purpose, perhaps i can just make my hack work on that instead |
| 05:02 | noidi | dysfun, have you seen this? https://github.com/marick/Midje/wiki/Production-mode |
| 05:02 | dysfun | yes. there's no way to actually use it :) |
| 05:03 | dysfun | marick says there'll be something coming soon |
| 05:03 | dysfun | til then i'm left with this awkward hack |
| 05:06 | noidi | ok |
| 05:10 | egli | dysfun: not the answer you want to hear, but I've been quite happy with codox |
| 05:11 | egli | and markdown format |
| 05:13 | dysfun | yeah, but i like marginalia output |
| 05:13 | dysfun | it's pretty |
| 05:13 | dysfun | people like reading pretty documentation that's helpful |
| 05:13 | egli | dysfun: yes, looks matter :-) |
| 05: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 |
| 05:41 | jonathanj | is there a standard or common markup accepted by tools for use in docstrings? |
| 05:43 | dysfun | no. if you choose a documentation generator tool, most of those support structured markup |
| 05:44 | dysfun | i'm quite fond of marginalia |
| 05:45 | dysfun | that embeds markdown |
| 05: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 |
| 05:49 | dysfun | mpenet: sorry, could you explain that please? |
| 05:49 | dysfun | you mean that you'd prefer *not* to see the code? |
| 05:51 | mpenet | yes |
| 05:52 | mpenet | by default at least |
| 05:52 | dysfun | oh that's an interesting idea |
| 05:52 | mpenet | codox is better imho for doc, you get the signature/docstring and a link to the code if necessary |
| 05:52 | mpenet | less noisy |
| 05:52 | mpenet | less scrolling |
| 05:52 | dysfun | i quite like codox output i must say. but i'm very fond of the idea of literate programming |
| 05:53 | dysfun | perhaps codox favours larger libraries and marginalia smaller ones? |
| 05:54 | mpenet | I wouldnt be so sure. unless it's a 10 line single namespace lib |
| 05:54 | dysfun | this is a small library. less than a hundred lines of code |
| 05:54 | mpenet | it's nice to have, but shouldn't be the default doc imo |
| 05:55 | dysfun | well i also like that when you go to your code, the docs are there too |
| 05:55 | dysfun | i wonder if you can just generate both |
| 05:56 | dysfun | off to a great start with codox. i get an obscure error about hiccup |
| 05:58 | egli | dysfun: you should be able to produce both marginalia and codox doc. Just specify different output dirs |
| 05:59 | dysfun | yup. except `lein doc` (codox) throws bizarre hiccup-related errors i'm trying to figure out how to fix |
| 06:01 | dysfun | i give up. any ideas? https://www.refheap.com/98497 |
| 06:01 | dysfun | that's me trying with the last-but-1 version because the latest did the same |
| 06:02 | mpenet | maybe a conflict with a user profile |
| 06:04 | dysfun | well whaddya know? |
| 06:04 | dysfun | clj-ns-browser |
| 06:04 | dysfun | which i haven't been using anyway because it's not very good |
| 06:06 | egli | dysfun: *that* was the problem? |
| 06:06 | dysfun | yes |
| 06:06 | dysfun | it was in my dev dependencies in my profile |
| 06:12 | dysfun | now i have to go fix my tests before i can generate it. heh. |
| 06:16 | dysfun | hrm. a marginalia-alike with live updating would be awesome |
| 06:17 | dysfun | you could change the docstring and go to your browser to see the updated docs |
| 06:17 | dysfun | without having to trigger a rebuild and hit refresh |
| 06: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 |
| 06:23 | dysfun | that sounds like a type error to me |
| 06:23 | zot | i found that doing a (long …) cast within the recurs fixes it, but that seems a strange fix |
| 06:24 | zot | since the thing being cast is the result of (- foo bar), both of which are numeric |
| 06:24 | zot | but i assume autoboxing is transparent, so maybe it's the only way? |
| 06:39 | Glenjamin | ^long might work |
| 06: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? |
| 07:01 | mpenet | anyone knows how to run core.async cljs test suite? |
| 07:01 | mpenet | it doesn't seem to be documented anywhere |
| 07:01 | noncom | dysfun: i did not understand what you're asking.. :) |
| 07: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? |
| 07: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? |
| 07:04 | noncom | and also i think there is no real alternative to clojure.tools.reader |
| 07:04 | dysfun | clojure.tools.reader is not standard, it's a pure clojure reimplementation |
| 07:05 | noncom | oh, i thought it's already inside... |
| 07:06 | dysfun | no. and i specifically want the edn reader |
| 07:06 | dysfun | (the format makes liberal use of lists and symbols which are very pretty in edn but require quoting and such in clojure code |
| 07:21 | noncom | dysfun: hmmm, interesting.. |
| 07:52 | jonathanj | are there documentation tools that aren't centered around literate programming? |
| 07:53 | jonathanj | hrm, when i "lein run" my application on OS X i get a Java dock icon until my code exits |
| 07:54 | jonathanj | 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? |
| 07:55 | dnolen | https://groups.google.com/d/msg/clojurescript/e3gOEUJlkMc/PATUU2JaBl4J |
| 07:55 | dnolen | ClojureScript 0.0-3115 out |
| 08:05 | dysfun | jonathanj: codox isn't |
| 08:05 | dysfun | also if you figure out how to stop the dock icon, i'd love to hear. i get it because i spin up netty |
| 08:11 | justin_smith | dysfun: maybe use a headless jre? |
| 08:12 | noncom | what is the current best option to validate passed function arguments? |
| 08: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 |
| 08:13 | justin_smith | noncom: I like prismatic/schema for that, but there is also :pre conditions |
| 08:15 | dysfun | reminds me of old-fashioned assert() |
| 08:17 | jonathanj | justin_smith: any suggestions to get rid of that? |
| 08:19 | jonathanj | hrm, how would i do the equivalent of `java -Dfoo=bar` from Clojure? |
| 08:19 | dysfun | what do you mean? how do you get access to the definitions? or how do you set them in-process? |
| 08:20 | dysfun | the latter cannot be done but you can work around it by agreeing to only use a wrapper |
| 08:20 | jonathanj | hrm |
| 08:20 | jonathanj | i was reading http://www.oracle.com/technetwork/articles/javase/headless-136834.html |
| 08:20 | noncom | in schema how can i say OR inside a type template? |
| 08:20 | dysfun | the former, you do the java way, with clojure syntax |
| 08:21 | noncom | like a value can be either [] or nil or keyword |
| 08:21 | jonathanj | i'd like to just try -Djava.awt.headless=true as a quick once-off |
| 08:21 | jonathanj | but it claims i can use System.setProperty to do the same thing, but apparently that code is broken |
| 08:21 | jonathanj | oh, hrm |
| 08:21 | jonathanj | that's a static method |
| 08:21 | dysfun | how are you launching clojure? like 'lein repl' ? |
| 08:22 | jonathanj | dysfun: i'm just using `lein run` at the moment |
| 08:22 | dysfun | ah right. well System/setProperty should work |
| 08: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) |
| 08:22 | jonathanj | sorry, i was an idiot and did (.setProperty System ...) initially |
| 08:23 | dysfun | heh, i do that often |
| 08:24 | justin_smith | jonathanj: I do "env _JAVA_OPTIONS=-DFOO=bar lein ..." |
| 08:26 | justin_smith | jonathanj: but you can also do :jvm-opts ["-Djava.awt.headless=true" ...] |
| 08:26 | jonathanj | ah, thanks, that would have been useful to at least try this out |
| 08:26 | justin_smith | (in project.clj) |
| 08:27 | justin_smith | 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 |
| 08:29 | jonathanj | how do i manually include a java project in my clojure project? |
| 08:30 | jonathanj | so either i have the original Java source or at least a jar, but it's not available on any kind of central repository |
| 08: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 |
| 08:33 | justin_smith | otherwise you can put it in your repo on the classpath |
| 08:34 | justin_smith | (or java-source-path, of course, if you want lein to compile it...) |
| 08:37 | jonathanj | justin_smith: it's not my code, the author is just kind of AWOL |
| 08:38 | jonathanj | if i use java-source-path, is it automatically compiled with my clojure code and available via (:import)? |
| 08:39 | jonathanj | i guess i can just give it a try |
| 08:41 | dysfun | ,(inc justin_smith) |
| 08: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... |
| 08:41 | dysfun | lol |
| 08:42 | dysfun | clearly i've forgotten the syntax |
| 08:42 | agarman | (inc justin_smith) |
| 08:42 | lazybot | ⇒ 210 |
| 08:42 | agarman | (dec dysfun) |
| 08:42 | lazybot | ⇒ 2 |
| 08:42 | jonathanj | justin_smith: thank you! |
| 08:42 | agarman | (inc dysfun) |
| 08:42 | lazybot | ⇒ 3 |
| 08:45 | justin_smith | jonathanj: yeah, if you set :java-source-paths [...] lein will compile the classes under that path |
| 08:59 | justin_smith | ,(str 'ba (repeat (rand-int 4) 'na)) |
| 08:59 | clojurebot | "baclojure.lang.LazySeq@c27025f5" |
| 08:59 | justin_smith | blergh |
| 08:59 | justin_smith | ,(apply str 'ba (repeat (rand-int 4) 'na)) |
| 08:59 | clojurebot | "ba" |
| 09:00 | justin_smith | ,(apply str 'ba (repeat (rand-int 4) 'na)) |
| 09:00 | clojurebot | "bananana" |
| 09:01 | dysfun | :) |
| 09:01 | dysfun | that's actually quite a nice way of introducing simple logic when teaching programming |
| 09:02 | dysfun | stealing that. thanks. |
| 09:02 | justin_smith | I'm sure it would go over great in a 5th grade classroom |
| 09:02 | justin_smith | heh :) |
| 09:02 | dysfun | i taught a friend to program clojure a few months ago that was odd |
| 09:02 | gfredericks | ,(apply str 'ba (take-while (fn [_] (< (rand) 0.75)) (repeat 'na))) |
| 09:02 | clojurebot | "bana" |
| 09:02 | dysfun | he'd not done anything more complex than excel formulae before |
| 09:03 | gfredericks | ,(apply str 'ba (take-while (fn [_] (< (rand) 0.75)) (repeat 'na))) |
| 09:03 | clojurebot | "banana" |
| 09:03 | gfredericks | ,(apply str 'ba (take-while (fn [_] (< (rand) 0.75)) (repeat 'na))) |
| 09:03 | clojurebot | "ba" |
| 09:03 | gfredericks | ,(apply str 'ba (take-while (fn [_] (< (rand) 0.95)) (repeat 'na))) |
| 09:03 | clojurebot | "banananananananananana" |
| 09: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 |
| 09:04 | justin_smith | &(frequencies (repeatedly 100 #(apply str 'ba (take-while (fn [_] (< (rand) 0.75)) (repeat 'na))))) |
| 09: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} |
| 09:04 | justin_smith | wow, it fit in one output! |
| 09:04 | dysfun | :) |
| 09:05 | agarman | (str (apply str (repeat (rand-int 16) 'na)) " " 'batman) |
| 09:05 | agarman | ,(str (apply str (repeat (rand-int 16) 'na)) " " 'batman) |
| 09:05 | clojurebot | " batman" |
| 09:05 | jonathanj | hrm, how would i have lein include some loose jar in my project? |
| 09:05 | justin_smith | jonathanj: put it in your :resource-paths |
| 09:05 | justin_smith | then it ends up on the classpath in the generated (uber)jar |
| 09:05 | agarman | ,(str (apply str (repeat (rand-int 16) 'na)) " " 'batman) |
| 09:05 | clojurebot | "nanananananananananana batman" |
| 09:05 | jonathanj | justin_smith: and for use during development? |
| 09: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. |
| 09:06 | justin_smith | jonathanj: yes, it will also be on the classpath while developing |
| 09:06 | justin_smith | jonathanj: but consider that it could also be pushed to a maven repo |
| 09:06 | jonathanj | do you mean inadvertently? |
| 09: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 |
| 09: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 |
| 09:07 | jonathanj | yeah, it did occur to me, i guess i'll aim for that later on |
| 09:09 | thheller | @dnolen just never liked the System/exit call, just saw your wiki edit to add it. thought I mention it |
| 09:09 | dnolen | thheller: sure but it doesn't matter much and System/exit is fine here |
| 09:10 | thheller | dnolen: yeah I guess so |
| 09: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 |
| 09:32 | jonathanj | 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.) |
| 09:33 | jonathanj | i'm just using `lein run` to run my main (which imports the java class), hopefully that's not the issue |
| 09:33 | cnb_ | is it possible to use definterface without the class being defined as final ? |
| 09:34 | justin_smith | jonathanj: oh, my bad, you need to add the jar itself to the resource-paths |
| 09:34 | jonathanj | justin_smith: yay! |
| 09:34 | justin_smith | jonathanj: that worked? |
| 09:35 | jonathanj | is src/main/resource the convention for resource-paths? |
| 09:35 | justin_smith | usually it is just resources/ |
| 09:35 | jonathanj | justin_smith: yes, that worked |
| 09:35 | justin_smith | awesome |
| 09:36 | justin_smith | 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 |
| 09:38 | jonathanj | justin_smith: is there some recommended reading regarding uploading jars to maven? |
| 09:39 | cnb_ | is it possible to use definterface without the class being defined as final ?/ |
| 09:39 | justin_smith | jonathanj: the mvn command can do this, there are some guides on sonatype too http://central.sonatype.org/pages/producers.html |
| 09:40 | justin_smith | cnb_: so you need an interface that isn't final? |
| 09:40 | cnb_ | yes |
| 09:40 | cnb_ | justin_smith: yes |
| 09:41 | cnb_ | justin_smith I mean the class than implements the interface using the webservice annotations is being declared as final |
| 09:42 | jonathanj | justin_smith: thanks again, you've been a tremendous help! |
| 09:42 | justin_smith | cnb_: so you need other interfaces to inherit from it? for normal usage of implementing the interface should be fine |
| 09:42 | jonathanj | ,(inc justin_smith) |
| 09: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... |
| 09:42 | justin_smith | jonathanj: the , isn't used for karma |
| 09:42 | jonathanj | (inc justin_smith) |
| 09:42 | lazybot | ⇒ 211 |
| 09:43 | cnb_ | justin_smith this one is being created as final (deftype ^{WebService {:targetNamespace "o.m.g"}} FooService [] |
| 09:43 | cnb_ | If I look at the .class the class generated is final, I do not want to be final |
| 09:43 | justin_smith | OK, than really what you care about is the deftype creating a final class |
| 09:43 | justin_smith | *then |
| 09:43 | cnb_ | yes |
| 09:44 | cnb_ | justin_smith: yes, that is the problem |
| 09:44 | justin_smith | maybe you need gen-class instead of deftype? |
| 09:45 | justin_smith | one moment |
| 09:46 | justin_smith | cnb_: this flow chart from cemerick is helpful http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/ |
| 09:46 | dysfun | hrm, i wonder if marginalia would be better served by inverting the order of functions in the source |
| 09:46 | justin_smith | cnb_: notice you are definitely inside the "interop zone" |
| 09: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 |
| 09:47 | justin_smith | cnb_: looks like if an instance of an anonymous type suffices you could get away with reify / proxy |
| 09:48 | justin_smith | dysfun: trufax |
| 09:48 | cnb_ | justin_smith thank you very much |
| 09:49 | dysfun | justin_smith: i guess it depends whether you hate your users or not ;) |
| 09:49 | justin_smith | cnb_: np, I use that flow chart a lot |
| 09:50 | justin_smith | 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 |
| 09:50 | noncom | are there any good tutorials or examples on clojure.tools.reader? |
| 09:50 | dysfun | heh |
| 09:50 | dysfun | do you use marginalia? |
| 09: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 |
| 09:51 | justin_smith | dysfun: I've played with it, I wish it were more flexible |
| 09:51 | justin_smith | s/defmethod/defmulti of course |
| 09:51 | dysfun | i'm quite fond of it, but obviously i'm going to have to build my own because yaks always need shaving |
| 09:52 | jonathanj | returning an OutputStream doesn't seem very clojure-like, is there a better alternative? |
| 09:52 | jonathanj | (i'm using a Java library that has InputStream and OutputStream parameters) |
| 09:53 | dysfun | justin_smith: tbh i tend to avoid multiple dispatch. i understand it can become a performance bottleneck in heavy throughput use cases |
| 09:54 | justin_smith | jonathanj: seems fine to return an OuputStream, it's easy enough to slurp from it or use with-open or whatever |
| 09:55 | justin_smith | dysfun: multimethods aren't much slower than fns, and if you do them right protocol functions will be faster than regular fns |
| 09:55 | dysfun | i use protocols |
| 09: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 | dysfun | 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 | Bronsa | noncom: http://sprunge.us/jQFL?clj |
| 10:16 | noncom | Bronsa: thank you! |
| 10:17 | noncom | 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 | noncom | you said "where possilbe" - what are the cases when this is not possible? |
| 10:20 | Bronsa | noncom: http://sprunge.us/aQdB?clj |
| 10:21 | Bronsa | 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 | noncom | 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 | dysfun | 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 | noncom | 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 | justin_smith | jonathanj: I think it is also possible without doing the toByteArray method call so that you get a proper pipe style setup |
| 10:32 | justin_smith | 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 | noncom | 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 | myguidingstar | 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 | tbaldrid_ | 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 | myguidingstar | 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 | ambrosebs | type annotations are documentation. |
| 11:18 | dysfun | hehe. i disagree :) |
| 11:18 | dysfun | i don't disagree they're useful, i just think from a documentation pov, docstrings are more useful |
| 11:19 | dysfun | 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 | dysfun | i'd go with 'almost always insufficient' actually |
| 11:30 | ambrosebs | dysfun: erm doc + type is way better than just doc |
| 11:30 | ambrosebs | especially when talking about clojure.core |
| 11:30 | ambrosebs | 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 | Glenjamin | just an unchecked one :p |
| 11:31 | dysfun | heh |
| 11:31 | dysfun | an imprecise one perhaps |
| 11:32 | dysfun | however, you have the freedom to divert from the specific to the more easily understandable |
| 11:33 | dysfun | 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 | ambrosebs | a few examples would make that perfect :) |
| 11:36 | dysfun | hrm, see i don't like the type signature there |
| 11:36 | dysfun | to me that should read number -> number and note in the docstring that it will perform conversion rules |
| 11:37 | dysfun | otherwise, that's pretty good |
| 11:38 | dysfun | 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 | dysfun | it's a problem of expression i think. how to express what it does concisely |
| 11:42 | dysfun | 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 | dysfun | and the union symbol looks too close to a 'u' |
| 11:45 | ambrosebs | the * is like a kleene star |
| 11:45 | ambrosebs | 0 or more types |
| 11:46 | ambrosebs | so the type sig that you might want is [Number * -> Number] |
| 11:46 | ambrosebs | 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 | ambrosebs | (even if it is implemented with 4 arities) |
| 11:48 | ambrosebs | so here's my favourite annotation in core.typed http://crossclj.info/doc/org.clojure/clojure/latest/clojure.core.html#_swap%21 |
| 11:49 | ambrosebs | 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 | ambrosebs | Bronsa: any sort of repeating pattern in a type that grows downwards is a TODO :)_ |
| 11:50 | ambrosebs | yea some-fn is a ridiculous annotation |
| 11:50 | ambrosebs | 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 | ambrosebs | (All [b ...] [b ... b -> [b .... b -> Any]]) just returns a function that takes the same arguments |
| 11:52 | ambrosebs | there's an example somewhere.. |
| 11:53 | ambrosebs | http://crossclj.info/doc/org.clojure/clojure/latest/clojure.core.html#_memoize |
| 11:53 | ambrosebs | so memoize takes a function and returns a function with the same interfact |
| 11:53 | ambrosebs | *interface |
| 11:53 | ambrosebs | 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 | dysfun | and the b ... b is a very verbose way of saying 'potentially many b' |
| 11:55 | dysfun | 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 | ambrosebs | that's of type '{:foo (Val 1) :bar (Val 2)} |
| 11:56 | ambrosebs | ah |
| 11:56 | ambrosebs | sorry |
| 11:57 | ambrosebs | that is specifically a hack at the moment |
| 11:57 | ambrosebs | but that's possible |
| 11:57 | ambrosebs | you need an Assoc type |
| 11:57 | ambrosebs | and there's a core.typed branch where this is actually implemented |
| 11:57 | ambrosebs | 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 | ambrosebs | that's the prototype syntax for assoc |
| 11:59 | ambrosebs | 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 | ambrosebs | 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 | dysfun | clojure is pretty flexible so you have to model in that flexibility, sure. |
| 12:01 | ambrosebs | https://www.irccloud.com/pastebin/xTWjWznc |
| 12:01 | ambrosebs | 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 | ambrosebs | 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 | dysfun | obviously it doesn't have variable arity |
| 12:04 | ambrosebs | does scala support rest parameters? |
| 12:05 | ambrosebs | I assumed it did |
| 12:05 | ambrosebs | 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:08 | ambrosebs | justin_smith: gold star! |
| 12:08 | ambrosebs | 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 | justin_smith | right |
| 12:09 | justin_smith | (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 | justin_smith | 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 | ambrosebs | which is currently disgusting to do |
| 12:13 | justin_smith | jonathanj: that's the toString of the array... |
| 12:14 | justin_smith | because spit expects a string |
| 12:14 | justin_smith | you could also use (spit (String. array_of_byte)) |
| 12:14 | justin_smith | ,(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 | mpenet`` | 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 | mpenet`` | yes, I can walk them and convert all the values to ensure proper hash equality, but it's not free |
| 12:33 | mpenet`` | ,(= ["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 | justin_smith | ,(= (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 | justin_smith | 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 | bbloom | then you need fake/simplified type signatures to document your type signatures :-P |
| 12:56 | ambrosebs | bbloom: truth |
| 12:56 | ambrosebs | 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 | justin_smith | 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 | muraiki | 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 | justin_smith | ,(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 | sm0ke | 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 | sm0ke | 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 | justin_smith | sm0ke: are you using thread / Thread. extensively? |
| 13:22 | sm0ke | justin_smith: well the thread pool is famous numcores*2+42 |
| 13:23 | sm0ke | 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 | justin_smith | 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 | ajmagnifico | (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 | justin_smith | sm0ke: manifold is what aleph does for async dispatch, so it's something you can actually compare to core.async |
| 13:26 | justin_smith | 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 | justin_smith | 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 | jonathanj | 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 | Guest8609 | 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 | jonathanj | Caused by: java.lang.ClassNotFoundException: org.apache.fop.apps.FopFactoryBuilder |
| 14:03 | jonathanj | https://github.com/apache/fop/blob/fop-1_1/src/java/org/apache/fop/apps/FopFactoryBuilder.java |
| 14:03 | jonathanj | 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 | hiredman | (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 | jonathanj | 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 | jonathanj | hiredman: i imported something else from a repl |
| 14:11 | jonathanj | => (import '[org.apache.fop.apps FOUserAgent]) |
| 14:11 | jonathanj | 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 | amalloy | 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 | jonathanj | 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 | jonathanj | => (import '[org.apache.fop.apps FopFactoryBuilder]) |
| 14:14 | jonathanj | 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 | hiredman | `lein classpath` will actually should you the jars |
| 14:16 | hiredman | 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 | jonathanj | 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 | jonathanj | terrific |
| 14:23 | hiredman | sounds like an apache project |
| 14:26 | djames | Any favorite hosted services for private Maven repos? |
| 14:29 | djames | 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 | sdegutis | 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 | sdegutis | I thought maybe it's group-by or partition or something, but no. |
| 14:33 | sdegutis | Closest is partition-by. |
| 14:33 | postpunkjustin | Oh yeah, maybe partition-by (complement clojure.string/blank?) |
| 14:34 | postpunkjustin | Not 100% sure |
| 14:34 | sdegutis | But partition-by leaves the ' ' inthere. |
| 14:34 | postpunkjustin | just filter it after? |
| 14:34 | postpunkjustin | 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 | justin_smith | ,(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 | turbofail | 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 | jonathanj | 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 | arrdem | 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 | justin_smith | a wiki model might make more sense than a source control model |
| 15:14 | arrdem | meh.. |
| 15:14 | arrdem | 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 | arrdem | 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 | justin_smith | 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 | jonathanj | output redirected to a file: https://pb.codehash.net/d517012d69854973b2a13c9a6e133dbe |
| 15:22 | jonathanj | it's kind of bizarre, i've never actually seen this before |
| 15:24 | jonathanj | someone just pointed this out: |
| 15:24 | jonathanj | >>> name('efbfbd'.decode('hex').decode('utf8')) |
| 15:24 | jonathanj | 'REPLACEMENT CHARACTER' |
| 15:24 | jonathanj | 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 | justin_smith | 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 | amalloy | 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 | jonathanj | so the difference is whether i pass System/out or whether i pass (output-stream "xxx.pdf") |
| 15:34 | jonathanj | 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 | amalloy | 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 | amalloy | eg, i expect if you passed (PrintStream. (output-stream "xxx.pdf")), you would get similarly broken behavior |
| 15:37 | jonathanj | hrm |
| 15:37 | jonathanj | https://pb.codehash.net/34e68111fa894f049b8c249e6e1645fa |
| 15:37 | jonathanj | this still produces the weird output |
| 15:47 | jonathanj | sigh |
| 15:48 | jonathanj | 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 | jonathanj | 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 | amalloy | 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 | amalloy | 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 | jonathanj | 0000000: e2e3 cfd3 .... |
| 16:06 | Frozenlock | ah! I just discovered dash.el to bring many clojure goodies into emacs. |
| 16:06 | Frozenlock | (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 | jonathanj | 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 | jonathanj | 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 | amalloy | 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 | jonathanj | 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: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 | justin_smith | 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 | dysfun | i get this error https://www.refheap.com/98522 |
| 16:53 | akkad | justin_smith nginx timesout |
| 16:53 | akkad | 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 | jonathanj | justin_smith, amalloy: thank you for your help and patience, i filed a bug with lein |
| 16:57 | jonathanj | (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 | justin_smith | if you don't change your project.clj, you don't even need to run lein cp next time |
| 16:59 | justin_smith | though of course, having lein fixed would be better |
| 17:01 | amalloy | justin_smith: java -cp `lein classpath` ... |
| 17:01 | amalloy | 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 | expez | (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 | justin_smith | after loading your project file manually etc. |
| 17:49 | justin_smith | 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 | justin_smith | or whatever it is called these days |
| 18:13 | justin_smith | this happens because the print is happening from a thread that has not inherited your main thread's value of *out* |
| 18:14 | justin_smith | 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 | {blake} | This is a web-based app. And when I change the code, it forces me to re-login. |
| 18:34 | {blake} | 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 | {blake} | 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 | {blake} | 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 | hiredman | if I want to load/replace/run code I do it via a repl |
| 18:39 | hiredman | 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 | freddd | 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 | amalloy | 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 | freddd | {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 | amalloy | 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 | freddd | ToxicFrog: yes, very true. i did mention that. thanks! |
| 19:11 | freddd | 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 | TEttinger | 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 | brehaut | {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 | bostonaholic | 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 | Morgawr | 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 | Morgawr | 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 | bcm | if you write a schema like (def a-and-anything {:a s/Str, s/Keyword s/Any}) |
| 23:48 | bcm | i think that will work |
| 23:51 | bcm | looks to work on my box, anyway. |
| 23:51 | bcm | 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 | bcm | 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" ? |