2011-06-18
| 01:06 | seancorfield__ | raek: hey, did you see my response about the cyclic dependency? been kinda tied up today and not on IRC much... |
| 02:47 | cwmaguire | help |
| 03:05 | schasi | help? |
| 03:05 | clojurebot | http://www.khanacademy.org/ |
| 06:07 | raek | seancorfield: yes, I saw it but was busy at the time. just re-read it from the logs now. |
| 06:08 | shtutgart | Hello, how can I get the length of the java array? Should I coerce it to seq? |
| 06:09 | raek | shtutgart: use alength |
| 06:10 | shtutgart | raek: of course! Thank you. |
| 06:10 | raek | if you call count on a seq, it will have to traverse the seq to count the elements. an array knows its size, so alength is constant time |
| 06:12 | tomoj | amalloy_: dude, thank you for implanting the urge to learn find in my brain |
| 06:12 | bsteuber | shtutgart: but if performance doesn't matter, just using count makes the function more flexible |
| 06:12 | bsteuber | as you can hand in all clojure seq types, too |
| 06:14 | shtutgart | bsteuber: perfomance isn't very important, but I'm writing java interfacing code, so I don't need support for the clojure types |
| 06:14 | bsteuber | shtutgart: ok makes sense :) |
| 06:15 | tomoj | count calls java.lang.reflect.Array/getLength |
| 06:15 | tomoj | alength just does .length |
| 06:15 | tomoj | constant factor difference on arrays |
| 07:30 | raek | any clojurians at dreamhack? |
| 07:40 | bsteuber | anyone got midje to work with clojure-1.3-alphas? |
| 08:45 | Moominpapa | Hi, I was taking a look at this article http://www.skuro.tk/2011/01/24/performance-boost-in-clojure-1-3/ |
| 08:46 | Moominpapa | I was wondering if using ^:static would do anything. |
| 08:46 | Moominpapa | So I put it in between "defn" and tak. |
| 08:47 | Moominpapa | It doesn't seem to make a blind bit a difference. |
| 08:47 | Moominpapa | Am I doing something wrong, or is the unadorned one already performing the same optimization? |
| 08:48 | Moominpapa | Better link to the function: https://raw.github.com/gist/788834/dd438ab2fbc2d1aff52eb1a380c5507caa6b7e2e/tak.clj |
| 10:24 | stirfoo | what would I use if I wanted a Java array of unsigned bytes [0, 255]? Seems as though byte-array uses signed bytes (or I'm doing something terribly wrong). |
| 10:25 | lucian | stirfoo: afaik, all java int-ish types are signed |
| 10:26 | lucian | there are some workarounds i believe |
| 10:28 | stirfoo | I could use shorts but it's for a core simulator, 8 bits would be much better |
| 10:29 | stirfoo | what's the range of char-array? (is there somewhere I can see what size these arrays actually hold?) |
| 10:29 | lucian | chars are unicode code points, i think |
| 10:29 | stirfoo | lucian: I was thinking the same from a bit of experimenting |
| 10:30 | lucian | so i think you're stuck with bytes, you can google for workarounds |
| 10:30 | stirfoo | ok, thanks lucian |
| 11:08 | sot | If I use a def form to bind a variable to the return value of a funtion, am I correct that the function will only ever be called once? My functionn return a zermq socket, and I do not want that code to be called more than once. |
| 11:15 | pdk | i don't see why binding a def stops the function from being called twice |
| 11:16 | pdk | maybe you should stick a precondition on the function that the value of the def you bound must be nil before it runs to prevent it from being run twice |
| 11:17 | pdk | adding pre/postconditions to a function looks like (defn x [args] {:pre [(condition-1) (condition-2)] :post [(postcondition-1) (postcondition-2)} (body ...)) |
| 11:19 | sot | Thanks, have not see those :pre :post options before |
| 11:21 | stirfoo | there is defonce as well, not sure it that is applicable here |
| 11:22 | stirfoo | I like pre's and postees though, been using them quite a bit |
| 11:24 | pdk | basically |
| 11:24 | pdk | you write the pre/postconditions into vectors |
| 11:25 | pdk | say stuff like [(< 1 arg1) (even? arg2)] etc |
| 11:25 | pdk | in the precondition you can use argument names directly |
| 11:25 | pdk | in the postcondition you can use % to refer to the function's return value since postconditions kick in only after the function is done |
| 11:26 | pdk | in both cases it logical and's everything in the vector for the pre/postconditions |
| 11:26 | pdk | so all of the preconditions have to be true before it starts and all of the postconditions have to be true afterward or it throws an exception |
| 11:26 | sot | Perfect, many thanks |
| 11:47 | fliebel | Anyone knows NIO? I'm trying to convert this to Clojure, but it fails: http://www.javaworld.com/javaworld/jw-04-2003/jw-0411-select.html?page=4#resources When I call accept on the server socket, it gives me java.nio.channels.IllegalBlockingModeException |
| 11:58 | the-kenny | Which is the "beste" Clojure testing framework? |
| 11:59 | the-kenny | s/beste/best/ |
| 11:59 | sexpbot | <the> Which is the "best" Clojure testing framework? |
| 12:11 | gfrlog | the-kenny: which is the "best" clojure data structure? |
| 12:11 | fliebel | (inc gfrlog) |
| 12:11 | sexpbot | ⟹ 2 |
| 12:11 | the-kenny | This is surely the list :p ;) |
| 12:11 | fliebel | Nah, it's the finger tree. |
| 12:11 | gfrlog | lists of finger trees |
| 12:12 | gfrlog | the-kenny: if you want a real answer you'll have to be more specific about what you want to test :) |
| 12:12 | fliebel | the-kenny: But if you don't like choosing, clojure.test sounds like an easy choice :) |
| 12:13 | gfrlog | yeah. The worst thing that can happen is you'll get a better idea of what you want |
| 12:13 | the-kenny | gfrlog: That's the problem. I don't know what I want. I used lazytest for one project (mostly because of the autotest feature and because it generates nice reports), but one thing which drives me crazy is that 1.1.2 (Clojure 1.2.1 compatible) has swank-clojure as a dependency |
| 12:14 | the-kenny | I also like the (given ...) macro, but that'll be removed in future versions |
| 12:14 | the-kenny | deftest feels a bit raw compared to lazytest, but clojure-test-mode is definitely a plus |
| 12:14 | the-kenny | s/deftest/clojure.test/ |
| 12:14 | sexpbot | <the> clojure.test feels a bit raw compared to lazytest, but clojure-test-mode is definitely a plus |
| 12:15 | lnostdal-laptop | is there some way to use lein only as a build/make type tool, so it doesn't download the same packages for each and every one of my new test projects but instead re-uses the common ones i already have stored locally here? |
| 12:15 | gfrlog | it is a bit raw. I normally end up making a macro or two to help |
| 12:15 | gfrlog | I thought lein/maven kept local copies around and used them when available... |
| 12:16 | the-kenny | gfrlog: It does |
| 12:16 | lnostdal-laptop | it copies the local copies |
| 12:16 | lnostdal-laptop | hm, i think |
| 12:16 | gfrlog | ah, you want to save disk space and not have all the duplicate jars? |
| 12:16 | lnostdal-laptop | well, i want to use git |
| 12:16 | gfrlog | eh? who doesn't use git? |
| 12:17 | gfrlog | you want your jars in the repo? |
| 12:17 | lnostdal-laptop | if i pull from some remote repo once i'll have to do that for each project |
| 12:17 | lnostdal-laptop | i don't want jars; i want source code and cached .class files .. maybe i just don't get this stuff |
| 12:17 | gfrlog | I don't think you normally want to version your .class files either |
| 12:18 | lnostdal-laptop | of course not |
| 12:18 | gfrlog | when you say "pull from some remote repo" are talking git-repo or maven-repo? |
| 12:19 | lnostdal-laptop | M-. .. ---> take me to the central code .. i fix some problem, and all projects should see the change |
| 12:19 | lnostdal-laptop | git |
| 12:20 | lnostdal-laptop | this feels so clunky .. sheesh |
| 12:20 | gfrlog | are you talking about when you have one lein project that uses another one? |
| 12:21 | lnostdal-laptop | yeah |
| 12:21 | gfrlog | ah hah |
| 12:21 | gfrlog | in that case lein has a "checkouts" feature |
| 12:21 | gfrlog | you create a "checkouts" directory in the root of a project that uses another project |
| 12:21 | gfrlog | (ignored by git) |
| 12:21 | gfrlog | and within "checkouts", you create symlinks to the root directory of the project you're using |
| 12:23 | lnostdal-laptop | is it possible to have a centralized place where lein looks for symlinks to local projects? |
| 12:23 | fliebel | lnostdal-laptop: Q: I want to hack two projects in parallel, but it's annoying to switch between them: https://github.com/technomancy/leiningen |
| 12:24 | gfrlog | lnostdal-laptop: well I suppose /checkouts could itself be a symlink...I don't know if that risks some kind of cyclic setup, but you can try it |
| 12:24 | lnostdal-laptop | ok, i'll try this .. thanks |
| 12:25 | gfrlog | yep |
| 12:25 | fliebel | Could anyone help me spot a bug in this NIO code? First file is my try at writing the second Java file in Clojure: https://gist.github.com/1033235 |
| 12:26 | gfrlog | I didn't know you could have two files in one gist. |
| 12:26 | gfrlog | but now I do. |
| 12:26 | gfrlog | fliebel: what do you mean by bug? what's it do? |
| 12:27 | fliebel | gfrlog: Well, sit there and listen, echo stuff back, rot13 encoded. The clojure code has a comment on the line where it throws the error. |
| 12:28 | gfrlog | oh ha; didn't see the comment :) |
| 12:28 | gfrlog | looked for it though |
| 12:30 | gfrlog | okay I'm going to stop pretending I know enough about java networking to comprehend this |
| 12:32 | fliebel | gfrlog: Basically I'm just trying to replicate the Java stuff, so it's a matter of find the difference. I'm goin got go through it line by line another time. |
| 12:34 | lucian | fliebel: afaict getChannel blocks |
| 12:35 | lnostdal-laptop | lein can't use my already installed (and running) clojure? .. and load projects/dependencies within that? |
| 12:35 | fliebel | lucian: accept blocks as well, but the thing is that it should return instantaneously because NIO notified us it's ready. |
| 12:36 | fliebel | lucian: Yea, same reactor pattern. |
| 12:36 | lnostdal-laptop | i thought the point of lisp is to work within lisp with an always up REPL .... *sigh* |
| 12:36 | lnostdal-laptop | why this lein stuff from the CLI .... |
| 12:37 | gfrlog | lnostdal-laptop: I think most people consider isolation to be a positive thing |
| 12:39 | lnostdal-laptop | i guess that's nice in some contexts .. need to think about this |
| 12:40 | tnbd | tnbd hi |
| 12:40 | gfrlog | tnbd: tnbd hi |
| 12:40 | lnostdal-laptop | oh, clojure is among the deps? .. what happens if one dep depends on one clojure version, and another dep depends on some other clojure version? |
| 12:41 | tnbd | wrong command, please don't hurt me :) |
| 12:42 | gfrlog | lnostdal-laptop: you could run into that problem with any other dependency as well. That's why dependency management is complicated :) |
| 12:43 | lnostdal-laptop | true |
| 12:43 | lucian | gfrlog: except it's not! :) |
| 12:44 | lnostdal-laptop | which is why having checkouts in git is nice i guess .. if i apply local patches they won't be overwritten as i continue to follow upstream |
| 12:44 | gfrlog | lucian: do go on |
| 12:44 | lucian | oh, and virtualenv |
| 12:44 | lucian | gfrlog: i can't even remember the last time i had trouble with dependencies |
| 12:45 | lnostdal-laptop | debian stable is easy because someone has already dealt with the dep problems for you; there's no magic there |
| 12:45 | gfrlog | lucian: I haven't had trouble, I just mean you can concoct complex situations |
| 12:45 | lucian | gfrlog: yes, but it's a solved problem. which i like |
| 12:45 | lnostdal-laptop | (same with ubuntu etc. etc.) |
| 12:45 | gfrlog | lucian: and the solution is? |
| 12:45 | lucian | gfrlog: lots of software to do it for us |
| 12:45 | gfrlog | to do what? |
| 12:45 | lnostdal-laptop | no, not software |
| 12:46 | lucian | gfrlog: dependency management |
| 12:46 | lnostdal-laptop | *sigH' |
| 12:46 | gfrlog | yes but how? what do you do when A -> B -> C.1 and A -> D -> C.2? |
| 12:46 | lucian | separate envs |
| 12:46 | gfrlog | the only solution I know of is to have your namespaces/packages versioned |
| 12:47 | gfrlog | lucian: "separate envs" is a solution within the jvm? |
| 12:47 | gfrlog | how does that work when there are global variables that C uses? |
| 12:47 | lucian | oh, i misread that |
| 12:48 | lucian | well, that's something you don't let happen |
| 12:48 | gfrlog | how do you prevent it? |
| 12:48 | lucian | your package manager will tell you |
| 12:49 | gfrlog | and then what do you do? |
| 12:49 | gfrlog | drop one of B or D? |
| 12:49 | lucian | yell at whoever did that :) |
| 12:49 | lucian | yes, the only sane solution |
| 12:49 | gfrlog | I think this is what I meant by "it's complex" :) |
| 12:49 | lucian | you said complicated |
| 12:50 | lucian | it is a fine distinction, but i think in this case pertinent |
| 12:50 | gfrlog | well then I will object to "it's a solved problem" as well :) |
| 12:50 | gfrlog | sounds to me like it's still a problem, you've just proved there isn't a solution |
| 12:51 | lucian | perhaps :) |
| 12:51 | gfrlog | or "decided" rather |
| 12:51 | gfrlog | when dependency conflicts can lead directly to "we can't do this project anymore", then I'd say that's worth calling a problem |
| 12:51 | lucian | i should've been more specific |
| 12:52 | lucian | preventing dependency conflicts from creating weird bugs is a solved problem |
| 12:52 | gfrlog | however I still don't know the answer to lnostdal's original question of what happens when you depend on two separate clojure versions |
| 12:52 | lucian | actually resolving conflicts, not entirely |
| 12:52 | gfrlog | not hard to find out though |
| 12:55 | gfrlog | I would think that kind of conflict would come up a lot in clojure development...I guess that suggests that lein silently makes decisions |
| 12:55 | gfrlog | since I've never seen it complain |
| 12:57 | fliebel | ... it seems I'm getting SelectionKey/OP_ACCEPT where I was expecting SelectionKey/OP_READ |
| 13:02 | fliebel | yay! I wasn't clearing some piece of mutable state. |
| 13:02 | gfrlog | now you have a rot13 server? |
| 13:03 | fliebel | gfrlog: No, just a magic question mark printing machine :( |
| 13:03 | fliebel | It's not so easy to turn a ByteBuffer into a string, it seems. |
| 13:04 | gfrlog | cannot be done by reading fewer than 4 javadoc pages |
| 13:04 | fliebel | But after I figure that out, I only have to port Twisted to conquer the world. :P |
| 13:04 | gfrlog | or, if you're doing it in Java/Eclipse, pressing random keys until it compiles |
| 13:20 | stirfoo | has anyone seen this brainf*ck compiler in Racket? http://hashcollision.org/brainfudge/ |
| 13:21 | stirfoo | It's pretty neat what they're doing with the reader |
| 13:22 | stirfoo | The #lang line installs a reader, the bf code is then compiled into Racket proper by way of a few macros. |
| 13:23 | stirfoo | I've got the majority of it rewritten in clojure. It mapped over cleanly. |
| 13:44 | fliebel | Has anyone played with cljque recently? I want to see if I can use it, but it seems very much on the move. |
| 13:44 | fliebel | ... and hasn't any examples or tests |
| 13:45 | fliebel | Also, there was a discussion about asynchronous ring a while back, anyone knows what became of that? |
| 14:36 | fliebel | Could anyone explain me a bit about vars, and how to change them? I'm still just guessing at the meaning of alter-var-root and set! and most of the time I get it wrong and Clojure bites me. |
| 14:38 | arohner | fliebel: a var is a box that contains a value |
| 14:38 | arohner | do you understand what I mean when I say "box"? |
| 14:39 | arohner | it's just an instance of a class that holds a reference |
| 14:39 | arohner | the var has one "root" value |
| 14:39 | arohner | then, each thread can override the value, on a thread-local basis, using binding |
| 14:40 | arohner | binding says "change the value of the var, in my thread only, during the score of the binding" |
| 14:41 | arohner | set! changes the thread-local value, but it's only allowed if you're already inside a binding |
| 14:41 | arohner | alter-var-root changes the root value that all threads see, but doesn't change their thread-local values, if any exist |
| 14:42 | fliebel | arohner: Ah! Why is it only allowed inside a binding? |
| 14:42 | arohner | I think because it makes things easier to reason about |
| 14:43 | arohner | once the binding leaves scope, the set gets undone as well |
| 14:44 | fliebel | Hm, okay. I guess I could use push-thread-bindings, if it's not private, or just stick with binding. |
| 14:45 | fliebel | I'm dealing with some Java, and I want to figure out a way to give every thread its own instance of something. |
| 14:47 | fliebel | I was thinking that tread-local bindings would be a nice way to construct the singleton counter-pattern. |
| 15:22 | zakwilson | Googling "clojure markdown" gets me half a dozen different ways to parse markdown in Clojure. Is there a generally preferred stable library? |
| 15:57 | ihodes | l |
| 16:10 | casper1 | I'm having a bit of trouble understanding the append/insert-child methods of clojure.zip. I want to add a child to a leaf note basically. But this throws an exception. Any tips? |
| 16:13 | casper1 | e.g. (zip/append-child (zip/next (zip/seq-zip '(1))) throws #<CompilerException java.lang.Exception: called children on a leaf node (NO_SOURCE_FILE:44)> |
| 16:14 | casper1 | i can add it to the root but i want to add it below the 1 node |
| 16:15 | scgilardi | there's a function you need to provide that means "can have children" (whether or not it currently does) based on the error message, I'm guessing that function returned false for the node you're trying to add to. you'll need to arrange for it to return true. |
| 16:16 | casper1 | hmm, i'm not sure how to do that |
| 16:18 | casper1 | the zip/branch? fn returns false for the 1 node, but I don't how to get it to return true |
| 16:20 | scgilardi | the doc for clojure.zip/zipper (in zip.clj in the clojure source) has some info. yes, branch? is what you need. seq-zip's version of branch? is (seq?) and (seq? 1) is false. |
| 16:25 | casper1 | Still not getting it i am afraid. Could you provide a tiny example of how to add a child node? |
| 16:29 | scgilardi | does this help? (I don't have a small example handy. branch? is written the way it is for seq because the corresponding make-node function relies on having a seq present for it to work.) |
| 16:29 | scgilardi | http://www.exampler.com/blog/2010/09/01/editing-trees-in-clojure-with-clojurezip/ |
| 16:31 | scgilardi | (this also looks helpful: http://groups.google.com/group/clojure/browse_thread/thread/3291d54508cc0bbf) |
| 16:32 | casper1 | I have been looking at that first one but it doesn't show how to actually insert a new child on a leaf note. Maybe i am just dense though and missing something obvious |
| 16:33 | casper1 | the second one seems to do the opposite, which may help. I'll put on my thinking cap :) |
| 16:34 | scgilardi | clojure.contrib.struct-ed=> (clojure.zip/root (clojure.zip/insert-child |
| 16:34 | scgilardi | (clojure.zip/seq-zip (list 1)) 2)) |
| 16:34 | scgilardi | (2 1) |
| 16:34 | scgilardi | (from the second) |
| 16:56 | jhickner | hello all. I'm trying to figure out how to serve a specific static (in compojure) from a wildcard path. For instance, any request to tiles/* should serve up tiles/tile.png. Most of the docs out there seem to be outdated. Any ideas? |
| 16:56 | jhickner | static file that ids |
| 17:04 | gfrlog | ,:-D |
| 17:04 | clojurebot | :-D |
| 17:05 | jhickner | looks like this works, using ring.util.response/file-response: (GET "/tiles/*" [] (file-response "public/tiles/tile.png")) |
| 19:07 | davekong | I am trying to read a 120MB binary file of 32bit bytes into a vector (maybe array), is there a simple, efficient way to do this? I have this CL code for doing it: http://www.pastie.org/2089175 |
| 19:15 | gfrlog | davekong: you want to read 32-bit words? |
| 19:15 | gfrlog | as integers? |
| 19:15 | davekong | yea |
| 19:16 | gfrlog | I think we gotta do some java stuff |
| 19:16 | gfrlog | and probably things from clojure.java.io |
| 19:19 | gfrlog | okay. With clojure.java.io you can get an input stream with (input-stream (as-file "filename")) |
| 19:20 | gfrlog | then you'd want a helper function that reads a word from the input stream by calling (.read ...) 4 times and combining those together |
| 19:20 | gfrlog | (which depends on the endianness of your data) |
| 19:21 | gfrlog | then with that helper function you can use (loop) to build up a vector of words |
| 19:24 | davekong | alright, let me try to figure it out from here, thanks |
| 19:24 | gfrlog | np |
| 21:29 | tufflax | How do I write def-, a private def? I've been trying but I can't get it to work :p |
| 21:30 | gfrlog | tufflax: I don't think there's a shortcut for (def #^{:private true} my-thing ...) |
| 21:30 | pdk | defn- doesn't have def-/defmacro- equivalents |
| 21:30 | pdk | just attach metadata with :private true |
| 21:30 | gfrlog | in clojure 1.3 I think (def ^private my-thing ...) will work |
| 21:30 | tufflax | So, it's impossible to write it? :p |
| 21:31 | gfrlog | tufflax: you could makee your own with defmacro |
| 21:31 | tufflax | How? That's what I've been trying |
| 21:31 | gfrlog | (defmacro def- [& args] `(def #^{:private true} ~@args)) |
| 21:31 | gfrlog | I think that could work |
| 21:32 | gfrlog | if it doesn't them something involving (with-meta) ... |
| 21:32 | tufflax | Isn't it just ^{:private true}? Instead of #^{...}? |
| 21:33 | gfrlog | I don't think so... |
| 21:35 | pdk | prob ^ |
| 21:35 | scgilardi | http://clojure.org/reader |
| 21:35 | tufflax | hm both works but http://clojure.org/reader doesn't mention #^ |
| 21:35 | scgilardi | (^ is the new syntax, #^ is the old, we may be in a transition period where both work) |
| 21:36 | tufflax | Anyway I tried (defmacro def- [& args] `(def #^{:private true} ~@args)), but it doesn't work |
| 21:36 | gfrlog | the cheatsheet calls ^ "Meta: ^form → (meta form)" |
| 21:36 | gfrlog | tufflax: okay let's see what with-meta does |
| 21:36 | gfrlog | ,(doc with-meta) |
| 21:36 | clojurebot | "([obj m]); Returns an object of the same type and value as obj, with map m as its metadata." |
| 21:37 | wonginator1221 | Hi guys, I'm currently trying to learn clojure through project euler and I've created a function that returns #{1 2 5}. What is the #{ ... } a shorthand form of? Thanks. |
| 21:37 | scgilardi | clojure.contrib.def has some examples |
| 21:37 | gfrlog | wonginator1221: it's a set |
| 21:37 | gfrlog | a collection with no order or duplicates |
| 21:38 | gfrlog | ,(class #{1 2 5}) |
| 21:38 | clojurebot | clojure.lang.PersistentHashSet |
| 21:38 | tufflax | but (def (with-meta a {...} 1)) doesn't work either if that's what you mean gfrlog |
| 21:38 | gfrlog | tufflax: I'm not quite sure what I mean. I'm looking up other metadata functions |
| 21:38 | tufflax | hehe |
| 21:39 | wonginator1221 | gfrlog: Ah.. ok thanks. I'm also running into a problem where I have a recursive func that works fine for small values, but i'm guessing fills that stack on larger numbers. The stacktrace is too long for my terminal to capture. Any tips? |
| 21:39 | gfrlog | wonginator1221: for recursion check out (recur) |
| 21:39 | gfrlog | you generally can't do it directly like other languages |
| 21:40 | gfrlog | ...sorta |
| 21:41 | gfrlog | tufflax: maybe (defmacro def- [name thing] `(def ~name (with-meta ~thing {:private true}))) |
| 21:41 | wonginator1221 | gfrlog: i have some minor experience in scheme and i usually just called the function by name. Is recur the correct special form for recursion? |
| 21:41 | gfrlog | there's probably a better way to do that, because I think you'll end up losing the rest of tthe metadata that way |
| 21:42 | gfrlog | wonginator1221: yes, recur is used for tail- |
| 21:42 | gfrlog | recursion |
| 21:42 | gfrlog | if you're not doing tail-recursion, then you can use the name directly, but you're responsible for the stack size |
| 21:42 | wonginator1221 | gfrlog: I am doing tail recursion so I guess I should look into recur. |
| 21:42 | gfrlog | the JVM does not optimize tail-calls, so that's why (recur) is used to make it explicit |
| 21:43 | gfrlog | wonginator1221: it's not hard, just use recur instead of the name of your function |
| 21:43 | wonginator1221 | One last question. Is jline 1.0 terrible with the repl? My experience has been less than exhilarating. Is rlwrap the way to go? |
| 21:44 | gfrlog | wonginator1221: I think? |
| 21:44 | gfrlog | I use leiningen to launch the repl. I think it uses rlwrap. |
| 21:44 | tufflax | gfrlog I don't think that's right :p the metadata should be on the symbol... |
| 21:44 | gfrlog | tufflax: lemme pull out a repl... |
| 21:45 | gfrlog | okay I think the metadata should be on the var specifically |
| 21:47 | gfrlog | I think alter-meta! might do it better |
| 21:48 | gfrlog | (defmacro def- [name thing] `(do (def ~name ~thing) (alter-meta! (var ~name) assoc :private true))) |
| 21:48 | scgilardi | wonginator1221: lein falls back to jline if rlwrap is not available and notes that rlwrap is better. yes. |
| 21:48 | gfrlog | tufflax: ^ that works for me |
| 21:48 | wonginator1221 | gfrlog: I've been trying to learn the netbeans IDE, but I honestly think it's a little overkill for some basic Project Euler problems. |
| 21:48 | tufflax | gfrlog what do you mean? |
| 21:48 | pdk | can always use vim |
| 21:48 | wonginator1221 | Installing lein at the moment. Thanks for the help. |
| 21:48 | gfrlog | tufflax: I pasted some code |
| 21:48 | gfrlog | wonginator1221: no problem |
| 21:49 | tufflax | oh |
| 21:49 | gfrlog | pdk: what are you talking about nobody but me uses vim |
| 21:49 | wonginator1221 | pdk: I've tried using the vimclojure plugin with very little success, but it's probably due to my lack of experience with vim. |
| 21:52 | tufflax | gfrlog thanks for the help. (defmacro def- [name val] (list `def (with-meta name (assoc (meta name) :private true)) val)) works too |
| 21:52 | gfrlog | tufflax: yeah that looks right |
| 21:52 | gfrlog | I think |
| 21:53 | gfrlog | I guess I can imagine how that would work |
| 21:53 | tufflax | hehe |
| 21:53 | gfrlog | it copies the meta from the symbol to the var |
| 21:53 | tufflax | yeah, it says exactly that in the docs :) |
| 21:53 | gfrlog | ,(meta 'name) |
| 21:53 | clojurebot | nil |
| 21:54 | gfrlog | probably you can replace (assoc (meta name) :private true) with {:private true} |
| 21:54 | gfrlog | since the symbol wouldn't have any meta to begin with |
| 21:54 | tufflax | maybe it has |
| 21:54 | gfrlog | oh I guess that's possible |
| 21:54 | tufflax | I guess it is possible |
| 21:55 | gfrlog | if you do (def- #^{:foo "bar"} ...) then maybe so |
| 21:57 | seancorfield | in clojure 1.3 you can just say (def ^:private thing 42) which isn't bad |
| 21:58 | gfrlog | ,(meta (var cond)) |
| 21:58 | clojurebot | {:macro true, :ns #<Namespace clojure.core>, :name cond, :file "clojure/core.clj", :line 491, :arglists ([& clauses]), :added "1.0", :doc "Takes a set of test/expr pairs. It evaluates each test one at a\n time. If a test returns logical true, cond evaluates and returns\n the value of the corresponding expr and doesn't evaluate any of the\n other tests or exprs. (cond) returns nil."} |
| 21:58 | seancorfield | and metadata is additive in 1.3 so (def ^:private ^{:foo "bar"} thing 42) works as expected |
| 21:58 | gfrlog | so you could say (def ^:macro ...) as well |
| 21:59 | gfrlog | just to be weird |
| 21:59 | seancorfield | :) |
| 22:02 | seancorfield | ,(clojure-version) |
| 22:02 | clojurebot | "1.2.0" |
| 22:02 | seancorfield | &(clojure-version) |
| 22:02 | sexpbot | ⟹ "1.2.0" |
| 22:03 | gfrlog | I approve of their behavior |
| 22:05 | gfrlog | it's most likely to match what folks wandering in with questions are using |
| 22:05 | seancorfield | it's interesting making code run on both 1.2 and 1.3... i didn't realize i'd let some 1.3-specific stuff into clojure.java.jdbc until aaron pointed it out (and fixed it - thankyou!) |
| 22:06 | seancorfield | and i tried to use congomongo but it relied on some contrib 1.2 stuff that doesn't run on 1.3 so i had to make a bunch of changes so congomongo would run on 1.3 as well |
| 22:06 | gfrlog | man we were just talking about why dependency management is hard earlier today |
| 22:07 | seancorfield | i think the move from 1.2 to 1.3 is going to be harder than it looks |
| 22:07 | seancorfield | mostly because of library dependencies |
| 22:07 | gfrlog | I've not tried it yet |
| 22:08 | seancorfield | some stuff is trivial, like *earmuffed* vars need ^{:dynamic true} to run on both 1.2 and 1.3 (or just ^:dynamic for 1.3) |
| 22:08 | gfrlog | all that math too |
| 22:09 | seancorfield | that depends on whether you stay within Long / Double ranges i guess |
| 22:09 | seancorfield | i think the 1.3 model is much better |
| 22:09 | gfrlog | that's pretty fundamental to just change how arithmetic works |
| 22:09 | gfrlog | without even bumping the major version number |
| 22:10 | seancorfield | i think it's the right behavior for "most" situations if clojure is really going to grow |
| 22:10 | gfrlog | which one is better is an orthogonal issue |
| 22:10 | seancorfield | i think it's also a religious issue :) |
| 22:11 | gfrlog | I likes me some bigints |
| 22:11 | kiras | if a function produces a lazy sequence and i do something like (take 5 (the-function 10)), where 10 specifies the number of elements potentially contained in the lazy-seq produced by the-function, i should only get a lazy-seq of five elements, right? or are there times when this is not the case? |
| 22:11 | gfrlog | kiras: five or less |
| 22:11 | gfrlog | ,(take 5 [1 2 3]) |
| 22:11 | clojurebot | (1 2 3) |
| 22:12 | kiras | gfrlog: thanks, that's what i thought |
| 22:12 | kiras | i'm a little confused by something then |
| 22:12 | gfrlog | what's that? |
| 22:13 | kiras | hm... maybe i was just misunderstanding something... |
| 22:14 | kiras | i typed in this function from "the joy of clojure" at the repl and it always seems to give me the entire sequence back, even when i take a subset of it |
| 22:15 | gfrlog | share it with a pastie? |
| 22:15 | seancorfield | ,(take 5 (map #(do (println %) %) (range 10))) |
| 22:15 | clojurebot | 0 |
| 22:15 | clojurebot | 1 |
| 22:15 | clojurebot | 2 |
| 22:15 | kiras | but maybe what i thought were the individual elements of the lazy-seq produced by the function are actually the entire element |
| 22:15 | clojurebot | 3 |
| 22:15 | clojurebot | 4 |
| 22:15 | clojurebot | 5 |
| 22:15 | clojurebot | 6 |
| 22:15 | clojurebot | 7 |
| 22:15 | kiras | sure |
| 22:15 | clojurebot | 8 |
| 22:15 | clojurebot | 9 |
| 22:15 | clojurebot | (0 1 2 3 4) |
| 22:15 | seancorfield | like that you mean? |
| 22:15 | seancorfield | although you only get 5 elements back, map is executed across more elements |
| 22:16 | gfrlog | ,(class (range 10)) |
| 22:16 | clojurebot | clojure.lang.LazySeq |
| 22:16 | gfrlog | range returns a chunked seq I think |
| 22:17 | seancorfield | ,(chunked-seq? (range 10)) |
| 22:17 | clojurebot | false |
| 22:17 | gfrlog | range does not return a chunked seq |
| 22:17 | seancorfield | ,(chunked-seq? (map identity (range 10))) |
| 22:17 | clojurebot | false |
| 22:17 | seancorfield | hmm... |
| 22:17 | gfrlog | I'm not sure why map would go over then |
| 22:17 | kiras | https://gist.github.com/1033674 |
| 22:18 | gfrlog | kiras: what is this supposed to do? |
| 22:19 | kiras | gfrlog: if you call it like, (lz-rec-step [1 2 3 4]), you should get back something like [1 [2 [3 [4 []]]]] |
| 22:19 | seancorfield | yup |
| 22:20 | seancorfield | which has two elements, so (take 1 ...) will return the first but (take 2 ...) will return all of it |
| 22:20 | gfrlog | ,(inc seancorfield) |
| 22:20 | clojurebot | java.lang.Exception: Unable to resolve symbol: seancorfield in this context |
| 22:21 | gfrlog | that is not how that works |
| 22:21 | gfrlog | (inc seancorfield) |
| 22:21 | sexpbot | ⟹ 1 |
| 22:21 | gfrlog | that is |
| 22:21 | kiras | hm... so it does... |
| 22:21 | gfrlog | kiras: and so if you take 5 elements, you also get both of them :) |
| 22:21 | kiras | gfrlog: yeah... lol |
| 22:21 | kiras | well, that makes more sense now |
| 22:22 | gfrlog | victory! |
| 22:22 | kiras | heh |
| 22:22 | seancorfield | lol... so sexpbot does karma points? |
| 22:22 | gfrlog | it does _something_ |
| 22:22 | gfrlog | I'm not sure what it means. |
| 22:22 | gfrlog | let's see what happens when I do it again |
| 22:22 | gfrlog | (inc seancorfield) |
| 22:22 | sexpbot | ⟹ 2 |
| 22:22 | seancorfield | &seancorfield |
| 22:22 | sexpbot | java.lang.Exception: Unable to resolve symbol: seancorfield in this context |
| 22:22 | gfrlog | (dec seancorfield) |
| 22:22 | sexpbot | ⟹ 1 |
| 22:22 | seancorfield | :( |
| 22:22 | seancorfield | i have side effects! oh noes! |
| 22:22 | gfrlog | it was just an experiment. You get to keep the original one. |
| 22:23 | gfrlog | (inc gfrlog) |
| 22:23 | sexpbot | You can't adjust your own karma. |
| 22:23 | gfrlog | I wonder how I display it. |
| 22:23 | kiras | so how useful would that kind of function be, really? |
| 22:23 | kiras | in terms of taking advantage of laziness? |
| 22:23 | gfrlog | kiras: normally you don't have to assemble laziness so directly |
| 22:23 | seancorfield | kiras: looking at the text in the book, i think it's just an example of laziness |
| 22:24 | gfrlog | 97% of the time you'll just use a function that returns a lazy seq by default |
| 22:24 | gfrlog | like range |
| 22:24 | gfrlog | ,(take 5 (range 1000000000000)) |
| 22:24 | clojurebot | java.lang.ExceptionInInitializerError |
| 22:24 | gfrlog | why does that happen. |
| 22:24 | gfrlog | ,(take 5 (range 1000000000)) |
| 22:24 | clojurebot | (0 1 2 3 4) |
| 22:25 | gfrlog | &(take 5 (range 10000000000000000)) |
| 22:25 | seancorfield | ,(take (range 1000000000000N)) |
| 22:25 | sexpbot | java.lang.Exception: EvalReader not allowed when *read-eval* is false. |
| 22:25 | clojurebot | Invalid number: 1000000000000N |
| 22:25 | seancorfield | ? |
| 22:25 | gfrlog | works in my repl |
| 22:26 | gfrlog | ,(* 100000 100000 100000 100000) |
| 22:26 | clojurebot | 100000000000000000000 |
| 22:26 | gfrlog | ,(take 5 (range (* 100000 100000 100000 100000))) |
| 22:26 | clojurebot | (0 1 2 3 4) |
| 22:26 | gfrlog | whatever |
| 22:27 | kiras | seancorfield: i agree that it's just an example, but i was a little surprised when take didn't act the way i expected. i now understand why, thanks to you and gfrlog, i was just thinking that in general, you probably wouldn't write a function producing a lazy-seq that could only ever have two elements, when the second element could be so large, right? |
| 22:28 | gfrlog | I'm having a hard time reasoning about whether you could interact with that thing in a partially-evaluated state... :/ |
| 22:28 | seancorfield | kiras: well, it's certainly an odd example :) |
| 22:28 | kiras | hehe so it's not just me |
| 22:28 | gfrlog | kiras: I think it's probably the case that you don't get anything from laziness there |
| 22:29 | gfrlog | but the repl is acting differently |
| 22:29 | seancorfield | if you did (ffirst (rest (lz-rec-step (range 100000)))) it would only evaluate the first two parts of the range |
| 22:30 | gfrlog | apparently I'm wrong but I don't know why yet |
| 22:30 | gfrlog | okay I think I got it |
| 22:31 | gfrlog | yeah. So you CAN leave it unevaluated, but it's a bizarre and inconvenient structure for sure |
| 22:32 | seancorfield | kinda surprised they didn't use cons rather than building a lop-sided tree |
| 22:33 | gfrlog | it kind of is cons, just more primitive |
| 22:33 | gfrlog | cons is a lop-sided tree after all :) |
| 22:34 | gfrlog | or rather a list is |
| 22:34 | gfrlog | ,(class (list* (range 10))) |
| 22:34 | clojurebot | clojure.lang.ChunkedCons |
| 22:34 | gfrlog | ah that's where I got the chunking idea from |
| 22:36 | kiras | seancornfield: how would you have expected them to use cons and what would be the benefit of that method? |
| 22:36 | gfrlog | (cons (first s) (lz-rec-step (rest s))) |
| 22:37 | kiras | gfrlog in the "then" part of the if? |
| 22:37 | gfrlog | yeah |
| 22:37 | seancorfield | yup |
| 22:37 | seancorfield | then you'd get back a flat lazy sequence |
| 22:37 | kiras | i tried that a few minutes ago and it seems to act the same |
| 22:38 | gfrlog | ,(let [f (fn lz-rec-step [s] (lazy-seq (if (seq s) (cons (first s) (lz-lec-step (rest s))) [])))] (f (range 10))) |
| 22:38 | clojurebot | java.lang.Exception: Unable to resolve symbol: lz-lec-step in this context |
| 22:38 | gfrlog | ,(let [f (fn lz-rec-step [s] (lazy-seq (if (seq s) (cons (first s) (lz-rec-step (rest s))) [])))] (f (range 10))) |
| 22:38 | clojurebot | (0 1 2 3 4 5 6 7 8 9) |
| 22:38 | kiras | well, not entirely the same |
| 22:38 | gfrlog | pardon me |
| 22:38 | gfrlog | and from THAT list you can take 5 and only get back 5 :) |
| 22:40 | kiras | gfrlog: are you sure? |
| 22:41 | seancorfield | kiras: try this (defn lz-rec-step [s] (lazy-seq (if (seq s) (cons (first s) (lz-rec-step (rest s))) []))) |
| 22:41 | seancorfield | then (take 5 (lz-rec-step (range 10))) |
| 22:41 | gfrlog | kiras: I just did it, of course I'm sure :) |
| 22:42 | gfrlog | well sorta |
| 22:42 | gfrlog | ,(let [f (fn lz-rec-step [s] (lazy-seq (if (seq s) (cons (first s) (lz-rec-step (rest s))) [])))] (take 5 (f (range 10)))) |
| 22:42 | clojurebot | (0 1 2 3 4) |
| 22:42 | gfrlog | there now I actually did it |
| 22:44 | kiras | but doesn't that not do what it's supposed to do anymore? |
| 22:44 | gfrlog | kiras: who knows what it's supposed to do? we're not quite sure why it's in the book. |
| 22:45 | gfrlog | kiras: you're right that it does something different |
| 22:45 | kiras | gfrlog: lol ok, sorry, i misunderstood what you were trying to do |
| 22:45 | seancorfield | it's still lazy tho', which is the main point (i hope) |
| 22:46 | gfrlog | of course even then it's still a weird example |
| 22:46 | gfrlog | because you're creating it from an already existing seq |
| 22:46 | seancorfield | we could ask chouser i guess? :) |
| 22:47 | kiras | hehe well, i thought the point was that it was supposed to take [1 2 3 4 5] and return [1 [2 [3 [4 [5]]]]] as a lazy-seq, which it does, but it seems like a strange lazy-seq to return... |
| 22:47 | kiras | so something like what you two are doing might have been a better example |
| 22:47 | gfrlog | kiras: if that's the point, then it does it quite well. I can't think of any application for that whatsoever though |
| 22:47 | gfrlog | even for my version, I STILL can't think of any application |
| 22:48 | gfrlog | turning an already-realized seq into a lazy seq seems pointless |
| 22:48 | kiras | he does have a simple-range example later that is clear enough though... |
| 22:50 | seancorfield | yeah, i guess part of the problem is finding a simple enough example to demonstrate laziness without distracting the reader with a lot of other stuff |
| 22:50 | seancorfield | mind you, that example is on page 116 so by that point readers have already seen a lot of stuff |
| 22:51 | gfrlog | yeah I can't say I'd have a better example |
| 22:51 | gfrlog | it's like how half of the stuff on 4clojure.com is just reimplementing clojure.core functions |
| 22:51 | seancorfield | and they're building on the example from page 115... (steps [1 2 3 4]) |
| 22:51 | kiras | seancorfield: i agree, that's probably a tough aspect of writing a book like this. i have to wonder if it might not have been better to just use the simple-range example instead of having both though |
| 22:52 | gfrlog | I don't have the book in front of me so I'll have to trust you guys to deliver judgments :) |
| 22:52 | seancorfield | ,(reductions + [1 2 3 4]) |
| 22:52 | clojurebot | (1 3 6 10) |
| 22:52 | seancorfield | ,(reductions cons [1 2 3 4]) |
| 22:52 | clojurebot | java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer |
| 22:52 | kiras | gfrlog: lol i'm in no position to be offering judgements, unless being new to the language and learning from the book counts as such a position. |
| 22:52 | gfrlog | ,(doc reductions) |
| 22:52 | clojurebot | "([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." |
| 22:53 | gfrlog | ,(reductions cons () [1 2 3 4]) |
| 22:53 | clojurebot | java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer |
| 22:53 | gfrlog | ,(reductions conj () [1 2 3 4]) |
| 22:53 | clojurebot | (() (1) (2 1) (3 2 1) (4 3 2 1)) |
| 22:53 | seancorfield | ,(reductions conj [] [1 2 3 4]) |
| 22:53 | clojurebot | ([] [1] [1 2] [1 2 3] [1 2 3 4]) |
| 22:53 | seancorfield | jinx! |
| 22:53 | gfrlog | nah I used lists :P |
| 22:53 | gfrlog | kiras: you are in a much better position than me: you have the book ;) |
| 22:54 | seancorfield | ,(take 2 (reductions conj [] [1 2 3 4])) |
| 22:54 | clojurebot | ([] [1]) |
| 22:54 | seancorfield | i was just thinking that steps is sort of close to reductions by way of example |
| 22:54 | seancorfield | ,(source reductions) |
| 22:54 | clojurebot | java.lang.Exception: Unable to resolve symbol: source in this context |
| 22:54 | gfrlog | ,(take 2 (shuffle (reductions conj () (range 1000)))) |
| 22:54 | clojurebot | ((642 641 640 639 638 637 636 635 634 633 ...) (934 933 932 931 930 929 928 927 926 925 ...)) |
| 22:54 | kiras | gfrlog: well, that is a point in my favor. |
| 22:55 | seancorfield | it's a good book... i bought it way back in the MEAP process... just bought chas's Clojure Programming in Rough Cuts too |
| 22:55 | seancorfield | i also have Clojure in Action MEAP |
| 22:55 | clojurebot | written in clojure is a huge selling point |
| 22:56 | gfrlog | only thing I've read is halloway's |
| 22:56 | gfrlog | where I learned to never write macros |
| 22:56 | seancorfield | Programming Clojure? |
| 22:57 | gfrlog | I think so |
| 22:57 | kiras | lol |
| 22:57 | kiras | yeah |
| 22:57 | gfrlog | the yellow book from a couple years ago |
| 22:57 | kiras | the first rule of macro club |
| 22:57 | seancorfield | written for 1.1 wasn't it? |
| 22:57 | gfrlog | at the latest, yeah |
| 22:57 | seancorfield | none of the 1.2 goodness :) |
| 22:57 | gfrlog | funny I don't even remember what the differences are |
| 22:57 | gfrlog | protocols and stuff I guess? |
| 22:57 | gfrlog | it's been so long.... |
| 22:57 | kiras | i think the datatypes |
| 22:57 | seancorfield | i'm really liking what i see in Clojure Programming from emerick, carper and grand |
| 22:58 | seancorfield | clojure 1.2 changes: https://github.com/clojure/clojure/blob/1.2.x/changes.txt |
| 22:59 | gfrlog | woah, weak refs |
| 23:00 | gfrlog | I didn't really know about case... |
| 23:00 | kiras | is there a good book that covers some of the more practical areas of using clojure? like, a few weeks ago, i was in here asking about reading files and stuff. and it's kind of interesting, since you can just use java classes to do it and maybe initially that's what people did, but now it seems like you'd use clojure libraries to do so... and this will probably keep happening. so what might have been considered standard before falls |
| 23:00 | kiras | out of favor as time goes on. |
| 23:02 | kiras | so maybe a book would be the wrong medium for something like that for this language. i think there's a tendency for this to happen with any language, but i think it might be more pronounced with clojure, since using java directly is encouraged, but inevitably, ways of doing the same thing without leaving clojure are developed. |
| 23:02 | technomancy | kiras: I/O is one of the few places the language has changed since 1.0 |
| 23:03 | kiras | technomancy: ah. well, you would definitely know better than i |
| 23:03 | technomancy | until 1.3 (or hopefully 2.0) is released, there will have been only 2 or 3 breaking changes in the past 2 years |
| 23:04 | gfrlog | technomancy: does that parenthesis mean that 1.3 might be renumbered 2.0? |
| 23:04 | kiras | i see things like see-saw and penumbra though, and i think they're good things, but before they were developed, would someone have been encouraged to just use opengl or swing directly? |
| 23:05 | technomancy | gfrlog: it's been suggested. it makes a lot of sense given that it's going to include a number of breaking changes, but I haven't heard anything about it recently |
| 23:05 | gfrlog | technomancy: (inc that-idea) |
| 23:06 | gfrlog | I was just telling seancorfield an hour ago that it bothered me |
| 23:06 | kiras | technomancy: well, i don't mean breaking changes, exactly. just that how you'd tend to do something in the language seems like it will keep changing from calling java directly to using clojure libraries that present a nicer way to do so. which is good, but it could be a challenge to keep up with. or not. |
| 23:06 | technomancy | gfrlog: scala 2.8 took a long time to get released, (lots of breaking changes) and by the time it came out, the developers wished they had called it 3.0 |
| 23:06 | technomancy | so it's ironic that we're making the same mistakes |
| 23:06 | gfrlog | technomancy: I feel like mucking with arithmetic is unusually fundamental |
| 23:07 | technomancy | kiras: yes, well most books avoid covering libraries outside the language itself |
| 23:07 | gfrlog | "it's okay, I'll just grep for wherever my code uses numbers." |
| 23:07 | technomancy | gfrlog: heh |
| 23:07 | kiras | technomancy: of course, the language is still fairly young and i haven't really been around other languages early on in their development. |
| 23:08 | gfrlog | technomancy: do you know if the integer changes in 1.3 effect rationals? |
| 23:08 | technomancy | gfrlog: I don't think so. but I haven't been tracking it closely |
| 23:08 | seancorfield | re: scala - as someone who started with 2.7 and endured the painful 2.8 process, i'll second that! |
| 23:09 | seancorfield | with scala 2.8, several RCs broke binary compatibility... so libraries constantly had to be recompiled |
| 23:11 | seancorfield | for clojure 1.3, the biggest issue for folks learning from books may be that all the examples in print will use contrib 1.2 stuff and contrib 1.2 doesn't run on clojure 1.3 - and the contrib library has been a) split up and b) many modules renamed |
| 23:12 | technomancy | we did learn our lesson pre 1.1 re: not assuming binary compatibility between releases |
| 23:12 | seancorfield | kiras: in particular, see http://dev.clojure.org/display/design/Contrib+Library+Names which shows how much contrib is changing... |
| 23:12 | technomancy | there was a lot more AOT going on for no good reason before that |
| 23:12 | seancorfield | technomancy: and that's one of the pillars of the 1.3 contrib shake up - no more binary libraries |
| 23:13 | seancorfield | all the "new" contrib stuff is source only and should run on 1.2 and 1.3 |
| 23:13 | seancorfield | intended to encourage folks on 1.2 to start using the new contrib stuff... |
| 23:13 | seancorfield | not sure how successful that will be tho'... |
| 23:14 | seancorfield | mind you, i just went thru congomongo and switched that over to the new contrib libraries so i could use it with clojure 1.3 |
| 23:14 | kiras | seancorfield: thanks. i'm sure that will be helpful pretty soon :) |
| 23:15 | technomancy | it would have been nice if the contrib dismantling had happened a year sooner |
| 23:15 | technomancy | though it wasn't till 1.2 landed that using Clojure without contrib was even all that viable |
| 23:15 | seancorfield | i wonder if Clojure Programming will target 1.2 or 1.3? |
| 23:16 | seancorfield | ooh, 1.3!! |
| 23:17 | seancorfield | quote: (All of the code in this book expects v1.3.0 or higher.) |
| 23:17 | seancorfield | that's progress! |
| 23:20 | seancorfield | just commented on the clojure.contrib.sql section suggesting they update to clojure.java.jdbc :) |
| 23:22 | hugod | do all the new contrib libs have versions that are equivalent to what was in 1.2 contrib? |
| 23:25 | hugod | if not, it makes porting code to clojure 1.3 more onerous, as you need to update all your code to match a changed api as well |
| 23:25 | hiredman | I don't know that any clojure books offer much beyond what is available in programming clojure |
| 23:26 | davekong | Thoughts about "The Joy of Clojure"? |
| 23:26 | hiredman | what we need is Clojure: A Critique |
| 23:27 | hiredman | do we really need a lot of books with nothing more than "this is what the literals look like, they are immutable, and here is a list of functions provided that you can do things with" |
| 23:28 | gfrlog | :) |
| 23:31 | gfrlog | yes. we need some more of those books. |
| 23:31 | gfrlog | one in every color. |
| 23:32 | kiras | gfrlog: to match the rainbow parentheses? |
| 23:32 | gfrlog | kiras: good point. Two in every color. |
| 23:32 | kiras | gfrlog: we would need two in every color then |
| 23:32 | kiras | heh |
| 23:33 | kiras | future authors, take note. the demand is there. |
| 23:34 | seancorfield | hugod: the guidance seems to be that the first release of any new contrib library should be a straight port of the old contrib equivalent, updated to run on both 1.3 and 1.2 |
| 23:35 | seancorfield | however, some functions have moved around (so it's not just a rename of the lib in your use / require call) |
| 23:35 | seancorfield | and i think there are going to be _some_ breaking changes |
| 23:36 | hugod | right, just wanting to minimise it… |
| 23:37 | seancorfield | i'm looking hard at c.j.j to figure out how to make the functionality more extensible and then there's the whole binding / thread thing for *earmuffed* variables (which i admit i don't fully understand yet) |
| 23:38 | seancorfield | davekong: i like joy of clojure - it attacks the "why" of clojure - but clojure in action and clojure programming seem to be focusing more on "how to" stuff |
| 23:39 | seancorfield | hiredman: Clojure Programming has chapters on database access (c.c.sql, clojureQL, hibernate, couchdb), math / analysis and lots of other stuff beyond the basics |
| 23:39 | seancorfield | i haven't read Programming Clojure tho' to know what else it has beyond the basics |
| 23:40 | seancorfield | but Programming Clojure doesn't have anything on protocols, records and types, right? because it's based on 1.1? |
| 23:41 | technomancy | seancorfield: well, because of that and because it's 200 pages long |
| 23:41 | technomancy | you really don't need that stuff in a 101-level introduction |
| 23:42 | seancorfield | joy of clojure was my "101" intro... :) |
| 23:45 | seancorfield | i just compared the ToC for Clojure in Action, Clojure Programming and The Joy of Clojure... hiredman could reasonably claim that CiA and JoC don't go far beyond the basics (although they have very different approaches) but CP is quite different |
| 23:46 | seancorfield | hiredman: what sort of stuff would you imagine being in Clojure: A Critique? |