#clojure logs

2011-11-26

00:00amalloylonstein: subvec patch is at http://dev.clojure.org/jira/browse/CLJS-107 - feel free to upvote it if you're excited, although i don't know if anyone on /core pays attention to upvotes
00:04technomancyvoting is for democracies
00:10brehautfor an actual democracy though
00:12amalloytechnomancy: btw, i haven't gotten an email from jira about creating this issue. i'm starting to wonder if maybe i didn't actually create it
00:13technomancybetter comment on it just to make sure you didn't imagine it!
00:20amalloytoo risky. if i didn't get a confirmation of that comment i'd be stuck forever
01:56accelis there any efforts to write a mathematica clone (i.e. symbolic mathematics) fully insdie of clojure?
01:56accelless incanter (numerical)
01:56accelmore symbolic
02:28ischyrushow does one check if a value is an atom?
02:32R4p70rThe ActionListener code here: http://clojure.org/jvm_hosted looks a bit verbose. Since there’s only one addActionListener() overload defined to take an ActionListener with one method. Can we simplify this somehow by not writing the interface and method name? Perhaps with some helper code?
03:53G0SUBPhotos from Clojure/conj 2011 are here - http://www.flickr.com/photos/ghoseb/sets/72157628155919755/
04:46Raynes&(type (atom 0))
04:46lazybot⇒ clojure.lang.Atom
04:46Raynes&(instance? clojure.lang.Atom (atom 0))
04:46lazybot⇒ true
04:46Raynesischyrus: ^
05:20alexbaranoskywhere can I find a 1.3 compatible library with macrolet in it?
05:37alexbaranoskyI've been experimenting with using the let family of macros for scoping, rather than defn- /def ^{:private true} -- anyone have any opinions on this? I think it is a much nicer way to show visually the dependencies between various functions
08:19MrHusHi I have a question regarding agents. I've got an agent that calls itself every one second. To create a loop. However since I've put the function inside a defrecord and made the method "live" a protocol in Actor. It does't work anymore. Here's what I've got: http://pastebin.com/3bW1XAM5
08:36BahmanHi all!
08:37BahmanDoes 'nil?' returns TRUE for Java 'null' values?
08:53Bahman,({:a 1, :b 2, :c 3} (symbol ":c"))
08:54clojurebotnil
08:54Bahman,(symbol ":c")
08:54clojurebot:c
08:54BahmanWould anyone please explain this to me?
08:56RaynesBahman: A symbol is not a keyword.
08:56Raynes&(type :c)
08:56lazybot⇒ clojure.lang.Keyword
08:56clojurebotflatten |is| rarely the right answer. What if your "base type" is a list
08:56Raynes&(type (symbol ":c"))
08:56lazybot⇒ clojure.lang.Symbol
08:57BahmanRaynes: I see. So is it possible to get a value from a hash map using a string?
08:58RaynesSure.
08:58Raynes&({:a 1, :b 2} (keyword "c")
08:58lazybotjava.lang.RuntimeException: EOF while reading, starting at line 1
08:58Raynes&({:a 1, :b 2} (keyword "c"))
08:58lazybot⇒ nil
08:58RaynesDuh.
08:58Raynes&({:a 1, :b 2} (keyword "a"))
08:58lazybot⇒ 1
08:58RaynesOr, if your string is a string representation of a keyword (like your example)...
08:59Raynes&({:a 1, :b 2} (read-string ":a"))
08:59lazybot⇒ 1
08:59BahmanThank you Raynes.
09:00Raynes&(-> ":a" (subs 1) keyword) ; another option for getting a keyword from a keywordy string.
09:00lazybot⇒ :a
10:33goodieboyi'm trying to decide on the interface of a dsl i'm playing with. I'm torn between using the hiccup/envlive approach (vectors, keywords) or using normal function calls.
10:34goodieboyI like the envlive approach because the syntax can be much shorter: [:or [:< 10] [:= "test"]] compared to (any-of (lt 10) (exactly "test"))
10:36goodieboyThe normal function approach is simple to implement, but i have to be careful with naming. Anyone have a feeling on which style to use?
10:39RaynesI think I'd encourage functions in this case.
10:39RaynesYou can always add the vector stuff on top of that later.
10:42goodieboyRaynes: Good point, so build a solid, function-based library then something on top, if desired.
10:43RaynesThat's generally the way to go in most situation.
10:43Raynessituations*
10:43goodieboymakes sense
10:56marcuslI would like to get started w/ Clojure. Which one should I read: "Programming Clojure" or "Joy of Clojure"?
10:57_ulisesmarcusl: read "joy of" once you're already up and running w/clojure I'd say
10:58marcuslWhat about the other one?
10:58_ulisesI read that one as a first and it was ok
10:58_ulisesok as in, it is a good first start
10:58_ulisesI've only read those two clojure books so I cannot compare to any other book though :)
10:58marcuslok, thank you.
10:59_ulisessure
12:07_ulisesquick question, I'm trying to bind to a symbol foo with a function so that I can test several implementations of foo with (binding [foo foo-v-1] (run-tests)) however clojure 1.3 is complaining. I have (declare foo) at the top of the file and I'm wondering whether I should replace (declare ...) with (def ^{:dynamic true} ...)?
12:07_ulisesalrenatives are of course welcome
12:07_ulisesalternatives even
12:12raek_ulises: with-redefs
12:12_ulisesthanks
12:13_ulisesam I right to think that dot are not allowed in symbol names?
12:14_uliseswell, I mean, compilation fails if I have foo-0.2 so ...
12:29raek_ulises: yes, dots are reserved
12:29_ulisesthanks again
12:34_ulisesdoes lein test work with clojure 1.3?
12:34kij_ulises: works fine here
12:35kij_ulises: but my usage is not that complicated.
12:35_ulisesmine is the simplest on earth too :/
12:35_ulisessingle test, etc.
12:35_ulisesI suspect difftest is the culprit
12:35_ulisesso I'll rephrase, does difftest work with clojure 1.3? :)
12:36kij;)
12:38_uliseshum, it's trying to load contrib stuff (Could not locate clojure/contrib/str_utils2__init.class or clojure/contrib/str_utils2.clj)
13:24kijIs there an nailgun-client for vimclojure 2.3, or is 2.2 fine ?
13:24Raynesdifftest should be fine.
13:24Rayneskij: What version of difftest do you have?
13:25RaynesVersion 1.3.5 is the newest and is totally contrib free.
13:29kijRaynes: Sorry, my reply was to the "lein test" question.
13:29Rayneskij: Right, I actually meant to direct that at _ulises
13:29_ulisesRaynes: probably have an old version, thanks
13:30Raynes_ulises: If you've got it installed as a lein plugin, look at ~/.lein/plugins
13:30RaynesIt'll be listed there with the version in the name.
13:30_ulisesanother question while we're at it, can one have different :pre and :post conditions for different arities of a function?
13:32_ulisesalong the lines of (defn foo ({:pre ...} [p] ...) ({:pre ...} [p1 p2] ...) ... )
13:50bobhopehello clojuristas
13:50bobhopeI'm having issues with lein and core.logic
13:50bobhopeI added core.logic's clojars repo to my project.clj
13:50bobhopeand I ran "lein deps"
13:51bobhopebut when I open the repl and do (use 'core.logic), it fails saying it couldn't find it
13:56duck1123it's clojure.core.logic
14:36djh__I'm having trouble trying to download .JPG files using my clojure code, the images I download don't seem to be readable/corrupted
14:37djh__I initially started with slurp -> spit
14:37djh__that downloaded the file (as such) but the files aren't readable by any image application
14:38djh__any ideas how I can accurately download an image from the web and store it locally?
14:53tomojdjh__: https://gist.github.com/f11bb40e7bd951dbd77a looks like this works
14:55tomojslurp/spit goes through string encoding/decoding which is screwing up the image data
14:55Raynesdjh__: (io/copy (io/input-stream "http://raynes.me/hfiles/chocolat.png&quot;) (io/file "local.png"))
14:55RaynesYou wouldn't dream of using slurp and spit for this anyways.
14:55tomojis it needed to close the input-stream? wasn't sure
14:56djh__oh man
14:56djh__thanks to you both
14:56djh__seriously
14:56RaynesYes, you should close it.
14:56djh__i've spent hours searching for this stuff
14:57RaynesPsh. I > any search engine.
14:57tomojbut with io/file it must close the output-stream on its own?
14:57Raynestomoj: Right.
14:58djh__i was under the assumption (with-open) closes the file at the end
14:59tomojyeah, I wasn't sure whether you needed a with-open with copy
15:24quotemstrIs it possible to write native-looking OS X programs in Clojure?
15:31kijquotemstr: there should be some qt/java bindings. Might be a try worth.
15:32rcg1there is http://qt-jambi.org/
15:33rcg1and afaik some guys try to port swt to qt on basis of qt-jambi
15:34rcg1btw. i dunno if the stock swt has native OS X look right away
15:35rcg1so you might even give swt a try http://eclipse.org/swt/
15:36rcg1there's also a short "hello world" written in clojure and swt http://kevinoncode.blogspot.com/2009/01/creating-clojure-gui-application-with.html
15:37rcg1which also has some helpful notes for running it on a mac
15:38quotemstrCool, thanks.
15:51quotemstrHrm. Swing seems to work well enough.
16:54devn"If Prolog is the Answer, What is the Question? or What it Takes to Support AI Programming Paradigms" Daniel G. Bobrow, 1985 -- IEEE Transactions on Software Engineering, Vol SE-11, No. 11, November 1985
16:55devndnolen: ^^
16:55amalloywhat a nice coincidence then, that prolog lets you derive questions from answers
16:55devn:D
16:57devnamalloy: the paper raises some interesting questions in my mind: "How are the paradigms integrated into the enviroment?"
16:57dnolendevn: nice
16:58devn"Coordination of environmental tools, such as debuggers and editors, are necessary. For example, to the extent that the editor understands something of the syntax of one paradigm, it must be extended to deal with all paradigms. Finally, one wants to be able to save and restore entities wirtten in new sublanguages, maintaining their user readable format."
16:58devnI hadn't given much thought to that particular aspect of using prolog in clojure. He talks about lisp throughout.
17:01quotemstrIs (new foo) or (foo.) preferred?
17:01radsI've been playing with Noir a bit. thinking in terms of MVC, it seems that Noir "views" serve as both a view and a controller. does anyone else think this is wrong? perhaps they should be called "actions", and if you want to split them up, you can make separate view and controller namespaces?
17:01devnquotemstr: I think (foo.), but if you want to be really explicit (new foo)
17:03BahmanThere is no line number information when my program throws an exception..it is always like
17:03BahmanBacktrace:
17:03devnrads: I don't know if I think it's "wrong". I think it passes on a bit of complexity by not separating them by file, but then again you could wind up in the same predicament even with different namespaces
17:03Bahman 0: extractor.core$do_decrypt_index.invoke(NO_SOURCE_FILE:1)
17:03Bahman 1: extractor.core$_main.doInvoke(NO_SOURCE_FILE:1)
17:03duck1123rads: That's kind of the direction I took with my MVC library. Views and actions are two separate things. And then I have filters (for lack of a better name at the time) that convert the request params into calls on the action
17:04dnolendevn: one interesting part of miniKanren is that mostly an illusion. You can freely mix Clojure and miniKanren code.
17:04BahmanHow can I enable verbose exception information?
17:04dnolendevn: most of the macros are just sugar around functions
17:04devndnolen: yeah, i viewed this paper in a lot of ways as a confirmation of what core.logic is doing
17:04devnbut it also raised a couple of questions that I hadn't considered
17:05radsdevn: it's fine to keep things in the same file (for the small sites), but it seems like calling them views will cause confusion for anyone familiar with MVC's definition of views rather than Noir's
17:06devnrads: I can see why that is a little bit of a cognitive annoyance. You can propose it via the issues queue on github and state your case. I think you're mostly right. It isn't a "view" in the traditional or (by folklore) "correct" sense.
17:07devnWhere logic is kept "out of the view".
17:08devnWhen someone says "the view" there is an ambiguity about what constitutes the logical view. In the frameworks most people have used, they are two separate files which I think aids the distinction between the two.
17:10radsif you grow out of the single file setup, which will happen for a site more than a few pages, you're going to have to have controllers and views. but the views in that context are different than the views that Noir sets you up with. I think that's why it could be very confusing
17:10devnrads: then again, playing devil's advocate: Is the naming of a thing worth producing extra code organization?
17:11duck1123devn: often times you want that extra level of orginization
17:11duck1123rads: feel free to check out my framework and see if it can work for you. https://github.com/duck1123/ciste
17:12radsi.e. the progression is: models and views -> models, views, and controllers. the problem is the views on the left and the right are two different things
17:12duck1123I'm interested to see if it can work for anyone other than me
17:12devnduck1123: That's fair, but where does it end? Do we also create a controller-specific lib namespace by default as well?
17:12devnSince that is important for large sites?
17:12devn"helpers", etc.
17:13devnDo we assume a large site will need utilities.clj and generate that by default as well?
17:13devnEtc. etc.
17:13radswell, I'm not sure what ibdknox has planned for Noir, but anyone who wants to build a bigger framework on top of it (something that could fill Rails's shoes) would have to distinguish between Noir's views and the traditional MVC views
17:14devnrads: that's a great point
17:15radsregarding this: duck1123: That's fair, but where does it end? Do we also create a controller-specific lib namespace by default as well?
17:15radsperhaps that should be an option in the "lein noir" generator
17:15devnrads: but then we get talking about sensible defaults...what is the default for noir?
17:15radsright
17:16duck1123currently, clojure web dev doesn't have that many patterns, and there are no common rules about namespace layout
17:16devnI don't know the "one size fits all" answer, just trying to get some conversation going.
17:17devnclojure web dev seems to be growing up and gaining a mini pattern here or there depending on what people like or dislike about a particular framework
17:17radsyeah
17:18devnwhich is why at the end of the day I end up feeling like, because clojure gives you this ability to build your own framework, I sort of prefer that, but there is no question in my mind that we need some kind of coherent "we made some good decisions ahead of time for you." web dev setup for new users
17:18devnbuild your own framework with relative ease*
17:19radsas heavy as rails is, it does get rid of a lot of the grunt work for you
17:19radsI think there's room for something in clojure like that
17:20radsjust a lot simpler
17:21alexbaranoskydangit, I'm playing with the fedex online print service - they estimate my OnLisp printing to cost $55.61
17:21devnrads: yeah, simple is hard when it comes to web dev. one of the big problems I think being: "Big or small project? How much organization is actually helpful? Are there modular components not included in the base of the framework so I can drop in replacements?"
17:23devnrads: not to mention questions like what your javascript setup will be, framework considerations there, etc. The list goes on and on. Rails provides a pretty heavy base, but still defers to third party authentication systems, pagination, etc.
17:23duck1123having a bunch of middleware that you can grab helps, but sometimes you want stuff that just won't work well as middleware
17:23radsindeed. these are big questions
17:24radsthe question is whether Noir is intended to be used as a base to build those kind of frameworks on top of
17:25radsand I don't see why it shouldn't. the views thing is just a stumbling block
17:25devnThat's a question for ibdknox
17:25radsyeah, I'm going to raise an issue on github
17:25duck1123I think Noir is intended to be just another layer in the onion
17:25devnI think it is worth talking about what we want to make our simplest possible unit of web development: Think something like sinatra.
17:26devnNoir on the top, ring at the bottom, something like that
17:28radsI think it could be both. you can start out with something small, but right now it's also easy to decouple the routes, controllers, views, which is what I'm doing in my own app right now
17:28radsthe decoupling could just be another layer on top
17:28devnrads: I think generators are probably a logical conclusion
17:29devnand then some dead simple configuration for the type of generation you'd like to do
17:29devnspeaking of the clojure web story, Bobby Calderwood did something cool:
17:29devnhttps://github.com/bobby/trail
17:30devnhttps://github.com/bobby/trail/tree/master/src/cljs/example
17:32radsclojurescript is really exciting. I'd love to write entire apps in clojure, and even share view templates between the server and the client
17:32devn"It's all happening, man."
17:32radsa framework that helps you set that up could be clojure's killer app like rails was for ruby, I think
17:33devnThings will solidify and we'll end up with some really fantastic examples of apps written entirely in clojure and clojurescript
17:33devnrads: yeah I think that's right.
17:34alexbaranoskyI agree that that would be a really great web-development experience
17:35devni think it's going to be somewhat dependent on whether people choose to use clojurescript with their clojure app, or if they use clojurescript as a drop-in replacement for something like coffeescript in their existing <language-goes-here> app
17:36devnmaking it drop-dead simple to drop some clojurescript into your clojure web app is going to be a big part of the narrative I think
17:37devnOn that note I think I've exhausted my hypotheticals for the day-- going to go mess around with core.logic a bit.
17:37devnHappy clojuring.
17:38radsthanks for the discussion!
17:42duck1123I think I'm beginning to regret making the switch to Closure Templates for my front-end. Everything is so much easier when it's a quick Hiccup vector
17:43duck1123Although I will admit that the separation of logic it required was good for me.
17:47ejacksonduck1123: have you tried enlive ?
17:47ejacksonor you doing this in cljs ?
17:48duck1123ejackson: I've looked at enlive. The main goal I had was to be able to define a template once, and be able to reference it for both server-side and javascript use
17:48duck1123Not that I've gotten around to much JS coding yet
17:48quotemstrIs it possible to generate a proxy with named functions instead of inline functions providing the method implementations?
17:49quotemstrThat is, instead of (proxy [Foo] [] (bar [x] (do-bar x))), (proxy [Foo] [] do-bar)
17:57amalloyquotemstr: i think you can do it with ##(doc update-proxy)
17:57lazybot⇒ "([proxy mappings]); Takes a proxy instance and a map of strings (which must correspond to methods of the proxy superclass/superinterfaces) to fns (which must take arguments matching the corresponding method, plus an additional (explicit) first arg corresponding to... https://gist.github.com/1396437
18:00quotemstrAh, cool.
18:00amalloy,(let [impl (fn [this] 10), p (proxy [java.util.List] [])] (update-proxy p {"size" impl}) (.size p))
18:00clojurebot10
18:00quotemstrAlso, with other Lisps, it's common to use Lisp code _as_ the configuration file syntax. Is anything wrong with this practice in Clojure programs?
18:00amalloyno
18:00alexbaranoskyquotemstr, in fact it is awesome
18:01quotemstrGreat. :-)
18:01amalloysometimes situations can arise in which it's better to use a .properties file and let java do the very-simple parsing, but most configs are .clj files
18:07radsif anyone was following the conversation we had about Noir's views earlier, I created an issue on GitHub for it: https://github.com/ibdknox/noir/issues/49
18:37dnolenhmm is not possible to get the last element of a sorted-set in constant time?
18:38amalloydnolen: ##(doc rsubseq)
18:38lazybot⇒ "([sc test key] [sc start-test start-key end-test end-key]); sc must be a sorted collection, test(s) one of <, <=, > or >=. Returns a reverse seq of those entries with keys ek for which (test (.. sc comparator (compare ek key)) 0) is true"
18:39amalloy(though as with anything in a sorted-set/map, that's logN time)
18:40dnolenamalloy: yes, yes :)
18:42devnis there a generic way to destructure keys: (def foo {:a 1 :b 2 :c 3}) (with-destructured-foo (do-something a b c))
18:42dnolenamalloy: thx, that's what I was looking for
18:43devnSpecifically I'm reading in a config file that has keys which are credentials that are passed to a function which creates a full map of credentials
18:43amalloydnolen: yeah, subseq and rsubseq are surprisingly little-known
18:43amalloygiven how dang awesome they are
18:44dnolenamalloy: yes, I actually only need rseq, but this is good to know.
18:44devnso I end up with (let [{:keys [a b c]} creds] (do-something a b c))
18:44devnthe repetition is mildly annoying
18:44amalloyoh yeah, rseq. silly me
18:54hansengelHi, I'm trying to solve problem #14 of Project Euler with Clojure but am
18:54hansengelhaving some performance issues.. my code: http://pastie.org/2926143
18:55hansengelI found a Java class which does the same thing in 6.1 secs (mine has been
18:55hansengelrunning for 30 minutes): http://rianjs.net/2011/05/java-solution-to-project-euler-problem-14
18:55hansengelis there something obvious I'm missing here? I've added every optimization I
18:55hansengelknow of as a Clojure noob.. but my script is very very slow
18:57hansengelor is there a easier / faster way to solve this with Clojure?
18:58amalloyhansengel: can you configure your irc client not to split your long message up into so many dang messages?
18:59devnamalloy: be nice
19:00amalloyalso, lines 28&30 are the most obvious egregious-performance issues
19:00hansengelamalloy: sorry, new to ERC as well :)
19:00devni figured it was probably a screen width issue
19:00amalloyyeah, it's always erc that does that
19:00amalloycraziest default setting ever
19:00amalloyanyway, seqs don't have random access - you're walking across the whole chain every time you call nth
19:00devnyeah that is a weird default
19:01tolstoyinsta-flood?
19:01devnanyone here use twitter-api much?
19:02amalloyyeah, that's another good one. if you accidentally try to send (say) ten thousand messages, erc's default behavior is: "Oh, I'm sure he meant to send all those. But if I send them all at once, flood-protection will silence him. So i'll send one per second."
19:03hansengelamalloy: ah right, I remember learning this - so iterate is not the way to go? how would I substitute vectors in?
19:03amalloyiterate is fine, vectors are crazy
19:03amalloybut nth is wrong
19:03amalloyjust loop over the seq calling first/rest
19:05R4p70rhansengel, (if (= 1 (first chain)), (recur (rest chain))
19:05dnolenhansengel: that memoize looks suspicious as well
19:06amalloymemoize is probably a win here
19:06hansengeldnolen: my attempt at a performance improvement, but I guess I was fixing the wrong problem
19:06dnolenhansengel: that's lot of overhead for a cheap calculation
19:06dnolenamalloy: how? there's just prim arithmetic there
19:07amalloydnolen: it's recursively calling itself a lot of times, though
19:07R4p70ramalloy, applay-chain does?
19:07amalloy(and if he's not on 1.3 the arithmetic isn't primitive)
19:07dnolenamalloy: apply-chain is not itself recursive.
19:08hansengelwow, running again with first / rest now.. so much faster
19:08amalloyfine, but iterate does it
19:08amalloyhansengel: probably about 500000 times faster :P
19:09hansengelI think I should drop this `for ( int i = 0; i < length; i++ ) foo[i]` mindset in clojure :)
19:11amalloydnolen: it looks like you're right, actually. i think i discovered that myself when i did this problem ages ago and mis-remembered the result
19:14amalloyhansengel: i'd rather write it without a loop at all, then you can't be tempted to do something silly
19:14R4p70rhansengel, You could also use something like (count (take-while ...
19:15amalloyeg, https://gist.github.com/1396561
19:21hansengelamalloy: great! I was wondering if I could use take-while, but I couldn't think of how to track a count for some reason..
19:21hansengelI'll try that implementation - my loop (without nth) is running just as slow by ~350,000
19:29pandeirois there a simpler way to add a key/value to every map in a vector than using (vec (for [v vect] (assoc v :thekey "val"))) ?
19:30hansengelwow, even faster, this seems like constant time
19:30hansengelI like the `(complement #{1})` trick as well! thanks very much amalloy, dnolen, R4p70r :)
19:33amalloypandeiro: if you're treating it like a seq, you probably don't need it to be a vector anyway
19:35pandeiroamalloy: it's cljs and i'm doing datatype conversion from vectors to JS arrays, so i need it to be... just checking there's no shortcut syntax somewhere i don't know yet
19:35nybbleshey could someone please tell me how to install clojure.tools.trace?
19:35nybbleslike what line should i put in my project.clj so that leiningen will fetch it
19:35amalloyprobably org.clojure/tools.trace
19:36nybbleshmmm
19:36nybblesawesome thanks
19:36R4p70rpandeiro, your code won't evaluate to a vector as amalloy said
19:36nybblesi also just clued in that the pom.xml has this info :)
19:36amalloyR4p70r: yes it will
19:36R4p70rpandeiro, wait you have vec in there sorry
19:37amalloybut he doesn't need the input to be a vector, since he's calling map on it
19:44dnolenafter a week of Scheme, it's fun to be writing Clojure again
19:44tolstoyMan oh man. Trying to find out when to use a threaded server vs a trendy node.js-style async server (use cases for each) is difficult.
19:44tolstoySo many claims!
19:45R4p70rdnolen, Scheme was no fun?
19:45dnolenR4p70r: Scheme is plenty fun, but I really miss function polymorphism there.
19:46dnolenalso the lack of ready-to-use fast data structures
19:46dnolenthat said, I do love me some syntax-rules
19:54nybblescould anyone please point me to a library or function to do string template substitution?
19:55nybbleslike the equivalent of python "%s blah blah blah %d" % ("foo", 1)
19:55tolstoy(format "%s blah blah %d" "foo" 1)
19:55nybblesah ok cool thanks :)
19:56tolstoyI was thinking you wanted something like "blah blah #{some-var} blah".
20:01quotemstrIs there a way to get Emacs to properly indent proxy functions?
20:05amalloyquotemstr: if you have a version of clojure-mode that's not a hundred years old it should work fine
20:06amalloyquotemstr: out of curiosity what class is it that you're proxying?
20:14quotemstramalloy: MessageCountChangeListener from JavaMail.
20:16amalloyquotemstr: http://javamail.kenai.com/nonav/javadocs/javax/mail/event/MessageCountListener.html? that's an interface, so you can (and generally should) use reify instead of proxy
20:19quotemstramalloy: Ah, okay.
20:21amalloyproxy is a bit of a black sheep - it provides one feature you can't get from reify (extending concrete classes), but it's ugly and (comparatively) slow, and its older syntax doesn't match with the newer interface-extension methods
20:30quotemstrIs there a more idiomatic way of writing (every? #((% arg1 arg2)) seq) ?
20:35tomojseq is a seq of 2-arg functions that return 0-arg functions?
20:36tomojor do you mean (every? #(% arg1 arg2) seq)?
20:36quotemstrErr, yes, I meant that.
20:38tomojoh. well, I can't think of anything better :)
20:39tomojare arg1/arg2 let bindings or fn params or something else?
20:40quotemstrAlso, I can't seem to find any obvious way of writing (ns foo (:something some.long.java.package.name bar)) (bar.qux ...). Is that possible? Import will work, but it just aliases the symbols to the ones in the package, yes?
20:41quotemstrtomoj: The actual code is (defn monitor [url filters] (let [folder (get-folder url)] (while (every? #(% folder) filters) (.idle folder true))))
20:42amalloyquotemstr: more concrete example? i can't tell what it is you're trying to do in your ns
20:43quotemstramalloy: I'd like to use a bunch of types from javax.mail.search, but I don't want to type "javax.mail.search" to fully qualify these types, and I don't want to list all the types I'll use in the import declaration.
20:43quotemstrI was hoping to somehow alias "javax.mail.search" to a shorter string.
20:43amalloyyou're out of luck there
20:43amalloyi tried to tack on a request for that feature to the pending "make ns forms better" ticket, but it was declined in the interests of keeping the patch small
20:45quotemstrAt least I'm not the only one.
20:45amalloyyes, it's a bit silly that require can do this but import can't
21:16quotemstrWhy does (println foo) seem to flush *out* while (pprint foo) does not?
21:16quotemstr(If I add an explicit (.flush *out*) after the pprint, everything works as I'd expect.)
21:17amalloyquotemstr: PrintStreams have an implicit flush after a println, iirc; pprint just writes a bunch of characters, the last one of which is a \newline
21:17amalloy$javadoc java.io.PrintStream println
21:17lazybothttp://download.oracle.com/javase/6/docs/api/java/io/PrintStream.html#println()
21:18amalloyhmmmm. the doc claims it flushes when a \n is written, but i dunno how much i'd rely on it
21:19quotemstramalloy: Right; I thought it worked like stdio streams in that respect.
21:22quotemstrAh, it's not that at all. println just calls prn, which has an explicit flush gated on *flush-on-newline*.
21:22quotemstr(Shouldn't it be newline itself that issues this flush?)
21:35quotemstrDoes count run in constant time for sequences that have a precomputed length?
21:40tomojyou mean like, if you (def nums (range 1e6)) and (count nums) twice, does the second count call run in constant time?
21:41tomojcounted? returns true for seqables for which count will always run in constant time
21:41tomojfor the former, looks like the answer is no, at least for lazy seqs
21:42tomojis there a name for the actual domain of count?
21:42quotemstrAh, I see. Thanks!
21:45tomojif two threads try to count a lazy seq at the same time, how do they share the work?
21:46amalloytomoj: by both doing all the work independently
21:47amalloythere's nothing to parallelize - you have to realize elements one at a time because they're recursively defined
21:47amalloyif you want, you can write a lazy-seq that also implements Counted
21:48tomojhmm
21:48amalloy&(count (let [data (map prn (range 10))] (reify clojure.lang.Counted (count [this] 10), clojure.lang.ISeq (seq [this] (seq data))))) ;; counts with no printing
21:48lazybot⇒ 10
21:48tomojsay I do (def nums (range 1e6)), and start counting
21:49tomojaren't all the objects reachable from nums getting cached nexts updating as I count?
21:49amalloyyes, but nobody's caching their counts
21:49tomojright, I mean the work of realizing the lazy seq
21:49amalloysure
21:50tomoje.g. if there's a side-effect in the lazy seq fn, does it happen for each element realized in both threads?
21:50tomojI mean, does it happen in both threads for every element
21:50tomojguess I can just test this
21:50tomoj:)
21:53amalloyit does not
21:53tomojso one thread blocks realizing the next element, other threads just sit and wait until it gets realized?
21:55amalloyyes
22:16zakwilsonI want to parse XML from a String. It doesn't appear that clojure.xml wants to do that. I'm guessing I should make an InputStream from my String somehow, but the javadoc for InputStream doesn't directly say how to do so. Suggestions?
22:19quotemstrWould you use an agent for a producer-consumer queue?
22:19amalloy$javadoc java.io.StringReader
22:19lazybothttp://download.oracle.com/javase/6/docs/api/java/io/StringReader.html
22:21amalloyquotemstr: no, i'd use a java.util.concurrent.LinkedBlockingQueue probably
22:22quotemstramalloy: Ah. Not Clojure primitives then?
22:23amalloynot really. you could do it with a ref on top of a persistent queue, but there's no real point in reinventing the plumbing. and an agent has all the wrong plumbing - it's designed for serializing accesses one thread at a time
22:24quotemstramalloy: So an agent is a queue with many writers and one reader, yes?
22:25amalloyuhhhh
22:25amalloyi guess that's what it is, but calling them readers and writers is confusing, because anyone who wants to can read the current state
22:25technomancyan agent is also a reference type, so it really is designed to be used to model a single stable identity with values that change over time.
22:26technomancythe fact that it happens to be the easiest way to use Clojure's built-in thread pools is coincidental
22:26quotemstrWell, my problem is this: I have a bunch of threads producing incremental, independent updates to a global state. The UI needs to re-render this state after each update.
22:27zakwilson&(isa? java.io.StringReader java.io.InputStream)
22:27lazybot⇒ false
22:27quotemstrSo I thought, "Okay, I'll have each thread put its updates on a queue, and I'll have the UI thread retrieve elements from the queue, perform the corresponding update, rerender, and repeat."
22:28quotemstrIt _sounds_ like an agent will do what I want here.
22:28technomancyyeah, that sounds like a good fit
22:28technomancyif you want all the actual updates to the state to happen on a single thread
22:29technomancyyou could use a watcher on the agent to perform the UI update, I think
22:29quotemstrAnother option would be to put the entire state behind a ref and update the state in a transaction, signaling the UI thread to rerender after each update.
22:33alexbaranoskycurious: what is the reason behind using (if (seq coll) x y) over (id (empty? coll) y x) ?
22:33alexbaranoskyid should be if...
22:34alexbaranoskyis it because checking for emptyness doesn't work so well for lazy seqs?
22:34technomancyalexbaranosky: I'd guess it's because people like to put the "usual" case first in ifs.
22:35alexbaranoskyI like to put the shortest case first
22:35quotemstrHrm: why do agents have validation functions? Can't the update functions do their own validation?
22:36technomancyquotemstr: anyone can send to an agent, but maybe the one who created it wants to be in charge of what's valid.
22:36quotemstrtechnomancy: My first instinct would be to mediate access to the agent in the first place then.
22:37quotemstr(defn my-send-off ...)
22:37technomancyquotemstr: as well as derefing though?
22:38quotemstrSure. The idea is to expose a higher-level facility that would just happen to be implemented, behind the scenes, with an agent.
22:39technomancymight make sense in your case, but in general the fact that every reference type supports a uniform validators interface is pretty handy
22:41quotemstrFair enough.
23:07moogatronicI wrote a function to check for balanced brackets, I'm new'ish to functional programming and clojure -- anyone care to critique?
23:07moogatronichttps://gist.github.com/1396939
23:08moogatronicbasically looking to see if i violated any obvious "don't do that" sort of stuff... since I seem prone to that. =)
23:10amalloymoogatronic: seems kinda pointless to shove a \] onto the stack given that you're never going to remove it
23:11moogatronicyeah, but i don't know how to fail fast at that point.
23:11amalloymoogatronic: ##(doc reductions)
23:11lazybot⇒ "([f coll] [f init coll]); Returns a lazy seq of the intermediate values of the reduction (as per reduce) of coll by f, starting with init."
23:11moogatronicbecause if i had []]
23:12moogatronicamalloy: will read more, thanks!
23:12amalloy(not-any? #{:fail} (reductions (fn [v ch] ... (if bad? :fail (keep-going)))))
23:12moogatronicit's a little messy because i want to allow any other characters in the string as well as the '[' and ']'.
23:13amalloyso?
23:14moogatronicheh, i have no answer to the "so?" question. =) But I will investigate reductions. =)
23:15ibdknoxWhy Noir doesn't have controllers (warning, it's long): http://groups.google.com/group/clj-noir/browse_thread/thread/1718a9b1312156d3
23:27quotemstrIs there anything wrong with iterating like this? (loop [[a b & r] foo] (pprint (format "%s-%s" a b)) (when (seq r) (recur r)))
23:30amalloyquotemstr: looks like a doseq over a partition
23:30amalloy(doseq [[a b] (partition 2 foo)] (pprint ...))
23:31quotemstrAha!
23:31amalloyalso, wait, why are you calling pprint on that format?
23:32amalloyseems like you just want printf
23:33quotemstrThanks.
23:33quotemstrThough actually, I figured out that I can do what I want with just (apply assoc (my-record. defaults...) arglist)
23:53cgray`is there a typehint that you can use to indicate an array?
23:55cgray`I'm using ^java.util.Arrays, but I have a feeling it's not right