#clojure logs

2011-06-18

01:06seancorfield__raek: hey, did you see my response about the cyclic dependency? been kinda tied up today and not on IRC much...
02:47cwmaguirehelp
03:05schasihelp?
03:05clojurebothttp://www.khanacademy.org/
06:07raekseancorfield: yes, I saw it but was busy at the time. just re-read it from the logs now.
06:08shtutgartHello, how can I get the length of the java array? Should I coerce it to seq?
06:09raekshtutgart: use alength
06:10shtutgartraek: of course! Thank you.
06:10raekif 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:12tomojamalloy_: dude, thank you for implanting the urge to learn find in my brain
06:12bsteubershtutgart: but if performance doesn't matter, just using count makes the function more flexible
06:12bsteuberas you can hand in all clojure seq types, too
06:14shtutgartbsteuber: perfomance isn't very important, but I'm writing java interfacing code, so I don't need support for the clojure types
06:14bsteubershtutgart: ok makes sense :)
06:15tomojcount calls java.lang.reflect.Array/getLength
06:15tomojalength just does .length
06:15tomojconstant factor difference on arrays
07:30raekany clojurians at dreamhack?
07:40bsteuberanyone got midje to work with clojure-1.3-alphas?
08:45MoominpapaHi, I was taking a look at this article http://www.skuro.tk/2011/01/24/performance-boost-in-clojure-1-3/
08:46MoominpapaI was wondering if using ^:static would do anything.
08:46MoominpapaSo I put it in between "defn" and tak.
08:47MoominpapaIt doesn't seem to make a blind bit a difference.
08:47MoominpapaAm I doing something wrong, or is the unadorned one already performing the same optimization?
08:48MoominpapaBetter link to the function: https://raw.github.com/gist/788834/dd438ab2fbc2d1aff52eb1a380c5507caa6b7e2e/tak.clj
10:24stirfoowhat 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:25lucianstirfoo: afaik, all java int-ish types are signed
10:26lucianthere are some workarounds i believe
10:28stirfooI could use shorts but it's for a core simulator, 8 bits would be much better
10:29stirfoowhat's the range of char-array? (is there somewhere I can see what size these arrays actually hold?)
10:29lucianchars are unicode code points, i think
10:29stirfoolucian: I was thinking the same from a bit of experimenting
10:30lucianso i think you're stuck with bytes, you can google for workarounds
10:30stirfoook, thanks lucian
11:08sotIf 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:15pdki don't see why binding a def stops the function from being called twice
11:16pdkmaybe 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:17pdkadding pre/postconditions to a function looks like (defn x [args] {:pre [(condition-1) (condition-2)] :post [(postcondition-1) (postcondition-2)} (body ...))
11:19sotThanks, have not see those :pre :post options before
11:21stirfoothere is defonce as well, not sure it that is applicable here
11:22stirfooI like pre's and postees though, been using them quite a bit
11:24pdkbasically
11:24pdkyou write the pre/postconditions into vectors
11:25pdksay stuff like [(< 1 arg1) (even? arg2)] etc
11:25pdkin the precondition you can use argument names directly
11:25pdkin the postcondition you can use % to refer to the function's return value since postconditions kick in only after the function is done
11:26pdkin both cases it logical and's everything in the vector for the pre/postconditions
11:26pdkso 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:26sotPerfect, many thanks
11:47fliebelAnyone 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:58the-kennyWhich is the "beste" Clojure testing framework?
11:59the-kennys/beste/best/
11:59sexpbot<the> Which is the "best" Clojure testing framework?
12:11gfrlogthe-kenny: which is the "best" clojure data structure?
12:11fliebel(inc gfrlog)
12:11sexpbot⟹ 2
12:11the-kennyThis is surely the list :p ;)
12:11fliebelNah, it's the finger tree.
12:11gfrloglists of finger trees
12:12gfrlogthe-kenny: if you want a real answer you'll have to be more specific about what you want to test :)
12:12fliebelthe-kenny: But if you don't like choosing, clojure.test sounds like an easy choice :)
12:13gfrlogyeah. The worst thing that can happen is you'll get a better idea of what you want
12:13the-kennygfrlog: 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:14the-kennyI also like the (given ...) macro, but that'll be removed in future versions
12:14the-kennydeftest feels a bit raw compared to lazytest, but clojure-test-mode is definitely a plus
12:14the-kennys/deftest/clojure.test/
12:14sexpbot<the> clojure.test feels a bit raw compared to lazytest, but clojure-test-mode is definitely a plus
12:15lnostdal-laptopis 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:15gfrlogit is a bit raw. I normally end up making a macro or two to help
12:15gfrlogI thought lein/maven kept local copies around and used them when available...
12:16the-kennygfrlog: It does
12:16lnostdal-laptopit copies the local copies
12:16lnostdal-laptophm, i think
12:16gfrlogah, you want to save disk space and not have all the duplicate jars?
12:16lnostdal-laptopwell, i want to use git
12:16gfrlogeh? who doesn't use git?
12:17gfrlogyou want your jars in the repo?
12:17lnostdal-laptopif i pull from some remote repo once i'll have to do that for each project
12:17lnostdal-laptopi don't want jars; i want source code and cached .class files .. maybe i just don't get this stuff
12:17gfrlogI don't think you normally want to version your .class files either
12:18lnostdal-laptopof course not
12:18gfrlogwhen you say "pull from some remote repo" are talking git-repo or maven-repo?
12:19lnostdal-laptopM-. .. ---> take me to the central code .. i fix some problem, and all projects should see the change
12:19lnostdal-laptopgit
12:20lnostdal-laptopthis feels so clunky .. sheesh
12:20gfrlogare you talking about when you have one lein project that uses another one?
12:21lnostdal-laptopyeah
12:21gfrlogah hah
12:21gfrlogin that case lein has a "checkouts" feature
12:21gfrlogyou create a "checkouts" directory in the root of a project that uses another project
12:21gfrlog(ignored by git)
12:21gfrlogand within "checkouts", you create symlinks to the root directory of the project you're using
12:23lnostdal-laptopis it possible to have a centralized place where lein looks for symlinks to local projects?
12:23fliebellnostdal-laptop: Q: I want to hack two projects in parallel, but it's annoying to switch between them: https://github.com/technomancy/leiningen
12:24gfrloglnostdal-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:24lnostdal-laptopok, i'll try this .. thanks
12:25gfrlogyep
12:25fliebelCould 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:26gfrlogI didn't know you could have two files in one gist.
12:26gfrlogbut now I do.
12:26gfrlogfliebel: what do you mean by bug? what's it do?
12:27fliebelgfrlog: 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:28gfrlogoh ha; didn't see the comment :)
12:28gfrloglooked for it though
12:30gfrlogokay I'm going to stop pretending I know enough about java networking to comprehend this
12:32fliebelgfrlog: 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:34lucianfliebel: afaict getChannel blocks
12:35lnostdal-laptoplein can't use my already installed (and running) clojure? .. and load projects/dependencies within that?
12:35fliebellucian: accept blocks as well, but the thing is that it should return instantaneously because NIO notified us it's ready.
12:36fliebellucian: Yea, same reactor pattern.
12:36lnostdal-laptopi thought the point of lisp is to work within lisp with an always up REPL .... *sigh*
12:36lnostdal-laptopwhy this lein stuff from the CLI ....
12:37gfrloglnostdal-laptop: I think most people consider isolation to be a positive thing
12:39lnostdal-laptopi guess that's nice in some contexts .. need to think about this
12:40tnbdtnbd hi
12:40gfrlogtnbd: tnbd hi
12:40lnostdal-laptopoh, 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:41tnbdwrong command, please don't hurt me :)
12:42gfrloglnostdal-laptop: you could run into that problem with any other dependency as well. That's why dependency management is complicated :)
12:43lnostdal-laptoptrue
12:43luciangfrlog: except it's not! :)
12:44lnostdal-laptopwhich 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:44gfrloglucian: do go on
12:44lucianoh, and virtualenv
12:44luciangfrlog: i can't even remember the last time i had trouble with dependencies
12:45lnostdal-laptopdebian stable is easy because someone has already dealt with the dep problems for you; there's no magic there
12:45gfrloglucian: I haven't had trouble, I just mean you can concoct complex situations
12:45luciangfrlog: yes, but it's a solved problem. which i like
12:45lnostdal-laptop(same with ubuntu etc. etc.)
12:45gfrloglucian: and the solution is?
12:45luciangfrlog: lots of software to do it for us
12:45gfrlogto do what?
12:45lnostdal-laptopno, not software
12:46luciangfrlog: dependency management
12:46lnostdal-laptop*sigH'
12:46gfrlogyes but how? what do you do when A -> B -> C.1 and A -> D -> C.2?
12:46lucianseparate envs
12:46gfrlogthe only solution I know of is to have your namespaces/packages versioned
12:47gfrloglucian: "separate envs" is a solution within the jvm?
12:47gfrloghow does that work when there are global variables that C uses?
12:47lucianoh, i misread that
12:48lucianwell, that's something you don't let happen
12:48gfrloghow do you prevent it?
12:48lucianyour package manager will tell you
12:49gfrlogand then what do you do?
12:49gfrlogdrop one of B or D?
12:49lucianyell at whoever did that :)
12:49lucianyes, the only sane solution
12:49gfrlogI think this is what I meant by "it's complex" :)
12:49lucianyou said complicated
12:50lucianit is a fine distinction, but i think in this case pertinent
12:50gfrlogwell then I will object to "it's a solved problem" as well :)
12:50gfrlogsounds to me like it's still a problem, you've just proved there isn't a solution
12:51lucianperhaps :)
12:51gfrlogor "decided" rather
12:51gfrlogwhen dependency conflicts can lead directly to "we can't do this project anymore", then I'd say that's worth calling a problem
12:51luciani should've been more specific
12:52lucianpreventing dependency conflicts from creating weird bugs is a solved problem
12:52gfrloghowever I still don't know the answer to lnostdal's original question of what happens when you depend on two separate clojure versions
12:52lucianactually resolving conflicts, not entirely
12:52gfrlognot hard to find out though
12:55gfrlogI would think that kind of conflict would come up a lot in clojure development...I guess that suggests that lein silently makes decisions
12:55gfrlogsince I've never seen it complain
12:57fliebel... it seems I'm getting SelectionKey/OP_ACCEPT where I was expecting SelectionKey/OP_READ
13:02fliebelyay! I wasn't clearing some piece of mutable state.
13:02gfrlognow you have a rot13 server?
13:03fliebelgfrlog: No, just a magic question mark printing machine :(
13:03fliebelIt's not so easy to turn a ByteBuffer into a string, it seems.
13:04gfrlogcannot be done by reading fewer than 4 javadoc pages
13:04fliebelBut after I figure that out, I only have to port Twisted to conquer the world. :P
13:04gfrlogor, if you're doing it in Java/Eclipse, pressing random keys until it compiles
13:20stirfoohas anyone seen this brainf*ck compiler in Racket? http://hashcollision.org/brainfudge/
13:21stirfooIt's pretty neat what they're doing with the reader
13:22stirfooThe #lang line installs a reader, the bf code is then compiled into Racket proper by way of a few macros.
13:23stirfooI've got the majority of it rewritten in clojure. It mapped over cleanly.
13:44fliebelHas anyone played with cljque recently? I want to see if I can use it, but it seems very much on the move.
13:44fliebel... and hasn't any examples or tests
13:45fliebelAlso, there was a discussion about asynchronous ring a while back, anyone knows what became of that?
14:36fliebelCould 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:38arohnerfliebel: a var is a box that contains a value
14:38arohnerdo you understand what I mean when I say "box"?
14:39arohnerit's just an instance of a class that holds a reference
14:39arohnerthe var has one "root" value
14:39arohnerthen, each thread can override the value, on a thread-local basis, using binding
14:40arohnerbinding says "change the value of the var, in my thread only, during the score of the binding"
14:41arohnerset! changes the thread-local value, but it's only allowed if you're already inside a binding
14:41arohneralter-var-root changes the root value that all threads see, but doesn't change their thread-local values, if any exist
14:42fliebelarohner: Ah! Why is it only allowed inside a binding?
14:42arohnerI think because it makes things easier to reason about
14:43arohneronce the binding leaves scope, the set gets undone as well
14:44fliebelHm, okay. I guess I could use push-thread-bindings, if it's not private, or just stick with binding.
14:45fliebelI'm dealing with some Java, and I want to figure out a way to give every thread its own instance of something.
14:47fliebelI was thinking that tread-local bindings would be a nice way to construct the singleton counter-pattern.
15:22zakwilsonGoogling "clojure markdown" gets me half a dozen different ways to parse markdown in Clojure. Is there a generally preferred stable library?
15:57ihodesl
16:10casper1I'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:13casper1e.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:14casper1i can add it to the root but i want to add it below the 1 node
16:15scgilardithere'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:16casper1hmm, i'm not sure how to do that
16:18casper1the zip/branch? fn returns false for the 1 node, but I don't how to get it to return true
16:20scgilardithe 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:25casper1Still not getting it i am afraid. Could you provide a tiny example of how to add a child node?
16:29scgilardidoes 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:29scgilardihttp://www.exampler.com/blog/2010/09/01/editing-trees-in-clojure-with-clojurezip/
16:31scgilardi(this also looks helpful: http://groups.google.com/group/clojure/browse_thread/thread/3291d54508cc0bbf)
16:32casper1I 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:33casper1the second one seems to do the opposite, which may help. I'll put on my thinking cap :)
16:34scgilardiclojure.contrib.struct-ed=> (clojure.zip/root (clojure.zip/insert-child
16:34scgilardi(clojure.zip/seq-zip (list 1)) 2))
16:34scgilardi(2 1)
16:34scgilardi(from the second)
16:56jhicknerhello 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:56jhicknerstatic file that ids
17:04gfrlog,:-D
17:04clojurebot:-D
17:05jhicknerlooks like this works, using ring.util.response/file-response: (GET "/tiles/*" [] (file-response "public/tiles/tile.png"))
19:07davekongI 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:15gfrlogdavekong: you want to read 32-bit words?
19:15gfrlogas integers?
19:15davekongyea
19:16gfrlogI think we gotta do some java stuff
19:16gfrlogand probably things from clojure.java.io
19:19gfrlogokay. With clojure.java.io you can get an input stream with (input-stream (as-file "filename"))
19:20gfrlogthen you'd want a helper function that reads a word from the input stream by calling (.read ...) 4 times and combining those together
19:20gfrlog(which depends on the endianness of your data)
19:21gfrlogthen with that helper function you can use (loop) to build up a vector of words
19:24davekongalright, let me try to figure it out from here, thanks
19:24gfrlognp
21:29tufflaxHow do I write def-, a private def? I've been trying but I can't get it to work :p
21:30gfrlogtufflax: I don't think there's a shortcut for (def #^{:private true} my-thing ...)
21:30pdkdefn- doesn't have def-/defmacro- equivalents
21:30pdkjust attach metadata with :private true
21:30gfrlogin clojure 1.3 I think (def ^private my-thing ...) will work
21:30tufflaxSo, it's impossible to write it? :p
21:31gfrlogtufflax: you could makee your own with defmacro
21:31tufflaxHow? That's what I've been trying
21:31gfrlog(defmacro def- [& args] `(def #^{:private true} ~@args))
21:31gfrlogI think that could work
21:32gfrlogif it doesn't them something involving (with-meta) ...
21:32tufflaxIsn't it just ^{:private true}? Instead of #^{...}?
21:33gfrlogI don't think so...
21:35pdkprob ^
21:35scgilardihttp://clojure.org/reader
21:35tufflaxhm both works but http://clojure.org/reader doesn't mention #^
21:35scgilardi(^ is the new syntax, #^ is the old, we may be in a transition period where both work)
21:36tufflaxAnyway I tried (defmacro def- [& args] `(def #^{:private true} ~@args)), but it doesn't work
21:36gfrlogthe cheatsheet calls ^ "Meta: ^form → (meta form)"
21:36gfrlogtufflax: okay let's see what with-meta does
21:36gfrlog,(doc with-meta)
21:36clojurebot"([obj m]); Returns an object of the same type and value as obj, with map m as its metadata."
21:37wonginator1221Hi 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:37scgilardiclojure.contrib.def has some examples
21:37gfrlogwonginator1221: it's a set
21:37gfrloga collection with no order or duplicates
21:38gfrlog,(class #{1 2 5})
21:38clojurebotclojure.lang.PersistentHashSet
21:38tufflaxbut (def (with-meta a {...} 1)) doesn't work either if that's what you mean gfrlog
21:38gfrlogtufflax: I'm not quite sure what I mean. I'm looking up other metadata functions
21:38tufflaxhehe
21:39wonginator1221gfrlog: 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:39gfrlogwonginator1221: for recursion check out (recur)
21:39gfrlogyou generally can't do it directly like other languages
21:40gfrlog...sorta
21:41gfrlogtufflax: maybe (defmacro def- [name thing] `(def ~name (with-meta ~thing {:private true})))
21:41wonginator1221gfrlog: 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:41gfrlogthere's probably a better way to do that, because I think you'll end up losing the rest of tthe metadata that way
21:42gfrlogwonginator1221: yes, recur is used for tail-
21:42gfrlogrecursion
21:42gfrlogif you're not doing tail-recursion, then you can use the name directly, but you're responsible for the stack size
21:42wonginator1221gfrlog: I am doing tail recursion so I guess I should look into recur.
21:42gfrlogthe JVM does not optimize tail-calls, so that's why (recur) is used to make it explicit
21:43gfrlogwonginator1221: it's not hard, just use recur instead of the name of your function
21:43wonginator1221One last question. Is jline 1.0 terrible with the repl? My experience has been less than exhilarating. Is rlwrap the way to go?
21:44gfrlogwonginator1221: I think?
21:44gfrlogI use leiningen to launch the repl. I think it uses rlwrap.
21:44tufflaxgfrlog I don't think that's right :p the metadata should be on the symbol...
21:44gfrlogtufflax: lemme pull out a repl...
21:45gfrlogokay I think the metadata should be on the var specifically
21:47gfrlogI think alter-meta! might do it better
21:48gfrlog(defmacro def- [name thing] `(do (def ~name ~thing) (alter-meta! (var ~name) assoc :private true)))
21:48scgilardiwonginator1221: lein falls back to jline if rlwrap is not available and notes that rlwrap is better. yes.
21:48gfrlogtufflax: ^ that works for me
21:48wonginator1221gfrlog: 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:48tufflaxgfrlog what do you mean?
21:48pdkcan always use vim
21:48wonginator1221Installing lein at the moment. Thanks for the help.
21:48gfrlogtufflax: I pasted some code
21:48gfrlogwonginator1221: no problem
21:49tufflaxoh
21:49gfrlogpdk: what are you talking about nobody but me uses vim
21:49wonginator1221pdk: I've tried using the vimclojure plugin with very little success, but it's probably due to my lack of experience with vim.
21:52tufflaxgfrlog thanks for the help. (defmacro def- [name val] (list `def (with-meta name (assoc (meta name) :private true)) val)) works too
21:52gfrlogtufflax: yeah that looks right
21:52gfrlogI think
21:53gfrlogI guess I can imagine how that would work
21:53tufflaxhehe
21:53gfrlogit copies the meta from the symbol to the var
21:53tufflaxyeah, it says exactly that in the docs :)
21:53gfrlog,(meta 'name)
21:53clojurebotnil
21:54gfrlogprobably you can replace (assoc (meta name) :private true) with {:private true}
21:54gfrlogsince the symbol wouldn't have any meta to begin with
21:54tufflaxmaybe it has
21:54gfrlogoh I guess that's possible
21:54tufflaxI guess it is possible
21:55gfrlogif you do (def- #^{:foo "bar"} ...) then maybe so
21:57seancorfieldin clojure 1.3 you can just say (def ^:private thing 42) which isn't bad
21:58gfrlog,(meta (var cond))
21:58clojurebot{: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:58seancorfieldand metadata is additive in 1.3 so (def ^:private ^{:foo "bar"} thing 42) works as expected
21:58gfrlogso you could say (def ^:macro ...) as well
21:59gfrlogjust to be weird
21:59seancorfield:)
22:02seancorfield,(clojure-version)
22:02clojurebot"1.2.0"
22:02seancorfield&(clojure-version)
22:02sexpbot⟹ "1.2.0"
22:03gfrlogI approve of their behavior
22:05gfrlogit's most likely to match what folks wandering in with questions are using
22:05seancorfieldit'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:06seancorfieldand 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:06gfrlogman we were just talking about why dependency management is hard earlier today
22:07seancorfieldi think the move from 1.2 to 1.3 is going to be harder than it looks
22:07seancorfieldmostly because of library dependencies
22:07gfrlogI've not tried it yet
22:08seancorfieldsome 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:08gfrlogall that math too
22:09seancorfieldthat depends on whether you stay within Long / Double ranges i guess
22:09seancorfieldi think the 1.3 model is much better
22:09gfrlogthat's pretty fundamental to just change how arithmetic works
22:09gfrlogwithout even bumping the major version number
22:10seancorfieldi think it's the right behavior for "most" situations if clojure is really going to grow
22:10gfrlogwhich one is better is an orthogonal issue
22:10seancorfieldi think it's also a religious issue :)
22:11gfrlogI likes me some bigints
22:11kirasif 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:11gfrlogkiras: five or less
22:11gfrlog,(take 5 [1 2 3])
22:11clojurebot(1 2 3)
22:12kirasgfrlog: thanks, that's what i thought
22:12kirasi'm a little confused by something then
22:12gfrlogwhat's that?
22:13kirashm... maybe i was just misunderstanding something...
22:14kirasi 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:15gfrlogshare it with a pastie?
22:15seancorfield,(take 5 (map #(do (println %) %) (range 10)))
22:15clojurebot0
22:15clojurebot1
22:15clojurebot2
22:15kirasbut maybe what i thought were the individual elements of the lazy-seq produced by the function are actually the entire element
22:15clojurebot3
22:15clojurebot4
22:15clojurebot5
22:15clojurebot6
22:15clojurebot7
22:15kirassure
22:15clojurebot8
22:15clojurebot9
22:15clojurebot(0 1 2 3 4)
22:15seancorfieldlike that you mean?
22:15seancorfieldalthough you only get 5 elements back, map is executed across more elements
22:16gfrlog,(class (range 10))
22:16clojurebotclojure.lang.LazySeq
22:16gfrlogrange returns a chunked seq I think
22:17seancorfield,(chunked-seq? (range 10))
22:17clojurebotfalse
22:17gfrlogrange does not return a chunked seq
22:17seancorfield,(chunked-seq? (map identity (range 10)))
22:17clojurebotfalse
22:17seancorfieldhmm...
22:17gfrlogI'm not sure why map would go over then
22:17kirashttps://gist.github.com/1033674
22:18gfrlogkiras: what is this supposed to do?
22:19kirasgfrlog: if you call it like, (lz-rec-step [1 2 3 4]), you should get back something like [1 [2 [3 [4 []]]]]
22:19seancorfieldyup
22:20seancorfieldwhich has two elements, so (take 1 ...) will return the first but (take 2 ...) will return all of it
22:20gfrlog,(inc seancorfield)
22:20clojurebotjava.lang.Exception: Unable to resolve symbol: seancorfield in this context
22:21gfrlogthat is not how that works
22:21gfrlog(inc seancorfield)
22:21sexpbot⟹ 1
22:21gfrlogthat is
22:21kirashm... so it does...
22:21gfrlogkiras: and so if you take 5 elements, you also get both of them :)
22:21kirasgfrlog: yeah... lol
22:21kiraswell, that makes more sense now
22:22gfrlogvictory!
22:22kirasheh
22:22seancorfieldlol... so sexpbot does karma points?
22:22gfrlogit does _something_
22:22gfrlogI'm not sure what it means.
22:22gfrloglet's see what happens when I do it again
22:22gfrlog(inc seancorfield)
22:22sexpbot⟹ 2
22:22seancorfield&seancorfield
22:22sexpbotjava.lang.Exception: Unable to resolve symbol: seancorfield in this context
22:22gfrlog(dec seancorfield)
22:22sexpbot⟹ 1
22:22seancorfield:(
22:22seancorfieldi have side effects! oh noes!
22:22gfrlogit was just an experiment. You get to keep the original one.
22:23gfrlog(inc gfrlog)
22:23sexpbotYou can't adjust your own karma.
22:23gfrlogI wonder how I display it.
22:23kirasso how useful would that kind of function be, really?
22:23kirasin terms of taking advantage of laziness?
22:23gfrlogkiras: normally you don't have to assemble laziness so directly
22:23seancorfieldkiras: looking at the text in the book, i think it's just an example of laziness
22:24gfrlog97% of the time you'll just use a function that returns a lazy seq by default
22:24gfrloglike range
22:24gfrlog,(take 5 (range 1000000000000))
22:24clojurebotjava.lang.ExceptionInInitializerError
22:24gfrlogwhy does that happen.
22:24gfrlog,(take 5 (range 1000000000))
22:24clojurebot(0 1 2 3 4)
22:25gfrlog&(take 5 (range 10000000000000000))
22:25seancorfield,(take (range 1000000000000N))
22:25sexpbotjava.lang.Exception: EvalReader not allowed when *read-eval* is false.
22:25clojurebotInvalid number: 1000000000000N
22:25seancorfield?
22:25gfrlogworks in my repl
22:26gfrlog,(* 100000 100000 100000 100000)
22:26clojurebot100000000000000000000
22:26gfrlog,(take 5 (range (* 100000 100000 100000 100000)))
22:26clojurebot(0 1 2 3 4)
22:26gfrlogwhatever
22:27kirasseancorfield: 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:28gfrlogI'm having a hard time reasoning about whether you could interact with that thing in a partially-evaluated state... :/
22:28seancorfieldkiras: well, it's certainly an odd example :)
22:28kirashehe so it's not just me
22:28gfrlogkiras: I think it's probably the case that you don't get anything from laziness there
22:29gfrlogbut the repl is acting differently
22:29seancorfieldif you did (ffirst (rest (lz-rec-step (range 100000)))) it would only evaluate the first two parts of the range
22:30gfrlogapparently I'm wrong but I don't know why yet
22:30gfrlogokay I think I got it
22:31gfrlogyeah. So you CAN leave it unevaluated, but it's a bizarre and inconvenient structure for sure
22:32seancorfieldkinda surprised they didn't use cons rather than building a lop-sided tree
22:33gfrlogit kind of is cons, just more primitive
22:33gfrlogcons is a lop-sided tree after all :)
22:34gfrlogor rather a list is
22:34gfrlog,(class (list* (range 10)))
22:34clojurebotclojure.lang.ChunkedCons
22:34gfrlogah that's where I got the chunking idea from
22:36kirasseancornfield: how would you have expected them to use cons and what would be the benefit of that method?
22:36gfrlog(cons (first s) (lz-rec-step (rest s)))
22:37kirasgfrlog in the "then" part of the if?
22:37gfrlogyeah
22:37seancorfieldyup
22:37seancorfieldthen you'd get back a flat lazy sequence
22:37kirasi tried that a few minutes ago and it seems to act the same
22:38gfrlog,(let [f (fn lz-rec-step [s] (lazy-seq (if (seq s) (cons (first s) (lz-lec-step (rest s))) [])))] (f (range 10)))
22:38clojurebotjava.lang.Exception: Unable to resolve symbol: lz-lec-step in this context
22:38gfrlog,(let [f (fn lz-rec-step [s] (lazy-seq (if (seq s) (cons (first s) (lz-rec-step (rest s))) [])))] (f (range 10)))
22:38clojurebot(0 1 2 3 4 5 6 7 8 9)
22:38kiraswell, not entirely the same
22:38gfrlogpardon me
22:38gfrlogand from THAT list you can take 5 and only get back 5 :)
22:40kirasgfrlog: are you sure?
22:41seancorfieldkiras: try this (defn lz-rec-step [s] (lazy-seq (if (seq s) (cons (first s) (lz-rec-step (rest s))) [])))
22:41seancorfieldthen (take 5 (lz-rec-step (range 10)))
22:41gfrlogkiras: I just did it, of course I'm sure :)
22:42gfrlogwell sorta
22:42gfrlog,(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:42clojurebot(0 1 2 3 4)
22:42gfrlogthere now I actually did it
22:44kirasbut doesn't that not do what it's supposed to do anymore?
22:44gfrlogkiras: who knows what it's supposed to do? we're not quite sure why it's in the book.
22:45gfrlogkiras: you're right that it does something different
22:45kirasgfrlog: lol ok, sorry, i misunderstood what you were trying to do
22:45seancorfieldit's still lazy tho', which is the main point (i hope)
22:46gfrlogof course even then it's still a weird example
22:46gfrlogbecause you're creating it from an already existing seq
22:46seancorfieldwe could ask chouser i guess? :)
22:47kirashehe 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:47kirasso something like what you two are doing might have been a better example
22:47gfrlogkiras: if that's the point, then it does it quite well. I can't think of any application for that whatsoever though
22:47gfrlogeven for my version, I STILL can't think of any application
22:48gfrlogturning an already-realized seq into a lazy seq seems pointless
22:48kirashe does have a simple-range example later that is clear enough though...
22:50seancorfieldyeah, 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:50seancorfieldmind you, that example is on page 116 so by that point readers have already seen a lot of stuff
22:51gfrlogyeah I can't say I'd have a better example
22:51gfrlogit's like how half of the stuff on 4clojure.com is just reimplementing clojure.core functions
22:51seancorfieldand they're building on the example from page 115... (steps [1 2 3 4])
22:51kirasseancorfield: 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:52gfrlogI don't have the book in front of me so I'll have to trust you guys to deliver judgments :)
22:52seancorfield,(reductions + [1 2 3 4])
22:52clojurebot(1 3 6 10)
22:52seancorfield,(reductions cons [1 2 3 4])
22:52clojurebotjava.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer
22:52kirasgfrlog: 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:52gfrlog,(doc reductions)
22:52clojurebot"([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:53gfrlog,(reductions cons () [1 2 3 4])
22:53clojurebotjava.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer
22:53gfrlog,(reductions conj () [1 2 3 4])
22:53clojurebot(() (1) (2 1) (3 2 1) (4 3 2 1))
22:53seancorfield,(reductions conj [] [1 2 3 4])
22:53clojurebot([] [1] [1 2] [1 2 3] [1 2 3 4])
22:53seancorfieldjinx!
22:53gfrlognah I used lists :P
22:53gfrlogkiras: you are in a much better position than me: you have the book ;)
22:54seancorfield,(take 2 (reductions conj [] [1 2 3 4]))
22:54clojurebot([] [1])
22:54seancorfieldi was just thinking that steps is sort of close to reductions by way of example
22:54seancorfield,(source reductions)
22:54clojurebotjava.lang.Exception: Unable to resolve symbol: source in this context
22:54gfrlog,(take 2 (shuffle (reductions conj () (range 1000))))
22:54clojurebot((642 641 640 639 638 637 636 635 634 633 ...) (934 933 932 931 930 929 928 927 926 925 ...))
22:54kirasgfrlog: well, that is a point in my favor.
22:55seancorfieldit's a good book... i bought it way back in the MEAP process... just bought chas's Clojure Programming in Rough Cuts too
22:55seancorfieldi also have Clojure in Action MEAP
22:55clojurebotwritten in clojure is a huge selling point
22:56gfrlogonly thing I've read is halloway's
22:56gfrlogwhere I learned to never write macros
22:56seancorfieldProgramming Clojure?
22:57gfrlogI think so
22:57kiraslol
22:57kirasyeah
22:57gfrlogthe yellow book from a couple years ago
22:57kirasthe first rule of macro club
22:57seancorfieldwritten for 1.1 wasn't it?
22:57gfrlogat the latest, yeah
22:57seancorfieldnone of the 1.2 goodness :)
22:57gfrlogfunny I don't even remember what the differences are
22:57gfrlogprotocols and stuff I guess?
22:57gfrlogit's been so long....
22:57kirasi think the datatypes
22:57seancorfieldi'm really liking what i see in Clojure Programming from emerick, carper and grand
22:58seancorfieldclojure 1.2 changes: https://github.com/clojure/clojure/blob/1.2.x/changes.txt
22:59gfrlogwoah, weak refs
23:00gfrlogI didn't really know about case...
23:00kirasis 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:00kirasout of favor as time goes on.
23:02kirasso 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:02technomancykiras: I/O is one of the few places the language has changed since 1.0
23:03kirastechnomancy: ah. well, you would definitely know better than i
23:03technomancyuntil 1.3 (or hopefully 2.0) is released, there will have been only 2 or 3 breaking changes in the past 2 years
23:04gfrlogtechnomancy: does that parenthesis mean that 1.3 might be renumbered 2.0?
23:04kirasi 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:05technomancygfrlog: 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:05gfrlogtechnomancy: (inc that-idea)
23:06gfrlogI was just telling seancorfield an hour ago that it bothered me
23:06kirastechnomancy: 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:06technomancygfrlog: 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:06technomancyso it's ironic that we're making the same mistakes
23:06gfrlogtechnomancy: I feel like mucking with arithmetic is unusually fundamental
23:07technomancykiras: yes, well most books avoid covering libraries outside the language itself
23:07gfrlog"it's okay, I'll just grep for wherever my code uses numbers."
23:07technomancygfrlog: heh
23:07kirastechnomancy: of course, the language is still fairly young and i haven't really been around other languages early on in their development.
23:08gfrlogtechnomancy: do you know if the integer changes in 1.3 effect rationals?
23:08technomancygfrlog: I don't think so. but I haven't been tracking it closely
23:08seancorfieldre: scala - as someone who started with 2.7 and endured the painful 2.8 process, i'll second that!
23:09seancorfieldwith scala 2.8, several RCs broke binary compatibility... so libraries constantly had to be recompiled
23:11seancorfieldfor 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:12technomancywe did learn our lesson pre 1.1 re: not assuming binary compatibility between releases
23:12seancorfieldkiras: in particular, see http://dev.clojure.org/display/design/Contrib+Library+Names which shows how much contrib is changing...
23:12technomancythere was a lot more AOT going on for no good reason before that
23:12seancorfieldtechnomancy: and that's one of the pillars of the 1.3 contrib shake up - no more binary libraries
23:13seancorfieldall the "new" contrib stuff is source only and should run on 1.2 and 1.3
23:13seancorfieldintended to encourage folks on 1.2 to start using the new contrib stuff...
23:13seancorfieldnot sure how successful that will be tho'...
23:14seancorfieldmind 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:14kirasseancorfield: thanks. i'm sure that will be helpful pretty soon :)
23:15technomancyit would have been nice if the contrib dismantling had happened a year sooner
23:15technomancythough it wasn't till 1.2 landed that using Clojure without contrib was even all that viable
23:15seancorfieldi wonder if Clojure Programming will target 1.2 or 1.3?
23:16seancorfieldooh, 1.3!!
23:17seancorfieldquote: (All of the code in this book expects v1.3.0 or higher.)
23:17seancorfieldthat's progress!
23:20seancorfieldjust commented on the clojure.contrib.sql section suggesting they update to clojure.java.jdbc :)
23:22hugoddo all the new contrib libs have versions that are equivalent to what was in 1.2 contrib?
23:25hugodif 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:25hiredmanI don't know that any clojure books offer much beyond what is available in programming clojure
23:26davekongThoughts about "The Joy of Clojure"?
23:26hiredmanwhat we need is Clojure: A Critique
23:27hiredmando 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:28gfrlog:)
23:31gfrlogyes. we need some more of those books.
23:31gfrlogone in every color.
23:32kirasgfrlog: to match the rainbow parentheses?
23:32gfrlogkiras: good point. Two in every color.
23:32kirasgfrlog: we would need two in every color then
23:32kirasheh
23:33kirasfuture authors, take note. the demand is there.
23:34seancorfieldhugod: 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:35seancorfieldhowever, some functions have moved around (so it's not just a rename of the lib in your use / require call)
23:35seancorfieldand i think there are going to be _some_ breaking changes
23:36hugodright, just wanting to minimise it…
23:37seancorfieldi'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:38seancorfielddavekong: 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:39seancorfieldhiredman: Clojure Programming has chapters on database access (c.c.sql, clojureQL, hibernate, couchdb), math / analysis and lots of other stuff beyond the basics
23:39seancorfieldi haven't read Programming Clojure tho' to know what else it has beyond the basics
23:40seancorfieldbut Programming Clojure doesn't have anything on protocols, records and types, right? because it's based on 1.1?
23:41technomancyseancorfield: well, because of that and because it's 200 pages long
23:41technomancyyou really don't need that stuff in a 101-level introduction
23:42seancorfieldjoy of clojure was my "101" intro... :)
23:45seancorfieldi 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:46seancorfieldhiredman: what sort of stuff would you imagine being in Clojure: A Critique?