2014-10-15
| 00:13 | amalloy | RazWelle1: clojure-clr is on-topic here, but i don't think there are many people here who use it: you may have trouble getting an answer. is there somewhere else you could ask, or some relevant section in the documentation? myself, i don't even understand what the question means |
| 00:15 | RazWelle1 | amalloy: not that I know of :\ seems most of the people who use clojureclr are either developers or C# experts, I'm a little new to both |
| 00:15 | RazWelle1 | I wanted to learn lisp in a way that was useful to my current project |
| 00:15 | RazWelle1 | which depends on a .net library |
| 00:16 | RazWelle1 | I even tried ironscheme but I'dve made more progress in clojure-clr |
| 00:16 | RazWelle1 | but not by much |
| 00:16 | TEttinger | RazWelle1: inspect an assembly as in reflection? |
| 00:16 | RazWelle1 | TEttinger: yeah basically python's dir() |
| 00:16 | RazWelle1 | So I can see what the repl is able to access |
| 00:16 | TEttinger | oh ok |
| 00:17 | RazWelle1 | I'm trying to translate this http://lib.openmetaverse.org/wiki/IronPython/Simple_Login |
| 00:17 | TEttinger | you saw this stuff right? https://github.com/clojure/clojure-clr/wiki/Loading-assemblies |
| 00:18 | RazWelle1 | Maybe I should try assembly-load-file macro, right now I"m doing it directly with (System.Reflection.Assembly/LoadFrom "libomv/OpenMetaverse.dll") |
| 00:18 | justin_smith | RazWelle1: the comment here may be useful https://github.com/clojure/clojure-clr/blob/master/Clojure/Clojure.Source/clojure/core_clr.clj#L199 |
| 00:18 | RazWelle1 | *click* |
| 00:19 | xsyn | How do you tell lein to build a dependency against a specific version of something. E.g. spark-core against mvn -Dhadoop.version=2.4.0 |
| 00:20 | xsyn | spark-core by default builds against 1.0.4 |
| 00:20 | justin_smith | RazWelle1: oooh - this one has a promising name... https://github.com/clojure/clojure-clr/blob/master/Clojure/Clojure.Main/Properties/AssemblyInfo.cs |
| 00:20 | justin_smith | AssemblyInfo |
| 00:21 | justin_smith | oh never mind |
| 00:21 | RazWelle1 | ooh |
| 00:21 | justin_smith | that just *provides* info about the clojure assembly |
| 00:21 | justin_smith | reverse of what you want |
| 00:21 | TEttinger | you can call this thorugh interop http://msdn.microsoft.com/en-us/library/system.reflection.assembly.gettypes(v=vs.110).aspx |
| 00:24 | egghead | grr, I can't find a mustache impl in clojure that will let me configure it to not replace missing vars |
| 00:57 | technomancy | does vim interpret Ctrl-i as a tab like emacs and other readline things? |
| 00:58 | bbloom_ | technomancy: you can do ctrl-v then type what you want directly |
| 00:58 | bbloom_ | so like if you need a real tab, ctrl-v + tab |
| 00:58 | turbofail | ,(do (require 'clojure.walk) (clojure.walk/macroexpand-all ''(-> a b))) |
| 00:58 | clojurebot | (quote (b a)) |
| 00:59 | turbofail | i don't think that should happen |
| 00:59 | bbloom_ | technomancy: in insert mode, i mean of course |
| 00:59 | technomancy | bbloom_: right, but inside a terminal, hitting TAB literally sends a ctrl-i keycode |
| 00:59 | technomancy | bbloom_: does gui vim interpret them as the same thing as well? |
| 01:00 | justin_smith | turbofail: that what should happen? |
| 01:00 | bbloom_ | technomancy: oh i have no idea |
| 01:00 | turbofail | justin_smith: it's macroexpanding things within a quote form |
| 01:00 | justin_smith | right, it's supposed to do that |
| 01:00 | technomancy | any gui vim users care to try? |
| 01:01 | turbofail | justin_smith: but that gives wrong results. evaluating '(-> a b) doesn't yield (b a) |
| 01:01 | justin_smith | why not? |
| 01:01 | justin_smith | it should |
| 01:01 | turbofail | justin_smith: notice the two quotes i was using in my macroexpand |
| 01:01 | turbofail | i.e. (macroexpand-all '(quote (-> a b))) |
| 01:02 | amalloy | turbofail: clojure.walk/macroexpand-all is not close to being an accurate representation of the compiler |
| 01:02 | justin_smith | right, macroexpand ignores one quote - otherwise it wouldn't be very useful |
| 01:02 | amalloy | justin_smith: ????? |
| 01:02 | turbofail | no, it ignores every quote |
| 01:02 | turbofail | ,(clojure.walk/macroexpand-all '(quote (quote (quote (-> a b))))) |
| 01:02 | clojurebot | (quote (quote (quote (b a)))) |
| 01:02 | amalloy | clojure.core/macroexpand ignores no quotes at all. clojure.walk/macroexpand-all ignores all of them |
| 01:03 | justin_smith | amalloy I mean '(+ 1 1) doesn't return (quote (+ 1 1)) - it doesn't show the first layer of quote |
| 01:03 | amalloy | justin_smith: macroexpand is not a macro, it is a function. that "first layer" doesn't exist |
| 01:03 | bbloom_ | technomancy: not sure what you're trying to figure out exactly |
| 01:03 | justin_smith | ahh, right |
| 01:03 | turbofail | amalloy: that may be the case but it should still at least try and be relatively faithful |
| 01:04 | amalloy | turbofail: for a macroexpander that comes close to replicating what the compiler does (but still is not perfectly accurate), try clojure.tools.macro/mexpand-all |
| 01:04 | amalloy | turbofail: it is implemented in the simplest possible way, like everything in clojure.walk |
| 01:04 | turbofail | ah |
| 01:05 | amalloy | macroexpand-all, like flatten, is (in my opinion) not really a top-quality tool, so much as an example of "check out all this really cool stuff we can do with a small amount of code in clojure! you should try out this language!" |
| 01:05 | amalloy | ie, an advertisement |
| 01:08 | amalloy | oh, pmap is on that list too |
| 01:08 | amalloy | it is impressive that those functions come as close to usefulness as they do; don't get me wrong, they're pretty cool. they do their job well, but once you move beyond toy examples you need something more substantial |
| 01:09 | amalloy | and hey, while you're in c.t.macro, check out macrolet and symbol macros. more fun than a barrel of monkeys |
| 01:18 | turbofail | hm. so what remaining discrepancies does c.t.macro/mexpand-all have? |
| 01:21 | amalloy | the gist of it is: it's not the compiler. you can't really hope to keep the two separate codebases in sync forever. something might "break" with any update to the compiler |
| 01:21 | amalloy | the only specific issue i can remember is that it doesn't cope with macros which return code objects that you couldn't have typed in as literals, such as sorted maps |
| 01:22 | amalloy | eg, (case x 1 true) expands to something like (case* x {1 true}), except that the map is sorted, not an array-map or a hash-map |
| 01:23 | turbofail | ah |
| 01:23 | clojurebot | Cool story bro. |
| 01:23 | turbofail | silence, bot |
| 01:23 | amalloy | so ifyou write a case statement with 8 or more entries, mexpand fails to retain the order |
| 01:23 | dbasch | for a good time, macroexpand-all (doseq [a [] b [] c [] d [] e [] f [] g []]) |
| 01:23 | dbasch | and read the output when you need help falling asleep |
| 01:24 | amalloy | loop loop loop |
| 01:24 | turbofail | i've looked into the guts of `for' before, that was an unpleasant experience |
| 01:27 | amalloy | i wonder what the guts of CL's LOOP look like |
| 01:28 | turbofail | on that note i'd kind of like something like racket's for/fold, for cases in which you're just going to be feeding the result of `for' straight into a reduce |
| 01:29 | turbofail | it'd be nice to not have that intermediate sequence |
| 01:58 | aztak | anyone using vim to hack clojure? Sometimes, mostlt when switching windows or using Tagbar, the syntax hilightning gets all screwed up.. anyone else having that problem? |
| 03:42 | raspasov | anyone with experience around serializing Clojure's deftype ? |
| 04:01 | hyPiRion | amalloy: the CL loop is an amazing macro with some bugginess in it |
| 04:02 | dysfun_ | is there a pretty-printer for the lein repl? |
| 04:02 | dysfun_ | for return values |
| 04:02 | raspasov | dysfun_: I like this library https://github.com/razum2um/aprint |
| 04:03 | dysfun_ | that is very nice, but still requires me to manually type it in at the repl |
| 04:03 | dysfun_ | i'm looking for something that hooks the return value after i execute some code at the repl and pretty prints that |
| 04:03 | raspasov | yea, haven't seen anything that does it automatically, it would be awesome though |
| 04:04 | dysfun_ | well, i may have to, because i'm getting quite annoying trying to deal with a large xml structure |
| 04:04 | dysfun_ | aha! https://github.com/greglook/whidbey |
| 04:05 | raspasov | nice! :) |
| 04:06 | razum2um1 | raspasov: thanks :) yep, I look to integrate this into repl to format returned value automatically |
| 04:07 | raspasov | razum2um1: cool! |
| 04:08 | dysfun_ | awesome, one line in ~/.lein/profiles.clj |
| 04:08 | dysfun_ | works like a charm |
| 04:20 | zwer | hyPiRion what bugginess? |
| 04:23 | hyPiRion | zwer: like https://www.refheap.com/91764 |
| 04:24 | hyPiRion | How to combine the loop clauses are afaik poorly defined and complex |
| 04:36 | pluma | Coming from a high-level non-FP background, what is a vector and how is it different from an array or list? |
| 04:43 | hyPiRion | pluma: shameless self-plug: http://hypirion.com/musings/understanding-persistent-vector-pt-1 |
| 04:43 | kungi | hyPiRion: Oh nice! |
| 04:44 | hyPiRion | In short. A vector is immutable, but still provides efficient updates and random access lookup compared to an immutable singly linked list |
| 04:44 | hyPiRion | Also, a vector is always strict, whereas a sequence may be lazy. |
| 04:46 | daniel__ | ,(cons 5 [1 2 3 4]) |
| 04:46 | clojurebot | (5 1 2 3 4) |
| 04:46 | daniel__ | ,(cons 5 '(1 2 3 4)) |
| 04:46 | clojurebot | (5 1 2 3 4) |
| 04:46 | daniel__ | ,(cons [1 2 3 4] 5) |
| 04:46 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long> |
| 04:46 | daniel__ | ,(cons [1 2 3 4] [5]) |
| 04:46 | clojurebot | ([1 2 3 4] 5) |
| 04:46 | hyPiRion | ,(conj [1 2 3 4] 5) |
| 04:46 | clojurebot | [1 2 3 4 5] |
| 04:46 | daniel__ | right :p |
| 04:46 | hyPiRion | ,(conj '(1 2 3 4) 5) |
| 04:46 | clojurebot | (5 1 2 3 4) |
| 04:48 | pluma | hyPiRion: thanks. |
| 04:49 | hyPiRion | np |
| 04:55 | CookedGryphon | Does anyone know how core async pipelines work? The docs suggest that transducer state won't be shared, so how would stateful transducers like dedupe work? |
| 05:05 | CookedGryphon | and does anyone have any suggestions for composing pipes? I just want to merge two existing chans, run a transformer on the combined result, and pipe the result into a third existing chan |
| 05:05 | CookedGryphon | and the code's coming out really clunky looking |
| 06:50 | kenrestivo | i've got a seq, and i'm dealing with a java thing that wants a java.util.Enumeration. any ideas how to force cast it? |
| 06:54 | clgv | ,(ancestors (class (range 10))) |
| 06:54 | clojurebot | #{clojure.lang.Sequential clojure.lang.IMeta clojure.lang.Seqable clojure.lang.IPersistentCollection clojure.lang.Obj ...} |
| 06:55 | clgv | ,(->> (ancestors (class (range 10))) (map #(.getName %)) sort) |
| 06:55 | clojurebot | ("clojure.lang.IHashEq" "clojure.lang.IMeta" "clojure.lang.IObj" "clojure.lang.IPending" "clojure.lang.IPersistentCollection" ...) |
| 06:55 | clgv | &(->> (ancestors (class (range 10))) (map #(.getName %)) sort) |
| 06:55 | lazybot | ⇒ ("clojure.lang.IHashEq" "clojure.lang.IMeta" "clojure.lang.IObj" "clojure.lang.IPending" "clojure.lang.IPersistentCollection" "clojure.lang.ISeq" "clojure.lang.Obj" "clojure.lang.Seqable" "clojure.lang.Sequential" "java.io.Serializable" "java.lang.Iterable" "java.lan... https://www.refheap.com/91773 |
| 06:55 | clgv | kenrestivo: you can get an Iterator via java.lang.Iterable interface |
| 06:57 | kenrestivo | i have no idea how to do that. tried (.iterator some-seq) and got something, but still same error, it's obviously not acceptable, has to be an Enumation |
| 06:58 | kenrestivo | Enumeration |
| 06:58 | clgv | kenrestivo: if there is no conversion object Iterator -> Enumeration in Java then you can also just (reify java.util.Enumeration (hasMoreElements ...) (nextElement ...)) |
| 06:59 | kenrestivo | oh, sure, thanks, guess i could just write my own. that should work. |
| 07:03 | clgv | kenrestivo: (defn ->enumeration [^java.lang.Iterable xs] (let [it (.iterator xs)] (reify java.util.Enumeration (hasMoreElements [_] (.hasNext it)) (nextElement [_] (.next it))))) |
| 07:05 | kenrestivo | clgv: thank you. that is awesome. worked. is that in a util library somewhere? |
| 07:06 | clgv | kenrestivo: no idea. just wrote it right now |
| 07:06 | kenrestivo | it's a couple lines longer than what i was writing, and it works whereas mine did not. anyway, thanks |
| 07:06 | clgv | :) |
| 07:20 | dysfun_ | is there a clojureish library that takes in an XML DTD and makes it easier to work with xml conforming to it? |
| 07:24 | clgv | dysfun_: that's pretty vague |
| 07:25 | dysfun_ | yes, i know. i don't work with xml much so i'm not sure how it may be made more useful. i do know that my code is a mess. i suppose xml validation would be a good start |
| 07:26 | rweir | what did you want it to do beyond validating that the xml is uh valid |
| 07:26 | clgv | dysfun_: data.xml converts the xml to a clojure data structure |
| 07:27 | dysfun_ | ideally some abstraction that allows easy transformation. zippers ended up making it more complex when i tried that last |
| 07:27 | dysfun_ | yes, i have that and i have messy code that works with it |
| 07:27 | dysfun_ | dtd validation would at least enable me to kill the error checking |
| 07:27 | clgv | dysfun_: maybe use a transformation language like xslt? |
| 07:28 | dysfun_ | hrm, i think what i want could be quite simple in xslt actually |
| 07:28 | dysfun_ | thanks |
| 07:29 | clgv | dysfun_: maybe that one helps if you need to integrate it within a clojure project https://github.com/pjt/saxon |
| 07:29 | dysfun_ | brilliant, thanks |
| 07:30 | perplexa | hello |
| 07:31 | dysfun_ | "You can download an evaluation copy of the software from here.". Maybe not :( |
| 07:31 | perplexa | i have a (dorun (for ...)) form, that i want to execute in parallel. should i use core.async or just get fancy with pmap? |
| 07:35 | clgv | dysfun_: oh well... |
| 07:35 | clgv | perplexa: clojure.core.reducers |
| 07:36 | dysfun_ | thanks |
| 07:37 | perplexa | clgv: i have multiple functions take take a couple of minutes for computation |
| 07:37 | perplexa | and i want them to run in parallel ;x |
| 07:38 | clgv | perplexa: example? |
| 07:38 | perplexa | actualy, they just submit the work to a cluster and then wait for the result |
| 07:38 | perplexa | clgv: cascalog queries :P |
| 07:39 | perplexa | but some just don't use the entire cluster, so that i have more map/reduce slots for more queries, therefor i want to execute them in parallel |
| 07:39 | clgv | perplexa: well, you can probably submit them asynchronously and just start waiting for the results after you submitted all |
| 07:39 | perplexa | that's what i want to do |
| 07:39 | perplexa | but i don't know what the right way would be ;/ |
| 07:39 | clgv | but then you do not need anthing in addition to the cluster lib |
| 07:40 | clgv | or does it not support asynchronous submits? |
| 07:40 | clgv | the easy trick would be to wrap those submits into futures then |
| 07:41 | perplexa | i don't think it does |
| 07:41 | perplexa | but i don't care about the results either, it's just fire&forget basically |
| 07:41 | clgv | you just want to heat the server room, eh? |
| 07:42 | clgv | well do you need to wait for completion of those tasks? |
| 07:42 | perplexa | haha :) nah, the queries read from hdfs and write to hdfs, and i don't need any of the info in clj |
| 07:42 | perplexa | nope :) |
| 07:42 | clgv | ok just use futures and forgot about them ;) |
| 07:43 | perplexa | i just hope the application doesn't terminate while they're still running ;p |
| 07:43 | perplexa | when using futures |
| 07:43 | perplexa | so.. i put a bunch of futures in a vector and then check if they're finished or something? |
| 07:44 | clgv | yeah. |
| 07:44 | clgv | well then you need to wait for completion by dereferencing the futures... |
| 07:47 | perplexa | clgv: soooo. just (let [x (for [..] (future ...))]) and then (map #(@%) x) afterwards or sth? |
| 07:50 | clgv | perplexa: no you need to eagerly create those futures, e.g. (doseq [f (mapv #(future ...) coll)] (deref f)) |
| 07:51 | clgv | perplexa: if you absolutely need that `for` wrap it in `vec` |
| 07:51 | perplexa | i don't think i do :) |
| 07:53 | perplexa | clgv: what's the difference between your example and mine? |
| 07:56 | clgv | perplexa: you have lazy stuff in there such that futures won't be created until that `for` is forced, so you effictively create the future when you are trying derefing it such that no parallelism is happening |
| 07:57 | perplexa | ah! thx |
| 07:57 | perplexa | that's what mapv is for i guess :) |
| 07:57 | perplexa | (inc clgv) |
| 07:57 | lazybot | ⇒ 30 |
| 07:57 | clgv | perplexa: in my example yes. in general there are other use cases as performance ;) |
| 07:58 | clgv | $karma perplexa |
| 07:58 | lazybot | perplexa has karma -1. |
| 07:58 | clgv | hehe |
| 07:58 | perplexa | haha |
| 08:54 | visof | hi |
| 08:55 | visof | is there anybody used apache-s4 beforehand? |
| 09:00 | clgv | ~anyone |
| 09:00 | clojurebot | Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..." |
| 09:02 | luxbock | in leiningen templates when passing the data map to the ->files function, how are functions as the values of the map used? |
| 09:02 | luxbock | in the chestnut template there's a line like this: `:not-om-tools? (fn [block] (if (om-tools? opts) "" block))` |
| 09:03 | luxbock | and then in the core.cljs file there's a line: `(dom/h1 {{#not-om-tools?}}nil {{/not-om-tools?}}(:text app))` |
| 09:03 | luxbock | so I understand what it does, but I'm still confused about the role of the `block` argument that the function gets |
| 09:05 | luxbock | ah think I get it now |
| 09:06 | luxbock | the block is the text between the mustache block as defined by #not-om-tools and /not-om-tools |
| 09:13 | perplexa | 14:34:38 perplexa | Java.lang.RuntimeException: No such var: impl/logical-comp, compiling:(cascalog/logic/ops.clj:46:3) |
| 09:13 | perplexa | 14:35:02 perplexa | i randomly get that error on a query that otherwise works, any ideas where this might come from? |
| 09:13 | perplexa | 14:55:53 perplexa | it's there in line 46: https://github.com/nathanmarz/cascalog/blob/develop/cascalog-core/src/clj/cascalog/logic/ops.clj |
| 09:13 | perplexa | 14:56:05 perplexa | but i don't see why it would randomly spew the above error |
| 09:14 | perplexa | is that actually a bug in clojure? i don't see why it would fail ;p |
| 09:18 | clgv | perplexa: you said that's executed on a cluster, are you sure the versions of cascalog are the same everywhere? |
| 09:19 | perplexa | clgv: yeah, i build an uberjar with lein, which includes the deps and then just run it via `hadoop jar` |
| 09:19 | hyPiRion | so nothing in :provided? |
| 09:20 | perplexa | actually, when it starts compiling stuff there, could it be that the cleanup interferes between futures ? |
| 09:20 | hyPiRion | I've heard of some issues with hadoop related to that |
| 09:20 | perplexa | hyPiRion: hadoop-core and hadoop-common are provided |
| 09:21 | perplexa | and those versions match the cluster's. |
| 09:21 | perplexa | it only happens randomly, too ;/ |
| 09:21 | perplexa | and i saw it just now that i started using futures, hmm |
| 09:21 | hyPiRion | alright, then idk |
| 09:22 | perplexa | when it says compiling, it's actually compiling stuff? |
| 09:22 | clgv | perplexa: but you only use the futures on the client side right? |
| 09:22 | perplexa | yes |
| 09:22 | clgv | and there error is server/cluster side? |
| 09:22 | perplexa | yesnope client-side |
| 09:22 | perplexa | doesn't even start the query |
| 09:23 | perplexa | s/yesnope/nope/ |
| 09:23 | clgv | perplexa: does the code within the future dynamically load namespaces? |
| 09:23 | perplexa | yes |
| 09:23 | perplexa | ;x |
| 09:24 | clgv | that's likely the reason - can you change it to depend statically on those namespaces? |
| 09:24 | perplexa | something like |
| 09:24 | perplexa | (require (symbol type-ns)) |
| 09:24 | perplexa | ((resolve (symbol type-ns "bootstrap")) id config input) |
| 09:24 | perplexa | it's gonna be hard to have them loaded statically :/ |
| 09:24 | clgv | perplexa: yeah require is not transactional |
| 09:25 | clgv | perplexa: I use that one https://gist.github.com/guv/ac76b9ab1878705062c6 |
| 09:25 | perplexa | nice, i'll see if that helps :) |
| 09:25 | clgv | but I think loading of namespaces should be made transactional |
| 09:26 | clgv | ah well, remove the println ;) |
| 09:27 | perplexa | my dirty work around would have been to add a sleep to the execution so that the bootstrapping happens with a 1sec delay between each query :D |
| 09:27 | hyPiRion | loading of namespaces transactionally is really hard, just fyi |
| 09:27 | stuartsierra | Basically impossible since Clojure allows arbitrary side-effects at the top-level. |
| 09:28 | dnolen_ | ,*clojure-version* |
| 09:28 | clojurebot | {:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"} |
| 09:29 | dnolen_ | ah hmm, oh well, anyways nice to see using transducers w/ parallel fold "just works" - (r/fold + ((map inc) +) (vec (range 1000000))) |
| 09:29 | clgv | stuartsierra: what do you mean exactly? |
| 09:30 | Bronsa | dnolen_: nice |
| 09:30 | stuartsierra | clgv: "loading a namespace" in Clojure just means loading a file, which means evaluating each of the top-level forms in that file in order. You can do *anything* in a file, no constraints. No way to define a "transaction" around that. |
| 09:31 | clgv | stuartsierra: ok. just limit it to require which currently manages to keep track of the namespaces it loaded |
| 09:32 | clgv | stuartsierra: but it only manages the names in a `ref` - nothing more |
| 09:32 | clgv | at that point there could be logic to load every namespace (as defined in context of `require`) only once in a thread-safe way |
| 09:34 | dnolen_ | Bronsa: btw is the JS analyzer work good enough to sync up cljs.core.async w/ clojure.core.async? |
| 09:37 | Bronsa | dnolen_: I'm actually waiting on CLJS-857 before cutting a first stable release |
| 09:39 | Bronsa | dnolen_: I can work around it if you decide that's not going to make in cljs btw, even though I'd rather not |
| 09:42 | dnolen_ | Bronsa: re: 857, question, why doesn't this affect the Clojure analyzer? |
| 09:42 | dnolen_ | Bronsa: or is what 857 proposes what Clojure already does? |
| 09:44 | Bronsa | dnolen_: deftype in clojure expands to (deftype* name class.name [fields] :implements [interfaces] (method [..] ..)) |
| 09:45 | Bronsa | so the inline method impls are in the local scope of the fields, that's what I'm proposing with 857 for cljs |
| 09:45 | dnolen_ | Bronsa: ok I'm cool with 857 |
| 09:47 | dnolen_ | Bronsa: just tried to apply - emits a lot of analyzer warnings - a I'd take new patch that addresses this |
| 09:47 | Bronsa | dnolen_: ok I'll take a look |
| 09:48 | dnolen_ | Bronsa: looks like a locals thing - analyzer complains about the fields as undeclared vars |
| 10:03 | verma | does cursive have insta-repl? like lighttable? |
| 10:06 | dnolen_ | verma: no only a more traditional REPL - but it's a pretty nice one |
| 10:08 | verma | dnolen_, nice! I have to talk to a group of js guys tomorrow, lighttable's insta-repl is pretty nice to show some funky clojure moves :) |
| 10:10 | mping | hi guys |
| 10:11 | mping | I'd like some advice |
| 10:11 | mping | I'm parsing a ~400mb json file |
| 10:13 | mping | and I'm trying to speed up the parsing and processing |
| 10:13 | mping | but it's still a bit slow |
| 10:13 | Bronsa | dnolen_: did resolve-var's impl change recently? |
| 10:15 | verma | mping what are you using to load the json file? |
| 10:16 | dnolen_ | Bronsa: confirm-var-exists changed, not resolve-var |
| 10:17 | dnolen_ | Bronsa: we used to not check that vars actually exist from other namespaces, not the case anymore |
| 10:42 | csd_ | How can I do a try/catch and have a statement execute conditional on an exception not being thrown? |
| 10:43 | stuartsierra | csd_: one way (when (try … true (catch Exception _ false)) (do-the-thing)) |
| 10:44 | csd_ | oh will the catch prevent the last statement from executing if there is an exception? |
| 10:44 | LauJensen | For those interested I made a screencast showing how to port a visual swing UI app to Clojurescript and HTML5/Canvas http://www.bestinclass.dk/blog/brians-brain-clojurescript |
| 10:45 | stuartsierra | csd_: No, I just used the result of the entire try/catch block as the test in the `when` |
| 10:45 | TimMc | csd_: (try (let [ret ...] (do-a-thing) ret) (catch ...)) |
| 10:45 | csd_ | i want to have things log differently depending on whether the action succeeds or fails.. i imagine there's an idiomatic way to do that |
| 10:46 | csd_ | stuartsierra: i see, clever |
| 10:46 | stuartsierra | A try/catch block returns a value, just like everything else in Clojure. |
| 10:48 | csd_ | in your example, I assume `ret` is the action that i want to execute conditional on success? |
| 10:48 | csd_ | meant to direct that to you TimMc |
| 10:49 | Bronsa | dnolen_: the patch didn't handle correctly defrecord's args, I just attached an updated patch. I don't see any warnings now |
| 10:57 | xsyn | using conj should stop me from having a stackoverflow in a recursive function, right? |
| 10:58 | gfredericks | uhm |
| 10:58 | gfredericks | depends on the details? conj is not lazy though if that's what you're after |
| 10:59 | gfredericks | pretty much any function call can give you a stackoverflow if you set it up for success correctly :) |
| 11:01 | dnolen_ | Bronsa: thanks |
| 11:08 | xeqi | gfredericks: identity? |
| 11:12 | gfredericks | xeqi: sure |
| 11:12 | gfredericks | xeqi: just call it with a bulging stack |
| 11:13 | justin_smith | gfredericks: that sounds like something I should look up on urbandictionary |
| 11:14 | gfredericks | justin_smith: I cannot condone any such activity |
| 11:19 | perplexa | is (some (partial = source) (keys input)) preferable over (nil? (get input source)) ? |
| 11:19 | perplexa | just wanna know if "source" is a key of "input" |
| 11:20 | xeqi | (doc contains?) |
| 11:20 | clojurebot | "([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or logarithmic time; it will not perform a linear search for a value. See also 'some'." |
| 11:21 | perplexa | xeqi: haha thanks :P |
| 11:28 | TimMc | csd_: No, ret is the return value from other work you were doing, if you wanted it. |
| 11:30 | hiredman | /win 26 |
| 11:32 | Bronsa | hiredman: http://sprunge.us/BGhG |
| 11:33 | justin_smith | Bronsa: clearly it's a secret code |
| 11:35 | m1dnight_ | Damnit, I wanted to buy a clj sticker for my laptop but I'm missing 0.05 dollars on my prepaid mastercard |
| 11:37 | hiredman | Bronsa: I have been data mined |
| 11:37 | perplexa | clgv: seems the thread safe require solved my problem, much apreciated! |
| 11:37 | perplexa | (inc clgv) |
| 11:37 | lazybot | ⇒ 31 |
| 11:38 | clgv | perplexa: great :) |
| 11:44 | TimMc | Bronsa, hiredman: More data: http://sprunge.us/YdDh |
| 11:46 | clgv | TimMc: guess he lost now? :P |
| 11:46 | perplexa | haha what |
| 11:47 | hiredman | reverse engineering my irssi setup |
| 11:47 | perplexa | somebody tell him about meta+[1-9] ;/ |
| 11:47 | perplexa | ;x |
| 11:47 | perplexa | oh hai |
| 11:47 | TimMc | perplexa: ...that doesn't help with more than 10 windows |
| 11:48 | justin_smith | TimMc: what, you don't have a "15" key on your keyboard? |
| 11:48 | hiredman | actually it does, M t is the same as /win 15 |
| 11:48 | perplexa | TimMc: there's also meta+qwertyuiop |
| 11:48 | TimMc | justin_smith: I know a guy who has a keybiard with F1–F25 and uses all of them. |
| 11:50 | verma | is there somewhere, where clojure benchmarks are listed? |
| 11:51 | Bronsa | TimMc: hah |
| 11:51 | clgv | verma: http://benchmarksgame.alioth.debian.org/ |
| 11:53 | verma | clgv, thanks, you think clojure was type annotated for these benchmarks? |
| 11:55 | clgv | verma: andy fingerhut optimized some (even all?) of those benchmark implementations |
| 11:56 | clgv | verma: ah no, maybe I confused it. the example I opened says alex miller ;) |
| 11:57 | Jaood | verma: extremely annotated |
| 11:57 | verma | nice, benchmarks are not bad :) |
| 11:57 | verma | nice |
| 11:57 | clgv | verma: that one feels like cheating badly: http://benchmarksgame.alioth.debian.org/u64q/program.php?test=pidigits&lang=clojure&id=5 |
| 11:58 | verma | haha, that qualifies as java |
| 11:58 | verma | but I guess that's the point, if need be fallback to raw java |
| 11:58 | clgv | even more it uses ASM to generate a class on the fly :P |
| 11:58 | verma | wait what? |
| 11:59 | clgv | that one is better http://benchmarksgame.alioth.debian.org/u64q/program.php?test=nbody&lang=clojure&id=1 |
| 11:59 | verma | oh nice! |
| 11:59 | verma | which javascript was there |
| 12:00 | verma | wish* |
| 12:00 | verma | but I guess this site is convincing enough, that clojure is not slow |
| 12:00 | verma | at least compared to what web-dev people do right now with Ruby/Python |
| 12:00 | verma | would definitely be interesting to see cljs and javascript added in there |
| 12:00 | Jaood | verma: you mean non-idiomatic clojure is not slow |
| 12:01 | clgv | Jaood: ah you can get it pretty idiomatic looking and fast, through macros or inline functions |
| 12:01 | verma | Jaood, if I use qualifiers people will get confused (context: I am doing a talk about clojure with a bunch of js guys). |
| 12:01 | noonian | even idiomatic clojure is not slow, its just not *as fast* as java |
| 12:02 | verma | I think this is a pretty picture: http://benchmarksgame.alioth.debian.org/u32q/which-programs-are-fastest.php |
| 12:04 | mping | talking of speed, guys can I have your opinion on some clj I have? |
| 12:04 | mping | I'm parsing a ~400mb json |
| 12:04 | mping | and I don' have alot of clues on how to speed it up |
| 12:04 | mping | I've used pmam and reducers |
| 12:04 | llasram | mping: A single JSON object or 400MB of separate JSON objects? |
| 12:05 | mping | *pmap |
| 12:05 | mping | llasram: separate |
| 12:05 | mping | one per row, newline separated |
| 12:05 | llasram | mping: Which JSON parser? |
| 12:05 | mping | cheshire |
| 12:05 | mping | but htop shows me that the cpus have alot of headroom |
| 12:05 | mping | and visualvm shows me assoc and such as dominators |
| 12:05 | llasram | Then are you sure you aren't IO-bound? |
| 12:05 | mping | yes; Im pretty sure |
| 12:06 | mping | Ive measured the time to parse the json |
| 12:06 | llasram | Are your JSON objects generally record-like, with largely the same keys across objects, or are they more map-like, with arbitrary data as JSON object keys? |
| 12:07 | mping | record-like |
| 12:07 | mping | I can provide the code if you guys want to take a look |
| 12:07 | llasram | Sure -- I've run out of reasonable questions to ask :-) |
| 12:07 | mping | my task is to read json files with an array path like [a b c d e f] |
| 12:08 | mping | and generate "n-grams" such as [a b c] [b c d ] ... |
| 12:08 | mping | then sum the whole thing and count |
| 12:08 | mping | my lines are like this: {"path":["a","b","c","d","e","f"],"pageviews":7,"visits":1,"duration":97878} |
| 12:09 | mping | I'm using lein-exec |
| 12:09 | mping | but I am a clojure n00b, so forgive any bad code |
| 12:10 | mping | here it is: https://gist.github.com/mping/180343e9c745c9c446d6 |
| 12:11 | Jaood | mping: are you using laziness? |
| 12:11 | mping | yes |
| 12:11 | mping | for reading the lines |
| 12:12 | llasram | mping: Independent of performance, the way `lazy-file-lines` depends on the lazy seq being fully-consumed to close the file is morally equivalent to depending on GC to release the resource |
| 12:13 | llasram | mping: There used to be similar helpers in monolithic contrib, but they're pretty much always a bad idea |
| 12:13 | llasram | Anything like `take` which produces an early-ending wrapper seq leaves the resource dangling until/if GC cleans it up |
| 12:15 | llasram | mping: Letting cheshire produce keyword-keys for maps is more convenient, but if you're aiming for performance is slower than just leaving the keys as strings |
| 12:16 | dnolen_ | Bronsa: patch has a bug |
| 12:16 | Bronsa | dnolen_: ? |
| 12:17 | dnolen_ | Bronsa: Caused by: java.lang.RuntimeException: Unable to resolve symbol: op in this context |
| 12:17 | Bronsa | dnolen_: gah, I probably have forgot to add that line to the commit |
| 12:17 | Bronsa | one sec |
| 12:18 | Bronsa | yeah |
| 12:18 | llasram | mping: Is your goal just "make it faster" or do you have specific performance benchmarks you need to hit? |
| 12:19 | Bronsa | dnolen_: removed old & updated |
| 12:24 | dnolen_ | Bronsa: applied |
| 12:27 | Bronsa | dnolen_: awesome. I'll get t.a.js up to date with the changes that went into cljs over the last month |
| 12:27 | Bronsa | dnolen_: once you cut a new cljs release I can release a new beta, then we can talk about porting core.async if you want |
| 12:27 | dnolen_ | Bronsa: cool sounds good! |
| 12:29 | verma | would be nice if people could take a look at this and point out obviously incorrect stuff: https://www.dropbox.com/s/9t8xt6x20oabpjg/ClojurePres.pdf?dl=0 |
| 12:29 | Bronsa | dnolen_: http://dev.clojure.org/jira/browse/ASYNC-86 is a blocker for that btw. |
| 12:29 | verma | any feedback is much appreciated |
| 12:29 | dnolen_ | Bronsa: ok thanks will look into that |
| 12:30 | Bronsa | dnolen_: I'm updating the patch to depend on 0.6.1 ATM, will probably need the ok of tbaldridge |
| 12:30 | dnolen_ | Bronsa: sure, I'll make sure to check with him |
| 12:36 | justin_smith | verma: what does "Language Age ratio" mean? |
| 12:37 | verma | I read it some where, how old a language is vs. how popular it is |
| 12:37 | verma | can't find source :( |
| 12:37 | justin_smith | ahh, so that means "it is popular for its age" |
| 12:37 | verma | popularity : age, age |
| 12:37 | verma | yes |
| 12:37 | verma | may be should just say that |
| 12:38 | justin_smith | if Language Age ratio is something people know about it's fine, I had just never heard the term before |
| 12:38 | verma | yeah, you're right, I changed the text |
| 12:38 | justin_smith | ahh - it's Popularit : Language Age ratio |
| 12:38 | verma | oh :P |
| 12:38 | verma | I made it italics |
| 12:38 | verma | so that it stands out |
| 12:39 | justin_smith | I thought Popularity: was a heading |
| 12:39 | justin_smith | heh |
| 12:39 | verma | but may be make it bold |
| 12:39 | justin_smith | yeah, I misread it |
| 12:39 | verma | I bold-italicised it |
| 12:40 | verma | this is a 10 minute intro slide to just get stuff started, all action will happen in repl |
| 12:40 | verma | slides* |
| 12:41 | justin_smith | verma: potential alternate target for the benchmark link http://benchmarksgame.alioth.debian.org/u64q/benchmark.php?test=all&lang=clojure&data=u64q |
| 12:41 | justin_smith | one that specifically highlights clojure |
| 12:41 | verma | yeah, I thought about that, the linked one actually says that its potentially as fast as go, where everyone seems to be flocking towards lately |
| 12:42 | verma | but that's just a get into the site URl and then I will browse around, but two links don't hurt, so I will add that too |
| 12:42 | benzap | So I was wondering, how hard is it to find a software development job which uses clojure? |
| 12:42 | verma | benzap, that's an excellent point as well, people are concerned that if they invest time in clojure they won't find a job |
| 12:44 | benzap | well, I know there are jobs |
| 12:44 | benzap | very few though |
| 12:44 | justin_smith | verma: "You can write your server side stuff in Clojure inter-ops with Java like its a no-brainer." - multiple issues with this sentence |
| 12:45 | verma | justin_smith, sure :) now I see them :) |
| 12:45 | verma | justin_smith, I changed it to: You can write your server side stuff in Clojure: it inter-ops with Java. |
| 12:46 | benzap | I'm currently working on my own side-project in clojure, which i'm hoping could be marketed sometime |
| 12:47 | benzap | but it would be awesome if I could find a remote job that used clojure |
| 12:47 | nullptr | easier to make jobs in something "new" than to find jobs |
| 12:47 | benzap | hmm yeah |
| 12:48 | verma | benzap, I pitch clojure all the time to people who pay me (consulting) .. |
| 12:48 | verma | most new stuff I am doing is mostly in clojurescript |
| 12:48 | noonian | someone was looking for part time clojure developers the other day, i don't remember who though |
| 12:48 | benzap | yeah, i saw that |
| 12:48 | benzap | seemed way out of my league, I think it was staples? |
| 12:49 | nullptr | a job that involves only one language does sound pretty lame, though :) |
| 12:49 | verma | yeah saw that too |
| 12:49 | benzap | agreed |
| 12:49 | benzap | maybe i'm just sick of my current working situation |
| 12:49 | benzap | legacy code, with years upon years woth of refactoring |
| 12:49 | verma | justin_smith, what did you think overall? a good intro? anything obvious I missed out/ |
| 12:49 | mping | llasram: sorry for MIA, was busy with some other stuff |
| 12:50 | mping | llasram: my goal is to show my Java colleague that clojure can be performant and more elegant :) |
| 12:50 | verma | mping, I would think telling them, its not java would suffice :P |
| 12:51 | verma | mping, I've had a few people I've told this to and it has somewhat worked. |
| 12:51 | justin_smith | verma: a good intro over all - one more copy thing, calling Chestnut a boilerplate - boilerplate is a pejorative term, may be better to call it a template |
| 12:52 | verma | justin_smith, thanks! will do |
| 12:53 | verma | justin_smith, you've earned a beer, send me btc address and I will send you beer worth of btc :D |
| 12:53 | benzap | verma: you working on an article? |
| 12:53 | verma | benzap, no I gotta go present clojure at a js meetup |
| 12:54 | benzap | oh nice |
| 12:54 | benzap | you should mention flyer.js just for kicks |
| 12:54 | benzap | i joke |
| 12:54 | verma | nice! |
| 12:57 | justin_smith | verma: it's all good, thanks anyway though |
| 12:59 | justin_smith | "it's all good" - why yes, I did spend some formative years in chicago |
| 12:59 | verma | justin_smith, sure, thanks for your help |
| 12:59 | verma | there should be a list of irc -> btc |
| 13:02 | mping | verma: problem is that my colleague wrote the equivalent of my code and it runs on 1/5 of the time or so |
| 13:02 | mping | although he didn't even parsed json |
| 13:02 | mping | I just find it strange that the cpus are not maxed out |
| 13:02 | verma | mping, he loaded json without parsing? |
| 13:03 | verma | that's a little presumptuous of me |
| 13:03 | verma | he/she |
| 13:03 | technomancy | hello people |
| 13:03 | dopamean_ | hello |
| 13:04 | technomancy | I have disabled SSL 3.0 on clojars due to http://poodlebleed.com |
| 13:04 | technomancy | please let me know if you experience any connection issues |
| 13:04 | justin_smith | "poodlebleed" - what a terrible name |
| 13:05 | technomancy | justin_smith: and a terrible logo |
| 13:05 | verma | I like how these vulnerabilities get their own pages now |
| 13:05 | verma | and domains |
| 13:05 | mping | verma: yep, since the records are simple he splits the string and other stuff |
| 13:06 | verma | mping, you can do the same can't you? |
| 13:06 | justin_smith | verma: mping: that's a terrible, and fragile way to do it |
| 13:06 | verma | justin_smith, yes yes, but we're racing for speed here I would think |
| 13:07 | verma | mping, you can't win if the other person is taking crappy shortcuts |
| 13:07 | justin_smith | well in that case go ahead and attach a booster rocket to your backpack, and ditch the helmet, you'll be more aerodynamic that way |
| 13:08 | verma | lol |
| 13:09 | verma | my hair would cause drag, a helmet would be nice since it'd reduce drag |
| 13:12 | justin_smith | mping: for a more clojure-friendly comparison: is each version thread safe? how hard is it to make each version thread safe if not? |
| 13:15 | mping | verma: i don't want to win I just want to do a good job |
| 13:16 | mping | justin_smith: what do you mean thread safe? we both try to parallelize using threads |
| 13:16 | justin_smith | mping: is this up to date with what you are doing? https://gist.github.com/mping/180343e9c745c9c446d6 |
| 13:16 | mping | after parsing the json into well-defined records , everything is fair game |
| 13:16 | mping | justin_smith: yep |
| 13:16 | justin_smith | mping: by thread safe I mean won't do weird broken stuff if you run it in many threads simultaneously |
| 13:17 | mping | justin_smith: yep its thread safe |
| 13:17 | llasram | mping: I'd try separating out the I/O -- benchmark just slurping the entire dataset into memory as a vector of strings is vs processing that data |
| 13:17 | verma | mping sure :) |
| 13:18 | mping | we don't share state "normally", only through core (reducers, pmap) or java's Array.parallelStream, blockingqueue and such |
| 13:18 | mping | justin_smith: json slurping is 8 secs |
| 13:18 | justin_smith | mping: small thing - you can use zero? instead of = 0 |
| 13:18 | justin_smith | on line 55 |
| 13:18 | mping | slurping + doing the "n-grams" thing for n = 3 is 22 secs |
| 13:18 | mping | justin_smith: thanks! |
| 13:19 | verma | mping: line-seq sort of does what lazy-file-lines is doing |
| 13:19 | justin_smith | mping: also I have heard nothing but bad things about pmap |
| 13:19 | justin_smith | mping: I think reducers are preferable |
| 13:19 | mping | justin_smith: I was wondering why pmap was not reducing the time... |
| 13:20 | mping | heheh |
| 13:20 | justin_smith | also #(map f %) is better performance wise than (partial map f) if you know you only get one arg |
| 13:21 | llasram | mping: How fast is the Java version? <5 seconds? |
| 13:21 | justin_smith | and (map #(println %)) should be (map println) |
| 13:21 | mping | the Java version takes a minute on my machine |
| 13:21 | llasram | pmap is weird, but reducers is not not ideal here because the input is IO. You can only do a parallel `fold` over vectors in clojure.core.reducers |
| 13:22 | llasram | Now I'm confused -- I thought you said your version was taking 22 seconds :-) |
| 13:23 | mping | llasram: I'm using a chunked version of pmap for parsing lines and partitioning |
| 13:23 | mping | llasram: 22 seconds for only slurp + partitioning |
| 13:23 | mping | total time last time was 4 or 5 mins |
| 13:23 | verma | mping, you could enable reflection warnings, and then type annotate some of the things |
| 13:23 | mping | llasram: and I'm doing r/fold for summing |
| 13:23 | llasram | mping: Ah |
| 13:24 | justin_smith | llasram: what about a map over a sequence of dereffed futures? because if it's IO bound we don't want the semi-laziness of pmap |
| 13:24 | llasram | mping: `fold` only runs in parallel if the ultimate input is a vector. It's just `reduce` over a lazy seq |
| 13:25 | llasram | mping: pmap has several problems, even when doing the chunking: (a) http://dev.clojure.org/jira/browse/CLJ-862 |
| 13:26 | llasram | and (b) it maintains the order of the output even when you don't need that property, which reduces throughput |
| 13:26 | mping | llasram: so what are my alternatives? |
| 13:27 | llasram | justin_smith: Futures of what? |
| 13:27 | justin_smith | llasram: the calculation to be done on each input |
| 13:27 | justin_smith | making sure it is not chunked, of course... |
| 13:27 | llasram | justin_smith: That's kind of what `pmap` is, just with a bunch of juggling which tries (poorly) to keep #CPUS+2 futures running at a time |
| 13:27 | stuartsierra | transducers and the new core.async pipelines are what you want. |
| 13:28 | mping | stuartsierra: I've tried to wrap my head around transducers but I still don't got it :( |
| 13:28 | llasram | mping: Because I/O seems to be such a small portion of the overall process, I'd slurp the entire dataset into a vector then use reducers ending in a `fold` |
| 13:28 | nullptr | mping: did you watch hickey's strangeloop presentation? it's quite accessible. |
| 13:28 | llasram | The entire pipeline should run in the forkjoin pool, utilizing all available CPUs |
| 13:29 | mping | nullptr: I skimmed over it but I have to watch it again |
| 13:30 | llasram | mping: You can also use all the same "manual" threading APIs available to and used by the Java version, but leverage e.g. Clojure first-class functions to simplify the code |
| 13:32 | mping | It seems that the (apply concat) is taking ages. |
| 13:33 | mping | I was using flatten but it seems overkill |
| 13:34 | llasram | mping: `(apply concat)` is the appropriate thing to do in the lazy-seq case. It does the most efficient thing possible given that it needs to both consume and produce lazy seqs |
| 13:34 | mping | 16s for slurping+partitioning vs 2mins for slurping+partitioning+apply-concat |
| 13:35 | mping | I might as well skip that and handle it within the r/fold |
| 13:38 | mping | thanks guys I'm gonna go back to the drawing board, see if I can use core.asyn and transducers |
| 13:46 | Fender | can any of you estimate the size of a vector of ~10 doubles/ints in memory? |
| 13:46 | Fender | a coarse estimate is good enough, I reckon it's 8byte*10+size(vector) |
| 13:47 | hiredman | Fender: no |
| 13:47 | hiredman | Fender: as rule of thumb, unless otherwise noted, collections on the jvm box primitives |
| 13:47 | mi6x3m | clojure is there a way to preserve new lines in macro defs? |
| 13:47 | Fender | "no" as in "no coarse estimate is good enough"? :) |
| 13:48 | Fender | "no" as in "nobody cas estimate that"?? |
| 13:48 | hiredman | so each int or double will also have associated object headers and such |
| 13:48 | lazybot | Fender: What are you, crazy? Of course not! |
| 13:49 | justin_smith | mi6x3m: the reading stage does not preserve newlines |
| 13:49 | mi6x3m | justin_smith: so I guess i'd have to use pprint? |
| 13:49 | mi6x3m | or something when I output macro generated source |
| 13:49 | hiredman | Fender: no as in "8byte*10+size(vector)" is not even close |
| 13:49 | Fender | hmm |
| 13:49 | justin_smith | mi6x3m: I think there exist pretty printing rules for code - I forget if they are in pprint or elsewhere |
| 13:50 | Fender | so double the size of the Numbers |
| 13:50 | Fender | and the size of vector is approx?? |
| 13:50 | lazybot | Fender: Definitely not. |
| 13:50 | Fender | hmm, slapping doesnt work in pidgin D: |
| 13:50 | hiredman | depending on what you are measuring for, another wrinkle is most jvms cache some number of boxed numbers, so like the objects in memory for the first 50 numbers will actually be the same |
| 13:50 | Fender | right, lazybot?? |
| 13:50 | mi6x3m | justin_smith: yes, thanks! |
| 13:50 | lazybot | Fender: Uh, no. Why would you even ask? |
| 13:51 | Fender | so hiredman, can you give an estimate? |
| 13:51 | hiredman | and clojure also provides primitive versions of vectors, but I am not sure I would recommend using them |
| 13:51 | hiredman | Fender: no |
| 13:51 | justin_smith | Fender: it would help to look at how vectors are implemented, the internals may not look like what you think http://hypirion.com/musings/understanding-persistent-vector-pt-1 |
| 13:51 | SagiCZ1 | when i call "lein deps" where do the dependencies end up? |
| 13:52 | Fender | I thought its like chunks of 32 references |
| 13:52 | justin_smith | SagiCZ1: ~/.m2/ |
| 13:52 | Fender | plus some points left and right |
| 13:52 | Fender | pointers that is |
| 13:52 | hiredman | it isn't C though, there are no raw pointers |
| 13:53 | justin_smith | Fender: it's more like a tree - that article shows a simplified version |
| 13:53 | martinklepsch | With things like rails you benefit from improved dev tooling as soon as you upgrade, with leiningen templates this is not as straightforward — did anyoneof you think about this? |
| 13:53 | hiredman | it is all jvm objects with headers, which I am not sure, but I think the size of the object header depends on if you are on a 32bit or 64bit machine |
| 13:53 | SagiCZ1 | justin_smith: thanks, found them.. it doesnt add the dependencies to classpath automatically? |
| 13:54 | justin_smith | SagiCZ1: that's what lein does - it's a tool that puts artifacts in the classpath |
| 13:54 | hiredman | Fender: there are tools for estimating the size of an object in memory, but I've never used them |
| 13:54 | SagiCZ1 | strange |
| 13:54 | justin_smith | SagiCZ1: the deps command just ensures that they have been downloaded |
| 13:54 | justin_smith | other tasks ensure that they are downloaded, and then run clojure with those files in the classpath |
| 13:54 | hiredman | generally if I really care about the size of something, I'd use a ByteBuffer |
| 13:55 | justin_smith | via the command line (check out the ps output for lein commands - you see a huge list of jars under .m2) |
| 13:55 | SagiCZ1 | justin_smith: i see.. i found my mistake.. i didnt run the leiningen REPL, just the regular REPL |
| 13:55 | justin_smith | right, like I said, lein is the tool that adds those things to the classpath |
| 13:56 | SagiCZ1 | justin_smith: thank you |
| 13:58 | justin_smith | np |
| 13:58 | mi6x3m | could someone of you people check out this macro def and tell me if it's a smart idea to call it like that (with keywords but in fixed positions) |
| 13:58 | mi6x3m | http://pastebin.com/M4MRqPg6 |
| 13:58 | clojurebot | It's greek to me. |
| 14:01 | llasram | mi6x3m: It's pretty bizarre |
| 14:01 | mi6x3m | llasram: can you suggest a better layout for the args? |
| 14:01 | Fender | ok, guys, I suppose to get an estimate I will just have to spam my memory with that stuff and see how many fit |
| 14:01 | Fender | maybe I just use a record with primitives if that is possible |
| 14:02 | Fender | that should keep a lid on the size of the thing |
| 14:02 | llasram | mi6x3m: Just either usse keyword args or positional args, not args which must be indicated by both position and keyword |
| 14:03 | SagiCZ1 | how would i find all functions that can be applied to a given object? |
| 14:03 | mi6x3m | llasram: this will not allow me to have a body of forms |
| 14:04 | SagiCZ1 | lets say i have this incanter type called "Matrix" .. |
| 14:04 | Fender | SagiCZ1: (comp seq #(.getMethods %) class) |
| 14:04 | justin_smith | SagiCZ1: knowing all types a clojure function could take is not generally easy |
| 14:05 | justin_smith | Fender: that's for methods of that class, not clojure functions - maybe I misunderstand the question |
| 14:05 | SagiCZ1 | justin_smith: maybe just functions that make up some protocol? |
| 14:06 | llasram | mi6x3m: Wah? Take a look at `reify` |
| 14:06 | Fender | yeah, maybe you're right |
| 14:06 | mi6x3m | llasram: excuse me? |
| 14:06 | Fender | well it will show you notifyAll() and such useful methods |
| 14:06 | justin_smith | ,(require '[clojure.reflect :as reflect]) |
| 14:06 | clojurebot | nil |
| 14:06 | shem | is there any compendium of core.typed annotations for untyped libraries? it seems like a lot of wasted effort when everybody does their own. |
| 14:06 | justin_smith | ,(:bases (reflect/reflect [])) |
| 14:06 | clojurebot | #{clojure.lang.APersistentVector clojure.lang.IReduce clojure.lang.IObj clojure.lang.IEditableCollection} |
| 14:06 | mi6x3m | I want to be able to pass n arguments after :include-source |
| 14:07 | justin_smith | that will tell you about interfaces it implements |
| 14:07 | llasram | mi6x3m: Well, `deftype` is a better example. It's a macro which accepts keyword arguments followed by any number of body forms |
| 14:07 | llasram | Crap, no not `deftype` either |
| 14:07 | llasram | One of those actually does accept some frikkin options :-) |
| 14:07 | mi6x3m | well how is it done? :) |
| 14:08 | llasram | Oh, they do both parse their arguments that way -- they just neither have any documented options right now |
| 14:09 | jeremyheiler | mi6x3m: basically you can to & body all the parameters, popping off keyword arg pairs until you don't find anymore. then the rest is the actual body |
| 14:10 | mi6x3m | jeremyheiler: yes, this was the previous version |
| 14:11 | llasram | mi6x3m: Then what was the problem with it? |
| 14:11 | mi6x3m | I thought it's weird of course |
| 14:11 | mi6x3m | lemme revert |
| 14:11 | mi6x3m | thanks a lot! |
| 14:12 | verma | in (def v 0) .. is "variable" the right term for "v"? |
| 14:14 | technomancy | verma: it's a var |
| 14:14 | technomancy | "variable" is an overloaded term that we don't use |
| 14:15 | xeqi | technomancy: not a symbol? |
| 14:16 | justin_smith | xeqi: depends on what you mean by v - the argument to def, or the thing dev outputs that is named v |
| 14:16 | justin_smith | *def outputs |
| 14:16 | technomancy | heh, well at one point it's a symbol, at one point it's a string, at one point it's bytes on disk |
| 14:16 | llasram | So say we all |
| 14:20 | dbasch | the rose is not the same as the name of the rose |
| 14:21 | justin_smith | and The Name of the Rose is an excellent book |
| 14:21 | technomancy | (inc umberto-eco) |
| 14:21 | lazybot | ⇒ 1 |
| 14:23 | mmeix | help for learning newbie again: |
| 14:23 | mmeix | (trying to reimplement map) |
| 14:24 | mmeix | (defn map- [fun s] (cons (fun (first s)) (lazy-seq (map- fun (rest s))))) |
| 14:24 | mmeix | gets me a NullPointerException - why? |
| 14:24 | llasram | mmeix: Where's your base case? |
| 14:24 | xeqi | mmeix: what happens when s is [] ? |
| 14:24 | llasram | Gotta have a base case |
| 14:25 | dbasch | justin_smith: indeed. I read it when it came out but I was probably too young to appreciate it fully. |
| 14:25 | parenjitsu | (apply semiotics) |
| 14:26 | justin_smith | dbasch: that, Baudolino, Island of the Day Before... excellent immersion in the medieval mind |
| 14:29 | dbasch | mmeix: (defn map- [fun s] (when (seq s) (cons (fun (first s)) (lazy-seq (map- fun (rest s)))))) |
| 14:37 | mmeix | ok ... thanks; I had tried (map- inc [2 3 4] and got the NullPointer - had thought since there was a "s" ([2 3 4]) this would start the sequence - wrong thinking obv. |
| 14:38 | dbasch | mmeix: that’s because at some point you get to the empty sequence, and (inc (first [])) is (inc nil) |
| 14:39 | mmeix | ah ...! thanks |
| 14:39 | mmeix | "(inc lightbulbs)" |
| 14:40 | mmeix | really appreciate ongoing help here :-) |
| 14:52 | brianwong | how do i get pprint to return the string it would print to *out* instead of actually printing to *out*? |
| 14:52 | brianwong | with clojure.pprint |
| 14:52 | brianwong | sorry if it is obvious |
| 14:53 | technomancy | brianwong: with-out-string is one way |
| 14:53 | brianwong | technomancy: thanks. |
| 14:54 | justin_smith | technomancy: not to be confused with without-string (another cantidate for the useless library) |
| 14:54 | kenrestivo | raynes: can i bug you with a conch question? https://www.refheap.com/91799 |
| 14:55 | brianwong | technomancy: that worked perfectly |
| 14:55 | kenrestivo | but, the above code just hangs, it opens the output file, but appears not to actually push any input into the program. |
| 14:55 | technomancy | justin_smith: you're full of good bad ideas today |
| 14:55 | justin_smith | (defmacro without-string [& body] `(do (with-out-string ~@body) nil)) |
| 14:56 | technomancy | http://www.theawl.com/2014/10/interpreting-the-animal-choices-on-the-worlds-most-popular-programming-books |
| 15:01 | muraiki | that aardwolf is pretty cool |
| 15:01 | muraiki | can eat 150,000 termites in a night. wow |
| 15:01 | muraiki | oh, 250,000. even better |
| 15:02 | amalloy | kenrestivo: it's super-weird that you call input-stream on each input twice, and close one of them but pass the other to this thrashcat thing |
| 15:02 | kenrestivo | amalloy: the internals of java are still mystifying to me, true. |
| 15:03 | kenrestivo | basically this is the way i was able to guess is how you do "foo < *.bar > baz" |
| 15:04 | kenrestivo | the globbing is done in clojure, and i get individual file streams, and i had to use this SequenceInputStream thing, and i stopped before it got into factories and helpers and such... |
| 15:04 | amalloy | kenrestivo: sure, it's a reasonable approach, but again what is the point of the 'iss binding? i'm saying all you do is open them and then close them |
| 15:05 | kenrestivo | i wasn't sure how to close them after they were done. i was under the impression that input-stream opens the file descriptor, and it has to be closed. maybe i've got that wrong? |
| 15:05 | justin_smith | kenrestivo: if it gets collected, it gets closed |
| 15:05 | amalloy | kenrestivo: you are not understanding what i am saying. you open some streams, assign them to iss. then you open some *totally different* streams, and give those to thrashcat |
| 15:06 | amalloy | then you close the streams in iss |
| 15:06 | kenrestivo | oh, cool, thanks. |
| 15:07 | amalloy | other than that, what you're doing here looks broadly correct. if thrashcat is not writing its output where you want...how am i supposed to help with that? i've never heard of a program named thrashcat; maybe it's broken. try with smoething simpler, like cat |
| 15:08 | kenrestivo | it operates just like cat, so i can subsitute cat for it. |
| 15:08 | kenrestivo | for testing. |
| 15:08 | kenrestivo | just takes stdin, does some work, poots the results to stout, and some status messages to stderr |
| 15:09 | kenrestivo | i'll beat on it some more. i just wanted a second opinion whether i was heading in the right direction, thanks. |
| 15:09 | amalloy | kenrestivo: if you are seeking help with conch, try to simplify your problem to the minimum necessary to reproduce it. with thrashcat, ->enumeration, and format-show-save all totally undefined, i can't guess what's wrong |
| 15:10 | kenrestivo | will do. minimum repro case would involve plain old cat. |
| 15:11 | geoffs` | If I wanted to define a function to look up an arbitrary symbol in the namespace that the function was defined in, can I just use *ns* within it to reference that namespace? |
| 15:11 | geoffs` | Like so: (defn get-postfix-cmd [cmd-sym] |
| 15:11 | geoffs` | (let [cmd-sym (symbol (str (name cmd-sym) "-cmd"))] |
| 15:11 | geoffs` | (cmd-sym (ns-publics *ns*)))) |
| 15:11 | geoffs` | |
| 15:11 | justin_smith | geoffs`: *ns* will get the current namespace at run time, which will be pretty much useless |
| 15:12 | geoffs` | That's what I thought |
| 15:12 | hiredman | *ns* is set at compile time, not run time |
| 15:13 | geoffs` | justin_smith: So is there a way to reference the namespace a function is defined in? |
| 15:13 | justin_smith | hiredman: but calling a form that contains a reference to *ns* will get the ns of the caller |
| 15:13 | justin_smith | s/form/fn |
| 15:14 | justin_smith | ,(defn getns [] *ns*) |
| 15:14 | clojurebot | #'sandbox/getns |
| 15:15 | justin_smith | ,(ns sandbox2) |
| 15:15 | clojurebot | nil |
| 15:15 | justin_smith | ,(sandbox/getns) |
| 15:15 | clojurebot | #<Namespace sandbox> |
| 15:15 | justin_smith | weird - that is not what it does in my repl... |
| 15:15 | justin_smith | ,*ns* |
| 15:15 | clojurebot | #<Namespace sandbox> |
| 15:15 | justin_smith | oh, bleh |
| 15:16 | amalloy | justin_smith: the bots would like to remind you they are not normal execution environments |
| 15:17 | dbasch | also, the bots like to be antropomorphized |
| 15:17 | dbasch | anthropomorphized, my fingers |
| 15:17 | justin_smith | https://www.refheap.com/91804 this is what I was talking about |
| 15:18 | patrkris | hi folks. i've created a data_readers.clj in my src directory, and in it I have defined another reader for the inst tagged literal. but when I fire up 'lein repl' and enter a #inst literal, it complains that the function I have designated for inst literals is unbound. as soon as I (use 'namespace-of-literal-fn) it works. is this expected behavior? |
| 15:18 | amalloy | dbasch: they like to be treated like ants. formicopomorphized? |
| 15:19 | dbasch | leiningen vs the bots |
| 15:19 | justin_smith | patrkris: are you requiring the defining namespace in data_readers.clj? |
| 15:19 | patrkris | justin_smith: no i am not. just a (require 'namespace) at the beginning of the file? |
| 15:20 | justin_smith | patrkris: yeah, as long as the name of the namespace reflects its place relative to the classpath |
| 15:20 | justin_smith | normal clojure namespace location rules |
| 15:21 | geoffs` | justin_smith: thanks for the confirmation. I think I've got it figured out. |
| 15:22 | justin_smith | geoffs`: maybe resolve would help? |
| 15:22 | patrkris | justin_smith: hmm... if i put (require 'name.space/read-instant) before the tag map, it complains that it is not a valid data-reader map |
| 15:23 | justin_smith | that's not how require works |
| 15:23 | justin_smith | and as to the latter - maybe you need an injection to make sure your ns is available before that file is loaded? |
| 15:24 | justin_smith | it would be (require 'name.space) then you can call name.space/read-instant |
| 15:24 | patrkris | justin_smith: yeah, my mistake. i did write only the namespace, not including the symbol of the namespace. gives the mentioned error. |
| 15:24 | patrkris | *symbol inside the namespace |
| 15:25 | justin_smith | total hack - {:read-instant-key (do (require 'name.space) name.space/read-instant)} |
| 15:25 | justin_smith | but there has to be something better than that |
| 15:28 | patrkris | justin_smith: yeah. according to http://clojure.org/reader, section Tagged Literals, it should be straight forward |
| 15:31 | justin_smith | ahh, so you don't need the ns to be loaded in side that data_readers file, but you do need to ensure it is loaded before that tag is found |
| 15:31 | justin_smith | so require the ns that defines that tag in any namespaces that use that literal (or load data that uses the literal) |
| 15:32 | justin_smith | *defines that tag reader |
| 15:33 | patrkris | justin_smith: ok, that was what I thought might be required. alright, thanks :) |
| 15:53 | kenrestivo | ok here is a minimum failing case: https://www.refheap.com/91807 . i am kind of exhausted so it wouldn't be surprising if there were something very obviously wrong in there |
| 15:56 | justin_smith | kenrestivo: so format-show-save gets a path and creates a file name in that path? |
| 15:56 | kenrestivo | yep |
| 15:57 | justin_smith | ,(clojure.java.io/file "foo" "bar" "baz") |
| 15:57 | clojurebot | #<File foo/bar/baz> |
| 15:57 | justin_smith | that may help you |
| 15:58 | justin_smith | this isn't relevant to your main issue, just thought I would point it out |
| 15:58 | kenrestivo | thanks, always happy to do a little bikeshedding :-) |
| 15:58 | justin_smith | so you can do :out (jio/file save-path (str name \- date)) |
| 15:59 | kenrestivo | i'm more curious why it's not writing any data. if it's not something dumb i'm doing, maybe it might be a bug in conch? i dunno. |
| 16:00 | justin_smith | if you deref that future, do you get an exception? |
| 16:03 | piranha | hey! Can somebody recommend a simple configuration library? I'm using weavejester's environ right now and I like it except for the part that I can't distribute defaults with uberjar, which I really want to do. |
| 16:05 | kungi | piranha: If you find one please tell me. I am also using environ and have the same problem. |
| 16:05 | piranha | ok :) |
| 16:06 | kungi | piranha: How about distributing a start.sh script running the uberjar? |
| 16:06 | piranha | hmmm... I wonder if modifying environ so that I can supply defaults from normal file additionally to project.clj makes sense |
| 16:06 | piranha | I thought about that a bit but I really like the idea of having just one file for distribution |
| 16:06 | piranha | two files are already "many" (vs "single" uberjar) |
| 16:06 | kungi | piranha: makes perfect sense |
| 16:07 | kungi | piranha: Can't you just read a config.edn in your resources on startup and get your defaults from there? |
| 16:07 | hiredman | https://github.com/sonian/carica |
| 16:07 | piranha | I guess that's an option |
| 16:07 | justin_smith | kenrestivo: OK, I am running it locally and it is hanging |
| 16:08 | kungi | hiredman: Looks interesting |
| 16:09 | piranha | hiredman: seems like what I need |
| 16:09 | justin_smith | kenrestivo: jstack tells me that the app is waiting for the future, and the process thread is waiting on the cat process to exit |
| 16:09 | piranha | thanks |
| 16:13 | piranha | hmhm, I wonder if it's going to be easier to extend carica to read env vars or environ to read from config.edn :) |
| 16:15 | hiredman | https://github.com/sonian/carica#middleware |
| 16:29 | mgaare | piranha: to get it into environ, maybe write a lein plugin in the vein of lein-environ |
| 16:30 | piranha | well, if I want it to be in uberjar, certainly not lein plugin |
| 16:30 | piranha | I think I got it right, just need to test now... will report in few minutes :) |
| 16:31 | mgaare | right on |
| 16:33 | arohner | piranha: kungi: you could use https://github.com/circleci/lein-jarbin and export env vars from a shell script |
| 16:33 | arohner | but I wouldn't recommend that for config |
| 16:34 | kenrestivo | justin_smith: thanks! not sure where to go from here. |
| 16:34 | justin_smith | kenrestivo: I'd say maybe some tracing via tools.trace |
| 16:34 | justin_smith | it's suspicious that the unixprocess for cat is sitting open |
| 16:38 | piranha | http://paste.in.ua/9934/ - ended up with this for having defaults in config.edn and it works fairly well for me |
| 16:38 | piranha | so I guess I'll stick with environ, couldn't figure out how to add environ variables to carica, this seemed easier :) |
| 16:38 | sveri | Hi, I have a web application and every time I refresh it using the tools.namespace function my tests are run, any ideas why that happens? I am using midje for testing, if that is of any help. |
| 16:40 | hiredman | ~midje |
| 16:40 | clojurebot | midje is :( |
| 16:41 | technomancy | midje has some weird ideas about how to structure your code |
| 16:42 | tuft | sveri: i'm not familiar with midje, but you don't have a (run-tests) in any of your namespaces do you? |
| 16:42 | technomancy | did I say weird? I meant wrong. |
| 16:42 | sveri | tuft: no, I only started it from the command line |
| 16:42 | arohner | sveri: midje's tests are expressions, not functions |
| 16:42 | nullptr | technomancy: do you use clojure.test or something else? |
| 16:42 | arohner | sveri: so they'll run every time the code is eval'd |
| 16:42 | technomancy | nullptr: yeah, with difftest |
| 16:42 | technomancy | nullptr: though I guess the thing now is humane-test-output |
| 16:42 | sveri | arohner: well, that explains it |
| 16:43 | arohner | sveri: also, yes, midje is :-( |
| 16:43 | sveri | well, I should ask clojurebot next time before I choose a lib |
| 16:43 | sveri | ~clojure.test |
| 16:43 | clojurebot | No entiendo |
| 16:43 | arohner | yeah :-( |
| 16:43 | arohner | I wrote http://blog.circleci.com/rewriting-your-test-suite-in-clojure-in-24-hours/ |
| 16:44 | arohner | an almost-working version of the source code is on github, but I wouldn't recommend it unless you have > 10k LoC |
| 16:44 | sveri | yea, I see |
| 16:45 | arohner | clojure.test isn't terrible. it isn't great, but it's a decent default |
| 16:45 | technomancy | I'd rather have something slightly primitive than something overachitected |
| 16:45 | sveri | seems like there is more on the road for me :D |
| 16:45 | sveri | thanks every1 |
| 16:45 | technomancy | because at least the primitive thing can be a good foundation to build on |
| 16:46 | bbloom_ | +1 to arohner and technomancy's comments here |
| 16:47 | sveri | technomancy: I agree with you, however, by looking at the github page its not that obvious |
| 16:47 | sveri | which autotest lib do you use? |
| 16:47 | sveri | for clojure.test I mean? |
| 16:48 | technomancy | sveri: I just trigger tests from inside emacs |
| 16:48 | technomancy | it's faster than waiting for autotest to pick them up |
| 16:48 | sveri | ok, next? :D |
| 16:48 | arohner | and works better when you have slow integration tests |
| 16:48 | bbloom_ | and forces you to *think* about what code will be impacted |
| 16:48 | bbloom_ | if you run your full test suite and get a failure in a test you didn't think to run, then you probably have discovered a design flaw in your architecture :-) |
| 16:48 | nullptr | arohner: interesting article, thanks. i see you used core.match, which also gets mixed reviews -- any thoughts on that? |
| 16:49 | arohner | nullptr: it worked in that application. I don't think I've used it since |
| 16:49 | arohner | I think just because I haven't had to solve a prolog problem recently |
| 16:50 | arohner | core.match is slightly strange because it has a lot of macro magic, and it's not all that obvious when you can use a normal expression, or a normal variable |
| 16:51 | amalloy | arohner: i was surprised to read that article: i would have thought half the ponit of using midje is its "provided" mocking, which doesn't translate to clojure.test at all |
| 16:51 | amalloy | ie, for a majority of uses of midje, i would expect your transformation script to be unusable |
| 16:52 | arohner | we had a lot of problems with the several ways to mock midje, so those had already been replaced with https://github.com/circleci/bond |
| 16:53 | arohner | using 'provided' was already a "immediately fails code review" for several months before that translation ran |
| 16:55 | sveri | arohner: hm, why? That was one of the reasons I chose midje |
| 16:56 | amalloy | it's the only reason i can imagine to choose midje. but it sounds like arohner's team decided to stop using midje, and it was a gradual process |
| 16:57 | bbloom_ | amalloy: you really can't imagine that people just like the cute => syntax? |
| 16:57 | arohner | sveri: 1) it was buggy 2) (trying to avoid getting dogmatic testing) the syntax complects mocking and stubbing |
| 16:57 | amalloy | bbloom_: in my model of the universe, everyone likes the same things as i do, so that sounds impossible |
| 16:57 | nullptr | i think bbloom_ is on the right track here |
| 16:57 | arohner | also, => syntax is a bad idea |
| 16:57 | bbloom_ | clearly |
| 16:58 | arohner | it's not lispy, which breaks editors, and several of the translations are ambiguous |
| 16:58 | bbloom_ | can't eval form to test an individual assertion == terrible |
| 16:58 | arohner | in the post I explain one of them, but there are several more |
| 16:58 | bbloom_ | there are problems with clojure.test's is macro too: they create shadow assertion worlds |
| 16:58 | piranha | if I have NPE when trying to run uberjar with java -jar, what do I do to figure out what's wrong? |
| 16:58 | clojurebot | No entiendo |
| 16:58 | bbloom_ | at least the `is macro defaults to just checking a damn boolean |
| 16:58 | bbloom_ | and relegates the shadow world to error reporting |
| 16:59 | piranha | 'lein run' works like a charm, but uberjar throws NPE and I really can't figure out what's wrong there... |
| 16:59 | bbloom_ | i know all about computing booleans, but in midge code, you friggin gotta know some magic alternative syntax |
| 16:59 | piranha | it also fails strangely: http://paste.in.ua/9935/#20:22 |
| 17:01 | piranha | hah, I think I figured it out |
| 17:02 | sveri | ~enlive |
| 17:02 | clojurebot | enlive is for generating HTML from pure-markup templates: http://wiki.github.com/cgrand/enlive/getting-started |
| 17:02 | sveri | Just asking, is enlive suspicious for being a bad guy in a good town too? |
| 17:03 | arohner | sveri: which role do you need? enlive does several things, and there are other options, depending on what you're trying to do |
| 17:03 | arohner | I personally avoid it because the docs used to be bad |
| 17:03 | sveri | I used it for template generation on server side |
| 17:04 | sveri | *use |
| 17:04 | arohner | if it's working and you understand how to use it, it's probably fine |
| 17:04 | sveri | took me some time, but I got used to it |
| 17:08 | schmir | I'm using clojure.jdbc and I'm trying to create the inital tables inside an sqlite database. Therefor I'd like to issue multiple create table statements. but If I run them via a single jdbc/excute! only the first table is created. in python I do have executescript, is there something like that in clojure.jdbc? or am I doing something else wrong? |
| 17:12 | danneu | schmir: i use (jdbc/execute! conn [(slurp "mass-of-sql.sql")]) all the time |
| 17:13 | danneu | schmir: you sure it's not bailing on an error? |
| 17:13 | schmir | danneu: it doesn't throw |
| 17:16 | danneu | schmir: i dont remember the idiosyncrasies of when things are thrown in jdbc. but i recall dealing with silent failure |
| 17:17 | danneu | schmir: https://github.com/danneu/bulletin/blob/master/src/bulletin/db.clj#L345-L348 |
| 17:18 | schmir | danneu: ok. let me test if wrapping my code in (with-db-transaction...) helps. |
| 17:19 | danneu | i dont really remember, but perhaps execute! fails silently when one of the statements in the sql string fails |
| 17:20 | danneu | schmir: i think that's why i had this code: https://github.com/danneu/bulletin/blob/master/src/bulletin/db.clj#L468-L473 - so my "reset-db!" fn prints out the created tables so i could easily see if it failed |
| 17:21 | danneu | pretty sad that i can't remember what was on my mind when i wrote code that's just 1 month old |
| 17:22 | schmir | danneu: :) |
| 17:22 | schmir | thanks for your help |
| 17:23 | danneu | schmir: i hope you figure somethin out. when i look at the jdbc api, a 'right way' never really jumps out at me |
| 17:26 | schmir | danneu: I'm now executing each sql statement one by one |
| 17:31 | danneu | schmir: also nice to have `DROP TABLE IF EXISTS <table> CASCADE;` before your creation sql |
| 17:37 | schmir | danneu: I'm starting with an empty table. |
| 17:37 | schmir | s/table/database/ |
| 17:38 | TimMc | danneu: Yes, I've struggled with this as well -- I don't think JDBC provides a way to say "run this script". :-( |
| 17:38 | TimMc | Much sadness. |
| 17:38 | TimMc | Very split-on-semicolon. |
| 17:43 | schmir | https://stackoverflow.com/questions/10929369/how-to-execute-muliple-sql-statements-from-java says I need to call executeBatch. db-do-commands seems to do that. |
| 17:50 | schmir | TimMc, danneu: jdbc/db-do-commands works with multiple statements. but I have to pass in each statement as a separate string :( |
| 17:52 | tuft | which version of clojure has transducers? |
| 17:53 | gfredericks | 1.7.0 alpha2 or something |
| 17:54 | TimMc | schmir: Lovely. |
| 17:57 | justin_smith | schmir: sounds like a job for apply + line-seq? |
| 17:59 | schmir | justin_smith: line-seq doesn't work. splitting by semicolons may be better (until one adds a semicolon inside a comment). but basically you'd have to implement your own sql parser. |
| 17:59 | justin_smith | schmir: my assumption was acquiscing to one statement per line |
| 17:59 | justin_smith | which may be onerous, sure |
| 18:06 | arrdem | why not just use fnparse and the specification SQL grammar... |
| 18:06 | arrdem | s/fnparse/instaparse/g |
| 18:08 | schmir | arrdem: that's overkill for my 4 create table statements... |
| 18:08 | justin_smith | in that case statement per file? which kind of sucks |
| 18:09 | arrdem | shrug. I'd think that actually using _real_ SQL would be less onerous and more general than imposing artifical constraints on the language just so you can do something "simpler". |
| 18:15 | amalloy | arrdem: remember, worse is better |
| 18:16 | danneu | schmir: there you go. roll a sql parser real quick. |
| 18:16 | dbasch | amalloy arrdem hence JSONx |
| 18:16 | tuft | gfredericks: thanks |
| 18:18 | danneu | schmir: since you're using clojure, you're probably retired and just rewriting your personal blog. |
| 18:18 | schmir | danneu: I'll have to finish my rosi sql parser first... |
| 18:18 | schmir | actually I'm getting paid to write clojure |
| 18:19 | schmir | (and read rosi sql...which is pretty terrible) http://www.99-bottles-of-beer.net/language-rosi-sql-1140.html |
| 18:22 | danneu | schmir: but honestly, if splitting on semicolon isn't good enough because of sql comments, then maybe the next simplest thing is to str/replace "/(--.+)\n/g" with "" before splitting on ; |
| 18:23 | danneu | though sometimes it's nice to leave gifts for your future self and let things break in a weird way |
| 18:23 | clojurebot | Cool story bro. |
| 18:24 | bostonaholic | lol clojurebot |
| 18:24 | schmir | danneu: :) |
| 18:25 | amalloy | huh. clojure.sourceforge.net redirects to clojure.org. i didn't know it used to be on sourceforge |
| 18:26 | technomancy | I thought you were an old-timer =) |
| 18:27 | hiredman | I dunno, was it ever in source forge? I mean, it was in google code |
| 18:28 | justin_smith | could be that clojure.sourceforge.net redirects for the same reason that george-w-bush.i.am does |
| 18:29 | amalloy | that doesn't even resolve :( |
| 18:30 | {blake} | I come across this pattern a lot: I have a map, and I want to fn[val] each map-entry and return a new map with the original keys mapped to the results of fn[val]. |
| 18:31 | arrdem | {blake}: flatland|amalloy/useful update-vals |
| 18:31 | {blake} | I want to do it this way: "map #({(key %)(fnx[val %)}) my-map" |
| 18:31 | justin_smith | amalloy_: huh, it did the other day - used to be *.i.am went to will.i.am |
| 18:33 | {blake} | arrdem, OK, so I'm not missing something elegant that's inherent to Clojure's built-ins. |
| 18:33 | arrdem | {blake}: sadly you are not |
| 18:33 | arrdem | {blake}: however given the number of different people who have re-invented that function... |
| 18:33 | {blake} | arrdem, Seems like there should be something, no? Like.... |
| 18:33 | {blake} | Hell, I don't know. =P |
| 18:34 | {blake} | I'll crib from amalloy_ (once again). |
| 18:34 | arrdem | this is the age-old debate over whether a language should be a kernel with libraries that make it usable or whether it should include the kitchen sink.. |
| 18:35 | {blake} | Is it? Maybe so. One gets used to having tremendous power in unexpected places in Clojure. Something obvious and simple--it's shocking for it to be missing! |
| 18:35 | justin_smith | any classy language should include a water fountain, a gromet factory, and a bidet |
| 18:35 | technomancy | this isn't exactly kitchen sink |
| 18:36 | arrdem | technomancy: but it can be written in terms of other language primitives, so neither is it fundimental. arguably. |
| 18:36 | technomancy | arrdem: clojure explicitly reject's scheme's fundamentalism |
| 18:37 | weavejester | Out of interest, what is this not-primitive, not-kitchen-sink? |
| 18:37 | technomancy | but yeah, I agree |
| 18:37 | {blake} | weavejester, Creating a new map from values of an old one, such that "key->value" in the old map becomes "key->(fn value)". |
| 18:38 | weavejester | {blake}: Oh, like a map-vals |
| 18:39 | weavejester | I’m kinda of the opinion there should be one, if not in Clojure core than in a separate clojure.* namespace |
| 18:39 | weavejester | It’s not trivial to write efficiently. |
| 18:39 | weavejester | Or it takes 5 lines or so |
| 18:40 | weavejester | Because where possible, you want to use transients, but some map types can’t be converted to transients |
| 18:40 | weavejester | And reduce-kv is more efficient than just into {} |
| 18:40 | {blake} | It just felt like something that could be done with a zipmap. |
| 18:41 | weavejester | {blake}: keys and vals aren’t guaranteed to be ordered the same |
| 18:41 | {blake} | weavejester, Well, I always have that suspicion, which is why I never use zipmap. But it must work sometimes. =P |
| 18:42 | weavejester | {blake}: Sure, it works, IIRC, but only due to implementation details |
| 18:42 | weavejester | To do it right you want something like: https://github.com/weavejester/medley/blob/master/src/medley/core.cljx#L49 |
| 18:43 | weavejester | And even that’s wrong for any non-hash non-array maps |
| 18:43 | Bronsa | weavejester: keys and vals are guaranteed to be ordered consistently |
| 18:43 | Bronsa | ,(doc keys) |
| 18:43 | clojurebot | "([map]); Returns a sequence of the map's keys, in the same order as (seq map)." |
| 18:43 | weavejester | I need to add in some additional conditions. I think one of the other utility libraries has a slightly more comprehensive version |
| 18:43 | Bronsa | ,(doc vals) |
| 18:43 | clojurebot | "([map]); Returns a sequence of the map's values, in the same order as (seq map)." |
| 18:44 | weavejester | Ohh |
| 18:44 | weavejester | It never used to be |
| 18:44 | Bronsa | weavejester: it's a recent addition to the docstrings |
| 18:44 | weavejester | I guess they changed it from “implementation detail” to “defined behavior” |
| 18:46 | Bronsa | I'm still not 100% satisfied with that docstring though. What if `seq` is implemented in such a way that its ordering might change between invocations? |
| 18:47 | weavejester | Bronsa: Yeah, it implies (seq map) is consistent, but… |
| 18:47 | ewingd | I'm trying to learn clojure and am working my way through some of the problems on hackerrank. Is anyone willing to help me figure out a NullPointerException I'm getting while compiling? |
| 18:48 | weavejester | ewingd: No promises, but post the code and I’ll take a look :) |
| 18:48 | dbasch | ewingd: paste a gist / pastebin / refheap |
| 18:48 | ewingd | https://gist.github.com/ewingd/f71cf27b90bd231d179b |
| 18:48 | ewingd | thanks |
| 18:48 | weavejester | Like a seq, I reserve the right to be lazy |
| 18:48 | TimMc | (realized? weavejester) |
| 18:49 | weavejester | #<weavejester: pending> |
| 18:49 | weavejester | Wait |
| 18:49 | weavejester | false |
| 18:49 | weavejester | :) |
| 18:50 | weavejester | ewingd: So, you might want to format the code in a more standard way… And there’s a def in a doseq there… |
| 18:50 | arrdem | &(Long. 0xFFF5) |
| 18:50 | gfredericks | ,0xFFF5 |
| 18:50 | clojurebot | 65525 |
| 18:50 | weavejester | ewingd: Though those aren’t a NPE |
| 18:50 | gfredericks | ,(Long. 0xFFF5) |
| 18:50 | clojurebot | 65525 |
| 18:51 | ewingd | When I run the code I get the correct output, but the first test run gets the NPE thrown. The rest all pass |
| 18:52 | hiredman | def defines a top level name, clojure is not like scheme |
| 18:52 | weavejester | ewingd: The first test run? |
| 18:53 | weavejester | ewingd: Like clojure.test? |
| 18:53 | ewingd | weavejester: the test cases that hackerrank.com runs on the submitted code |
| 18:54 | weavejester | ewingd: Do you have a link to the question? |
| 18:54 | ewingd | weavejester: https://www.hackerrank.com/challenges/service-lane |
| 18:54 | weavejester | ewingd: If the wrong data is put in, any part of it could be nil potentially. |
| 18:58 | weavejester | ewingd: You’ve mixed up N & T in the test case, which might be the problem |
| 19:00 | weavejester | The definition of this problem is really hard to read |
| 19:00 | ewingd | weavejester: Yes it is. |
| 19:01 | myguidingstar | hi all, I have a noob question |
| 19:01 | myguidingstar | can tranducers be used to alternate all reducers? if yes, is it recommended to do so? |
| 19:03 | weavejester | myguidingstar: At the risk of being wrong, I believe transducers cover the functionality of reducers. It’s a more general abstraction. |
| 19:04 | weavejester | That said, I haven’t played around with them much |
| 19:04 | weavejester | ewingd: Okay, I think I see what the question is asking for now |
| 19:05 | weavejester | Find the minimum value between two indexes of an array |
| 19:05 | ewingd | yes, which is exactly what I am attempting to do in that solution |
| 19:06 | weavejester | ewingd: I think your problem is that the first line is “N T”, and you run (read-string “N T”) which gets you N |
| 19:07 | myguidingstar | weavejester, I 'feel' the same, and my current guess is that traducers are a re-design of reducers |
| 19:07 | weavejester | You then use N in place of T to get the number of tests |
| 19:08 | ewingd | weavejester: thanks, I'll give that a try. Is there a better approach I can take to reading the test case input lines? |
| 19:09 | weavejester | ewingd: Yeah, so, a few pointers. First, formatting - it really helps to format your code in the normal way. Makes reading it a lot easier. So that means vars-with-hyphenated-names, and no lone parentheses on their own lines. |
| 19:10 | weavejester | ewingd: It might sound trivial, but programs are written once, read many times. Readability is super important. |
| 19:10 | ewingd | weavejester: I completely understand. I just haven't seen examples of normal code yet |
| 19:11 | weavejester | ewingd: Second, Clojure is a functional language, and while it doesn’t strictly enforce it, you’re encouraged to separate out the stuff that handles I/O and side effects from the functional parts of your code. |
| 19:12 | weavejester | ewingd: Give me a minute and I’ll put together an example of code |
| 19:13 | ewingd | weavejester: Thanks, I was just about to ask for one. |
| 19:13 | dnolen_ | myguidingstar: not sure what you are saying |
| 19:13 | dnolen_ | cfleming: macroexpand can't come soon enough :) |
| 19:14 | cfleming | dnolen_: Hehe, ok, I'll get on it. |
| 19:14 | cfleming | dnolen_: I'm working on some formatting problems right now which will make pretty printing expansions much nicer. |
| 19:15 | dnolen_ | cfleming: nice, thanks for the indenting flag btw, it's great |
| 19:16 | cfleming | dnolen_: Yeah, people had been asking for that for a while, I'm embarassed to admit how long it took to implement in the end. |
| 19:16 | myguidingstar | dnolen_, are transducers the new, 'better' reducers? |
| 19:17 | amalloy | myguidingstar: broadly, yes |
| 19:18 | myguidingstar | so is it recommended that one should start with transducers instead of reducers? |
| 19:18 | amalloy | yes. don't bother with reducers; they haven't seen any major changes since their original introduction, and not much use since then either |
| 19:18 | myguidingstar | okay, thanks lot |
| 19:19 | nkozo | amalloy: transducers totally replaces reducers? |
| 19:20 | nkozo | I mean, using transducers you can do everything you can do with reducers? I must study both yet :) |
| 19:20 | dnolen_ | nkozo: more or less - you can use transducers w/ parallel fold anyway - so you're not missing out on anything |
| 19:20 | nkozo | great |
| 19:20 | amalloy | nkozo: to the best of my knowledge that's true. certainly in theory; in practice there may be a function or two left to implement, i dunno |
| 19:21 | amalloy | but transducers are a more general concept; reducers are a special case of transducers, so to speak |
| 19:25 | weavejester | ewingd: Take a look at: https://gist.github.com/weavejester/040fa26b7fc1918f9144 |
| 19:25 | weavejester | ewingd: I’ve tried to minimise new concepts in that gist |
| 19:26 | ewingd | weavejester: Thanks |
| 19:29 | weavejester | ewingd: And this is the same code, just written with some more advanced features of the language: https://gist.github.com/weavejester/040fa26b7fc1918f9144 |
| 19:30 | weavejester | ewingd: But the basic idea is: read everything in first, get the input out of the way. Then when you just have data, you can work on it with pure functions. Finally, when you have your data, handle the output. |
| 19:30 | ewingd | weavejester: Thank you for all the effort you have put into this. It's a little overwhelming coming to a functional language from PHP and Python |
| 19:31 | weavejester | ewingd: It definitely is. |
| 19:32 | weavejester | ewingd: The idea with functional languages is to try and silo side effectful code. So we get our hands dirty with I/O, then transition to using pure functions where the bulk of the logic usually happens. |
| 19:35 | ewingd | weavejester: Sounds good. I'm sure I'm going to have enough to keep me busy for a while with those samples |
| 20:09 | arnaudsj | Hi, silly question about interop with Scala. Any ideas why I see this kind of options in the repl when trying to autocomplete the Scala function TwitterUtils/createStream => TwitterUtils/createStream TwitterUtils/createStream$default$3 TwitterUtils/createStream$default$4 |
| 20:10 | justin_smith | arnaudsj: that's how inner classes are specified in clojure interop |
| 20:10 | arnaudsj | In Scala the function has different arities by in Clojure it seems to only show one, with default values for argument 3 and 4 - any ideas? |
| 20:11 | arrdem | arnaudsj: it looks like Scala is generating a different class for each arity of the function. |
| 20:12 | arnaudsj | arrdem: that's what I thought, but then I get this in the REPL |
| 20:12 | arnaudsj | => (TwitterUtils/createStream$default$3) |
| 20:12 | arnaudsj | #<Nil$ List()> |
| 20:13 | arnaudsj | which seems to match only this first definition: https://github.com/apache/spark/blob/master/external/twitter/src/main/scala/org/apache/spark/streaming/twitter/TwitterUtils.scala#L38-L45 |
| 20:14 | arrdem | arnaudsj: I suspect you're hitting line 82 not 38 |
| 20:16 | ed-g | Hello. I'm using core.async in cljs, and I don't understand what arguments to pass to alts!, or what exactly it evaluates to. I'm familiar with select() from POSIX, and I've read Rich's examples but they're too advanced for me. |
| 20:16 | arnaudsj | https://www.irccloud.com/pastebin/1b2nzcFi |
| 20:17 | arnaudsj | I think in this case it is line 55 |
| 20:17 | ed-g | Is there a basic tutorial out there somewhere? (not the one in core.async/examples git) |
| 20:17 | arrdem | arnaudsj: looks right to me. |
| 20:17 | arrdem | arnaudsj: single line pastes like that are OK in channel |
| 20:18 | arnaudsj | arrdem: my question is how I can verify it is hitting the right function / arity because I want to pass a second arg (filters) |
| 20:18 | bbloom_ | ed-g: generally, you want to use alt! which is macro sugar over alts! |
| 20:18 | bbloom_ | ed-g: you only need to use alts! when you have a dynamic set of channels to read from, which is reasonably rarae |
| 20:18 | bbloom_ | rare* |
| 20:18 | arrdem | arnaudsj: you should be able to hit that same static method with different arities and have it behave. |
| 20:19 | arrdem | arnaudsj: you could always take the disassembler to the bytecode and verify what it does by hand :P |
| 20:19 | arnaudsj | because passing a second args does not seem to do the trick: |
| 20:19 | arnaudsj | => (TwitterUtils/createStream sc ["test"]) |
| 20:19 | arnaudsj | IllegalArgumentException No matching method found: createStream clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:80) |
| 20:19 | ed-g | bbloom_: thanks! yes I do have dynamic channels but I am merging them using mix / admix |
| 20:19 | arnaudsj | arrdem: because in this last case I would expect those lines to be hit: https://github.com/apache/spark/blob/master/external/twitter/src/main/scala/org/apache/spark/streaming/twitter/TwitterUtils.scala#L68-L70 |
| 20:19 | arrdem | arnaudsj: is that a "raw" Java array or is that a Scala "Array" class? |
| 20:20 | arrdem | arnaudsj: because that looks like a type missmatch error to me |
| 20:20 | arrdem | brb FPGA build done debugging |
| 20:20 | bbloom_ | ed-g: the alt! macro doc string may help https://github.com/clojure/core.async/blob/48bf181cd194a182ec303611bdfa2e54f86f3743/src/main/clojure/clojure/core/async.clj#L326-L353 |
| 20:21 | arnaudsj | arrdem: well that's the part I am a little bit fuzzy here. How do I cast the argument as a Java array or Scala array? |
| 20:21 | TEttinger | scala's Array IIRC is a class, not a primitive. Java's is a primitive |
| 20:22 | arrdem | arnaudsj: http://grimoire.arrdem.com/1.6.0/clojure.core/to-array |
| 20:22 | arrdem | arnaudsj: no idea about making a Scala array out of it sorry |
| 20:23 | TEttinger | also, http://grimoire.arrdem.com/1.6.0/clojure.core/make-array/ |
| 20:24 | justin_smith | arnaudsj: into-array if the array needs any type other than Object |
| 20:24 | TEttinger | Scala Array should just involve a constructor... |
| 20:24 | arnaudsj | arrdem: this seems to work |
| 20:24 | arnaudsj | (TwitterUtils/createStream sc (into-array ["test"])) |
| 20:24 | TEttinger | nice, arnaudsj! |
| 20:24 | arrdem | arnaudsj: yeah that was my guess |
| 20:24 | TEttinger | (inc justin_smith) |
| 20:24 | TEttinger | (inc arrdem) |
| 20:24 | TEttinger | aw, lazybot is down |
| 20:25 | arrdem | T_T THE KARMA NOOOOOO |
| 20:25 | arrdem | :P |
| 20:25 | TEttinger | Raynes ping |
| 20:25 | arnaudsj | arrdem: thank you! There is much I still need to learn about Clojure Java/Scala Interop. |
| 20:25 | arnaudsj | TEttinger: thank you! |
| 20:25 | TEttinger | clojure java interop is... easier |
| 20:25 | TEttinger | no prob! |
| 20:25 | arrdem | arnaudsj: I'm like 80% scala interop from Java isn't generally possible |
| 20:25 | ed-g | bbloom_: I'm reading it now, it just isn't clear to me what operation the example (alt! [c t] ([val ch] (foo ch val)) ... ) accomplishes. In particular, what is the difference between a chan and a port, and is the val the result of TAKE from one of the channels? |
| 20:25 | arrdem | but Clojure/Java interop is gr8 |
| 20:26 | arrdem | Java/Clojure interop.... is improving |
| 20:26 | TEttinger | (inc justin_smith) |
| 20:26 | TEttinger | (inc arrdem) |
| 20:26 | arnaudsj | arrdem: yes, I have done a few project and I had no problems with Clojure/Java interop, but with Apache Spark, which is a mix Scala/Java it is a little bit more challenging ;) |
| 20:26 | bbloom_ | ed-g: a port is either the read end or write end of a channel. that feature seems to not have been finished, but it doesn't matter b/c a channel counts as a port for both ends of that channel |
| 20:27 | lazybot | ⇒ 93 |
| 20:27 | lazybot | ⇒ 37 |
| 20:27 | TEttinger | how is arrdem's karma not higher? you make grimoire! |
| 20:27 | arrdem | this is an open question :P |
| 20:27 | TEttinger | $karma TEttinger |
| 20:27 | lazybot | TEttinger has karma 25. |
| 20:28 | bbloom_ | ed-g: so as for that particular example, the square brackets of the [c t] is a vector, and teh docs say: " a vector of ports as per alts!" so let's head over to that doc string |
| 20:28 | arrdem | I think the real answer is that I tend to answer low hanging fruit questions from newbies who don't know how to inc ;P |
| 20:28 | TEttinger | same here |
| 20:28 | ed-g | bbloom_: gotcha. And it looks like I can tell which channel was selected since it can be bound to within each expression. |
| 20:28 | TEttinger | since that's all I can answer, no core.async or macro answers for me |
| 20:28 | bbloom_ | ed-g: from the alts! doc string: " ports is a vector of channel endpoints, which can be either a channel to take from or a vector of [channel-to-put-to val-to-put], in any combination." |
| 20:28 | arrdem | clearly we need to patch lazybot to detect "thanks!?" messages and auto-inc |
| 20:29 | bbloom_ | so that [c t] is a vector of two channels to take from |
| 20:29 | TEttinger | I just added a feature to my lazybot fork that augments its quotegrabs |
| 20:29 | TEttinger | you can now get all quotes by a nick dumped to pastebin |
| 20:29 | arrdem | o nice! |
| 20:30 | bbloom_ | ed-g: and the [[out val]] example is a vector of "puts", where a put is just a two-item vector of channel and value to put. so [x y [[z 123]]] says take from channel x or take from channel y, or put 123 on channel z |
| 20:30 | TEttinger | mostly the quotes are grabbed when someone says something terrible, but one guy says some great stuff https://www.refheap.com/91824 |
| 20:30 | bbloom_ | ed-g: if you it's just a raw symbol without any vector brackets, it's the same as a single item vector put |
| 20:31 | bbloom_ | ed-g: got it? |
| 20:31 | arrdem | TEttinger: ..... |
| 20:31 | arrdem | TEttinger: this is hillarious. thank you. |
| 20:31 | verma | would it be ok if I use clojure logo on my presentation? |
| 20:31 | TEttinger | verma: I think it's CC-licensed |
| 20:32 | verma | ah nice TEttinger, thanks |
| 20:32 | ed-g | bbloom_: okay this is starting to make sense. It's a nice terse syntax. I really appreciate the help. |
| 20:32 | verma | (inc TEttinger) |
| 20:32 | lazybot | ⇒ 26 |
| 20:32 | TEttinger | I'll check the wiki, verma |
| 20:34 | bbloom_ | ed-g: frankly, i think the syntax is a tad too terse, but the documentation is pretty clear after you see a couple examples |
| 20:35 | TEttinger | wikipedia seems to think it's public domain, verma https://commons.wikimedia.org/wiki/File:Clojure-icon.gif |
| 20:35 | technomancy | it's not public domain |
| 20:35 | TEttinger | I was wondering |
| 20:35 | technomancy | but you're probably fine as long as you're not using it for your own product |
| 20:35 | TEttinger | yeah |
| 20:35 | arrdem | Thinking of which. Grimoire 0.3.10 is getting close to ready. Feature requests/ideas welcome. |
| 20:35 | technomancy | (like a consulting course or a user group) |
| 20:36 | ed-g | bbloom_: yes with examples it's not too bad. I just wasn't finding well-documented examples with my web searches, other than that from the docstring. |
| 20:36 | TEttinger | is it's a talk about clojure, then it would make sense to use the appropriate logo. using something like a swastika to represent clojure's logo would not be appropriate |
| 20:36 | verma | TEttinger, lol |
| 20:37 | verma | thanks technomancy, TEttinger |
| 20:37 | verma | I am using it for a community meetup presentation |
| 20:37 | verma | or planning to rather |
| 20:37 | justin_smith | arrdem: I go for low hanging fruit questions all the time too. I think I just waste more time on IRC than you do |
| 20:37 | TEttinger | no prob then |
| 20:37 | arrdem | justin_smith: or something |
| 20:37 | TEttinger | you might also want to grab the typed clojure logo, verma |
| 20:37 | TEttinger | just in case for later |
| 20:38 | verma | what is that? |
| 20:38 | TEttinger | http://typedclojure.org/images/typed-clojure-an-optional-type-system-letterbox.png http://typedclojure.org/ |
| 20:39 | numberten | is there a way to specify that 'lein test' ignore an entire file? |
| 20:39 | technomancy | numberten: yeah, check out test selectors |
| 20:39 | numberten | thanks :) |
| 20:43 | arnaudsj | https://www.irccloud.com/pastebin/cyhmYtLK |
| 20:44 | justin_smith | lein has some catching up to do http://thespacereporter.com/2014/10/maven-orbiter-finds-hydrogen-layer-that-spreads-21000-miles-from-mars/ |
| 20:44 | arnaudsj | This is in reference to: http://twitter4j.org/javadoc/twitter4j/FilterQuery.html |
| 20:44 | arnaudsj | brb |
| 20:45 | justin_smith | arnaudsj: there is no actual constructer that is just a number, which constructor are you trying to use? |
| 20:46 | justin_smith | it tried the only one-arg constructor, which takes an array of long (that is what caused the error message you see) |
| 20:46 | arnaudsj | justin_smith: just passing a long, which should default to the follow param if I look at the definition |
| 20:46 | verma | TEttinger, thanks! will do |
| 20:46 | justin_smith | arnaudsj: there is no such constructor |
| 20:47 | justin_smith | long[] follow means array of long |
| 20:47 | arnaudsj | FilterQuery(long[] follow)? |
| 20:47 | justin_smith | right, that means array |
| 20:47 | arnaudsj | ok my bad |
| 20:47 | TEttinger | verma: a possible big advantage of typed clojure is in teaching newbies (because it gives better error messages), especially clojure newbies who are used to statically typed languages already. |
| 20:47 | justin_smith | (FilterQuery. (into-array Long [123123])) |
| 20:49 | ed-g | well that code managed to lock up my browser |
| 20:53 | ed-g | is it okay to run (go (loop [] (alt! ...) (recur)) in a browser or is that a guaranteed denial of service? I was hoping the thread of control would return to the browser when cljs was stopped on the channels but maybe not. |
| 20:54 | bbloom_ | ed-g: the thread of control is returned to the browser, but if you write a truly blocking loop w/o any waiting channel ops in it, it will loop for ever and the browser is still cooperatively threaded |
| 20:54 | arnaudsj | justin_smith: hmmm, still no go => (FilterQuery. (into-array Long [123123])) |
| 20:54 | arnaudsj | ClassCastException [Ljava.lang.Long; cannot be cast to [J |
| 20:54 | bbloom_ | ed-g: is your alt! writing to any sliding or dropping channels? or is there a :defualt clause? |
| 20:54 | ed-g | bbloom_: gotcha |
| 20:55 | bbloom_ | ed-g: chances are you're just writing repeatedly forever in to some place that won't ever block |
| 20:55 | bbloom_ | ed-g: what's in your alt? |
| 20:55 | ed-g | bbloom_: I am only reading from channels ( cljs-http get operations) but they are also merged in an mix which may change things |
| 20:55 | TEttinger | ,(into-array long [123123]) |
| 20:55 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.core$long cannot be cast to java.lang.Class> |
| 20:56 | ed-g | bbloom_: large. is there a pastebin for this channel? |
| 20:56 | TEttinger | ,(long-array [123123]) |
| 20:56 | clojurebot | #<long[] [J@e5e57b> |
| 20:56 | bbloom_ | ~paste |
| 20:56 | clojurebot | paste is https://refheap.com/ |
| 20:57 | TEttinger | arnaudsj: [J is a primitive array of longs. [Ljava.lang.Long; is the JVM internal code for an array of objects, not primitives, of class java.lang.Long |
| 20:58 | arnaudsj | TEttinger: thank you, I needed to understand the difference between (into-array [123]) and (long-array [123]) |
| 20:58 | TEttinger | arrays are a little black-magic in clojure. there are some good guide out there |
| 21:00 | ed-g | alt! block https://www.refheap.com/91826 |
| 21:01 | TEttinger | http://www.learningclojure.com/2010/09/macros-and-type-hints-metadata-and.html arnaudsj |
| 21:01 | TEttinger | also, arnaudsj: http://asymmetrical-view.com/2009/07/02/clojure-primitive-arrays.html |
| 21:04 | arrdem | TEttinger: Grimoire takes PRs (and soon articles) for community docstrings :P |
| 21:05 | TEttinger | arrdem: what was that in reference to? |
| 21:06 | arrdem | TEttinger: you just dug up a bunch of crap about arrays that could go in the notes while someone here still remembers it |
| 21:06 | TEttinger | oh ok |
| 21:06 | TEttinger | uh, should I fork grimoire? |
| 21:07 | TEttinger | seems a bit convoluted |
| 21:07 | arrdem | TEttinger: just go to into-array's page and click the "edit" link on the community docstring :P |
| 21:07 | TEttinger | oh phew |
| 21:07 | arrdem | TEttinger: that does all the forking/merging crap for you. |
| 21:09 | arrdem | oh balls I totally broke my edit links |
| 21:09 | arrdem | whelp |
| 21:10 | TEttinger | edit link 404s yeah |
| 21:10 | arrdem | guess I'm rushing out a half baked 0.3.10 tonight then |
| 21:10 | arrdem | TEttinger: https://github.com/clojure-grimoire/grimoire/edit/develop/resources/store/org.clojure/clojure/1.6.0/clojure.core/into-array/extended-docstring.md |
| 21:11 | TEttinger | You need to fork this repository to propose changes. |
| 21:11 | TEttinger | I need to eat dinner to propose changes. |
| 21:11 | arrdem | lol |
| 21:16 | ed-g | okay what's happening is that the stops-data-chan gives data from my page once using cljs-http.client/get, then it gives me an infinite number of nil's. |
| 21:19 | nullptr | ed-g: this looks a bit suspicious (def stops-data-chan (http/get stops-url {:channel stops-data-chan})) |
| 21:21 | ed-g | nullptr: it does, doesn't it? I'll rewrite as a let and without self-reference |
| 21:23 | bbloom_ | ed-g: a nil means the channel is closed |
| 21:23 | ed-g | bbloom_: I've heard that, but why then is it still returning data in alt! ? |
| 21:24 | bbloom_ | ed-g: it's not returning data, it's reported that it's closed |
| 21:25 | TEttinger | arrdem: do I need to fork the repo? |
| 21:25 | ed-g | bbloom_: oops I should rephrase that. why is alt! executing blocks for closed channels? |
| 21:25 | bbloom_ | ed-g: it does exactly the same thing as trying to read from a closed channel outside of an alt! |
| 21:26 | bbloom_ | ed-g: there's no other way to tell if a channel is closed other than to attempt to read from it and to get a nil |
| 21:28 | ed-g | bbloom_: so I should be careful never to close channels which may be read in a loop? or is there some way to detect if all channels being selected upon in an alt! block have been closed in which case I can exit my loop? |
| 21:29 | bbloom_ | ed-g: you can just exit the loop if one of your inputs has been closed... |
| 21:29 | bbloom_ | ed-g: you can detect that by examining the value that was given to you |
| 21:29 | bbloom_ | ed-g: if it's nil, the channel was closed, and now your alt! is no longer sensible to re-enter |
| 21:29 | bbloom_ | if you use alts! and had a dynamic set of channels, you could remove the closed channel from the set, but that's almost always not necessary |
| 21:29 | ed-g | bbloom_: okay that makes sense. What if I want to read data from all the channels until they are all closed? I think I'm still stuck in a posix select() mentality. |
| 21:30 | bbloom_ | it really depends on your use case |
| 21:30 | nullptr | in the one you presented, you could have separate go blocks to avoid having to maintain a dynamic list of non-closed chans |
| 21:31 | bbloom_ | ed-g: but you can just use the merge function |
| 21:31 | bbloom_ | ed-g: https://github.com/clojure/core.async/blob/master/src/main/clojure/cljs/core/async.cljs#L674 |
| 21:31 | ed-g | nullptr: oh that would be great! I didn't know that was possible. |
| 21:32 | bbloom_ | ed-g: you do know you don't need to use alt! to read from a channel, right? |
| 21:32 | bbloom_ | ed-g: the two major differences between a typical unix select loop and core.async usages are 1) first class channels and 2) threads are cheap |
| 21:32 | ed-g | bbloom_: I had considered using merge but didn't want to tag each result with it's type. although that might be a more flexible way to go. |
| 21:33 | bbloom_ | ed-g: what do you mean tag results? |
| 21:33 | bbloom_ | ed-g: you want to know what channels they came from? |
| 21:33 | bbloom_ | just map over the channels to "tag" them: https://github.com/clojure/core.async/blob/master/src/main/clojure/cljs/core/async.cljs#L638 |
| 21:33 | bbloom_ | then merge the mapped channels |
| 21:33 | bbloom_ | you gotta start thinking higher level than C :-) |
| 21:34 | nullptr | map without transducers?! what is this, early 2014? |
| 21:35 | ed-g | bbloom_: yes I need to know the source channel, since results from various JSON url's are handled differently. |
| 21:35 | nullptr | i think separate go loops will make this much simpler for your use case |
| 21:35 | bbloom_ | ed-g: yeah, you can trivially make multiple go loops |
| 21:36 | bbloom_ | ed-g: you may also want to watch Rob Pike's talk about Go: https://talks.golang.org/2012/concurrency.slide#1 |
| 21:36 | ed-g | nullptr: it certainly looks like it would be much easier. I assumed that was not available in javascript since it was single threaded. |
| 21:36 | bbloom_ | ed-g: and part 2 http://blog.golang.org/advanced-go-concurrency-patterns |
| 21:36 | bbloom_ | ed-g: half the entire point of core.async is to give you multiple threads of control cheaply |
| 21:36 | nullptr | ed-g: yes, it does feel a bit weird but you'll get used to it |
| 21:36 | ed-g | bbloom_: cool, that would be a great starting place. |
| 21:36 | bbloom_ | ed-g: you can easily have thousands of running go loops |
| 21:37 | ed-g | bbloom_: I gathered that, but I assumed all loops had to be running lexically under one go macro. |
| 21:38 | bbloom_ | ed-g: no, all of the puts and takes have to be lexically within any go macro |
| 21:38 | ed-g | okay time to do some homework. |
| 21:38 | ed-g | (inc bbloom_) |
| 21:38 | lazybot | ⇒ 2 |
| 21:38 | bbloom_ | ed-g: each go creates a new thread of control |
| 21:38 | ed-g | (inc nullptr ) |
| 21:38 | lazybot | ⇒ 1 |
| 21:38 | bbloom_ | aw, can i get my inc over at bbloom without the udnerscore? :-) |
| 21:38 | ed-g | (inc bbloom) |
| 21:38 | lazybot | ⇒ 46 |
| 21:39 | bbloom_ | cheers, good luck |
| 21:42 | amalloy | (dec bbloom_) ; can't have counterfeit karma floating around |
| 21:42 | lazybot | ⇒ 1 |
| 21:42 | bbloom_ | (inc amalloy_) |
| 21:42 | lazybot | ⇒ 1 |
| 21:42 | bbloom_ | (inc amalloy_) |
| 21:42 | lazybot | ⇒ 2 |
| 21:42 | bbloom_ | $karma bbloom_ |
| 21:42 | lazybot | bbloom_ has karma 1. |
| 21:42 | bbloom_ | $karma bbloom____ |
| 21:42 | lazybot | bbloom____ has karma 0. |
| 21:42 | bbloom_ | amalloy: i'm still up 1 |
| 21:54 | TimMc | (inc _______) |
| 21:54 | lazybot | ⇒ 1 |
| 21:59 | arrdem | TEttinger: if you have to fork then I've got the workflow wrong |
| 22:00 | arrdem | TEttinger: in the past you've just been able to click the "edit" link and go |
| 22:00 | arrdem | TEttinger: it's not a huge surprise that stuff is broken... major internal transitions are underway |
| 22:00 | TEttinger | heh, ok |
| 22:00 | arrdem | but nonetheless it should be fixed. |
| 22:00 | arrdem | /should get fixed |
| 22:01 | arrdem | the intent is that this is a zero fork workflow. if I can't get that working then I'll be abandoning the current data representation |
| 22:02 | TEttinger | D: |
| 22:09 | Bruce_Wayne | hey guys |
| 22:09 | Bruce_Wayne | anyone know datomic? |
| 22:09 | bbloom_ | ~ask |
| 22:09 | clojurebot | The Ask To Ask protocol wastes more bandwidth than any version of the Ask protocol, so just ask your question. |
| 22:10 | Bruce_Wayne | how do you write: {:db/id #db/id[:db.part/user] |
| 22:10 | Bruce_Wayne | without the # |
| 22:11 | arrdem | &(/ 1300 0.78) |
| 22:11 | lazybot | ⇒ 1666.6666666666665 |
| 22:13 | Bruce_Wayne | so no datomic knowledge out there? |
| 22:14 | arrdem | #clojure is not paid support, no |
| 22:14 | bbloom_ | Bruce_Wayne: why can't you use the tagged literal? (that's what that # thing is called in that context) |
| 22:15 | bbloom_ | Bruce_Wayne: and i think this is the fn you want: http://docs.datomic.com/clojure/index.html#datomic.api/tempid |
| 22:15 | Bruce_Wayne | aparently No reader function for tag db/id |
| 22:16 | bbloom_ | Bruce_Wayne: well you should have told us the error message you were getting, b/c lots of folks can help w/ that w/o datomic knowledge |
| 22:16 | Bruce_Wayne | basically clojure is saying how do you read that in a map |
| 22:16 | bbloom_ | you don't need the tempid function |
| 22:16 | Bruce_Wayne | what do I need |
| 22:16 | Bruce_Wayne | ? |
| 22:17 | bbloom_ | Bruce_Wayne: a quick google suggests that the tempid function is recommended: https://github.com/Datomic/day-of-datomic/blob/master/samples/literals_vs_code.clj |
| 22:17 | bbloom_ | and the same search results yield https://groups.google.com/forum/#!topic/datomic/Fi7iXps2npw |
| 22:59 | cddr | What's the best approach for depending on home brew libraries that aren't yet ready to push to clojars? I know about lein local-install but is there anything else I should know about? |
| 23:24 | justin_smith | cddr: lein install |
| 23:24 | justin_smith | maybe that's what you meant by local-install |
| 23:29 | dopamean_ | i was in here the other day asking about what to do for a situation in a library im writing where there is a failed http request made using clj-http |
| 23:29 | dopamean_ | and i said originally that since my function returns a map if successful i wanted to return some sort of failure map |
| 23:29 | dopamean_ | but was discouraged from doing that and i dont recall why. can someone explain why that is a less than attractive option? |
| 23:31 | justin_smith | what does clj-http return on failure? |
| 23:32 | pw_ | (defprotocol IFoo (foo [this & args])) doesn't work, does defprotocol support fn-like destructuring? |
| 23:32 | arrdem | pw_: no |
| 23:32 | pw_ | arrdem: ok, thanks |
| 23:32 | jeremyheiler | dopamean_: it's throwing an exception, right? |
| 23:33 | dopamean_ | currently thats what i have it doing. i use try to make the request and then catch the exception and throw my own if ther eis a problem |
| 23:33 | dopamean_ | which doesnt work all the time because its possible to get a 200 response but with nothing in the body because of the api this thing is working with |
| 23:33 | dopamean_ | so i was hoping to be able to sort of handle for all types of situations in one way |
| 23:35 | jeremyheiler | dopamean_: you can. |
| 23:36 | jeremyheiler | specifcy `:throw-excpetions false` in the opts map |
| 23:37 | dopamean_ | hmm. iirc technomancy thought it might not be a good idea to return a map with an error key and message. i think he described just throwing the exception as "more civilised" |
| 23:39 | jeremyheiler | heh ok. just do what you want lol |
| 23:39 | dopamean_ | i want to return the map regardless of what happened to the http request. i just wanted to be clear on why some people thought it wasnt a good idea |
| 23:40 | dopamean_ | ill do it anyway |
| 23:40 | jeremyheiler | i don't know. i think it's perferctly fine. |
| 23:40 | dopamean_ | cool |
| 23:40 | dopamean_ | thanks. |
| 23:41 | jeremyheiler | np. if it helps, that's what i do. |
| 23:41 | jeremyheiler | at least when i need to handle the responses more effectively |
| 23:41 | jeremyheiler | err.. i guess differently |
| 23:41 | dopamean_ | i knew what you meant. i write a lot of ruby for work and its something i do somewhat frequently there. |
| 23:42 | dopamean_ | so it seemed natural here |
| 23:42 | jeremyheiler | cool |