#clojure logs

2014-10-15

00:13amalloyRazWelle1: 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:15RazWelle1amalloy: 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:15RazWelle1I wanted to learn lisp in a way that was useful to my current project
00:15RazWelle1which depends on a .net library
00:16RazWelle1I even tried ironscheme but I'dve made more progress in clojure-clr
00:16RazWelle1but not by much
00:16TEttingerRazWelle1: inspect an assembly as in reflection?
00:16RazWelle1TEttinger: yeah basically python's dir()
00:16RazWelle1So I can see what the repl is able to access
00:16TEttingeroh ok
00:17RazWelle1I'm trying to translate this http://lib.openmetaverse.org/wiki/IronPython/Simple_Login
00:17TEttingeryou saw this stuff right? https://github.com/clojure/clojure-clr/wiki/Loading-assemblies
00:18RazWelle1Maybe I should try assembly-load-file macro, right now I"m doing it directly with (System.Reflection.Assembly/LoadFrom "libomv/OpenMetaverse.dll")
00:18justin_smithRazWelle1: the comment here may be useful https://github.com/clojure/clojure-clr/blob/master/Clojure/Clojure.Source/clojure/core_clr.clj#L199
00:18RazWelle1*click*
00:19xsynHow 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:20xsynspark-core by default builds against 1.0.4
00:20justin_smithRazWelle1: oooh - this one has a promising name... https://github.com/clojure/clojure-clr/blob/master/Clojure/Clojure.Main/Properties/AssemblyInfo.cs
00:20justin_smithAssemblyInfo
00:21justin_smithoh never mind
00:21RazWelle1ooh
00:21justin_smiththat just *provides* info about the clojure assembly
00:21justin_smithreverse of what you want
00:21TEttingeryou can call this thorugh interop http://msdn.microsoft.com/en-us/library/system.reflection.assembly.gettypes(v=vs.110).aspx
00:24eggheadgrr, I can't find a mustache impl in clojure that will let me configure it to not replace missing vars
00:57technomancydoes vim interpret Ctrl-i as a tab like emacs and other readline things?
00:58bbloom_technomancy: you can do ctrl-v then type what you want directly
00:58bbloom_so like if you need a real tab, ctrl-v + tab
00:58turbofail,(do (require 'clojure.walk) (clojure.walk/macroexpand-all ''(-> a b)))
00:58clojurebot(quote (b a))
00:59turbofaili don't think that should happen
00:59bbloom_technomancy: in insert mode, i mean of course
00:59technomancybbloom_: right, but inside a terminal, hitting TAB literally sends a ctrl-i keycode
00:59technomancybbloom_: does gui vim interpret them as the same thing as well?
01:00justin_smithturbofail: that what should happen?
01:00bbloom_technomancy: oh i have no idea
01:00turbofailjustin_smith: it's macroexpanding things within a quote form
01:00justin_smithright, it's supposed to do that
01:00technomancyany gui vim users care to try?
01:01turbofailjustin_smith: but that gives wrong results. evaluating '(-> a b) doesn't yield (b a)
01:01justin_smithwhy not?
01:01justin_smithit should
01:01turbofailjustin_smith: notice the two quotes i was using in my macroexpand
01:01turbofaili.e. (macroexpand-all '(quote (-> a b)))
01:02amalloyturbofail: clojure.walk/macroexpand-all is not close to being an accurate representation of the compiler
01:02justin_smithright, macroexpand ignores one quote - otherwise it wouldn't be very useful
01:02amalloyjustin_smith: ?????
01:02turbofailno, it ignores every quote
01:02turbofail,(clojure.walk/macroexpand-all '(quote (quote (quote (-> a b)))))
01:02clojurebot(quote (quote (quote (b a))))
01:02amalloyclojure.core/macroexpand ignores no quotes at all. clojure.walk/macroexpand-all ignores all of them
01:03justin_smithamalloy I mean '(+ 1 1) doesn't return (quote (+ 1 1)) - it doesn't show the first layer of quote
01:03amalloyjustin_smith: macroexpand is not a macro, it is a function. that "first layer" doesn't exist
01:03bbloom_technomancy: not sure what you're trying to figure out exactly
01:03justin_smithahh, right
01:03turbofailamalloy: that may be the case but it should still at least try and be relatively faithful
01:04amalloyturbofail: 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:04amalloyturbofail: it is implemented in the simplest possible way, like everything in clojure.walk
01:04turbofailah
01:05amalloymacroexpand-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:05amalloyie, an advertisement
01:08amalloyoh, pmap is on that list too
01:08amalloyit 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:09amalloyand hey, while you're in c.t.macro, check out macrolet and symbol macros. more fun than a barrel of monkeys
01:18turbofailhm. so what remaining discrepancies does c.t.macro/mexpand-all have?
01:21amalloythe 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:21amalloythe 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:22amalloyeg, (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:23turbofailah
01:23clojurebotCool story bro.
01:23turbofailsilence, bot
01:23amalloyso ifyou write a case statement with 8 or more entries, mexpand fails to retain the order
01:23dbaschfor a good time, macroexpand-all (doseq [a [] b [] c [] d [] e [] f [] g []])
01:23dbaschand read the output when you need help falling asleep
01:24amalloyloop loop loop
01:24turbofaili've looked into the guts of `for' before, that was an unpleasant experience
01:27amalloyi wonder what the guts of CL's LOOP look like
01:28turbofailon 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:29turbofailit'd be nice to not have that intermediate sequence
01:58aztakanyone 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:42raspasovanyone with experience around serializing Clojure's deftype ?
04:01hyPiRionamalloy: the CL loop is an amazing macro with some bugginess in it
04:02dysfun_is there a pretty-printer for the lein repl?
04:02dysfun_for return values
04:02raspasovdysfun_: I like this library https://github.com/razum2um/aprint
04:03dysfun_that is very nice, but still requires me to manually type it in at the repl
04:03dysfun_i'm looking for something that hooks the return value after i execute some code at the repl and pretty prints that
04:03raspasovyea, haven't seen anything that does it automatically, it would be awesome though
04:04dysfun_well, i may have to, because i'm getting quite annoying trying to deal with a large xml structure
04:04dysfun_aha! https://github.com/greglook/whidbey
04:05raspasovnice! :)
04:06razum2um1raspasov: thanks :) yep, I look to integrate this into repl to format returned value automatically
04:07raspasovrazum2um1: cool!
04:08dysfun_awesome, one line in ~/.lein/profiles.clj
04:08dysfun_works like a charm
04:20zwerhyPiRion what bugginess?
04:23hyPiRionzwer: like https://www.refheap.com/91764
04:24hyPiRionHow to combine the loop clauses are afaik poorly defined and complex
04:36plumaComing from a high-level non-FP background, what is a vector and how is it different from an array or list?
04:43hyPiRionpluma: shameless self-plug: http://hypirion.com/musings/understanding-persistent-vector-pt-1
04:43kungihyPiRion: Oh nice!
04:44hyPiRionIn short. A vector is immutable, but still provides efficient updates and random access lookup compared to an immutable singly linked list
04:44hyPiRionAlso, a vector is always strict, whereas a sequence may be lazy.
04:46daniel__,(cons 5 [1 2 3 4])
04:46clojurebot(5 1 2 3 4)
04:46daniel__,(cons 5 '(1 2 3 4))
04:46clojurebot(5 1 2 3 4)
04:46daniel__,(cons [1 2 3 4] 5)
04:46clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>
04:46daniel__,(cons [1 2 3 4] [5])
04:46clojurebot([1 2 3 4] 5)
04:46hyPiRion,(conj [1 2 3 4] 5)
04:46clojurebot[1 2 3 4 5]
04:46daniel__right :p
04:46hyPiRion,(conj '(1 2 3 4) 5)
04:46clojurebot(5 1 2 3 4)
04:48plumahyPiRion: thanks.
04:49hyPiRionnp
04:55CookedGryphonDoes 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:05CookedGryphonand 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:05CookedGryphonand the code's coming out really clunky looking
06:50kenrestivoi'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:54clgv,(ancestors (class (range 10)))
06:54clojurebot#{clojure.lang.Sequential clojure.lang.IMeta clojure.lang.Seqable clojure.lang.IPersistentCollection clojure.lang.Obj ...}
06:55clgv,(->> (ancestors (class (range 10))) (map #(.getName %)) sort)
06:55clojurebot("clojure.lang.IHashEq" "clojure.lang.IMeta" "clojure.lang.IObj" "clojure.lang.IPending" "clojure.lang.IPersistentCollection" ...)
06:55clgv&(->> (ancestors (class (range 10))) (map #(.getName %)) sort)
06:55lazybot⇒ ("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:55clgvkenrestivo: you can get an Iterator via java.lang.Iterable interface
06:57kenrestivoi 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:58kenrestivoEnumeration
06:58clgvkenrestivo: if there is no conversion object Iterator -> Enumeration in Java then you can also just (reify java.util.Enumeration (hasMoreElements ...) (nextElement ...))
06:59kenrestivooh, sure, thanks, guess i could just write my own. that should work.
07:03clgvkenrestivo: (defn ->enumeration [^java.lang.Iterable xs] (let [it (.iterator xs)] (reify java.util.Enumeration (hasMoreElements [_] (.hasNext it)) (nextElement [_] (.next it)))))
07:05kenrestivoclgv: thank you. that is awesome. worked. is that in a util library somewhere?
07:06clgvkenrestivo: no idea. just wrote it right now
07:06kenrestivoit's a couple lines longer than what i was writing, and it works whereas mine did not. anyway, thanks
07:06clgv:)
07:20dysfun_is there a clojureish library that takes in an XML DTD and makes it easier to work with xml conforming to it?
07:24clgvdysfun_: that's pretty vague
07:25dysfun_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:26rweirwhat did you want it to do beyond validating that the xml is uh valid
07:26clgvdysfun_: data.xml converts the xml to a clojure data structure
07:27dysfun_ideally some abstraction that allows easy transformation. zippers ended up making it more complex when i tried that last
07:27dysfun_yes, i have that and i have messy code that works with it
07:27dysfun_dtd validation would at least enable me to kill the error checking
07:27clgvdysfun_: maybe use a transformation language like xslt?
07:28dysfun_hrm, i think what i want could be quite simple in xslt actually
07:28dysfun_thanks
07:29clgvdysfun_: maybe that one helps if you need to integrate it within a clojure project https://github.com/pjt/saxon
07:29dysfun_brilliant, thanks
07:30perplexahello
07:31dysfun_"You can download an evaluation copy of the software from here.". Maybe not :(
07:31perplexai have a (dorun (for ...)) form, that i want to execute in parallel. should i use core.async or just get fancy with pmap?
07:35clgvdysfun_: oh well...
07:35clgvperplexa: clojure.core.reducers
07:36dysfun_thanks
07:37perplexaclgv: i have multiple functions take take a couple of minutes for computation
07:37perplexaand i want them to run in parallel ;x
07:38clgvperplexa: example?
07:38perplexaactualy, they just submit the work to a cluster and then wait for the result
07:38perplexaclgv: cascalog queries :P
07:39perplexabut 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:39clgvperplexa: well, you can probably submit them asynchronously and just start waiting for the results after you submitted all
07:39perplexathat's what i want to do
07:39perplexabut i don't know what the right way would be ;/
07:39clgvbut then you do not need anthing in addition to the cluster lib
07:40clgvor does it not support asynchronous submits?
07:40clgvthe easy trick would be to wrap those submits into futures then
07:41perplexai don't think it does
07:41perplexabut i don't care about the results either, it's just fire&forget basically
07:41clgvyou just want to heat the server room, eh?
07:42clgvwell do you need to wait for completion of those tasks?
07:42perplexahaha :) nah, the queries read from hdfs and write to hdfs, and i don't need any of the info in clj
07:42perplexanope :)
07:42clgvok just use futures and forgot about them ;)
07:43perplexai just hope the application doesn't terminate while they're still running ;p
07:43perplexawhen using futures
07:43perplexaso.. i put a bunch of futures in a vector and then check if they're finished or something?
07:44clgvyeah.
07:44clgvwell then you need to wait for completion by dereferencing the futures...
07:47perplexaclgv: soooo. just (let [x (for [..] (future ...))]) and then (map #(@%) x) afterwards or sth?
07:50clgvperplexa: no you need to eagerly create those futures, e.g. (doseq [f (mapv #(future ...) coll)] (deref f))
07:51clgvperplexa: if you absolutely need that `for` wrap it in `vec`
07:51perplexai don't think i do :)
07:53perplexaclgv: what's the difference between your example and mine?
07:56clgvperplexa: 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:57perplexaah! thx
07:57perplexathat's what mapv is for i guess :)
07:57perplexa(inc clgv)
07:57lazybot⇒ 30
07:57clgvperplexa: in my example yes. in general there are other use cases as performance ;)
07:58clgv$karma perplexa
07:58lazybotperplexa has karma -1.
07:58clgvhehe
07:58perplexahaha
08:54visofhi
08:55visofis there anybody used apache-s4 beforehand?
09:00clgv~anyone
09:00clojurebotJust 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:02luxbockin leiningen templates when passing the data map to the ->files function, how are functions as the values of the map used?
09:02luxbockin the chestnut template there's a line like this: `:not-om-tools? (fn [block] (if (om-tools? opts) "" block))`
09:03luxbockand then in the core.cljs file there's a line: `(dom/h1 {{#not-om-tools?}}nil {{/not-om-tools?}}(:text app))`
09:03luxbockso I understand what it does, but I'm still confused about the role of the `block` argument that the function gets
09:05luxbockah think I get it now
09:06luxbockthe block is the text between the mustache block as defined by #not-om-tools and /not-om-tools
09:13perplexa14:34:38 perplexa | Java.lang.RuntimeException: No such var: impl/logical-comp, compiling:(cascalog/logic/ops.clj:46:3)
09:13perplexa14:35:02 perplexa | i randomly get that error on a query that otherwise works, any ideas where this might come from?
09:13perplexa14: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:13perplexa14:56:05 perplexa | but i don't see why it would randomly spew the above error
09:14perplexais that actually a bug in clojure? i don't see why it would fail ;p
09:18clgvperplexa: you said that's executed on a cluster, are you sure the versions of cascalog are the same everywhere?
09:19perplexaclgv: yeah, i build an uberjar with lein, which includes the deps and then just run it via `hadoop jar`
09:19hyPiRionso nothing in :provided?
09:20perplexaactually, when it starts compiling stuff there, could it be that the cleanup interferes between futures ?
09:20hyPiRionI've heard of some issues with hadoop related to that
09:20perplexahyPiRion: hadoop-core and hadoop-common are provided
09:21perplexaand those versions match the cluster's.
09:21perplexait only happens randomly, too ;/
09:21perplexaand i saw it just now that i started using futures, hmm
09:21hyPiRionalright, then idk
09:22perplexawhen it says compiling, it's actually compiling stuff?
09:22clgvperplexa: but you only use the futures on the client side right?
09:22perplexayes
09:22clgvand there error is server/cluster side?
09:22perplexayesnope client-side
09:22perplexadoesn't even start the query
09:23perplexas/yesnope/nope/
09:23clgvperplexa: does the code within the future dynamically load namespaces?
09:23perplexayes
09:23perplexa;x
09:24clgvthat's likely the reason - can you change it to depend statically on those namespaces?
09:24perplexasomething like
09:24perplexa (require (symbol type-ns))
09:24perplexa ((resolve (symbol type-ns "bootstrap")) id config input)
09:24perplexait's gonna be hard to have them loaded statically :/
09:24clgvperplexa: yeah require is not transactional
09:25clgvperplexa: I use that one https://gist.github.com/guv/ac76b9ab1878705062c6
09:25perplexanice, i'll see if that helps :)
09:25clgvbut I think loading of namespaces should be made transactional
09:26clgvah well, remove the println ;)
09:27perplexamy 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:27hyPiRionloading of namespaces transactionally is really hard, just fyi
09:27stuartsierraBasically impossible since Clojure allows arbitrary side-effects at the top-level.
09:28dnolen_,*clojure-version*
09:28clojurebot{:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"}
09:29dnolen_ah hmm, oh well, anyways nice to see using transducers w/ parallel fold "just works" - (r/fold + ((map inc) +) (vec (range 1000000)))
09:29clgvstuartsierra: what do you mean exactly?
09:30Bronsadnolen_: nice
09:30stuartsierraclgv: "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:31clgvstuartsierra: ok. just limit it to require which currently manages to keep track of the namespaces it loaded
09:32clgvstuartsierra: but it only manages the names in a `ref` - nothing more
09:32clgvat that point there could be logic to load every namespace (as defined in context of `require`) only once in a thread-safe way
09:34dnolen_Bronsa: btw is the JS analyzer work good enough to sync up cljs.core.async w/ clojure.core.async?
09:37Bronsadnolen_: I'm actually waiting on CLJS-857 before cutting a first stable release
09:39Bronsadnolen_: I can work around it if you decide that's not going to make in cljs btw, even though I'd rather not
09:42dnolen_Bronsa: re: 857, question, why doesn't this affect the Clojure analyzer?
09:42dnolen_Bronsa: or is what 857 proposes what Clojure already does?
09:44Bronsadnolen_: deftype in clojure expands to (deftype* name class.name [fields] :implements [interfaces] (method [..] ..))
09:45Bronsaso the inline method impls are in the local scope of the fields, that's what I'm proposing with 857 for cljs
09:45dnolen_Bronsa: ok I'm cool with 857
09:47dnolen_Bronsa: just tried to apply - emits a lot of analyzer warnings - a I'd take new patch that addresses this
09:47Bronsadnolen_: ok I'll take a look
09:48dnolen_Bronsa: looks like a locals thing - analyzer complains about the fields as undeclared vars
10:03vermadoes cursive have insta-repl? like lighttable?
10:06dnolen_verma: no only a more traditional REPL - but it's a pretty nice one
10:08vermadnolen_, 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:10mpinghi guys
10:11mpingI'd like some advice
10:11mpingI'm parsing a ~400mb json file
10:13mpingand I'm trying to speed up the parsing and processing
10:13mpingbut it's still a bit slow
10:13Bronsadnolen_: did resolve-var's impl change recently?
10:15vermamping what are you using to load the json file?
10:16dnolen_Bronsa: confirm-var-exists changed, not resolve-var
10:17dnolen_Bronsa: we used to not check that vars actually exist from other namespaces, not the case anymore
10:42csd_How can I do a try/catch and have a statement execute conditional on an exception not being thrown?
10:43stuartsierracsd_: one way (when (try … true (catch Exception _ false)) (do-the-thing))
10:44csd_oh will the catch prevent the last statement from executing if there is an exception?
10:44LauJensenFor 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:45stuartsierracsd_: No, I just used the result of the entire try/catch block as the test in the `when`
10:45TimMccsd_: (try (let [ret ...] (do-a-thing) ret) (catch ...))
10:45csd_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:46csd_stuartsierra: i see, clever
10:46stuartsierraA try/catch block returns a value, just like everything else in Clojure.
10:48csd_ in your example, I assume `ret` is the action that i want to execute conditional on success?
10:48csd_meant to direct that to you TimMc
10:49Bronsadnolen_: the patch didn't handle correctly defrecord's args, I just attached an updated patch. I don't see any warnings now
10:57xsynusing conj should stop me from having a stackoverflow in a recursive function, right?
10:58gfredericksuhm
10:58gfredericksdepends on the details? conj is not lazy though if that's what you're after
10:59gfrederickspretty much any function call can give you a stackoverflow if you set it up for success correctly :)
11:01dnolen_Bronsa: thanks
11:08xeqigfredericks: identity?
11:12gfredericksxeqi: sure
11:12gfredericksxeqi: just call it with a bulging stack
11:13justin_smithgfredericks: that sounds like something I should look up on urbandictionary
11:14gfredericksjustin_smith: I cannot condone any such activity
11:19perplexais (some (partial = source) (keys input)) preferable over (nil? (get input source)) ?
11:19perplexajust wanna know if "source" is a key of "input"
11:20xeqi(doc contains?)
11:20clojurebot"([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:21perplexaxeqi: haha thanks :P
11:28TimMccsd_: No, ret is the return value from other work you were doing, if you wanted it.
11:30hiredman /win 26
11:32Bronsahiredman: http://sprunge.us/BGhG
11:33justin_smithBronsa: clearly it's a secret code
11:35m1dnight_Damnit, I wanted to buy a clj sticker for my laptop but I'm missing 0.05 dollars on my prepaid mastercard
11:37hiredmanBronsa: I have been data mined
11:37perplexaclgv: seems the thread safe require solved my problem, much apreciated!
11:37perplexa(inc clgv)
11:37lazybot⇒ 31
11:38clgvperplexa: great :)
11:44TimMcBronsa, hiredman: More data: http://sprunge.us/YdDh
11:46clgvTimMc: guess he lost now? :P
11:46perplexahaha what
11:47hiredmanreverse engineering my irssi setup
11:47perplexasomebody tell him about meta+[1-9] ;/
11:47perplexa;x
11:47perplexaoh hai
11:47TimMcperplexa: ...that doesn't help with more than 10 windows
11:48justin_smithTimMc: what, you don't have a "15" key on your keyboard?
11:48hiredmanactually it does, M t is the same as /win 15
11:48perplexaTimMc: there's also meta+qwertyuiop
11:48TimMcjustin_smith: I know a guy who has a keybiard with F1–F25 and uses all of them.
11:50vermais there somewhere, where clojure benchmarks are listed?
11:51BronsaTimMc: hah
11:51clgvverma: http://benchmarksgame.alioth.debian.org/
11:53vermaclgv, thanks, you think clojure was type annotated for these benchmarks?
11:55clgvverma: andy fingerhut optimized some (even all?) of those benchmark implementations
11:56clgvverma: ah no, maybe I confused it. the example I opened says alex miller ;)
11:57Jaoodverma: extremely annotated
11:57vermanice, benchmarks are not bad :)
11:57vermanice
11:57clgvverma: that one feels like cheating badly: http://benchmarksgame.alioth.debian.org/u64q/program.php?test=pidigits&amp;lang=clojure&amp;id=5
11:58vermahaha, that qualifies as java
11:58vermabut I guess that's the point, if need be fallback to raw java
11:58clgveven more it uses ASM to generate a class on the fly :P
11:58vermawait what?
11:59clgvthat one is better http://benchmarksgame.alioth.debian.org/u64q/program.php?test=nbody&amp;lang=clojure&amp;id=1
11:59vermaoh nice!
11:59vermawhich javascript was there
12:00vermawish*
12:00vermabut I guess this site is convincing enough, that clojure is not slow
12:00vermaat least compared to what web-dev people do right now with Ruby/Python
12:00vermawould definitely be interesting to see cljs and javascript added in there
12:00Jaoodverma: you mean non-idiomatic clojure is not slow
12:01clgvJaood: ah you can get it pretty idiomatic looking and fast, through macros or inline functions
12:01vermaJaood, if I use qualifiers people will get confused (context: I am doing a talk about clojure with a bunch of js guys).
12:01noonianeven idiomatic clojure is not slow, its just not *as fast* as java
12:02vermaI think this is a pretty picture: http://benchmarksgame.alioth.debian.org/u32q/which-programs-are-fastest.php
12:04mpingtalking of speed, guys can I have your opinion on some clj I have?
12:04mpingI'm parsing a ~400mb json
12:04mpingand I don' have alot of clues on how to speed it up
12:04mpingI've used pmam and reducers
12:04llasrammping: A single JSON object or 400MB of separate JSON objects?
12:05mping*pmap
12:05mpingllasram: separate
12:05mpingone per row, newline separated
12:05llasrammping: Which JSON parser?
12:05mpingcheshire
12:05mpingbut htop shows me that the cpus have alot of headroom
12:05mpingand visualvm shows me assoc and such as dominators
12:05llasramThen are you sure you aren't IO-bound?
12:05mpingyes; Im pretty sure
12:06mpingIve measured the time to parse the json
12:06llasramAre 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:07mpingrecord-like
12:07mpingI can provide the code if you guys want to take a look
12:07llasramSure -- I've run out of reasonable questions to ask :-)
12:07mpingmy task is to read json files with an array path like [a b c d e f]
12:08mpingand generate "n-grams" such as [a b c] [b c d ] ...
12:08mpingthen sum the whole thing and count
12:08mpingmy lines are like this: {"path":["a","b","c","d","e","f"],"pageviews":7,"visits":1,"duration":97878}
12:09mpingI'm using lein-exec
12:09mpingbut I am a clojure n00b, so forgive any bad code
12:10mpinghere it is: https://gist.github.com/mping/180343e9c745c9c446d6
12:11Jaoodmping: are you using laziness?
12:11mpingyes
12:11mpingfor reading the lines
12:12llasrammping: 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:13llasrammping: There used to be similar helpers in monolithic contrib, but they're pretty much always a bad idea
12:13llasramAnything like `take` which produces an early-ending wrapper seq leaves the resource dangling until/if GC cleans it up
12:15llasrammping: 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:16dnolen_Bronsa: patch has a bug
12:16Bronsadnolen_: ?
12:17dnolen_Bronsa: Caused by: java.lang.RuntimeException: Unable to resolve symbol: op in this context
12:17Bronsadnolen_: gah, I probably have forgot to add that line to the commit
12:17Bronsaone sec
12:18Bronsayeah
12:18llasrammping: Is your goal just "make it faster" or do you have specific performance benchmarks you need to hit?
12:19Bronsadnolen_: removed old & updated
12:24dnolen_Bronsa: applied
12:27Bronsadnolen_: awesome. I'll get t.a.js up to date with the changes that went into cljs over the last month
12:27Bronsadnolen_: 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:27dnolen_Bronsa: cool sounds good!
12:29vermawould 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:29Bronsadnolen_: http://dev.clojure.org/jira/browse/ASYNC-86 is a blocker for that btw.
12:29vermaany feedback is much appreciated
12:29dnolen_Bronsa: ok thanks will look into that
12:30Bronsadnolen_: I'm updating the patch to depend on 0.6.1 ATM, will probably need the ok of tbaldridge
12:30dnolen_Bronsa: sure, I'll make sure to check with him
12:36justin_smithverma: what does "Language Age ratio" mean?
12:37vermaI read it some where, how old a language is vs. how popular it is
12:37vermacan't find source :(
12:37justin_smithahh, so that means "it is popular for its age"
12:37vermapopularity : age, age
12:37vermayes
12:37vermamay be should just say that
12:38justin_smithif Language Age ratio is something people know about it's fine, I had just never heard the term before
12:38vermayeah, you're right, I changed the text
12:38justin_smithahh - it's Popularit : Language Age ratio
12:38vermaoh :P
12:38vermaI made it italics
12:38vermaso that it stands out
12:39justin_smithI thought Popularity: was a heading
12:39justin_smithheh
12:39vermabut may be make it bold
12:39justin_smithyeah, I misread it
12:39vermaI bold-italicised it
12:40vermathis is a 10 minute intro slide to just get stuff started, all action will happen in repl
12:40vermaslides*
12:41justin_smithverma: potential alternate target for the benchmark link http://benchmarksgame.alioth.debian.org/u64q/benchmark.php?test=all&amp;lang=clojure&amp;data=u64q
12:41justin_smithone that specifically highlights clojure
12:41vermayeah, 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:42vermabut 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:42benzapSo I was wondering, how hard is it to find a software development job which uses clojure?
12:42vermabenzap, that's an excellent point as well, people are concerned that if they invest time in clojure they won't find a job
12:44benzapwell, I know there are jobs
12:44benzapvery few though
12:44justin_smithverma: "You can write your server side stuff in Clojure inter-ops with Java like its a no-brainer." - multiple issues with this sentence
12:45vermajustin_smith, sure :) now I see them :)
12:45vermajustin_smith, I changed it to: You can write your server side stuff in Clojure: it inter-ops with Java.
12:46benzapI'm currently working on my own side-project in clojure, which i'm hoping could be marketed sometime
12:47benzapbut it would be awesome if I could find a remote job that used clojure
12:47nullptreasier to make jobs in something "new" than to find jobs
12:47benzaphmm yeah
12:48vermabenzap, I pitch clojure all the time to people who pay me (consulting) ..
12:48vermamost new stuff I am doing is mostly in clojurescript
12:48nooniansomeone was looking for part time clojure developers the other day, i don't remember who though
12:48benzapyeah, i saw that
12:48benzapseemed way out of my league, I think it was staples?
12:49nullptra job that involves only one language does sound pretty lame, though :)
12:49vermayeah saw that too
12:49benzapagreed
12:49benzapmaybe i'm just sick of my current working situation
12:49benzaplegacy code, with years upon years woth of refactoring
12:49vermajustin_smith, what did you think overall? a good intro? anything obvious I missed out/
12:49mpingllasram: sorry for MIA, was busy with some other stuff
12:50mpingllasram: my goal is to show my Java colleague that clojure can be performant and more elegant :)
12:50vermamping, I would think telling them, its not java would suffice :P
12:51vermamping, I've had a few people I've told this to and it has somewhat worked.
12:51justin_smithverma: 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:52vermajustin_smith, thanks! will do
12:53vermajustin_smith, you've earned a beer, send me btc address and I will send you beer worth of btc :D
12:53benzapverma: you working on an article?
12:53vermabenzap, no I gotta go present clojure at a js meetup
12:54benzapoh nice
12:54benzapyou should mention flyer.js just for kicks
12:54benzapi joke
12:54vermanice!
12:57justin_smithverma: it's all good, thanks anyway though
12:59justin_smith"it's all good" - why yes, I did spend some formative years in chicago
12:59vermajustin_smith, sure, thanks for your help
12:59vermathere should be a list of irc -> btc
13:02mpingverma: problem is that my colleague wrote the equivalent of my code and it runs on 1/5 of the time or so
13:02mpingalthough he didn't even parsed json
13:02mpingI just find it strange that the cpus are not maxed out
13:02vermamping, he loaded json without parsing?
13:03vermathat's a little presumptuous of me
13:03vermahe/she
13:03technomancyhello people
13:03dopamean_hello
13:04technomancyI have disabled SSL 3.0 on clojars due to http://poodlebleed.com
13:04technomancyplease let me know if you experience any connection issues
13:04justin_smith"poodlebleed" - what a terrible name
13:05technomancyjustin_smith: and a terrible logo
13:05vermaI like how these vulnerabilities get their own pages now
13:05vermaand domains
13:05mpingverma: yep, since the records are simple he splits the string and other stuff
13:06vermamping, you can do the same can't you?
13:06justin_smithverma: mping: that's a terrible, and fragile way to do it
13:06vermajustin_smith, yes yes, but we're racing for speed here I would think
13:07vermamping, you can't win if the other person is taking crappy shortcuts
13:07justin_smithwell 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:08vermalol
13:09vermamy hair would cause drag, a helmet would be nice since it'd reduce drag
13:12justin_smithmping: for a more clojure-friendly comparison: is each version thread safe? how hard is it to make each version thread safe if not?
13:15mpingverma: i don't want to win I just want to do a good job
13:16mpingjustin_smith: what do you mean thread safe? we both try to parallelize using threads
13:16justin_smithmping: is this up to date with what you are doing? https://gist.github.com/mping/180343e9c745c9c446d6
13:16mpingafter parsing the json into well-defined records , everything is fair game
13:16mpingjustin_smith: yep
13:16justin_smithmping: by thread safe I mean won't do weird broken stuff if you run it in many threads simultaneously
13:17mpingjustin_smith: yep its thread safe
13:17llasrammping: 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:17vermamping sure :)
13:18mpingwe don't share state "normally", only through core (reducers, pmap) or java's Array.parallelStream, blockingqueue and such
13:18mpingjustin_smith: json slurping is 8 secs
13:18justin_smithmping: small thing - you can use zero? instead of = 0
13:18justin_smithon line 55
13:18mpingslurping + doing the "n-grams" thing for n = 3 is 22 secs
13:18mpingjustin_smith: thanks!
13:19vermamping: line-seq sort of does what lazy-file-lines is doing
13:19justin_smithmping: also I have heard nothing but bad things about pmap
13:19justin_smithmping: I think reducers are preferable
13:19mpingjustin_smith: I was wondering why pmap was not reducing the time...
13:20mpingheheh
13:20justin_smithalso #(map f %) is better performance wise than (partial map f) if you know you only get one arg
13:21llasrammping: How fast is the Java version? <5 seconds?
13:21justin_smithand (map #(println %)) should be (map println)
13:21mpingthe Java version takes a minute on my machine
13:21llasrampmap 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:22llasramNow I'm confused -- I thought you said your version was taking 22 seconds :-)
13:23mpingllasram: I'm using a chunked version of pmap for parsing lines and partitioning
13:23mpingllasram: 22 seconds for only slurp + partitioning
13:23mpingtotal time last time was 4 or 5 mins
13:23vermamping, you could enable reflection warnings, and then type annotate some of the things
13:23mpingllasram: and I'm doing r/fold for summing
13:23llasrammping: Ah
13:24justin_smithllasram: 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:24llasrammping: `fold` only runs in parallel if the ultimate input is a vector. It's just `reduce` over a lazy seq
13:25llasrammping: pmap has several problems, even when doing the chunking: (a) http://dev.clojure.org/jira/browse/CLJ-862
13:26llasramand (b) it maintains the order of the output even when you don't need that property, which reduces throughput
13:26mpingllasram: so what are my alternatives?
13:27llasramjustin_smith: Futures of what?
13:27justin_smithllasram: the calculation to be done on each input
13:27justin_smithmaking sure it is not chunked, of course...
13:27llasramjustin_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:27stuartsierratransducers and the new core.async pipelines are what you want.
13:28mpingstuartsierra: I've tried to wrap my head around transducers but I still don't got it :(
13:28llasrammping: 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:28nullptrmping: did you watch hickey's strangeloop presentation? it's quite accessible.
13:28llasramThe entire pipeline should run in the forkjoin pool, utilizing all available CPUs
13:29mpingnullptr: I skimmed over it but I have to watch it again
13:30llasrammping: 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:32mpingIt seems that the (apply concat) is taking ages.
13:33mpingI was using flatten but it seems overkill
13:34llasrammping: `(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:34mping16s for slurping+partitioning vs 2mins for slurping+partitioning+apply-concat
13:35mpingI might as well skip that and handle it within the r/fold
13:38mpingthanks guys I'm gonna go back to the drawing board, see if I can use core.asyn and transducers
13:46Fendercan any of you estimate the size of a vector of ~10 doubles/ints in memory?
13:46Fendera coarse estimate is good enough, I reckon it's 8byte*10+size(vector)
13:47hiredmanFender: no
13:47hiredmanFender: as rule of thumb, unless otherwise noted, collections on the jvm box primitives
13:47mi6x3mclojure is there a way to preserve new lines in macro defs?
13:47Fender"no" as in "no coarse estimate is good enough"? :)
13:48Fender"no" as in "nobody cas estimate that"??
13:48hiredmanso each int or double will also have associated object headers and such
13:48lazybotFender: What are you, crazy? Of course not!
13:49justin_smithmi6x3m: the reading stage does not preserve newlines
13:49mi6x3mjustin_smith: so I guess i'd have to use pprint?
13:49mi6x3mor something when I output macro generated source
13:49hiredmanFender: no as in "8byte*10+size(vector)" is not even close
13:49Fenderhmm
13:49justin_smithmi6x3m: I think there exist pretty printing rules for code - I forget if they are in pprint or elsewhere
13:50Fenderso double the size of the Numbers
13:50Fenderand the size of vector is approx??
13:50lazybotFender: Definitely not.
13:50Fenderhmm, slapping doesnt work in pidgin D:
13:50hiredmandepending 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:50Fenderright, lazybot??
13:50mi6x3mjustin_smith: yes, thanks!
13:50lazybotFender: Uh, no. Why would you even ask?
13:51Fenderso hiredman, can you give an estimate?
13:51hiredmanand clojure also provides primitive versions of vectors, but I am not sure I would recommend using them
13:51hiredmanFender: no
13:51justin_smithFender: 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:51SagiCZ1when i call "lein deps" where do the dependencies end up?
13:52FenderI thought its like chunks of 32 references
13:52justin_smithSagiCZ1: ~/.m2/
13:52Fenderplus some points left and right
13:52Fenderpointers that is
13:52hiredmanit isn't C though, there are no raw pointers
13:53justin_smithFender: it's more like a tree - that article shows a simplified version
13:53martinklepschWith 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:53hiredmanit 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:53SagiCZ1justin_smith: thanks, found them.. it doesnt add the dependencies to classpath automatically?
13:54justin_smithSagiCZ1: that's what lein does - it's a tool that puts artifacts in the classpath
13:54hiredmanFender: there are tools for estimating the size of an object in memory, but I've never used them
13:54SagiCZ1strange
13:54justin_smithSagiCZ1: the deps command just ensures that they have been downloaded
13:54justin_smithother tasks ensure that they are downloaded, and then run clojure with those files in the classpath
13:54hiredmangenerally if I really care about the size of something, I'd use a ByteBuffer
13:55justin_smithvia the command line (check out the ps output for lein commands - you see a huge list of jars under .m2)
13:55SagiCZ1justin_smith: i see.. i found my mistake.. i didnt run the leiningen REPL, just the regular REPL
13:55justin_smithright, like I said, lein is the tool that adds those things to the classpath
13:56SagiCZ1justin_smith: thank you
13:58justin_smithnp
13:58mi6x3mcould 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:58mi6x3mhttp://pastebin.com/M4MRqPg6
13:58clojurebotIt's greek to me.
14:01llasrammi6x3m: It's pretty bizarre
14:01mi6x3mllasram: can you suggest a better layout for the args?
14:01Fenderok, guys, I suppose to get an estimate I will just have to spam my memory with that stuff and see how many fit
14:01Fendermaybe I just use a record with primitives if that is possible
14:02Fenderthat should keep a lid on the size of the thing
14:02llasrammi6x3m: Just either usse keyword args or positional args, not args which must be indicated by both position and keyword
14:03SagiCZ1how would i find all functions that can be applied to a given object?
14:03mi6x3mllasram: this will not allow me to have a body of forms
14:04SagiCZ1lets say i have this incanter type called "Matrix" ..
14:04FenderSagiCZ1: (comp seq #(.getMethods %) class)
14:04justin_smithSagiCZ1: knowing all types a clojure function could take is not generally easy
14:05justin_smithFender: that's for methods of that class, not clojure functions - maybe I misunderstand the question
14:05SagiCZ1justin_smith: maybe just functions that make up some protocol?
14:06llasrammi6x3m: Wah? Take a look at `reify`
14:06Fenderyeah, maybe you're right
14:06mi6x3mllasram: excuse me?
14:06Fenderwell it will show you notifyAll() and such useful methods
14:06justin_smith,(require '[clojure.reflect :as reflect])
14:06clojurebotnil
14:06shemis there any compendium of core.typed annotations for untyped libraries? it seems like a lot of wasted effort when everybody does their own.
14:06justin_smith,(:bases (reflect/reflect []))
14:06clojurebot#{clojure.lang.APersistentVector clojure.lang.IReduce clojure.lang.IObj clojure.lang.IEditableCollection}
14:06mi6x3mI want to be able to pass n arguments after :include-source
14:07justin_smiththat will tell you about interfaces it implements
14:07llasrammi6x3m: Well, `deftype` is a better example. It's a macro which accepts keyword arguments followed by any number of body forms
14:07llasramCrap, no not `deftype` either
14:07llasramOne of those actually does accept some frikkin options :-)
14:07mi6x3mwell how is it done? :)
14:08llasramOh, they do both parse their arguments that way -- they just neither have any documented options right now
14:09jeremyheilermi6x3m: 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:10mi6x3mjeremyheiler: yes, this was the previous version
14:11llasrammi6x3m: Then what was the problem with it?
14:11mi6x3mI thought it's weird of course
14:11mi6x3mlemme revert
14:11mi6x3mthanks a lot!
14:12vermain (def v 0) .. is "variable" the right term for "v"?
14:14technomancyverma: it's a var
14:14technomancy"variable" is an overloaded term that we don't use
14:15xeqitechnomancy: not a symbol?
14:16justin_smithxeqi: depends on what you mean by v - the argument to def, or the thing dev outputs that is named v
14:16justin_smith*def outputs
14:16technomancyheh, well at one point it's a symbol, at one point it's a string, at one point it's bytes on disk
14:16llasramSo say we all
14:20dbaschthe rose is not the same as the name of the rose
14:21justin_smithand The Name of the Rose is an excellent book
14:21technomancy(inc umberto-eco)
14:21lazybot⇒ 1
14:23mmeixhelp for learning newbie again:
14:23mmeix(trying to reimplement map)
14:24mmeix(defn map- [fun s] (cons (fun (first s)) (lazy-seq (map- fun (rest s)))))
14:24mmeixgets me a NullPointerException - why?
14:24llasrammmeix: Where's your base case?
14:24xeqimmeix: what happens when s is [] ?
14:24llasramGotta have a base case
14:25dbaschjustin_smith: indeed. I read it when it came out but I was probably too young to appreciate it fully.
14:25parenjitsu(apply semiotics)
14:26justin_smithdbasch: that, Baudolino, Island of the Day Before... excellent immersion in the medieval mind
14:29dbaschmmeix: (defn map- [fun s] (when (seq s) (cons (fun (first s)) (lazy-seq (map- fun (rest s))))))
14:37mmeixok ... 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:38dbaschmmeix: that’s because at some point you get to the empty sequence, and (inc (first [])) is (inc nil)
14:39mmeixah ...! thanks
14:39mmeix"(inc lightbulbs)"
14:40mmeixreally appreciate ongoing help here :-)
14:52brianwonghow do i get pprint to return the string it would print to *out* instead of actually printing to *out*?
14:52brianwongwith clojure.pprint
14:52brianwongsorry if it is obvious
14:53technomancybrianwong: with-out-string is one way
14:53brianwongtechnomancy: thanks.
14:54justin_smithtechnomancy: not to be confused with without-string (another cantidate for the useless library)
14:54kenrestivoraynes: can i bug you with a conch question? https://www.refheap.com/91799
14:55brianwongtechnomancy: that worked perfectly
14:55kenrestivobut, the above code just hangs, it opens the output file, but appears not to actually push any input into the program.
14:55technomancyjustin_smith: you're full of good bad ideas today
14:55justin_smith(defmacro without-string [& body] `(do (with-out-string ~@body) nil))
14:56technomancyhttp://www.theawl.com/2014/10/interpreting-the-animal-choices-on-the-worlds-most-popular-programming-books
15:01muraikithat aardwolf is pretty cool
15:01muraikican eat 150,000 termites in a night. wow
15:01muraikioh, 250,000. even better
15:02amalloykenrestivo: 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:02kenrestivoamalloy: the internals of java are still mystifying to me, true.
15:03kenrestivobasically this is the way i was able to guess is how you do "foo < *.bar > baz"
15:04kenrestivothe 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:04amalloykenrestivo: 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:05kenrestivoi 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:05justin_smithkenrestivo: if it gets collected, it gets closed
15:05amalloykenrestivo: 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:06amalloythen you close the streams in iss
15:06kenrestivooh, cool, thanks.
15:07amalloyother 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:08kenrestivoit operates just like cat, so i can subsitute cat for it.
15:08kenrestivofor testing.
15:08kenrestivojust takes stdin, does some work, poots the results to stout, and some status messages to stderr
15:09kenrestivoi'll beat on it some more. i just wanted a second opinion whether i was heading in the right direction, thanks.
15:09amalloykenrestivo: 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:10kenrestivowill do. minimum repro case would involve plain old cat.
15:11geoffs`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:11geoffs`Like so: (defn get-postfix-cmd [cmd-sym]
15:11geoffs` (let [cmd-sym (symbol (str (name cmd-sym) "-cmd"))]
15:11geoffs` (cmd-sym (ns-publics *ns*))))
15:11geoffs`
15:11justin_smithgeoffs`: *ns* will get the current namespace at run time, which will be pretty much useless
15:12geoffs`That's what I thought
15:12hiredman*ns* is set at compile time, not run time
15:13geoffs`justin_smith: So is there a way to reference the namespace a function is defined in?
15:13justin_smithhiredman: but calling a form that contains a reference to *ns* will get the ns of the caller
15:13justin_smiths/form/fn
15:14justin_smith,(defn getns [] *ns*)
15:14clojurebot#'sandbox/getns
15:15justin_smith,(ns sandbox2)
15:15clojurebotnil
15:15justin_smith,(sandbox/getns)
15:15clojurebot#<Namespace sandbox>
15:15justin_smithweird - that is not what it does in my repl...
15:15justin_smith,*ns*
15:15clojurebot#<Namespace sandbox>
15:15justin_smithoh, bleh
15:16amalloyjustin_smith: the bots would like to remind you they are not normal execution environments
15:17dbaschalso, the bots like to be antropomorphized
15:17dbaschanthropomorphized, my fingers
15:17justin_smithhttps://www.refheap.com/91804 this is what I was talking about
15:18patrkrishi 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:18amalloydbasch: they like to be treated like ants. formicopomorphized?
15:19dbaschleiningen vs the bots
15:19justin_smithpatrkris: are you requiring the defining namespace in data_readers.clj?
15:19patrkrisjustin_smith: no i am not. just a (require 'namespace) at the beginning of the file?
15:20justin_smithpatrkris: yeah, as long as the name of the namespace reflects its place relative to the classpath
15:20justin_smithnormal clojure namespace location rules
15:21geoffs`justin_smith: thanks for the confirmation. I think I've got it figured out.
15:22justin_smithgeoffs`: maybe resolve would help?
15:22patrkrisjustin_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:23justin_smiththat's not how require works
15:23justin_smithand as to the latter - maybe you need an injection to make sure your ns is available before that file is loaded?
15:24justin_smithit would be (require 'name.space) then you can call name.space/read-instant
15:24patrkrisjustin_smith: yeah, my mistake. i did write only the namespace, not including the symbol of the namespace. gives the mentioned error.
15:24patrkris*symbol inside the namespace
15:25justin_smithtotal hack - {:read-instant-key (do (require 'name.space) name.space/read-instant)}
15:25justin_smithbut there has to be something better than that
15:28patrkrisjustin_smith: yeah. according to http://clojure.org/reader, section Tagged Literals, it should be straight forward
15:31justin_smithahh, 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:31justin_smithso require the ns that defines that tag in any namespaces that use that literal (or load data that uses the literal)
15:32justin_smith*defines that tag reader
15:33patrkrisjustin_smith: ok, that was what I thought might be required. alright, thanks :)
15:53kenrestivook 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:56justin_smithkenrestivo: so format-show-save gets a path and creates a file name in that path?
15:56kenrestivoyep
15:57justin_smith,(clojure.java.io/file "foo" "bar" "baz")
15:57clojurebot#<File foo/bar/baz>
15:57justin_smiththat may help you
15:58justin_smiththis isn't relevant to your main issue, just thought I would point it out
15:58kenrestivothanks, always happy to do a little bikeshedding :-)
15:58justin_smithso you can do :out (jio/file save-path (str name \- date))
15:59kenrestivoi'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:00justin_smithif you deref that future, do you get an exception?
16:03piranhahey! 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:05kungipiranha: If you find one please tell me. I am also using environ and have the same problem.
16:05piranhaok :)
16:06kungipiranha: How about distributing a start.sh script running the uberjar?
16:06piranhahmmm... I wonder if modifying environ so that I can supply defaults from normal file additionally to project.clj makes sense
16:06piranhaI thought about that a bit but I really like the idea of having just one file for distribution
16:06piranhatwo files are already "many" (vs "single" uberjar)
16:06kungipiranha: makes perfect sense
16:07kungipiranha: Can't you just read a config.edn in your resources on startup and get your defaults from there?
16:07hiredmanhttps://github.com/sonian/carica
16:07piranhaI guess that's an option
16:07justin_smithkenrestivo: OK, I am running it locally and it is hanging
16:08kungihiredman: Looks interesting
16:09piranhahiredman: seems like what I need
16:09justin_smithkenrestivo: jstack tells me that the app is waiting for the future, and the process thread is waiting on the cat process to exit
16:09piranhathanks
16:13piranhahmhm, I wonder if it's going to be easier to extend carica to read env vars or environ to read from config.edn :)
16:15hiredmanhttps://github.com/sonian/carica#middleware
16:29mgaarepiranha: to get it into environ, maybe write a lein plugin in the vein of lein-environ
16:30piranhawell, if I want it to be in uberjar, certainly not lein plugin
16:30piranhaI think I got it right, just need to test now... will report in few minutes :)
16:31mgaareright on
16:33arohnerpiranha: kungi: you could use https://github.com/circleci/lein-jarbin and export env vars from a shell script
16:33arohnerbut I wouldn't recommend that for config
16:34kenrestivojustin_smith: thanks! not sure where to go from here.
16:34justin_smithkenrestivo: I'd say maybe some tracing via tools.trace
16:34justin_smithit's suspicious that the unixprocess for cat is sitting open
16:38piranhahttp://paste.in.ua/9934/ - ended up with this for having defaults in config.edn and it works fairly well for me
16:38piranhaso I guess I'll stick with environ, couldn't figure out how to add environ variables to carica, this seemed easier :)
16:38sveriHi, 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:40hiredman~midje
16:40clojurebotmidje is :(
16:41technomancymidje has some weird ideas about how to structure your code
16:42tuftsveri: i'm not familiar with midje, but you don't have a (run-tests) in any of your namespaces do you?
16:42technomancydid I say weird? I meant wrong.
16:42sverituft: no, I only started it from the command line
16:42arohnersveri: midje's tests are expressions, not functions
16:42nullptrtechnomancy: do you use clojure.test or something else?
16:42arohnersveri: so they'll run every time the code is eval'd
16:42technomancynullptr: yeah, with difftest
16:42technomancynullptr: though I guess the thing now is humane-test-output
16:42sveriarohner: well, that explains it
16:43arohnersveri: also, yes, midje is :-(
16:43sveriwell, I should ask clojurebot next time before I choose a lib
16:43sveri~clojure.test
16:43clojurebotNo entiendo
16:43arohneryeah :-(
16:43arohnerI wrote http://blog.circleci.com/rewriting-your-test-suite-in-clojure-in-24-hours/
16:44arohneran almost-working version of the source code is on github, but I wouldn't recommend it unless you have > 10k LoC
16:44sveriyea, I see
16:45arohnerclojure.test isn't terrible. it isn't great, but it's a decent default
16:45technomancyI'd rather have something slightly primitive than something overachitected
16:45sveriseems like there is more on the road for me :D
16:45sverithanks every1
16:45technomancybecause at least the primitive thing can be a good foundation to build on
16:46bbloom_+1 to arohner and technomancy's comments here
16:47sveritechnomancy: I agree with you, however, by looking at the github page its not that obvious
16:47sveriwhich autotest lib do you use?
16:47sverifor clojure.test I mean?
16:48technomancysveri: I just trigger tests from inside emacs
16:48technomancyit's faster than waiting for autotest to pick them up
16:48sveriok, next? :D
16:48arohnerand works better when you have slow integration tests
16:48bbloom_and forces you to *think* about what code will be impacted
16:48bbloom_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:48nullptrarohner: interesting article, thanks. i see you used core.match, which also gets mixed reviews -- any thoughts on that?
16:49arohnernullptr: it worked in that application. I don't think I've used it since
16:49arohnerI think just because I haven't had to solve a prolog problem recently
16:50arohnercore.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:51amalloyarohner: 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:51amalloyie, for a majority of uses of midje, i would expect your transformation script to be unusable
16:52arohnerwe 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:53arohnerusing 'provided' was already a "immediately fails code review" for several months before that translation ran
16:55sveriarohner: hm, why? That was one of the reasons I chose midje
16:56amalloyit'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:57bbloom_amalloy: you really can't imagine that people just like the cute => syntax?
16:57arohnersveri: 1) it was buggy 2) (trying to avoid getting dogmatic testing) the syntax complects mocking and stubbing
16:57amalloybbloom_: in my model of the universe, everyone likes the same things as i do, so that sounds impossible
16:57nullptri think bbloom_ is on the right track here
16:57arohneralso, => syntax is a bad idea
16:57bbloom_clearly
16:58arohnerit's not lispy, which breaks editors, and several of the translations are ambiguous
16:58bbloom_can't eval form to test an individual assertion == terrible
16:58arohnerin the post I explain one of them, but there are several more
16:58bbloom_there are problems with clojure.test's is macro too: they create shadow assertion worlds
16:58piranhaif I have NPE when trying to run uberjar with java -jar, what do I do to figure out what's wrong?
16:58clojurebotNo entiendo
16:58bbloom_at least the `is macro defaults to just checking a damn boolean
16:58bbloom_and relegates the shadow world to error reporting
16:59piranha'lein run' works like a charm, but uberjar throws NPE and I really can't figure out what's wrong there...
16:59bbloom_i know all about computing booleans, but in midge code, you friggin gotta know some magic alternative syntax
16:59piranhait also fails strangely: http://paste.in.ua/9935/#20:22
17:01piranhahah, I think I figured it out
17:02sveri~enlive
17:02clojurebotenlive is for generating HTML from pure-markup templates: http://wiki.github.com/cgrand/enlive/getting-started
17:02sveriJust asking, is enlive suspicious for being a bad guy in a good town too?
17:03arohnersveri: which role do you need? enlive does several things, and there are other options, depending on what you're trying to do
17:03arohnerI personally avoid it because the docs used to be bad
17:03sveriI used it for template generation on server side
17:04sveri*use
17:04arohnerif it's working and you understand how to use it, it's probably fine
17:04sveritook me some time, but I got used to it
17:08schmirI'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:12danneuschmir: i use (jdbc/execute! conn [(slurp "mass-of-sql.sql")]) all the time
17:13danneuschmir: you sure it's not bailing on an error?
17:13schmirdanneu: it doesn't throw
17:16danneuschmir: i dont remember the idiosyncrasies of when things are thrown in jdbc. but i recall dealing with silent failure
17:17danneuschmir: https://github.com/danneu/bulletin/blob/master/src/bulletin/db.clj#L345-L348
17:18schmirdanneu: ok. let me test if wrapping my code in (with-db-transaction...) helps.
17:19danneui dont really remember, but perhaps execute! fails silently when one of the statements in the sql string fails
17:20danneuschmir: 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:21danneupretty sad that i can't remember what was on my mind when i wrote code that's just 1 month old
17:22schmirdanneu: :)
17:22schmirthanks for your help
17:23danneuschmir: i hope you figure somethin out. when i look at the jdbc api, a 'right way' never really jumps out at me
17:26schmirdanneu: I'm now executing each sql statement one by one
17:31danneuschmir: also nice to have `DROP TABLE IF EXISTS <table> CASCADE;` before your creation sql
17:37schmirdanneu: I'm starting with an empty table.
17:37schmirs/table/database/
17:38TimMcdanneu: Yes, I've struggled with this as well -- I don't think JDBC provides a way to say "run this script". :-(
17:38TimMcMuch sadness.
17:38TimMcVery split-on-semicolon.
17:43schmirhttps://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:50schmirTimMc, danneu: jdbc/db-do-commands works with multiple statements. but I have to pass in each statement as a separate string :(
17:52tuftwhich version of clojure has transducers?
17:53gfredericks1.7.0 alpha2 or something
17:54TimMcschmir: Lovely.
17:57justin_smithschmir: sounds like a job for apply + line-seq?
17:59schmirjustin_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:59justin_smithschmir: my assumption was acquiscing to one statement per line
17:59justin_smithwhich may be onerous, sure
18:06arrdemwhy not just use fnparse and the specification SQL grammar...
18:06arrdems/fnparse/instaparse/g
18:08schmirarrdem: that's overkill for my 4 create table statements...
18:08justin_smithin that case statement per file? which kind of sucks
18:09arrdemshrug. 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:15amalloyarrdem: remember, worse is better
18:16danneuschmir: there you go. roll a sql parser real quick.
18:16dbaschamalloy arrdem hence JSONx
18:16tuftgfredericks: thanks
18:18danneuschmir: since you're using clojure, you're probably retired and just rewriting your personal blog.
18:18schmirdanneu: I'll have to finish my rosi sql parser first...
18:18schmiractually I'm getting paid to write clojure
18:19schmir(and read rosi sql...which is pretty terrible) http://www.99-bottles-of-beer.net/language-rosi-sql-1140.html
18:22danneuschmir: 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:23danneuthough sometimes it's nice to leave gifts for your future self and let things break in a weird way
18:23clojurebotCool story bro.
18:24bostonaholiclol clojurebot
18:24schmirdanneu: :)
18:25amalloyhuh. clojure.sourceforge.net redirects to clojure.org. i didn't know it used to be on sourceforge
18:26technomancyI thought you were an old-timer =)
18:27hiredmanI dunno, was it ever in source forge? I mean, it was in google code
18:28justin_smithcould be that clojure.sourceforge.net redirects for the same reason that george-w-bush.i.am does
18:29amalloythat 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:31arrdem{blake}: flatland|amalloy/useful update-vals
18:31{blake}I want to do it this way: "map #({(key %)(fnx[val %)}) my-map"
18:31justin_smithamalloy_: 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:33arrdem{blake}: sadly you are not
18:33arrdem{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:34arrdemthis 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:35justin_smithany classy language should include a water fountain, a gromet factory, and a bidet
18:35technomancythis isn't exactly kitchen sink
18:36arrdemtechnomancy: but it can be written in terms of other language primitives, so neither is it fundimental. arguably.
18:36technomancyarrdem: clojure explicitly reject's scheme's fundamentalism
18:37weavejesterOut of interest, what is this not-primitive, not-kitchen-sink?
18:37technomancybut 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:38weavejester{blake}: Oh, like a map-vals
18:39weavejesterI’m kinda of the opinion there should be one, if not in Clojure core than in a separate clojure.* namespace
18:39weavejesterIt’s not trivial to write efficiently.
18:39weavejesterOr it takes 5 lines or so
18:40weavejesterBecause where possible, you want to use transients, but some map types can’t be converted to transients
18:40weavejesterAnd reduce-kv is more efficient than just into {}
18:40{blake}It just felt like something that could be done with a zipmap.
18:41weavejester{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:42weavejester{blake}: Sure, it works, IIRC, but only due to implementation details
18:42weavejesterTo do it right you want something like: https://github.com/weavejester/medley/blob/master/src/medley/core.cljx#L49
18:43weavejesterAnd even that’s wrong for any non-hash non-array maps
18:43Bronsaweavejester: keys and vals are guaranteed to be ordered consistently
18:43Bronsa,(doc keys)
18:43clojurebot"([map]); Returns a sequence of the map's keys, in the same order as (seq map)."
18:43weavejesterI need to add in some additional conditions. I think one of the other utility libraries has a slightly more comprehensive version
18:43Bronsa,(doc vals)
18:43clojurebot"([map]); Returns a sequence of the map's values, in the same order as (seq map)."
18:44weavejesterOhh
18:44weavejesterIt never used to be
18:44Bronsaweavejester: it's a recent addition to the docstrings
18:44weavejesterI guess they changed it from “implementation detail” to “defined behavior”
18:46BronsaI'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:47weavejesterBronsa: Yeah, it implies (seq map) is consistent, but…
18:47ewingdI'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:48weavejesterewingd: No promises, but post the code and I’ll take a look :)
18:48dbaschewingd: paste a gist / pastebin / refheap
18:48ewingdhttps://gist.github.com/ewingd/f71cf27b90bd231d179b
18:48ewingdthanks
18:48weavejesterLike a seq, I reserve the right to be lazy
18:48TimMc(realized? weavejester)
18:49weavejester#<weavejester: pending>
18:49weavejesterWait
18:49weavejesterfalse
18:49weavejester:)
18:50weavejesterewingd: So, you might want to format the code in a more standard way… And there’s a def in a doseq there…
18:50arrdem&(Long. 0xFFF5)
18:50gfredericks,0xFFF5
18:50clojurebot65525
18:50weavejesterewingd: Though those aren’t a NPE
18:50gfredericks,(Long. 0xFFF5)
18:50clojurebot65525
18:51ewingdWhen I run the code I get the correct output, but the first test run gets the NPE thrown. The rest all pass
18:52hiredmandef defines a top level name, clojure is not like scheme
18:52weavejesterewingd: The first test run?
18:53weavejesterewingd: Like clojure.test?
18:53ewingdweavejester: the test cases that hackerrank.com runs on the submitted code
18:54weavejesterewingd: Do you have a link to the question?
18:54ewingdweavejester: https://www.hackerrank.com/challenges/service-lane
18:54weavejesterewingd: If the wrong data is put in, any part of it could be nil potentially.
18:58weavejesterewingd: You’ve mixed up N & T in the test case, which might be the problem
19:00weavejesterThe definition of this problem is really hard to read
19:00ewingdweavejester: Yes it is.
19:01myguidingstarhi all, I have a noob question
19:01myguidingstarcan tranducers be used to alternate all reducers? if yes, is it recommended to do so?
19:03weavejestermyguidingstar: At the risk of being wrong, I believe transducers cover the functionality of reducers. It’s a more general abstraction.
19:04weavejesterThat said, I haven’t played around with them much
19:04weavejesterewingd: Okay, I think I see what the question is asking for now
19:05weavejesterFind the minimum value between two indexes of an array
19:05ewingdyes, which is exactly what I am attempting to do in that solution
19:06weavejesterewingd: I think your problem is that the first line is “N T”, and you run (read-string “N T”) which gets you N
19:07myguidingstarweavejester, I 'feel' the same, and my current guess is that traducers are a re-design of reducers
19:07weavejesterYou then use N in place of T to get the number of tests
19:08ewingdweavejester: thanks, I'll give that a try. Is there a better approach I can take to reading the test case input lines?
19:09weavejesterewingd: 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:10weavejesterewingd: It might sound trivial, but programs are written once, read many times. Readability is super important.
19:10ewingdweavejester: I completely understand. I just haven't seen examples of normal code yet
19:11weavejesterewingd: 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:12weavejesterewingd: Give me a minute and I’ll put together an example of code
19:13ewingdweavejester: Thanks, I was just about to ask for one.
19:13dnolen_myguidingstar: not sure what you are saying
19:13dnolen_cfleming: macroexpand can't come soon enough :)
19:14cflemingdnolen_: Hehe, ok, I'll get on it.
19:14cflemingdnolen_: I'm working on some formatting problems right now which will make pretty printing expansions much nicer.
19:15dnolen_cfleming: nice, thanks for the indenting flag btw, it's great
19:16cflemingdnolen_: 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:16myguidingstardnolen_, are transducers the new, 'better' reducers?
19:17amalloymyguidingstar: broadly, yes
19:18myguidingstarso is it recommended that one should start with transducers instead of reducers?
19:18amalloyyes. don't bother with reducers; they haven't seen any major changes since their original introduction, and not much use since then either
19:18myguidingstarokay, thanks lot
19:19nkozoamalloy: transducers totally replaces reducers?
19:20nkozoI mean, using transducers you can do everything you can do with reducers? I must study both yet :)
19:20dnolen_nkozo: more or less - you can use transducers w/ parallel fold anyway - so you're not missing out on anything
19:20nkozogreat
19:20amalloynkozo: 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:21amalloybut transducers are a more general concept; reducers are a special case of transducers, so to speak
19:25weavejesterewingd: Take a look at: https://gist.github.com/weavejester/040fa26b7fc1918f9144
19:25weavejesterewingd: I’ve tried to minimise new concepts in that gist
19:26ewingdweavejester: Thanks
19:29weavejesterewingd: And this is the same code, just written with some more advanced features of the language: https://gist.github.com/weavejester/040fa26b7fc1918f9144
19:30weavejesterewingd: 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:30ewingdweavejester: 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:31weavejesterewingd: It definitely is.
19:32weavejesterewingd: 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:35ewingdweavejester: Sounds good. I'm sure I'm going to have enough to keep me busy for a while with those samples
20:09arnaudsjHi, 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:10justin_smitharnaudsj: that's how inner classes are specified in clojure interop
20:10arnaudsjIn 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:11arrdemarnaudsj: it looks like Scala is generating a different class for each arity of the function.
20:12arnaudsjarrdem: that's what I thought, but then I get this in the REPL
20:12arnaudsj=> (TwitterUtils/createStream$default$3)
20:12arnaudsj#<Nil$ List()>
20:13arnaudsjwhich 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:14arrdemarnaudsj: I suspect you're hitting line 82 not 38
20:16ed-gHello. 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:16arnaudsjhttps://www.irccloud.com/pastebin/1b2nzcFi
20:17arnaudsjI think in this case it is line 55
20:17ed-gIs there a basic tutorial out there somewhere? (not the one in core.async/examples git)
20:17arrdemarnaudsj: looks right to me.
20:17arrdemarnaudsj: single line pastes like that are OK in channel
20:18arnaudsjarrdem: my question is how I can verify it is hitting the right function / arity because I want to pass a second arg (filters)
20:18bbloom_ed-g: generally, you want to use alt! which is macro sugar over alts!
20:18bbloom_ed-g: you only need to use alts! when you have a dynamic set of channels to read from, which is reasonably rarae
20:18bbloom_rare*
20:18arrdemarnaudsj: you should be able to hit that same static method with different arities and have it behave.
20:19arrdemarnaudsj: you could always take the disassembler to the bytecode and verify what it does by hand :P
20:19arnaudsjbecause passing a second args does not seem to do the trick:
20:19arnaudsj=> (TwitterUtils/createStream sc ["test"])
20:19arnaudsjIllegalArgumentException No matching method found: createStream clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:80)
20:19ed-gbbloom_: thanks! yes I do have dynamic channels but I am merging them using mix / admix
20:19arnaudsjarrdem: 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:19arrdemarnaudsj: is that a "raw" Java array or is that a Scala "Array" class?
20:20arrdemarnaudsj: because that looks like a type missmatch error to me
20:20arrdembrb FPGA build done debugging
20:20bbloom_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:21arnaudsjarrdem: 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:21TEttingerscala's Array IIRC is a class, not a primitive. Java's is a primitive
20:22arrdemarnaudsj: http://grimoire.arrdem.com/1.6.0/clojure.core/to-array
20:22arrdemarnaudsj: no idea about making a Scala array out of it sorry
20:23TEttingeralso, http://grimoire.arrdem.com/1.6.0/clojure.core/make-array/
20:24justin_smitharnaudsj: into-array if the array needs any type other than Object
20:24TEttingerScala Array should just involve a constructor...
20:24arnaudsjarrdem: this seems to work
20:24arnaudsj(TwitterUtils/createStream sc (into-array ["test"]))
20:24TEttingernice, arnaudsj!
20:24arrdemarnaudsj: yeah that was my guess
20:24TEttinger(inc justin_smith)
20:24TEttinger(inc arrdem)
20:24TEttingeraw, lazybot is down
20:25arrdemT_T THE KARMA NOOOOOO
20:25arrdem:P
20:25TEttingerRaynes ping
20:25arnaudsjarrdem: thank you! There is much I still need to learn about Clojure Java/Scala Interop.
20:25arnaudsjTEttinger: thank you!
20:25TEttingerclojure java interop is... easier
20:25TEttingerno prob!
20:25arrdemarnaudsj: I'm like 80% scala interop from Java isn't generally possible
20:25ed-gbbloom_: 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:25arrdembut Clojure/Java interop is gr8
20:26arrdemJava/Clojure interop.... is improving
20:26TEttinger(inc justin_smith)
20:26TEttinger(inc arrdem)
20:26arnaudsjarrdem: 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:26bbloom_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:27lazybot⇒ 93
20:27lazybot⇒ 37
20:27TEttingerhow is arrdem's karma not higher? you make grimoire!
20:27arrdemthis is an open question :P
20:27TEttinger$karma TEttinger
20:27lazybotTEttinger has karma 25.
20:28bbloom_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:28arrdemI 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:28TEttingersame here
20:28ed-gbbloom_: gotcha. And it looks like I can tell which channel was selected since it can be bound to within each expression.
20:28TEttingersince that's all I can answer, no core.async or macro answers for me
20:28bbloom_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:28arrdemclearly we need to patch lazybot to detect "thanks!?" messages and auto-inc
20:29bbloom_so that [c t] is a vector of two channels to take from
20:29TEttingerI just added a feature to my lazybot fork that augments its quotegrabs
20:29TEttingeryou can now get all quotes by a nick dumped to pastebin
20:29arrdemo nice!
20:30bbloom_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:30TEttingermostly the quotes are grabbed when someone says something terrible, but one guy says some great stuff https://www.refheap.com/91824
20:30bbloom_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:31bbloom_ed-g: got it?
20:31arrdemTEttinger: .....
20:31arrdemTEttinger: this is hillarious. thank you.
20:31vermawould it be ok if I use clojure logo on my presentation?
20:31TEttingerverma: I think it's CC-licensed
20:32vermaah nice TEttinger, thanks
20:32ed-gbbloom_: okay this is starting to make sense. It's a nice terse syntax. I really appreciate the help.
20:32verma(inc TEttinger)
20:32lazybot⇒ 26
20:32TEttingerI'll check the wiki, verma
20:34bbloom_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:35TEttingerwikipedia seems to think it's public domain, verma https://commons.wikimedia.org/wiki/File:Clojure-icon.gif
20:35technomancyit's not public domain
20:35TEttingerI was wondering
20:35technomancybut you're probably fine as long as you're not using it for your own product
20:35TEttingeryeah
20:35arrdemThinking of which. Grimoire 0.3.10 is getting close to ready. Feature requests/ideas welcome.
20:35technomancy(like a consulting course or a user group)
20:36ed-gbbloom_: 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:36TEttingeris 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:36vermaTEttinger, lol
20:37vermathanks technomancy, TEttinger
20:37vermaI am using it for a community meetup presentation
20:37vermaor planning to rather
20:37justin_smitharrdem: I go for low hanging fruit questions all the time too. I think I just waste more time on IRC than you do
20:37TEttingerno prob then
20:37arrdemjustin_smith: or something
20:37TEttingeryou might also want to grab the typed clojure logo, verma
20:37TEttingerjust in case for later
20:38vermawhat is that?
20:38TEttingerhttp://typedclojure.org/images/typed-clojure-an-optional-type-system-letterbox.png http://typedclojure.org/
20:39numbertenis there a way to specify that 'lein test' ignore an entire file?
20:39technomancynumberten: yeah, check out test selectors
20:39numbertenthanks :)
20:43arnaudsjhttps://www.irccloud.com/pastebin/cyhmYtLK
20:44justin_smithlein has some catching up to do http://thespacereporter.com/2014/10/maven-orbiter-finds-hydrogen-layer-that-spreads-21000-miles-from-mars/
20:44arnaudsjThis is in reference to: http://twitter4j.org/javadoc/twitter4j/FilterQuery.html
20:44arnaudsjbrb
20:45justin_smitharnaudsj: there is no actual constructer that is just a number, which constructor are you trying to use?
20:46justin_smithit tried the only one-arg constructor, which takes an array of long (that is what caused the error message you see)
20:46arnaudsjjustin_smith: just passing a long, which should default to the follow param if I look at the definition
20:46vermaTEttinger, thanks! will do
20:46justin_smitharnaudsj: there is no such constructor
20:47justin_smithlong[] follow means array of long
20:47arnaudsjFilterQuery(long[] follow)?
20:47justin_smithright, that means array
20:47arnaudsjok my bad
20:47TEttingerverma: 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:47justin_smith(FilterQuery. (into-array Long [123123]))
20:49ed-gwell that code managed to lock up my browser
20:53ed-gis 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:54bbloom_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:54arnaudsjjustin_smith: hmmm, still no go => (FilterQuery. (into-array Long [123123]))
20:54arnaudsjClassCastException [Ljava.lang.Long; cannot be cast to [J
20:54bbloom_ed-g: is your alt! writing to any sliding or dropping channels? or is there a :defualt clause?
20:54ed-gbbloom_: gotcha
20:55bbloom_ed-g: chances are you're just writing repeatedly forever in to some place that won't ever block
20:55bbloom_ed-g: what's in your alt?
20:55ed-gbbloom_: I am only reading from channels ( cljs-http get operations) but they are also merged in an mix which may change things
20:55TEttinger,(into-array long [123123])
20:55clojurebot#<ClassCastException java.lang.ClassCastException: clojure.core$long cannot be cast to java.lang.Class>
20:56ed-gbbloom_: large. is there a pastebin for this channel?
20:56TEttinger,(long-array [123123])
20:56clojurebot#<long[] [J@e5e57b>
20:56bbloom_~paste
20:56clojurebotpaste is https://refheap.com/
20:57TEttingerarnaudsj: [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:58arnaudsjTEttinger: thank you, I needed to understand the difference between (into-array [123]) and (long-array [123])
20:58TEttingerarrays are a little black-magic in clojure. there are some good guide out there
21:00ed-galt! block https://www.refheap.com/91826
21:01TEttingerhttp://www.learningclojure.com/2010/09/macros-and-type-hints-metadata-and.html arnaudsj
21:01TEttingeralso, arnaudsj: http://asymmetrical-view.com/2009/07/02/clojure-primitive-arrays.html
21:04arrdemTEttinger: Grimoire takes PRs (and soon articles) for community docstrings :P
21:05TEttingerarrdem: what was that in reference to?
21:06arrdemTEttinger: you just dug up a bunch of crap about arrays that could go in the notes while someone here still remembers it
21:06TEttingeroh ok
21:06TEttingeruh, should I fork grimoire?
21:07TEttingerseems a bit convoluted
21:07arrdemTEttinger: just go to into-array's page and click the "edit" link on the community docstring :P
21:07TEttingeroh phew
21:07arrdemTEttinger: that does all the forking/merging crap for you.
21:09arrdemoh balls I totally broke my edit links
21:09arrdemwhelp
21:10TEttingeredit link 404s yeah
21:10arrdemguess I'm rushing out a half baked 0.3.10 tonight then
21:10arrdemTEttinger: https://github.com/clojure-grimoire/grimoire/edit/develop/resources/store/org.clojure/clojure/1.6.0/clojure.core/into-array/extended-docstring.md
21:11TEttingerYou need to fork this repository to propose changes.
21:11TEttingerI need to eat dinner to propose changes.
21:11arrdemlol
21:16ed-gokay 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:19nullptred-g: this looks a bit suspicious (def stops-data-chan (http/get stops-url {:channel stops-data-chan}))
21:21ed-gnullptr: it does, doesn't it? I'll rewrite as a let and without self-reference
21:23bbloom_ed-g: a nil means the channel is closed
21:23ed-gbbloom_: I've heard that, but why then is it still returning data in alt! ?
21:24bbloom_ed-g: it's not returning data, it's reported that it's closed
21:25TEttingerarrdem: do I need to fork the repo?
21:25ed-gbbloom_: oops I should rephrase that. why is alt! executing blocks for closed channels?
21:25bbloom_ed-g: it does exactly the same thing as trying to read from a closed channel outside of an alt!
21:26bbloom_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:28ed-gbbloom_: 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:29bbloom_ed-g: you can just exit the loop if one of your inputs has been closed...
21:29bbloom_ed-g: you can detect that by examining the value that was given to you
21:29bbloom_ed-g: if it's nil, the channel was closed, and now your alt! is no longer sensible to re-enter
21:29bbloom_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:29ed-gbbloom_: 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:30bbloom_it really depends on your use case
21:30nullptrin the one you presented, you could have separate go blocks to avoid having to maintain a dynamic list of non-closed chans
21:31bbloom_ed-g: but you can just use the merge function
21:31bbloom_ed-g: https://github.com/clojure/core.async/blob/master/src/main/clojure/cljs/core/async.cljs#L674
21:31ed-gnullptr: oh that would be great! I didn't know that was possible.
21:32bbloom_ed-g: you do know you don't need to use alt! to read from a channel, right?
21:32bbloom_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:32ed-gbbloom_: 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:33bbloom_ed-g: what do you mean tag results?
21:33bbloom_ed-g: you want to know what channels they came from?
21:33bbloom_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:33bbloom_then merge the mapped channels
21:33bbloom_you gotta start thinking higher level than C :-)
21:34nullptrmap without transducers?! what is this, early 2014?
21:35ed-gbbloom_: yes I need to know the source channel, since results from various JSON url's are handled differently.
21:35nullptri think separate go loops will make this much simpler for your use case
21:35bbloom_ed-g: yeah, you can trivially make multiple go loops
21:36bbloom_ed-g: you may also want to watch Rob Pike's talk about Go: https://talks.golang.org/2012/concurrency.slide#1
21:36ed-gnullptr: it certainly looks like it would be much easier. I assumed that was not available in javascript since it was single threaded.
21:36bbloom_ed-g: and part 2 http://blog.golang.org/advanced-go-concurrency-patterns
21:36bbloom_ed-g: half the entire point of core.async is to give you multiple threads of control cheaply
21:36nullptred-g: yes, it does feel a bit weird but you'll get used to it
21:36ed-gbbloom_: cool, that would be a great starting place.
21:36bbloom_ed-g: you can easily have thousands of running go loops
21:37ed-gbbloom_: I gathered that, but I assumed all loops had to be running lexically under one go macro.
21:38bbloom_ed-g: no, all of the puts and takes have to be lexically within any go macro
21:38ed-gokay time to do some homework.
21:38ed-g(inc bbloom_)
21:38lazybot⇒ 2
21:38bbloom_ed-g: each go creates a new thread of control
21:38ed-g(inc nullptr )
21:38lazybot⇒ 1
21:38bbloom_aw, can i get my inc over at bbloom without the udnerscore? :-)
21:38ed-g(inc bbloom)
21:38lazybot⇒ 46
21:39bbloom_cheers, good luck
21:42amalloy(dec bbloom_) ; can't have counterfeit karma floating around
21:42lazybot⇒ 1
21:42bbloom_(inc amalloy_)
21:42lazybot⇒ 1
21:42bbloom_(inc amalloy_)
21:42lazybot⇒ 2
21:42bbloom_$karma bbloom_
21:42lazybotbbloom_ has karma 1.
21:42bbloom_$karma bbloom____
21:42lazybotbbloom____ has karma 0.
21:42bbloom_amalloy: i'm still up 1
21:54TimMc(inc _______)
21:54lazybot⇒ 1
21:59arrdemTEttinger: if you have to fork then I've got the workflow wrong
22:00arrdemTEttinger: in the past you've just been able to click the "edit" link and go
22:00arrdemTEttinger: it's not a huge surprise that stuff is broken... major internal transitions are underway
22:00TEttingerheh, ok
22:00arrdembut nonetheless it should be fixed.
22:00arrdem /should get fixed
22:01arrdemthe 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:02TEttingerD:
22:09Bruce_Waynehey guys
22:09Bruce_Wayneanyone know datomic?
22:09bbloom_~ask
22:09clojurebotThe Ask To Ask protocol wastes more bandwidth than any version of the Ask protocol, so just ask your question.
22:10Bruce_Waynehow do you write: {:db/id #db/id[:db.part/user]
22:10Bruce_Waynewithout the #
22:11arrdem&(/ 1300 0.78)
22:11lazybot⇒ 1666.6666666666665
22:13Bruce_Wayneso no datomic knowledge out there?
22:14arrdem#clojure is not paid support, no
22:14bbloom_Bruce_Wayne: why can't you use the tagged literal? (that's what that # thing is called in that context)
22:15bbloom_Bruce_Wayne: and i think this is the fn you want: http://docs.datomic.com/clojure/index.html#datomic.api/tempid
22:15Bruce_Wayneaparently No reader function for tag db/id
22:16bbloom_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:16Bruce_Waynebasically clojure is saying how do you read that in a map
22:16bbloom_you don't need the tempid function
22:16Bruce_Waynewhat do I need
22:16Bruce_Wayne?
22:17bbloom_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:17bbloom_and the same search results yield https://groups.google.com/forum/#!topic/datomic/Fi7iXps2npw
22:59cddrWhat'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:24justin_smithcddr: lein install
23:24justin_smithmaybe that's what you meant by local-install
23:29dopamean_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:29dopamean_and i said originally that since my function returns a map if successful i wanted to return some sort of failure map
23:29dopamean_but was discouraged from doing that and i dont recall why. can someone explain why that is a less than attractive option?
23:31justin_smithwhat does clj-http return on failure?
23:32pw_(defprotocol IFoo (foo [this & args])) doesn't work, does defprotocol support fn-like destructuring?
23:32arrdempw_: no
23:32pw_arrdem: ok, thanks
23:32jeremyheilerdopamean_: it's throwing an exception, right?
23:33dopamean_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:33dopamean_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:33dopamean_so i was hoping to be able to sort of handle for all types of situations in one way
23:35jeremyheilerdopamean_: you can.
23:36jeremyheilerspecifcy `:throw-excpetions false` in the opts map
23:37dopamean_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:39jeremyheilerheh ok. just do what you want lol
23:39dopamean_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:40dopamean_ill do it anyway
23:40jeremyheileri don't know. i think it's perferctly fine.
23:40dopamean_cool
23:40dopamean_thanks.
23:41jeremyheilernp. if it helps, that's what i do.
23:41jeremyheilerat least when i need to handle the responses more effectively
23:41jeremyheilererr.. i guess differently
23:41dopamean_i knew what you meant. i write a lot of ruby for work and its something i do somewhat frequently there.
23:42dopamean_so it seemed natural here
23:42jeremyheilercool