2011-11-26
| 00:00 | amalloy | lonstein: 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:04 | technomancy | voting is for democracies |
| 00:10 | brehaut | for an actual democracy though |
| 00:12 | amalloy | technomancy: 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:13 | technomancy | better comment on it just to make sure you didn't imagine it! |
| 00:20 | amalloy | too risky. if i didn't get a confirmation of that comment i'd be stuck forever |
| 01:56 | accel | is there any efforts to write a mathematica clone (i.e. symbolic mathematics) fully insdie of clojure? |
| 01:56 | accel | less incanter (numerical) |
| 01:56 | accel | more symbolic |
| 02:28 | ischyrus | how does one check if a value is an atom? |
| 02:32 | R4p70r | The 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:53 | G0SUB | Photos from Clojure/conj 2011 are here - http://www.flickr.com/photos/ghoseb/sets/72157628155919755/ |
| 04:46 | Raynes | &(type (atom 0)) |
| 04:46 | lazybot | ⇒ clojure.lang.Atom |
| 04:46 | Raynes | &(instance? clojure.lang.Atom (atom 0)) |
| 04:46 | lazybot | ⇒ true |
| 04:46 | Raynes | ischyrus: ^ |
| 05:20 | alexbaranosky | where can I find a 1.3 compatible library with macrolet in it? |
| 05:37 | alexbaranosky | I'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:19 | MrHus | Hi 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:36 | Bahman | Hi all! |
| 08:37 | Bahman | Does 'nil?' returns TRUE for Java 'null' values? |
| 08:53 | Bahman | ,({:a 1, :b 2, :c 3} (symbol ":c")) |
| 08:54 | clojurebot | nil |
| 08:54 | Bahman | ,(symbol ":c") |
| 08:54 | clojurebot | :c |
| 08:54 | Bahman | Would anyone please explain this to me? |
| 08:56 | Raynes | Bahman: A symbol is not a keyword. |
| 08:56 | Raynes | &(type :c) |
| 08:56 | lazybot | ⇒ clojure.lang.Keyword |
| 08:56 | clojurebot | flatten |is| rarely the right answer. What if your "base type" is a list |
| 08:56 | Raynes | &(type (symbol ":c")) |
| 08:56 | lazybot | ⇒ clojure.lang.Symbol |
| 08:57 | Bahman | Raynes: I see. So is it possible to get a value from a hash map using a string? |
| 08:58 | Raynes | Sure. |
| 08:58 | Raynes | &({:a 1, :b 2} (keyword "c") |
| 08:58 | lazybot | java.lang.RuntimeException: EOF while reading, starting at line 1 |
| 08:58 | Raynes | &({:a 1, :b 2} (keyword "c")) |
| 08:58 | lazybot | ⇒ nil |
| 08:58 | Raynes | Duh. |
| 08:58 | Raynes | &({:a 1, :b 2} (keyword "a")) |
| 08:58 | lazybot | ⇒ 1 |
| 08:58 | Raynes | Or, if your string is a string representation of a keyword (like your example)... |
| 08:59 | Raynes | &({:a 1, :b 2} (read-string ":a")) |
| 08:59 | lazybot | ⇒ 1 |
| 08:59 | Bahman | Thank you Raynes. |
| 09:00 | Raynes | &(-> ":a" (subs 1) keyword) ; another option for getting a keyword from a keywordy string. |
| 09:00 | lazybot | ⇒ :a |
| 10:33 | goodieboy | i'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:34 | goodieboy | I like the envlive approach because the syntax can be much shorter: [:or [:< 10] [:= "test"]] compared to (any-of (lt 10) (exactly "test")) |
| 10:36 | goodieboy | The 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:39 | Raynes | I think I'd encourage functions in this case. |
| 10:39 | Raynes | You can always add the vector stuff on top of that later. |
| 10:42 | goodieboy | Raynes: Good point, so build a solid, function-based library then something on top, if desired. |
| 10:43 | Raynes | That's generally the way to go in most situation. |
| 10:43 | Raynes | situations* |
| 10:43 | goodieboy | makes sense |
| 10:56 | marcusl | I would like to get started w/ Clojure. Which one should I read: "Programming Clojure" or "Joy of Clojure"? |
| 10:57 | _ulises | marcusl: read "joy of" once you're already up and running w/clojure I'd say |
| 10:58 | marcusl | What about the other one? |
| 10:58 | _ulises | I read that one as a first and it was ok |
| 10:58 | _ulises | ok as in, it is a good first start |
| 10:58 | _ulises | I've only read those two clojure books so I cannot compare to any other book though :) |
| 10:58 | marcusl | ok, thank you. |
| 10:59 | _ulises | sure |
| 12:07 | _ulises | quick 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 | _ulises | alrenatives are of course welcome |
| 12:07 | _ulises | alternatives even |
| 12:12 | raek | _ulises: with-redefs |
| 12:12 | _ulises | thanks |
| 12:13 | _ulises | am I right to think that dot are not allowed in symbol names? |
| 12:14 | _ulises | well, I mean, compilation fails if I have foo-0.2 so ... |
| 12:29 | raek | _ulises: yes, dots are reserved |
| 12:29 | _ulises | thanks again |
| 12:34 | _ulises | does lein test work with clojure 1.3? |
| 12:34 | kij | _ulises: works fine here |
| 12:35 | kij | _ulises: but my usage is not that complicated. |
| 12:35 | _ulises | mine is the simplest on earth too :/ |
| 12:35 | _ulises | single test, etc. |
| 12:35 | _ulises | I suspect difftest is the culprit |
| 12:35 | _ulises | so I'll rephrase, does difftest work with clojure 1.3? :) |
| 12:36 | kij | ;) |
| 12:38 | _ulises | hum, it's trying to load contrib stuff (Could not locate clojure/contrib/str_utils2__init.class or clojure/contrib/str_utils2.clj) |
| 13:24 | kij | Is there an nailgun-client for vimclojure 2.3, or is 2.2 fine ? |
| 13:24 | Raynes | difftest should be fine. |
| 13:24 | Raynes | kij: What version of difftest do you have? |
| 13:25 | Raynes | Version 1.3.5 is the newest and is totally contrib free. |
| 13:29 | kij | Raynes: Sorry, my reply was to the "lein test" question. |
| 13:29 | Raynes | kij: Right, I actually meant to direct that at _ulises |
| 13:29 | _ulises | Raynes: probably have an old version, thanks |
| 13:30 | Raynes | _ulises: If you've got it installed as a lein plugin, look at ~/.lein/plugins |
| 13:30 | Raynes | It'll be listed there with the version in the name. |
| 13:30 | _ulises | another question while we're at it, can one have different :pre and :post conditions for different arities of a function? |
| 13:32 | _ulises | along the lines of (defn foo ({:pre ...} [p] ...) ({:pre ...} [p1 p2] ...) ... ) |
| 13:50 | bobhope | hello clojuristas |
| 13:50 | bobhope | I'm having issues with lein and core.logic |
| 13:50 | bobhope | I added core.logic's clojars repo to my project.clj |
| 13:50 | bobhope | and I ran "lein deps" |
| 13:51 | bobhope | but when I open the repl and do (use 'core.logic), it fails saying it couldn't find it |
| 13:56 | duck1123 | it's clojure.core.logic |
| 14:36 | djh__ | 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:37 | djh__ | I initially started with slurp -> spit |
| 14:37 | djh__ | that downloaded the file (as such) but the files aren't readable by any image application |
| 14:38 | djh__ | any ideas how I can accurately download an image from the web and store it locally? |
| 14:53 | tomoj | djh__: https://gist.github.com/f11bb40e7bd951dbd77a looks like this works |
| 14:55 | tomoj | slurp/spit goes through string encoding/decoding which is screwing up the image data |
| 14:55 | Raynes | djh__: (io/copy (io/input-stream "http://raynes.me/hfiles/chocolat.png") (io/file "local.png")) |
| 14:55 | Raynes | You wouldn't dream of using slurp and spit for this anyways. |
| 14:55 | tomoj | is it needed to close the input-stream? wasn't sure |
| 14:56 | djh__ | oh man |
| 14:56 | djh__ | thanks to you both |
| 14:56 | djh__ | seriously |
| 14:56 | Raynes | Yes, you should close it. |
| 14:56 | djh__ | i've spent hours searching for this stuff |
| 14:57 | Raynes | Psh. I > any search engine. |
| 14:57 | tomoj | but with io/file it must close the output-stream on its own? |
| 14:57 | Raynes | tomoj: Right. |
| 14:58 | djh__ | i was under the assumption (with-open) closes the file at the end |
| 14:59 | tomoj | yeah, I wasn't sure whether you needed a with-open with copy |
| 15:24 | quotemstr | Is it possible to write native-looking OS X programs in Clojure? |
| 15:31 | kij | quotemstr: there should be some qt/java bindings. Might be a try worth. |
| 15:32 | rcg1 | there is http://qt-jambi.org/ |
| 15:33 | rcg1 | and afaik some guys try to port swt to qt on basis of qt-jambi |
| 15:34 | rcg1 | btw. i dunno if the stock swt has native OS X look right away |
| 15:35 | rcg1 | so you might even give swt a try http://eclipse.org/swt/ |
| 15:36 | rcg1 | there's also a short "hello world" written in clojure and swt http://kevinoncode.blogspot.com/2009/01/creating-clojure-gui-application-with.html |
| 15:37 | rcg1 | which also has some helpful notes for running it on a mac |
| 15:38 | quotemstr | Cool, thanks. |
| 15:51 | quotemstr | Hrm. Swing seems to work well enough. |
| 16:54 | devn | "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:55 | devn | dnolen: ^^ |
| 16:55 | amalloy | what a nice coincidence then, that prolog lets you derive questions from answers |
| 16:55 | devn | :D |
| 16:57 | devn | amalloy: the paper raises some interesting questions in my mind: "How are the paradigms integrated into the enviroment?" |
| 16:57 | dnolen | devn: nice |
| 16:58 | devn | "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:58 | devn | I hadn't given much thought to that particular aspect of using prolog in clojure. He talks about lisp throughout. |
| 17:01 | quotemstr | Is (new foo) or (foo.) preferred? |
| 17:01 | rads | I'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:01 | devn | quotemstr: I think (foo.), but if you want to be really explicit (new foo) |
| 17:03 | Bahman | There is no line number information when my program throws an exception..it is always like |
| 17:03 | Bahman | Backtrace: |
| 17:03 | devn | rads: 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:03 | Bahman | 0: extractor.core$do_decrypt_index.invoke(NO_SOURCE_FILE:1) |
| 17:03 | Bahman | 1: extractor.core$_main.doInvoke(NO_SOURCE_FILE:1) |
| 17:03 | duck1123 | rads: 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:04 | dnolen | devn: one interesting part of miniKanren is that mostly an illusion. You can freely mix Clojure and miniKanren code. |
| 17:04 | Bahman | How can I enable verbose exception information? |
| 17:04 | dnolen | devn: most of the macros are just sugar around functions |
| 17:04 | devn | dnolen: yeah, i viewed this paper in a lot of ways as a confirmation of what core.logic is doing |
| 17:04 | devn | but it also raised a couple of questions that I hadn't considered |
| 17:05 | rads | devn: 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:06 | devn | rads: 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:07 | devn | Where logic is kept "out of the view". |
| 17:08 | devn | When 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:10 | rads | if 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:10 | devn | rads: then again, playing devil's advocate: Is the naming of a thing worth producing extra code organization? |
| 17:11 | duck1123 | devn: often times you want that extra level of orginization |
| 17:11 | duck1123 | rads: feel free to check out my framework and see if it can work for you. https://github.com/duck1123/ciste |
| 17:12 | rads | i.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:12 | duck1123 | I'm interested to see if it can work for anyone other than me |
| 17:12 | devn | duck1123: That's fair, but where does it end? Do we also create a controller-specific lib namespace by default as well? |
| 17:12 | devn | Since that is important for large sites? |
| 17:12 | devn | "helpers", etc. |
| 17:13 | devn | Do we assume a large site will need utilities.clj and generate that by default as well? |
| 17:13 | devn | Etc. etc. |
| 17:13 | rads | well, 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:14 | devn | rads: that's a great point |
| 17:15 | rads | regarding this: duck1123: That's fair, but where does it end? Do we also create a controller-specific lib namespace by default as well? |
| 17:15 | rads | perhaps that should be an option in the "lein noir" generator |
| 17:15 | devn | rads: but then we get talking about sensible defaults...what is the default for noir? |
| 17:15 | rads | right |
| 17:16 | duck1123 | currently, clojure web dev doesn't have that many patterns, and there are no common rules about namespace layout |
| 17:16 | devn | I don't know the "one size fits all" answer, just trying to get some conversation going. |
| 17:17 | devn | clojure 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:17 | rads | yeah |
| 17:18 | devn | which 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:18 | devn | build your own framework with relative ease* |
| 17:19 | rads | as heavy as rails is, it does get rid of a lot of the grunt work for you |
| 17:19 | rads | I think there's room for something in clojure like that |
| 17:20 | rads | just a lot simpler |
| 17:21 | alexbaranosky | dangit, I'm playing with the fedex online print service - they estimate my OnLisp printing to cost $55.61 |
| 17:21 | devn | rads: 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:23 | devn | rads: 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:23 | duck1123 | having a bunch of middleware that you can grab helps, but sometimes you want stuff that just won't work well as middleware |
| 17:23 | rads | indeed. these are big questions |
| 17:24 | rads | the question is whether Noir is intended to be used as a base to build those kind of frameworks on top of |
| 17:25 | rads | and I don't see why it shouldn't. the views thing is just a stumbling block |
| 17:25 | devn | That's a question for ibdknox |
| 17:25 | rads | yeah, I'm going to raise an issue on github |
| 17:25 | duck1123 | I think Noir is intended to be just another layer in the onion |
| 17:25 | devn | I think it is worth talking about what we want to make our simplest possible unit of web development: Think something like sinatra. |
| 17:26 | devn | Noir on the top, ring at the bottom, something like that |
| 17:28 | rads | I 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:28 | rads | the decoupling could just be another layer on top |
| 17:28 | devn | rads: I think generators are probably a logical conclusion |
| 17:29 | devn | and then some dead simple configuration for the type of generation you'd like to do |
| 17:29 | devn | speaking of the clojure web story, Bobby Calderwood did something cool: |
| 17:29 | devn | https://github.com/bobby/trail |
| 17:30 | devn | https://github.com/bobby/trail/tree/master/src/cljs/example |
| 17:32 | rads | clojurescript is really exciting. I'd love to write entire apps in clojure, and even share view templates between the server and the client |
| 17:32 | devn | "It's all happening, man." |
| 17:32 | rads | a framework that helps you set that up could be clojure's killer app like rails was for ruby, I think |
| 17:33 | devn | Things will solidify and we'll end up with some really fantastic examples of apps written entirely in clojure and clojurescript |
| 17:33 | devn | rads: yeah I think that's right. |
| 17:34 | alexbaranosky | I agree that that would be a really great web-development experience |
| 17:35 | devn | i 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:36 | devn | making 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:37 | devn | On that note I think I've exhausted my hypotheticals for the day-- going to go mess around with core.logic a bit. |
| 17:37 | devn | Happy clojuring. |
| 17:38 | rads | thanks for the discussion! |
| 17:42 | duck1123 | I 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:43 | duck1123 | Although I will admit that the separation of logic it required was good for me. |
| 17:47 | ejackson | duck1123: have you tried enlive ? |
| 17:47 | ejackson | or you doing this in cljs ? |
| 17:48 | duck1123 | ejackson: 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:48 | duck1123 | Not that I've gotten around to much JS coding yet |
| 17:48 | quotemstr | Is it possible to generate a proxy with named functions instead of inline functions providing the method implementations? |
| 17:49 | quotemstr | That is, instead of (proxy [Foo] [] (bar [x] (do-bar x))), (proxy [Foo] [] do-bar) |
| 17:57 | amalloy | quotemstr: i think you can do it with ##(doc update-proxy) |
| 17:57 | lazybot | ⇒ "([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:00 | quotemstr | Ah, cool. |
| 18:00 | amalloy | ,(let [impl (fn [this] 10), p (proxy [java.util.List] [])] (update-proxy p {"size" impl}) (.size p)) |
| 18:00 | clojurebot | 10 |
| 18:00 | quotemstr | Also, 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:00 | amalloy | no |
| 18:00 | alexbaranosky | quotemstr, in fact it is awesome |
| 18:01 | quotemstr | Great. :-) |
| 18:01 | amalloy | sometimes 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:07 | rads | if 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:37 | dnolen | hmm is not possible to get the last element of a sorted-set in constant time? |
| 18:38 | amalloy | dnolen: ##(doc rsubseq) |
| 18:38 | lazybot | ⇒ "([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:39 | amalloy | (though as with anything in a sorted-set/map, that's logN time) |
| 18:40 | dnolen | amalloy: yes, yes :) |
| 18:42 | devn | is there a generic way to destructure keys: (def foo {:a 1 :b 2 :c 3}) (with-destructured-foo (do-something a b c)) |
| 18:42 | dnolen | amalloy: thx, that's what I was looking for |
| 18:43 | devn | Specifically 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:43 | amalloy | dnolen: yeah, subseq and rsubseq are surprisingly little-known |
| 18:43 | amalloy | given how dang awesome they are |
| 18:44 | dnolen | amalloy: yes, I actually only need rseq, but this is good to know. |
| 18:44 | devn | so I end up with (let [{:keys [a b c]} creds] (do-something a b c)) |
| 18:44 | devn | the repetition is mildly annoying |
| 18:44 | amalloy | oh yeah, rseq. silly me |
| 18:54 | hansengel | Hi, I'm trying to solve problem #14 of Project Euler with Clojure but am |
| 18:54 | hansengel | having some performance issues.. my code: http://pastie.org/2926143 |
| 18:55 | hansengel | I found a Java class which does the same thing in 6.1 secs (mine has been |
| 18:55 | hansengel | running for 30 minutes): http://rianjs.net/2011/05/java-solution-to-project-euler-problem-14 |
| 18:55 | hansengel | is there something obvious I'm missing here? I've added every optimization I |
| 18:55 | hansengel | know of as a Clojure noob.. but my script is very very slow |
| 18:57 | hansengel | or is there a easier / faster way to solve this with Clojure? |
| 18:58 | amalloy | hansengel: can you configure your irc client not to split your long message up into so many dang messages? |
| 18:59 | devn | amalloy: be nice |
| 19:00 | amalloy | also, lines 28&30 are the most obvious egregious-performance issues |
| 19:00 | hansengel | amalloy: sorry, new to ERC as well :) |
| 19:00 | devn | i figured it was probably a screen width issue |
| 19:00 | amalloy | yeah, it's always erc that does that |
| 19:00 | amalloy | craziest default setting ever |
| 19:00 | amalloy | anyway, seqs don't have random access - you're walking across the whole chain every time you call nth |
| 19:00 | devn | yeah that is a weird default |
| 19:01 | tolstoy | insta-flood? |
| 19:01 | devn | anyone here use twitter-api much? |
| 19:02 | amalloy | yeah, 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:03 | hansengel | amalloy: ah right, I remember learning this - so iterate is not the way to go? how would I substitute vectors in? |
| 19:03 | amalloy | iterate is fine, vectors are crazy |
| 19:03 | amalloy | but nth is wrong |
| 19:03 | amalloy | just loop over the seq calling first/rest |
| 19:05 | R4p70r | hansengel, (if (= 1 (first chain)), (recur (rest chain)) |
| 19:05 | dnolen | hansengel: that memoize looks suspicious as well |
| 19:06 | amalloy | memoize is probably a win here |
| 19:06 | hansengel | dnolen: my attempt at a performance improvement, but I guess I was fixing the wrong problem |
| 19:06 | dnolen | hansengel: that's lot of overhead for a cheap calculation |
| 19:06 | dnolen | amalloy: how? there's just prim arithmetic there |
| 19:07 | amalloy | dnolen: it's recursively calling itself a lot of times, though |
| 19:07 | R4p70r | amalloy, applay-chain does? |
| 19:07 | amalloy | (and if he's not on 1.3 the arithmetic isn't primitive) |
| 19:07 | dnolen | amalloy: apply-chain is not itself recursive. |
| 19:08 | hansengel | wow, running again with first / rest now.. so much faster |
| 19:08 | amalloy | fine, but iterate does it |
| 19:08 | amalloy | hansengel: probably about 500000 times faster :P |
| 19:09 | hansengel | I think I should drop this `for ( int i = 0; i < length; i++ ) foo[i]` mindset in clojure :) |
| 19:11 | amalloy | dnolen: 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:14 | amalloy | hansengel: i'd rather write it without a loop at all, then you can't be tempted to do something silly |
| 19:14 | R4p70r | hansengel, You could also use something like (count (take-while ... |
| 19:15 | amalloy | eg, https://gist.github.com/1396561 |
| 19:21 | hansengel | amalloy: 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:21 | hansengel | I'll try that implementation - my loop (without nth) is running just as slow by ~350,000 |
| 19:29 | pandeiro | is 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:30 | hansengel | wow, even faster, this seems like constant time |
| 19:30 | hansengel | I like the `(complement #{1})` trick as well! thanks very much amalloy, dnolen, R4p70r :) |
| 19:33 | amalloy | pandeiro: if you're treating it like a seq, you probably don't need it to be a vector anyway |
| 19:35 | pandeiro | amalloy: 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:35 | nybbles | hey could someone please tell me how to install clojure.tools.trace? |
| 19:35 | nybbles | like what line should i put in my project.clj so that leiningen will fetch it |
| 19:35 | amalloy | probably org.clojure/tools.trace |
| 19:36 | nybbles | hmmm |
| 19:36 | nybbles | awesome thanks |
| 19:36 | R4p70r | pandeiro, your code won't evaluate to a vector as amalloy said |
| 19:36 | nybbles | i also just clued in that the pom.xml has this info :) |
| 19:36 | amalloy | R4p70r: yes it will |
| 19:36 | R4p70r | pandeiro, wait you have vec in there sorry |
| 19:37 | amalloy | but he doesn't need the input to be a vector, since he's calling map on it |
| 19:44 | dnolen | after a week of Scheme, it's fun to be writing Clojure again |
| 19:44 | tolstoy | Man 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:44 | tolstoy | So many claims! |
| 19:45 | R4p70r | dnolen, Scheme was no fun? |
| 19:45 | dnolen | R4p70r: Scheme is plenty fun, but I really miss function polymorphism there. |
| 19:46 | dnolen | also the lack of ready-to-use fast data structures |
| 19:46 | dnolen | that said, I do love me some syntax-rules |
| 19:54 | nybbles | could anyone please point me to a library or function to do string template substitution? |
| 19:55 | nybbles | like the equivalent of python "%s blah blah blah %d" % ("foo", 1) |
| 19:55 | tolstoy | (format "%s blah blah %d" "foo" 1) |
| 19:55 | nybbles | ah ok cool thanks :) |
| 19:56 | tolstoy | I was thinking you wanted something like "blah blah #{some-var} blah". |
| 20:01 | quotemstr | Is there a way to get Emacs to properly indent proxy functions? |
| 20:05 | amalloy | quotemstr: if you have a version of clojure-mode that's not a hundred years old it should work fine |
| 20:06 | amalloy | quotemstr: out of curiosity what class is it that you're proxying? |
| 20:14 | quotemstr | amalloy: MessageCountChangeListener from JavaMail. |
| 20:16 | amalloy | quotemstr: 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:19 | quotemstr | amalloy: Ah, okay. |
| 20:21 | amalloy | proxy 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:30 | quotemstr | Is there a more idiomatic way of writing (every? #((% arg1 arg2)) seq) ? |
| 20:35 | tomoj | seq is a seq of 2-arg functions that return 0-arg functions? |
| 20:36 | tomoj | or do you mean (every? #(% arg1 arg2) seq)? |
| 20:36 | quotemstr | Err, yes, I meant that. |
| 20:38 | tomoj | oh. well, I can't think of anything better :) |
| 20:39 | tomoj | are arg1/arg2 let bindings or fn params or something else? |
| 20:40 | quotemstr | Also, 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:41 | quotemstr | tomoj: The actual code is (defn monitor [url filters] (let [folder (get-folder url)] (while (every? #(% folder) filters) (.idle folder true)))) |
| 20:42 | amalloy | quotemstr: more concrete example? i can't tell what it is you're trying to do in your ns |
| 20:43 | quotemstr | amalloy: 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:43 | quotemstr | I was hoping to somehow alias "javax.mail.search" to a shorter string. |
| 20:43 | amalloy | you're out of luck there |
| 20:43 | amalloy | i 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:45 | quotemstr | At least I'm not the only one. |
| 20:45 | amalloy | yes, it's a bit silly that require can do this but import can't |
| 21:16 | quotemstr | Why does (println foo) seem to flush *out* while (pprint foo) does not? |
| 21:16 | quotemstr | (If I add an explicit (.flush *out*) after the pprint, everything works as I'd expect.) |
| 21:17 | amalloy | quotemstr: 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:17 | amalloy | $javadoc java.io.PrintStream println |
| 21:17 | lazybot | http://download.oracle.com/javase/6/docs/api/java/io/PrintStream.html#println() |
| 21:18 | amalloy | hmmmm. the doc claims it flushes when a \n is written, but i dunno how much i'd rely on it |
| 21:19 | quotemstr | amalloy: Right; I thought it worked like stdio streams in that respect. |
| 21:22 | quotemstr | Ah, it's not that at all. println just calls prn, which has an explicit flush gated on *flush-on-newline*. |
| 21:22 | quotemstr | (Shouldn't it be newline itself that issues this flush?) |
| 21:35 | quotemstr | Does count run in constant time for sequences that have a precomputed length? |
| 21:40 | tomoj | you mean like, if you (def nums (range 1e6)) and (count nums) twice, does the second count call run in constant time? |
| 21:41 | tomoj | counted? returns true for seqables for which count will always run in constant time |
| 21:41 | tomoj | for the former, looks like the answer is no, at least for lazy seqs |
| 21:42 | tomoj | is there a name for the actual domain of count? |
| 21:42 | quotemstr | Ah, I see. Thanks! |
| 21:45 | tomoj | if two threads try to count a lazy seq at the same time, how do they share the work? |
| 21:46 | amalloy | tomoj: by both doing all the work independently |
| 21:47 | amalloy | there's nothing to parallelize - you have to realize elements one at a time because they're recursively defined |
| 21:47 | amalloy | if you want, you can write a lazy-seq that also implements Counted |
| 21:48 | tomoj | hmm |
| 21:48 | amalloy | &(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:48 | lazybot | ⇒ 10 |
| 21:48 | tomoj | say I do (def nums (range 1e6)), and start counting |
| 21:49 | tomoj | aren't all the objects reachable from nums getting cached nexts updating as I count? |
| 21:49 | amalloy | yes, but nobody's caching their counts |
| 21:49 | tomoj | right, I mean the work of realizing the lazy seq |
| 21:49 | amalloy | sure |
| 21:50 | tomoj | e.g. if there's a side-effect in the lazy seq fn, does it happen for each element realized in both threads? |
| 21:50 | tomoj | I mean, does it happen in both threads for every element |
| 21:50 | tomoj | guess I can just test this |
| 21:50 | tomoj | :) |
| 21:53 | amalloy | it does not |
| 21:53 | tomoj | so one thread blocks realizing the next element, other threads just sit and wait until it gets realized? |
| 21:55 | amalloy | yes |
| 22:16 | zakwilson | I 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:19 | quotemstr | Would you use an agent for a producer-consumer queue? |
| 22:19 | amalloy | $javadoc java.io.StringReader |
| 22:19 | lazybot | http://download.oracle.com/javase/6/docs/api/java/io/StringReader.html |
| 22:21 | amalloy | quotemstr: no, i'd use a java.util.concurrent.LinkedBlockingQueue probably |
| 22:22 | quotemstr | amalloy: Ah. Not Clojure primitives then? |
| 22:23 | amalloy | not 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:24 | quotemstr | amalloy: So an agent is a queue with many writers and one reader, yes? |
| 22:25 | amalloy | uhhhh |
| 22:25 | amalloy | i 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:25 | technomancy | an 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:26 | technomancy | the fact that it happens to be the easiest way to use Clojure's built-in thread pools is coincidental |
| 22:26 | quotemstr | Well, 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:27 | zakwilson | &(isa? java.io.StringReader java.io.InputStream) |
| 22:27 | lazybot | ⇒ false |
| 22:27 | quotemstr | So 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:28 | quotemstr | It _sounds_ like an agent will do what I want here. |
| 22:28 | technomancy | yeah, that sounds like a good fit |
| 22:28 | technomancy | if you want all the actual updates to the state to happen on a single thread |
| 22:29 | technomancy | you could use a watcher on the agent to perform the UI update, I think |
| 22:29 | quotemstr | Another 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:33 | alexbaranosky | curious: what is the reason behind using (if (seq coll) x y) over (id (empty? coll) y x) ? |
| 22:33 | alexbaranosky | id should be if... |
| 22:34 | alexbaranosky | is it because checking for emptyness doesn't work so well for lazy seqs? |
| 22:34 | technomancy | alexbaranosky: I'd guess it's because people like to put the "usual" case first in ifs. |
| 22:35 | alexbaranosky | I like to put the shortest case first |
| 22:35 | quotemstr | Hrm: why do agents have validation functions? Can't the update functions do their own validation? |
| 22:36 | technomancy | quotemstr: anyone can send to an agent, but maybe the one who created it wants to be in charge of what's valid. |
| 22:36 | quotemstr | technomancy: My first instinct would be to mediate access to the agent in the first place then. |
| 22:37 | quotemstr | (defn my-send-off ...) |
| 22:37 | technomancy | quotemstr: as well as derefing though? |
| 22:38 | quotemstr | Sure. The idea is to expose a higher-level facility that would just happen to be implemented, behind the scenes, with an agent. |
| 22:39 | technomancy | might make sense in your case, but in general the fact that every reference type supports a uniform validators interface is pretty handy |
| 22:41 | quotemstr | Fair enough. |
| 23:07 | moogatronic | I wrote a function to check for balanced brackets, I'm new'ish to functional programming and clojure -- anyone care to critique? |
| 23:07 | moogatronic | https://gist.github.com/1396939 |
| 23:08 | moogatronic | basically looking to see if i violated any obvious "don't do that" sort of stuff... since I seem prone to that. =) |
| 23:10 | amalloy | moogatronic: seems kinda pointless to shove a \] onto the stack given that you're never going to remove it |
| 23:11 | moogatronic | yeah, but i don't know how to fail fast at that point. |
| 23:11 | amalloy | moogatronic: ##(doc reductions) |
| 23:11 | lazybot | ⇒ "([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:11 | moogatronic | because if i had []] |
| 23:12 | moogatronic | amalloy: will read more, thanks! |
| 23:12 | amalloy | (not-any? #{:fail} (reductions (fn [v ch] ... (if bad? :fail (keep-going))))) |
| 23:12 | moogatronic | it's a little messy because i want to allow any other characters in the string as well as the '[' and ']'. |
| 23:13 | amalloy | so? |
| 23:14 | moogatronic | heh, i have no answer to the "so?" question. =) But I will investigate reductions. =) |
| 23:15 | ibdknox | Why Noir doesn't have controllers (warning, it's long): http://groups.google.com/group/clj-noir/browse_thread/thread/1718a9b1312156d3 |
| 23:27 | quotemstr | Is there anything wrong with iterating like this? (loop [[a b & r] foo] (pprint (format "%s-%s" a b)) (when (seq r) (recur r))) |
| 23:30 | amalloy | quotemstr: looks like a doseq over a partition |
| 23:30 | amalloy | (doseq [[a b] (partition 2 foo)] (pprint ...)) |
| 23:31 | quotemstr | Aha! |
| 23:31 | amalloy | also, wait, why are you calling pprint on that format? |
| 23:32 | amalloy | seems like you just want printf |
| 23:33 | quotemstr | Thanks. |
| 23:33 | quotemstr | Though actually, I figured out that I can do what I want with just (apply assoc (my-record. defaults...) arglist) |
| 23:53 | cgray` | is there a typehint that you can use to indicate an array? |
| 23:55 | cgray` | I'm using ^java.util.Arrays, but I have a feeling it's not right |