#clojure logs

2011-03-13

01:18waxrose>.>
01:19scottjI'm not very good at reading ascii art
01:21waxrosewhy's that?
01:23scottjlack of imagination I suppose
01:24waxroseWhat are you up to tonight?
01:25scottjwas reading programming pearls first chapter (reduce (fn [bitmap n] (aset bitmap (dec n) 1) bitmap) (int-array 27000 0) file) then I got distracted by grooveshark
01:26waxroseI've never had a chance to read that one.
01:26waxroseBetween class and doing every thing else.
01:30scottjreading's overrated
01:32waxrosehow so?
01:33waxroseI find reading the only way to progress outside of pure experience.
01:34scottjI find reading uninspired by experience produces poor comprehension and short retention
01:35scottjI'm skeptical of the value of reading not motivated by problem solving
01:39waxrosemmhmm
01:40waxroseBut then again, not every one reacts to stimulus the same way.
03:44hiredman~search for rhickey
08:42pyrhi
09:02nawkgud morning
09:24raekCompilerException java.lang.NoSuchMethodError: clojure.lang.RestFn.<init>(I)V (autodoc.clj:1)
09:24raekgrrr
13:08zoldar,(do (defn pad [coll n x] (let [cnt (- n (count coll))] (if (pos? cnt) (concat coll (take cnt (repeat x))) coll))) (pad [1 2 3] 5 nil))
13:08clojurebotDENIED
13:08zoldarhmm, anyway, isn't such function already somewhere in core or contrib ?
13:10david`https://gist.github.com/868264
13:10david`:(
13:12nickik,((fn [coll n x] (let [cnt (- n (count coll))] (if (pos? cnt) (concat coll (take cnt (repeat x))) coll))) [1 2 3] 5 nil)
13:12clojurebot(1 2 3 nil nil)
13:13MayDaniel,((fn [coll n x] (take n (concat coll (repeat x)))) [1 2 3] 5 nil)
13:13clojurebot(1 2 3 nil nil)
13:13zoldarah, nice
13:14zoldardavid`, your (ns ..) form seems wrong to me. "use" instead of ":require" would probably work here
13:15nickiki edit de function in the irc. very lucky that i got all the parans right the first time.
13:16david`zoldar: thx!
13:16TimMczoldar: ##(take 5 (concat [1 2 3] (repeat nil)))
13:16sexpbot⟹ (1 2 3 nil nil)
13:18raekdavid`: note that since 1.2 there is also clojure.string: (ns foo (:require [clojure.string :as str])) (str/replace ...)
13:18zoldarthat just shows how my clojure-fu still sucks...
13:19raekthough, some of the functions did not "make it" there
13:19raekor was renamed, so you'd have to read through the docs to see what's changed
13:19raekhttp://clojuredocs.org/clojure_core/clojure.string
13:29joodie...
14:00avdiI'm learning about metadata righ now, but "^" doesn't seem to be working. Has this changed?
14:01joodieShould work. Which version of clojure are you using?
14:02spewn&(let [x ^{:a 1 :b 2} [1 2 3]] (meta x))
14:02sexpbot⟹ nil
14:02avdi1.2
14:02avdihmmm
14:02spewnStrange. That works for me with 1.2.0. What's wrong with sexpbot?
14:03avdiThe Halloway book shows ^foo returning metadata for ^foo
14:03joodieworks for me too @ 1.2
14:04raekavdi: this has indeed changed. since clojure 1.2, you have to use (meta ...) to extract the metadata
14:05avdiraek: gotcha, that explains it.
14:05avdiraek: thanks
14:05raekavdi: and ^ is the new reader syntax for adding metadta (#^ still works, though, but should be avoided for future compability)
14:05joodieand since 1.2 you can use ^{ ... } to set metadata
14:06joodieIf you want the details of these sort of short-hands, look at the reader docs: http://clojure.org/reader
14:06raekalso, with-meta is the function you'd use in you program (^ only adds metadata to the *code literal*)
14:07avdiraek: I'm going to have to think about that last statement for a bit
14:10raekif the evaluator sees a collection literal with metadata on it, it will evaluate the contents and make a new data structure of the same kind. the metadata map will also be evaluated. then, the evaled metadata will be attached to the new data structure
14:10raek,(let [x 1] (meta ^{:foo x} [1 x 3]))
14:10clojurebot{:foo 1}
14:11raekbut
14:11raek,(let [x 1] (meta ^{:foo x} (list 1 x 3)))
14:11clojurebotnil
14:12raek(list ...) is not a data literal, so the metadata on the code won't be attached to the result
14:12raek,(let [x 1] (meta (with-meta (list 1 x 3) {:foo x})))
14:12clojurebot{:foo 1}
14:13raek,(let [x 1] (meta (with-meta [1 x 3] {:foo x})))
14:13clojurebot{:foo 1}
14:14avdiIn the first (list) example, what exactly is the metadata attached to?
14:14avdithe list form?
14:15joodiecould be
14:15raekit's attached to the list whose elements are the symbol "list", the number 1, the symbol "x" adn the number 2
14:15raek*3
14:15avdiraek: gotcha. Makes sense.
14:16raekthat is, the thing that is sent to the compiler
14:17raekso, symbols and list have special behaviour for metadata, just as they have special behaviour for evaluation in general
15:42angermanhow do i get c.c.string/join to not return LazySeq@… ?
15:43angermanI hoped, doall would do… but doesn.
15:43fliebelangerman: apply str?
15:44angermanfliebel: ?
15:44amalloyangerman: ##(str (range))
15:45sexpbotExecution Timed Out!
15:45amalloyangerman: ##(str (range 2))
15:45sexpbot⟹ "clojure.lang.LazySeq@3c2"
15:45fliebel&(apply str (reng 5))
15:45sexpbotjava.lang.Exception: Unable to resolve symbol: reng in this context
15:45amalloy&(apply str (range 2))
15:45sexpbot⟹ "01"
15:45fliebel&(apply str (range 5))
15:45sexpbot⟹ "01234"
15:45fliebelright, finally
15:45amalloystring/join is the same, iirc - it wants multiple params, not a single coll
15:46amalloyso if you have a coll you should be able to apply it
15:46raekangerman: you can use pr-str to turn clojure data structures into strings
15:46raek*a string
15:46amalloy,(pr-str (promise))
15:46clojurebotExecution Timed Out
15:46amalloyraek: not entirely true :P ^
15:47fliebel&(pr-str [1 2 3])
15:47sexpbot⟹ "[1 2 3]"
15:47raekI don't know if I would call a promise a data structure
15:48raek,((juxt str pr-str) (range 5))
15:48clojurebot["clojure.lang.LazySeq@1b554e1" "(0 1 2 3 4)"]
15:48angermanwhat for is clojure.string/join?
15:48angermanso I tried to write code according to clojure.string/join whil eusing c.c.string/join. ouch.
15:49raekclojure.string/join takes a seq of strings as its input (if the elements are not strings they will probably be converted with 'str')
15:50raekso if you want to turn the elements into strings in some other way (e.g. pr-str) you should (map pr-str ...) them first
15:50angermanno. I actually wanted to use "join" because I wanted the seperator.
15:51raekyes, but the stuff you want to join with the separator must be a seq of strings
15:52angermanreak, yes, that's what I get from (format…)
15:52amalloy&(use '[clojure.string :only [join]])
15:52sexpbot⟹ nil
15:52amalloy&(join "," (range 5))
15:52sexpbot⟹ "0,1,2,3,4"
15:52angermanthe problem was that i tried (join coll sep) instead of (join sep coll)
15:52raekformat will also call str on its arguments
15:52raekah
15:53angerman&(doc clojure.string/join)
15:53sexpbot⟹ "([coll] [separator [x & more]]); Returns a string of all elements in coll, separated by an optional separator. Like Perl's join."
15:53angerman&(doc clojure.contrib.string/join)
15:53sexpbot⟹ "([separator coll]); Returns a string of all elements in coll, separated by separator. Like Perl's join."
15:53angermanthat is plain weird!
15:53amalloyangerman: you're just misreading the arglists
15:53amalloyboth of them take sep coll
15:54angermanamalloy: ahh, multi arity
15:54angermandang.
15:54amalloyindeed
16:39Userhey
16:39jaleyhi guys - can anyone offer me some best-practice advice wrt wrapping up java APIs and mocking?
16:39Useranyone familiar with Enlive?
16:41jaleyI'm using java api generated by apache axis to talk to some servers with soap. I think for test purposes I'd like to mock out the real function calls with c.c.mock, but clearly I can't use binding to mock out a java method call. Is this an acceptable time to break idioms and wrap the java API with clojure function calls? Or would another approach altogether be better maybe?
16:43Userwhat does the soap client look like
16:43UserI generally extend the soap client with a class of my own
16:44jaley@User ; (.getEvents *service*)
16:44jaleywhere service is a java object, code generated by axis
16:47anthonyI'm working with a datastore, which has an int field representing an enum. In Clojure, I need to translate these ints to/from keywords (with hard-coded associations). What's the cleanest way to do this? I've had a map like asc = {0 :start 1 :inprogress 2 :end}, which allows me to do (asc 1) to get a value from a key, but how about the other way around (given a value, find the key)?
16:48Usermake a java class with public static final variables then refer to it as class/CONSTANT
16:48User*trollface*
16:49amalloy&(clojure.walk/walk reverse hash-map {0 :start 1 :inprogress 2 :end})
16:49sexpbotjava.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.Map$Entry
16:49amalloybooo
16:49raekI would use two maps. maybe initialize them from the same data
16:49amalloy&(clojure.walk/walk (comp vec reverse) hash-map {0 :start 1 :inprogress 2 :end})
16:49sexpbotjava.lang.IllegalArgumentException: No value supplied for key: {:start 0, :inprogress 1, :end 2}
16:49anthonyIs there an easy way to "flip" a map? Or should I store the data a different way, then create maps out of it (like an even-length vector?)?
16:50amalloyugh, whatever
16:50amalloyanthony: there are a number of ways to flip a map. the one that requires the least thinking for me is ##(into {} (for [[k v] {0 :start 1 :inprogress 2 :end}] [v k]))
16:50sexpbot⟹ {:start 0, :inprogress 1, :end 2}
16:51anthonyamalloy: Awesome. That works perfectly. Thanks a ton.
16:51amalloyi was trying to use walk because it's cleaner, but i was doing it wrong :P
16:51amalloy&(clojure.walk/walk (comp vec reverse) identity {0 :start 1 :inprogress 2 :end})
16:51sexpbot⟹ {:start 0, :inprogress 1, :end 2}
16:51phenom_anyone know how to fix indentation in amcs when declaring deftypes with multiple protocols ?
16:51amalloythere
16:51sattvik,(let [m {0 :a 1 :b}] (zipmap (vals m) (keys m)))
16:51anthonyEven better.
16:51clojurebot{:b 1, :a 0}
16:51amalloysattvik: ##(apply zipmap ((juxt vals keys) {0 :a 1 :b}))
16:51sexpbot⟹ {:b 1, :a 0}
16:52raek,(into {} (map (juxt val key) {:a 1, :b 2}))
16:52clojurebot{1 :a, 2 :b}
16:52jaleyoh my, so many ways to skin that cat?
16:52amalloyah, score one for raek, i think
16:52anthonyhaha dangit, now I have too many options to pick from. :-)
16:52raekphenom_: in emasc?
16:52raek*emacs
16:52anthonyI like the juxt one, though. Thanks for all the help, amalloy and raek
16:54UserI came upon the following code when looking at enlive:
16:54User (transformation [:.text] (content item) {[:input][:br]} (clone-for [x choices]
16:54phenom_raek: yea
16:55Userwhat kind of selector is {[:input][:br]}
16:55UserI thought selector had to be a vector
16:55raekphenom_: you can use M-x customize-variable, clojure-mode-use-backtracking-indent
16:55amalloyUser: that doesn't look like a selector to me
16:55phenom_raek: http://pastie.org/1667951
16:55jaley@User from memory, can a selector not also be a function?
16:56brehautUser: enlive uses a map as a range selector for some things
16:56raekphenom_: yes, enabling backtracking indent makes that indent correctly
16:57phenom_raek: perfect, thnx
16:57amalloymaps...as range selectors? gross
16:58UserI have no idea what that is
16:58Userhttp://groups.google.com/group/enlive-clj/browse_thread/thread/45e0e64f51ec6bdb?pli=1
16:58Userlook at cgrand's answer
16:58Userfirst code snippet
16:59brehautUser: {:input :br} selects (inclusively) everything between an input and br
16:59Useroh
16:59Userintredasting
17:01brehautamalloy: why is maps as ranges bad?
17:03amalloybrehaut: it clashes conceptually with the notion of key=>value; he's just using it to store a pair. if [[:input][:br]] isn't used for anything else i'd like it better
17:03brehauti think it is used
17:04amalloyi imagine so
17:04amalloyotherwise he'd use it here :)
17:04brehautindeed :P
17:07Userwhat's [[:input][:br]] used for ?
17:10brehaut [[#{:ul :ol} :.outline] :> :li] ul.outline > li, ol.outline > li
17:10brehautthats from the readme
17:10brehautunder 'syntax'
17:11brehautroughly parenthisis basicly (which CSS doesnt have)
17:13Userso set is used for OR
17:13Userand vector is and
17:14TimMcamalloy: Yeah, I was cringing when I saw that in his (not= DSL macros) talk
17:14brehautits not and, its grouping
17:14Userit has to match both selectors in the inner vector
17:14brehauts/grouping/parenthsis
17:14sexpbot<brehaut> its not and, its parenthsis
17:14Userdoes it not?
17:15Userwhat the hell is parenthesis
17:15amalloylol
17:15brehautwell yes, but not in an and way
17:15Userparenthesis is a character
17:15brehaut(1 + 2) * 3
17:15brehautparenthsis
17:15UserI read it as such
17:16brehautit makes that subselector atomic to the operators that contain it
17:16TimMcparenthes*e*s
17:17Userok so if I have this selector [:ul :.outline] it will select all elements that are ul tag and outline style
17:17brehautTimMc: sorry
17:17Userbecause I always thought that would select an element with outline style that is a child of ul element
17:18brehautUser: no, it will select all elements with the "outline" class that are inside a ul element
17:18brehautwait, i think you might be right in that case
17:18joshua__Is there a Clojure library out there for converting HTML to Markdown. I've been trying to do it with an XSLT and Saxon, but I've been having a bit of trouble.
17:18brehauthah excuse me for being a complete arse
17:19brehautbut i think you are right that it is actually an and in this case
17:20Userthat's what confused me immensely
17:21Userthe outermost vector is processed differently than any inner vectors
17:21brehautyeah you are right
17:21amalloybrehaut: you forgot to pretend you prefer tea
17:21Useroff to my REPL
17:21Usergot to test this
17:22brehautamalloy: oh crap
17:22brehautUser: good plan
17:25Userhttp://pastebin.com/5AfExvj5
17:25Userlook at this
17:26Userthe difference between [:ul :.content] [:body :.content] and [[:ul :.content]]
17:26Useror lack there-of
17:30brehautTimMc: well done :)
17:30tufflaxI don't like that clojurebot uses notice for that :P
17:31TimMcbrehaut: Thanks!
17:33brehautUser: that does appear surprising
17:34amalloytufflax: what would you prefer?
17:35tufflaxNormal message maybe. The thing is that it makes a sound, which I turned off now, but it's handy to have that sound if someone needs to reach me
17:36TimMcIs it a new feature?
17:38amalloytufflax: that's a weird thing for your client to do
17:38amalloynotices are supposed to be lower-impact than regular messages, not higher
17:38tufflaxoh, is that so :P
17:39tufflaxWHat's supposed to be higher then?
17:39Deranderamalloy: textual makes them show up with a red background and red text
17:41amalloyThe NOTICE message is used similarly to PRIVMSG. The difference between NOTICE and PRIVMSG is that automatic replies must never be sent in response to a NOTICE message.
17:43Raynesamalloy: I'd use notice for that as well assuming we had a similar feature in sexpbot.
17:43amalloyRaynes: github commits?
17:43brehautwhoa, raynes has taken time out from trying android apps to visit irc!?
17:43RaynesGhats
17:44Raynesbrehaut: I'm actually just on my phone.
17:44tufflaxamalloy: I don't think it clear from that that notices are lower-impact than regular messages. But, anyway, it's not a big problem :)
17:45Raynesamalloy: That's a ripoff of someone else's bot. Never occurred to me to use notices for that.
17:45RaynesA more sophisticated ripoff, but a ripoff nonetheless.
17:46RaynesBrb, getting on the desktop.
17:46amalloytufflax: agreed, that in itself is insufficient to show that notices are lower-impact. but i think it does demonstrate that they shouldn't be *higher* impact
17:49tufflaxamalloy: Yeah, perhaps. Thank you for making me aware :)
17:50RaynesBack.
17:51Raynesamalloy: Don't we have a contributor list that isn't on my blog? Like, in the README?
17:51RaynesIf so, we should add brehaut to that. I never intended to edit that blog post every time someone committed to sexpbot.
17:52RaynesI'll check and do that in a moment. Got to get my environment going.
17:56Raynesbrehaut: But yes, Android is awesome. :>
17:56brehautha
18:01nickikWhat does this mean in java
18:01nickikint iterations = 1 << (maxDepth - depth + minDepth);
18:02amalloy<< is left-bit-shift
18:02Userit's a retarded shift trick
18:02UserIt basically says 2^(maxdepth-depth + mindepth)
18:02brehautlooks liek someone is trying to (perhaps naively) optimize multiplication
18:03nickiki doing a benchmark
18:03amalloytbh i can't imagine why you'd want to add max+min depths together, and subtract some other depth
18:03nickikim
18:03Userit might make it faster but unless this is rolling in a loop like crazy
18:03Userit's not worth the obfuscation
18:04raekit's like when people write x >> 1 instead of x / 2
18:04Useryeah
18:04brehautit also makes assumptions about the compiler(s)
18:04nickikhttp://shootout.alioth.debian.org/u64/program.php?test=binarytrees&amp;lang=java&amp;id=2
18:05amalloywow, it's been a while since i saw such unanimous unbridled hate for shift operators
18:05Usernot worth it in this case
18:05brehautamalloy: ha
18:05nickikhow should I writ it in clojure?
18:06Userthe cost of other things in the outer loop is many many many times bigger than the difference between bitshift and multiplication
18:06Raynesbrehaut: I just wrote a contributor section into the sexpbot readme and put you in it. Congratulations in becoming an honorary sexpbot contributor. You win a brand new internet!
18:06brehautRaynes: cheers :)
18:06brehautits trying hard to be the least used contribution too :P
18:07User(bit-shift-left 1 (- maxDepth (+ depth minDepth)))
18:08Raynesbrehaut: It's a sneaky little thing that nobody would ever care about until it actually works for them and then they love it.
18:08brehautthats the plan
18:08amalloyyeah
18:14Userinteresting page nickik
18:14nickikpage?
18:14spewn&(+ 1 2 3
18:14Userclojure is quite slow especially when problem size isn't huge
18:14sexpbot⟹ 6 ; Adjusted to (+ 1 2 3)
18:14spewnI love it!
18:14phenom_anyone have cake working with clojure 1.3 ?
18:14Userthe shootout nickik
18:15phenom_[org.clojure/clojure "1.3.0-master-SNAPSHOT"] as a dependency isn't working for me in project.clj
18:15nickikUser, yeah im doing a project for school and i want to have the binarytree working with 1.3 alpha
18:15Userfor huge huge problem size of 2^20 it's only 3 times slower than java but for 2^12 which is a huge binary tree nonetheless it's like 15 times slower than java
18:16User(most of my programs use lists and vectors of size around 10 and there clojure is around 40 times slower than java)
18:21Userwow for binary trees of size 4096 nodes, clojure is the slowest language
18:21nickikMhh the bitshift does not seam to work with longs
18:22nickikcall to shiftLeft can't be resolved.
18:22nickik(its a reflection warning)
18:23nickikUser, why do you think that is?
18:23Useryeah and that code uses unchecked ops everywhere
18:24Userno idea
18:24Userimmutable data and checked arithmetrics are usually the biggest slowness
18:24Usernotice that lisp does much better
18:25raekboxing is very bad for performance too
18:25Userbecause it allows mutation and it uses imperative programming
18:25Useryes
18:25Userthis code uses (int x) and such a lot though
18:25Userhttp://shootout.alioth.debian.org/u64/benchmark.php?test=binarytrees&amp;lang=clojure
18:26nickikin 1.2 you cant box if you have a function call right?
18:26UserI don't see how it can be improved
18:26nickikher is my take: https://github.com/nickik/IDPA-Programmiersprachen-Benchmarken/blob/master/clojure/src/clojure/binarytrees_me.clj
18:26UserI mean even LUA is faster :D
18:26Userand python :P
18:27raeknickik: you can't pass primitives over function boundaries, yes
18:27raek...in 1.2
18:27Userand erlang
18:27Userand ruby :D
18:28nickikreak, the version i linked is 1.3
18:28Userseems to me that JVM also limits clojure performance in some ways, it just wasn't made for this
18:28nickikthat should speed things up
18:28UserLISP compilers have free hands
18:28nickikthe code for this example is almost one to one translation from java
18:29UserI know
18:29Userit's quite non-idiomatic too
18:30Usernobody actually writes clojure like that imo
18:30nickikdoes not matter its a benchmark
18:31nickikWas a stupid idea to use benchmarking for a school project
18:31nickikits way to hard and does not look impressiv
18:32Userindeed
18:32UserI'm just saying, it's an annoying thing with clojure
18:32nickikshould of just have implemented some parallel code in clojure and java and show how clojure is better
18:32Useryou have to write differently than normal if you don't want some huge performance hits
18:33Userin java I just write normal code and it usually doesn't run much slower than hand optimized
18:33Userwith clojure difference is quite significant
18:34Userwith all those unchecked-add, I think it woudl be easier to just rebind + to unchecked-add :P
18:34nickik 2^(maxdepth-depth + mindepth) should work to right, then i could throw away bit-shift
18:35nickikwhats the function for 2^ in clojure?
18:35Userbit shift is quite a bit faster than power
18:35nickikbut it needs to use reflection
18:35Userclojure generally uses Math/pow from java
18:35Userfor all you power needs
18:36nickiki have to find out whats faster later
18:36Useror (apply * (repeat 2 n))
18:36amalloyclojure.math/expt
18:36Userboth are slot :D
18:36Userslow
18:36clojurebotGabh mo leithscéal?
18:36amalloyUser: i disagree with your claim about map/pow
18:36amalloys/map/Math
18:36sexpbot<amalloy> User: i disagree with your claim about Math/pow
18:37Userwhy
18:37amalloyit only deals with Double, and for example there's clojure.math/expt that handles all of clojure's numeric data types
18:38Useryeah well in any case any implementation does as many multiplications as the exponent is
18:38Userwhile bitshift is like a single add
18:39amalloyUser: half an hour ago you were telling everyone that << wasn't worth the obfuscation
18:39Usergenerally
18:40Userin any case it's unfortunate that default numeric data in clojure is that slow...considering 99% of the time I modify numeric data it's "count++" type of code and the variable is well inside int range
18:41Userthus I rarely get to use the benefits (automatic promotion of type)
18:41brehautUser: really? you increment counters a lot in your clojure code?
18:41amalloyhah, good catch there brehaut
18:41Usernot that much
18:42Userusually when I use recur
18:42Userbut it sure comes up more often than anything else
18:42Userany other numeric manipulation
18:42amalloyUser: i rarely wind up needing to use recur either. just let the lazy seqs flow
18:43amalloyless performant but more reusable
18:43Userand how do you generate these seqs
18:43amalloyand more readable
18:43Userusually there's some variable that changes
18:43brehaut&(apropos "-indexed")
18:43sexpbotjava.lang.Exception: Unable to resolve symbol: apropos in this context
18:43brehaut&(use 'clojure.repl)
18:43sexpbot⟹ nil
18:43amalloymap-indexed
18:43Userin any case it's SLOOOOOW
18:43brehaut&(apropos "-indexed")
18:43sexpbot⟹ (keep-indexed map-indexed)
18:44Userthat just hides inc calls
18:44amalloybut brehaut, those use lazy seqs under the covers. it's so slow!
18:44Userthey still happen and they are still slow
18:44amalloyUser: actually it's using (range), bet you a million dollars. (range hides the incs, of course)
18:44User:D:D:D:D
18:44Useralways comes down to inc :D
18:45tomojdon't bet
18:45Users/inc/inc calls/
18:45sexpbot<User> always comes down to inc calls :D
18:45tomojneither use range in 1.2
18:45amalloytomoj: if i'm wrong i'll just claim by "dollars" i meant something else
18:45tomojok :)
18:45brehauttomoj: they do use primative ints for counters though
18:46brehaut(which is to say: agreeing)
18:46phenom_,(deftype Test [] clojure.lang.IPersistentVector (length [this]))
18:46tomojreally? I dno't see that
18:46clojurebotsandbox.Test
18:46phenom_,(Test.)
18:46clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.AbstractMethodError>
18:46brehaut'size (int (count c))" hmm, maybe just for the size
18:47tomojI see a letfn with lazy-seq that calls itself
18:47tomojin 1.2 I don't see how this could possibly be primitive
18:47brehautthe inner most let
18:47tomojah, right
18:48brehautit would boxed up again though wouldnt it
18:50UserI doubt core functions use primitive ints for anything
18:50Userbecause most of those functions are supposed to work for infinite sequences and stuff like that
18:51Userin any case look at that language shootout page
18:51brehauti see no reason that there could not be a polymorphic implementation that uses primatives till it overflows and then slowints to the rest of infinity
18:52Usereven though clojure beats a lot of languages such as ruby, lua and stuff at binary trees with size of 1 mil, it's the slowest language with small trees size 4000, which is majority of data
18:52UserI ever use
18:52tomojslower than ruby is hard to believe
18:54Userlook at it yourself
18:54dnolenUser: JVM startup time.
18:54tomojI don't mean that I don't believe those are the current results, I mean that those results aren't _right_ :)
18:56dnolenUser: has nothing to do w/ small trees. A warm JVM will be eat Python and Ruby for breakfast.
18:56UserI think jvm startup time doesn't count
18:56Userlook at java stats
18:56Userit beats most languages
18:56Userclojure none
18:56ossarehmorning 'all
18:57ossarehs/'//
18:57sexpbot<ossareh> morning all
18:57dnolenUser: I don't know the details of how those example are run, if they are AOT etc. Doesn't matter, Clojure is not slow on small trees, makes no sense.
18:57tomojsaying "java beats most languages" or "clojure beats none" seems a bit misleading. as if the results give facts about the languages
18:58ossarehclojure beats everything I've ever used in terms of expressiveness.
18:58tomojthat in this example clojure loses to ruby suggests very strongly to me that these results aren't about the language at all
18:59Usersee tomoj you are arguing with no data either
18:59Useragainst what you call flawed data
19:00brehautone sample point is not a basis for an argument either
19:00Userfrom dropdown you can select other samples
19:00joshua__link to what your talking about
19:00joshua__?
19:00Userbut that's beside the point
19:01Userjoshua__: http://shootout.alioth.debian.org/u64/benchmark.php?test=binarytrees&amp;lang=clojure
19:01tomojpresumably running with the larger tree sizes gives larger runtimes
19:01Userit does
19:01tomojI wonder if that is the only way the jvm startup time becomes less dominant, and the only way hotspot is allowed to wake up?
19:02Userno idea
19:02tomojstill, slower than ruby baffles me unless the runtime for that size is very short
19:02Userin any case you can compare java and clojure if you want
19:02Usermy java code is usually 3 - 200 times faster
19:02Usermost often in 10-40 range
19:04Userthis usually comes from ArrayList - clojure vector difference and arithmetics
19:06joshua__http://shootout.alioth.debian.org/u64/performance.php?test=binarytrees&amp;sort=elapsed
19:06joshua__isn't that saying Clojure is ahead, not behind? Or am I missing something?
19:07dnolenUser: not surprising. Writing fast Clojure takes some experience. Clojure generates a lot of classes, even w/ AOT I imagine that adversely affects startup time.
19:08nickikAh it works know with 1.3, know i only have to find out if its going to be fast than 1.2
19:09amalloyjoshua__: you must be reading it wrong
19:09mecmy paredit has quit working. It was working perfectly yesterday, and I havn't changed anything since. Anyone know what might be wrong, or how to find out?
19:10Userjoshua__ that is N=20 --> million elements tree, try N=12 4000 elements tree
19:10tomojmec: elaborate?
19:10Userdnolen: saying that writing fast programs reuqires special knowledge doesn't do it any favors
19:11mectomoj: the commands to move parenthesis around do nothing, and while typing ( produces () deleting the opening parenthesis does not remove the closing one at the repl. In a *.clj file it doesnt appear to work at all
19:12amalloymec: the repl is generally not in paredit mode. mine isn't, anyway
19:12tomojmec: and you still see "Paredit" in the modeline for a clj file?
19:12dnolenUser: eh? that's the case for pretty much every PL I ever used for any non-trivial program.
19:12mectomoj: no, there is a Paredit on the repl line
19:13tomojI'd be surprised if that didn't cause trouble
19:13tomojbut if you don't see it in the modeline for a clj file, it's not on
19:13dnolenUser: in fact, Alioth benchmarks is proof of that.
19:14mectomoj: the lines are still in my .emacs to enable it
19:14tomoja clojure-mode-hook?
19:14brehautdnolen: you can write fast small programs in c without specialist knowledge
19:15amalloyi set my repl to use paredit mode once. it was a disaster, for reasons i don't remember
19:15dnolenbrehaut: non-trivial means moving memory around, then you have start getting clever.
19:15mecit looks like it adds it to anything that is a -mode-hook and specifically after that to slime-repl-mode-hook
19:15brehautdnolen: sure, it gets hard very fast
19:16ldhany compojure folks? i'm trying to set the content-type header in my handler response. I've seen it documented like this, but I get "unsuppored binding form: :headers
19:16ldh(GET "/" [{:headers {"Content-type" "text/plain"}} "Response text"]
19:16tomojclj files aren't in slime-repl-mode
19:16tomojand I don't think you want paredit turning on in every mode hook...
19:16mecoh sorry its just '(emacs-lisp lisp inferior-lisp slime)
19:16tomojperhaps you should add clojure? ..do you use clojure-mode?
19:17mecyes let me add it and see if that fixes it
19:17nickikhttps://github.com/nickik/IDPA-Programmiersprachen-Benchmarken/blob/master/clojure/src/clojure/binarytrees_me.clj
19:18brehautldh: you might find #compojure more helpful?
19:18nickikCan somebody help me I keep getting "Exception in thread "main" clojure.lang.ArityException: Wrong number of args (2) passed to: core$number-QMARK-"
19:18ldhbrehaut: ah, of course. thanks.
19:18brehautldh: sorry i cant help more, i mainly use moustache
19:18mecI get a "File mode specification error: (error "Unmatched bracket or quote")" when I open a .clj, could that be the case?
19:18mecr/case/cause/
19:19Userdnolen: I can do very fast java programs without any special care
19:19nickikHard to understand whats going on if you don't even get a linenumber.
19:19tomojmec: you lost me, sorry. good luck
19:20dnolenUser: would you say your Java knowledge is about equal to your Clojure knowledge?
19:20tomojamalloy:
19:21ldhbrehaut: no worries. a bit of struggle is part of the process of learning a new language/paradigm I suppose ;)
19:21tomojer. amalloy: I heard durendal can make paredit work in the repl. haven't tried it yet
19:21brehautldh: perceiver though, clojure's web ecosystem is developing very nicely
19:22nickikdnolen, i think its true because in java you mostly just use plain old imperativ code witch is just fast than in clojure (plus its mutch easier to get primitv types working)
19:22ldhbrehaut: indeed. seems like a pretty exciting time to be writing webapps in clojure
19:22brehautldh: definately is
19:23Userdnolen: no, but in java I at least don't need to change operators in every function and wrap all in additional casts to get performance
19:24tomojnickik: condp passes two args to each pred, number? and string? take only one arg
19:25tomojer, ignore that
19:25tomojbut that's where your problem is :)
19:25Userhere's java optimization: unroll a loop somewhere, take a calculated variable and take it out of a loop
19:26dnolenUser: I'm certainly not saying all in the Clojure world is wine and roses. < I agree 1.2 required too much expertise. Those are known pain points - 1.3.0 addresses some of the more problematic one.
19:26joshua__I just tried to implement a html to markdown converter. My attempt can be seen here: https://gist.github.com/868546 It was created by trying to translate this SO answer to Clojure: http://stackoverflow.com/questions/59557/html-to-markdown-with-java
19:26Userhere's clojure optimization: every trick of java optimization PLUS you need to replace all calls to * + - etc with unchecked, all numeric variables with (int x) and arguments with type hints
19:26joshua__It doesn't work. I don't know enough about what I'm doing to know why.
19:26Usera LOT more work, also makes code super ugly
19:27dnolenUser: and it would great for higher order operations to work on collections of Java primitives. Work is being done on this stuff.
19:28nickikyou can rebind *unckecked-math* or something to avoid the hole unckecked stuff right? (in 1.3)
19:28tomojnickik: right, so it's evaluating (apply number? args). I guess you're passing two args?
19:29tomoj..those will never be numbers anyway, will they?
19:30nickiktomoj, true i will replace it with something else
19:31mecwow so apparently an errant close paren somewhere in the source killed Paredit from loading at all
19:33nickiktomoj, i dont think its that. I use the same -main in a other namespace and it works there
19:33tomojthere, how many args do you pass?
19:34Deranderserial-port is relevant to my interests
19:34dnolenUser: for a lang that's three years old to be butting up against CL and Racket on Alioth is remarkable, I have high hopes for continued improvements to Clojure performance and regaining some lost expressivity.
19:35nickiktomoj, only one.
19:35tomojnickik: gotta go. if you're passing one arg to that one, and two args here, maybe you can see the problem?
19:37Userwhat expressivity was lost?
19:38Userdnolen:scala isn't any older (I think?) and is 3 times faster
19:39amalloyugh. unless you have to write any code in scala. that should slow you down
19:39dnolenUser: Scala is 2003.
19:39brehautScala is much older than clojure: wikipedia lists its first appearance as 2003
19:39Deranderdoesn't clojure also stand to gain massively from java 7?
19:40dnolenDerander: I don't think so.
19:40nickikmmh not really
19:40Deranderokay
19:40Derandernevermind then :-)
19:40nickikmaybe a little but not like ruby
19:40amalloy_Derander: it looks that way to me, but people who know better than i say no
19:40Userbesides clojure isn't butting up to CL and Racket for small lists
19:40Deranderokay. I'm also watching from a ruby perspective so perhaps I crossed the channels
19:40nickikthe forkjoin stuff and the closures will be helpfull
19:41dnolenUser: Alioth doesn't bench small lists in long running programs.
19:47User4000 elements is still quite big
19:48Usertry putting 10 elements into a vector...then 10 elements into an arraylist, then run this in a million iteration loop, so hotspot isn;t an issue
19:48Userstaggering difference
19:49nickikdnolen, did you look into that logic programming language you mention on your blog (that so much faster then prolog). I didn't have time to look into.
19:54dnolenUser: Try changing an ArrayList and getting the old version of the ArrayList before the change. staggering difference. Anyways sorry but this conversation isn't going anywhere for me.
19:54dnolennickik: ? what are you referring to?
19:56nickikdnolen, The Mercury Programming Language
19:59dnolennickik: I've only looked into it a little. Seems interesting, performance is very impressive. Lack of REPL is a turnoff for me tho.
20:12amalloytechnomancy: that is an adorable thing for your kid to do
20:13UserI knew you;'d say that
20:15Usertoo bad immutability doesn't do anything when vector doesn't leave the fn
20:34fliebeldnolen: Which of your posts mentions Mercury? I think that paper you sent me also mentions it.
20:34dnolenfliebel: I only mentioned it in passing as something interesting to look at. Enjoying the paper?
20:36fliebeldnolen: So far… meh. It contains a lot of stuff I already read in TRS, but I assume it's only the beginning, and even there it has a few interesting insights.
20:38dnolenfliebel: yeah it picks up when it covers the implementation.
20:38fliebelI skipped forward to the arithmetic part, and they explained why it is so much more complicated that one would think at first, thinking of it as a recursive full-adder. They stress determinism(is that a valid word?) much more than the book.
20:40fliebelI think they mentioned Mercury for its ability to use regular functions in unifications, deferring their action untill all values are grounded, but deny this approach because it can not be said to terminate.
20:40fliebelThis is kind of what project does, right?
20:43dnolenfliebel: project is for getting a logic vars value so you can use regular (non-relational) operations on them. For example you might know that a logic var is bound to a Clojure set, and you really just want to use conj etc on it's value.
20:45fliebeldnolen: Oh, yea, I mixed up a few terms, I need to sleep. See ya.
20:47brehautdnolen: is project equiv to m-lift for logos ?
20:48dnolenbrehaut: sadly my monad fu is significantly less than my logic fu, and honestly both are quite low :) what does m-lift do? lift a value out of a monad?
20:48brehautit lifts a function into the monad
20:49dnolenbrehaut: ah, it takes a regular function and allows it be used w/in a monad?
20:49brehautyeah thats a better way of putting it
20:54brehautmy monad fu is pretty low too, but im interested in the correspondence between alternative models of evaluation and the monadic operations
20:54dnoleninteresting, it does sound related. But the issue is different. Many useful operations are hard (impossible?) to define efficiently in a relational way (where inputs/outputs are interchangeable). So instead of struggling to define everything relationally, project is bit of an escape hatch for solving common problems with the downside that you can no longer infer inputs from outputs.
20:55brehautah right
20:56brehautthat input/output interchangability is where ive hit a roadblock trying to slowly evolve a logical variation of the monkey and banana from a naive functional variation
20:57dnolenbrehaut: in Prolog?
20:57brehautin clojure
20:58brehauttaken from the bratko book
20:58brehautits trivial in prolog :)
21:01brehautdnolen: even using fogus's unifier i still have to be fairly explicit about the solving steps
21:01brehautdnolen: https://github.com/brehaut/monkey-and-banana if you are interested
21:02brehauti want to have a crack at getting a logos version done too
21:02dnolenbrehaut: have you looked at logicT ?
21:02brehautdnolen: nope? what is it
21:03brehautlogic monad transformer?
21:03dnolenbrehaut: yeah, Oleg's implementation in Haskell of miniKanren's core ideas.
21:03brehauthuh. thats definatly something i need to read up on
21:04dnolenbrehaut: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.84.6597&amp;rep=rep1&amp;type=pdf
21:05brehautdnolen: great, thanks!
21:05dnolenbrehaut: if you implement anything like that in Clojure I'd love to see that and compare :)
21:06brehautdnolen: i'll have to understand it first :P
21:06brehautbut it soudns like something worth doing
21:15amalloybrehaut: writing code is a lot less adventurous if you understand it first
21:15brehautamalloy: thats not true if monads are involved :P
21:16brehautalso the paper is by oleg, they man has a brain the size of a small galaxy
21:17brehautit dawns on me that thus far none of my experiements in logic programming with clojure have included any notion of a logical variable
21:44fmwhttp://paste.pocoo.org/show/353261/ for some reason an if-not block seems to be executing there, even if it shouldn't. Any idea what I'm doing wrong there?
21:45amalloyfmw: ((println
21:45amalloyi don't think that is your *actual* problem (yet), but it will cause you pain eventually
21:46fmwamalloy: the whole 3 lines (both println's and (. vintage ...) are supposed to be part of the same block
21:46fmwthe println's are only for debugging though
21:46amalloythere are two ways to fix this problem
21:47amalloywell. i guess that depends where the .add is supposed to go. your indentation makes this really hard to read
21:47fmwthe .add is outside of the if (its added anyway)
21:48amalloyokay. so you have two issues here
21:48amalloyone is that you've stuck an if-not inside of a doto form where it doesn't realy belong
21:48amalloythis is expanding into (if-not document (nil? ...) ((println ...)) (.vintage ...))
21:50amalloythe other is that you don't group expressions by wrapping them with more parens: ((println x) (println y)) doesn't mean "print x, then y", it means "print x, then treat the return value of that print as a function and call it with argument y"
21:50amalloyyou're looking for (do (println x) (println y))
21:51fmwamalloy: ok, thanks, that fixes it
21:51fmwthat as in moving it out of the doto/wrapping the println's in a do
21:52amalloygood good
21:53fmwamalloy: as to the indentation, is it still objectable with http://paste.pocoo.org/show/353264/ ? if so, why? I suppose indentation is very personal, but I'd like to get used to an idiomatic identation style because I'm just starting out with Clojure anyway
21:54amalloyfmw: that's much better
21:54amalloyi wouldn't put a newline after the [ in let, but i'm pretty sure there are people who would side with you
21:55fmwamalloy: allright. yes, I was debating that with myself when I put it there
21:56amalloybtw, you know you don't *have* to type-hint those variables, right? i mean, feel free if you need performance or like it as self-documenting code, but it's not required
21:56tomoj(if-not x (do y z)) == (when-not x y z)
21:56fmwamalloy: aye, I know, but I was like: why not?
21:57amalloysure
21:57tomojbut, (when-not (nil? x)) seems strange
21:57tomojwhy not (when x) ?
21:57amalloytomoj: yeah. i wanted to emphasize "what do does" rather than "how i would write the code" which actually sidesteps the problem he was having
21:58tomojsorry, I just got here
21:58tomojdid you already make the . point?
21:58amalloyno
21:58amalloyi just fixed his problem. i haven't addressed ways to make his code better in general
21:59fmwso, whats the . point? ;)
21:59tomojwhether you asked for it or not: (. age setIntValue x) is less idiomatic than (.setIntValue age x)
22:00tomojI got excited when I saw lucene, then unexcited at couchdb :(
22:00fmwtomoj: aww, whats wrong with couchdb?
22:00amalloybefore any of yours, i would (let [{:keys [distillery title bottler ...]} (:value json-item)] ...)
22:00amalloythen you can stop messing around with json maps and just have a bunch of local bindings for the stuff you're interested in
22:01tomojfmw: nothing, I like it quite a lot, I'm just not using it right now
22:01fmwtomoj: ok :)
22:02tomojI think there is a beautiful clojure library for solr/lucene that hasn't been written yet
22:02tomojI tried and failed miserably
22:02amalloytomoj: ninjudd and/or lancepantz were at least starting to work on that
22:02tomojit's abstract classes all the way down
22:03brehauti think abstract classes go up rather than down
22:03amalloyanyway fmw does my suggestion make sense? i think tomoj will agree that it's more interesting than his suggestions :), so if not let me know
22:04fmwamalloy: the :keys suggestion?
22:04amalloyright
22:04tomojbrehaut: maybe solr's got me standing on my head
22:04brehauttomoj: entirely possible
22:04fmwamalloy: yes, I'm trying to implement it atm actually
22:04amalloygreat
22:04tomojamalloy: agreed
22:05brehauttomoj: one of my friends wrote his own in memory clj text index because it was simplier than trying to grok lucene et al
22:14amalloyfmw: if you don't mind, i've rewritten this to remove most of the duplicated code i could find: https://gist.github.com/868661
22:14amalloybut since i don't have lucene/couch handy, i don't even know if it compiles, so test with care before including :P
22:15fmwamalloy: cool, I think I fully understand the code, even :)
22:15fmwcheers
22:15amalloyfmw: that's the idea! write each idea exactly once :)
22:16fmwamalloy: yes, I get the point and see why this is idiomatic
22:17amalloyoh, i bet my change from (Integer.) to (int) broke things, though. don't use that :P
22:18fmwamalloy: ok, that was one of the things I was wondering about
22:18amalloya brief attack of amnesia
22:18amalloynothing more
22:18fmwamalloy: also, why the when instead of if? AFAIK it does exactly the same, but when is more idiomatic because it implies a do?
22:19amalloyfmw: that is one of the two reasons
22:19joshua__Anyone here familiar with XSLT?
22:19amalloythe other is that, after doing this for a while, seeing an if without an else will make you dizzy: you will never leave one out on purpose
22:19amalloyer, on accident
22:19amalloyjoshua__: it's been like four years but i used to be pretty solid on them
22:19fmwamalloy: ok :)
22:19fmwpoint taken
22:20joshua__I just tried to implement a html to markdown converter. My attempt can be seen here: https://gist.github.com/868546 It was created by trying to translate this SO answer to Clojure: http://stackoverflow.com/questions/59557/html-to-markdown-with-java
22:21DeranderIs it possible to use java.nio.file's api to watch files for changes w/o polling in java 6? is there an alternate api for java 6? I can't believe polling has been the way to track files forever
22:21brehautjoshua__: have considered enlive instead of xslt ?
22:21joshua__brehaut, enlive has an html to markdown function!?!
22:21brehautjoshua__: no, but it has general html scrapping functions
22:21brehautand its selector based
22:22joshua__brehaut, I'm already using it for the scraping. See: http://173.255.212.42/item?id=1589257
22:23joshua__I just don't want it to look ugly, so I'm planning to select only the part of the comment I want with enlive, convert that to html, convert that html into markdown, and than have the backend of comments be markdown
22:25woobyDerander: not that i've seen, if you really needed to you could dip into the host api w/ JNA
22:25wooby(or jni)
22:26Deranderwooby: seems unbelievably goofy to me, but okay :-/
22:27tomojI think I managed to get a stupid example with jnotify working reasonably easily once
22:28woobypossible someone's already done the goofiness for you, i haven't looked in awhile
22:30amalloywooby: impossible. there is a limitless supply of goofiness to be done
22:39fmwamalloy: hmm, thats giving an error for me http://paste.pocoo.org/show/353276/
22:40amalloyfmw: missing a ~ in ~document at line 11, sorry
22:41fmwamalloy: meh, in hindsight I should've spotted that!
22:41fmwthanks though
22:41amalloyfmw: i left it in intentionally, to give you practice reading compiler stacktraces.......
22:41fmwamalloy: hehe :)
22:46fmwamalloy: this one is really inexplicable for me: http://paste.pocoo.org/show/353278/ says java.lang.ClassCastException: java.lang.String cannot be cast to org.apache.lucene.document.Fieldable
22:46fmwon the (doto document line, even
22:47tomojis there a reason for add-field to be a macro?
22:47amalloytomoj: i wanted to get the string version of the symbol
22:48tomojah, I see
22:48fmwthe error occurs regardless of using a macro or not
22:48amalloysince he's doing (Field. "title" title)
22:48fmw(if I remember correctly)
22:49amalloyoh
22:49amalloyer hm
22:50amalloyfmw: sure? the easiest explanation would be that my macro is wrong somewhere
22:50tomojpresumably age and vintage are strings from the json?
22:50tomoj.add on a Document expects a Fieldable
22:50amalloyoh
22:50fmwtomoj: ah yes they are.
22:50amalloyyes thanks
22:51fmwits not being used for vintage/age though
22:51fmwthe macro
22:51amalloyfmw: see the last two lines
22:51amalloyyou mean age-field, not age
22:51fmwamalloy: ah yes
22:52fmwI corrected that in the let, but copied your code without thinking elsewhere.
22:52tomojdoes using the name of the local binding for the field name not seem a bit strange? very terse and pretty, but..
22:52fmwI don't like the stack traces yet, really, so hard to see where you're going wrong exactly
22:53amalloytomoj: i wouldn't object if you called it gross
22:54amalloyif you wanted to make it into a function and pass the string manually i guess that would be okay with me
22:55amalloybetter i guess would be to create a function version, and wrap it in a macro that uses the local binding
22:56tomojdunno that it's bad, just strange and different
22:57amalloytomoj: part of my campaign to never type the same symbol twice in any program
22:58tomojmy analogous code just took a map of keywords for field names to values
22:58tomojbut solr took care of all the per-field properties
22:58amalloytomoj: i have a keywordize macro i use occasionally: (keywordize [a b c]) expands to {:a a :b b :c c}
22:59amalloyit's pretty common that N different functions refer to some stuff by the same names, and want to pass around data in a map
23:00tomojthen again, do the per-field properties really belong in create-document?
23:00tomojnevermind, it's 30 lines of code :)
23:01amalloythe dude wants code to add some fields to a thing? he gets code to add fields to a thing
23:01fmwheh
23:01tomojis lucene schemaless?
23:01tomojnever used it except through solr
23:02fmwtomoj: as in that it doesn't require all fields for every document?
23:02tomojI mean, you could add whatever fields with whatever names/properties you wanted?
23:03fmwtomoj: yes
23:04amalloyhey ossareh, were you at the clojure meetup? nobody ever said "hey i'm ossareh"
23:09tomojamalloy: I think it's that it blurs the distinction between code and data in a way I just haven't really seen before
23:10tomojbut the more I think about it, the more it seems like that might be a good thing
23:10amalloytomoj: well, glad to have opened your mind, i guess, whether or not you decide you like it
23:12tomoj:)
23:13tomojbeing without keywordize when you need it is certainly ugly
23:14amalloyheh
23:15amalloyneeding it is usually a bad smell anyway
23:16phenom_does clojure have a sort of circular linked list or ring-like data structure ?
23:17tomojfor what?
23:17brehaut&(take 10 (cycle [:a :b :c])
23:17sexpbot⟹ (:a :b :c :a :b :c :a :b :c :a) ; Adjusted to (take 10 (cycle [:a :b :c]))
23:18phenom_well, i've got a list but id like to read the first element, then rotate left (so the head goes to the end and everything shift over 1)
23:18brehautphenom_: cons pairs are you easiest route to cycles
23:19phenom_cons pairs ?
23:19brehaut,(cons 1 ())
23:19clojurebot(1)
23:19brehaut,(cons 2 (cons 1 ())
23:19clojurebotEOF while reading
23:19brehautthat'll teach me to use clojurebot
23:19tomojguess the question is, do you need to edit it during these read/rotates?
23:20brehauttomoj wins for best question
23:20phenom_tomoj, well, other threads may edit it
23:20tomojthen it's an interesting problem
23:20tomoj:(
23:20phenom_i was using a [index, content] pair
23:21phenom_"head" was (nth content index)
23:22amalloyken wesson implemented a ringbuffer on the mailing list a while ago
23:22brehautphenom_: can you back up a step and explain what you are trying to solve?
23:23amalloybut in general i like brehaut's answer better. instead of asking for a data structure to solve a problem (which you've usually created for yourself), look for a better approach to the problem
23:24phenom_well, i've got a list of items, i need to get the first element, then rotate the list ... other threads might be adding elements to the end of the list or removing elements from anywhere within the list
23:24amalloyphenom_: what do you mean, get the first element then rotate the list? "rotating the list" sounds like an artifact of your implementation, not your requirements
23:25phenom_i want to cycle through the list
23:25amalloyie, it sounds like you're really looking for a bounded-size queue
23:25amalloyand you want to let other threads *delete* things from the list while you're doing that? prefer suicide
23:25phenom_well, using refs :P
23:26amalloythat's not going to make it less confusing
23:28phenom_amalloy ... let's say you've got a list of email addresses and a system that receives requests to send out email ... everytime you get an email, you cycle through the list of addresses, send it to exactly one, then rotate the list
23:29phenom_so: list = a@a.com, b@b.com, c@c.com ... request one get's mailed to a@a.com, then the next request to b@b.com etc.
23:29amalloywhy would my system do that? i can't imagine a real-life scenario where i would say "here is an email, please send it to someone on this list but i'm not sure who"
23:29phenom_that's beside the point
23:30brehautphenom_: what requirement forces you to remove from anywhere in the list?
23:30amalloyi don't think it is. refs or no, if you introduce concurrency to this model your performance will be basically random
23:31amalloylike, i was thinking "maybe he's doing load-balancing for a set of servers"
23:31amalloybut you might as well just assign randomly in that case, it will all work out on average
23:31brehautphenom_: is it some sort of priority requirement?
23:31phenom_no priority
23:31phenom_just round-robin
23:32brehautits not round robin if you take randomly
23:32phenom_well, server 4 may go down
23:33amalloyphenom_: so? keep an unordered set of servers and assign randomly to any that are still working. no reason to futz with keeping an ordered list
23:34phenom_amalloy: the requirement is to do sequentially in the order they were added to the list
23:35brehautphenom_: it sounds like you want a clojure.lang.PersistentQueue in some reference type
23:35brehautor alternatively to restructure your program to run in an agent
23:36brehautyour third option is to not use a persistent queue type and switch to a java concurrent queue which is blocking
23:36tomojwouldn't you need a dequeue?
23:36phenom_brehaut: but how do i get the round-robin behaviour? dequeue then requeue ?
23:37tomojer, deque
23:37brehautphenom_: round robin is the consumeres taking turns
23:37brehautim not sure how thats a data concern
23:38tomojyyy ju'i nai
23:38phenom_brehaut: the logic to forward requests to the appropriate server ... how would that be done in round-robin then ?
23:38phenom_given a list of servers
23:39brehautcycle your list of servers, send a message to each server to to get work, server requests work?
23:43phenom_brehaut: the problem with that is given list [s1 s2 s3], when the first request comes it it should be sent to s1, when the second comes in (possibly in a different thread), it needs to go to s2
23:44phenom_meaning, the system doesn't know up front all the requests ... it's done as it's picked up off the network
23:47amalloyphenom_: how can it be a "requirement" that servers be assigned to strictly in order, when you have to be tolerant to them disappearing at any time?
23:47brehautphenom_: i think we are talking passed each other now. i have no idea what you want that i havent mentioned previously
23:47brehauti know that if i had n servers and 1 work queue, i would just use a blocking work queue
23:48brehautand make the workers request items off it as fast as they could
23:48brehautand not owrry about trying to implement some addition round robin scheduling
23:48phenom_okay, maybe load balancing is the wrong anaolgy
23:49phenom_how about a message queue ... you have n subscribers but you want an incoming message in a queue to be sent to exactly one and only one ... so you use a round robin system
23:49brehautphenom_: i wouldnt. i would us a blocking queue
23:50amalloyindeed
23:50brehautphenom_: the blocking queue ensures all the concurrency semantics around dequeueing one item to each requester, in order, and such that if there is no work to do, nobody spins
23:50amalloywhat if one message were really long? or one server were really slow? round-robin makes no sense
23:51phenom_subscribers are passive ... the messages need to be pushed over the network
23:52amalloythat's even more nuts. how will you find out if a subscriber crashes?
23:52phenom_ack/nack expiry
23:53amalloyin the meantime you've wasted time sending him N requests he never got, and you've had to remember them so you can reassign them to someone else
23:53amalloyjust make the subscribers ask you for data like brehaut says
23:53phenom_assume the other :P
23:53phenom_the problem is the cycling
23:53amalloyanyway apparently my being opinionated isn't solving your problem, and i don't have real ideas. afk