#clojure logs

2013-10-15

00:00Raynes&(doc some-fn)
00:00lazybot⇒ "([p] [p1 p2] [p1 p2 p3] [p1 p2 p3 & ps]); Takes a set of predicates and returns a function f that returns the first logical true value returned by one of its composing predicates against any of its arguments, else it returns logical false. Note that f is short-circu... https://www.refheap.com/19823
00:03tsantosRaynes: that sure looks like what I wanted. Testing it out...
00:07tsantosRaynes: yep, works like a charm, thanks.
00:31yeoj___jjkk/quit
01:03dobry-den(File. (clojure.java.io/resource "test.jpg")) ; Error, File doesn't know type URL.
01:04dobry-den(File. (.toURI (clojure.java.io/resource "test.jpg"))) ; Success
01:04dobry-den-__-
01:16satshaba2(:key value) vs (value :key) ------- Fight!
01:17satshaba2no really which is prefered?
01:22SegFaultAXIf your keys are keywords, prefer using the keywords in function position.
01:23RaynesWhichever one looks best in context.
01:23satshaba2hmmmm
01:24satshaba2Well I come from python so I'm more inclined for (mapthing :key)
01:24satshaba2i.e. mapthing[key]
01:25satshaba2but it might make sense to do (:key mapthing) because then I think "key of mapthing"
01:26SegFaultAXTo me (:kw foo) is pretty unambiguous in most situations. (foo :kw) could be a lookup or a normal function call.
01:27satshaba2ahh yes I see
01:27satshaba2ok then (:kw foo) it is!
01:28SegFaultAXsatshaba2: Pick a style and stick with it, that's the most important thing.
01:28satshaba2yes agreed. I pick (:kw foo)
01:28SegFaultAXI just prefer to use (:kw foo) because it's more visually obvious that I'm doing a lookup.
01:28SegFaultAXCool.
01:35bitemyappSegFaultAX: I do the same thing.
01:35bitemyapp(:kw foo)
01:35bitemyappSegFaultAX: the other reason to do it is that some map-like data structures will not implement IFn
01:35bitemyappsuch as datomic entities.
01:36bitemyappsatshaba2: ^^
01:39SegFaultAXbitemyapp: Yup
02:30logic_progis there a clojurescript cookbook ?
02:35eredi just started running through https://github.com/magomimmo/modern-cljs and i'm already impressed
02:35jonasenlogic_prog: I don't think so
02:35eredspeaking of clojurescript anyway
02:35logic_progthe pre-requisite for that page aone would take a year to read
02:36eredi'm only so far into this as idiomatic-for-javascript-but-just-ported-to-clojurescript (.getElementById js/document "email")
02:37eredand even just adding a repl that i can talk to my browser is still really cool
02:37eredcan't wait to see what this looks like later on when it actually gets to idiomatic clojure
02:46shoshinhello, ping.
02:46shoshini have a question that i've been trying to work through a bit.
02:47shoshinhow do i access a value that is present inside a vector.
02:47sm0ke,([1 2 3] 1)
02:47clojurebot2
02:47shoshin[{:a 1 :b 2 :c 3} {:a 4 :b 5 :c 6}] i want to access the values of key :a
02:48shoshinsm0ke
02:48shoshin^^
02:48sm0ke,(map [{:a 1 :b 2 :c 3} {:a 4 :b 5 :c 6}] :a)
02:48clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword>
02:48sm0keoops wait
02:48sm0ke,(map :a [{:a 1 :b 2 :c 3} {:a 4 :b 5 :c 6}])
02:48clojurebot(1 4)
02:48sm0kehehe i am still learning too
02:49shoshinsm0ke thank you! I need to dig more into map and clojure's data structures.
02:49shoshinany resources/pointers?
02:49sm0keshoshin: the vector which you gave has each element as a map
02:50sm0keshadower: now keyword also act as fucntions on maps like ##(:key {:key :value})
02:50lazybot⇒ :value
02:50sm0kefinally the (map) function runs the function passed as first argument on each element of collection and returns the new collection
02:51sm0keoops he left
02:56sm0kehey guys in my project.clj i have defined a :main namespace and also a profile {:package {:aot :all}} ,, but when i gnerate a uberjar using 'lien with-profile uberjar'and try to run with 'java -cp my.jar main.name_space' ,,i get 'could not find or load main class main.name_space'
02:56sm0kealso i see that namespace being compiled while generating uberjar
03:01sm0kei workaround this by putting (:gen-class) in my main namespace..but i dont know if this is the correct way
03:01teromyou will need :gen-class for AOT, so it is not a workaround, but requirement, afaik
03:03sm0kei really dont understand what compilation mean in leinigen
03:03llasramYou don't need :gen-class for AOT, but you do need :gen-class for AOT to produce an actual *class* for the namespace
03:03sm0keis compiling and generating class different?
03:03llasramYes
03:04sm0kereally?
03:04llasramSo on the JVM you do need an actual class to hold bytecode for any functions as method
03:04sm0keisnt compilation means generating class on jvm?
03:04llasramThe way Clojure does that is by having a class per function
03:05llasramSo doing AOT will pre-generate the classes for all of your functions
03:05sm0kebut not my namespace?
03:05llasramExactly. You only get a class for a namespace with e.g. your static main by specifying that that namespace should :gen-class
03:06llasramThat said, you don't need to AOT and :gen-class to get an entry-point, or really even an uberjar entrypoint, even if you really need that
03:06llasramMy preferred approach is to use the `clojure.main` class included in Clojure
03:06sm0kehmm didnt know about that
03:06llasramthen you can do: java -cp my-uberjar.jar clojure.main -m my.name.space
03:07llasramAnd that will run the `-main` method in my.name.space
03:07sm0keoh i see
03:08sm0kellasram: worked like a charm thanks!
03:08sm0kei guess using that approach we can have multiple main methods too
03:08sm0kein deifferent namespaces though
03:10llasramYou can also call `clojure.main` with `-e <string>` to `eval` some arbitrary string
03:12Jardaif I have a dependency from clojars that is causing me trouble, how can I install it locally to get possibility to fix it
03:13JardaI mean, is there a way of doing git-dependencies or such with leiningen2
03:13teromllasram: Hmm. I usually produce uberjars so that I can java -jar my-uber.jar, but that didn't occur to my mind that I could then also do that. Seems logical though, now that I think more of that.
03:13eredJarda: try lein-localrepo?
03:13eredhttps://github.com/kumarshantanu/lein-localrepo
03:14eredthere might be something better than that
03:14llasramJarda: If the project is using lein already, you don't need a plugin. Just checkout and `lein install`
03:14llasram(w/in the project)
03:14eredoh that's easier than mine :D
03:15Jardallasram: so if my project is in ~/projects/myproject, where should I checkout the dependency?
03:15Jardaoh, or do you mean it can be wherever and leiningen will just know where to fetch the dependency
03:15llasramOh, well
03:16llasramSo if you `lein install` it'll install the version that project's project.clj declares it to be; i.e., probably some SNAPSHOT release
03:16llasramIf you just want to pull the dep in as source in your project, that's what "checkout" dependencies are for
03:17llasramCheck the second project out wherever you like, then
03:17llasramin your project create a directory called "checkouts", and w/in that dir make a symlink for the dependency named for the dependency artifact basename
03:18llasramJust linking to the dependency project top-level directory
03:18llasramThe lein doco has more details
03:19Jardahttps://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md#checkout-dependencies ?
03:19Jardathanks :)
03:19eredllasram: neat, i'll have to remember that one
03:19llasramterom: Yeah. I used them when I first started doing Clojure, but at this point I'm actually not entirely certain what uberjar main functions are really for. I *always* need e.g. a wrapper shell script anyway
03:19llasramJarda: yep, and np!
03:19sm0kei think the only problem is when the external project installs on ivy
03:19eredi have a few things i'm going to be working on soon where i'll be working on a project, but also a couple supporting libraries, in parallel
03:19sm0kelein cant fetch from local ivy repos
03:20llasramYeah, if the external dep doesn't use lein, then you need to e.g. use `mvn` (or maybe lein-localrepo -- haven't used) to make it available locally
03:20sm0kebut who uses ivy anyways..
03:21sm0keno one uses scala from clojure is guess
03:21llasramAt least not directly much thus-far
03:22teromllasram: true, I seem to find that also. In some rare cases I just want to run uberjar as-is. I guess if I have some GUI application it makes more sense. (On Windows, I can then just double-click the .jar to launch it)
03:23sm0kei think clojure interop with scala will be nasty..specially with Scala people using case classes almost everywhere
03:23sm0kei dont know how well clojure treats case classes
03:24llasramterom: Yeah, that may be true. Although the one time I've needed that so far, I used the `lein-exec` approach of embedding a prefix combo sh/.bat script at the beginning of the file
03:24sm0kealso one more with with that clojure.main approach.. i had to replace underscore with hyphen
03:24sm0kedont know what thats all about
03:25llasramsm0ke: Does your namespace have an '_' in it?
03:25sm0keyes
03:25llasramInteresting
03:25llasram&(map munge ["some-name" "same_name"])
03:25lazybot⇒ ("some_name" "same_name")
03:26llasramClojure name munging for JVM representation isn't reversible
03:26llasramAnd since "-" is munged to "_"
03:26llasramusing "_" kind of humorously can get you into trouble sometimes
03:26llasramBest to just stick w/ convention and use "-" :-)
03:27sm0kellasram: no no wait i think you misunderstood
03:27llasramTOO LATE
03:27sm0kellasram: i have _ in my namespace's parent folder name
03:27sm0kelike org_some/namespace
03:28sm0keinside clojure file i write it as org-some.namespace
03:28sm0kei think thats the convention in clojure
03:28llasramOh, ok, yeah. So the actual name of the namespace is "org-some.namespace", which is in fact what you need to pass to clojure.main
03:30sm0kellasram: yes but if you put (:gen-class) in yu ns and invoke it deirectly via java -jar you have to put _ in main ns
03:30llasramsm0ke: Right -- because then you're directly feeding the munged JVM name to the `java` command
03:31sm0kehmm ok weird enough.. i am just wondering why didnt i make a folder by name 'org-some' in the first place then
03:33sm0keaha .. http://stackoverflow.com/questions/4420944/why-does-clojure-convert-dashes-in-names-to-underscores-in-the-filesystem/4451693#4451693
03:34sm0keso much for java interop
03:34llasramYeah, that's the ultimate reason. And for directories is just simpler -- otherwise your build tool would need to munge each directory name when adding stuff to the JAR, which has a lot of confusion-potential
03:34llasramEspecially for e.g. resources
03:36sm0keyeah makes sense
03:37sm0kebut i really was hoping clojure.main would automatically convert between _ and - by itself for its argument
03:38sm0keanyhoo its trivial to nag for
03:38llasramEh. It explicitly takes the Clojure namespace name. You can't in Clojure (:require 'org_some.namespace)
03:39sm0kegot it!
03:54glosoliHow does one define snippet in Enlive with optional arguments ?
04:02muhoowhy (-> (foo "bar") baz quuz) not (-> "bar" foo baz quuz) ? i see that pattern and wonder why
04:03llasrammuhoo: Starting with (foo "bar"), adding the -> and not thinking about it is my guess :-)
04:03llasramI did see someone once here claim that they found e.g. (-> "some-path" io/file .exists) confusing though
04:09muhooit is kind of rpn-ish i guess
04:09muhooin datomic it's common to have (->> (d/q '[massive bunch of stuff ]) foo bar baz) though
04:10llasramHuh
04:10llasramInteresting
04:11muhoobut if there's just one arg to that first function, i don't see why not just thread it in with everything else
04:11llasramYeah, I'm with you there
05:06talios'lo cemerick
05:08cemericktalios: Hi Mark :-)
05:09taliosusing pristmatic schema of course, gotta have my types!
05:10dcunit3dwhere do u work lol
05:10glosolidcunit3d: lol, we find it easier to collect and manager your data with Clojure :D
05:10glosoliat NSA :DD
05:10dcunit3dlol
05:10taliosdcunit3d: http://www.smxemail.com - move to New Zealand and work for us ;)
05:11glosolidcunit3d: Small company in Europe Lithuania :) you wouldn't know ;d
05:11glosoliStill kinda fun though
05:11taliostho currently we're desperate for some coffeescript/javascript skilz
05:11cemericktalios: good deal. No typed clojure tho?
05:11dcunit3dnew zealand sounds fun. anywhere with good mountains sounds fun
05:12dcunit3di'm currently in boulder, but haven't found much clojure here yet
05:12talioscemerick: looking at it :) we have ambrose on the podcast again last week, I see schema plans to maybe also compile out core.typed annotations which could be good
05:12dcunit3dcolorado
05:12cemerickdcunit3d: talios uses osgi *voluntarily*. Serious warning sign, right? ;-P
05:12cemericktalios: yup, I heard, enjoyed it :-)
05:12talioslolz, if we could drop it we would. Altho, I'd rather keep OSGi and dump hibernate first :)(
05:13talioscemerick: had to do some 'creative' editing with the intro to ambrose as we wern't sure if he was showing up or not, then turned up in the middle of recording ;0
05:14talioscemerick: i'm missing your show - record!!!
05:14glosoliwhat kind of show ?
05:15cemericktalios: yeah, I know. It's been tough to squeeze it in of late. :-(
05:16taliosglosoli: cemerick's clojure podcast, and my "generic software development maven build love/hate scala/clojure/frege" podcast
05:16glosolitalios: where??
05:16lazybotglosoli: Definitely not.
05:16llasramIs lazybot a bit spastic???
05:16lazybotllasram: Oh, absolutely.
05:17taliosglosoli: http://www.illegalargument.com/ is mine, latest show has Ambrose on talking about core.typed ( his 2nd appearance )
05:17cemerickglosoli: http://mostlylazy.com
05:17talioscemerick himself is mostly lazy, so hasn't recording in a LONG time.
05:17glosoliDamn guys, thanks! :)
05:18cemericktalios: that was an intentional reference :-)
05:18cemerickI didn't want people to think it'd be a regular thing...but I didn't mean for it to be quarterly, either.
05:18taliosglosoli: I think the two interviews with Ambrose, and the one we did with James Ladd on Redline Smalltalk are our most listened to shows ( and most enjoyable to record )
05:19glosolitalios: I never heard of them... (a bit out of date here) will have to catch up today! :)
05:19talioscemerick: could you worse, you could have been like arbscht and started "The Weekly REPL" podcast, do 4 episodes and stop :)
05:19cemerickhah, yeah
05:21taliosfor awhile, we considered getting arbscht on our show regularly, but then we'd have 3 cohosts all at the same company :)
05:21taliosand I think theres only so many ways we can mangle the company name
05:23taliosanyone tried out Cursive here? Been using the EAP all week and it's so much better than La Clojure from Jetbrains
05:24glosolitalios: is it truth that cursive will become commercial at some poitn ?
05:24glosolipoint"
05:25taliosglosoli: that's colins aim yes, I believe Jetbrains are also going to seed the clojure space to Cursive so as to not compete
05:26sm0keis anyone working with light table too?
05:26glosolitalios: Kinda makes me want to stay way from it, until I learn about the pricing
05:26taliosLa Clojure was never really had anyone full time on it anyway
05:27glosoliYeah :) just because of Clojure I got used to Emacs, and even used tried vim lol
05:28taliosglosoli: I'll chase up Colin on pricing ( he's supposed to be hotdesking next to me for the next week or so ), I think he wants it to be cheap, comparable in pricing to some of the cheapers JB offerings I think
05:28sm0kevim does pretty good with clojure
05:29taliosI've dabbled with emacs for the last 20 odd years, and I still can't grapple the archaic key cording
05:30glosoliDunno it kinda felt easy for me (though I hadn't used it more than half year)
05:40Jardais anyone aware of a clojurescript core.async wrapper for making xhr requests?
05:47sm0kethat would be cool
05:48Jardahttp://dimagog.github.io/blog/clojure/clojurescript/2013/07/12/making-http-requests-from-clojurescript-with-core.async/
05:48sm0kei think there are some old libraries which wrap jQuery..like jayq
05:48Jardathis is cool, but I'm looking more like a complete library to use
05:48sm0keit wont be hard to put that in a core.async channel goroutive
05:49Jardasm0ke: yeah that blog post shows just that (using goog.net XHR)
05:49Jardabut I don't feel like wrapping callback code by myself
05:51sm0keJarda: hmm well i dont know what clojure experts have to say about it..but core.async just need the most minimal changes...its pretty un intrusive way of introducing async behaviour
05:52sm0kecoming from scala and working with actors i dont mind put a feww go blocks and >! !<
05:53sm0kelet me know if you find one
05:53sm0ke:P
07:02glosoliEnlive question here, I have map consisting of key that stands as element id, and value as error message, any suggestions how could iterate the keys and at the same time be doing selection of these elements, so I could add classes to them ?
07:05notofihi. Why does this code declare 'x' ?
07:06clgvglosoli: since you want to do side effects you can use (doseq [[k v] mymap] (do-somthing k, v))
07:06notofi(defn testfn [] (def x 1))
07:07clgvnotofi: do not use `def` in functions - `def` is only intended for definition of symbols in a namespace and not for "local variables" (= local bindings)
07:07clgvnotofi: you want `let`, e.g. (defn testfn [] (let [x 1] (+ x 2)))
07:07glosoliclgv: hmm now when I thought, all I need to do set same class on several nodes hmm there should be something inbuilt I am not aware of
07:08notoficlgv: I know I shouldn't do this but I am working with some code that uses for example defonce in some init functions. Before that there is a declare, and as I see it this declare is not needed
07:08clgvglosoli: oh you actually search for a way to select all nodes with keys in the map at once?
07:09clgvnotofi: this non idiomatic and probably leads you straight to hell sooner or later ;)
07:09glosoliclgv: I have a list of keywords (which would correspond to the right ids in html template) and I want to select all them at once and apply some action like add-class
07:10clgvnotofi: if you really need to set a value to a variable in a namespace from an init function better define the var with defonce and an atom a value and swap the atom in the init function
07:11notoficlgv: why you shouldn't do this? it seems shorter than using an atom
07:11clgvglosoli: I dont know whether there is a built-in helper for that. since an id should be unique I guess this is not considered basic functionality
07:12glosoliclgv: Ids are unique
07:12glosoliI have a list of ids, I wanna do the selection of them and execute add-class on all of them
07:12clgvglosoli: yes thats what I said ;)
07:12glosoliaa ok
07:13clgvglosoli: you could simply use `map`+ the id selection function
07:18glosoliclgv thanks
07:20clgvnotofi: you can read that up on the mailinglist. the discussion is often repeated.
07:21clgvnotofi: my personal reason is that it will be hard to understand and reason about your code if you use `def` within functions regularly
07:22clgvnotofi: there are better more technical reasons to avoid it
07:28notoficlgv: you know any? :)
07:29glosoliclgv: In case you are curious, that's easily doable by grouping your selectors in set
07:29clgvglosoli: you mean you can use enlive's `select` with a set of ids?
07:31glosolimore like [#{:#some_id :#some_other_id}] (add-class "error")
07:31glosoliI guess it applies select on it, though I don't use select directly
07:34clgvah ok. I only know enlive's `select` from seesaw ;)
08:17augustljson sucks.. I want most keys to be keywords in maps after json parsing, but some keys are numbers, and I want those to be numbers, not symbolized numbers, i.e. :0. But in JSON, all keys are strings. Meh!</rant>
08:21shoshinping
08:21shoshini have a question, give an sequence containing maps how would i try to find if a particular key is present in any of the maps or not?
08:22shoshinfor example ({:a 1 :b 2 :c 3} {:a 4 :b 5 :c 6} {:a 7 :b 8 :c 9})
08:22shoshinhow do i find if the key :a is present in all the maps?
08:22sm0ke_augustl: i think if prsing using cheshire you can opt for keywods as keys (parse-string "{\"foo\":\"bar\"}" true)
08:23rkneufeldshoshin: probably via some
08:23sm0ke_the true flag towards the end
08:23shoshinrkneufeld would some work on a sequence?
08:23rkneufeldshoshin: I think so, give it a go in a REPL.
08:23augustlsm0ke_: teah that's what I do, but then the JSON {"0":"test","5":"bar"} will become {:0 "test" :5 "bar"}, since json sucks :)
08:24sm0ke_augustl: so what do you want instead?
08:25shoshinrkneufeld i tried the following (some #{:a} ({:a 1 :b 2 :c 3} {:a 4 :b 5 :c 6})
08:25shoshinreturns nil
08:26rkneufeldThe list of maps you have isn't quoted
08:26augustlsm0ke_: I want to be able to tell the world that the keys are numbers, not strings, which json doesn't support
08:26Morgawr`(let [a {:a :b :c :d}] (str (map reverse (into [] a))))
08:26rkneufeldshoshin: It's trying to find the first map inside the second (or the other way around…). Add a single quote in front of ({:a 1 ...)
08:27Morgawrhow do I trigger clojurebot? D:
08:27sm0ke_augustl: are you sure?
08:27sm0ke_var a = {3: 4} on my browser repl works fine
08:27augustlsm0ke_: yeah, keys have to be strings. Or, you could of course parse the string and check if it only contains ascii number characters
08:27sm0ke_a[3] also returns 4
08:27augustlsm0ke_: JS will stringify that automatically actually
08:27augustlsm0ke_: and JS != JSON anyway :)
08:27rkneufeldshoshin: hmm, that doesn't work either. Must be something off about the set. It works with :a alone.
08:27shoshinrkneufeld (some #{:a} '({:a 1 :b 2 :c 3} {:a 4 :b 5 :c 6}))
08:28sm0ke_isnt json = javascript object notation?
08:28shoshindoesn't work, yes.
08:28Morgawr&(let [a {:a :b :c :d}] (str (map reverse (into [] a))))
08:28lazybot⇒ "clojure.lang.LazySeq@bc3043e0"
08:28Morgawrhow do I make it not print LazySeq? ^
08:28MorgawrI tried using doall but it doesn't work
08:28rkneufeld&(some #a '({:a 1 :b 2 :c 3} {:a 4 :b 5 :c 6})
08:28lazybotjava.lang.RuntimeException: No reader function for tag a
08:28rkneufeld&(some a '({:a 1 :b 2 :c 3} {:a 4 :b 5 :c 6})
08:28lazybotjava.lang.RuntimeException: EOF while reading, starting at line 1
08:28sm0ke_anyways i am not sure if i understand
08:28rkneufeld&(some a '({:a 1 :b 2 :c 3} {:a 4 :b 5 :c 6}))
08:28lazybotjava.lang.RuntimeException: Unable to resolve symbol: a in this context
08:28rkneufeld&(some :a '({:a 1 :b 2 :c 3} {:a 4 :b 5 :c 6}))
08:28lazybot⇒ 1
08:28Morgawr&(let [a {:a :b :c :d}] (str (doll (map reverse (into [] a)))))
08:28lazybotjava.lang.RuntimeException: Unable to resolve symbol: doll in this context
08:28augustlsm0ke_: not entirely, {foo: "bar"} is invalid JSON
08:28Morgawr&(let [a {:a :b :c :d}] (str (doall (map reverse (into [] a)))))
08:28lazybot⇒ "clojure.lang.LazySeq@bc3043e0"
08:28Morgawr:|
08:29augustlsm0ke_: it has to be {"foo":"bar"} (quote the key)
08:29rkneufeldshoshin: the last one (typing is hard)
08:29sm0ke_augustl: what the...yes of course...its invalid everywhere
08:30shoshinrkneufeld you mean this one? (some :a '({:a 1 :b 2 :c 3} {:a 4 :b 5 :c 6}))
08:30sm0ke_without foo being defined
08:30augustlsm0ke_: considering adding content type negotiation so I can serve EDN which has sets and arbitrary map keys and what not
08:30sm0ke_,{foo :bar}
08:30clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(NO_SOURCE_PATH:0:0)>
08:30sm0ke_,{'foo :bar}
08:30clojurebot{foo :bar}
08:30shoshinrkneufeld i think i need to map the some over the collection.
08:30jonasen_&(let [a {:a :b :c :d}] (pr-str (map reverse (into [] a))))
08:30lazybot⇒ "((:b :a) (:d :c))"
08:30shoshin*sequence
08:31jonasen_Morgawr: ^
08:31Morgawrjonasen_: okay but that is only if I want to use "str" on it, how do I make sure it realizes anyways?
08:31MorgawrI thought doall would realize sequences
08:32rkneufeldshoshin: yeah. Check out https://github.com/clojure-cookbook/clojure-cookbook/blob/master/composite-data/determining-if-a-collection-holds-one-of-several-values/determining-if-a-collection-holds-one-of-several-values.asciidoc – some applies the set to each value of the seq. (#{:a} {:a 1}) is nil, but (#{:a} :a) is :a.
08:32sm0ke_well json is a subset of clojure maps...so yes that would not work both ways
08:32sm0ke_js has no concept of sets
08:33shoshinrkneufeld that helped me understand this! Thank you so much!
08:33jonasen_&(let [a {:a :b :c :d}] (str (seq (map reverse (into [] a)))))
08:33lazybot⇒ "((:b :a) (:d :c))"
08:33augustlsm0ke_: indeed, and some times I want to convey that something is a set, not a sorted list
08:33wakeupHi all
08:34wakeupI get a IllegalStateException I/O in transaction
08:34sm0ke_augustl: may be you want to cosider serialization instead?
08:34wakeupI guess it's because I do a database write during dosync
08:34jonasen_Morgawr: Use seq
08:34wakeupHow do I solve this without using a lock?
08:35sm0ke_augustl: something like nippy?
08:36Morgawrjonasen_: alright, thanks
08:37wakeupAH solved it
08:37augustlsm0ke_: or EDN :)
08:38augustland content negotiation where the client says which content types it accepts, HTTP style
09:21clgvwakeup: if you want to do sequential I/O from transactions agents fit pretty well for that
09:22tbaldridgewakeup: a little more context may help as well. What is the lock doing?
09:49rurumatewoohoo from euroclojure
09:50rurumatethey finally got the wlan running
09:51mdrogalis:)
09:51ssideris1hey! I'm there (here) too
09:51ambrosebshello euroclojure!
09:52mdrogalisWhat city is it in?
09:52rurumateberlin
09:53mdrogalisSounds terrific
09:53rurumatewhy is everyone saying haitch-tml today, pronouncing the letter H this way? is this a new fancy way to speak?
09:54ssideris1rurumate: I think it's a british thing
09:55rurumateapparently not everyone agrees on that: http://www.youtube.com/watch?v=c3y0CD2CoCs
09:57dobry-dentbaldridge: That was a good macro vid
10:00mdrogalisdobry-den: Yeah I learned a lot from that screencast.
10:00mdrogalisIf it's the one I think you're talking about, heh.
10:08tbaldridgedobry-den: great! I'm glad it helped
10:09silasdavisI've currently got some code that uses the AmazonS3Client directly and I was considering the merits of using: https://github.com/weavejester/clj-aws-s3/blob/master/src/aws/sdk/s3.clj
10:09silasdavisbut it looks like that doesn't allow you to create an s3-client with the parameter-less constructor
10:11silasdavisCurrently I am using the parameter-less constructor and an instance profile on elastic beanstalk which has s3 credentials attached which the S3 client knows how to find if given no creds
10:12silasdavisshall I just stick with the java SDK?
10:12tbaldridgesilasdavis: I find little reasons not to use bare Java APIs for most things
10:12tbaldridgemany wrapper libraries don't add much in the way of clojure integration, and simply restrict your options.
10:13silasdavisgreat, that was the sort of validation I was after, I use the bare api, seems nice enough anyway
10:44wakeup(seq (take ....)) is not lazy or is it?
10:44llasramwakeup: Why would it not be lazy?
10:44tbaldridgewakeup: it's lazy
10:44wakeupdo I need to use doall?
10:45llasramNot if you want it to be lazy :-)
10:45tbaldridgewakeup: yep, or do vec on it. I often prefer to make all my non-lazy seqs into vectors.
10:45wakeupis pmap lazy?
10:45tbaldridgewakeup: yep
10:46wakeupok
10:46Morgawrit's semi-lazy :P
10:46tbaldridgewakeup: if it deals with seqs, it's lazy. Unless specified otherwise.
10:46Morgawr&(doc pmap)
10:46lazybotjava.lang.SecurityException: You tripped the alarm! pmap is bad!
10:46Morgawr:|
10:46Morgawrdang lazybot
10:46tbaldridge,(doc pmap)
10:46clojurebot"([f coll] [f coll & colls]); Like map, except f is applied in parallel. Semi-lazy in that the parallel computation stays ahead of the consumption, but doesn't realize the entire result unless required. Only useful for computationally intensive functions where the time of f dominates the coordination overhead."
10:46tbaldridge:-P
10:46Morgawrthanks :P
10:47wakeup,(doc doall)
10:47clojurebot"([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. doall can be used to force any effects. Walks through the successive nexts of the seq, retains the head and returns it, thus causing the entire seq to reside in memory at one time."
10:47tbaldridge&(let [pmap 42] 42)
10:47lazybotjava.lang.SecurityException: You tripped the alarm! pmap is bad!
10:47tbaldridgelol
10:47mdrogalisBad tbaldridge D:
10:47Morgawrtime to report to the authorities
10:47Morgawrkeep calm and don't panic
10:47mdrogalisGet this guy outta here, he's using pmap. D:
10:48tbaldridgeI like to live dangerously
10:52wakeupWhat about ref's, I seem to be unable to predict their value,
10:52wakeupanything I should know about using deref?
10:52mdrogaliswakeup: Predict?
10:57tbaldridgewakeup: I agree with mdrogalis I don't understand the word "predict" in this context.
10:57mdrogalis(crystal-ball IRef)
10:57mdrogalisBacked by data.generators 'anything' function :)
11:16sm0keis the quick sort example in joy of clojure the worst example ever or what?
11:16sm0kei remember reading a quicksort in lyah
11:16sm0keclojure version is hedious
11:17benmosswhats bad about it
11:18llasramsm0ke: If the version of quicksort in LYAH is pretty, I'm willing to bet that it isn't really a quicksort
11:19sm0kehttp://learnyouahaskell.com/recursion ... its pretty neat
11:20llasramActually, now that I'm looking at them, neither one is actually quicksort
11:21wakeupNullPointerException clojure.core/fn--5420 (core_print.clj:187)
11:21wakeupI can't see em any more...
11:22indigowakeup: :P
11:22indigoI like your nick, btw
11:22indigoHelps me wake up in the morning xP
11:22wakeupI am serious though
11:23wakeuphow am I supposed to debug my concurrent shit if I get NPE's from
11:23wakeupcore_print ?
11:23tbaldridgewakeup: code paste?
11:24dnolensm0ke: you can write a very nearly that neat in Clojure
11:24dnolens/very/version
11:26wakeuptbaldridge: having trouble locating where the exception comes from.
11:26wakeupno stack trace either.
11:26tbaldridgehttps://github.com/clojure/clojure/blob/master/src/clj/clojure/core_print.clj#L187
11:26wakeupmight as well segfault.
11:26tbaldridgeeven print-stack-trace on *e gives you nothing?
11:30llasramsm0ke: ##((fn qsort [[x & xs]] (if x (let [smaller? (partial >= x)] (concat (->> xs (filter smaller?) qsort) [x] (->> xs (remove smaller?) qsort))))) (repeatedly 20 (partial rand-int 256)))
11:30lazybot⇒ (0 17 27 29 46 64 74 113 119 121 126 145 171 174 184 185 194 197 206 245)
11:30llasramsm0ke: The version in /JoC/ is lazy, which takes a bit more work
11:37zerokarmaleftsm0ke: the beauty of the lazy JoC version is that if you select into the sorted result (with nth or drop & take, etc.), the algorithm only sorts the partitions necessary to give you the correct result
11:38sm0kei guess..its beyond me..i am still a beginer
11:39sm0kebut still the structure of loop is bit confusing .. specially the recur call is hard to understand
11:40sm0kelist* with 4 arguments..crazy
11:50indigoQuick question
11:50indigoThere is some fizzbuzz code on rosettacode written in Clojure
11:50indigohttps://www.refheap.com/19834 <-- do you really need a lazy-seq considering there's already an iterate there?
11:51Morgawrmm. considering map is lazy, I'd say you don't need the lazy-seq but I'm not 100% sure
11:51mdrogalisI believe you can forego it.
11:52indigoIt works if I forego it, but I'm just wondering if there is a reason that it was there
11:52Morgawrindigo: overengineering probably :P
11:53indigoMorgawr: Heh yeah, maybe I'll go ahead and update it on Rosetta Code
11:53indigoConcise code ftw
11:54mdrogalisSpeaking of Fizz Buzz https://gist.github.com/MichaelDrogalis/4684403
11:54mdrogalisThis is still hilarious to me.
11:55stuartsierraheh
11:55glosolilol
11:55zerokarmaleftmdrogalis: haha
11:56indigoHeh
11:56indigoToo bad he didn't put the numbers in
11:57mdrogalisindigo: Yeah I think I got close enough and enjoyed that answer a lot, so I stopped. :P
11:57si14is there anyone who use Prismatic's Schema with CLJS?
11:58si14got my build suddenly broken, just a ton of "Use of undeclared Var [record-name-here]"
11:58indigoIf anyone I interview writes FizzBuzz in Clojure, they're getting hired on the spot :P
11:59mdrogalisindigo: Even with my non-modulus magic?
12:00indigoYep :P
12:01indigoThen I can have a buddy to complain about PHP with
12:01wakeupNow what could that hint to? java.util.concurrent.ExecutionException: java.lang.NullPointerException
12:01wakeup at java.util.concurrent.FutureTask$Sync.innerGet
12:02marcopolo2indigo: I used to work at a php shop, I feel your pain
12:02indigoHehe
12:04dgrnbrgIs there a way in compojure or another accepted library for mounting a ring handler at a context path?
12:04jonasen_si14: did you update cljs?
12:04si14jonasen_: yes. -1934 now
12:05clojurebotHuh?
12:05jonasen_si14: did you run lein cljsbuild clean?
12:05si14jonasen_: yes
12:06jonasen_si14: do any of the warnings point to a particular file/line-number?
12:07si14jonasen_: yes. it looks like this: https://gist.github.com/si14/d7e5254391cffc2c51f7
12:07si14jonasen_: but for all records, actually
12:09indigoI think I killed RosettaCode :<
12:09indigoOh no, nvm, it's back up again
12:10noncomif i have (defn hey [x] (+ 1 x)), how do i pass "hey" to a macro so that it gets passed not as 'hey, but as the form itself? or at least as the generated IFn object?
12:11llasramnoncom: You don't
12:11si14jonasen_: when I run generated stuff in browser I get "Uncaught TypeError: Cannot set property 'schema$utils$schema' of undefined "
12:11mdrogalisNew talk by Rich up on InfoQ :)
12:12noncomllasram: oh sad..
12:12llasramnoncom: Why? You really don't need that
12:12noncomwait i make a simple example, maybe you can give a hint
12:13llasramok
12:14marcopolo2mdrogalis: link?
12:17mdrogalismarcopolo2: http://www.infoq.com/presentations/datomic-functional-database?utm_source=infoq&amp;utm_medium=videos_homepage&amp;utm_campaign=videos_row3
12:17marcopolo2mdrogalis: thanks!
12:17CreapI have a plugin system, and a user can put a plugin in a directory and a namespace string in a config file. I then want to require the ns and get a function with a predefined name
12:18Creap(map (comp require symbol #(str % "/message-handler") :ns) (vals plugins)) is my current attempt, which doesn't work very well..
12:18wakeupWhat the hell. What could go wrong, so that locking doesn't work?
12:19wakeupWhen I comment out the actual (non-logging) body of locking it works fine
12:19wakeupwhen I do IO in the body, the lock is just ignored
12:19mdrogalisSure!
12:19wakeupexcept logging
12:19jonasen_si14: I can reproduce.. I'll take a look if I can find the cause
12:19wakeupweeeiird i hate my job right now
12:19si14jonasen_: thank you very much.
12:20tbaldridgewakeup: you really have to give some context. ranting doesn't help if we don't even know what your problem is
12:20wakeupI don't either
12:21wakeupI am trying to produce a minimal example ;)
12:22marcopolo2Creap: are you requiring ns/func, instead of just the namespace?
12:24Creapin the example above yes, I've tried a number of variants though
12:25marcopolo2Creap: try not including the /func, just the ns, so get rid of the #(str ...)
12:28Creapmarcopolo2: ok, but just to be clear, will require return the namespace, or just include the file?
12:28Creapif it does the latter, I think I have it working, but I expected a result as well
12:28TimMcwakeup: Laziness.
12:29marcopolo2Creap: pretty sure it will return nil
12:30dobry-denQuestion: Does loop/recur only exist because of the JVM's limitation?
12:30dobry-denI guess, what's the surrogate for loop/recur if you didn't have it?
12:30TimMcYes, otherwise we'd just tail-call.
12:31Creapit did indeed, and they were required.. thanks, just need to get the message-handler for those namespaces now
12:31noncomllasram: sorry for the delay https://www.refheap.com/19835
12:31dobry-denTimMc: What's an example of how you'd write (loop [x 0] (when (< x 10) (recur (inc x))))
12:31dobry-denin other lisps
12:33mdrogalislol Rich in that talk "What happens when you play with machines? You get hurt!"
12:34llasramnoncom: I'm sorry, but I really don't have any idea what you're trying to do :-/
12:35arrdemmdrogalis: which one?
12:37noncomllasram: here is something like i do: http://blog.zololabs.com/2009/12/10/frumios-a-silly-object-system-for-clojure/ what if, in terms of that example, i want to use functions defined elsewhere as (method) instead of defining it in place?
12:37mdrogalisarrdem: The Functional Database. Find it on InfoQ. Very new.
12:38marcopolo2Creap: you could try (kinda hacky): (eval `(var ~(symbol "ns" "fn"))) => returns reference to ns/fn function
12:38TimMcdobry-den: (fn foo [x] (when (< x 10) (foo (inc x))))
12:38marcopolo2Creap: there has to be a better way to do that
12:38dobry-denTimMc: Does loop/recur only exist because it does something different than your example?
12:38marcopolo2Creap: don't do what I did
12:39dobry-denClojure is my first lisp and in my ignorance, loop/recur simply feels like a low-level loop where its binding has a nice aesthetic just like `let`
12:40llasramnoncom: If there's an identifier in scope which refers to a function, you can just pass the identifier to the macro, and the macro can expand to code referring to the function via identifier
12:40technomancydobry-den: it is a low-level loop
12:40dobry-denI'm talking to someone that suggests that loop/recur is unpleasant and it only exists to address a jvm limitation
12:40technomancyapplication-level logic should always be expressed in higher-order terms via the seq api
12:41TimMcdobry-den: In a language with tail-call optimization, my example's call to foo would replace the current stack frame with the new call.
12:41noncomllasram: will it expand to the original form of the function or resolve to the compiled form?
12:41TimMcClojure on extant versions of the JVM can't support that, so we have loop/recur.
12:42llasramnoncom: It'll expand to exactly the same code using the identifier you'd write by hand
12:42TimMcIt does basically the same thing, but is much more limited.
12:42dobry-denTimMc: Even so, loop/recur is sort of like an "anonymous loop" compared to your named-fn example.
12:42seangroveWish they'd hold EuroClojure in SF, would be a lot more convenient
12:42noncomllasram: thanks!
12:42TimMcdobry-den: It's an anaphoric named-let.
12:43Creapmarcopolo2: I thought that (symbol "foo.bar/baz") would work
12:44Creapbut I guess I misunderstood symbol
12:44dobry-denTimMc: Right, and that seems like useful construct to have in a language. I'm admittedly ignorant of these things but I was trying to suggest to someone that loop/recur is actually a nice construct for a language to have.
12:45justin_smitha better analog to loop/recur in cl would be tagbody (with the special case of one tag at the top) - but that is very low level and only used when you are optimizing performance (and usually want multiple tags rather than a case statement or if or something)
12:45technomancydobry-den: in practice you only use loop/recur for things that can't be framed in terms of seq operations, which is almost never
12:45justin_smithor am I thinking labels? it has been a while
12:46llasramtechnomancy, dobry-den: seq operations / the CollReduce protocol
12:46rasmustolooping in low places
12:47justin_smithyeah, looking at the docs I was right the first time tagbody, one label at the top, and "go" instead of recur
12:47justin_smiththat still isn't right though - go does not take args
12:47justin_smithnever mind, none of this is all that relevant anyway
12:49dobry-dentechnomancy: So let's say you were implementing Hy (http://docs.hylang.org/en/latest/language/api.html#builtins) - Would you not implement loop/recur?
12:49dobry-denAnd what would you implement instead as your "lowest level loop"
12:51technomancydobry-den: I'm not saying it's not needed in the language; I'm saying it's more of an escape hatch. lots of higher-level functionality that comes with the language needs to be implemented in terms of loop/recur, but the day-to-day programmer never sees it
12:51CreapI would expect (var ((symbol "clojure.string" "join")) "_" [1,2]) or ((symbol "clojure.string" "join") "_" [1,2]) to work, why don't they?
12:52dobry-dentechnomancy: The person pointed out to me that Clojure is the only lisp with loop/recur as evidence that it's a hack
12:53technomancyhaha
12:53technomancyhave you seen CL's LOOP?
12:54dobry-denYeah, he actually directed me there as the pinnacle of looping in lisp
12:54technomancyhahahaha
12:55technomancydoesn't sound like someone who will listen to reason
12:55justin_smithCreep: in the virst example you just have the parens around the call to var balanced wrong
12:56dobry-denThe context here is that I'm in #hy trying to defend loop/recur in worlds abroad and #clojure just isn't giving me the amunition I need to subjugate the heathens.
12:57gfredericksclojurebot: #clojure is wussy about heathen subjugation
12:57clojurebotAck. Ack.
12:57technomancydobry-den: it's true that you don't need loop/recur in languages with guaranteed TCO, but CL and elisp don't have guaranteed TCO either; they have horrible iterative hacks
12:57dobry-denThis Hy lang is built on Python fwiw
12:57arrdemdobry-den: just use loop/recur to run circles around them. they're unfortunate enough to be atop cython, shouldn't be hard.
12:57justin_smithCreap: never mind, there is more wrong there than that, but there is a version of that first that works, working on it
12:58dobry-denI know python doesn't have tail call optimization, but I suggestd that it doesnt matter because loop/recur is so elegant that it can be implemented with assignment.
12:58justin_smithCreap: ##((resolve (symbol "clojure.string/join")) "_" [1,2])
12:58lazybotjava.lang.SecurityException: You tripped the alarm! resolve is bad!
12:58justin_smith,((resolve (symbol "clojure.string/join")) "_" [1,2])
12:58clojurebot"1_2"
12:58justin_smith:P
12:59justin_smithahh, there we go
13:00igstanis there any reason clojure has loop/recur instead of normal name-based TCO? other than as a hint for the compiler that it should complain if the functions isn't actually tail-recursive?
13:01technomancyigstan: having it refuse to compile in non-tail-positions is the reason, yeah
13:01justin_smithCreap: the reason var acts so weird is it is a macro, it only works if the thing it gets is directly a symbol - a form that resolves to a symbol only comes in as the form, not the resulting symbol
13:01dobry-denarrdem: haha yes. disappear into a trapdoor of recurs
13:01igstantechnomancy: thanks
13:01technomancyI think scala does what you suggest, but there's no way to have the compiler enforce non-stack-consuming recursion IIRC
13:02igstantechnomancy: scala has an annotation @tailrec. it will do TCO without it, but only complain about non-TCO code if you add the annotation
13:03technomancygotcha. so this is basically a macro to do the same thing.
13:03justin_smithwhat I like about recur is the explicit error if not in the tail position - you don't get as many mystery overflows from small errors or bad refactorings
13:04igstantechnomancy: it just occurred to me that clojure could have used metadata for this?
13:04igstansimilar to the scala annotation
13:05technomancyigstan: yeah, that could probably be used to do the same thing
13:05technomancyigstan: but you'd still need a way to recur to a loop-point that wasn't the function entry point
13:05technomancyso you couldn't get rid of recur entirely
13:06igstantechnomancy: it's true, that's what I was thinking right now. in scala I always end up with an inner go helper functions that is tail-recursive and carries the accumulator
13:08Creap justin_smith thanks!
13:08wakeupWhat could be the reasons for a function to throw a NullPointerExc. only when used in pmap?
13:09wakeupThe function looks like this: (fn [out str] (.write out str))
13:09wakeupit also calls .flush on out
13:09wakeupit also calls pr-str
13:09justin_smithwakeup: using with-* macro or binding a *special* var so that the resource you want does not exist by the time a parallel thread looks for it?
13:09wakeupand get
13:09wakeupYes I found the binding issue
13:09justin_smithwakeup: are you using with-open to open the out?
13:10wakeupjustin_smith: No.
13:10justin_smithso what was it?
13:10wakeupI use Socket.
13:10wakeupno I am past that binding issue
13:10wakeupwas clueless for hours
13:11wakeupI still get a NPE
13:12wakeupcould it be a variable bound by let outside of pmap?
13:13tbaldridgewakeup: very much so, pmap will use multiple threads to execute the function. bindings are sometimes not there, or not what you expect.
13:13tbaldridgewakeup: but doing IO inside of pmap is just....wrong.
13:13justin_smithsince pmap is mp, the form that launches pmap can exit before all the parts of pmap are done
13:13mdrogalistbaldridge: Is that necessarily true? That's how you pipeline in Datomic.
13:13wakeuphmm no thats not it
13:13justin_smithtbaldridge: yeah, good point, I would expect weird overlapping output to the socket
13:14wakeuptbaldridge: I am using pmap to test IO operations for thread safety...
13:14tbaldridgemdrogalis: let me re-phrase that...doing side-effecting IO inside of pmap is troublesome.
13:14wakeuptbaldridge: alternatives?
13:15tbaldridgewakeup: future would be a good one.
13:15mdrogalistbaldridge: How is that any different? Haha.
13:15justin_smithyeah, a doseq or dotimes launching futures that use the Socket would work nicely
13:15tbaldridgemdrogalis: doing reading IO is fine, you're not modifying anything (and based on the datastore may not actually modify any state).
13:15gfredericksI wrote a pdoseq the other day
13:16mdrogalisPipelining into Datomic isn't reading IO though
13:16gfredericksnot as featured as doseq though
13:16mdrogalisIf I understand what you're saying correctly
13:17tbaldridgemdrogalis: I'm not sure what you mean.
13:17mdrogalistbaldridge: Eh, nevermind. It's not really important. I think I get your point.
13:17noncom,('a)
13:17clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: Symbol>
13:17noncom,('a 1)
13:17clojurebotnil
13:17noncom,('a 1 4)
13:17clojurebot4
13:17noncom,('a 3 5 1)
13:17clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: Symbol>
13:18noncomwhy is that ^^ ?
13:18noncomwhat does mean passing 1 or 2 args to a symbol?
13:18tbaldridgenoncom: calling a symbol as if it were a function treats the 1st argument as a hashmap. if you give it a 2nd argument it gives a default
13:18justin_smithnoncom: symbol as a called thing is a lookup in a map
13:18justin_smithso it is just like (:key {} :default)
13:18tbaldridgenoncom: 1 argument "can't find 'a in 1", 2 arguments "can't find 'a in 1, so I'll return default"
13:19noncomoh, wow, i see! thanks!
13:21broquaint,('a {'a "Like so"})
13:21clojurebot"Like so"
13:21broquaint,('a {'b "Like so"} "Defaulty")
13:21clojurebot"Defaulty"
13:21jonasen_si14: They really like their macros over at prismatic :)
13:24dnolenCLJS users - do people really have strong opinion that the lower level try* is gone - it could be used for catching all errors even non error values - I don't really see the point given how people actually write libraries.
13:24dnolenfrom what I call tell for all browser errors, Foo instanceof Error will be true
13:27dnolenso only thing you can't catch is stuff like throw "Foo" which honestly is pretty silly and not something I think JS libs generally do
13:31gfredericksdnolen: I don't expect to have a strong opinion about this, but FWIW I can't even parse your sentences to figure out what you're asking
13:31gfredericksmight just be lack of context
13:31justin_smithI guess it would mess up someone's plan to do continuations in js via try/catch - which would be a silly plan anyway
13:32justin_smithgfredericks: any object can be thrown in js, in practice only errors are thrown
13:33gfredericksso there was some try* that could catch anything? and that was removed recently? and dnolen is wondering if anybody thinks it should still be available?
13:33justin_smiththat's how I read it
13:34gfredericksdoes that mean it's not possible to do the cljs analog of (try (a thing) (catch Throwable t (cleanup mess) (throw t)))
13:34gfrederickswhere (cleanup mess) only applies to errors and so couldn't be stuck in a finally
13:34dnolengfredericks: try* could catch anything, same way as try can catch anything in JS
13:35dnolengfredericks: most host errors will be instances of Error, so that more or less works
13:35gfredericksdnolen: so now it's impossible to catch non-Errors?
13:35dnolengfredericks: but if user code throws a string or a number, you can't catch it
13:35dnolengfredericks: but I'm not convinced that's something worth caring about
13:35dnolenif a library is throwing strings ... rage face
13:35gfredericksthat sounds like a problem for a lib that wants to be able to excute user code and cleanup issues if any exception is thrown
13:35justin_smithit would prevent porting slingshot - don't know how big a deal that is
13:35justin_smithhttps://github.com/scgilardi/slingshot
13:36gfredericksand my point is that it doesn't have to be a library doing the messy thing -- it could be a user where a library wants to not break just because a user was messy
13:37dnolengfredericks: no, any host error will be an instance of Error, the only thing that won't work if library code *explicitly* throws non Errors
13:37gfredericksusers can throw non errors though
13:37dnolengfredericks: CLJS users?
13:37gfredericksye
13:37gfrederickss
13:37dnolengfredericks: won't happen cause you can't catch it
13:37gfredericksusers won't throw them?
13:38gfredericksoh throw will check
13:38gfredericksI see
13:38dnolengfredericks: if they do they won't be able to catch it
13:38dnolengfredericks: the only problem is external libs that might do this
13:38gfrederickswhat will (throw "foo") do?
13:42dnolengfredericks: it will throw something you can't catch
13:42dnolengfredericks: more or less consider that undefined behavior
13:42justin_smithfwiw talking to the js expert here, almost nobody in idiomatic js uses throw, because it totally breaks the page if not caught, so they use things like console.assert instead
13:44TimMc"breaks the page"?
13:45justin_smithall js stops running
13:45TimMcThat sounds incorrect.
13:45si14jonasen_: yeah :)
13:45TimMcjustin_smith: I'm gonna need a demo of this.
13:46justin_smithTimMc: this is a web shop, we see this all the time - if you have js that throws and uncaught exception, all your js on that page stops running
13:46justin_smithI could make a minimal example maybe (though I am not on the js side of things here)
13:47gfredericksmaybe you're miscommunicating? the thing it sounds like you're saying contradicts my ten years or something of working in web browsers
13:47justin_smithmaybe
13:48gfrederickse.g., if you add a click handler to an element that logs to the console and then throws. and then you clicked twice. how many logs would you expect?
13:48jonasen_dnolen: I wouldn't be suprised if there were js libs out there that throws strings
13:49dnolenjonasen_: I've never seen one that I'd want to use.
13:49gfredericksjonasen_: dnolen: it seems super common in clj-jvm libs to want to be able to catch _all_ throwables for some purpose or another. the idea that something could sneak through because a user is ignorant is troubling
13:49dnolenjonasen_: or that anyone I know would want to use - exist is one, pervasive is another
13:50dnolengfredericks: yes, but real the question is whether it actually matters at all for most interop. I'm inclined to say no.
13:50jonasen_dnolen: that
13:50bitemyappjustin_smith: wat
13:50jonasen_'s true
13:51bitemyappjustin_smith: So Mozilla is telling people to do things that break web browsers? -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Statements#Exception_Handling_Statements
13:51justin_smithbitemyapp: gfredericks: sorry, it appears I didn't actually understand the problem on the js side of things
13:51justin_smithmea culpa
13:52bitemyappjustin_smith: it's okay, i was just hella confused and thought I was in an alternate universe where JavaScript is even worse than usual.
13:53justin_smithI've had frontend guys say "this happens because any error just stops all the rest of the scripts" - clearly that was an oversimplifications
13:53gfredericksbitemyapp: also if you use the variable "foo" anywhere in your file it causes the browser to interpret the statements in reverse
13:53justin_smithor a specific case, or something
13:53jonasen_http://www.devthought.com/2011/12/22/a-string-is-not-an-error/ "An unfortunately common pattern in Node.JS"
13:53jonasen_dnolen: ^ That's all I was able to find on the matter
13:53TimMcjustin_smith: If they have a big init function and it throws part way, sure, that will break the app.
13:54bitemyappwhich is also not a good way to write JS code.
13:54bitemyappYou can have a callback that does nothing but throw an exception in JS, but as long as the binding is still valid, that callback will keep getting called and keep throwing exceptions.
13:54justin_smithahh, ok
13:54bitemyappAll that stuff is independent of each other, you have to write your code in big monolithic blocks to short-circuit behavior.
13:55bitemyappanything that's part of the event loop is unkillable unless you explicitly: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget.removeEventListener
13:55bitemyappor unless you capture the event and preventDefault
13:56bitemyappI'm sure dnolen could think of other ways. You get my meaning.
13:56bitemyappjustin_smith: I take it you're mostly backend?
13:56justin_smithyeah, all I know about frontend is when things break between the two I guess
13:58justin_smithI thought I knew a bit more before this conversation than I think I know now, for sure :)
13:59bitemyappjustin_smith: ego is the enemy of learning.
13:59justin_smithdefinitely
14:05jonasen_dnolen: I can prepare a patch for CLJS-620. Do you think it's a good idea to defina a (definline ...) macro that expands to (defmacro ^:inline ...) or should I explicitly add ^:inline metadata?
14:05dnolenjonasen_: lets just stick with ^:inline for now
14:06jonasen_dnolen: ok
14:24jonasen_dnolen: uploaded. Note that I made it an error, so this might break some libraries that are immitating cljs.core
14:24jonasen_dnolen: I can change it to a warning if you want to
14:28dnolenjonasen_: I prefer it be a warning - I think the warning/error behavior should be tunable via cljsbuild
14:31amacdougallI'm having an issue with enfocus, and in hopes of debugging it, I decided to fork the repo and experiment. Turns out I was embarking on a whole new adventure! Any advice on how to use a local copy of a library in a project?
14:32amacdougallI've tried making a local jar and installing it in a local Maven repo, following http://nakkaya.com/2010/03/16/adding-custom-libraries-into-local-leiningen-repository/ -- but it's failing in a way that hints that I may be on the wrong track.
14:34amacdougallFirst I had to specify a domina dependency in the client project for cljsbuild to work, and after doing so, my JS immediately dies with "Uncaught Error: Namespace "goog.string" already declared." (which doesn't seem like something that should be occurring under any circumstances)
14:35jonasen_dnolen: In that case we'll get several warnings so this change might not be much of an enhancement: https://www.refheap.com/19838
14:43coventryamacdougall: I generally use lein checkout dependencies for that. https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md#checkout-dependencies
14:44coventry(Lets you modifiy the library you're bringing in without doing the lein install dance each time.)
14:47amacdougallThat might do the job! I'll try it out now and let you know.
14:48amacdougallDo I simply put a path to the folder that has the library's project.clj and let Leiningen figure out the rest?
14:48amacdougallBecause THAT would be a godsend. And yeah, it sure looks like it...
14:48coventryYep. cd my-project; mkdir checkouts ; cd checkouts; ln -s /path/to/dependency
14:49coventryThen stick the dependency in project.clj, restart your repl, and play.
14:53amacdougallWhile I'm working, I suppose I should state the issue I'm trying to debug, in case anyone has ideas -- I'm using enfocus's "listen-live" function to handle clicks on <a class="internal"> links, cancel link navigation, and use client-side routing. enfocus/listen worked fine with a (.preventDefault e) side effect... enfocus/listen-live does not! It runs the handler, but the browser navigates anyway.
14:54amacdougallLooking at https://github.com/ckirkendall/enfocus/blob/master/project/cljs-src/enfocus/events.cljs, it looks like listen-live builds a goog.Event from the native DOM event, while listen does not. And goog.Event.prototype.preventDefault doesn't seem to actually invoke the native .preventDefault...
15:00coventryOh, also, you have to (require :reload) the dependency to pick up changes since the ns was last loaded.
15:01bitemyappcoventry: (require '[clojure.tools.namespace.repl :refer [refresh]]) (refresh)
15:02amacdougallcoventry: The checkouts version works like a charm, thank you! Unfortunately, I'm still getting the same error as when I used the local jar, and it's a weird one -- it's claiming that "Namespace "goog.string" already declared", but it's the very first time it's executing main.js!
15:02amacdougall...it must be executing something else before that... wait, I just might be stupid. Never rule that out.
15:04coventrybitemyapp: Sometimes that's been slow for me.
15:04amacdougallYeah, problem solved. This will be very helpful! Thanks, coventry.
15:04coventryNo worries.
15:09dnolenjonasen_: hrm why are there multiple warnings there?
15:09jonasen_dnolen: because analysis continues if we emit a warning
15:10dnolenjonasen_: but why two warnings for 1 when?
15:10bitemyappcoventry: figured I'd offer the more robust solution :P
15:11jonasen_dnolen: no idea ...
15:11dnolenjonasen_: I'm pretty sure the second one can be supressed
15:11dnolenjonasen_: is that in the REPL?
15:12jonasen_dnolen: yes
15:12dnolenjonasen_: ok so the REPL does two analysis passes is why
15:13achin__@technomancy: I'm using your Clojure build pack on Cloud Foundry. I got it to work, but had to munge PATH to include java/bin. I thought the Java buildpack installed the JDK to $BUILD_DIR, not $HOME. http://git.io/fmisbg
15:13dnolenjonasen_: in general we don't emit warnings w/o first checking that the user wants to see them, :undeclared is what we normally check for in *cljs-warnings* dynamic hash-map
15:14dnolenjonasen_: we might want to check for something else, or just rethink *cljs-warnings* and make it a bit simpler.
15:14jonasen_dnolen: yeah, I also realized that resolve-var shouldn't call warning explicitly, It should go via resolve-existing-var or something
15:15jonasen_dnolen: as the docstring for resolve-var suggests
15:18amacdougallAha... enfocus's events/listen-live actually throws away the original DOM event, passing a completely new goog.events.Event to the client. preventDefault and stopPropagation become impossible.
15:18amacdougallSternly resisting the temptation to make jokes about .preventDefault and the US government.
15:34Creapis there a way to auto-restart my app, run with lein run, when it crashes?
15:38mtpuse runit
15:39Creapok, I'll look into it
15:40mtp:)
15:41mtpit's a great thing. you also don't have to use the whole thing, if you just need runsvdir.
15:41mtpmost people just need runsvdir
15:43llasram(inc mtp)
15:43lazybot⇒ 1
15:44wakeupCan anyone give me an example of a simple threadsafe counter?
15:44llasram##(java.util.concurrent.atomic.AtomicLong.)
15:44lazybot⇒ 0
15:45llasrammtp: runit is the best. All nice and Unix-y, but without totally rejecting the FHS like djb's originals
15:46Creapmtp: excellent, that took me <5 minutes, thanks
15:46mtp:)
15:47wakeupWhy does this not work:
15:47wakeup(dosync (ref-set cnt (inc (deref cnt))))
15:47wakeup(try STUFF-HERE
15:47wakeup (finally (dosync (ref-set cnt (dec (deref cnt))))))
15:47wakeup?
15:47mtpi'd like, at some point, to merge s6-supervise with runit
15:47mtplater, tho. :)
15:48mnemnionI have a hopefully quick if noobish question. I have, basically (do (make a directory) (put stuff in it))
15:48coventrywakeup: how does it fail?
15:48indigowakeup: Why not use atoms instead?
15:49wakeupcoventry: the value of (deref cnt) seems to be unpredictable.
15:49gtrakwakeup: works as expected to me
15:49wakeup(when used concurrently)
15:49mnemnionI think the problem is that clojure is trying to (put stuff in it) before (make a directory) returns
15:49indigo(def i (atom 0)) (swap! i inc)
15:49coventrywakeup: Well, you don't have it locked during the try block.
15:49mnemnionbecause when I do them one at a time on the REPL, no problme.
15:50gtrakseems like you should use alter insted of ref-set? (unrelated)
15:50indigoOr, you know, use atoms ;P
15:51gtrakthis sounds like xy-problem http://www.perlmonks.org/?node_id=542341
15:51wakeupcoventry: why would I? (honest question)
15:52llasrammnemnion: Clojure doesn't have any implicit laziness. Unless you're doing `(make a directory)` as part of realizing a lazy-seq, `do` always evaluates body forms in order
15:53indigowakeup: What are you trying to do
15:53mnemnionllasram: okay. what seems to be happening is that the system call isn't actually completing before the next form evaluates.
15:53coventrywakeup: The question from my perspective is why you would expect the value to be predictable, given that cnt could be concurrently modified during the try block.
15:53wakeupindigo: cound the number of open connections (concurrently)
15:53wakeupcount*
15:53TimMcwakeup: While your code is executing STUFF-HERE, another thread is molesting your refs.
15:53mnemnioneven though the (make a directory) form returns successfully.
15:53indigowakeup: Then you should use an atom
15:53wakeupI will try an atom
15:54llasrammnemnion: Post full reproducing code? Can't say what is going on w/o, but I assure you that there isn't random out-of-order execution happening
15:54TimMcwakeup: If you're just counting the number of threads that are executing STUFF-HERE, your code should work (although it is a bit awkward.)
15:55TimMcWhat is your evidence that the result of teh deref is "unpredictable"?
15:55wakeupTimMc: it doesn't though
15:55mnemnionllasram: sure, the only dependency is me.raynes/fs. I'll toss up a gist. thanks!
15:55wakeupTimMc: I open 10 connections, then I close them, then the value is random
15:55RaynesMy code is like an infection. Spreads hate and anger to all who depend on it.
15:56wakeupTimMc: obviously I am doing something wrong ;)
15:57tbaldridgewakeup: use alter instead of ref-set. that should help
15:57coventryI would experiment with tracing output in the finally blocks.
15:58arrdemRaynes: could be worse, it could not work while doing all the above.
15:58wakeuptbaldridge: would you also suggest using atoms instead?
15:58mnemnionhttps://gist.github.com/mnemnion/6997178
15:58tbaldridgethe problem is that but yeah, use an atom
15:58tbaldridgetypeo there.
15:59wakeupBtw, I got rid of my NPE's by using futures instead of pmap. Can you guys explain me thats the difference of spawing a lot of futures and pmap?
15:59tbaldridgeyes, use an atom
15:59lynaghkcemerick: ping
15:59TimMctbaldridge: Actually, I'm not seeing why this wouldn't work.
15:59TimMcYou think there needs to be an ensure? :-/
15:59mnemnionllasram: the pieces all work. I can call them one at a time at the REPL and it does what I want.
15:59llasrammnemnion: Yeah, so `map` explicitly returns a lazy sequence. You need to force it (probably via `dorun`) in this case, or use a non-lazy form like `doseq` instead
15:59llasram(in `athena-gen-dirs`)
16:00mnemnionllasram: thanks again! The consequences of laziness on side-effect producing code still bite me.
16:00llasrammnemnion: When you call the functions in the REPL they work because printing forces the full seqs to be realized
16:00llasrammnemnion: Yeah, it's tricky, especially at first!
16:01tbaldridgeTimMc: I think alter implies ensure, not sure if ref-set does.
16:01mnemnionllasram: I intuited a laziness problem, that's where the 'do' came from, but it's in the wrong place. I see that now. cheers
16:02tbaldridgewakeup: the pmap vs futures thing may come down to a matter of bindings, but your new solution is sound. Side effects should be done in futures not in pmap.
16:02mnemnion....and it works! ...and it was the last thing that needed to work! I am in a fine mood now. Kudos llasram.
16:03llasrammnemnion: Glad to help :-)
16:04wakeuptbaldridge: Imho this behaviour is quite buggy, I literally spent 4 hours trying to figure that one out.
16:04lynaghke
16:04llasramOh man, I wish
16:04wakeupand I didn't even use binding
16:05wakeupThe NPE doesn't help one bit...
16:05lynaghkUgh, sometimes my desktop goes "beep" and all of the windows and buttons stop working. But the music keeps playing. Linux...
16:05wakeuplol
16:05wakeupsounds like windows ;)
16:05tbaldridgewakeup: there's certain facts about Clojure semantics that are easy for beginners to miss. For instance, pmap uses multiple threads and bindings may not be passed around. You shouldn't deref a ref inside a dosync, etc.
16:06tbaldridgeThese things all come with time
16:06lynaghkwakeup: are you kidding? I should just compile xmonad for Windows 2000 and be done with all of my hardware problems.
16:06wakeuplynaghk: Windows 2000 does indeed rock. I make my mum use it on a 15 year old thinkpad.
16:07coventryWhy shouldn't you deref a ref inside a dosync? I haven't used transactions much yet.
16:08wakeupI am afraid what will happen when no browser support win2k. Her office suite doesn't support >xp and nobody could possibly ask her to learn to use a modern MS office.
16:08TimMcderef is fine inside a dosync, just make sure to use ensure (if it matters.)
16:10coventryOh, I see how wakeup's code could be failing, and why using alter fixes it. Thanks.
16:10tbaldridgecoventry: yeah, I think that's the problem. From what I can tell (I might be wrong) if you use deref inside a dosync (without a ensure) the transaction will not be restarted if that ref is modified.
16:10wakeupUsing atoms has the same effect...
16:10coventrytbaldridge: Yes, the refs page on clojure.org is pretty explicit about that possibility.
16:11coventrywakeup: You need to make the changes atomic using swap! for an atom or alter for a ref.
16:12coventryWhat is happening is you have multiple threads coming in, reading the value of cnt and trying to inc/dec it at the same time.
16:13coventryIf you use one of the functions which take an altering function instead, there won't be an opportunity for modification between the read and the inc/def.
16:13TimMcwakeup: Could not reproduce with: https://www.refheap.com/19843
16:13TimMcI'd be interested in a SSCCE.
16:15pjstadiga deref and ref-set inside of a dosync should be fine
16:15indigoTIL SSCCEE
16:15indigoEr E
16:16coventryTimMc: Try taking the delays out.
16:16wakeupstill works
16:16wakeupweird
16:17TimMccoventry: Still works.
16:17TimMccoventry: Let me know if you find something.
16:17coventrycnt has a value of 7 after running https://www.refheap.com/19844 for me.
16:18tbaldridgeand if you use alter?
16:18indigoHm, still has a value of 0
16:18pjstadigcoventry: you probably need to reref the futures
16:18wakeupWhen I use alter the system deadlocks
16:18pjstadiger deref
16:18TimMccoventry: Are you sure all those threads have finished? :-P
16:18tbaldridgewakeup: how are you using alter?
16:18wakeupinside a dosync?
16:18tbaldridgeshould be (alter cnt inc)
16:18wakeup(alter ref inc)
16:19TimMcI do not believe that ref-set is not strictly stronger than ensure.
16:19wakeupin a dosync right?
16:19tbaldridgeyep
16:19indigocoventry: It has a value of 145 if I do it with 2000 threads
16:20pjstadigindigo: then you are not waiting for the 2000 threads to finish before checking the value
16:21pjstadigalter is better style than deref/ref-set, but not different semantics
16:21indigopjstadig: Ah, gotcha
16:22wakeupI am now using alter and still getting random values....
16:22coventryTimMc, pjstadig, You're right, cnt is zero if I delay a second before checking it.
16:22TimMc~sscce
16:22clojurebotAn SSCCE is a Short, Self-Contained, Correct Example <http://sscce.org/&gt;
16:22indigo^
16:22pjstadigwakeup: you need to paste the exact code
16:23TimMcwakeup: ^ Post an SSCCE *demonstrating* how you get those "random" values.
16:23TimMcYou are misinterpreting your results.
16:23pjstadigthere's probably an unrealized lazy seq, or otherwise un-joined threads that are causing "randomness"
16:26coventrywakeup: Are you sure all *your* threads are finished when you check the value of cnt? Tracing the finally blocks could help determine that.
16:37cemericklynaghk: heyo
16:39dobry-denIs there a way to throw a Warning to the user?
16:42indigodobry-den: https://github.com/clojure/tools.logging ?
16:43dnolenfeel free to chime in the try* change if you are likely to be affected by it, http://groups.google.com/forum/#!topic/clojure-dev/1ahsYtzFbJg
16:43bitemyappdobry-den: [com.taoensso/timbre "2.6.2"] (:require [taoensso.timbre :as t]) (t/warn "you have been warned")
16:44dobry-denthanks yall
16:46Jardatimbre seems cool
16:46justin_smithit even optionally does colors for tty output
16:47justin_smithI wish you could set *out* to be a specific output stream for timbre though - things still get weird under emacs/nrepl it seems
16:47lynaghkcemerick: hey dude
16:47lynaghkcemerick: I saw you had some patches submitted to amazonica and I was going to ask you a few questions about what you're using it for
16:48lynaghkI'm thinking about using S3 as a store for small (128kB-ish chunks) and basically need to use a gazillion threads to get any kind of throughput with that
16:48lynaghkI decided to just use the java bits manually rather than figure out how to out-reflect amazonica, though.
16:50bitemyapplynaghk: are the throughput limitations due to how slow S3 is or something else?
16:50cemericklynaghk: Using it for s3 + dynamo at the moment
16:51lynaghkbitemyapp: I think the HTTP negotiation latency dominates the transfer time
16:51bitemyapplynaghk: that's what I would figure. Is there some reason you couldn't use Riak+Bitcask, Dynamo, or something else?
16:51lynaghkbitemyapp: there's an (old) analysis of S3 stuff here: http://improve.dk/pushing-the-limits-of-amazon-s3-upload-performance/
16:52lynaghkbitemyapp: inexpensive storage is more important that latency---things will be synced to the end machines and cached there
16:52lynaghkI just want to make sure there's bandwidth for the syncing
16:53cemericklynaghk: I've not bothered benchmarking my s3 puts. Fast Enough, etc.
16:53lynaghkcemerick: yeah. the main issue I was having with amazonica is that everything is magic---I couldn't figure out how to twiddle the Java client options
16:54cemerickdropbox was (still is?) built on s3, so I suspect it's not going to get in your way, perf wise, at least until you're up at some serious scale
16:54cemericklynaghk: gotta use it with the javadocs open
16:54amacdougallcoventry: I was able to debug, fix, and pull-request that library. Thanks again for the help!
16:54lynaghkbitemyapp: bitcask looks interesting, thanks for the pointer
16:56bitemyapplynaghk: Riak+Bitcask and HDFS are good alternatives for when you need a bit more magic than S3 offers.
16:56bitemyappI didn't mention HDFS because BC seemed closer to the mark.
16:56bitemyappthe LevelDB backend for Riak is for more traditional OLTP workloads.
16:57bitemyapplynaghk: a common tactic in Hadoop shops is to use HBase as an index for content stored in HDFS.
16:58bitemyappso that you have something more sophisticated than just 1-1 URLs if and when needed.
16:58bitemyappyou don't want the blobs inline in HBase generally.
16:58justin_smithspeaking of aws and alternatives, does anyone have experience with using clojure on an openstack? my company uses beanstalk but it would be nice to have options and potentially the extra power you could get with the openstack alternative
16:59lynaghkbitemyapp: do you know offhand how difficult it would be to package up bitcask and ship it via an uberjar?
16:59bitemyapplynaghk: approximately as difficult as any Erlang application.
16:59lynaghkif I wanted to use it instead of the plain filesystem for a simple k/v cache (a subset of the keys avaliable in S3)
16:59lynaghkbitemyapp: no idea how difficult that is = )
17:00bitemyappI'd be comfortable filing it under "ideas that are not good"
17:01bitemyapplynaghk: if you want an embedded kv store, then you should look at kyoto cabinet, derby, and LevelDB
17:01bitemyappthere are pure Java ports of LevelDB and a JNI version
17:01bitemyapplynaghk: that's much wiser if you just want an embedded KV store that hits the filesystem.
17:01lynaghkbitemyapp: awesome, thanks for the info. will do.
17:01technomancyberkeleydb is the old-school choice for embedded kv
17:01technomancyold as the hills
17:01bitemyapptechnomancy: I was trying not to go there.
17:02technomancybecause Oracle?
17:02brehautthose hills rise wild
17:02lynaghkability to uberjar via lein is a big requirement
17:03bitemyapplynaghk: the most robust answer for an uberjar environ is probably H2/Derby/HSQLDB. LevelDB and Kyoto Cabinet are going to mean either JNI or a port.
17:03llasramI've never actually used berkeleydb, but there's this great line in the `reprepro` BUGS section: "Reprepro uses berkeley db, which was a big mistake."
17:03lynaghkbitemyapp: you know if any of those have an idiomatic clojure API for doing, e.g., keyset intersections and batch lookups/writes?
17:04lynaghkthe keys are derived from the content, so everything immutable
17:04bitemyapplynaghk: you want Derby/H2/HSQLDB and to just use SQL then.
17:05lynaghkbitemyapp: really? I feel like the overhead of writing 10000 keys into a SQL string would dominate the useful work
17:05technomancyIIRC sleepycat had a history of making their license look like a BSD-style license when it was actually copyleft, and then approaching users to work out a licensing deal after they'd already written their code around it
17:05technomancy(before they even got acquired by oracle)
17:06bitemyapptechnomancy: hence why I was trying not to go there.
17:06bitemyappleft a bad taste in a lot of peoples' mouths.
17:06lynaghkbitemyapp: well, it's all k/v so it shouldn't be too hard to benchmark a few different options. thanks again for the tips!
17:06technomancybitemyapp: well, only if you plan on distributing
17:07bitemyapplynaghk: that's not quite how I would do it.
17:07indigoRiak is sexy
17:07bitemyapp10000 keys in a query that is.
17:07lynaghkbitemyapp: I haven't used those guys before---I'll take a look at the APIs and see if there's a saner way to do batch ops
17:08lynaghkit's just the first thing I thought of when you mentioned SQL.
17:08bitemyapplynaghk: leveldb is more designed around batch ops than the SQL options or Kyoto Cabinet.
17:08bitemyapplynaghk: it's built on top of log-structured merge trees. I don't know how applicable it'll be to your problem, it's foreign to me.
17:08bitemyappI do a lot of database stuff and I am baffled by what you just mentioned.
17:08bitemyappI'd need more info than intersecting 10,000 keys.
17:09lynaghkbitemyapp: I just mean for a batch operation like, "insert 10000 keys" with SQL I'd have to write a giant query to see which of those keys already exist, subtract, and then write the new ones
17:10lynaghksince SQL strings are the only interface to SQL databases---but, like I said, maybe there are some features in the DBs that you mentioned that provide more data-oriented interfaces over just strings.
17:11bitemyapplynaghk: roughly you're talking about "insert where not exists", I don't think the overhead surrounding the SQL string is a big deal when the database is embedded. It's all something that can be measured. Please blogginate if you do.
17:12lynaghkbitemyapp: I'd need to spend approx 20x as much work to get a suitable blog post over what I was going to just do in the privacy of my own application
17:12lynaghk= )
17:13bitemyapplynaghk: at least toss me an anecdote then :(
17:14lynaghkbitemyapp: you have the same handle on github?
17:14bitemyapplynaghk: yes. I was also in Clojure Cup.
17:14lynaghkbitemyapp: I'll shoot you an email when I get it all worked out
17:14bitemyapplynaghk: leveldb is generally a couple micros per write and hundreds of nanos per read, with that in mind, doing the "obvious thing" (just iterating) should only take 20-30 millis.
17:14bitemyapplynaghk: is 20-30 millis to sync your 10,000 immutable keys acceptable?
17:14lynaghkbitemyapp: yeppers.
17:14bitemyappthen you could just do the "obvious" thing in leveldb and verify how long it takes.
17:15lynaghkyeah, will probably do that
17:17bitemyapplynaghk: I feel like Hacker News has disincentivized sharing knowledge because if you don't write a perfect post criticisms come out of the woodwork.
17:17bitemyappI find this very sad :(
17:18brehautyou can write the perfect post, but someone will have a different perspective where the contents of that post are not relevant and they'll still complain
17:20lynaghkbitemyapp: nah, nothing about HN---it just takes me forever to write anything
17:20bitemyappwell I'll still be pleased if you toss an anecdote my way :)
17:20indigoFuck it, learn through criticism!
17:20bitemyappindigo: <3
17:20indigo:D
18:26tyler_webdoes JAVA_OPTS environment work when running `lein run`, or do I need to add to a project file?
18:29TimMctyler_web: It's an environment variable, so when running `lein run`.
18:29justin_smithtyler_web: you can use :jvm-opts in a project.clj, or _JAVA_OPTIONS on the command line
18:30TimMcOh, has the env var changed?
18:31TimMcI see JAVA_OPTS and JVM_OPTS in the lein bin.
18:31justin_smithI always use _JAVA_OPTIONS
18:32mklappstuhlusing (try () (catch ...)) is there a way to catch any exception no matter which class?
18:33technomancycatching Exception will catch subclasses of Exception too
18:33justin_smithand Exception is a subclass of Throwable
18:34justin_smiththough catching Throwable may be a bit overboard
18:34technomancyyeah, don't catch Throwable
18:34technomancyyou won't be able to stop your program without kill -9
18:36TimMcYou can safely catch Exception and AssertionError.
18:36AimHereBut then again, nobody else will be able to stop it too, muHAHAHA!
18:37mklappstuhlAh, that makes sense, thanks!
18:37gfrederickscatching throwable is often useful if you're rethrowing it
18:37gfredericksthere was a bug in java.jdbc regarding transaction roleback due to the fact that it _wasn't_ catching throwable
18:37TimMcIf you get your hands on an OOM error or similar, you want to rethrow it as quickly as possible.
18:38TimMcand with minimal allocation
18:38mklappstuhlI don't really know what I'm doing. Running a big job saving things to a database and I dont want it to stop if it doesn't work in one instance...
18:38mklappstuhlTimMc: OOM?
18:38gfredericksyeah just catch Exception for that probably
18:39mklappstuhlWill do
18:39TimMcout of memory
18:51dnolenmarcopolo2: are you the author of servant? https://github.com/MarcoPolo/servant?
19:27dobry-denIs it possible to write an `unroll` macro so that [(unroll [:a :b :c]) bar] -> [:a :b :c :bar]?
19:29justin_smithdobry-den: that macro would need to look out at the thing that contains it
19:29justin_smithwhich is weird
19:29justin_smithand probably not at all possible
19:32turbofailyou could get a similar effect by just using syntax-quote: `[~@[:a :b :c] ~bar]
19:33turbofailslightly less convenient, but not too bad
19:33dobry-den(conj [:a :b :c] :bar)
19:34gws,(flatten [[:a :b :c] :bar])
19:34clojurebot(:a :b :c :bar)
19:58amalloydobry-den: unroll is indeed impossible to write; any non-crazy use cases are easily handled with turbofail's suggestion
20:02marcopolo2dnolen: yup!
20:11eriktjacobsenHello
20:13eriktjacobsenGot a question regarding dependencies. I have some sub projects that all compile fine and use aws javasdk 1.5.8, but my top level project has the bandalore library that uses like 1.3 aws java sdk, and it causes top project to fail to compile… Do I have to patch bandalore to use 1.5.8, or how can I tell it to use two version of aws-java-sdk for each of the individual projects?
20:13eriktjacobsenthis is using lein
20:15marcopolo2eriktjacobsen: can you post your project.clj file on refheap.com?
20:19eriktjacobsenmarcopolo2: included the relevant paste:
20:19eriktjacobsenhttps://www.refheap.com/19848
20:19eriktjacobsenlooking at it, perhaps should add rotary to top level project?
20:19eriktjacobsentrying that now
20:20eriktjacobsenAlso perhaps I should take a step back, trying to fix this compile issue: http://stackoverflow.com/questions/19391375/clojure-leiningen-compile-error-with-multiple-projects-classnotfoundexception
20:21eriktjacobsenPosted pointed me to the dependencies possibly linking wrong libs, so since the version showing up in top level project (1.3) doesn't have the calls I'm using in 1.5.8, i'm hoping that is the root of my compile issues
20:21rasmusto,(for [a nil] a)
20:21clojurebot()
20:22rasmusto,(doseq [a nil] (println a))
20:22clojurebotnil
20:25dnolenmarcopolo2: pretty cool, but I'm assuming it's not possible to put a piece of data into a worker w/o copying without first partitioning it first into array buffers?
20:25marcopolo2dnolen: thanks! yeah, unfortunately that's a limitation in web workers :(
20:26dnolenmarcopolo2: still very cool, and seems very useful.
20:26marcopolo2I wish there was an immutable type you could create and transfer around
20:27marcopolo2dnolen: you going to clojure/conj again?
20:28marcopolo2also servant made the web worker part of the crypt demo the easiest part! as opposed to the js version where it was the trickiest part!
20:28dnolenmarcopolo2: yess
20:28marcopolo2dnolen: Awesome! :D
20:28dnolenmarcopolo2: yes, using the channels for the worker pool is really cool
20:29dnolenmarcopolo2: makes coordination triival
20:29marcopolo2dnolen: It really does! I kinda felt like I was cheating
20:39bjaanyone using tmux to send-keys to their repl encountered issues with send-keys not supporting zoomed panes in tmux 1.8?
21:14logic_progI have written a few macros in the past. I want to better understand how the macro compiletime/runtime works. Is this documented anywhere? [not how to write macros, but a description of when/how macro expansion works in clojure]
21:17nightflyLook up documentation for Common Lisp macros
21:17brehautnightfly: thats not especially relevant
21:18nightflyHow so? They behave practically identical
21:18nightflyUnless you do AOT stuff, then all bets are off
21:19brehautlogic_prog: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L7140 is where to begin with specifics
21:19logic_progbrehaut: lol
21:19logic_progactually wait, are you serious?
21:19brehautyeah
21:19brehautmaybe im weird in the head, but the clojrue compiler is relatively straightforward
21:20logic_progwhere the fuck is "the annotated clojure source / rich hickey" ?
21:20brehautyou want anotated source? most of use would be happy with non whitesmith source :P
21:20logic_progbrehaut: I think the correct word is "genius" not "weird in the head"
21:20brehautlogic_prog: im no genius
21:21Apage43macroexpand(form) just calls macroexpand1(form) repeatedly until it stops getting a different result
21:21logic_proghttps://github.com/clojure/clojure/tree/master/src/jvm/clojure/lang is the entireity of the clj source?
21:21logic_progthis actually doesn't seem so bad
21:21brehautand theres an isMacro method that is used to determine if a symbol / ref refers to a macro
21:21Apage43and macroexpand1(form) will return form *unless* form is a seq whose first element is a symbol that corresponds to a var in the current ns that is defined as a macro
21:22brehautlogic_prog: its the entireity of the low level stuff; core.clj adds a crap ton of the sophisticated syntax and semantics
21:22Apage43in which case it will instead return the result of applying the macro fn to the rest of the form
21:23logic_prog(defn macroexpand [form] (let [h (head form)] (if (isMacro? h) (macroexpand-1 form) form))) ?
21:23brehautclose enough for government work yeah
21:23Apage43yeah but in java
21:23brehautso its 75 lines long
21:24Apage43also the isMacro check is inside of macroexpand-1
21:24Apage43https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L6530-L6535
21:24logic_progman, that code isn't half bad
21:24Apage43macroexpand itself is really short
21:24logic_progit looks readable too
21:25logic_progI feel like I can read the entirety of compieler.java if I just had brehaut/Apage43 as guides
21:26Apage43and isMacro just checks is the key :macro is set to true on the Var's metadata
21:27brehautlogic_prog: compilers get complicated for about 3 reasons imho: a) monsterously recursive with many cases b) tend to have a lot of layers c) they have to generate a lot of code for all the specific features of the language
21:27Apage43(the isMacro in Compiler.java can also take a symbol, in which case it looks up the var, then does said check)
21:27logic_progso clojure avoids this mess by "java has a JIT" ?
21:27brehautlogic_prog: clojure's compiler isnt especially layered, and it only has to implement the special forms
21:27brehautlogic_prog: it avoids part of the mess due to that yeah
21:28logic_progactually, here's a dumbass question
21:28Apage43,(meta #'when)
21:28clojurebot{:macro true, :ns #<Namespace clojure.core>, :name when, :arglists ([test & body]), :column 1, ...}
21:28logic_progdoes clojur'es compiler compile *.clj files to *.java strings and runs them on the fly, or is the clojure compiler an "interpreter for *.clj files" taht gets JITTed ?
21:29brehautit compiles them to inmemory java bytecode in classes
21:29Apage43well the first one definitely doesn't happen. It never generates java *source*
21:29logic_progApage43: clojure is more dynamic than I thought
21:29Apage43it does generate jvm bytecode though, yes
21:29logic_progI need one more help from the two of you, then I'll stop wasting your time
21:29brehautlogic_prog: thats all abstracted away in the asm package though :)
21:29logic_progcan you point me at where in Compiler.java clojure does the bytecode generation?
21:29Apage43javac : java :: Compiler.java : clj ;; sort of
21:29logic_progI'm kinda interested in this as an alternative to LLVM
21:30logic_progI want to learn how clojure does *.clj -> java asm
21:30brehauthttps://github.com/clojure/clojure/tree/master/src/jvm/clojure/asm i think
21:30Apage43basically all the emit* methods are calls to the ASM library
21:31Apage43which does the work of providing a sane way of building java bytecode programatically
21:31logic_progthis is fucking badass
21:31logic_progclojure source = my new reading project
21:31brehautlogic_prog: part of that magic is that clojure has (if i recall correctly) a custom class loader
21:32logic_progoh, all of https://github.com/clojure/clojure/tree/master/src/jvm/clojure/asm is added 6 years ago
21:32brehautif i recall correctly its a third party library that is bundled with clojure?
21:32Apage43http://asm.ow2.org/
21:33Apage43"ASM is an all purpose Java bytecode manipulation and analysis framework. It can be used to modify existing classes or dynamically generate classes, directly in binary form. "
21:33brehautreformated in whitesmith probably :P
21:33brehaut(https://en.wikipedia.org/wiki/Indent_style#Whitesmiths_style)
21:35logic_progneed to eat dinner; thanks to everyone for insightful pointers
22:01RoboClaudioRaynes: Many people must be bugging you with this, so I apologise if you recently answered the question, but I'm wondering: is Meet Clojure is still on hold?
22:34amalloyRoboClaudio: i'm pretty sure he hasn't worked on it at all recently
22:52RoboClaudioamalloy: thanks :)
23:20technomancyten whole minutes
23:21amalloygfredericks: static compiler? i'm not entirely clear on what that means. does clojure have a dynamic compiler?
23:22brehaut(def static-compiler (constantly some-binary))
23:23amalloybrehaut: that's how ghc works, right? always compiles down to a lazy binary, which loads whatever code it decides you *actually* need at runtime :)
23:24brehautlol :)
23:24brehauti dont know: ive never had a haskell program compile without a type error
23:24amalloynor with a type error, i should think
23:25brehautwell true
23:25brainproxyin core.async / its docs, are "channel" and "port" synonyms?
23:26brainproxyor they convey a different meaning?
23:26marcopolo2brainproxy: yes
23:27marcopolo2brainproxy: to the first one sorry
23:27brainproxymarcopolo2: thanks
23:30coventryI have a macro which is erroring out with a really uninformative stack trace. All it says is that something went wrong in macroexpand1, doesn't even give the line number of the form which caused the arity exception. Is this a common problem with developing macros and if so are there any tricks for getting better stack traces from macros?
23:31marcopolo2coventry: I usually play around with (macroexpand1 '(your-macro foo))
23:31marcopolo2the will show you what your macro will expand to without running it
23:33coventryThis is a recursive macro, though. It macroexpands its contents, then wraps the interesting contents of whatever special form is yielded by that, and will recurse on the eval. I suppose I can just trace the output of the macro at each stage.
23:34talios'lo brehaut
23:34brehauthi talios
23:35marcopolo2coventry: I did something similar a while ago, I ended up changing the inner macroexpands to macroexpand1 to see if I could spot the error
23:35marcopolo2coventry: what's the macro?
23:36amalloycoventry: "a really uninformative stack trace" is subjective. it's often the case that if you gisted it someone could help
23:36coventrymarcopolo2: It's a general code-transformation scheme similar to riddley.walk. In this case, I want it to wrap whatever it's passed in tracing/debugging instrumentation.
23:39brainproxymarcopolo2: are you aware of a larger set of examples for core.async (i.e. larger than the set in the github repo) which explores the API in more detail?
23:39marcopolo2brainproxy: you doing cljs or clj?
23:39brainproxyi must admit that it's not clear to the "why" and "how" / "how to" for many of the API features
23:39brainproxymarcopolo2: cljs mainly, at this point
23:39coventryamalloy: I don't need help to debug in this case, I'm just anticipating difficulties in more complex situations. But I would welcome any suggestions you have about how to read https://www.refheap.com/19855
23:39brainproxyfor core.async I mean
23:40brainproxyclear to *me
23:40marcopolo2brainproxy: google david nolen's core.async tests
23:40gfredericksamalloy: you done known I was talkin bout static types
23:40marcopolo2he has some examples for some core.async cljs stuff
23:41gfredericksamalloy: gotta sacrifice clarity if I'm gonna fit my IRC comments within 140 characters
23:41marcopolo2brainproxy: but it's pretty simple, in cljs you can just use the go blocks
23:42brainproxymarcopolo2: right, playing around already
23:42marcopolo2brainproxy: Anything in particular tripping you up?
23:42brainproxyno, just looking over the API, which seems to have grown since last time I tinkered
23:42brainproxystuff like onto-chan, admix, mult
23:43brainproxymaybe i just didn't look that closely beforehand, not sure
23:43amalloycoventry: line 73 of wrap_macro_test, right? contains a call to wrap3/walk-wrap, with the wrong number of args
23:43brehauttalios: hows things?
23:43marcopolo2brainproxy: o wow, you are right. never saw those before
23:46coventryamalloy: No, that is the initial test form. The call to wrap3/walk-wrap is actually in wrap-macro/wrap-form*, a couple of layers down the stack.
23:47marcopolo2brainproxy: the source is pretty helpful
23:47brainproxymarcopolo2: that is a true statement
23:47brainproxy:)
23:47brainproxyi just like examples