#clojure logs

2010-11-02

00:08_seanc_I see that add-classpath is deprecated, what is the correct way to add things to the classpath? I need to add the Sqlite driver :X
00:12amalloy_seanc_: i don't actually know about classpath management in clojure. i'd either add it to my CLASSPATH env variable or figure out how to get the jar from maven
00:13amalloyif you're using lein or cake, you should be able to specify a dependency on sqlite in project.clj, and they'll download it, put it on the classpath, and make it Just Work
00:14_seanc_I didn't know lein would do that, I'll look into it
00:14amalloyit looks like you just have to add [org.xerial/sqlite-jdbc "3.7.2"] to project.clj
00:14amalloyas a dependency
00:16amalloy_seanc_: yeah, just tried it in one of my projects, and it goes and gets it for me
00:16_seanc_How did you figure that out?
00:16amalloywell, i searched on google for "sqlite maven"
00:16_seanc_I was thinking I needed to use clojars, which is 0.5.6
00:16_seanc_ah
00:17amalloyfound the artifact ID and a list of version numbers; picked the newest
00:17amalloyobviously if you need a different version you should specify that instead
00:19_seanc_I forget that lein is mavenish
00:20amalloyoh by the way, you have to run lein deps to actually *get* the jars
00:23_seanc_got that part! :D
00:23_seanc_You're awesome, thanks
00:25amalloywelcome, _seanc_
00:42jcromartiedoes lein use a local maven repo to store jars of the same version?
00:42amalloyjcromartie: ~/.m2
00:42jcromartieok so it doesn't always fetch
00:43amalloyno
00:43jcromartieI like my build tools to work offline at least at some point
00:43amalloythough you can force it to, if you tell it to get a snapshot
01:58LauJensenGood morning team :)
02:02amalloymornin' LauJensen
02:08sthubnergood morning!
02:11rata_good morning LauJensen
02:12rata_how do you get the previous versions of a ref/atom? is it possible?
02:14amalloyrata_: you have to track them yourself. you might find add-watch useful
02:14amalloy&(doc add-watch)
02:14sexpbot⟹ "([reference key fn]); Alpha - subject to change. Adds a watch function to an agent/atom/var/ref reference. The watch fn must be a fn of 4 args: a key, the reference, its old-state, its new-state. Whenever the reference's state might have been changed, any registered watches will have their function... http://gist.github.com/659310
02:16rata_which files installs lein self-install?
02:17amalloyrata_: http://github.com/technomancy/leiningen/raw/master/bin/lein
02:18rata_no... I mean... once you run "lein self-install", does it install other files besides "lein"?
02:19amalloyrata_: i think it gets a copy of maven, and uses that to get clojure and clojure-contrib, and then the real leiningen jars
02:19rata_ok
02:21amalloywhy do you ask?
02:23rata_because the archlinux AUR package installs just /usr/bin/lein and I was suspicious about that
02:23amalloyah
02:24rata_ok... a "locate lein" says it installed everything inside ~/.m2 :)
02:24rata_amalloy: did you solve the problem you had with the value of an atom being changed?
02:25amalloyrata_: sorta. i ended up using another atom
02:25rata_amalloy: why not use add-watch + set-validator?
02:27amalloyrata_: those introduce asynchronicity and/or exception-handling problems that have to be handled with every swap!
02:29rata_amalloy: I didn't know that... why is it so? add-watch says the fn is called synchronously
02:30amalloyrata_: sure, synchronously, but then your watcher function has to do something that causes the original caller/swapper to abort the swap, or notice it hasn't applied cleanly. that seems even less clean to me
02:32amalloyand even if it's technically synchronous, you have to do basically the same thing as if it were asynchronous. try using it yourself
02:33rata_and why don't you compare the old value with the new value in the caller/swapper?
02:34amalloyrata_: then i can't tell whether it stayed the same because (f old-val) == old-val, or because (pred (f old-val)) was false
02:35rata_do you need to make that difference?
02:35rata_and the value is an integer, right?
02:35amalloyin my particular case...maybe, i'm not sure. but i wanted to generalize this to be useful for every instance of this problem
02:36rata_what are you working on?
02:36amalloysexpbot, at the moment
02:36amalloyit wants to make sure only N threads can be servicing requests at a time
02:37amalloyso i could do it by comparing the old-val and new-val, since it's just an integer and i know it's incrementing
02:37amalloybut i was hoping to solve the problem in a more general way
02:38hiredmanuh
02:39hiredmanamalloy: http://download.oracle.com/javase/tutorial/essential/concurrency/pools.html
02:42amalloyhiredman: good point, and maybe the right long-term answer. but what if, eg, someone sends sexpbot a million long-running requests via /msg? the current implementation sends them back a million error messages; a thread pool would queue them all up, locking up sexpbot until they were done
02:49rata_amalloy: and set-validator! + try-catch?... if the validator fn returns false, it throws an exception and you know it failed... and you don't need the extra atom
02:50amalloyrata_: no, but i need a try/catch. i don't think either is much better than the other
02:52amalloyrata_: my current implementation is at http://bit.ly/aw8GIW if you want to tell me how it could be better
02:52rata_a macro could hide the try-catch thing in a beautiful thing... maybe (changed? (swap! an-atom inc) :some-kwd)... if it doesn't change :some-kwd will be returned... it's the same logic as (get ...)
02:52amalloyrata_: you don't really need a macro; you can do it in a function that hides the same logic
02:53rata_can you do it? the exception would be thrown on the swapper function and not in "changed?"
02:54amalloyrata_: see the commit i linked. i used an atom, but the function could use try/catch similarly
02:57rata_which commit?
02:58amalloyhttp://bit.ly/aw8GIW
03:02rata_amalloy: yes, it's the same idea
03:07rata_but maybe the try-catch thing will be a little faster, as it doesn't need to create an atom (which I suppose isn't cheaper than throwing an exception, but don't know really)
03:08amalloyrata_: i don't know either, but i had the opposite intuition - i know exceptions are slow, and the STM seemed like it had to be faster
03:09rata_oh ok
03:17rata_amalloy: I was away when you said it, but congratulations for being in the contributors list =)
03:17amalloyheh, thanks
04:50rata_good night :)
04:59esjMorning all
05:02LauJensenMorning esj
06:15Kenjinhello
06:30KenjinCould someone take a look please? https://gist.github.com/ffaea21e7de730165da6 thanks
06:44esjKenjin: I get a "connection refused" but I have zero idea about java.rmi
06:45Kenjinesj: the java bit has to be running
06:46Kenjinbasically "r.rebind("rmi://localhost/rmiconnect", rc);" creates an object rmiconnect in the rmi-registry
06:46esjox
06:46esjsorry to be no help
06:47Kenjinesj: no problem. thanks for taking look :)
07:32neotyk&(loop [s '(1 2 3)] ((fn [] (if-let [r (next s)] (recur (rest s))))))
07:32neotyk,(loop [s '(1 2 3)] ((fn [] (if-let [r (next s)] (recur (rest s))))))
07:32clojurebotjava.lang.IllegalArgumentException: Mismatched argument count to recur, expected: 0 args, got: 1
07:33neotykcan someone explain why (fn [] takes precedence over (loop [..] ?
07:34LauJensenneotyk: It looks up the tree and grabs the first match IIRC
07:35neotykHi LauJensen, yes, that is for sure what happens
07:35neotykany ideas how do I make sure that loop is used?
07:35neotykI have no option to get rid of this fn []
07:36neotykthis is generated by macro of with-connection from sql
07:41neotykok, local let FTW
08:16LauJensenclojurebot: clojureql?
08:16clojurebotclojureql is http://gitorious.org/clojureql and tracked @ http://clojureql.lighthouseapp.com/
08:16LauJensenclojurebot: forget clojureql
08:16clojurebotclojureql is http://gitorious.org/clojureql and tracked @ http://clojureql.lighthouseapp.com/
08:16LauJensenclojurebot: clojureql is http://github.com/LauJensen/clojureql
08:16clojurebotRoger.
08:32_na_ka_na_how to do byte operations in Clojure? For example how to do 76 & 0xFF
08:35cemerick-> (bit-and 76 0xFF)
08:35cemerick,(bit-and 76 0xFF)
08:35clojurebot76
08:36cemerickhuh, no sexpbot
08:36cemerick_na_ka_na_: ^^
08:36_na_ka_na_thanks
09:17tonylmorning
09:17neotykafternoon
09:23fliebelmorning
09:24raekfliebel: did you manage to see this? http://pastebin.com/9CUeiq3W
09:24raek5 mins after you left...
09:24fliebelraek: No, I didn't
09:26fliebelraek: Great! Only I just posted it to the mailinglist :(
09:26tonylfliebel: it's happened to me before
09:27fliebelraek: Trying it right away.
09:29raekas jarpiain said, reduce builds up a nested lazy sequence of map calls
09:31fliebelraek: Right. I was hoping someone would say something like that. My firt thought was a mistake, then I thought of a lazy gotcha, but hten I started to belive it was a real bug.
09:35fliebelraek: Works! Next step is to figure out why it is so slow and make it use all my cores.
10:03jaleyhello! can anyone clarify the ! naming convention for me? is it supposed to indicate side-effects only? or something else?
10:04raekjaley: side-effects that are not safe to do in a transaction or a transition function (or anything that might be executed more than one time)
10:05drewrI generally use it to also mean there's no interesting return value from the function (though that's not necessarily clojure's position)
10:05jaleyok.. so it'd be sensible to use it for operations that send things over a network? as in... i don't want to resend requests in transactions being retried
10:05raekyes
10:05jaleycool - thanks guys!
10:10fliebelHow can I do type hinting inside of ->?
10:11bsteuberI like the quote "Java is the new COBOL" from clojure in action
10:12chouserheh. I thought that was VB
10:12bsteubermight be nice on a T-Shirt :)
10:12chouseror PHP, or ...
10:12bsteubertrue, there are more candidates
10:12tonylfliebel: do you mean data type hinting or fn parameters type hinting
10:14fliebeltonyl: I think the data thing. I get reflection warnings for a few method calls without parameters.
10:14chouserfliebel: you should be able to hint the previous expression.
10:15fliebeltonyl: I'm doing something like (-> file .method1 .method2)
10:16fliebelchouser: I hinted the starting value, but I don't understand where the type gets lost and how to add it back.
10:17fliebelhttp://github.com/pepijndevos/Clomian/blob/master/src/clomian.clj#L20
10:18chouserfliebel: these are just guesses since I don't have the required jars to test it, but it's probably just the (get ...) forms that Clojure can't figure out the return type of
10:19chouserso try hinting those, like ^LevelObject (get "Level")
10:19fliebelchouser: I turned them into .get calls, which didn't help. Will try the hint there.
10:25chouseroh, you should hint file too
10:27fliebelchouser: I hinted nearly every single line in that macro :(
10:30fliebelchouser: All these methods are now java, so they should have a set return type. But I keep getting 2 of these: Reflection warning, clomian.clj:25 - call to get can't be resolved.
10:30fliebelReflection warning, clomian.clj:27 - reference to field getValue can't be resolved
10:32AWizzArdinteresting: I was running (time (dotimes [i 10000000] (XYZ "12345"))) and got those timings (in msecs) for XYZ replaced with: empty? 560, not-empty 560, (not (empty? )) 650 (why is this so much slower?), seq 480, .isEmpty 3 (winner), (not (.isEmpty )) 42
10:32AWizzArd(time (dotimes [i 10000000] (not true))) ==> 41 msecs
10:33AWizzArdIs timing (not true) mostly measuring how long looking up 'not' takes?
10:38AWizzArd$(let [*14-days* 14] 10)
10:38AWizzArd,(let [*14-days* 14] 10)
10:38clojurebot10
10:38AWizzArd,(let [+14-days+ 14] 10)
10:38clojurebotInvalid number: +14-days+
10:39AWizzArdBug or feature? ;)
10:49jcromartieAWizzArd: what
10:49jcromartieAWizzArd: I'm confused
10:50jcromartie,'+1
10:50clojurebot1
10:50jcromartie,'+1-
10:50clojurebotInvalid number: +1-
10:51tonylso +1 is a number
10:52tonyl,+1
10:52clojurebot1
10:52tonyl,-1
10:52clojurebot-1
10:52tonylpos and neg
10:53tonylfliebel: get you give a snippet of the blocks fn, to see how the type hinting of java calling is going.
10:54fliebeltonyl: "get you give"?
10:55tonyl*can you give or post a snippet
10:55tonyl:P mybad
10:56fliebeltonyl: I have this with ^java.io.File at the top and get > .get http://github.com/pepijndevos/Clomian/blob/master/src/clomian.clj#L20
10:57tonylalright, i'll test it
10:59fliebelawesome
11:00tonyldoes the input file has some special markup or it can be a file with any content?
11:01fliebeltonyl: It's a nbt file. I don't think you can test it without installing jnbt and getting some sample file.
11:02fliebeltonyl: I think I'm better of finding a profiler and utilizing my other core than nitpicking about reflection.
11:04tonylyeah... I haven't mess with nbt files
11:14jcromartiewow can we have an official Clojure version of this http://docs.python.org/faq/programming
11:19chouserAWizzArd: for me, all the seq/empty calls (with or without not) come in at essentially identical times, and .isEmpty (with or without not) is indeed about 100x faster
11:20chouseroops, sorry, was scrolled way up.
11:36AWizzArdchouser: are you on 1.3α2 ?
11:36chouseryeah
11:37AWizzArdand is (not (.isEmpty )) as fast as .isEmpty alone, or takes 10x as much runtime?
11:38mrijkHi all... I am looking for the tree picture (hires) from the presentation "The Roots of Clojure"
11:39AWizzArdMy timings were .isEmpty < (not (.isEmpty )) < seq < empty? < not-empty < (not (empty? ))
11:42chouserAWizzArd: same speed
11:42chouser.isEmpty == (not (.isEmpty )) < seq == empty? == not-empty == (not (empty? ))
11:42chouserAWizzArd: you're letting hotspot have a chance to inline everything?
11:51fliebeltonyl: I don't understand half of what I'm doing in this profiling app, but it seems it's spending quite a lot of time reflecting, and runs on one core at the moment.
11:53tonylis it reflecting all the methods?
11:54tonylfor sure it is not reflecting anything clojure, that is the weird part
11:54fliebeltonyl: I'm not sure. I think only 2-4 of them.
11:57chouserfliebel: if you care about performance, it's absolutely worth getting rid of reflection
11:57chouserfliebel: what version of Clojure are you using?
11:57fliebelchouser: I figured… 1.2
11:58chouserand it's complaining about .get and .getValue?
11:58fliebelyea
11:59chousercare to paste or push what you've currently got?
12:00fliebelokay, but currently… it stopped "working" i.e. giving reflection warnings. So I'll get those back fisrt.
12:00chouserhm
12:01chouseractually, wait a sec
12:02fliebelokay, it "works" again
12:02fliebelhttp://github.com/pepijndevos/Clomian/blob/master/src/clomian.clj#L23
12:03fliebelCheck this for the return values: http://jnbt.sourceforge.net/doc/
12:03chouser.getValue only claims to return an Object. What type is it actually going to return?
12:03fliebelall but the last one return CompoundTag the last bye[]
12:05fliebeland get returns some sort of map, does it matter which one?
12:05chousera Clojure map?
12:05fliebelno, java.util.map
12:05chouserok
12:09chouserCompoundTag doesn't have a 'get' method
12:09fliebelchouser: ^org.jnbt.CompoundTag (.get "Level") for both gets leaves me with only this one: Reflection warning, clomian.clj:28 - call to get can't be resolved.
12:10chouseroh, .get is returning a CompoundTag
12:10chouserok, I'm caught up
12:10Kenjinhi
12:10fliebelyea, I'm confused as wel..
12:11KenjinAnyone done some rmi with clojure? https://gist.github.com/ffaea21e7de730165da6
12:11chousertry ^java.util.Map (.getValue) instead of the first .getValue
12:11fliebelgetValue returns a map of tags, and those tags return another map.
12:12fliebelbriljant! Works so far :)
12:12chouser:-)
12:15fliebelNow I only need to figure out how to use my other core. Agents, future, pmap… I don't know. Does Joy of Clojure have a chapter on this?
12:17chouserhm, what you want is parallelism, I think, not concurrency
12:18chouserwhich is currently better covered outside clojure's core features than within them.
12:18fliebelchouser: You mean in Java?
12:18chouserI mean Clojure has these innovative features to address concurrency, but little of its own to address parallelism
12:19chouserbut perhaps pmap or the forkjoin lib would help.
12:19tonylfutures?
12:20chousereither way, you're going to need to figure out what chunks of work are expensive enough to be worth farming out to other threads
12:20chouserthere's some interesting stuff coming to integrate forkjoin with Clojure vectors, but I'm not sure if it's available anywhere yet.
12:20fliebelchouser: IO? I'm reading 2000 files ;)
12:20chouserLiebke gave a talk on it at Clojure Conj.
12:21fliebelchouser: I saw the slides.
12:21AWizzArdchouser: did the Conj gave any insights about what opportunities Clojure will have in future versions to tackle parallelism?
12:21chouserfliebel: if you're IO-bound, you may not be able to keep all your cores busy
12:22fliebelchouser: I'm not sure I am… I'm just doing a lot of it.
12:23chouserAWizzArd: just what I mentioned.
12:24angermanare there any enty level clojure presentation slides up online somewhere I might take a look at for inspiration?
12:24chouserangerman: rhickey's videos are still the gold standard (and widely mimicked) I believe
12:24chouserangerman: -for-lisp-programmers and -for-java-programmers
12:25AWizzArdchouser: yes, saw it after hitting Enter.
12:25chouserAWizzArd: :-) ok
12:25chouserangerman: you're giving an intro talk?
12:25angermanchouser: yep, tomorrow.
12:25chouserheh
12:26angermanit's at the chair at my university where I'm writing my final thesis.
12:26chouserwell, I've given a couple of those now, and next time I think I'm going to try keep the number of "clojure syntax" slides to 1 or 0
12:27fogus_chouser: 1 is more ffective
12:27chouserI liked how my expression-problem talk went in that regard -- present an interesting problem and some code in a familiar language that sets up or solves the problem
12:27fogus_with a single bullet ;-)
12:27chouserfogus_: * none ?
12:28chouserthen once they've got the data structures/problem space in their head, re-present with clojure syntax.
12:28chouserand *hopefully* they can just ease into it without concentrating on the details too much
12:28angermannah, they do know java fairly well. We had a talk on python a few weeks ago and they were interested and at the same time scared that you could probably poke any object with lots of crap.
12:28chouserheh
12:29chouser"you could, but you don't" :-)
12:29angermanthough I'd say they are very likely familiar with functional approaches.
12:29angermanso it's more a "so we got the JVM we like, and here's a language that put's the fun back into programming.
12:31fliebelchouser: Some high-tech profiling with Activity monitor and println shows that I'm doing 100% of one core and not so much IO, though the number of files being read is huge(I estimate 5 per second).
12:31clojurebotOk.
12:35chouserfliebel: freqs takes the bulk of youre time?
12:36chouserfliebel: btw, you can (repeat 128 {})
12:37fliebelchouser: I think so, but I haven't tried very hard to profile.
12:40fliebelchouser: There are a few copies of pvreduce floating around on github. That sounds like the thing I need.
12:54lpetitHi, in the github "clojure" organization, the sub project names are not prepended with "clojure.". While I can see this makes sense because they already are in the "clojure" organization, there's still the problem that this "organization" metadata is github specific, not git. So by default when people will start to "fork" clojure organization's project, not having this "clojure." prefix may be a problem. At least I know that for my
12:59lpetitWouldn't it make sense to add a "clojure." prefix to the project names ?
13:10amalloylpetit: like change the clojure repository from "clojure" to "clojure.clojure"?
13:11lpetitOh please
13:12lpetitamalloy: like clojure.data.finger-tree instead of data.finger-tree, (or maybe clojure-data.finger-tree to follow the "contrib" convention ?)
13:16lpetitmust leave, have posted the question on IRC? cu
13:16lpetits/IRC/ml/
13:30amalloy&(class #"")
13:30amalloy,(class #"")
13:30clojurebotjava.util.regex.Pattern
13:31amalloy,(class java.util.regex.Pattern)
13:31clojurebotjava.lang.Class
13:31fliebelamalloy: The mysterious Class object :)
13:32amalloyfliebel: i always forget and try to use Pattern/class
13:37amalloybeing able to just use Pattern will be very convenient if i ever remember it
13:48alpheusI need help understanding when function names are bound to the function object. I tried to write a trace utility (using robert.hooke) to trace a recursive function, and, of course, the call inside the function was to a function *before* the hook was installed, so only the outer function call was traced.
13:49alpheusIn Lisp, I might try to bind later, using something like funcall through a name to designate the function.
13:51amalloyalpheus: (declare) is for forward declarations
13:51chouseralpheus: this is changing between 1.2 and 1.3. which version would you like to discuss? :-)
13:52alpheus1.2, I guess. I'm hoping to have some working code before 1.3 is released ;)
13:56chouserhm
13:56chouserI thought I knew, but I'm seeing behavior I wasn't expeting
13:56alpheusWe can pretend I'm debugging fib: (defn fib [n] (if (= n 1) 1 (* n (fib (- n 1))))) ;; not the production version, of course
13:57chouserduh, I'm on 1.3
13:58chouserhm, same on 1.2
13:58ubiitrying to find some recent Clojure podcasts or videos, can anyone point me to a few?
13:58ubiimost of the ones that I have found so far, are from 2008
13:58ubiialso, any word on when the Clojure Conj videos will be available?
13:58chouseralpheus: you can delay var resolution for you recursive call by using (#'fib (- n 1)) instead
13:59alpheusindeed?
14:00alpheusThank you. It does just what I needed.
14:00chouseralpheus: that'll work the same going forward
14:01ubiichouser: when do you expect JoC to be completed?
14:01chousernote there's some runtime cost because it derefs #'fib each time its called
14:01ubiigoing through the MEAP now and am really enjoying it
14:01kryftubii: December, I think.
14:02chouserubii: thanks! the chapters are essentially complete. hoping for tree pulp version in December
14:02alpheusIt's funny. I tried the same thing with Stuart Sierra's trace and when it didn't show the inner function calls, I decided to write my own using robert.hooke.
14:02alpheusNow I know the real answer.
14:02chouserohhhh
14:03alpheusI'm lucky my employers are tolerant of my learning clojure on their dime!
14:03ubiichouser: when do you plan to go back and address some of the minor spelling/grammar and formatting issues in the MEAP, which folks have brought up on the MEAP forum?
14:04chouserubii: the copyeditors are hard at work, presumably as we speak.
14:04ubiichouser: cool, thx
14:05kryftchouser: Hehe, glad to hear that, although I love the content. :)
14:05clojurebotamespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it
14:06chouser,(macroexpand-1 '(defn f [] (f)))
14:06clojurebotDENIED
14:07chouserhmph
14:07chouseralpheus: anyway, look at the macroexpansion carefully
14:07chouseralpheus: and tell me what defines f at the point of the recursive call
14:09ubiichouser: I have to say that I really like the approach you guys took, where you start off by explaining the philosophy of Clojure and providing an overview of the core concepts, as compared to other books, which simply jump right in to basic syntax
14:09kryftAgreed.
14:09kryftIt really is a joy to read in that respect.
14:10chouserwell, that's good to hear. those two chapters got shuffled repeatedly through the process before finally landing with philosophy first.
14:10kryftI also like how you actually explain a bit about what's going on under the hood (eg. how to implement persistent data structures efficiently)
14:11chouserkryft: I was going to go with "it's magic", which is just one more reason why it's good to have fogus_ as a co-author.
14:11ubii:)
14:12amalloychouser: well, neither of you is wrong
14:13kryftchouser: :)
14:17arohnerwhen using paredit, how do you split a string into two strings? i.e. "foo | bar" -> "foo " "bar"
14:18amalloyarohner: M-shift-s, as i recall
14:18maravillasM-S perhaps?
14:19arohneramalloy, maravillas: yes, thank you
14:19arohnerparedit-split-sexp
14:20fliebelAre there any gotchas for using transients? I have a seq of transient maps, but when I do (map persistent!) on them, I get "Transient used after persistent! call"
14:23AWizzArdfliebel: do you have a doall around your map?
14:23AWizzArdYou better should use doseq here.
14:23amalloyhm, not that i know of.
14:23amalloy&(map persistent! (map transient! (map range (range 4))))
14:23sexpbotjava.lang.Exception: Unable to resolve symbol: transient! in this context
14:23amalloy&(map persistent! (map transient (map range (range 4))))
14:23sexpbotjava.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IEditableCollection
14:24amalloyoh well :P
14:27fliebelstill nothing.
14:29chouserfliebel: transients are not mutable collections in the classic sense. you have to leave your code structured as for persistent collections
14:29chouser...and just do a transient up front and a persistent! afterwards
14:30LauJensen&(-> [1 2 3] transient (conj! 4) persistent!)
14:30sexpbot⟹ [1 2 3 4]
14:31fliebelchouser: I do that… I think. I have a seq of transients, and when I do persistent! on one item, it works. When I do it to all in a map I get an error.
14:31AWizzArdfliebel: do you have a 'doall' around your map?
14:32chouserhmmm
14:32fliebelAWizzArd: I'm on the repl, so they're going to get realized anyway.
14:32chouseractually, it might have to be around inner map's
14:34chouser,(last (map persistent! (map-indexed #(conj! %2 %1) (map transient (repeat 100 [])))))
14:34clojurebot[99]
14:34chouserhm, or maybe not
14:34chouser,(last (map persistent! (map-indexed #(conj! %2 %1) (repeat 100 (transient [])))))
14:34clojurebotjava.lang.IllegalAccessError: Transient used after persistent! call
14:35fliebelchouser: This works: (persistent! (first t)) This doesnt: (doseq [t t] (println (persistent! t)))
14:35chouserfliebel: are you sure they're different transients?
14:36fliebelchouser: Different? t and t is the same thing.
14:36chouser,(let [t (repeat 2 (transient []))] (= (first t) (second t)))
14:36clojurebottrue
14:37chouser,(let [t (map transient (repeat 2 []))] (= (first t) (second t)))
14:37clojurebotfalse
14:38Rayneschouser: One of these days I'm going to replace your comma and ampersand keys while you're in the shower.
14:38fliebelchouser: wait… you are onto something there. If I would add an item to one of those transients, would the other get updated as well?
14:39chouserfliebel: sometimes, yes.
14:39jarpiain,(persistent! (second (reductions conj! (transient []) [1 2 3 4]))
14:39clojurebotEOF while reading
14:39jarpiain,(persistent! (second (reductions conj! (transient []) [1 2 3 4])))
14:39clojurebot[1]
14:39jarpiain,(map persistent! (reductions conj! (transient []) [1 2 3 4]))
14:39clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalAccessError: Transient used after persistent! call>
14:40chouserRaynes: , is clojure whitespace -- I find this a convenient coincidence
14:40chousernot to mention a hard habit to break. :-)
14:40fugueIs there any way to pass system properties while using lein swank ?
14:40fliebelchouser: Woo, changing (repeat 128 (transient {})) into (repeatedly 128 #(transient {})) solved the problem :P
14:41chouserfliebel: :-) there you go
14:41Rayneschouser: Understandable. Fortunately, outside of #clojure, sexpbot responds to ,.
14:41chouserRaynes: have you considered ,, ?
14:41chouserhm, nm
14:41RaynesEverybody hates two character prefixes.
14:41chouser,,:already-taken
14:41clojurebot:already-taken
14:42RaynesGood prefixes are hard to find these days. ;)
14:42chouserwhat else has sexpbot used? -> and now & ?
14:43Raynes-> "still works"
14:43sexpbot⟹ "still works"
14:43chouserah, cool.
14:44RaynesI added & because, as I mentioned before, everybody hates two character prefixes.
14:45fliebelwoot, using transients cut my map-hammer-time in half :)
14:47fliebelbut I'm still limited by the speed the one core I'm using :(
14:49ubiifliebel: one core, why?
14:50fliebelubii: because I haven't figured out how to use the other one yet.
14:51ubiifliebel: dumb question, is that due to how you coded things or due to your OS?
14:51ariejanHello. I'm new. My name is Ariejan. Any one worked with aleph here? How can I print the user-agent string?
14:52fliebelubii: because of how I coded things.
14:53fliebelariejan: I don't know, but I think you'll find the answer in Ring.
14:53alpheuschouser: Not sure if I'm getting what you're showing me, but in (defn f [] (f)) the call to f is ultimately an arg to fn*
14:54chouseralpheus: yes. and f is defined by (fn f ...), which is shadowing the outer (def f ...)
14:54ubiifliebel: ah, ok
14:54alpheusok, that makes sense
14:55jarpiainhmm isn't the recursive call in (def f (fn [] (f))) also compiled to this.invoke() ?
14:55chouseralpheus: so, could do (declare f) (def f (fn [...] ... (f ...)))
14:55jarpiainwith or without previous declare
14:56chouserforcing that inner f to refer to a var instead of a local
14:58alpheusI see. I'll have to think about that for a while.
14:59chouserah, and formulated that way still works fine in 1.3
15:01alpheusNaturally, I'm starting to wonder what's really going on with recur.
15:02chouserrecur compiles to a goto, I believe
15:03kotarakalpheus: are you the "hanging defmethod" guy?
15:03chouserjarpiain: I don't think the compiler knows f is this in (def f (fn [] ...))
15:03alpheuskotarak: No, I don't think so.
15:03kotarakalpheus: ah. ok. never mind.
15:05alpheusThis is a pretty great channel. But I guess you all knew that already.
15:05jarpiainchouser: right, just checked. The 'f is used to name the generated class but not as a this-label
15:05chouserjarpiain: huh! I didn't realize the name was propogated in at all. interesting.
15:06kotarak(def f (fn f ...))?
15:06jarpiainthat's the only thing the third argument of analyze() is used for
15:06chouserkotarak: no, without the inner name
15:07chouser(class @(def my-name-is-here (fn []))) ;=> user$eval267$my_name_is_here__268
15:07kotarakchouser: I meant with (fn f ...) the function knows itself as f.
15:08chouserkotarak: yes, but even without that the outer def passes the name in such that the generated class includes it. jarpiain knew this, but I'm just learning.
15:15rata_hi all
15:16fliebelhi
15:16kotarakchouser: you didn't know?
15:16kotarako.O
15:17rata_which profiler do you guys use?
15:17hiredman_it's wasn't always the case that defn propagated the name like that
15:17kotarakI was wondering what happens if I have something like (defn foo ...) + somehwere else (let [f (fn foo [] ...) ...) Do I get a clash in class names?
15:18hiredman_no
15:18fliebelrata_: I just toyed with visualVM, but I don't *use* it.
15:19rata_fliebel: ok.. how was it?
15:20fliebelrata_: Like stacktraces.
15:33fliebelIn Python there is glob to mach certain files. What is the best way I can do this in Clojure? file-seq coms closest I think. Should I just do regexes on that and filter?
15:35amalloyfliebel: i haven't looked for a clojure-specific way, but java.io.File has a list(FilenameFilter) method
15:36fliebelamalloy: But that doesn't do recursion I think. that is more like ls | grep
15:37amalloyyeah, and it's kinda gross anyway, i guess
15:41amalloyfliebel: i don't see any better way than file-seq/regex, unless you want to use the shell's globbing
15:43amalloythough it's still going to recurse into directories whose children you know you won't want
15:44amalloyimplementing filtered-file-seq yourself would be a trivial modification of http://bit.ly/bHsvOu
15:44fliebelamalloy: I already figured out the regex.
15:46amalloyyou understand what i meant about recursing into uninteresting subdirs though, right? you can't fix that with just a regex
15:47amalloyif that doesn't matter to you, and it might well not, then go for it
15:47fliebelamalloy: I realize that. I'll think about it.
15:47fliebelamalloy: There are some 2000 files in a sub dir I'd like to avoid.
15:49amalloywell then, time to implement filtered-file-seq :)
15:50fliebelamalloy: Yea… You're right.
15:53chouser(tree-seq #(and (.isDirectory %) (not (re-find ... (.getName %)))) #(.listFiles %) (File. ...))
15:54amalloychouser: no cigar. you need to filter the children, not the branches
15:55chouserhm, I suppose you're right
15:55fliebelbut, how does this work? listFile only returns the files, not the directories, if I'm corect.
15:56amalloyfliebel: you're not correct, though :)
15:57fliebelamalloy: Which part of my assumtion is wrong?
15:57amalloyit returns all the File objects, and directories are Files
15:57fliebelamalloy: java.io is strange...
15:57amalloyhttp://download.oracle.com/javase/1.4.2/docs/api/java/io/File.html#listFiles%28%29
15:58amalloyyes, it's a dreadful mess
15:59ubiiI still can't get use to seeing oracle associated with java, instead of sun
16:01amalloyfliebel: http://download.oracle.com/javase/1.4.2/docs/api/java/io/File.html#listFiles%28java.io.FileFilter%29 could be used to return just the files or just the directories
16:02fliebelamalloy: Hav you seen how I am to create a FileFilter?
16:03amalloyfliebel: well, if you were going to do it i'd use reify. but FileFilter is a hack around java's lack of HOFs like (filter)
16:03fliebelamalloy: I was also thinking reify.
16:06chouseramalloy: one of many
16:06amalloyfliebel: (seq (-> (java.io.File. ".") (.listFiles (reify java.io.FileFilter (accept [this f] (.isDirectory f)))))) is how you could do it with reify
16:06ohpauleezubii: me too
16:06ohpauleezevery time I see the docs, I freak out a little
16:07fliebelamalloy: I know :) (thanks to chouser)
16:08clojurebotWhy are you asking *him*
16:08ubiihaving been a Sun sysadmin, in my previous life, I find it painful to now see Oracle pasted on everything :(
16:09technomancyit would be good to make it easier to navigate between the wiki on dev.clojure.org and the ticket tracker
16:09technomancyI only found http://dev.clojure.org/jira by some random poking around
16:18fliebelwhich of all those 508 functions does the opposite of filter? I can do use not of course but I know it's there.
16:19chouserrmove
16:19chouserremove
16:19fliebelyay!
16:19chouserfliebel: http://clojuredocs.org/clojure_core/clojure.core/filter
16:20kotarak(filter (complement your-predicate) ...) for another road to Rome
16:20fliebelooh
16:22ubiiwait, clojuredocs is written using Rails, what happened to eating our own dog food? :)
16:23technomancyubii: at least it's not closed-source anymore =\
16:23ubiitechnomancy: what was it before?
16:23ubiimeant to say, what was it using before?
16:23technomancyI guess they had "unique scalability requirements".
16:23technomancyno, I mean it's always been rails, but at least now it's open to community improvement
16:23ubiiah
16:24ubiiwait, rails can scale, when did that happen? :)
16:25chouserI'm so happy to have a site like that -- if having it written with rails is what it took, so be it.
16:25ubiisorry, being a ruby guy, I have to bash a bit on rails
16:26ubiiof course, even though I do ruby, I haven't touched rails in years
16:26ubiichouser: I agree, the tools used to build it are much less import than the fact that it exists
16:27ubiiI was just being a smarta$$, since I knew technomancy was a fellow ruby convert
16:28chouserI've done a fair amount with ruby myself, though only one (attempted) rails projects.
16:28ubiiI will shut up now and get back to reading JoC :)
16:29technomancyI was just a little put off by the way they brushed off compojure as "not ready" without providing constructive criticism. I think it's good that the site exists.
16:30chouserIf I had the time to contribute to a such a project, their choice of tools would matter to me more, I'm sure.
16:35ubiiI really should be working on implementing the necessary reporting capabilities for the Sinatra app that I wrote last week, which does email campaign monitoring
16:38LauJensenubii: Only slightly more difficult than doing the same using ring and Moustache
16:38LauJensenAt least for me :)
16:38bobo_im starting to prefer moustache aswell
16:38mabesubii: yeah, it wouldn't be too hard unless you are relying on a lot of gems (e.g. for openauth)
16:38bobo_noticed that compojure 0.5.x was released recently though, dont know what changed
16:39ubiiLauJensen: actually, someone else suggested that combo, so I will look at that as well
16:40bobo_and dont forget to look at enlive if you want templating!
16:41LauJensenYea, Moustache/Enlive is a winning combo
16:42ubiithx, I will check them both out
16:43ubiiunfortunately, due to time constraints, I will need to finish up the reporting capability, using Sinatra
16:43ubiithen I can go back and look at porting it
16:43RaynesThe only thing keeping me from really liking Compojure is the furious lack of documentation.
16:43ubiistill learning Clojure, so it is probably premature to try and port it right now
16:44apgwozisn't compojure more or less just a url mapping framework at this point? ring handles pretty much everything else as far as i can tell.
16:44raekit seems so
16:44ubiithen again, I never touched Sinatra before I wrote this app, but at least I knew Ruby
16:44danlarkinI've never heard a lack of something be called furious
16:44apgwoz(well, compojure + hiccup (or something like it) + ring)
16:46drewryou can read compojure's src quicker than an equivalent how-to
16:46rlbCan you create a class instance when the class is stored in a variable, i.e. (def x Integer) (??? x 5)?
16:46rlbnew won't work
16:47rlbI can easily work around it -- mostly just curious.
16:48pjstadig~suddenly
16:48clojurebotCLABANGO!
16:49cemerickdanlarkin: along the lines of "violent agreement", perhaps :-)
16:49cemerickdanlarkin: welcome back to irc ;-)
16:50alpheusvehement apathy
16:50lrennrlb:
16:50mabesrlb: you can use .newInstance.. However, that doesn't seem to work on Integer.. Here is an example:
16:50mabes,(let [x java.util.Date] (.newInstance x))
16:50clojurebot#<Date Tue Nov 02 13:51:49 PDT 2010>
16:50lrenn->(let [c java.lang.String] (.newInstance c))
16:50sexpbotjava.lang.IllegalArgumentException: No matching method found: newInstance
16:50danlarkincemerick: ahoyhoy
16:50_seanc_What is the best way to iterate over a seq and create a new collection with the values from the first? (Does that make sense?)
16:50lrennoddly, that works in my repl.
16:50hiredman_seanc_: you mean map?
16:50cemerickoutlandish asceticism
16:51_seanc_hiredman: I tried map, it gave me an error
16:51kotarak"an error" means....?
16:51_seanc_I cleared the terminal :X
16:51_seanc_let me get it ahain
16:51hiredman_seanc_: well you did it wrong
16:51duncanmwhy is ^int not allowed as a type hint? is it useless to hint that?
16:51_seanc_again*
16:51_seanc_hiredman: that much I've come to expect :D
16:51clojurebothiredman is lazy
16:52kotarak,(map identity [1 2 3])
16:52hiredmanclojurebot: I'll replace you with a very small shell script
16:52clojurebot(1 2 3)
16:52clojurebotclojurescript is Chouser's baby
16:53tonylwhat's up with clojurebot and its random quips? somebody logged in like it?
16:53tonylthey are funny though lol
16:53rata_has anybody used profiler4j?
16:53danlarkintonyl: it's NLP
16:53amalloyclojurebot: clojurescript?
16:53clojurebotclojurescript is Chouser's baby
16:54amalloytonyl: ^^ he just overeagerly matches "regular" chatter as a question directed at his info database
16:54tonylfoo hahaha
16:54tonyli thought it was just for an instant repl in the chat
16:54hiredmanovereagerly?
16:55kotarakrata_: I used jvisualvm with success. But YMMV.
16:56amalloyhiredman: well he piped up with a quote about clojurescript just because your message to him ended with "script"
16:56amalloyclojurebot: script
16:56_seanc_hiredman: where did I go wrong http://pastie.org/1267706
16:56hiredmanamalloy: saw your link to the horrible code you wrote to limit the number of threads running a task, I still don't see why you just don't use a threadpool
16:57hiredman_seanc_: doseq returns nil
16:57hiredmanmap is lazy
16:57amalloyhiredman: yes, i agree it's pretty horrible
16:57hiredmanso do it right
16:57hiredmanI pasted you a link to the pool docs
16:57_seanc_I guess that's where I'm lost. The tutorial on SQL (wikibooks) has them using doseq
16:58amalloyhiredman: i'm trying to improve thread-safety in the current code without changing its semantics
16:59hiredmanif the semantics are garbage they should be changed
17:00amalloyhiredman: fixedthreadpool queues up pending requests; currently sexpbot discards them. i don't see any particular reason to prefer queueing them instead of discarding them
17:01hiredmanyou can easily write a custom threadpool
17:02hiredmanyou wouldn't even need a custom threadpool
17:02amalloyhm, okay, i'm looking at ThreadPoolExecutor
17:03_seanc_hiredman: since map iterates over the coll, how do you access the current value within the function?
17:03_seanc_Ah ha! I figured it out
17:03tonyl_seanc_ is the parameter passed to the fn
17:03_seanc_it's the combination of #(%) - right?
17:03tonylor (fn [parameter] parameter)
17:04_seanc_granted, while it works, I still don't fully understand #
17:04_seanc_tonyl: cool! That's awesome thanks for the tip
17:04amalloy_seanc_: then i suggest not using #(...) yet. it's really shorthand for (fn [...] ...)
17:05_seanc_amalloy: oh, well that's a really straightforward explanation. You need to write a blog so I can read it :D
17:05bobo_you can also just use defn and create a function if you want to name it.
17:05amalloyhaha, maybe i'll start collaborating with Raynes, since I Don't Blog either :P
17:06_seanc_I try to look all of this stuff up ClojureDocs, but for instance they don't have # on there
17:06amalloy_seanc_: # isn't limited to this usage - it's not a function, so to speak
17:07amalloy# is a trigger character that the reader treats specially depending on what character is next
17:08amalloyfor example:
17:08amalloy&(map class [#(inc %) #{1} #".*"])
17:08sexpbot⟹ (net.licenser.sandbox.box5691$eval5848$fn__5849 clojure.lang.PersistentHashSet java.util.regex.Pattern)
17:09_seanc_Ah, very cool
17:11bobo_http://clojure.org/reader has more info on it
17:11_seanc_Just arrived there!
17:11_seanc_thanks bobo_
17:11bobo_:-)
17:13amalloyah right, #' and #_. i knew i'd forgotten a couple
17:14Raynesamalloy: I really don't. Now that the conj is over, I doubt I'll find things worthy to blog about. I don't make many interesting discoveries on my own.
17:14amalloyRaynes: i know. i don't either. but i found your blog title very amusing
17:15ubiidamn, I will be happy when the elections will be over tonight, as my phone has been ringing non-stop for days, with automated campaign messages from various candidates and election pollers calling
17:16ubiithat is the disadvantage of working from home
17:18technomancyubii: disadvantage of having a land-line more like =)
17:18ubiitrue, the only reason I have it is associated with my DSL
17:19pjstadigi just never answer my phone when the caller-id is an 800 number
17:19pjstadigor "Unavailable"
17:19ubiiit is supposed to be a freaking business line, but somehow it is still listed as a residential line, which is why everyone and the brother calls it
17:20ubiiyet, I can't get it added to the do not call list, because it is a business line
17:20ubiigo figure
17:20ubiidamn, catch 22
17:20ubiisorry, didn't mean to vent, just tired of hearing that damn phone ring
17:21amalloyubii: get a call-screening device? or google voice?
17:21bobo_or just mute the phone
17:22ubiiI should, but that would make too much sense :)
17:22bobo_or move to sweden and get a dsl connection without a phone!
17:24pjstadigor vote for people who will change campaign laws
17:24NafaiI'm so glad I don't have a landline
17:29LauJensenGood night to everybody in #landline
17:42fliebelDang! The Python version of my parser does in seconds what takes my Clojure version minutes…
17:44RaynesMake it faster.
17:44fliebelRaynes: I've been doing that all day :(
17:44apgwozwhat does the parser do?
17:44apgwozerr, what does it parse
17:45fliebelapgwoz: Read a bunch of NBT files and plot frequencies.
17:46RaynesStop. Hammock time.
17:46fliebel?
17:47RaynesI keep forgetting that not everybody was at the Conj.
17:47RaynesRich talked about 'hammock' time in his second talk at the Conj. It's become a bit of a meme.
17:48danlarkinhttp://p.hagelb.org/hammock.jpg
17:48fliebeldanlarkin: Oh, well, that explains it all...
17:49raekis it only in my language a hammock is one of these? http://randomfunnypicture.com/wp2/wp-content/uploads/2010/04/meanwhile-in-finland.jpg
17:49raek(modulo the snow and the finnish guy)
17:49fliebelI guess (not= Hammock Hammer)?
17:50fliebelRaynes: But what did you mean to say?
17:51RaynesIt was actually completely random and entirely unrelated to what you were saying before it.
17:51RaynesLike a clojurebot message.
17:52fliebelRaynes: Okay :( I was hoping you had some smart insight on how Python can outperform Clojure.
17:53apgwozRaynes: in all actuality, i took your comment to mean, "fliebel should stop and think about the problem for the night. the solution will come to him"
17:53apgwozwhich relates back to rich's talk
17:53apgwoz:)
17:53Raynesapgwoz: Right. We'll go with that. fliebel: ^ That's what I meant to say.
17:53apgwozhaha
17:54fliebelokay, good night all ;)
17:54RaynesGood night. May the Rich be with you.
17:55fliebelMaybe tomorrow someone can explain me how to profile and improve my code.
17:56amalloyraek: i think we'd call that a swing bench or something silly like that, but it's close to a hammock. hammocks are tradionally more like http://www.hammocks.com/hammocks/fabric-hammocks/textalinehammocknavystripe.cfm
17:56raekah, a "hängmatta"
17:59apgwozRaynes: woah, you have an affect on people :)
17:59RaynesI do?
17:59apgwozwell, fliebel left.
18:00apgwozpresumably to go think about the problem.
18:03Rayneshiredman: ping
18:05Rayneshiredman: I'm terribly sorry that I am not the perfect coder, but I *do* accept patches and advice, but I don't respond well to flat out insults.
18:06RaynesIf you'd like to talk about anything, assuming you get these messages, let me know. I'd love to discuss whatever reason you have for despising me so, and I'd certainly like to resolve any issues.
18:12danlarkinhe has you on ignore, just fyi
18:12RaynesI figured.
18:12RaynesAny clue as to why?
18:13RaynesI mean, he's welcome rub me in the dirt all he wants, but surely he isn't going to insult everybody with an association to sexpbot now. That would be unfortunate. :\
18:14RaynesI suppose this isn't the place to discuss such things though. I'll leave it be.
18:18angermanhow do i have to understand (.instanceMember Classname args*)?
18:18angermanahh so that's a constructor.
18:18angermanor not? ... yikes
18:19duncanmhmm, what's an idiomatic way to remove some entries out of a map based on its val?
18:20duncanm(into {} (remove #(pred? (val %)) my-map)) ?
18:20angermanfilte?
18:20clojurebot,(let [testar (fn [x y] (cond (= (reduce + (filter odd? (range 0 x))) y) (str y " is a")) )] (testar 11 25))
18:20angermanfilter?
18:20clojurebotfilter is not map
18:20gfrlog,(deref (future (+ 7 8)))
18:20clojurebot15
18:22gfrlogam disappointed that partition can drop elements off the end of your list
18:22gfrlog,(partition 3 (range 5))
18:22clojurebot((0 1 2))
18:22scgilardigfrlog, see partition-all
18:22gfrlogawesome, thanks :)
18:22scgilardiangerman: see http://stackoverflow.com/questions/2753874/how-to-filter-a-persistent-map-in-clojure
18:23amalloy&(.length "10")
18:23amalloy&(.add (ArrayList.) 10)
18:23sexpbot⟹ 2
18:23sexpbotjava.lang.IllegalArgumentException: Unable to resolve classname: ArrayList
18:23amalloy&(.add (java.util.ArrayList.) 10)
18:23sexpbot⟹ true
18:23amalloyangerman: ^^
18:23raekangerman: (.method object arg1 arg2) is java object.method(arg1, arg2);
18:24raekangerman: (.method SomeClass arg1 arg2) is java SomeClass.method(arg1, arg2);
18:25angermanraek: so a class can have nonstatic methods. hmm...
18:25scgilardiwhoops, http://stackoverflow.com/questions/2753874/how-to-filter-a-persistent-map-in-clojure was for duncanm
18:25raek"(.instanceMember Classname args*)" does not make much sense, since instances (objects) and classes are different things
18:25amalloyangerman: do you have java experience?
18:25angermanscgilardi: wasn't bad for me to review that either :D
18:26raekangerman: static=class, instance=object
18:26angermanraek: but that's precicely how it's on the clojure.org/java_interop page stands
18:26angermanraek: so my thinking was right. But the confidence was too low.
18:26amalloyangerman: poorly written, then
18:27angermanto me the 1st 3rd and 4th line make sense
18:27raekyes, how unfortunate...
18:27angermanthe 2nd one doesn't.
18:27amalloy&Boolean/TRUE
18:27amalloy&(. Boolean TRUE)
18:27sexpbot⟹ true
18:27sexpbotjava.lang.IllegalArgumentException: No matching method found: TRUE
18:28amalloyugh, i can never remember how to get at static fields using . notation
18:29raekangerman: yes, your thinking was right
18:29rata_amalloy: is it that possible? I thought / was the way
18:29raekthe / way expands to the dot form
18:30raekbut the / way is considered more ideomatic
18:30amalloy&(macroexpand 'Boolean/TRUE)
18:30sexpbot⟹ Boolean/TRUE
18:30amalloy&(macroexpand '(. Boolean TRUE))
18:30sexpbot⟹ (dot Boolean "TRUE")
18:31amalloyraek: the interup section angerman is talking about seem to suggest that (. Boolean TRUE) should work; do you know what was wrong with my example?
18:32gfrlog(dot toString true)
18:32gfrlog,(dot toString true)
18:32clojurebotjava.lang.Exception: Unable to resolve symbol: dot in this context
18:32raekI think 'dot' is something in the implementation of clj-sandbox
18:33amalloygfrlog: also, booleans are primitives, which don't have a toString method. use (String/valueOf true) instead
18:33gfrlogsilly primitives!
18:33gfrlog,null
18:33clojurebotjava.lang.Exception: Unable to resolve symbol: null in this context
18:33amalloygfrlog: yeah
18:34amalloy&nil
18:34sexpbot⟹ nil
18:34gfrlogis nil null, or is it an object?
18:34amalloyit's null
18:34amalloy&(String/valueOf nil)
18:34sexpbotjava.lang.NullPointerException
18:34amalloyreally?
18:35gfrlog&(println "java.lang.NullPointerException")
18:35sexpbot⟹ java.lang.NullPointerException nil
18:35gfrlogdang it lets you tell the differenc
18:35raekamalloy: (. Boolean TRUE) works in a normal repl
18:35amalloyraek: thanks
18:36Chousukeor just Boolean/True
18:36Chousukeer
18:36ChousukeTRUE
18:37amalloyChousuke: sure, of course that's the "right" way; but i was confused that . didn't work
18:38Chousukeah, right.
18:39wsimpsonwhy is one less right?
18:40gfrlogbecause it is left
18:41gfrlogor more left at least
18:41wsimpsontouche.
18:41Chousukewsimpson: The sugared form is prettier :P
18:42Chousuketherefore better.
18:44kotarakif rich says that one form is to be prefered over this other, this is enough "right" for me.
18:45amalloywsimpson: my suspicion is because String/valueOf makes it look like a first-class function, while (. String valueOf) makes it look like something else
18:46wsimpsonAh. That makes sense.
18:46ChousukeString/valueOf also makes it clear that it's a static field/method
18:47wsimpsonDuly noted.
18:48wsimpsonThanks. :)
18:50zencobrasJust getting starting with clojure and emacs (tough combo, but fun). Anyone willing to answer a couple of questions? I am trying the labrepl exercises, and when I run 'slime-connect', get the following : "Versions differ: nil (slime) vs 20100404 (swank). Continue? (y or n)". The REPL seems to run OK - but how to I resolve this version issue?
18:52arohnerzencobras: add (eval-after-load 'slime '(setq slime-protocol-version 'ignore)) to your .emacs
18:52zencobrasPackage list shows slime 20100404, slime-repl 20100404 and swank-clojure 1.1.0.
18:52zencobrasarohner: thanks!
18:54zencobrasarohner: worked like a charm
18:59rickmodeI keep wanting to know if an object is a single object, or some sort of sequence, but *not* a map. I'm tending to use coll?, and when I control the type of object, I use seq?, but I really want something like c.c/seqable? that doesn't allow nil. Basically I want (at least) non-nil lists, vectors, and ArraySeq's to pass. Perhaps I'm attacking the problem wrong?
18:59arohner,(doc sequential?)
18:59clojurebot"([coll]); Returns true if coll implements Sequential"
19:00arohnerrickmode: does that do it for you?
19:00cemerickrickmode: there's a seqable? in clojure.contrib.core, but it's a fundamentally flawed concept
19:00rickmodecemerick: how so?
19:01raekrickmode: what will you use this function for?
19:01raeka macro?
19:01rickmodearohner: perhaps sequential? is what I want
19:01cemerickrickmode: Because seq is polymorphic beyond what can be representable by the JVM's type system. Protocols will fix this, but there's not yet a Collection protocol or somesuch that would provide a proper seqable? fn that collection implementations could implement.
19:02cemericks/can be/is
19:03rickmoderaek: I'm thinking of things similar to how "The Little Schemer" attacks atoms and lists. Basically I want various functions to all one or more items, and I'd like the caller to pick any sort of sequence. E.g. (foo (list :a :b)), (foo [:a :b])
19:03cemerickrickmode: until then, we're left with things like clojure.contrib.core/sequable?, which is just a bunch of instance? checks essentially.
19:03rickmoderaek: seems wrong somehow to force a particular sort of sequence
19:04raekmaybe you could do a cond with the map? test before the coll? test
19:04rickmoderaek: I don't usually allow either a map or coll, but ya - that works in those cases. Perhaps sequential? is the right forward-compatible beast?
19:06rickmodecemerick: does sequential? cover all cases where an object can behave list-like? (that is, supports first and rest/next)?
19:06cemerickrickmode: no, sequential? tests for (instance? Sequential x). That only includes seqs, vectors, and lists.
19:07rickmodecemerick: what other listy things are there?
19:07cemerickwhich leaves out strings, maps, and java.util.Lists, to name some others that work with first/rest/next
19:07tonyl&(supers Sequential)
19:07sexpbotjava.lang.Exception: Unable to resolve symbol: Sequential in this context
19:08cemerick&(supers clojure.lang.Sequential)
19:08sexpbotjava.lang.NullPointerException
19:08cemerick,(supers clojure.lang.Sequential)
19:08clojurebotnil
19:08cemerickach, not supers
19:08clojurebothttp://haacked.com/images/haacked_com/WindowsLiveWriter/IConfigMapPathIsInaccessibleDueToItsProt_1446B/works-on-my-machine-starburst.png
19:08cemericktonyl: you want "descendents", except it doesn't exist ;-)
19:08rickmodecemerick: so it's OK for clojure-only code, but doesn't generalize. Perhaps it's ok for my cases though. - ya I look at Seqeuential... it's a type-marker.
19:09rickmode(empty interface)
19:09tonylyeah, i was looking in the docs :P
19:09clojurebotHuh?
19:09raekI know I have had the same thought as rickmode about finding something similar to listp and atomp
19:09raekbut for some reason, it has not been a problem for me
19:09rickmoderaek: ya that's why i was wondering if am attacking the problem wrong
19:10raekmaybe I tend to treat one data structure specially in the fn, and leave everything else as-is
19:10raeklike in http://gist.github.com/633049
19:11raekin common lisp, it's mostly black and white. either something is a list or an atom
19:11raekin Clojure, there's lots of data structures
19:11rickmoderaek: your gist makes sense... but what if you want to allow single objects too.. then you hit my scenario.
19:11raekone of the aspects that make it non-lispy
19:12raek,(coll? "foo")
19:12clojurebotfalse
19:12raekyeah...
19:12rickmoderaek: indeed. clojure (correctly) adds sets and maps to the list. It has not (yet) unified all possible sequences though
19:13raekI'm afraid I don't have any good answer
19:13rickmodethe list meaning, the list of fundamental data structures
19:13hiredmancoll? checks to see if it's an ipcollection
19:14hiredmanwhich a string certainly isn't
19:14hiredmanneither are many Collections
19:14raekah,
19:14raek,(coll? (java.util.ArrayList.))
19:14clojurebotfalse
19:14rickmodeI *think* I'm ok with sequential? for these clojure functions (i'm not worried about java interop). I'm hoping callers can do (foo :a) (foo (list :a :b)) (foo [:a :b]) and (fn [& rest] (foo rest))
19:14raeksounds resonable to me
19:15rickmodebut *not* (foo {:a 1, :b 2})
19:16rickmodemakes me think this "one or many" idiom is somehow flawed
19:19amalloyrickmode: why not allow maps? if the caller wants to treat their map as a list of pairs, who are you to stop them?
19:19amalloyif you somehow managed to exclude maps, they could just (foo (seq {:a 1 :b 2}))
19:20rickmodeamalloy: in this particular case, the caller is passing in one or more keywords... a map wouldn't make sense, but just about anything else would. (The keywords are parameter names for form validation like, :first-name, :last-name).
19:21raekrickmode: you wouldn't be using ring.middleware.params?
19:21rickmodeamalloy: I think I'm still getting over my OO/strong-typing hangover. coll? will do the trick, i think. a map will cause a barf on first usage, so that's good enough
19:22amalloyrickmode: it will barf on (foo [[:a 1] [:b 2]]) too, so coll? isn't really helping
19:22rickmoderaek: right. (though I don't feel like using ring.middleware.keyword-params - I'm sticking with (name :first-name) since I have only about 3 usages of name.
19:22raekrickmode: I think it is simpler to let the user pass the single thing in a collection of size 1, unless there is any compelling reason
19:23amalloyyou could do like: (and (coll? x) (not-any? coll? x))
19:23raekI don't like the way wrap-params handles multiple values of the same key
19:24raekI think it should split into two variants: one that always store a single value per key (last one wins) and one that has a vector for each key
19:24Raynesraek: Made any interesting progress on your message parser lately?
19:24rickmoderaek: oh... i'm not doing that. I'm rolling (yet another) form validation system. I'm allowing something like (validator [:password :password2] #(= %1 %2) "passwords don't match")
19:25hiredmansurely you mean (validator [:password :password2] =)
19:25raeklooks very much like something I started to work on once... :)
19:25rickmoderaek: as well as (validator :first-name #(not (str/blank? %) "first name required")
19:26raekRaynes: well, I think the vocabulary is starting to crystallize
19:26raekrickmode: http://gist.github.com/586836
19:26amalloyrickmode: oh. so more like (or (not (coll? x)) (not-any? coll? x))
19:26Raynesraek: Irclj is attention starved. If it doesn't get new code soon, I fear it'll begin gnawing on sexpbot an any other bot it can get it's parentheses around.
19:27Raynesand*
19:27raekrickmode: also http://github.com/Kaali/pour
19:28raekwhich that was a remix of
19:29raekRaynes: you will love the abstractions that are in my mind currently
19:30Raynesraek: :D
19:30rickmoderaek: heh.. ya it's kinda like that... though I'm reading up on monads and it seems like validation... and perhaps the entire response cycle, can be recast / simplified with compossable m-state.. er .. thingies
19:31raekrickmode: I know very little about monads, but I have a hunch that they might be a good fit
19:38rickmoderaek: is your weby stuff in a github project?
19:39raeknot yet
19:39raekthis will eventually be a lib, but I haven't had much time to work on it, unfortunately
19:40Raynesraek: By the way. We have to change the name of Irclj to (apply str (distinct (str "irc" "clj"))). Only difficult thing will be the namespaces. :P
19:44raekI should get some sleep
19:44raekbut I don't wanna
19:44raekClojure is way too fun
19:44raekgn
20:38ymasoryis there a function that makes a seq of n elements by applying the provided function n times and collecting its results?
20:38ymasoryi can do this with a comprehension or map but i would need a range too
20:39tonyl,(range 10)
20:39clojurebot(0 1 2 3 4 5 6 7 8 9)
20:40ymasorytonyl: hm?
20:42amalloy&(doc repeatedly)
20:42sexpbot⟹ "([f] [n f]); Takes a function of no args, presumably with side effects, and returns an infinite (or length n if supplied) lazy sequence of calls to it"
20:42amalloyymasory: ^^
20:42amalloy&(repeatedly 10 rand)
20:42sexpbot⟹ (0.23348923774335106 0.8732098324061308 0.582779226332408 0.9926034362933805 0.9522604963670783 0.5401583818751448 0.3418314042183209 0.15130219536490885 0.5458508576119281 0.241182907854135)
20:43amalloythat what you were looking for?
20:43ymasoryamalloy: thank you yes
21:44fbru02hey guys ... so Leiningen uses ant to run right ?
21:46amalloyfbru02: maven
21:47fbru02amalloy: did this change recenly ? from the doc For the actual task execution cycles it uses Ant under the covers via Lancet. ????
21:49fbru02brb
21:49amalloyokay. i wouldn't be astonished to find out that that's true, i guess, but i thought it used maven for everything. if technomancy were around i'd say ask him
21:50fbru02amalloy: thanks !
21:51tonylI thought it uses maven for dependencies and for alternative building with a pom file instead of project.clj
21:51tonylbut i've been out of the leiningen for a while
21:52amalloytonyl: it looks like that's true. lein and cake both use ant for actual compilation
22:24gfrlog,(apply * (range 500))
22:24clojurebot0
22:25amalloy&(apply * (range 1 500))
22:25tonyl&(apply * (range 1 500))
22:25sexpbot⟹ 244027365198222013740247757084609385250714868560638568438482717677169074630776399521099289500440656372602723295429640716832675744415635440096157041031865857095581514387866120754592171817254085834909576484982545268861134034654153892212560462090528843775757893150955429972698873556207528854806765473079... http://gist.github.com/660719
22:25sexpbot⟹ 244027365198222013740247757084609385250714868560638568438482717677169074630776399521099289500440656372602723295429640716832675744415635440096157041031865857095581514387866120754592171817254085834909576484982545268861134034654153892212560462090528843775757893150955429972698873556207528854806765473079... http://gist.github.com/660718
22:25tonyllol
22:25amalloylol
22:25tonylthat was weird
22:25gfrlogthat was weird
22:26gfrlogI was remarking to myself how you both came up with the number 500....
22:26amalloynotice the gists came out of order?
22:27tonylyeah
22:27tonyllag
22:27amalloyyeah, presumably latency on github's end
22:29gfrlogpresumably the designers of github forgot to include the library that determines what order numbers come in
22:29amalloy#include <reality.h>?
22:30gfrlogimport org.apache.integers.comparison.*;
22:30tonyli think it's built in ruby
22:31gfrlog,(ruby-eval "660718.is_less_than?(660719)")
22:31clojurebotjava.lang.Exception: Unable to resolve symbol: ruby-eval in this context
22:31gfrlogunacceptable
22:31ymasorywhere does autonomous code go in clojure considering agents don't have a loop? in a java thread?
22:32amalloyymasory: autonomous? do you mean asynchronous, maybe?
22:33ymasoryamalloy: autonomous. as in autonomous threads/actors
22:33ymasoryagents you pass functions to from the current thread of control. they don't have an independent thread of control, from what i understand
22:33ymasoryor my bad, yes they do, to run the function
22:34ymasoryi guess i could just pass the agent the looping function (i.e. the "run" method of a java thread)
22:34amalloyymasory: every clojure function is a java object that implements Runnable. if you want, you can pass them to a thread
22:34amalloy&(supers (class (fn [])))
22:34sexpbot⟹ #{java.util.Comparator java.io.Serializable clojure.lang.IObj clojure.lang.IMeta java.util.concurrent.Callable java.lang.Object clojure.lang.AFn clojure.lang.AFunction java.lang.Runnable clojure.lang.Fn clojure.lang.IFn}
22:35ymasoryamalloy: pass them to a thread or to an agent?
22:35amalloyeither will take them; what you should do depends on your goal
22:36ymasorywhat is the guarantee i get from an agent over the same code running in a thread?
22:38amalloyagents are basically an object that queues up actions, and passes them to a thread one at a time
22:38amalloyif you create ten threads and start them all, they run in parallel; if you create an agent and send it ten functions, they run in series
22:40ymasoryso the main benefit of agents is that they manage the thread pool for me?
22:40hiredmanagents provide an identity for a series of values over time
22:40amalloythey also have a value
22:40hiredmanjust like refs and atoms
22:41ymasoryright, i guess this is mind-shock for me trying to integrate threads and value-holders into one useful entity
22:41amalloyright. if you just want threads, use clojure futures, and/or java threadpools
22:42tonylis there a clojure construct for threadpools?
22:42cemericktonyl: threadpools are a fundamentally hosty concept
22:42amalloybut to perform a series of actions that are conceptually related and need to share state, agents are perfect
22:42tonyleven for the jvm?
22:42cemerickof course
22:43cemericksee java.util.concurrent
22:43hiredmanwell the jvm is the host
22:43cemerick.NET/CLR has something equivalent
22:44tonylok
22:44tonyli guess i need to learn more about the parallel concepts than just the summaries
22:44tonylgood, thanks
22:44cemerickand then Clojure hosted on some platform that has no threadpool abstraction (probably javascript, for example) just won't be able to support e.g. futures
22:45tonylgot it
22:46ymasoryare agents supposed to fall off like java threads, or is it safe to terminate them directly?
22:46amalloyymasory: fall off?
22:47cemerickymasory: agents are lightweight reference types whose values change asynchronously *via* threads
22:47cemerickso talking about "terminating" them doesn't really make sense
22:47ymasorycemerick: well in my case i'm passing them a looping function, like you would the run function in a java thread
22:48ymasoryi guess i'm not supposed to do that
22:48cemerickymasory: you mean a fn that never returns?
22:48amalloyymasory: yeah, that's covered in Agent Abuse 101 :)
22:49ymasoryyeah it's a total abuse of an actor too (coming from a scala background here)
22:49amalloyit sounds like you want a direct analog to java threads
22:49amalloyin clojure that's a future, not an agent
22:49cemerickymasory: just a future will do fine
22:50amalloyymasory: the idea with sending agents functions is that they take the function's return value and store it as their new state
22:51amalloyif the function never returns, that is a huge warning signal that you shouldn't use agents; for one thing, all agents share a limited threadpool, and you're monopolizing one of their threads
22:51ymasoryoh i see. instead of an actor sending back a reply
22:51amalloyymasory: maybe. i don't have any real background in scala or erlang
22:53hiredmanyou can use send or send-off inside an agent to loop
22:54ymasoryhiredman: send a message to yourself?
22:54hiredmanit's not a message
22:54hiredmanit's a function
22:54hiredmanbut yes
22:54ymasoryah
22:55cemerickymasory: *agent* is bound to the current agent
22:55ymasoryvery nice
22:56ymasoryso i think the last part of this puzzle is figuring out how i can schedule a function to be sent to an agent in the future
22:56ymasorythat what a future is?
22:57hiredmansend or send-off is scheduling an action to be run in the future
22:57cemerickA future simply runs some code asynchronously, retaining the result, and blocking on derefs until that value is available.
22:58ymasoryhiredman: i meant how can i delay the send call
22:58hiredmanwhy?
22:58clojurebotwhy not?
22:58hiredmanclojurebot: buzz off
22:58clojurebotTitim gan éirí ort.
22:58ymasoryhiredman: because it's a modeling project, the model only allows a function every so often
22:59cemerick,(print "I can't do that, Dave.")
22:59clojurebotI can't do that, Dave.
22:59amalloyymasory: (future (Thread/sleep 5000) (inc 1))
22:59hiredmanymasory: use a scheduledthreadpool
23:00cemerickwe should be able to get parameterization of threadpools into send, send-off, and future for the 1.3.0 cycle
23:00tonylwhat is the meta :once true for?
23:00ymasory&(future (Thread/sleep 5000) (println "hi!"))
23:00sexpbot⟹ #<core$future_call$reify__5500@f84033: :pending>
23:01hiredmancemerick: has rich indicated interest in that?
23:02amalloy&@(future (Thread/sleep 5000) (inc 1))
23:02sexpbot⟹ 2
23:03cemerickhiredman: yes, indicated that is was a semi-safe bet for "release.next" just prior to the 1.2.0 release IIRC
23:03cemericks/is/it
23:04tonylis the future object just a reified object done on the fly?
23:05cemerickfuture is a macro that creates an anonymous fn that is run on a dedicated threadpool
23:06tonyli meant on future-call
23:06amalloy&(macroexpand '(future (Thread/sleep 5000) (inc 1)))
23:06sexpbot⟹ (clojure.core/future-call (fn* [] (dot Thread "sleep" 5000) (inc 1)))
23:07cemericktonyl: future-call does that dispatch of any fn, returning a java.util.concurrent.Future that also happens to implement IDeref
23:08hiredmanI had a patch once that, if I recall, let you pass in something on agent creation (it was something out of Agent.java that you could proxy if you wanted to) with the idea of being able to create agents that would have their actions run on the EDT
23:08hiredmanthat did not go over well
23:09hiredmanmaybe I should have just offered the patch without mentioning my envisioned use
23:09cemerickyeah; IIRC, Rich said he'd be looking to parameterize the send itself
23:09hiredmanoh
23:09hiredmaninteresting
23:10cemerickMy general impression is that there are deeper rearchitecting that are on the table though…which is why I never offered up a patch. ;-)
23:11hiredmanI must say I never use agents though
23:20ymasoryhiredman: what do you use?
23:25amalloyymasory: whatever tool is suitable for the job, i imagine
23:26amalloyagents sound deceptively useful, because they incorporate both mutability and concurrency, which are tricky problems in general
23:26amalloybut most of the time, you want something else
23:26hiredmanlots of futures and promises
23:27ymasoryi guess i was perfectly happy with actors
23:34cemerickThere's no reason to generalize about which construct is better than another; they all have their uses for different types of problems.
23:45amalloycemerick, ymasory is right: i use a fork to eat everything because it's just the best eating utensil. sometimes soup is a little tricky, and i wish campbells would fix that bug, but otherwise i'm very happy with my fork
23:46cemerickheh
23:46ymasoryall i said was that i was happy. but i guess happiness is an offensive idea in a developer's life :)
23:47cemerickymasory: don't worry, I'm sure amalloy was sending nothing but <3 ;-)
23:47ymasoryyeah he's the man
23:49Raynesamalloy has magic in him. Magic, I say.
23:49amalloyRaynes: shhhhh, you'll let all the magic smoke out