#clojure logs

2010-01-04

00:01rikthevikhi, i've got a quick question about unpacking lists and vector
00:01rikthevikin erlang i'm used to saying Foo, Bar = MyListWithTwoItems
00:02rikthevikis there a way to do this in a let statement? something like (let '(foo, bar) list-with-two-items)
00:03piccolino(let [[foo bar] list-with-two-items] ...)
00:04piccolinoLots of other things you can do with that, see here: http://clojure.org/special_forms#toc4
00:06rikthevikthis is exactly what i needed. thanks much
00:06piccolinoNo problem.
00:46rikthevikalso...
00:46rikthevikclojure rules!
01:11KirinDaveI am a loser for not knowing but..
01:11KirinDaveHow would I programatically get the documentation and arglists for a function?
01:11KirinDaveI thought I could go (meta fun-name) and get it all.
01:12KirinDaveBut evidently that's not it?
01:12wooby(doc <function>)
01:12clojurebotexcusez-moi
01:12woobyhehe
01:12KirinDavewooby: doc returns nil
01:12hoeckKirinDave: (meta #'<varname>)
01:12woobyoh, it must write to stdout
01:13KirinDaveAhh.
01:13KirinDaveWhy the #'?
01:13hoeckKirinDave: functions don't have metadata (yet)
01:13KirinDaveSo what does #' doe?
01:13KirinDaveErr, do?
01:13hoeckand the #' returns the var behind the symbol varname
01:13hoeck,`#'map
01:13clojurebot(var clojure.core/map)
01:13KirinDaveAh.
01:13hoeck,(meta #'map)
01:13clojurebot{:ns #<Namespace clojure.core>, :name map, :file "clojure/core.clj", :line 1705, :arglists ([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]), :doc "Returns a lazy sequence consisting of the result of applying f to the\n set of first items of each coll, followed by applying f to the set\n of second items in each coll, until any one of the colls is\n exhausted. Any remaining items in other colls are ignored. Function\n
01:14KirinDaveSo it returns the binding itself?
01:14hoeckyes, kind of
03:54rdsrI all I'm having a little trouble with processing xml in Clojure.
03:55rdsrCan someone point me as to where to paste my code so that I can share it over here?
03:55woobyrdsr: http://paste.lisp.org/
03:56rdsrthk u wooby
03:56woobynp
03:57lisppaste8rdsr pasted "processing xml with clojure" at http://paste.lisp.org/display/92976
03:58rdsrI can't get this to work. the ids vector is always empty
04:05unfo-why not use clojure.xml.parse or lazy-xml from contrib?
04:05rdsrI tried parse but its very slow (the file is huge) Haven't tried lazy xml
04:06rdsrAlso I just want to extract the atom ids and nothing more. I think xml/parse parses the whole thing into memory
04:06rdsrNot sure about lazy-xml
04:14lisppaste8rdsr pasted "processing xml with clojure-2" at http://paste.lisp.org/display/92977
04:15rdsrSorry I should have been more clear
04:15rdsrpasted the code again
04:17woobyrdsr: so you just need IDs you said?
04:18woobyi haven't done any xml stuff in clojure but i'd like to, i'll try and bang something out with lazy-xml
04:19rdsryes
04:19rdsrnever really tried lazy-xml. I also look into it. Thanks
04:23rdsr(use '[clojure.contrib.lazy-xml])
04:23rdsroops! wrong window ! :D
04:23rdsrsorry
05:06LauJensenMorning all
05:07woobygood morning
05:08woobydoes the 'no ctor' error generally mean, 'wrong args passed to java method?'
05:12rdsrThks for suggesting wooby. I was able to get the ids from lazy-xml.
05:12rdsrBut the previous code still bothers me. I can't find anything wrong there
05:13rdsrAnyways using lazy-xml solved my other xml problems also :)
05:13woobyrdsr: awesome!
05:14woobyrdsr: i wouldn't worry about it, it looked pretty messy dealing with sax
05:14rdsrI guess so
06:19vu3rddwhich is the swank-clojure version used by folks? the one from technomancy or the one from jochu? I am using the one from jochu and slime from http://git.boinkor.net/gitweb/slime.git
06:19vu3rddBut technomancy's version seem to be actively developed.
06:20sethstechnomancy's fork works great for me
06:21vu3rddseths: ok. I am planning to package swank-clojure for Debian and push it into the official debian archives. I will start using technomancy's version and package it.
06:22sethsvu3rdd: awesome!
06:55vu3rddseths: I had a quick look at technomancy's version of swank-clojure.
06:56vu3rddWhat I don't like about it is that it tries to do a lot of things like downloading the jar files etc..
06:57vu3rddIt has got some hard coded jar file paths and versions. I feel that they are best decided by some external program (like the package management system provided by the OS).
06:58vu3rddI will most likely be packaging jochu's version, as it is simple and clean and works with the upstream slime. I haven't tested technomancy's swank with upstream slime though.
07:44sethsvu3rdd: understood about the hardcoded versions
07:44sethsbut I would think that those are pending tweaks
07:45sethsand that the tm fork is the better medium to long term option
07:45sethsI am just a happy user, but I have tweeted him about the news
07:48vu3rddseths: ok. I am also planning to write to him and jochu on this before I decide to package it.
07:49vu3rddThe problem I see with all these tools built around clojure is that they seem to live in their own world, in which dependencies are hard coded.
07:50vu3rddwhile they make it easy for the user, it makes the life of a distro developer hard.
07:51vu3rddI believe this is true of Java and Ruby world as well? I am just an old C/Un*x hacker and probably that's why my thinking is a bit screwed up. :-)
07:51fanaticovu3rdd: it's a very young community. as the platform matures these packaging issues will take care of themselves.
07:53vu3rddfanatico: yes, I am sure it will.
07:53raph_Hi there. i have a big problem with clojure.contrib.sql
07:53vu3rddclojure community is great. I am very addicted to it..
07:53raph_i think it's a bug but i'm not very sure
07:54raph_I'm running quite a big fn that does around a thousand updates. For each updates it reopens a connection with (with-connection
07:54vu3rddseths: My thoughts on packaging are summed up in this thread as well - <https://lists.ubuntu.com/archives/ubuntu-devel/2009-January/027272.html&gt;
07:54sethsvu3rdd: great, thanks
07:54raph_after a certain number of requests the system locks out. I tried with Sqlite and Mysql and it does a similar thing with boths
07:55vu3rddI would love to hear from the Clojure community on how to solve this problem.
07:56sethsvu3rdd: I think that technomancy has been a big proponent of ELPA
07:56sethshttp://tromey.com/elpa/
07:56sethsThe Emacs Lisp Package Archive
07:57sethshis emacs-starter-kit uses it
07:57sethsunfortunately it's not integrated with GNU/Emacs yet but there may be plans
07:57fanaticothe parallel delivery stategy always made the most sense to me. once debian/ubuntu/*distro is no longer the "platform", it makes sense to hand off packaging responsibilities.
07:58seths(integrating package.el with GNU/Emacs that is)
07:58vu3rddseths: yes, I had been looking at it as well. I read from Tromey's blog that elpa is going to be in the Emacs mainline
07:59fanaticoELPA is a great example. Managing elisp files with debian never felt natural or simple, so most people ended up with an ad-hoc "whatever works" scheme.
08:00vu3rddfanatico: I have never felt so. I believe elpa takes the control away from the user. If you are editing your .emacs, you always know what you are doing.
08:01vu3rddI am using a "manual" setup for slime/swank/clojure-mode for the past few weeks and have never faced any major issues because of the fact that it is manual.
08:04sethsvu3rdd: I was trying a manual setup to get a SLIME repl for the new branch
08:04sethseven wrote a rakefile to help: http://bitbucket.org/seths/clojuggle/
08:05sethsbut it was solved best by leiningen and swank-clojure-project
08:05vu3rddseths: I haven't tried the "new" branch yet.
08:05fanaticoright, but the cruft builds up over time. I'm sure my .emacs.d directory has lots of out-of-date files in it, because I can't be bothered to make monitor every place I downloaded it from. It's the same kind of fragility you see on systems where everything has been manually compiled (but obviously, to a lesser extent).
08:06vu3rddI am definitely going to take a deeper look at technomancy's branch tonight.
08:08sethscheers all
08:10fanaticoand it has effects on the platform itself. elisp, with all it's very obvious flaws (regexps, lack of lexical scope, namespaces, etc), will never have a chance to correct these issues because the thought of updating all that legacy code w/o a packaging mechanism in place is insane.
08:16gfourhello!
08:20gfouri entered this on the clojure REPL: (class "\a") and it doesn't return to the prompt after the error, is it normal?
08:23chousergfour: yes, unfortunately, for some exceptions thrown by the reader
08:24chouseryour repl is still inside the string where you were when the exception was thrown
08:24chousertry typing " and pressing enter
08:38gfourthank you!
08:48carka little question : if i want to execute a clojure function from the command line, what would be the "java -cp lib/* clojure.main <something here>" command line to give ?
08:53gfourcark: what if you use unix pipes: echo "(println \"hello\")" | clojure will run the (println "hello") code
08:53carkright that would work, anyways in the meantime i'll just do : java -cp lib/* clojure.main myscript.clj
08:54chouserjava -cp build/clojure/clojure.jar clojure.main -e '(println "hi")'
08:54carkah thanks !
08:55carkwhere is that documented ?
08:55chouserjava -cp build/clojure/clojure.jar clojure.main -h
08:55chouser:-)
08:55carkah right, ok now i feel dumb
09:19wiligLauJensen: Thanks for the screen casts Lau. Being completely new to Clojure I was able to implement a tiny web app in a few hours.
09:23LauJensenwilig: Wow - That sounds great :)
09:24wiligLauJensen: It was! It's a really productive environment.
09:25wiligLauJensen: I have a small patch for clojureql, how should I submit it? (Currently clojureql doesn't support boolean columns)
09:27LauJensenEmail it my way, I'll add it
09:36wiligLauJensen: On it's way.
09:36LauJensenI just got it, thanks! I'll have a look at it asap
09:39LauJensenLooks good, thanks!
09:41wiligHeh, hard to mess up 3 lines to code too badly. Thanks for the quick response!
09:42LauJensenwilig: I just need to clear a merge request before I push it, hope you will be a little patient :)
09:43wiligLauJensen: Please take whatever time you need. I'm back to work today so it's Python all day long. I probably won't get a chance to play more until the weekend.
09:43LauJensenOk great
09:49the-kennyAnyone aware of a good java-ide for emacs? I don't want to go back to eclipse
09:49the-kennyI just want things like auto-completion for methods, classes etc. and import-management
10:22cemerickinteresting that (-> \c int byte) works, but not (-> \c byte)
10:24cemerickI wonder if that's intentional
10:25ohpauleezyes, because byte attempts to cast to Number
10:25stuartsierraJava chars are 16-bit, maybe that's why.
10:28cemerickohpauleez: yeah, I see that. Trying to fix the wrongs of the past, perhaps. ;-)
10:29ohpauleezahh, gotcha. It has to do with not using the primitive types
10:29ohpauleezI just started digging into it right now
10:30ohpauleezhttp://java.sun.com/javase/6/docs/api/java/lang/Character.html
10:32cemerickI doubt it has anything to do with primitives or not -- more about whether the "tower" should have chars mixed up in it, even for environments that don't conflate chars with numbers.
10:32cemerick...or, that's my hypothesis, anyway.
10:32hiredmancemerick: it does have to do with primitives
10:33cemerickoh?
10:33ohpauleezbecause you can cast a char with (byte) in Java
10:33hiredmanprimitives are more, uh, fluid? about casting and what not
10:33ohpauleezbut not a Character to Byte (which is a subclass of Number)
10:34ohpauleezbut you can do in-part casting, by getting the integer value, (Integer), and then pushing it to byte (Byte)
10:34ohpauleezif you used just primitives, you could directly do (byte) on a char
10:34rhickeydo we want a tag of 1.1 or 1.1.0 for the release git tag?
10:35ohpauleez1.1.0 is my vote, fwiw
10:35hiredmanseems like it should match whatever the *clojure-version* is
10:36cemerickhiredman: yeah, I was fundamentally just noting that int is polymorphic, even over Objects. The int/byte fns are fns, so there's no primitives anyway.
10:38ohpauleezcemerick, if you can represent the single chars as Strings, you might be able to parse them directly into bytes.
10:40stuartsierrarhickey: 1.1.0
10:55stuartsierraBy the way, 1.1.0 isn't in Maven central yet. Has it been submitted?
10:55rhickey1.1.0 tag is up
11:36technomancythe-kenny: unfortunately there isn't one
11:41stuartsierraContrib 1.0.0 Release Candidate 1 is up.
11:41stuartsierraZIP: http://clojure-contrib.googlecode.com/files/clojure-contrib-1.0.0-RC1.zip
11:42stuartsierrabranch: http://github.com/richhickey/clojure-contrib/tree/1.0.x
11:42stuartsierratag: http://github.com/richhickey/clojure-contrib/tree/1.0.0-RC1
11:49the-kennytechnomancy: :(
12:07the-kennyStrange - paredit is broken in my repl
12:12noidithe-kenny, I've never had any luck with using paredit and clojure-mode in the repl :P
12:12the-kennynoidi: paredit is partly working, never tried clojure-mode
12:12the-kennynoidi: () works perfectly, removing of [] is broken
12:30stuartsierraContrib 1.1.0 Release Candidate 1 is up.
12:31replacathe-kenny: I've had the same issue with paredit at the repl. Never dug in enough to figure it out. But it's not just you!
12:31the-kennyreplaca: mh ok
12:31the-kennyMaybe I'll try to fix it someday
12:36arohnerthe-kenny: paredit mode works for me on the slime repl
12:36arohnerI don't have a hook for it yet, so I had to do M-x paredit-mode
12:36arohnerbut since my repl buffer never closes, I only had to do it once :-)
12:36the-kennyarohner: And if you insert a [, will it insert the missing ] and if you delete the [, will it delete the ] too?
12:36arohneryes
12:37the-kennyThat's strange
12:37mithraicHi. So, I'm new to the clojure world, but have been around Scala for a longish while.
12:37mithraicWe have a raging debate at work at the moment whether to implement something new in Scala or Clojure.
12:37mithraicArguments for Scala are relative syntactic familiarity, maturity, and option-to-be-imperative
12:37mithraicarguments for Clojure are that syntax-less-ness will keep things tidy and quicker to learn, and that STM will help avoid snafus in going parallel
12:37arohnermithraic: you know which side this channel will come down on :-)
12:37mithraicAny comments/thoughts?
12:38mithraicI'm genuinely curious. I think both languages are quite nice (though i'm less familiar with clojure)
12:38woobymithraic: i was obsessed with scala for a few months, but core simplicity of clojure is what's sold me and i'm not looking back
12:38woobymithraic: i haven't used either for 'production' but i do have a new personal rule, avoid any language that allows you to solve towers of hanoi with the type system
12:39Chousuke:P
12:39Chousuke~scala
12:39Chousukeclojurebot: scala
12:39Chousukehm
12:39Chousukeclojurebot: :(
12:39clojurebotExcuse me?
12:40mithraicwooby: :)
12:40technoma`mithraic: option-to-be-imperative is only going to feel like an advantage for a month at most. then it's an albatross around your neck.
12:40ChousukeYou *can* write imperative code in Clojure. it's just done through Java interop, and it's not very idiomatic at all :/
12:42mithraicso, one thing that's come up for me writing in Python (bear with me)
12:42stuartsierraI think it comes down to type systems. If you like complex static typing (some people do) then Scala it is. If you like dynamic types, go for Clojure.
12:42mithraicis (just where stuartsierra is headed)
12:42woobymithraic: out of curiosity, do you have any people familiar with lisp on your team?
12:42mithraicis that type systems can be a kind of guaranteed-to-be-correct documentation
12:42the-kennyBut it shouldn't happen with :pre and :post :)
12:43mithraicwhich we've found frustrating sometimes in python -- the 'where did this thing come from' problem
12:43mithraicwooby: no, though the fella leading the charge for clojure learned LISP from alan perlis back in the day
12:43ChousukeWell, python is different from clojure in that it still has classes
12:43stuartsierraDynamic typing allows you to be careless sometimes, it's true.
12:43ChousukeIdiomatic clojure code works mostly with simple values
12:44Chousukemaps, vectors, lists, and other simple things.
12:44mithraicyeah, though don't you end up with maps-of-lists-of-vectors and that sort of thing?
12:44_fogus_mithraic: I've been using Scala professionally for about a year and a half, and Scala type decls have been pretty nice as far as documentation go
12:44Chousukemithraic: sometimes
12:45mithraicthe work, incidentally, would mostly be with probability distributions of various kinds. bayesian inference, EM, MCMC, that sort of thing.
12:45Chousukehmm
12:46mithraichow does clojure do with JVM primitive types?
12:46mithraicsorry for being so ignorant
12:46Chousukeyou can use them in loops.
12:46stuartsierraWriting *efficient* math-heavy code in Clojure can be tricky, and often loses the functional/immutable benefits.
12:46Chousukefunction arguments are always boxed.
12:46Chousukethere's incanter though.
12:47stuartsierraChousuke: Yes, but Incanter uses Java matrix libs.
12:47ChousukeWell, yeah.
12:49stuartsierraI would suggest writing low-level numeric routines in Java and using Clojure as a high-level driver.
12:49woobythat's a cool approach
12:51ChousukeI think primitive support for functions will happen after cinc, and the timeline for that is still unknown ;P
12:51stuartsierraYes, I believe we will get to the point where you can write fast numeric routines (not just loops) in Clojure, but that point is still some ways off.
12:52_fogus_mithraic: Here a post comparing Scala and Clojure... totally fair comparison too. ;-) http://blog.fogus.me/2010/01/04/comparing-lines-of-code-scala-and-clojure-fud-version/
12:53Chousuke;P
12:54ohpauleezWell, fwiw, I was co-learning scala and clojure
12:54ohpauleezand immediately fell in love with Clojure
12:54mithraic_fogus_: very nice.
12:54ohpauleezand it has since slowly risen to be one of my favorite languages to work in
12:54replacaQ: does anyone know how to enumerate a set of resources in your classpath? I am loading a directory ./templates/static/..., into my jar and I want to be able to spit all those files to a particular location at runtime. I know how to do that once I have a list of resource names, but I would rather not hard code that list.
12:55piccolinofogus, that page is basically why I left Scala for Clojure.
12:55piccolinoFelt like I was still writing Java.
12:55_fogus_piccolino: Of course, that blog post is a joke. That's about as far from idiomatic Scala as you can get without breaking the compiler.
12:56piccolinoOh, I didn't read it.
12:56piccolinoThat is still in line with my experience of Scala, though.
12:58_fogus_Scala's biggest fault IMO is that it provides too many ways of doing complementary things -- which can trip people up
12:58stuartsierrareplaca: You can't enumerate the classpath.
12:59piccolinoI also didn't like that the type system can start to fail you with things you can't do, due to the type erasure that happens.
12:59mithraicyeah, it has a pastiche of syntactic styles.
12:59mithraicwell, the Manifest support can patch up erasure to a pretty good extent.
13:00piccolinoYeah, I guess I was doing the thing they can't do.
13:00piccolinoCan't remember exactly, though, but I tried manifests.
13:00mebaran151it seems like functional and object oriented programming have always been opposites: objects are all about encapsulated state while functional programming is all about avoiding that state to begin with
13:01replacastuartsierra: so I need to know the exact name of a resource in order to get it?
13:01woobymithraic: have you seen the latest rich hickey talk, 'are we there yet?'
13:01Chousukeoh, right.
13:01ohpauleezwooby: link?
13:02woobyhttp://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey
13:02ChousukeRich's talks are good for converting people :P
13:02ohpauleezthanks
13:02ohpauleezhe converted me :)
13:02mebaran151he gives amongst the best presentations of any programmer I've seen
13:03mithraicwooby: thanks, i'll look
13:03woobyi agree, this latest one completely floored me
13:03Chousukemebaran151: well, you could have Objects that don't hold any *mutable* state
13:03woobyhe's almost like the charles manson of programming talks, i'm totally under his spell now lol
13:03ohpauleezhahaha
13:03stuartsierrareplaca: yes
13:03somniumdo delays/lazy-seqs qualify as mutable?
13:04stuartsierrareplaca: or just pull directories from the classpath and traverse the filesystem
13:04Chousukesomnium: lazy seqs are persistent. they might be created from a mutable source, but once realised, the seq itself never changes... so, no?
13:04Chousukesomnium: delays are similar.
13:04rhickeysomnium: no, since you can't go back and change them
13:06mebaran151Chousuke, then Objects are basically scoping modifiers, which are probably best handled via things like lets
13:07somniumrhickey: is there a reasonable way to approach implementing them via deftype at present?
13:09rhickeysomnium: ah, you mean, do they use mutation internally - yes, they do, and no, you can't implement via deftype at present
13:10replacastuartsierra: 'k, thanks!
13:12somniumrhickey: I wrote a clojure-special-form to js compiler that gingerly macroexpands forms and emits js, and it works better than I anticipated. I tried to write a macro to emulate deftype using closures for immutability, but lazy-seq I could only manage with a mutable field.
13:13rhickeysomnium: delay and lazy-seq do caching that requires a once-only mutation
13:14rhickeyI haven't yet decided how to expose support for this - early versions of reify had volatile support, but that's kind of raw
13:16somniumrhickey: related to license, Im hoping to put the core compiler on github in the near future under eclipse, but to get the seq fns from core working I had to directly edit clojure.core, is it okay just to include clojure's own license in that?
13:17somniumrhickey: though they both emit a form of clojure, I dont know much about licenses and Im not a contributor so I thought I should check
13:20rhickeysomnium: a modified/derived version of clojure.core will fall under the original Clojure license
13:32somniumrhickey: roger, thanks
13:33cemerickmy code is so littered with -> and ->>, I'm starting to worry it constitutes a smell.
13:33LauJensencemerick: Thanks for that 'all my functions take 316 args' - it was a good read :)
13:34cemerickSure. Never thought it would bring out the hordes to the degree that it did. ;-)
13:35jasappcemerick: link?
13:35cemerickjasapp: http://muckandbrass.com/web/display/~cemerick/2009/12/30/All+my+methods+take+316+arguments%2C+and+I+like+it+that+way
13:35jasappcool, thanks
13:36chousercemerick: I've noticed a trend that direction in my code as well.
13:37chousercemerick: I'm not at all sure it's bad though. It's actually a form of strictness -- everything within ->> has to follow the pattern.
13:37chouserso when you're reading it, that's one less detail you have to keep in mind. You know each step will take a seq and apply if via the ->> rules
13:38cemerickoh, and then -?>
13:38cemerickwe just need -?>> now
13:38mebaran151would the alternative huge number of let bindings be smell?
13:38cemerickmebaran151: oh, that'd definitely be worse. I just worry when I start edging towards using something too much.
13:39rhickeyI think the placeholder versions of -> and ->> are on much shakier footing than -> and ->>
13:39mebaran151I find breaking things in let pipelines makes it easier for me to remember what I was doing
13:39cemerickrhickey: placeholder?
13:39chouser-$>
13:39chouseror whatever. -%>
13:39_fogus_rhickey: You mean -$> -$>> ?
13:39rhickeyvarious people have proposed -$> etc
13:40cemerickoh, right
13:40_fogus_nevermind
13:40rhickeyI'm opposed
13:40_fogus_As am I
13:41cemerickclojure.template opened the door, certainly.
13:41_fogus_-$> -$>> presuppose too much information on the pipeline contents
13:42chouseralso could never work well with destructuring, so better to just leave them out.
13:42rhickey-> has a clear analogue in concatenated member calls, and ->> in stream pipes, they are easy to understand
13:42LauJensenrhickey: Is the funding graph on Cloure.org updated?
13:43_fogus_Question, is there any reason why -> and ->> not do -?> and -?>> by default?
13:43rhickey_fogus_: I don't understand
13:44rhickeyLauJensen: it's pretty close to current
13:44_fogus_That is, besides the fact that it's probably bad form to swallow exceptions
13:44LauJensenk
13:44ohpauleez_fogus_: I think that's the reason
13:44ohpauleezPersonally, I want to know when the system fails and how it fails, and optionally tell it pass me null
13:45_fogus_ohpauleez: I thought I was missing something else
13:45ohpauleezahhh, nope you got it
13:45chouser_fogus_: -?> doesn't actually swallow exceptions though, right?
13:46ohpauleezrhickey: When I get my signing bonus for this new job, I'm writing out my check :)
13:46chouserhaving -?> as the only behavior might be a problem since -> doesn't generally assume anything about the type of the object being passed along.
13:46rhickeyohpauleez: great - thanks!
13:46ohpauleezalso, the offer still stands whenever you want me to do corporate outreach
13:47chouserI guess ->> techinically doesn't either, but if it's used for something other than a seq I'd be a bit suspicious. Which suggests that having ->> short-circuit on nil be default might not be so bad.
13:47rhickeychouser: what if the last call is into?
13:48chouser:-(
13:48chousernevermind.
13:49_fogus_chouser: Hmmm, good question. I always assumed that it did, which is why I never used it. I thought it was equivalent to `(try (-> ~@forms) (catch NullPointerException _# nil))
13:50chouser_fogus_: It appears to just check the return value at each step, and if it's nil, bail out.
13:52chouser.?. is I suppose the most useful by default, since (.foo nil ...) is sure to throw something.
13:52_fogus_chouser: Cool. Which is another way to avoid some NPEs
13:53chouserbut knowing where it threw, that is what stage failed, might be really useful, so ... bleh.
13:53_fogus_agreed
13:56the-kennystuartsierra: What value? nil?
14:14LauJensen~source -?>
14:15LauJenseneeh?
14:15fliebelHey, cool, is -?> in contrib?
14:16LauJensendefnilsafe is a cute macro
14:17fliebelHow about a variant of -$> ?
14:18ieureHey, I just wrote my first practical Clojure app. I’d really like it if some of you dudes could take a look and let me know what I could do better.
14:18ieureIt’s at http://github.com/ieure/Twidoop
14:24LauJensenieure: Looks nice and well layout - You seem to use excessive 'do' statements though. 'when' and 'doseq' don't need it
14:24LauJensens/layout/layed out
14:28pjacksonieure: no tests :)
14:30ieurepjackson, Yeah - that’s going to get fixed.
14:31ieureLauJensen, Okay. I thought it was idiomatic to wrap side-effecting stuff like the print and flush calls in do - is that not the case?
14:32LauJensenNo, you can use do with statements which dont take entire bodies, like (if (= x 5) (do (stmt 1) (stmt 2)) (stmt 3))
14:32LauJensenbut with 'when' its implicit (when (stmt 1) (stmt 2)), no need for do
14:32technoma`ieure: doseq/when have the same implications
14:32ieuretechnoma`, Okay.
14:33technoma`when you see them, you know there will be side-effects involved
14:33tolstoyIf I have a big string number, "342342342342342342", what's the good Clojure way to turn that into a number?
14:33LauJensen,(Integer. "342342342342342342")
14:33clojurebotjava.lang.NumberFormatException: For input string: "342342342342342342"
14:33LauJensenno luck
14:33tolstoyIs there a nice type independent way to do it?
14:34ieuretechnoma`, I know doseq always indicates side-effects, but is that really true of when? I thought that was just basic flow control.
14:34LauJensen,(BigInteger. "342342342342342342")
14:34clojurebot342342342342342342
14:34tolstoy(As in, I don't care if it's an Integer, Long or BigNumber.)
14:34stuartsierratolstoy: read-string
14:36tolstoyAh, okay.
14:36fliebelWhat is some processor intensive stuff I can write in a few lines to test something?
14:37the-kennyfliebel: Fibonacci numbers
14:37fliebelthanks
14:38technoma`ieure: actually that can be a style thing. multiple statements in when does indicate side-effects, but some people use when for single-body clauses rather than if
14:39ieuretechnoma`, Got it.
14:40ieureWell, I’m glad my first real foray into Clojure isn’t terrible. It’s been handling the full Twitter firehose for around a week now, and has been 100% stable. Which rocks pretty hard.
14:41stuartsierrafliebel: searching for primes
14:46tolstoyIs there an equivalent to the Math.round for Clojure? Just want the integer part of a division on a big, uh, integer.
14:47tolstoyI get back: 43535345435345/10, which is kinda not what I really need in order to convert that to a string.
14:47Knekk try (Math/round 1.2)
14:47Knekk,(Math/round 1.2)
14:47clojurebot1
14:47hiredman,(.numerator 43535345435345/10)
14:47clojurebot8707069087069
14:47KirinDavetolstoy: Any java method is obtainable in clojure.
14:48hiredman,(pr-str 43535345435345/10)
14:48clojurebot"8707069087069/2"
14:48hiredman,(read-str "8707069087069/2")
14:48clojurebotjava.lang.Exception: Unable to resolve symbol: read-str in this context
14:48hiredman,(read-string "8707069087069/2")
14:48clojurebot8707069087069/2
14:49tolstoyOkay. I was hoping there was more Clojure-like ways to do some of this. No prob.
14:50mebaran151is there anyway to increase the size of the agent thread pool?
14:52hiredmanwhy?
14:54fliebelWhat the heck does this mean? Exception in thread "main" java.lang.ClassFormatError: Invalid method Code length I admit I'm doing stuff you usually don't...
14:54hiredmanyour functions are too big
14:54fliebelhiredman: what is the limit of a function?
14:55hiredmanfliebel: ideally you should look at your function and say "omg, this is three pages long, maybe I should break it up"
14:55hiredmanin the non-ideal case, the length is restricted to whatever the jvm bytecode limit is
14:56fliebelhiredman: the truth is that I'm using apply with about 100 seqs turned into one let ;)
14:56hiredmanhttp://bugs.sun.com/view_bug.do?bug_id=4262078
14:56fliebeluuuhm 1000
14:56hiredmanthat sounds pretty horrible
14:56hiredmanwhy would you put yourself through that?
14:57fliebelhiredman: it is, but don't worry, I'm not going to use it. I wanted to see what would happen... and get reliable numbers for (time) by doing it an awful amount of times.
15:00ordnungswidrighi all
15:01fliebelhiredman: doing fibonacci numbers with -> is not good :D
15:05hiredmanfliebel: why?
15:07unfo-why does clojurebot use /notice?
15:09hiredmandarned if I know...
15:13fliebelhiredman: for fun...
15:13hiredmanfliebel: why is it not a good idea?
15:14fliebelhiredman: because that gave the above error.
15:14fliebelActually it was not -> but a custom macro… I'm now trying -> but I'm afraid that'll blow the stack.
15:24fliebelIn which order are macro's expanded?
15:24somniumfliebel: outside-in, opposite of fns
15:25somniumfliebel: or rather, as the reader reads them, contrary to fn evaluation
15:25pjacksonIs there a function to recursively macroexpand a form?
15:25somnium,(doc mexpand-all)
15:25clojurebot"clojure.contrib.macro-utils/mexpand-all;[[form]]; Perform a full recursive macro expansion of a form."
15:25fliebelsomnium: So can I write fn in a -> macro?
15:25pjacksonThanks.
15:25somniumfliebel: sure, just wrap in extra parens
15:26fliebelsomnium: huh?
15:26somnium(unless youre passing it its argvec through some convoluted mechanism)
15:26rbehi
15:27somnium,(macroexpand '(-> [foo] (fn (print foo))))
15:27clojurebot(fn* ([foo] (print foo)))
15:27somnium(macroexpand '(-> [foo] ((fn (print foo)))))
15:27somnium,(macroexpand '(-> [foo] (fn (print foo))))
15:27clojurebot(fn* ([foo] (print foo)))
15:27somniumbah
15:27somnium,(macroexpand '(-> [foo] ((fn (print foo)))))
15:27clojurebotjava.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol
15:28rbeneed some help... how can i get the name of a function when no var exists?
15:28somnium,(macroexpand '(-> [foo] ((fn [x] (print x)))))
15:28clojurebot((fn [x] (print x)) [foo])
15:29rbeexample:
15:29rbe,(let [f [+ - *]] (for [y f] {(:name (meta (var y))) (y 1 2)}))
15:29clojurebotjava.lang.Exception: Unable to resolve var: y in this context
15:29fliebelsomnium: I think I understand…
15:29somniumfliebel: sorry for the mess, ^^ thats what I meant by extra parens are needed
15:30fliebelsomnium: Unless I want to add something to the final fn* thing...
15:30somniumfliebel: right
15:31somnium,(let [f '[+ - *]] (for [y f] {(:name (meta (resolve y))) (y 1 2)}))
15:31clojurebot({+ 2} {- 2} {* 2})
15:32rbethx somnium
15:33somniumrbe: you have to have the symbol though, if youve got the actual fn (as an argument for example), its not possible afaik
15:33rbehm i get: java.lang.ClassCastException: clojure.core$_PLUS___4509 cannot be cast to clojure.lang.Symbol with your example??
15:34somniumrbe: the vector is quoted
15:34technoma`does anyone else prefer not using recur in contexts in which TCO is not required?
15:34rbeah ok
15:34technoma`I have this notion in my head that using recur is a way of signalling to readers "this operation must not consume stack", but I'm not sure if that's a convention or something I just made up myself. =)
15:35hiredmanbest just use reduce and map and never think about it
15:36rbesomnium: when i use that in my code the functions (y in my example) does not get evaluated..it's always nil
15:36rbejust my own functions instead of + - *
15:38somniumrbe: if you do (defn foo ...) and then (resolve 'foo) it should work
15:40rbesomnium: now the name of the fun resolves to nil...
15:42rbewith (resolve foo) it worked... but the (foo param) gets me nil....
15:42hiredmanfunctions don't have names
15:43Knekkremember, there is no function.
15:43KnekkNeo
15:43hiredmanthere are functions
15:43hiredmanthey just don't have names
15:43rbebut a var has got...
15:43Knekkmust be a glitch in the Matrix
15:44hiredmanfunctions are values, like the integer 1, which does not have a name, but can be bound to a name
15:44pjacksonKnekk: You're thinking of spoons, I think.
15:44Knekkoh right
15:44Knekkspoons
15:44pjacksonIsn't it ironic when all you want is a spoon but all you can find is a function.
15:45hiredmanwhat is a spoon?
15:45Knekk(defn spoon [] nil)
15:45rbeok... i define a list of functions (def funs [fun-a fun-b])
15:45hiredmanthere is no spoon! only a function that transforms the present state into a future state where a spoon apears to have operated
15:45somnium:-)
15:46rbethen i want to apply every function to one argument, producing a map with {:fun-name result}
15:46hiredmanrbe: fun-a is a a fn or a var, or a symbol resolved to a var, or what?
15:46somniumrbe you need the symbols, which can resolve to vars, which can resolve to fns
15:46rbefun-a was defined earlier by (defn fun-a [arg] ...)
15:47fliebelhiredman: Using -> indeed causes a "Exception in thread "main" java.lang.StackOverflowError"
15:47somniumso unquoted fn-a is the fn that the the var named by 'fn-a resolves to
15:47somniumnot a fn named fn-a!
15:47somniumrbe: what is the sound of one hand clapping?
15:48hiredmanrbe: basically, you need to quote the vector to prevent resolution so you can do your own resolution
15:48arohnerfunctions do have names
15:48arohner(fn foo [] ...)
15:49rbeok when i quote the vector the name resolution succeeds, but the function call no longer takes place... how to do it then?
15:49hiredmanarohner: that is a self reference and entirely opaque
15:50hiredmanrbe: I don't know I haven't really been paying attention to the code you are using
15:50rbehere it some code
15:50rbe(defn fun-a [arg] ... )
15:50rbe(defn fun-b [arg] ...)
15:50hiredmanpastebin
15:51rbeok ...
15:51hiredmanI imagine you are now applying the symbols as functions
15:51hiredmanwhich won't give you an error because symbols are IFns
15:51hiredmanbut it won't give you the results you want
15:52hiredman,((resolve '+) 1 2)
15:52clojurebot3
15:52hiredman,('+ 1 2)
15:52clojurebot2
15:52hiredman,(:+ 1 2)
15:52clojurebot2
15:52rbehttp://pastebin.com/d2b5b571d
15:53hiredmanrbe: so when you quote the vector, the name f in the for now refers to a symbol, not the function in the var named by that symbol
15:53hiredmanso you need to resolve f and apply
15:54rbeah the resolve again... thanks a lot
15:55arohneror just ((resolve 'foo) 42)
15:59fliebelI can generate fibonacci number up to 900 faster than contrib :D
16:00fliebelFor low numbers mine is at least twice as fast, for 900 10/11 msec and over 900… stacktrace.
16:02hiredman~fib
16:02clojurebotExcuse me?
16:02hiredmanclojurebot: fib is reply See #haskell
16:02clojurebotIn Ordnung
16:02hiredmanbah
16:04fliebelWhat do you think about it? http://gist.github.com/268866
16:05hiredmanfliebel: I will be impressed when you find something that blazing fast generation of fibs is good for
16:06fliebelhierdman: I won't, my code is another hack, but it was fun...
16:06fliebelI think it's more useful to be able to have fibs 'til infinity.
16:07hiredmanhow is that useful?
16:09fliebelhiredman: I think there are more applications needing a fib above 900 than applications depending on fib speed, but I also think there are very few applications relying on fib at all..
16:09fliebelhiredman: I just wanted to write fib using -> :D
16:09hiredmanfliebel: name one
16:10fliebelhiredman: I don't know any application using fib, except rosseta style stuff.
16:10arohnerfliebel: that is pretty cool
16:10fliebelarohner: thanks
16:10arohnerpersonally, I learned something from (-> (take n infinite-seq))
16:11arohnerwhy is that a macro though?
16:11fliebelarohner: what?
16:11arohnerjust the idiom
16:11arohnerit was new to me
16:11fliebelarohner: It's a macro because -> is :D
16:12fliebelarohner: I could not do the ~@ magic with a normal function.
16:13ieureRight - you can only use that with syntax-quote, I think.
16:16arohnerwhat's the process for committing to contrib?
16:18hiredmanbasically the same as for clojure
16:19arohnerso you have to get someone to commit for you?
16:19arohnermake a ticket, etc?
16:20fliebelhiredman: that is… writing a letter to rhickey containing your usernames and a signed license agreement?
16:20hiredmanyes
16:21hiredmanfliebel: it's not a "letter" it's the contributors agreement
16:21hiredmantechnoma`: have you seen http://blog.bigsmoke.us/2007/06/11/microsoft-batch-file-meets-bash-shellscript ?
16:21fliebelhiredman: so you download a pdf somewhere?
16:22hiredmanclojurebot: ca?
16:22clojurebotCA is Contributor Agreement: http://clojure.org/contributing
16:34technoma`hiredman: that is fiendish
16:45hiredmanhttp://www.music.mcgill.ca/~sinclair/content/blog/a_functional_game_loop_for_glut_in_scheme_using_continuations mmmm
17:05arohneris there a way to detect that a var is in a binding? i.e. doesn't have its root value?
17:06arohnerah, .getRoot
17:08optimizerrlwrap java -Dswt.library.path=/usr/lib/jni clojure.main <-- great for running "clojure"
17:08optimizerbut how do I get "clojure test.clj" to run test.clj?
17:08optimizerinstead of haing ot copy/paste in tets.clj?
17:09arohner,(doc clojure.main/main)
17:09clojurebot"([& args]); Usage: java -cp clojure.jar clojure.main [init-opt*] [main-opt] [arg*] With no options or args, runs an interactive Read-Eval-Print Loop init options: -i, --init path Load a file or resource -e, --eval string Evaluate expressions in string; print non-nil values main options: -r, --repl Run a repl path Run a script from from a file or resource - Run a script from standard input -h, -?, --help Print this help m
17:10arohnerit looks prettier on your own screen
17:10optimizerwhoa, much nicer
17:10arohnerbut you should be able to just add test.clj to the cmd line, assuming it's in your classpath
17:11optimizerarohner: it works; nice; thanks
17:12arohnergreat
17:19michaeljaakahi clojure people
17:19mebaran151_what's the best way to recursively list files in a directory in Clojure?
17:20hiredman,(doc file-seq)
17:20clojurebot"([dir]); A tree seq on java.io.Files"
17:20hiredmantree-seq
17:20michaeljaakaI want to write qsort just as learning example of Fp
17:20hiredmansomeone file a bug
17:20michaeljaakahttp://gist.github.com/268915
17:20michaeljaakahave something like this
17:20michaeljaakabut can't find out why getting exception
17:20michaeljaakaanyone would like to help?
17:25optimizeris there a book like "Beautful Clojure" that just shows lots of beautiful Clojure code?
17:28somniumoptimizer: maybe print out clojure.contrib.monads?
17:28mitchellhoptimizer: No official book like that yet, I would say Clojure is still a bit too new :)
17:29michaeljaakaok, I have manage to fix my code
17:29michaeljaakathis is it http://gist.github.com/268924
17:29michaeljaakadon't know why but nested let didn't work
17:30optimizerhow do I get swt.jar?
17:30hiredmancore.clj is usually pretty nice
17:31hiredmanoptimizer: I believe swt has some native code components
17:31hiredmanmichaeljaaka: you have too many parens
17:31michaeljaakanoticed that, thanks
17:32michaeljaakaclojure people you are great!
17:37mebaran151_hiredman, when did treeseq get added?
17:38hiredmanlong long ago in the great before time
17:54jasappdoes anyone know if there is code somewhere to go from an xml zipper back to xml?
17:54mebaran151_I learn something new every day
17:55hiredmanclojure.xml/emit
17:56jasappemit doesn't work on zippers, does it?
17:59jasappyeah, it doesn't look like it
18:00hiredmanwell, you call root on the zipper
18:01jasappnice, thanks
18:01hiredmanemit emits to *out* so you might want to rebind it or use with-out-string
18:18tolstoyWhen slime-compiling a file, using some code in another module like (ns bar (:use lib.foo)) what has to be in the classpath?
18:19tolstoyDo each of your clj files have to be on the classpath as well as each jar?
18:19tolstoyIs there something about Slime that makes you not able to compile files that way? Maybe need to load it or something first?
18:21hiredman~namespace
18:21clojurebotamespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it
18:23somniumtolstoy: you should only need bar.clj and lib.foo.clj/jar/class on the classpath
18:23tolstoyHm.
18:23tolstoyWhat about when using slime (with a standalone swank using slime-connect)?
18:24somniumtolstoy: the classpath is the classpath is the classpath afaik
18:24tolstoyI mean, I "get" namespaces, which is why I don't understand why I can't ^c^k.
18:24hiredmanwhat makes you think you get namespaces?
18:25tolstoyhiredman: Ah, you're saying they're inherently incomprehensible as currently implemented?
18:25hiredmanno
18:25tolstoyI have ${PWD}/src/lib/foo.clj on the classpath. I have ${PWD}/src/lib on the class path.
18:26tolstoyIn foo.clj, I have (ns lib.foo ....)
18:26somniumwhats the warning on single-legment namespaces about?
18:26hiredmanand thus it is proven
18:26hiredmansomnium: don't use them and expect them to work
18:26somniumhmm
18:26somniumhiredman: when do they break?
18:27tolstoyhiredman: Ah, thanks for the help! Your snark is clearing it right up for me!
18:27hiredmanit has to do with how namespaces are translated into classes/packages and the java default package
18:27hiredmantolstoy: hey, you where the one that claimed to understand namespaces
18:28hiredmandid you read what clojurebot barfed out for you at all?
18:28tolstoyhiredman: I don't understand namespaces at all. They mean nothing to me. I *thought* I was complying with exactly what clojurebot said.
18:29hiredmanas an excercise in communication, can you repeat back to me what you think clojurebot said?
18:29tolstoyAh, my classpath doesn't have to root of the package hierarchy in it.
18:30somniumhiredman: hmm, I haven't encountered a problem thus far, do you know an example offhand where they break? (I was just thinking to use one, so this is good timing)
18:30hiredmansomnium: I don't
18:31Chousukesomnium: single-segment namespaces are prone to collision. I think that's about it :P
18:31tolstoyhiredman: I made a typical mistake (that I've not made in years. Sorry!
18:31tolstoy~classpath
18:31clojurebotclasspath is (System/getProperty "java.class.path")
18:31hiredmanthere was some change in AOT compilation long ago that brought this about and the move from "clojure" to "clojure.core"
18:31somniumChousuke: is that all? :D
18:31somniumwell, a little preemptive renaming never hurt anyone I guess
18:32ChousukeI guess the clojure standard is to use two-segment namespaces.
18:32Chousukeclojure.core etc ;P
18:33ChousukeI guess single-segment namespaces would also break when gen-classing
18:34ChousukeI don't really know the java package/class naming stuff and how namespaces relate to those, so I can't say for sure.
18:34hiredmanclojurebot: logs?
18:34clojurebotlogs is http://clojure-log.n01se.net/
18:36hiredmanhttp://clojure-log.n01se.net/date/2008-11-13.html#14:28 <-- there'ish
18:36hiredmannot very in depth though
18:37the-kenny#{"fleetdb"} :D
18:38the-kennyLooks like clojurebot is using sets there :)
18:38Chousukeheh
18:38hiredmansets and clojure.set/difference
19:34aldebrnAnyone yet thought to create a units system in Clojure using metadata? So measurements can be represented as m/s vs ft/hr, radians vs degrees, etc.?
19:36technomancyaldebrn: unfortunately you can't add metadata to final classes yet. =(
19:39aldebrnI don't know what final classes are in Clojure but :(
19:42technomancyaldebrn: java defines its numeric classes as "final", which means they can't be extended
19:48aldebrnOh, that tears that idea :-/
19:51arohneraldebrn: though you'll be able to do that after metadata is a protocol
19:52arohnermaybe
19:52aldebrnClojure is such a fast-moving target!
20:42ndimidukfrom within (ns foo (:gen-class)), how do I access foo.class?
20:44ndimiduki'd like to pass the .class of the generated class as a parameter. saying (. instance method foo) doesn't work.
20:45ndimidukcompiling throws an exception saying Unable to resolve symbol foo
20:52optimizeri have swt.jar installed; how do I get clojure to recognize and use it?
21:00chouserndimiduk: you probably need a package name on that class. (ns pkg.Foo (:gen-class))
21:00chouserthen you should be able to use pkg.Foo as the class anem
21:00chousername
21:00chouseroptimizer: just make sure that swt.jar file is mentioned in your classpath
21:08arohnerI just fixed a bug in my code caused by improperly using for. I should be "old enough" by now
21:10hiredmanI think I used for once in clojurebot
22:06joshua-choiHey, is there a function so that "space" -> \space, "newline" -> \newline, etc.?
22:11chouser,(read-string (str \\ "newline"))
22:12clojurebot\newline
22:14chouser,char-escape-string
22:14clojurebot{\newline "\\n", \tab "\\t", \return "\\r", \" "\\\"", \\ "\\\\", \formfeed "\\f", \backspace "\\b"}
22:14tomojthat's slick
22:15chouser,char-name-string
22:15clojurebot{\newline "newline", \tab "tab", \space "space", \backspace "backspace", \formfeed "formfeed", \return "return"}
22:17chouser,(some (fn [[c s]] (when (= s "newline") c)) char-name-string)
22:17clojurebot\newline
22:20chouserjoshua-choi: take your pick
22:20hiredman,((clojure.set/map-invert char-name-string) "newline")
22:20clojurebot\newline
22:23alexykis there anything in stdlib to merge two sorted vectors in sorted order?
22:26chouser,(reduce into (sorted-set) [[1 2 3] [4 5 6]])
22:26clojurebot#{1 2 3 4 5 6}
22:26piccolin1We would all be totally screwed without chouser.
22:26hiredmanthat would lose duplicates
22:26chouserI suppose merging two sorted vectors should be possible in O(n)
22:26chouserah, good point
22:26chouserand that reduce is O(n log n)
22:27hiredmansince into uses reduce?
22:27chouseralexyk: I don't know of anything that does exactly what asked.
22:27chousersounds interesting though.
22:27piccolinoShouldn't it be possible to insert into a sorted vector without a lot of copying with the vector structure?
22:28piccolinoIf that function were written?
22:28chouserhiredman: no, because each item is inserted individually into the sorted set -- doesn't leverage the fact that the inputs are sorted.
22:28chouserpiccolino: nope, can't change either of the input vectors, so you'd still need a whole new vector
22:29piccolinoOh, whoops, I was just thinking on a slightly related note, about a single item being inserted.
22:29piccolinoAnd insert in the persistent sense.
22:31chouserhm.. could operate on seqs -- two in, one out
22:33alexykhiredman: I can lose dups allright
22:34alexykbut, I may as well keep them, so elegance would win
22:35hiredmanmerging sorted vectors is never going to be elegant
22:40lisppaste8Chouser pasted "sorted-seq-merge" at http://paste.lisp.org/display/93006
22:40joshua-choi@chouser: Thanks a lot; char-name-string was exactly what I needed
22:41hiredmana vector is already an ordered associative thing, and each element is associated which it's place in order
22:41chouseralexyk: that should do it, though it might be faster to just stuff your two vectors into an array and call Java's sort method on it.
22:44alexykthanks!
22:45chouserwasn't as interesting as I'd hoped. heh.
22:47chouserlazy-seq takes all the fun out of it
22:49joshua-choiHow does one invert a map: {:a 2, :b 3} -> {2 :a, 3 :b}?
22:51hiredmanif you scrollup you will see
22:51arohner,(doc clojure.set/map-invert)
22:51clojurebot"([m]); Returns the map with the vals mapped to the keys."
22:51hiredmanspoiler
22:51joshua-choiWow, I didn't see that; thanks
23:11arohnerparedit is great. now I want it to auto-indent my code