#clojure logs

2010-09-15

02:56LauJensenGood morning all ya'll
02:58defnmorning
02:59amalloymornin'
02:59bobo_yo!
02:59bobo_im boored at my php at work, cant it be conj-labs soon!
03:02LauJensenUnfortunately no - Im really looking forward to this one as well
03:12amalloyneat, i hadn't heard of conj-labs yet. Laujensen: http://www.conj-labs.eu/instructors.html misspells career
03:12LauJensenThanks! :)
03:13LauJensenfixed
03:13LauJensenamalloy: If you want to tag along, talk to your boss asap, we're almost sold out
03:14amalloynah, never gonna happen. <shameless-plug>www.hubpages.com</shameless-plug> is gonna be on PHP forever
03:15bobo_amalloy: i code php at my current assignment aswell...
03:15LauJensenamalloy: You should criticise your company so heavily in public like that
03:15LauJensens/should/shouldnt/
03:15sexpbot<LauJensen> amalloy: You shouldnt criticise your company so heavily in public like that
03:15amalloyhah
03:17amalloybenefits/speed uses parallize instead of parallelize
03:18LauJensenfixed, thanks
03:19amalloynext time the tech industry crashes i'll moonlight as a copy-editor
03:19amalloycourse/practical: s/breakfeast/breakfast
03:22amalloyanyway lj, it sounds neat. let me know when you're in california :)
03:22LauJensenI'll be sure to do that :)
03:23LauJensenI just had a connection reset, so if you said anything after I said 'fixed, thanks' it got lost
03:23amalloy(12:16:54 AM) amalloy: next time the tech industry crashes i'll moonlight as a copy-editor
03:23amalloy(12:17:46 AM) amalloy: course/practical: s/breakfeast/breakfast
03:23defnlau, you a cake user?
03:23LauJensendefn: yes sir
03:23amalloy(and now i've read the whole thing. no more typos from me)
03:23LauJensenamalloy: even if it is a feast? :)
03:24LauJensenamalloy: thanks for your feedback, big help
03:24defnLauJensen: how's it going for you?
03:24amalloyi doubt the hotels provide real feasts, even in germany
03:24LauJensendefn: Really well
03:24defnLauJensen: yeah I'm super impressed
03:25LauJensenMe too- I love their task system
03:25defnthe persistent JVM can sometimes be a little annoying
03:25amalloyas someone who's satisfied with lein, what does cake do that i should be interested in?
03:25LauJensenyes, and it has a bug
03:25defnbut it's a small price to pay for a persistent JVM
03:25defnit's beautiful sometimes
03:25LauJensenamalloy: a persistent JVM (ie. no startup time after the first command), a great dependency based task system and its truely cross-platform, easy to install on Windows
03:25defnLauJensen: oh? which bug is that?
03:26LauJensendefn: Sometimes commands that follow each other in a short space of time can generate a BindAddress Exception, they're looking at it now though
03:26defnamalloy: it also lets you do up front default configuration so you can create new projects with default :dependencies and :dev-dependencies
03:26LauJensenamalloy: And also, its a drop in replace for lein
03:26defnyeah they're basically compatible
03:26amalloyhmm. persistent jvm sounds nice, but i'm blessed to use ubuntu at home and at work
03:27defnamalloy: im not sure i understand?
03:27amalloyie, don't care much about the cross-platform stuff
03:27defnubuntu has some sort of default persistent JVM or something?
03:27LauJensenamalloy: hehe, PHP and Ubuntu, you're giving me strange images in my head. But how does that relate to cake?
03:27defnamalloy: im not sure how cross-platform means anything for cake
03:27LauJensenamalloy: ah ok. One day you might get a customer who requires building to take place on a Windows server. Thats my situation right now and Cake solved it
03:27defncake runs on *nix and OSX
03:28LauJensendefn: read what I said above about x-platform
03:28defnamalloy: do you have autotest built in?
03:29amalloyummmmm, i might, but since i've never heard of it chances are slim
03:29defni dunno, cake does a lot more than that
03:29defnit's pretty awesome -- worth a look
03:30defnLupus79: what are you using tasks for?
03:30defnerr LauJensen
03:30LauJensendefn: I have a build which needs to compile an embedded database, download a bunch of things from the net depending on some specs given in a config folder and then put all of that into an executable jar
03:30amalloydefn: believe it or not, searching for "clojure auto test" yields a lot of results :P. what am i actually looking for?
03:30LauJensen...on Windows
03:30defnLauJensen: pepijn and i are working on a static site generator with cake tasks
03:31defnamalloy: it's a way to continuously run your tests against your existing code
03:31defnwhen you save a file it notices, and runs your tests against the new code
03:31defnyou have a scrolling window of tests -- you write one that fails, then you write the code to satisfy the test, repeatr
03:31defnrepeat*
03:32defnthe window shows you when you've met the requirement
03:32defnhttp://en.wikipedia.org/wiki/Continuous_integration
03:32defnread that before i get a case of the clojurian fantods
03:34amalloydefn: after i'm done reading about the etymology of fantods
03:36LauJensendefn: Didn't know Cake already had support for autotest
03:41defnamalloy: :)
03:42defnLauJensen: it's great.
03:42defnPeople have balked at the Ruby/Clojure marriage in Cake but I think it's really superficial -- the tool seems to do what I'm interested in doing.
03:43LauJensenSure, and Ruby is a huge plus for me. Its a relatively small bootstrap that lets me be completely x-platform
03:43LauJensenIf you have a problem with that, you should have a bigger problem with the bash/lein relationship
03:58amalloyif anyone has some spare brain time, i've put a description of a problem i need to work out an algorithm for at www.malloys.org/~akm/canonical.txt. i'd love some suggestions to prevent me going too deep down a silly road before i get started
04:13LauJensenamalloy: first tip: dont solve this using PHP, second tip: dont make me scroll all the way to the right to read the end of every line...please :)
04:14amalloyLauJensen: heh, sorry. i'm surprised browsers don't wrap .txt files. and yes, this is for my clojure project
04:16amalloyLauJensen: added hard line breaks if you refresh
04:21jjidosince the values are sorted, each box contains a series of adjacent segments. I would intersect the whole box segment (lowest to highest) with other boxes, then look closer at those that have non-empty intersection
04:24amalloyjjido: hmm. interesting idea. the boxes will tend to be pretty small, so i'm not sure how much this buys me but it's worth thinking about
04:32jjidohow do I implement a fork-join kind of parallel algorithm? Agents?
04:34grignaakjjido: there used to be a wrapper around fork-join. but this page says its deprecated http://clojure.org/other_libraries
05:50fliebelIs there a better way than this to put together a line-seq? (apply str (interleave seq-of-lines (repeat \newline)))
05:52fliebel(and what was the the name of the fn that did nothing at all?)
05:53ordnungswidrigI have an problem where my algorithm must iterate a list multiple times and I wonder if I can enhance it.
05:54kumarshantanuordnungswidrig: share a gist maybe?
05:55ordnungswidrigbasically for every split of the list [s1 s2 s3 s4 …],i.e. [] [s1 … s4], [s1] [s2…s4], [s1,s2] [s3,s4]….
05:55ordnungswidrigI have to check the left partition and the right partition. but the check of the right partition need the reverse iteration of the right part
05:57ordnungswidrigCurrently i have the steps: iterate over the list and split into a partition, say [p1 p2 p3.. pn] [a1 a2 a3…an]. Second iterator over the ps to calculate sth. then reverse iterator over the as to calc sth else.
05:58Chousukefliebel: identity
05:59fliebelChousuke: Nice name...
05:59ordnungswidrigso that are three iteration and the calculation over the ps and as can be done iteratively, e.g. as reduction and are the same for each partition. i.e. (calc p1 p2 p3) always gives the same result and can be calculated from (calc p1 p2) and p3
06:01ordnungswidrigso that there are three iterations....
06:02kumarshantanuordnungswidrig: probably a pastebin.com or gist.github.com entry will help undrstand it better
06:03ordnungswidrigkumarshantanu: I have no code at the moment but I will gist it soon
06:03ordnungswidrigkumarshantanu: a little confusing, what I wrote. :-)
06:04kumarshantanuordnungswidrig: yeah I can't get the picture readily from the description
06:05ordnungswidrigkumarshantanu: i wouldn't either
06:06ordnungswidrigis there a way to get all partitions [[] [x1..xn]] [[x1] [x2..xn]] [[x1 x2] [x3..xn]] [[x1 x2 x3] [x4..xn]] .. [[x1..xn] []] for the list [x1..xn]?
06:09ordnungswidrig,(let [l (range 1 10)] (map #(take % l) (range (count l))))
06:09clojurebot(() (1) (1 2) (1 2 3) (1 2 3 4) (1 2 3 4 5) (1 2 3 4 5 6) (1 2 3 4 5 6 7) (1 2 3 4 5 6 7 8))
06:12Chousuke-> (for [i (range (count [1 2 3 4]))] ((juxt take drop) i [1 2 3 4]))
06:12sexpbot=> ([() (1 2 3 4)] [(1) (2 3 4)] [(1 2) (3 4)] [(1 2 3) (4)])
06:13ordnungswidrigI don't like the count
06:13Chousuke-> (for [i (range (inc (count [1 2 3 4])))] ((juxt take drop) i [1 2 3 4]))
06:13sexpbot=> ([() (1 2 3 4)] [(1) (2 3 4)] [(1 2) (3 4)] [(1 2 3) (4)] [(1 2 3 4) ()])
06:14Chousuke-> (take 5 (for [i (range)] ((juxt take drop) i [1 2 3 4]))); I guess you can do this too
06:14sexpbot=> ([() (1 2 3 4)] [(1) (2 3 4)] [(1 2) (3 4)] [(1 2 3) (4)] [(1 2 3 4) ()])
06:14ordnungswidrig,(reductions conj [1 2 3 4 5])
06:14clojurebotjava.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IPersistentCollection
06:14Chousukebut note that the seq will be infinite
06:15ordnungswidrig,(reductions conj [] (range 1 5))
06:15clojurebot([] [1] [1 2] [1 2 3] [1 2 3 4])
06:19ordnungswidrig,(let [l (range 1 5)] (map (fn [i] [(take i l) (drop i l)]) (range (count l))))
06:19clojurebot([() (1 2 3 4)] [(1) (2 3 4)] [(1 2) (3 4)] [(1 2 3) (4)])
06:32kjeldahl,(if (= 1 9) (println "abc") (do ((println "def")(println "ghi")nil)))
06:32clojurebotjava.lang.NullPointerException
06:32kjeldahlAnybody feel like clueing me in?
06:33LauJensen,(if (= 1 9) (println "abc") (do (println "def")(println "ghi")nil))
06:33clojurebotdef ghi
06:33LauJensenthats your clue :)
06:33kjeldahlThanks!
06:35ordnungswidrigkumarshantanu: http://gist.github.com/580531
06:36ordnungswidrig,((print 1))
06:36clojurebotjava.lang.NullPointerException
06:37bobo_,("asdf")
06:37clojurebotjava.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn
06:37ordnungswidrig,(nil)
06:37clojurebotjava.lang.IllegalArgumentException: Can't call nil
06:37LauJensen,(:hey)
06:37clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to keyword: :hey
06:37ordnungswidrig,(print 1)
06:37clojurebot1
06:37ordnungswidrigwhy then the NPE on ,((print 1))
06:37bobo_what does print return? nil?
06:37ordnungswidrig,(1)
06:37clojurebotjava.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn
06:38LauJensen,(nil? (print "hi"))
06:38clojurebottrue
06:38clojurebothi
06:38ordnungswidrigbobo_: yes, print returns nil but clojurebot seems to mess this up
06:38ordnungswidrigwhy would return print it args?
06:39bobo_why does (nil) and ((print "asdf")) return different errors then?
06:40LauJensenbobo_: nil is a special case
06:40bobo_so its different to call nil and something that retuns nil?
06:41ordnungswidrig,(letfn [(px [rest] (do (print rest) rest))] (px (+ (px 1) (px 2))))
06:41clojurebot3
06:41clojurebot123
06:41ordnungswidrig,(do (print 1) 2)
06:42clojurebot2
06:42clojurebot1
06:42ordnungswidrigweird, why does ,(print 1) omit nil then?
06:42LauJensenbobo_: yes
06:42LauJensenI think nil is implemented as a cornercase
06:43ordnungswidrigLauJensen: so (nil) -> IllegalArgumentException (let [x nil] x) -> NPE?
06:44LauJensen,(((constantly nil)))
06:44clojurebotjava.lang.NullPointerException
06:44LauJensen,(nil)
06:44clojurebotjava.lang.IllegalArgumentException: Can't call nil
06:45ordnungswidrigI hope for 2.0 there is better error reporting on the replease plan :)
06:47LauJensenI think when the Compiler is called with nil, it just rejects. When its called with a body its parses it one item at a time, hence the different exception, its in a nested try/catch around here: http://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L5369
06:57LauJensenWhat am I missing here
06:57LauJensen,(let [b (Boolean. "false")] (println (class false) \: (class b) \: (not false) \: (not b)))
06:57clojurebotjava.lang.Boolean : java.lang.Boolean : true : false
07:07LauJensen,(let [b (Boolean. "false")] (println (false? b) \: (true? b)))
07:07clojurebotfalse : false
07:16raekI can't understand why they didn't make that constructor private...
07:17LauJensenmy bad. Its a known (and document?) design decision for performance concerns
07:17LauJensenUse Boolean/FALSE or read-string if you need to parse input
07:17raek,(Boolean/parseBoolean "false")
07:17clojurebotfalse
07:18raek,(let [b (Boolean/parseBoolean "false")] (println (false? b) \: (true? b)))
07:18clojurebottrue : false
07:21kjeldahl,(for [scvec [1 2 3]] (println scvec))
07:21clojurebot(nil nil nil)
07:21kjeldahl,(for [scvec [1 2 3]] (scvec))
07:21clojurebotjava.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn
07:21Chousukewhat are you trying to do?
07:22kjeldahlIt's wierd. In my repl environment, that line works (the first one). I get output. When I run the same code as part of some other code, the code inside the for loop doesn't seem to execute.
07:23kjeldahl(and no, the code doesn't just output stuff, that's just for verification)
07:25LauJensenkjeldahl: for is lazy, are you evaluating it ?
07:25LauJensen,(let [b (for [i (range 5)] (print i))] nil)
07:25clojurebotnil
07:25LauJensen,(let [b (doall (for [i (range 5)] (print i)))] nil)
07:25clojurebot01234
07:26kjeldahlI have no idea what you're talking about, but it sounds correct.
07:26LauJensenkjeldahl: A lazy sequence is not evaluated until you consume its elements. Its only a promise of evaluation
07:26LauJensenconsider
07:26LauJensen,(take 5 (iterate inc 0))
07:26clojurebot(0 1 2 3 4)
07:27LauJensenif (iterate inc 0) wasn't lazy, it would compute towards infinity
07:27LauJensen(take 5) evaluates 5 (actually more but thats a detail) elements
07:27fliebelLauJensen: Because of chunking?
07:27LauJensenfliebel: (actually more) = chunking
07:31kjeldahlSo what's the simplest way to iterate over all elements in a vector then, not lazily?
07:32spariev,(doseq [i [1 2 3]] (print i))
07:32clojurebot123
07:33LauJensenkjeldahl: for, map, filter etc are for non-side-effectfull operations, ie functional programming. dotimes and doseq are for side-effects. It depends on what you want to do
07:34kjeldahlExcellent. doseq was what I needed. Thanks all.
07:53LauJensenWhats the ideal way to mimic an html table representation in Swing ?
07:56maravillasmiglayout feels a bit like html tables, if you squint
07:56bobo_jtable?
07:57LauJensenbobo_: JTable would be fine, except its a hassle to implement buttons and dropdowns in it, so its more a visual thing. maravillas Im already using miglayout as the layoutmanager
07:57fliebelLauJensen: The default layout is kind of like a 3x3 table… not what you want probably. My Swing is to rusty.
07:58LauJensenalthough these guys seem to be loving it http://www.jasperpotts.com/blog/2007/09/nimbus-almost-done/
07:58LauJensenbut then again, the java sharks seem to be okay with writing a few thousand lines of code per component
07:59bobo_yeh, swing is... not fun in any way
07:59LauJensentrue
08:00bobo_http://blogs.sun.com/geertjan/entry/simple_example_for_an_outlineview i liked that example, its not pure swing but still
08:00bobo_it is supposed to show how easy it is. i think it shows how increadibly much code it requires for hardly anything
08:01fliebelLauJensen: If you're a Python guy, you might try writing ugly interfaces with the Java tcl bindings :P
08:01LauJensenfliebel: You might want to check out some of my older posts on the blog :)
08:02fliebelLauJensen: How old? Where's your search box?
08:02LauJensen,google python vs clojure
08:02clojurebotjava.lang.Exception: Unable to resolve symbol: google in this context
08:03LauJensenclojurebot: google python vs clojure
08:03clojurebotFirst, out of 32100 results is:
08:03clojurebotBest In Class: Python vs Clojure - Evolving
08:03clojurebothttp://www.bestinclass.dk/index.php/2009/10/python-vs-clojure-evolving/
08:03bobo_oh, i missed your best in class tour post
08:03LauJensenI did two of them. I come off as though I hate Python which I dont, its actually on my top 5 list of languages :)
08:03LauJensenbobo_: :(
08:03bobo_i blame my vacation!
08:04LauJensenbobo_: You can hook up an RSS reader to get notified when something happens, either that or keep up with me on twitter
08:04fliebelLauJensen: What are the other 3?
08:04bobo_i think you are in my rss, and on twitter. i must have failed somehow
08:05LauJensenfliebel: Clojure, Haskell, Python, Common Lisp, C#
08:05bobo_LauJensen: hm, i cant find any rss link or similar?
08:05LauJensenbobo_: Your browser should pick it up automatically. Check out the footer on that Best In Class Tour blogpost
08:05LauJensenThere's shiny new icon and a link
08:06bobo_hm, chrome didnt pick it up, weird
08:06bobo_firefox did
08:07LauJensenthats odd. Its an old standard
08:09sparievLauJensen: what about FormLayout ? http://www.jgoodies.com/freeware/forms/index.html
08:10sparievit used to be good when i did swing development last time, like 5 years ago :)
08:10LauJensenspariev: Hadn't seen that before, but it looks nice
08:10LauJensenOh how I miss the old days of Visual Studio and C#. I wonder why nobody just started with building UI systems equivalent to Winforms. GTK sucks, Swing sucks. Code generated UIs suck. You just want to drag and drop and design and be done with it
08:11LauJensenQt is actually very close... then they gave up on Jambi
08:11cinim0d['ol
08:12fliebelLauJensen: You mean you drag and drop Swing? I did it by hand… years ago. Jambi is still maintained open source I believe.
08:12LauJensenfliebel: 'maintained open source'
08:12LauJensenfliebel: No I dont drag and drop, but I want to
08:13lpetithi
08:13bobo_netbeans has an awesome swing drag and drop editor
08:13LauJensenfliebel: If you're on ubuntu you likely have 'qt-designer' installed. Thats the kind of editor I want
08:13LauJensenbobo_: Does it spew out a .java file when you're done designing?
08:13fliebelLauJensen: I'm on Mac, but I have it installed, because I like QT better than TK in Python.
08:13bobo_LauJensen: yes, (and a .form)
08:13LauJensenbobo_: How are you driving that from Clojure?
08:14bobo_no clue, havent done any swing with clojure.
08:14bobo_but might work. i think the .form is only for netbeans to make sense of stuff
08:14LauJensenI'll have to check that out once I get some time
08:16fliebelWhat is the best way to get the first element from a seq to satisfy f? I currently have (first (drop-while f))
08:16cinim0dfliebel: find-first
08:17fliebelcinim0d: Thanks
08:17bobo_some googling tells me cemerick has used mattise (netbeans gui editor) and clojure
08:17cemerickbobo_: indeed I have
08:18fliebel(doc find-first)
08:18clojurebot"clojure.contrib.seq-utils/find-first;[[pred coll]]; Returns the first item of coll for which (pred item) returns logical true. Consumes sequences up to the first match, will consume the entire sequence and return nil if no match is found."
08:18bobo_google knows theese logs way to good
08:18fliebelHow comes find-first is not in here? http://clojure.github.com/clojure/clojure.core-api.html
08:18LauJensenbobo_: generally I try to be very productive by staying away from all of the tools cemerick uses. So far its worked great :)
08:19bobo_haha
08:19Chousukefliebel: because it's in contrib? :)
08:19fliebelChousuke: So then why did the above doc command work?
08:19sparievLauJensen: btw there is a GUI tool for Formlayout - http://www.formdev.com/jformdesigner/
08:19sparievnot free, though
08:20Chousukefliebel: Clojurebot's doc is special
08:20Chousukefliebel: and I think it might have contrib loaded anyway
08:20Chousukedoc looks up vars in any loaded namespace, not just core
08:20cinim0dfliebel: also, the bot specified that it was contrib.
08:21LauJensencemerick: it was a joke ol buddy, come on now :)
08:21fliebelcinim0d: I saw that, after I asked :(
08:21cinim0dnp
08:21LauJensenspariev: Looks too complex.
08:22sparievmaybe, haven't used it
08:26fliebelWhere can i read about the decomposition map thing in 1.2?
08:30fliebel*destructuring
08:31fliebelfound it… partially
08:32Chousukeit's just & {map form}
08:32Chousukeand then the rest args will be expected to be key val key2 val2 ... which will be poured into a map and destructured like a normal map.
08:33fliebelChousuke: So how do I destructure a normal map?
08:34fliebelI did find {:keys [:list :of :keys]} but that seems so… I don't know...
08:34Chousuke,(let [{:keys [a b]} {:a 2 :b 2 :c 3}] [b a])
08:34clojurebot[2 2]
08:34Chousukeoops, didn't mean to put two 2s
08:34Chousukeanyway
08:34raek,(let [{x :a, y :b} {:a 1, :b 2}] (list x y))
08:34clojurebot(1 2)
08:35Chousukeor you can do {name :key name2 "string" name3 'symbol name4 5}
08:35fliebelraek: That looks more like I expected it to work. What is this :keys business anyway?
08:36Chousukeit's a shortcut
08:36Chousuke{a :a b :b c :c} is a very common form
08:36fliebelOkay...
08:40raekyes, :keys assume the the keywords have the same name as the symbols given
08:40raekit is also possible to do a similar thing with strings
08:41raek,(let [{:strs [a b]} {"a" 1, "b" 2}] (list a b))
08:41clojurebot(1 2)
08:41Chousukeand symbols
08:41Chousuke(:syms)
08:41raek,(let [{:syms [a b]} {'a 1, 'b 2}] (list a b))
08:41clojurebot(1 2)
08:41Chousukeyou can also freely combine those as long as the names don't collide :P
08:41fliebelraek: Thank you! That makes sense to me :) Can you also combine :keys and :strs?
08:47shooverLauJensen: WinForms? If you enjoyed that maybe you should come back and check out WPF. You can drag and drop or type markup, and it's far more declarative and enjoyable to work with than WinForms
08:52jjidohow do I implement a fork-join kind of parallel algorithm? Agents?
08:53Chousukeyou could use ForkJoin? :P
08:53ChousukeIt's available in library form for JDK6 too
08:54jjidoChousuke: thanks! Is there a doc?
08:54Chousukeprobably somewhere
08:56ChousukeIf you want to do it purely in Clojure I suppose agents might work.
08:56LauJensenshoover: Sounds good but Im not working with CLR in any way
08:57Chousukeyou might have a thread do part of the work and then send the result to an agent which combines it with already finished stuff.
08:57raekjjido: what does "fork-join" mean? something like (let [f1 (future exp1) f2 (future exp2)] (+ @f1 @f2))?
08:58raekor something more special?
08:59jjidoChousuke: yes I want something like that. raek: let me think
08:59ChousukeI wonder how the par branch is doing
09:00raekanyway, futures are a simple way to do some computations in other threads and then collect the results
09:00Chousukerhickey implemented some interesting parallel vector ops with the JDK7 forkjoin library but it seems to have been forgotten :P
09:01raekpvalues and pcalls might also be worth checking out
09:03jjidoraek: the result combine operation is repeated on all chunks recursively
09:03jjidoI think there should be a specific chunk size which forks / joins
09:05jjidothen it could be the scheme you describe
09:08fliebelHmm, how is unit testing most commonly done in Clojure? I just came up with a funny idea.
09:08raekclojure.test, something like this: http://gist.github.com/570143
09:09raek(variation of style exists, of course. this is just how I have done it.)
09:11fliebelraek: I just thought about sort of inline tests for side-effect-free functions. I'll cook something up.
09:12raek,((fn [x] {:pre [(pos? x)]} (dec x)) 0)
09:12clojurebotjava.lang.AssertionError: Assert failed: (pos? x)
09:13raek(dunno if this has to do with what you do, but fyi all fns can have pre and post conditions)
09:13fliebelraek: Something like that, but not jus constraining input and output, but rather have a map of arguments and expected results.
09:34fliebelhmmm, what is the non-lazy variant of map? Or do i just wrap it in doall?
09:36Chousukethere is none, so yes, use doall
09:37Chousukeunless you mean doseq, but that doesn't produce a sequence :)
09:38fliebelChousuke: http://gist.github.com/580719 <- also my inline-testing idea
09:39fliebelIn my opinion, it'd be far more pleasant to test some functions by just giving them an extra map of expected results.
09:39Chousukeyeah, use doseq
09:41Chousuke(doseq [{[input output] :tests} (meta f)] (assert (= (apply f input) output)))
09:41Chousuke(map destructuring there just for fun)
09:42Chousukeer, and also wrong.
09:42Chousukenever mind :P
09:42ChousukeI thought it was a good idea and then it wasn't.
09:42fliebelChousuke: What's wrong?
09:42Chousuke(meta f) is not a seq
09:43fliebelChousuke: So can't you destructure a map?
09:43Chousukefliebel: in this there's no map to destructure.
09:44Chousukeany destructuring in doseq is applied to every element of the seq
09:44Chousukewhich is the error in the above.
09:45fliebelah, I see
09:45Chousukeso it has to be (doseq [[input output] (:tests (meta f))] (assert (= (apply f input) output)))
09:54fliebelChousuke: It seems core/test does about the same as I wanted :-o So I only need to define a macro to add the data easily.
10:05fliebelHuh, this is weird, I can make a defn with either the doc string or the arguments going first.
10:05fliebelWhat is the preferred way?
10:06chousera string after the args won't be a doc string, I think.
10:06mrBlissfliebel: if you put the argument first, the docstring is interpreted as part of the function
10:07fliebelright… stupid of me
10:22nunbHi can someone point me to a comparison of Moustache vs Compojure routing? Moustache appears to yield a more composable structure.. but not sure how battle-tested it is.
10:24LauJensennunb: I think its at least as battle-tested as Compojure. I don't know of any direct comparisons, but its a good topic for a future blogpost
10:24LauJensenI've deployed both Compojure and Moustache in professional solutions, more than once on both counts as well.
11:05fliebelAm I correct that app in Moustache returns a function that takes a ring request?
11:05fliebelIf so, what does a minimal request map look like?
11:21jcromartieI'm trying to duplicate a Ruby script in Clojure, and I am finding that the Clojure version is (surprisingly) much slower than the Ruby version.
11:21jcromartieit takes about 5x longer than the Ruby version
11:22jcromartie(paste on the way)
11:24jcromartiehttp://gist.github.com/580882
11:26raekfliebel: yes, the function returned takes a ring request and returns a ring response
11:26raekfliebel: iirc, moustache probably just looks at the :url key
11:26fliebelraek: Cool :) Yea, and the request method, got it working :)
11:27fliebelraek: I'm looking to (ab)use Moustache both as Ring middleware and as routing for something else.
11:30AWizzArdA very lightweight http client? I need to write my own headers and decide what method I want to use (Post, Put, Head, ...).
11:35jcromartieI revised the clojure version at http://gist.github.com/580882
11:35jcromartieto be a little nicer
11:38nunbjcromartie: how do you compare runtimes?
11:38jcromartiethe time shell command
11:38jcromartietaking into account the startup
11:38nunbjvm startup cost?
11:38nunboh
11:38jcromartieruby takes 9 seconds, clojure takes 50
11:38jcromartieno room for JVM startup there :)
11:39dnolenjcromartie: hmm I wouldn't be surprised if the Clojure shell is the bottleneck, you're running sed on every match?
11:39dnolenshell out I mean
11:39jcromartieyeah
11:40jcromartiebut why would Ruby be so much better at that?
11:40jcromartietechnically speaking
11:40jcromartieI know why it would make sense for Ruby to optimize that :P
11:41fliebeljcromartie: I wonder the same thing. I recently just printed hello world in a loop in both Clojure and Python, and Python was orders of magnitude faster.
11:41dnolenjcromartie: why do you need to use sed (I don't know what it does) ?
11:41raekI tend to do (into {} (for [[key val] seq] [(f key val) (g key val)])) *a lot*. any suggestions for an alternative?
11:41raek2) or for the [f (g key val)] case?
11:42grignaakjuxt!
11:42fliebelraek: What is that supposed to do?
11:42jcromartiednolen: in this case, sed just prints a certain range of lines
11:43grignaak,(into {} (map (juxt inc dec) '(1 2 3 4)))
11:43clojurebot{2 0, 3 1, 4 2, 5 3}
11:43raeksomething like map, but for the entries of a map
11:43raekI think I saw a map-vals function in contrib once, but I can't seem to find it
11:44fliebelgrignaak: Good to see juxt put to a use :)
11:44raekmaybe (zipmap (keys m) (map some-fn (vals m))) would be sufficient in some cases
11:44grignaakdoh! just saw the destructuring of key val
11:44dnolenjcromartie: why not just use Clojure for that? UNIX is all about stringing different commands together, JVM is all about working within the JVM. Will probably end up being much faster than Ruby then ;)
11:45jcromartieyeah
11:49arohnerjcromartie: my guess is, you're spawning a new shell for each call to (sh)
11:49jcromartiewhereas Ruby does...?
11:49AWizzArdclojure.contrib.http-agent was deprecated. Is there a new http client somewhere?
11:50jcromartiewoo hoo!
11:50jcromartieit's way faster now
11:52ohpauleezAWizzArd: I'm not sure where in contrib it is, but http://github.com/technomancy/clojure-http-client and http://github.com/neotyk/ahc-clj are cool. If you need auth support or more features, just use HttpClient
11:52dnolenjcromartie: what did you do?
11:53AWizzArdohpauleez: HttpClient <== Apache Project?
11:53ohpauleezyeah
11:53jcromartiednolen: (->> (read-lines file) (take end-n) (drop (dec start-n)))
11:53ohpauleezIt's the only one I know of that you can set the post body, auth support, etc
11:53dnolenjcromartie: nice, how many seconds does it take now?
11:54chouserjcromartie: what JVM are you using?
11:54jcromartiechouser: Mac OS X 10.6 default
11:54jcromartiednolen: now it's like 1/3 to 1/4 the time of Ruby
11:55arohnerjcromartie: what did you change?
11:55jcromartiearohner: take'ing and drop'ing from duck-streams/read-lines instead of shelling out to sed
11:55jcromartieshelling out kills it
12:00jcromartiehey chouser: you wrote shell-out. is there no way to use pipes with it?
12:01slyrusall of the clojure http clients I've found are wrappers (in some cases wrappers upon wrappers). A drakma equivalent would be nice.
12:01kjeldahlSuggestions for most elegant way to express: (if-not (nil? expr) expr someothervalue)
12:02chouserjcromartie: no, there isn't.
12:02hiredman(or expr1 expr2)
12:02kjeldahlhiredman: thanks
12:03AWizzArdslyrus: there was a http client in Contrib, I don't know why it was removed.
12:03Rayneskjeldahl: Remember that 'nil' is false in Clojure. You rarely have to explicitly check if something is nil with niL?
12:03Raynesnil?*
12:03chouserjcromartie: would a (with-sh [[in out err] ("sed" ...)] ...) sort of thing work for your use case?
12:04apgwoz,(false? nil)
12:04clojurebotfalse
12:04Raynes-> (if nil 0 1)
12:04sexpbot=> 1
12:04kjeldahlRaynes: Thanks. Very elegant.
12:04ohpauleez(boolean nil)
12:04apgwozah, yes
12:05ohpauleezwill be false
12:05apgwozthat's what i was missing
12:05apgwoz,(false? (boolean nil))
12:05clojurebottrue
12:05ohpauleezthere it is
12:13chillitomi hear all the cool kids are in here..
12:13chillitomanyone want to suggest a simple little algorithm for me to try cutting my clojure teeth on?
12:14chouserchillitom: I always recommend projecteuler.net
12:14ohpauleezchillitom: What are you coming from?
12:15ohpauleezI sometimes suggest a collective intelligence algo on a simple web system.
12:15ohpauleezlike chouser said, euler is nice. Gives you a chance to take a simple algo, then type it, then parallelize it
12:16ohpauleezAnything you choose, you'll want to be able to play with the data structures a lot, and the concurrent stuff.
12:17ohpauleezI also recommend watching the video/presentation called Are We There Yet? (http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey)
12:17fliebelchillitom: I like this one: http://projecteuler.net/index.php?section=problems&amp;id=11 Not to much math and a lot of data.
12:18fliebelEnlive is killing me… deftemplate gives me a nullpointer for everything I do, even with no selectors in it or copying an example from the web.
12:19fliebelI tried entering an absolute path to my file, nothing!
12:21chillitomchouser: euler is a bit too mathematical for me.. primes i don't find that interesting (although i know i should)
12:21chillitomohpauleez: coming from pretty much everything.. c,java,c#,haskell
12:22chillitom..ruby,python
12:22chouserchillitom: fair enough
12:23ohpauleezchillitom: What types of things do you typically write?
12:23chillitomchouser: did you used be be a big cheese in ##java?
12:23chillitomi recognise your name
12:23ohpauleezI would just do a weekend project, a parallel web scraper is nice (takes less than a day)
12:24chillitomohpauleez: that's a good idea and relates nicely to my day job
12:24chouserchillitom: goodness, no.
12:24chillitomchouser: no offence intended ;-)
12:25chouser:-)
12:25ohpauleezchillitom: You'll want to look at enlive, get it working, then add agents (you'll be blown away), then type-hint it. If you loop on a data structure you may get to play with transients
12:26ohpauleezIf you're a guy who totally digs performance, time how each approach takes, and get ready to be blown away
12:26ohpauleez:)
12:27jjidowhat is enlive?
12:27ohpauleezenlive is a selector based templater/scraper: http://clojuredocs.org/Enlive/net.cgrand.enlive-html
12:28ohpauleezproject at http://github.com/cgrand/enlive
12:28jjidohtml only?
12:28LauJensenjjido: also xml (no namespaces though)
12:29raekenlive example (title fetching): (-> "http://clojure.org/&quot; URL. html-resource (select [:title]) first :content first)
12:29jcromartiechouser: I don't think so, doing it in Clojure is much faster than launching many shells
12:30raekit uses tagsoup for the html parsing, so it can consume "street HTML" too
12:30jjidoI would like to look how to parallelise the merge-sort I wrote, I am still not clear what Clojure offers for that
12:30raekbut as the programmer, you see a fixed element tree (with all html, head and body tags properly placed)
12:34ohpauleezjjido: You could use futures and promise and do each part in a different thread
12:34ohpauleezYou could also abuse agents and do the same thing
12:35ohpauleezyou could possible use pmap, depends on how you wrote your mergesort
12:35ohpauleezpossibly*
12:35bobo_hm, anyone using cake in ubuntu?
12:35chillitomraek, i was gonig to ask if tagsoup was behind it, i've used that lib before, v effective
12:36jjidoohpauleez: you need Java to start threads?
12:36ohpauleeznope, ,(doc future)
12:36chouserjcromartie: I meant for piping to shell commands
12:36ohpauleez,(doc future)
12:36clojurebot"([& body]); Takes a body of expressions and yields a future object that will invoke the body in another thread, and will cache the result and return it on all subsequent calls to deref/@. If the computation has not yet finished, calls to deref/@ will block."
12:36jcromartiehmm, posisbly
12:37chouserhm ... actually, I think I just had a better idea.
12:37jcromartiebut sometimes I just need a bunch of pipes and redirects, etc. :)
12:37bobo_https://gist.github.com/b239769d7f21d7ef59f7 anyone have any clue on how to solve that?
12:37raek(doto (Thread. (fn [] ...)) .start)
12:37jjidoraek: looks fine
12:38raekclojure functions implement runnable, so interop is pretty painless in this case
12:38ohpauleezjjido: http://www.michaelharrison.ws/weblog/?p=239
12:38chillitomi learnt haskell about three years ago and i remember picking it up in about a week.. Clojure looks much easier and it's taking me weeks, i think the old grey matter has slowed down
12:38raekfutures has the advantage that they can return a value back
12:38fliebelbobo_: Check the path?
12:39ohpauleezjjido: that you can deref using @
12:39bobo_fliebel: but shouldnt gem install handle that for me?
12:39bobo_i know 0 about ruby/gem
12:39raek(doc future)
12:39clojurebot"([& body]); Takes a body of expressions and yields a future object that will invoke the body in another thread, and will cache the result and return it on all subsequent calls to deref/@. If the computation has not yet finished, calls to deref/@ will block."
12:40laurusIs it OK to use Clojure with OpenJDK?
12:40ohpauleezlaurus: I use JDK7 with my clojure
12:40ohpauleezworks just fine for me
12:40fliebelbobo_: It should, but apparently it didn't. So make sure the place ruby puths the bin is on the path, and before the ubuntu thing that catches the missing things.
12:40laurusohpauleez, OpenJDK or SunJDK?
12:40ohpauleezlaurus: OpenJDK
12:40laurusExcellent, that's great to hear!
12:41ohpauleezThat said, I also use SunJDK (Apple branded) for some stuff
12:41laurus:)
12:43laurusThanks for the info!
12:43ohpauleezlaurus: totally welcome
12:44ohpauleezjjido: ping me if you run into trouble
12:44fliebelWhy does Enlive only look on the cp for files?
12:45ohpauleezfliebel: I don't think I was aware it did that. Maybe hit up the clojure-web list/google group
12:45jjidoohpauleez: ok
12:47chillitomohpauleez: watching are we there yet on your recommendation, i love rich's presentations
12:47fliebelohpauleez: Enlive readme: if you specify your resources as strings they will be searched on the classpath
12:47ohpauleezchillitom: They are awesome, and I feel like that one gets to the heart about the Clojure mindset and design philosophy
12:49raekfliebel: use (java.io.File. "filename") or (clojure.java.io/file "filename")
12:50raekthe JVM doesn't have a strong notion of current working directory, so absolute paths might be a good idea
12:50raekalso, leiningen makes the resources/ directory available on the classpath
12:50ohpauleezre: resources directory, would explain why I never ran into this issue
13:41amalloyi want to know who was so cruel as to put map, reduce, filter, and join into PHP but make them painful to use. it'd almost be better if they weren't there at all
13:42ohpauleezamalloy: haha, I'm currently working on a PHP project with work. I hear ya
13:50bobo_amalloy: +1 on that
13:55LauJensenamalloy: What makes them so painful?
13:56amalloyclosures aren't available (until 5.3, in which they exist but are bulky)
13:57bobo_if you can call "put your code in a string" as a closure
13:58bobo_or is the create_function 5.3?
13:59amalloynot sure
14:13mfexhi all
14:14mfexis there an unfold function somewhere in clojure or contrib?
14:14LauJensenmfex: what would unfold do ?
14:15mfexit is the opposite of reduce
14:15mfexor the opposite of fold, see http://en.wikipedia.org/wiki/Anamorphism
14:17raekcan you show an example input and output?
14:19mfexthis is the equivalent of iterate from the wiki: (defn iterate-unfold [f x] (unfold (fn [a] [a (f a)]) (fn [_] false) x))
14:19mfexI want to use it in an answer for this question on the group: http://groups.google.com/group/clojure/browse_thread/thread/f1593f492759e66b#
14:20bobo_wow, 1.2GB of memory used by a new empty cake project with swank running?
14:21raekmy clojure processes often start at ~700 MB if I don't pass JVM options
14:21fliebelbobo_: So all those EMACS acronyms still apply?
14:21raekthen I can get them down to about 150 MB
14:21bobo_fliebel: acronyms? :-)
14:21bobo_lein swank uses 300MB
14:22bobo_same project
14:22raek(this is when starting a repl and swank)
14:22bobo_oh well, memory is made to be used
14:23fliebelbobo_: http://en.wikipedia.org/wiki/Emacs#Performance
14:23bobo_cute :-)
14:23lancepantzbobo_: you tweak the jvm options and get the memory footprint down
14:23lancepantz*could
14:24bobo_lancepantz: i dont realy care, im jsut very suprised
14:24bobo_and i cant spell, guess im running out of memory
14:24lancepantzyou're not the first to bring it up, its a legit beef
14:25lancepantzif you do and find anything useful, send a pull request :)
14:25bobo_:-)
14:25lancepantzthere's a section about jvm opts in the readme if that's of help
14:26LauJensen.cake/config => project.java_opts = -Xmx256M
14:26lancepantzwhat always shocks me is the memory usage of growl on os x
14:27bobo_why isnt -Xmx256M default if it is an improvement?
14:27lancepantzit was like 8gb
14:28bobo_8gb? thats alot :-p
14:28LauJensenbobo_: its a improvement if you have a tiny little computer with no memory, if you have 4Gb+, you dont care
14:28LauJensenI want my JVM to have 700+ memory :)
14:28bobo_yeh, as i said, i dont care, im just supprised :-)
14:28LauJensenbobo_: yea right, you're trying to code Clojure on the ipad I know you are!
14:28bobo_i wish!
14:29lancepantzhah, i'm going to add that to the cake readme
14:29lancepantzmore believable than commodore 64 anyways
14:30bobo_i think i miss the default core.clj file lenigen creates.
14:30lancepantzit does that?
14:30bobo_yes
14:30lancepantzdoes it create it project/src/project/core.clj or project/src/core.clj?
14:31bobo_TestProject/src/TestProject$ ls
14:31bobo_core.clj
14:31lancepantzcool
14:31bobo_and it just contains (ns TestProject.core)
14:31lancepantzyeah, that is a good idea
14:32LauJensenwell, if everybody wants a core.clj I guess its a good idea
14:32lancepantzi'm sure that's what ninjudd was thinking
14:32chousermfex: I'm not sure exactly what you want -- you've looked at 'iterate'?
14:32bobo_if most people want it atleast, but should probably be able to turn it of then
14:49Raynes,(dosync (alter (ref 0) inc))
14:49clojurebot1
14:49chouser*bam* STM
14:49ohpauleezrad
14:50ohpauleezis that new to clojurebot?
14:50chousernope
14:50ohpauleezah, just showing the STM some love
14:51chouserI guess. I dunno what Raynes is up to.
14:51wwmorgan,(get 1 1) ; shouldn't this raise a type error?
14:51clojurebotnil
14:51RaynesI'm playing around with sandboxing in sexpbot, so I wanted to make sure that worked in clojurebot.
14:52LauJensen-> (time nil)
14:52sexpbotjava.lang.SecurityException: Code did not pass sandbox guidelines: ()
14:54LauJensenwwmorgan: it ends up running
14:54LauJensen public final Object valAt(Object key) {
14:54LauJensen return valAt(key, null);
14:54LauJensen }
14:54LauJensen
14:54LauJensenI wonder if the second param isnt an imposed default
14:54LauJensensimilar to
14:54LauJensen,(get {:a 5} :b)
14:54clojurebotnil
14:55wwmorganLauJensen: I mean in a philosophical sense, shouldn't a type error be the correct behavior?
14:55LauJensenoooh you're being philosophical...
14:55chouserwwmorgan: I'm pretty sure it's not accidental
14:56LauJensenchouser: Yea Im feel confident as well, but I still wonder why
14:56wwmorganI can maybe see the argument for (get nil 1) returning nil rather than raising an error, but (get 1 1) is just a wrong thing
14:56LauJensenI guess its like (count nil), makes code more robust and concise
14:57chouserunless it's more like (count 34) which does throw a type error
14:58LauJensenhmm, we did I suddenly get the feeling we're in PHP land?
14:58LauJensens/we/why/
14:58sexpbot<LauJensen> hmm, why did I suddenly get the feeling why're in PHP land?
14:58wwmorganI guess there's an implied /g in sexpbot's s/
14:59LauJensenwwmorgan: yea the g was just bloat, Raynes killed it
14:59wwmorgancontains? does the same thing actually, which is more insidious, because (contains? 1 {1 2}) returns nil when it could throw an exception
15:00chouserooh
15:00chousercompile time assertions could be made about code you don't own.
15:01wwmorgan,(contains? (transient {1 2}) 1) ; This used to be a bug. I don't know whether it's been fixed.
15:01clojurebotfalse
15:01chouserwouldn't that be fun? To declare somewhere that, in this code base, contains? and get may only be called on objs that implement Associative or whose type is unknown.
15:02chouserthen as soon as you say (fn [] (contains? 1 a)) you get a compile-time error.
15:04hiredman(let [contains? (constantly true)] (fn [] (contains? 1 a)))
15:04chouserdon't worry, it wouldn't be fooled.
15:04hiredmanoh, ok
15:05hiredmanmaybe arkham could do it
15:05chouserthat is, if compile time assertions could be fooled by things like that, then I think they'd be pretty useless.
15:05chouserand since they don't exist yet, we can ascribe to them any fantastic behavior we want yay
15:06chouserarkham could do it at "compile time" or does it have such a stage?
15:06hiredmanwell, it could do static analysis
15:06chouserit starts with what the reader produces?
15:06hiredmanyes
15:07hiredman(all mostly in theory too)
15:07chouseroh, I thought you had it mostly working
15:07hiredmanbut import generator does something similar
15:08chouserdid you consider using compiler-produced analysis trees?
15:08hiredmannope
15:09hiredmanI hadn't really considered it at all
15:09chouserfair enough
15:09chouserI don't know if it would be of any benefit at all
15:09chouserand they're certainly rather impenetrable right now
15:09andyfingerhutDoes anyone have any experience with Java performance analysis tools that get into details of caching performance etc. on multi-core machines, and deal with multi-threaded Java programs well? To be accurate such a thing would have to have some info about the particular processor arch you are running on.
15:14lancepantzandyfingerhut: do you use jmx?
15:15lancepantzi don't know if you can get that level of detail out of it, but its always had what i needed
15:15bobo_visualvm can tell you alot, not sure if its enough
15:15andyfingerhutI believe I used jmx briefly, but at the time wasn't looking for that kind of info out of it.
15:16lancepantzjconsole has all sorts of stuff i could never make sense of as well
15:17bobo_visualvm is jconsole on steroids
15:17lancepantzhmm,
15:17lancepantzi'll have to check it out
15:19LauJensenbobo_: IIRC jconsole and jvisualvm complement each other. jconsole had more memory info last time I checked
15:19bobo_i was at a jrockit talk last night, they claimed their stuff can do alot
15:19LauJensenI dont think they were wrong :)
15:19bobo_cant remember what it was called, jrockit console or something
15:21bobo_and jconsole might have more memory info, was probably a year since i used any of them
15:22andyfingerhutThanks for the pointers: jmx, jconsole, visualvm (maybe a superset of jconsole, maybe not), jrockit console. I'll start by Googling through their docs for keywords first.
15:23bobo_visualvm and jconsole is a part of jdk, so you probably have them installed already
15:24andyfingerhutI've found it challenging in some cases to determine why some multi-threaded programs that are embarrassingly parallel (i.e. no interaction at all between the threads in terms of message passing, locking, or anything like that) do not achieve a speedup equal to the number of cores.
15:25bobo_they showed how to find exactly that at the presentation i was at yeasterday :-)
15:25chouserI've used yourkit, but not nearly to the extent of its abilities.
15:25andyfingerhutIf the cores share a cache, that seems like a possible explanation, but I'd like to figure out how to verify that guess with data.
15:26bobo_ive seen alot of love been given to yourkit
15:29andyfingerhutbobo_ Is there a publically-available version of the presentation you attended yesterday? Or was it a private sales demo or something like that?
15:31bobo_i might have misunderstood what you wanted. but anyway, it was at a user group. but dont know if slides are anywhere.
15:31andyfingerhutDo you have a name/email/other contact info for the presenter?
15:32bobo_they will give it at javaone next week atleast
15:32bobo_they are most likley willing to show you more if you are a company with money :-)
15:33bobo_was the authors of: http://www.amazon.co.uk/Oracle-JRockit-Definitive-Marcus-Hirt/dp/1847198066/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1284579092&amp;sr=8-1
15:34andyfingerhutUnderstood that being a company with money can get you good tech support and help. I've been there :) But right now I'm looking at what I can do for free. Not looking for handouts, but willing to take advantage of free trials if available.
15:34bobo_http://www.oracle.com/technetwork/middleware/jrockit/downloads/index.html
15:34bobo_seem to be download links
15:34andyfingerhutbobo_ Thanks much.
15:35bobo_it probably requires you to use jrockit vm aswell. no clue about that
15:52hiredmanis there nothing in contrib that does bytes->hex string and hex string -> bytes?
15:53ordnungswidrigbytes in an array?
15:53hiredmanright
15:54ordnungswidrig(map Integer/toHexString array)
15:55hiredmanwell, I have functions that do both
15:57ordnungswidrigwould be a nice add-on for contrib.
15:57hiredmanright
15:58hiredmanbut in their own namespace? or an existing one?
15:59ordnungswidrigwould you mind to address the general case of radix conversion?
16:00hiredmanyes
16:00hiredman(as in no)
16:01ordnungswidrigonly hex?
16:02hiredmanthis algorithm is more about speed (makes use of a lookup table) than generality
16:06jcromartie(map (partial format "%02x") bytes)
16:06ordnungswidrighiredman: then I'd expect it somewhere in a crypto packages next to message digests and so on :)
16:07jcromartieyes, that's where I always use it
16:07jcromartie,(map (partial format "%02x") (.getBytes "Hello, World!"))
16:07clojurebot("48" "65" "6c" "6c" "6f" "2c" "20" "57" "6f" "72" "6c" "64" "21")
16:08hiredmanjcromartie: I haven't done measurements, but I think just about anything would outperform format
16:09jcromartieI'm usually only converting one byte array at a time
16:10hiredmanwould you be interested in doing some comparisions of the format method versus my code?
16:10jcromartiesure
16:10jcromartiemine is "fast enough" :)
16:11hiredmanhttp://gist.github.com/581363
16:13jcromartieI'd cheat
16:13jcromartiememoize format
16:14ordnungswidrighiredman: holy crap, where does one need such fast byte->hex methods?
16:15hiredmanordnungswidrig: *shrug*
16:15hiredmanthe code we write today is the building blocks of the code we write tomorrow
16:15ordnungswidrigI mean, when things must be fast, who would use hex-digit encodings?
16:17hiredmanI ended up with this while thinking about a process that involved taking uuids (keys) stored as strings, getting the numeric value and using a mod to partition the keys
16:21ordnungswidrigsharding?
16:23hiredmansimilar
16:23arkhfwiw, I made a small predicate that tests to see if a string matches a private IP address in the ranges defined by RFC 1918 - still very much learning clojure and/so criticisms welcome: http://gist.github.com/581391
16:26ordnungswidrigarkh: either use regex groups and drop the split or make a split and drop the regex :)
16:28arkhordnungswidrig: that's a good idea; I'd probably opt to go with groups. Thanks
16:32jkkramerarkh: (if (every? true? (map #(octet-range %) [b c d])) true) can be just (every? octet-range [b c d])
16:32raekarkh: if-let + destructuring + re-find + groups is my favourite approach
16:33raek(small detail: predicates (functions that return booleans) are usually named with an ending questionmark)
16:34grignaakright and can drop the ifs around the ands
16:35ordnungswidrigI gisted a comment
16:36arkhjkkramer: I'm surprised I missed that. Like I'm trying to win a verbosity contest o.0
16:36raek(if-let [[_ a b c d] (re-find #"^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$" ip)] ...)
16:36sdeobald.
16:36sdeobaldRaynes: Hey, sorry to bother you, but do you have any documentation on running tryclojure?
16:37grignaakalso gisted a comment
16:37arkhraek:, grignaak: thank you
16:38grignaakarkh: fixed formatting on comment (was thinking pastie, not gist)
16:41ordnungswidrigI gisted again, now with destructuring: (if-let [[a b c d :as qs] (map #(Byte/decode %) (clojure.string/split ip #"\."))] ...
16:41arkhI think my strictly imperative language background is evident in my code : (
16:42arkhall these suggestions rock though : )
16:43ordnungswidrigarkh: you will get comfortable with functional style. After that you'd better hope then not to have to use an imperative language again. The other way is harder.
16:44chouserit's not that it's hard to write imperative code after you know how to do it functionally, it's just hard to keep your lunch down while you're doing it.
16:45ordnungswidrigchouser: exactly
16:46ordnungswidrigI've "annoyed" team members by using a Maybe-Monad type in a java project. But it safed by a lot of NPEs at runtime.
16:49grignaakordnungswidrig: me too, mine was called MaybeSo and MaybeNot
16:50ordnungswidrigif java had function types or sth like closures it would have been prettier. the incomplete type system doesn't make it better as an addition.
16:50bobo_hm, how did thoose monads look? and how did you use them? i dont know much about monads, but dont think ive seen any in java?
16:52chouserI don't see monads here, but this may give you a sense of what general functional programming looks like in a language not designed to support it: http://functionaljava.org/
16:53ordnungswidrigbobo_: I used them as a NPE safe alternative to "null". Maybe.just(value).map(new Function<String, Integer>{){Integer apply(String s) {return s.length();}}).map(new Function<Integer, Integer>(){Integer apply(Integer v) {return v*v;}})
16:53bobo_dick wall of javaposse fame has a talk on parleys on functional java aswell...
16:53bobo_ordnungswidrig: so pretty much like Some in scala? but with the horrible syntax of java?
16:54ordnungswidrigbobo_: yes, I borrowed maybe from haskell, in scala it is Some
16:54bobo_ok, thanks, much clearer to mee!
16:55ordnungswidrigthe syntax is not that worse, IntelliJ reduces the noise for me. Missing type inference and type erasure and lack of higher order types is what me bugs in practice.
17:17jjidoso I added promise and send-off to my merge-sort algorithm, it sorts fine but the (agent nil) must be still running because it never terminates...
17:18ohpauleezjjido: did you shutdown the agents?
17:18jjidoohpauleez: the agents just deliver a value
17:18ohpauleezalso, did you try deferencing futures as a possible solution too?
17:19ohpauleezat the very end, you need to: (shutdown-agents)
17:20jjidocode: http://pastebin.ca/1941654
17:20jjidothanks ohpauleez
17:21ohpauleezyou shouldn't have to pass off the futures to agents
17:23ohpauleezie: you can use agents, (await) on the agents, and then merge their results. Or use futures and merge @your-future, which will block until the future is done
17:23ohpauleezso you can continue to use promises, but in this case, you may not need to
17:24ohpauleezthat said, the code there should work (essentially you're running a thread via another thread), but (shutdown-agents) should fix your agent
17:24ohpauleeznicely done jjido this is a good example
17:24jcromartiehiredman: (def byte-str-chunk (memoize (fn [b] (format "%02x" b))))
17:24jcromartiehiredman: (defn byte-str [bytes] (apply str (map byte-str-chunk bytes)))
17:24jcromartieshould be pretty fast
17:25ohpauleezIf you want to keep exploring, you should be able to create a version that uses pmap, mapping the merge to partitions of the entire list, then you can apply the the final merge to the result
17:26ohpauleez(apply merge-sort-lists (pmap merge sort (partition my-data)))
17:27ohpauleezrather: (apply merge-sorted-lists-rec (pmap merge-sort-rec (partition 5 my-data)))
17:28arkhnew gist is up for 'is-rfc1918?'. ordnungswidrig's version is epic: http://gist.github.com/581391
17:29raekminor detail: when there is no false branch in an 'if', it can be marked by using 'when' instead
17:30chousers/can/should/
17:30chouser:-)
17:30raekalso, I misread the indentation
17:30raekthe 'and' and the 'or' are not indented the same
17:31arkhgood call on the if/when; the or is in the and, though
17:32jjidoohpauleez: I don't understand what you suggest. What do you mean "you're running a thread via another thread"
17:33ohpauleeza future is a separate thread, and an agent is a separate thread. So when you're sending the future to an agent to gather the results, you're using two threads. Unless I'm making a mistake (which may be true)
17:35grignaak_awayis future different in clojure and java? in java a future is just a _promise_ of a return value at some later date.
17:36grignaak_awayalthough typically returned by a executor, it need not be. it could be a thunk!
17:36ohpauleez,(doc future)
17:36clojurebot"([& body]); Takes a body of expressions and yields a future object that will invoke the body in another thread, and will cache the result and return it on all subsequent calls to deref/@. If the computation has not yet finished, calls to deref/@ will block."
17:36jjidoI don't need explicit agents then?
17:36arkhraek: is that indentation ok?
17:37ohpauleezgrignaak: in clojure, that's just called a promise
17:37ohpauleez,(doc promise)
17:37clojurebot"([]); Alpha - subject to change. Returns a promise object that can be read with deref/@, and set, once only, with deliver. Calls to deref/@ prior to delivery will block. All subsequent derefs will return the same delivered value without blocking."
17:37ohpauleezjjido: right, you don't need the agents
17:41ohpauleezbased on implementation, the promises are optional too
17:42hiredmanno
17:42hiredmanclojure futures are java Futures
17:43ohpauleezsee, I told you I might be wrong with some of this :)
17:45raekarkh: let me check...
17:45raekthe or is now correct
17:46arkhraek: thank you
17:46raekbut the equality sign on the row below should be aligned with the one on the or-line
17:46raek(or (= ...)
17:46raek (= ...))
17:47ohpauleezjjido: Things working out ok?
17:47arkhraek: yes and done : )
17:48raekemacs (and other editors, I hope) can do this automatically
17:48raekin emacs you can simply select the text and press tab
17:49jjidoohpauleez: look http://pastebin.ca/1941677
17:49jjidocan't figure what is a good parallel cutoff
17:50arkhusing vim right now : / I'd probably use emacs now that I know people re-map their keyboard to swap caps lock and ctrl (or just make caps lock a third ctrl)
17:50arkhthat's a recipe for carpal tunnel otherwise
17:50ohpauleezjjido: looks awesome to me. The cutoff point is usually your nonfunctional requirement (when you get it fast enough)
17:51ohpauleezyou could add (partition) in there
17:51ohpauleezbased on the size of the list
17:51ohpauleezvector*
17:51jjido,(doc partition)
17:51ohpauleezohhh, nvm, I see what you're doing
17:51clojurebot"([n coll] [n step coll] [n step pad coll]); Returns a lazy sequence of lists of n items each, at offsets step apart. If step is not supplied, defaults to n, i.e. the partitions do not overlap. If a pad collection is supplied, use its elements as necessary to complete last partition upto n items. In case there are not enough padding elements, return a partition with less than n items."
17:52jjidohow do I repeat a function 10 times? For better time measurement
17:53amalloy,(dotimes [_ 10] (* 2 1))
17:53clojurebotnil
17:56lpetitI'm currently annoying my whole team (ok, that's just one person :-) ) by having written some "way" to manipulate classes in an immutable/editable way. Defined some kind of INonEditable / IEditable pair of interfaces. All my domain model classes implement INonEditable, and have peers which implement IEditable. INonEditable keeps a pointer to the "reference" IEditable, and is created by...
17:56lpetit...calling createEditable() on the IEditable interface (thus allows polymorphism in deep object graphs). Of course there's no real O(anything) / efficient structure sharing, but it does the trick ! It also allowed to have some nice polymorphic reset() createNonEditable() isDirty() methods on IEditable interface :-)
17:57jjidogoes faster on my machine with less parallelism (ie. cutoff value higher)
17:58ohpauleezjjido: you want 2 * number of cores
17:58ohpauleezusually
17:58ohpauleezwow... let me rephrase that
17:58jjidoisn't that automatic?
17:59ohpauleez# of threads at any given time shouldn't exceed 2 * # of cores. And your computation time has to be longer than thread startup time (or acquisition from pool) at your smallest piece
17:59ohpauleezas two general rules of thumb
18:00ohpauleezjjido: how big is your dataset?
18:01jjidoohpauleez: I just have 200 values. I think my machine likes 100 elements partition
18:01lpetit"# of threads at any given time shouldn't exceed 2 * # of cores" : is this empirical ? explainable ? If empirical, what are the implicit assumptions on the "context" ?
18:02lpetitohpauleez: ^^^
18:02ohpauleezjjido: pass it something like (range 1000 0 -1)
18:04ohpauleezlpetit: let me dig up a paper for you. You can generate this empirically. It was one of the first labs I had to do in a concurrent class using MPI
18:04ohpauleezI believe the ideal number of long running threads is the number of cores available
18:05ohpauleezthe *2 is used for shorter running threads to prime the thread for execution while a running thread finishes up
18:06lpetitohpauleez: ok, but doing experiments generally comes with experiment context, so that people know when they are in the same experimental conditions and if the next result have any chance to be predicted as being the same, no ?
18:06ohpauleezno, that's correct
18:06ohpauleezie: if there's io latency
18:07ohpauleezand so on
18:07lpetitohpauleez: ok, so it's empirical, I guess tonight I'm too tired to be able to remind anything else but that, thx :)à
18:07lpetit:)
18:07ohpauleez:)
18:09ohpauleezthat's a good thing to motivate
18:09lpetitIs it true to say that most (if not all) lein commands are generally short of additional command line argument (and that generally the "configuration part" of the command belongs to project.clj) ?
18:10ohpauleezthat is true
18:10ohpauleezI would even say all, with the exception being dependencies that add commands to lein
18:10ohpauleezlike nailgun for example
18:12lpetitso the simplest GUI for lein (given that we're already in the context of some Eclipse/lein project) is a menu entry somewhere, with one submenu entry for each lein task, without additional needed input from the user
18:12lpetit?
18:13hiredmanhard to say
18:13hiredmanlein test can take the namespace of tests to run as an argument, which is very useful
18:14ohpauleezand lein interactive would need a shell-like window. lein compile can take namespace args too
18:15ohpauleezlpetit: I would look at similar projects, like how eclipse handles make, ant, maven (I'm not familiar eclipse)
18:16lpetitanother option: would it be safe to eagerly 'require the tasks namespaces, just for then being able to dynamically inspect the task's signature, and dynamically inferring from it whether it has args or not, and if yes, dynamically create an appropriate Form for the user to type arg values ?
18:17ohpauleezCould you have a settings panel somewhere, and then use the menu+hot key approach?
18:17lpetitohpauleez: yes, but sometimes those things are overly complex for the simples (and more often used) use cases. But indeed I'll look at them, though more at maven's ones than ant's ones (ant being so general and low level, its GUIs tend to be very generic and *heavy*)
18:17ohpauleezgood point
18:18technomancylpetit: there are already fns in leiningen.core that can inspect a task and tell if it needs a project arg or not
18:19lpetitof course, there would be menu + hot key. I also guess that once the user has entered values for a task with arguments, those values could be already filled the next time. And an alternate hot key approach for automatically using the last values without going through the popup
18:19technomancylpetit: in fact, leiningen.core/apply-task might be what you're looking for
18:19lpetittechnomancy: my hero !
18:19arohnera little bit off topic question, but I'm calling java code from clojure, and the java code throws an exception, that doesn't contain file names or line numbers. What could cause that? IIRC, this code was compiled "normally" using ant
18:19lpetittechnomancy: and what about auto-discovery ?
18:20technomancylpetit: leiningen.help/tasks will list them
18:20ohpauleezarohner: it sounds like the java code wasn't compiled with debug info. That's the only thing I know that can do that
18:20ohpauleezhappens with you pass optimization flags sometimes
18:20hiredmanarohner: I don't believe exceptions contain that information, you have to look at the stacktrace
18:21arohnerhiredman: java code threw an exception, I caught it in clojure and did exception.printStackTrace()
18:21lpetittechnomancy: even those who are spread over plugins as dependencies, scripts directly put by the user in his project's src/leiningen package, and those placed in %LEIN_HOME%/plugins ?
18:22technomancylpetit: should catch them all; it walks the classpath
18:22ohpauleezarohner: what is the ant command and options used to compile the code?
18:23jjidoohpauleez: I used a dataset with 1000 ~ random numbers
18:23arohnerohpauleez: <javac srcdir="." destdir="${classes.dir}" classpathref="classpath" />
18:23ohpauleezarohner: totally bizarro. I've got nothing
18:23lpetittechnomancy: ok, by opening the jars, etc. ? BTW, does it also work if plugins as jars do not contain the .cljs, but just the AOT compiled version of the plugin ?
18:23ohpauleezjjido: alright! How'd it run?
18:24jjidosame, I need to use half the total size as cutoff
18:24technomancylpetit: it has to have the source
18:24technomancynever heard of an AOT'd lein plugin
18:25technomancysource in jars is fine
18:26lpetittechnomancy: of course, ability to guess namespaces from AOT compiled classes only requires to depend upon an implementation detail of AOT.
18:26arohnerohpauleez: the ant docs say javac takes an option of debug=#{true,false}, and defaults to false. Rebuilding the java now...
18:26lpetittechnomancy: fine by me.
18:27ohpauleezarohner: ahh, keep me posted, I'd be interested to see what happens here. I've never run into this before
18:27lpetittechnomancy: I just wanted to know the current capabilities. I imagine that leiningen.help/tasks has to load (err require) the plugin in the VM to easily get the docstring ?
18:28lpetits/the docstring/its docstring/
18:28sexpbot<lpetit> technomancy: I just wanted to know the current capabilities. I imagine that leiningen.help/tasks has to load (err require) the plugin in the VM to easily get its docstring ?
18:29technomancylpetit: yeah, correct. the help task is pretty short; less than 40 lines; should be easy to understand how it works.
18:30lpetittechnomancy: yep, sorry, should ask the source first. Difficult to resist the temptation to directly ask the master of the source, though :)
18:32lpetitOk, so it seems like everything is already there to quickly get something interesting, and pretty much automagic, cool !
18:32lpetitmust leave, cu and thank you all
18:38_ViCan Clojure run on any alternative small JVMs?
18:38ohpauleez_Vi: such as...? The Blackberry VM?
18:39_ViTried "gij-4.4" as alternative JVM, it failed.
18:39hiredmanyeah, no no
18:40ohpauleezahh, really depends on the subset of instructions and lib support. But I would say most likely not
18:40_ViSomething like "java.lang.VerifyError: verification failed at PC 214 in ... incompatible type on stack"
18:40hiredmandon't expect anything to work on the gnu java stuff
18:40hiredmangcj, gij, etc
18:40hiredmannot a real jvm
18:41_ViWhat else things it tested on apart from official Sun^WOracle JVM?
18:41hiredmanblackberry uses j2me which is a striped down version of java 1.4 which nothing runs on
18:41hiredmanalmost no phones have a decent jvm
18:42_Vi(Trying with some "jamvm-1.5.4" which is found by "Tiny JVM" request. Expecting a fail.)
18:42hiredmanI've heard of clojure running on jam
18:42hiredmanbut I think jam's gc is not so hot
18:45_Vihiredman, Trying that.
19:06_Vibash$ ( ulimit -v 70000; jamvm -Xmx10m -jar clojure.jar) # works
19:08hiredmanwhats -v?
19:09_ViLimit virtual memory to 70000 KB for jamvm.
19:09amalloyhey technomancy, who's in charge of slime/swank?
19:10_ViUsual java requires over 200 MB.
19:12tomojgcj worked fine for me doing relatively mundane things with clojure
19:12tomojI didn't even notice I had switched to gcj
19:38_ViBTW I can checkpoint a jamvm process with cryopid, but can't do it with usual java. (However it does not increase starting speed of clojure anyway)
19:55technomancyamalloy: I'm in charge of swank-clojure, sorta. buncha CL guys are in charge of slime.
19:56amalloytechnomancy: i can reliably crash emacs with swank-clojure, but can't easily reduce the problem to a few lines
19:58technomancyamalloy: must be a combination of Emacs and Slime bugs
19:58technomancynever seen Emacs itself crash though; that's amazing
19:58amalloyi thought so too! it doesn't actually crash as in dump core, but it refuses to respond to anything or redraw the window or whatever
20:00technomancyoh, just a hang then. it could just be a slime bug then.
20:00amalloybut ugh, i seem to have fixed the problem without keeping around a copy of the clj file causing the problem
20:01amalloyworst bug report ever
20:01technomancyit's OK, I'm not really in a position to fix elisp bugs anyway.
20:26fbru02what is a good way of composing lambda fns ??
20:29woobyfbru02: comp?
20:30fbru02wooby: i have yet try it out but the thing is i have fn1(z) and fn2(z) and i want fn3(z) = fn1(z) + fn2(z) what i mean is that i want them both to close over a particuar value
20:33amalloy,(reduce + ((juxt inc dec) 10))
20:33clojurebot20
20:34amalloyfbru02: (juxt inc dec) creates a new function that calls inc and dec on its arguments, and returns a list of the results
20:34amalloythen i call that function on 10, yielding [11 9], and reduce it with + to get, effectively (+ (inc 10) (dec 10)), which sounds like what you want
20:39fbru02amalloy: wooby : thanks !!!
20:39amalloya less trivial example, to add together 2n and n/2:
20:39amalloy,(reduce + ((juxt #(* % 2) #(/ % 2)) 10))
20:39clojurebot25
21:27_Vi(def q (ref 0)), (def f (future (loop [] (dosync (ref-set q (+ 1 @q))) (recur)))), (dosync (for [x (range 1000)] @q))
21:28_ViWhy it returns list where I see that q is updated? Isn't it in a transaction created by "dosync"?
21:52Scriptorwhat's the best solution for when you need to go through multiple lists at the same time?
21:52Scriptornot concurrently, say when you need to match each item in two lists
21:55hiredman,(map vector (range 10 20) (range 30 40))
21:55clojurebot([10 30] [11 31] [12 32] [13 33] [14 34] [15 35] [16 36] [17 37] [18 38] [19 39])
21:58Scriptorah, so if map's given multiple lists, it does what I need?
21:59Raynesmap applies the function to one element in each sequence that is passed to it until any one of the sequences are exhausted.
22:01Scriptorsounds good, do reduce and filter act in the same way?
22:08RaynesScriptor: Nope.