0:04 brennanc: is there anything like find-doc but that has just the function names. It's really hard to read it when it outputs 20 pages
0:09 Jedi_Stannis: brennanc: not that I know of, shouldn't be too hard to write one
1:27 joha1: I'd like to use a syntax quote which doesn't try to resolve symbols. Is there any easy way of achieving this?
1:30 hiredman: uh, quote?
1:30 ,'(a b @(c d))
1:30 clojurebot: (a b (clojure.core/deref (c d)))
1:30 hiredman: or not
1:31 why do you want syntax quote?
1:33 joha1: building a function that generates code from a template, and I want to insert some values deep inside the vector. Perhaps there is a better way
1:35 hiredman: zippers
1:36 joha1: what i'm looking for is something like `(xxx (yyy ~zzz))) -> (xxx (yyy 3)), but without symbol resolution (assuming zzz = 3)
1:36 zippers, eh? I'll see what I can find
1:36 hiredman: clojure.zip
1:37 ,(require '[clojure.zip :as zip])
1:37 clojurebot: nil
1:37 hiredman: ,(zip/zip-vec '[a b c])
1:37 clojurebot: java.lang.Exception: No such var: zip/zip-vec
1:37 joha1: yes of course, that should work. I looked into zip just a few hours ago. thanks for the hint
1:37 hiredman: ,(-> '[a b c] zip/vec-zip zip/root)
1:37 clojurebot: java.lang.Exception: No such var: zip/vec-zip
1:38 hiredman: bah
1:39 ,(ns-interns (find-ns 'zip))
1:39 clojurebot: java.lang.NullPointerException
1:40 hiredman: ,(find-ns 'zip)
1:40 clojurebot: nil
1:40 hiredman: ,(ns-interns (find-ns 'clojure.zip))
1:40 clojurebot: {lefts #'clojure.zip/lefts, down #'clojure.zip/down, insert-left #'clojure.zip/insert-left, up #'clojure.zip/up, next #'clojure.zip/next, path #'clojure.zip/path, children #'clojure.zip/children, vector-zip #'clojure.zip/vector-zip, append-child #'clojure.zip/append-child, zipper #'clojure.zip/zipper, branch? #'clojure.zip/branch?, end? #'clojure.zip/end?, leftmost #'clojure.zip/leftmost, edit #'clojure.zip/edit, replace
1:40 hiredman: ,(-> '[a b c] zip/vector-zip zip/root)
1:40 clojurebot: [a b c]
1:40 hiredman: ,(-> '[a b c] zip/vector-zip zip/left zip/left zip/root)
1:40 clojurebot: java.lang.NullPointerException
1:41 hiredman: ,(-> '[a b c] zip/vector-zip zip/down zip/right zip/right (zip/replace 'z) zip/root)
1:41 clojurebot: [a b z]
2:06 hiredman: hmmm
2:06 that is three commits of autodocs for rev 687
2:08 replaca: yeah, cause I'm doing more work on the robot than people are doing work on contrib
2:08 and google's lame-ass wiki doesn't have an offline preview tool
2:09 I can do some stuff editing in the text box and hitting preview, but only so much
2:09 hiredman: I see
2:09 replaca: if you want too see the current product, go to http://
2:10 but it still has a long way to go
2:10 Cark: wah nice stuff you're doing there
2:11 hiredman: nice
2:11 replaca: thx
2:11 dealing with the google wiki is kind of a bear
2:11 all sorts of limitations I wouldn't have in HTML :-(
2:15 Cark: ah funny, so many functions in there i implemented on my own
2:15 replaca: the problem has been that contrib is so opaque! I'm trying to fix that
2:16 noidi: that's great!
2:16 the fixing, not the opaqueness ;)
2:16 replaca: :-)
2:16 noidi: grepping the sources gets old fast
2:18 replaca: know whatchya mean
2:26 cp2: bah, i lost my uptime
6:49 emacsen: hey pjb3
8:50 kadaver: what are hashmaps internally? red-black-trees?
8:52 cemerick: kadaver: they're hash array mapped tries
8:52 the sorted hash maps are red-black trees, I think.
9:12 rhickey_: cemerick: right, sorted sets/maps are rb trees
9:22 cemerick: I haven't had a good brainfuck in a while, but implementing conses, lists, and map/reduce in terms of constraint propagation certainly qualifies...
10:49 postit: hi. i need a litte advice on which order to read some books
10:50 ["On Lisp","Practical Common Lisp","The Clojure book"]
10:51 Chouser: if you've already decided to learn Clojure, I think I'd start with the Clojure book
10:51 postit: i know the basics of lisp and functional programming
10:51 Chouser: I've never read PCL, so someone that has may have a different opinion
10:51 gnuvince: PCL is nothing really special and it's really tailored for Common Lisp
10:51 postit: do you know, does the clojure book just deal with syntax compared to other lisps?
10:52 gnuvince: I'd start with the Clojure book as well and if you need to, On Lisp.
10:52 postit: there's more to the Clojure book than just explanation of the syntax.
10:53 postit: ive decided on clojure, but i wanted to get a good understanding of the "lispy" way to design things too
10:53 arohner: postit: I would look at SICP then as well
10:53 gnuvince: postit: learn Clojure and read code by others
10:53 You'll pick it up.
10:54 arohner: but yeah, gnuvince is right. The clojure way of doing things is not exactly the same as CL or Scheme
10:54 Chouser: The Clojure Book is aims at both Lispers and Java'ers, so it explains how and why to do idiomatic Clojure
10:54 postit: i was wondering that to. if i could learn enough clojure from the "clojure book" to port other stuff as i read
10:55 Raynes: The Clojure book teaches Clojure very well. I learned out of it.
10:55 Chouser: yes, I think if you grok the clojure book material, "on lisp" will then still be useful and interesting.
10:55 postit: great, thanks guys!
11:04 dliebke: postit: the author of Programming Clojure, Stuart Halloway, also wrote some articles on porting examples from PCL to Clojure. http://
11:04 rapido: ,(count [1 2 3])
11:04 clojurebot: 3
11:05 rapido: ~confluently persistent
11:05 clojurebot: It's greek to me.
11:18 postit: is emacs/slime the preferred dev environment (at least if you use emacs)
11:21 djpowell: it is pretty good. i just use emacs + clojure-mode + the built-in M-x inferior-lisp
11:22 clojuredev seems quite nice tho - i like the rainbow paren highlighting - anyway of doing that in emacs?
11:22 clojure-dev for eclipse i mean
11:25 arohner: postit: if you're already an emacs user, then yes it's the best environment
11:25 I use emacs + slime, though inferior lisp works pretty well
11:26 what does rainbow paren highlighting do?
11:27 Chousuke: different colour for each paren pair.
11:27 arohner: on my emacs, if you put your cursor on a paren, bracket or brace, it highlights the matching one
11:27 but only when the cursor is on a paren
11:27 and it highlights in a different color when there is no match
11:28 djpowell: the rainbow paren thing in clojure-dev just syntax colors parens different colors depending on the nesting level - not only when the cursor is near them
11:31 Chousuke: anyway, it's pointless to ask if emacs can do something. you need to ask "where's the plugin?"
11:33 Chouser: and then, "why does it only work with xemacs"?
11:33 arohner: emacswiki.org has a section on paren modes: http://
12:42 gnuvince: Can anyone answer a Java question?
12:43 danlarkin: waste of a question :)
12:43 gnuvince: Well, whatever
12:43 I compiled a bunch of Java files.
12:43 That worked
12:44 when I do: java ClassName, I get an error telling my that package/ClassName is a "wrong name"
12:45 Exact message: $ java BinRepParser
12:45 Exception in thread "main" java.lang.NoClassDefFoundError: BinRepParser (wrong name: hu/belicza/andras/bwhf/control/BinRepParser)
12:50 hiredman: gnuvince: what package is the class in?
12:51 gnuvince: hu.belicza.andras.bwhf.control
12:51 hiredman: you need to include the package
12:51 java hu.belicza.andras.bwhf.control.BinRepParser
12:51 gnuvince: ah<
12:52 thanks
12:52 brianh2: gnuvince: yeah. look @ this http://
13:03 replaca: For those using emacs and slime, I strongly recommend paredit: http://
13:03 (actually this is true even if you're not using slime)
13:14 gnuvince: AAAAAAAAAAAAAAAAAAH!
13:14 * gnuvince smacks himself in the face
13:17 Lau_of_DK: Evening gents
13:21 technomancy: paredit is amazing.
13:22 it makes me hate editing non-lisp code.
13:23 gnuvince: technomancy: it's neat, but I could not get used to it.
13:23 I'd need to spend more time using it
13:29 technomancy: gnuvince: only in the long run
13:29 stuhood: gnuvince: it waits longer to optimize, and can use more memory on optimizations
13:29 danlarkin: -server will use hotspot
13:29 gnuvince: technomancy: the largest bottleneck (20%) was FileInputStream.read; removing -server fixed the problem.
13:30 p_l: JVM 1.7 is supposed to always use the same optimization model as -server
13:31 technomancy: gnuvince: are you talking about my extract-jar function?
13:33 gnuvince: technomancy: no, my Starcraft parser.
13:34 technomancy: gnuvince: that was really weird, because I almost sent an email to the mailing list last night asking why a function that used FileInputStream.read was slow.
13:34 I thought you were reading my mind.
13:34 dnolen: gnuvince is your project a one time run thing?
13:34 gnuvince: technomancy: I thought that I was nearly 20x slower than Java; turns out my Java was faulty and I wasn't analyzing any file. The number is now ~2.5-3x slower. And when I profiled both programs, -server was about twice as slow as -client
13:34 technomancy: nice
13:35 gnuvince: dnolen: currently, yes; give a bunch of files on the command line and it parses them.
13:36 dnolen: gnuvince: client speeds up startup time, server does really aggressive on the fly optimization. for long running processes server is usually better from what I understand.
13:36 technomancy: anyway, FileInputStream.read takes an array of bytes, but it won't accept a (make-array Byte 1000); it needs a (make-array Byte/TYPE 1000), but I have no idea what the difference is; I just copied it blindly. =)
13:37 gnuvince: technomancy: reference type vs value type. The first is a Byte[], the second a byte[] and apparently Java treats them differently.
13:38 technomancy: static typing saves the day again
13:39 who knows what horrors would occur if I sent it bytes when it wanted Bytes.
13:39 or vice versa
13:39 gnuvince: That's more of a "let's have primitives and objects" problem.
13:39 danlarkin: technomancy: this has nothing to do with static typing
13:39 it's strong typing vs weak typing, which is orthogonal to static vs dynamic
13:43 technomancy: oh, bytes are primitive, right.
13:46 Chousuke: having the primitive types is a nasty JVM wart, but I guess there at least used to be a reason to have them :/
13:46 gnuvince: I figure performance
13:47 Although it seems like the kind of thing the compiler should take care of.
13:48 Cark: well it really makes sense ti have a buffer made of real contiguous bytes
13:48 rather than byte objects or whatever
13:49 danlarkin: right, well it's an array of data structures rather than an array of pointers to classes with overhead etc
13:50 I agree it's a wart, but I /suppose/ I can see the rationale for having it
13:51 Cark: .net has the same thing m
13:51 more or less
13:51 so i guess that's pretty much the way to go
13:56 gnuvince: instance? seems like a pretty quick operation, am I right?
13:56 dnolen: what kind of machine does clojurebot run on?
14:00 Cark: clojurebot has been on strike these days
14:00 clojurebot: are you there ?
14:00 clojurebot: Huh?
14:02 cemerick: gnuvince: as quick as Class.isInstance :-)
14:03 gnuvince: cemerick: that's what I wanted to know, that seems to be pretty fast, right?
14:03 cemerick: for the job, it's all there is...
14:04 the speed of instance? is never going to be your bottleneck, if that's your question
14:04 gnuvince: cemerick: think again :)
14:04 rank self accum count trace method 1 37.54% 37.54% 3532 300290 java.lang.Class.isInstance 2 20.12% 57.66% 1893 300285 java.lang.Class.isInstance
14:04 3 17.94% 75.60% 1688 300292 java.lang.Class.isInstance
14:04 4 2.44% 78.04% 230 300308 java.io.FileInputStream.readBytes
14:04 well, the output didn't come out too nicely :-/
14:05 cemerick: can you paste the code that produces that mix?
14:05 gnuvince: http://
14:05 check starcraft/replay/parse.clj
14:07 cemerick: where's the source of the instance? calls?
14:07 Cark: did you set the *wern-on-reflection* variable ?
14:07 warn
14:08 gnuvince: Cark: yes, there's none.
14:08 cemerick: most likely the call to vector? in read-field
14:11 cemerick: what's the overall runtime of the code that you profiled? I'm thinking if the overall runtime was very short, then instance? calls would likely still be reflective, and they could easily be a significant amount of runtime compared to a small disk read.
14:12 Cark: and the file must be in the cache too, so even faster to read
14:14 gnuvince: cemerick: ~110 seconds.
14:14 cemerick: it processed over a thousand files in that time frame.
14:16 Cark: what's the troughput ? how many megabytes in this time frame ?
14:17 gnuvince: Not a lot
14:17 151 MB
14:18 Each file is about 150 KB
14:18 Cark: i remember seeing somewhere a way to read several buffers in one go
14:18 an array of buffers with different types
14:19 gnuvince: Cark: my hands are tied by the Java lib I use.
14:19 I don't do the IO
14:19 I take the file
14:19 pass it off to a Java method
14:19 grab the ByteBuffer it returned
14:19 and work with that.
14:24 replaca: I will attest to isInstance? being a bottleneck, it's also the slowest thing in the pretty printer (although I do do it a lot).
14:24 Cark: ah too bad ...because with a FileChannel you have this method : read(ByteBuffer[] dsts)
14:24 gnuvince: replaca: I do a lot of vector? calls too.
14:24 Cark: you could then prepare wrapped buffers on top of that for each record type
14:25 for each field type i mean
14:25 gnuvince: I was thinking of changing my API slightly, but it seems that a comparaison of length or using try/catch are the same speed.
14:25 Cark: does your library do memory mapped files ?
14:26 gnuvince: Cark: not that I know of.
14:26 as far as I can tell (not really a Java programmer), the guy just opens a FileInputStream, reads, and returns a ByteBuffer.
14:26 Cark: anyways that's not your problem ...you need to do less at run time
14:27 gnuvince: yeah
14:27 I define a field in a record like this:
14:27 replaca: gnuvince: obviously the pretty printer needs to think about types a lot, cause it's making dynamic decisions based on type. BUt it does more work than it needs to. I'll need to deal with that when I revisit dispatch.
14:28 gnuvince: [:name 1 Byte] or [:name2 [1 Byte] Integer]. The vector? calls is to read the [1 Byte] and use the value as the number of Integers to read.
14:30 ,(let [xs (repeat 1000000 [[1] [2 3]])] (time (doseq [x xs] (if (= (count x) 1) 1 2))))
14:30 clojurebot: "Elapsed time: 3834.042 msecs"
14:30 gnuvince: ,(let [xs (repeat 1000000 [1 [2 3]])] (time (doseq [x xs] (if (vector? x) 2 1))))
14:30 clojurebot: "Elapsed time: 2458.336 msecs"
14:30 Cark: I would prepare that parsing before hand
14:31 you know build a lambda
14:31 there you're "parsing" the field spec during the actual processing
14:32 gnuvince: So turn these into lambdas instead of structs? http://
14:33 Cark: that's nice and clean as it is
14:33 but you could process this "DSL" before hand into lambdas to make it quicker to parse
14:36 gnuvince: To make sure I'm following, something like (compile-record [:name 1 Byte] [:name2 [1 Byte] Integer]) and that would return a fn that takes a ByteBuffer as its input?
14:37 Cark: right
14:38 gnuvince: Should that be a macro or a function?
14:38 cipher: hey gnuvince what are you writing there--quick description
14:39 gnuvince: cipher: it's a library that reads a Starcraft replay file and returns information about the game (players, races, map, etc.) as well as all the actions done by the players. Players use those kinds of programs to analyse their games.
14:40 cipher: neat.
14:49 gnuvince: Cark: do you think compile-field should be a function or a macro? I'd prefer a function, but I'm not sure if I can do it...
14:50 cipher: gnuvince: did you see my PM?
14:50 gnuvince: Oh, yes.
14:50 Thanks
14:51 cipher: Ok.
14:52 gnuvince: Did you guys to bnetd?
14:52 cipher: we have some involvement
14:52 had*
14:53 gnuvince: OK
14:53 Shame Vivendi pulled the plug on that project :(
14:53 technomancy: if I can't delete a file, should I raise an instance of Exception, or is there a more specific class I should use?
14:53 gnuvince: technomancy: IOException?
14:54 technomancy: gnuvince: thanks; that sounds better
14:55 what do you think: does a delete-file-recursively function belong in contrib?
14:56 http://
15:03 gnuvince: Java doesn't already have a method for that?
15:03 technomancy: gnuvince: yeah, I was surprised, but I couldn't find one.
15:03 maybe they just hid it really well?
15:05 gnuvince: Python's shutil.rmtree ftw!
15:05 technomancy: FileUtils.rm_rcf
15:05 *rm_rf
15:05 Chouser: that's the kind of thing apache commons provides
15:05 leafw: technomancy, gnuvince: no, java does not have a recursive file deletion command. I guess it meant too much potential for damage.
15:06 technomancy: Chouser: yeah, but needing a 3rd-party dependency for something that basic is unfortunate.
15:06 leafw: at least it has File.mkdirs()
15:06 Chouser: technomancy: yeah
15:06 technomancy: this functionality is pretty important for unit testing
15:06 since you need to clean up after yourself
15:13 posted it to the mailing list
15:13 can create an issue/patch
15:13 cemerick: contrib *is* a 3rd party dependency (or dependencies). Much more pleasant API than 99% of the stuff out there, but it's a dependency nonetheless.
15:15 technomancy: every project I've worked with uses contrib already
15:15 so it's not an additional dependency for most
15:15 and it's not exactly 3rd-party
15:16 Chousuke: Chouser: what's the plan with your clojure-compiler? I see you haven't worked on it in a while
15:17 cemerick: my real point is that I think it'd be bad if stuff as generic (and as redundant w.r.t. existing libraries) as common IO operations starts leaking into contrib
15:20 Chouser: Chousuke: I've got a new job and a lot less time to work on Clojure stuff
15:20 so the plans the same, the pace is just way down
15:26 Chousuke: the code you have right now looks quite scary.
15:26 Chouser: hm. yeah, it's not gotten to the "clean up" phase yet. ;-)
15:43 jayfields: how can I return the first item from a collection that matches a predicate?
15:43 other than (first (filter pred coll))
15:43 kotarak: (seq-utils/find-first pred coll)
15:43 jayfields: cool. thanks.
15:44 I take it that's in contrib?
15:44 kotarak: Yup.
15:45 cemerick: Chouser: hey, congrats! Is it hush-hush, or do we get to leer at your new employer's wares?
15:45 Chouser: http://
15:59 drewr: Chouser: Congrats!
16:00 Are you relocating to FL or working from IL/IN/wherever you are now?
16:01 Chouser: telecommuting full time now. We'll see how that goes. :-)
16:02 drewr: It's definitely bittersweet.
16:03 I love it today because it's 65 and I'm on my porch.
16:03 Chouser: ah, nice
16:09 triddell: functions are supposed to return early, right? I have a function that checks user security against authorized access roles. How should I return true after the first authorized match from a for list comphrehension?
16:10 are not supposed to return early that is
16:10 hiredman: (first (for ...))
16:11 arohner: triddell: for returns a lazy list that is realized as necessary
16:12 first "blocks" until the first element is returned from the lazy list
16:12 technomancy: cemerick: I don't follow.
16:12 what's wrong with that?
16:13 hiredman: ~literal [3] clojure
16:13 clojurebot: a very attractive hammer with a nice heft to it
16:13 hiredman: ^- now using fnparse
16:14 cemerick: technomancy: there's a lot of java libraries that do a lot of things. Reimplementing capabilities (especially inherently-stateful stuff like IO) in clojure is counterproductive overall, IMO. Not having to do that sort of thing is why having fantastic java interop is a Good Thing.
16:14 AWizzArd: ~ max people
16:14 clojurebot: max people is 164
16:15 triddell: arohner & hiredman: thanks
16:15 cemerick: been that way for a long time now
16:15 maybe clojurebot should track the date that the last max was reached
16:16 technomancy: cemerick: everyone's just going to re-implement it on their own anyway
16:16 AWizzArd: Well, it first was 164. Then Clojurebot forgot that number. After a few days it maxed out freshly on 162. But then I resetted it to 164 again. This is now a while ago.
16:16 technomancy: contrib is useful *because* it provides common I/O operations
16:17 AWizzArd: Until that max number of users there was a funny correlation between the numbers of the GG and the number of users in here. That correlation was: for each 10 new users in the GG we got one more user here.
16:17 cemerick: technomancy: really? At what point is pulling in well-tested libraries worthwhile, then?
16:17 technomancy: cemerick: rm -rf ain't exactly rocket science
16:17 AWizzArd: For some reason then the number of users here settled at +/- 125, while the GG got more users.
16:17 technomancy: you'd pull in 3rd-party libs for tricky things like joda for date parsing
16:18 cemerick: I'm sure someone will reimplement date parsing in clojure, too. I'm just wondering where the line gets drawn.
16:19 technomancy: cemerick: I did. but I realized it's a bad idea because it's impossible to get right.
16:19 so it didn't go in contrib.
16:19 but this is very, very different.
16:22 cemerick: To each his own, I guess. Reinventing any otherwise well-tested wheel without getting a significant return on that work just seems like a waste to me. *shrug*
16:23 technomancy: everybody who writes tests for code that writes to disk needs to delete whole directories. having to pull in an apache dependency to do this is... sad.
16:23 cemerick: not really -- we use ant to clean such temp spaces up.
16:24 technomancy: it's fewer lines of code to just implement the function than actual lines of XML necessary to express the dependency on apache commons io.
16:24 what about people who want to run tests from the REPL or from slime?
16:26 cemerick: that largely doesn't make sense to me either :-)
16:27 technomancy: if you have to launch a new instance every time you want to run the tests, it totally kills your rhythm since you've got to wait a few seconds for the JVM to boot.
16:28 which is OK for integration tests, but totally unacceptable for unit tests where you need instant feedback
16:29 see http://
16:30 cemerick: like I said, to each his own. IMO, the REPL is phenomenal for interactive development, but any results from tests run in it aren't to be trusted -- too much opportunity for environment pollution that can skew them one way or another.
16:31 technomancy: yeah, it can't be your only method of testing; that's for sure.
16:31 but to avoid testing with it is to give up a valuable tool.
16:33 cemerick: I don't avoid it...but then, I can't think of a single REPL-friendly test we have that uses any temp files.
16:37 technomancy: maybe that's because you don't have an rm -rf that works from the repl. =)
16:37 cemerick: heh
16:38 nah, we just don't generate files *shrug*
16:38 if we did, I'd probably have to know my way around a shell way better than I do
16:39 * technomancy is a fan of self-contained tests
16:41 cemerick: everything we do is in-memory. GC cleans up after us :-)
16:42 technomancy: that's awesome if you can get away with it. =)
16:42 cemerick: I know :-D
16:58 emacsen: Can someone explain why I get an error that v doesn't resolve in the context: http://
16:58 (that's not the final code, but it's the simplest version I have right now)
16:59 cemerick: emacsen: each arity must be wrapped in parens....
16:59 emacsen: cemerick, ah :)
17:00 cemerick: emacsen: http://
17:00 kotarak: emacsen: and the (if (empty? ..) true) ( ... looks ominous. The if is basically useless.
17:00 emacsen: kotarak, the first one? you're probably right
17:01 otherwise, well you need it to return true sometime right?
17:01 cemerick, thx
17:01 kotarak: And (cond ... :else false) can also be left out. cond will return nil of no clause matched, so it will count as false.
17:02 emacsen: This also isn't the final code. It's going to do more than this, and will be lazy, but this is my first shot
17:02 kotarak, for this version, true. Later versions, no, but you're right in what you see
17:02 (because nil won't print as false in print I believe
17:05 hiredman: ~ticker JAVA
17:05 clojurebot: JAVA; -0.06
17:12 durka42: ~ticker ORCL
17:12 clojurebot: ORCL; -0.18
17:13 danlarkin: ~ticker CHINA
17:13 clojurebot: CHINA; +0.07
17:13 danlarkin: tada!
17:14 durka42: china?
17:14 p_l: ?
17:15 kotarak: ~ticker CON.F
17:15 clojurebot: java.io.IOException: Server returned HTTP response code: 400 for URL: http://
17:15 durka42: CDC Corporation
17:15 (Public, NASDAQ:CHINA)
19:19 cads: hey, how do I use a namespace like clojure.set ? Neither (use clojure.set) or (use clojure/set) seem to work.
19:22 technomancy: (use 'clojure.set)
19:22 Raynes: use 'clojure.set
19:22 technomancy: You win this time. :(
19:22 technomancy: or even better put (:use [clojure.set]) in your ns directive
19:26 lisppaste8: Rayne pasted "imports and uses in namespace example for cads" at http://
19:28 cads: why do we quote it?
19:28 wow, thanks for the example rayne
19:29 Raynes: cads: No problem.
19:29 technomancy: cads: because clojure.set is not bound to a value
19:29 Raynes: Quoting it keeps Clojure from trying to evaluate it.
19:29 technomancy: try just entering clojure.set into a repl; it doesn't mean anything
19:29 Raynes: ^ what he said.
19:29 cads: ah
19:30 technomancy: it's a symbol that is used to look up a namespace
19:30 which is different from a var that's used to look up a value
19:30 cads: I thought it would just pass the symbol in that case, but I remember the eval rules now
19:30 technomancy: cads: if use were a macro, it could do that
19:31 but use is a function
19:31 ns is a macro, which is why the evaluation rules are different there
19:37 cgrand: technomancy: hi! just noticed (while grepping irc logs) that you talked to cgrand-rec 2 days ago. cgrand-rec isn't me, it's a disconnected irssi logging the channel
19:37 technomancy: cgrand: ah; good to know. =)
19:38 I forgot what I said though.
19:38 cgrand: that you were trying the new enlive
19:39 technomancy: oh, I was "use"ing enlive and was wondering if it might be better not to export any vars that conflicted with clojure core.
19:39 unlink: What's the idiom for function definitions visible only inside another function?
19:39 technomancy: I've since decided to stick with "use :only" unless I have a reason not to
19:39 unlink: define them in let bindings
19:40 lisppaste8: technomancy pasted "let-binding a function for internal use; see target-file" at http://
19:40 technomancy: unlink: ^^
19:41 unlink: boom
19:41 stuhood: you overwhelmed lisp.org with your awesome code, and it is throwing 500's...
19:41 technomancy: amazing
19:42 if you want something done right, you have to do it yourself: http://
19:42 dreish: Or http://
19:42 technomancy: witness the power of Static Files
19:42 does gist do clojure highlighting?
19:42 dreish: Yes.
19:42 stuhood: yea
19:42 technomancy: cool
19:43 but I prefer static files. =)
19:43 dreish: They do Genshi highlighting.
19:43 stuhood: speaking of which, has anyone tried to get Clojure highlighting for Trac?
19:44 dreish: Maybe Genshi's not so obscure. (I'd never heard of it.) But anyway they cover something like 80 languages.
19:44 cgrand: technomancy: it bothers me to clash with clojure.core (eg CSS :not is 'but), I should rename 'complement back to 'complement-state (or 'negate or something else) and find another name for 'empty
19:45 technomancy: cgrand: clashing in private defns is not as big of a deal
19:45 unlink: So def always (re)binds in the global namespace, regardless of the scope?
19:46 technomancy: yeah. you shouldn't use it at outside toplevel scope unless you have a really good reason to do it though.
19:46 unlink: I guess I'm just used to scheme's scoping
19:46 which is different
19:47 technomancy: in fact, you shouldn't do it after your application has loaded at all
19:47 cgrand: technomancy: I want to keep them (complement and empty) public
19:47 technomancy: or at least be aware that you're stepping outside the Golden Path
19:47 unlink: right
19:48 I think (def a [x] (def b [x] (+ x 1)) (b x)) is nicer syntax than (def a [x] (let [b (fn [x] (+ x 1))] (b x))) though
19:48 s/\<def\>/&n
19:49 chessguy: so i'm thinking about an interesting little project, but i'd really need a freaking good REPL to play with it. anybody got any good suggestions? is SLIME as good as it gets?
19:49 dreish: letfn would be handy.
19:49 technomancy: chessguy: slime is rockin'
19:49 unlink: see: factorial with recur
19:49 technomancy: be sure you use M-x clojure-install to set it up though.
19:50 chessguy: hmm. i don't remember if that's how i installed it or not
19:50 how would i tell?
19:50 technomancy: chessguy: if you used it, you should have a call to clojure-slime-config somewhere in your personal .emacs setup.
19:51 chessguy: doesn't look like it
19:51 just (slime-setup)
19:51 technomancy: if you've already got it working you should be ok
19:51 chessguy: and slime-setup '(slime-repl)
19:51 technomancy: I was just thinking if you were going to install from scratch
19:51 unlink: Am I writing this idiomatically? http://
19:52 dreish: unlink: Maybe (letfn [inner [n m] ...] (inner n 1)) ?
19:52 unlink: Oh, there exists a letfn?
19:52 dreish: Since January, yes.
19:52 chessguy: i don't get it, when i M-x slime, it says something about connecting to a server? what is it connecting to
19:52 unlink: oh
19:52 hot
19:53 technomancy: chessguy: a clojure instance is started that "serves" the Emacs instance over slime
19:53 there's a socket connection between the two
19:53 chessguy: oh, a JVM environment?
19:54 Raynes: technomancy: Stop being smarter than me. It's not nice. :|
19:54 technomancy: heh
19:54 chessguy: yeah, it's launched as a subprocess.
19:54 chessguy: cool
19:54 dreish: unlink: Or just ((fn inner [n m] ...) n 1), but the double open parens can cause crossed eyes.
19:56 chessguy: does slime store the result of the last evaluation anywhere that you can get at it?
19:56 e.g., for haskell, in ghci, if i do > 2 + 3, followed by > it == 5, i'd get true
19:56 technomancy: chessguy: probably, but I couldn't tell you off the top of my head. the slime manual is really good though.
19:56 chessguy: oh ok, i'll take a look
19:57 thanks
20:15 dysinger: why does this work (straight java)
20:15 sonian.archive.aws=> (String/format "%s ran %d miles today" (to-array ["Stu" 8]))
20:16 "Stu ran 8 miles today"
20:16 sonian.archive.aws=>
20:16 and this one doesn't
20:16 sonian.archive.aws=> (format "%s ran %d miles today" ["Stu" 8])
20:16 java.util.MissingFormatArgumentException: Format specifier 'd' (NO_SOURCE_FILE:0)
20:16 sonian.archive.aws=>
20:16 dreish: Remove the []
20:16 dysinger: I know that works
20:17 I am saying the internal code for (format converts to a java array and passes it to java like the 1st call
20:17 dreish: The & turns the remaining args into a sequence.
20:18 dysinger: ~(format "%s ran %d miles today" (seq ["Stu" 8]))
20:18 clojurebot: format is http://
20:18 dysinger: oops
20:18 hiredman: dysinger: it works that way because [] does not make an array
20:18 dysinger: ,(format "%s ran %d miles today" (seq ["Stu" 8]))
20:18 clojurebot: java.util.MissingFormatArgumentException: Format specifier 'd'
20:19 dreish: dysinger: Why would you expect that to work?
20:19 hiredman: [] makes a persistent vector, which java's format doesn't know anything about
20:19 dreish: args now contains (("Stu" 8)) -- a seq with only one thing in it.
20:19 dysinger: right
20:19 dreish: That thing happens to be another seq, but it needs _two_ things.
20:19 Not _one_ seq.
20:20 dysinger: so the only way to format with a seq / vector / set is to use apply
20:20 dreish: Sure, or you could do String/format yourself I guess.
20:21 dysinger: y
20:21 dreish: If you do it a lot, maybe write a formatseq?
20:21 dysinger: true
20:21 dreish: I'd probably apply. It seems cleaner somehow.
20:21 dysinger: y it works fine
20:21 just curious
20:22 the & args turning into a seq explains the magic
20:22 dreish: k
20:23 dysinger: sorry for the bone-headed questions - I've been seriously programming clojure for 3 weeks.
20:23 :)
20:23 dreish: np
20:24 For some reason I thought you'd been around for months, actually.
20:24 dysinger: I learn quick - but sometimes ask dumb questions
20:24 and I did Java for 10 years and some lisp already :)
20:25 am totally loving it though
20:25 I rewrote some java today and shrank it 10:1
20:25 dreish: It is nice.
20:27 Raynes: dysinger: Good evening.
20:27 dreish: Whenever I have to make a change to the existing Java part of my pet project, it's painful to have to deal with that language.
20:27 dysinger: heya Raynes
20:38 chessguy: hmm, i don't get how to use slime presentations to copy the previous results to the prompt
20:42 gnuvince_: Sometimes I hate dynamic typing...
20:50 chessguy: i'm reading http://
20:53 technomancy: chessguy_: M-p
20:53 slashus2: try them all
20:54 chessguy: M-p takes me to the last one that matches what i've typed so far
20:55 technomancy: C-h m will show you what bindings are active for the current mode
20:59 chessguy: none of those seem to do what i want
21:03 *sigh*
21:16 unlink: How do I pattern match based on whether the argument to a function was a vector or a scalar?
21:16 durka42: you could do something with multimethods
21:17 or you could just put an if statement at the top of the function
21:17 dreish: Destructuring isn't the same as pattern matching, in that it can't really do what you're asking for.
21:18 unlink: oh
21:18 hiredman: well
21:18 it can
21:18 unlink: That was basically the #1 use case of pattern matching for me
21:19 hiredman: (defmulti f vector?)
21:19 (defmethod f true [arg] do vector stuff)
21:19 (defmethod f false [arg] do scalar stuff)
21:19 dreish: hiredman: That's a multimethod, as durka42 suggested.
21:20 unlink: e.g. fun g(a, b, c) = case a of [] => (round c) = 1 | 1::xs => not (null xs) | _ => b
21:22 dreish: I'm surprised no one has written a defpattern macro for contrib yet.
21:23 unlink: Obviously (fn ([[a b & c]] ...) ([_] ...)) doesn't work.
21:28 Jedi_Stannis: what are you trying to do?
21:31 technomancy: chessguy: it might be a clojure repl feature rather than a slime feature
21:50 chessguy: Jedi_Stannis, a simple example: if i've done user> (+ 2 3)
21:50 and gotten back 5
21:51 i want to be able to do user> (+ 5
21:51 and then hit some combo
21:51 to put the 5 from the previous evaluation into what i'm currently typing
21:51 Jedi_Stannis: *1
21:51 ?
21:52 ,(doc *1)
21:52 clojurebot: "; bound in a repl thread to the most recent value printed"
21:52 chessguy: oh cool!
21:52 Jedi_Stannis: ,(doc *2)
21:52 clojurebot: "; bound in a repl thread to the second most recent value printed"
21:53 Jedi_Stannis: ,(doc *3)
21:53 clojurebot: "; bound in a repl thread to the third most recent value printed"
21:53 chessguy: ,(doc *42)
21:53 clojurebot: java.lang.Exception: Unable to resolve var: *42 in this context
21:53 Jedi_Stannis: lol
21:53 only 1 - 3
21:53 chessguy: just checking :)
21:53 ,(doc *4)
21:53 clojurebot: java.lang.Exception: Unable to resolve var: *4 in this context
21:53 chessguy: boo
21:53 ok, better than nothing
21:53 thanks!
21:54 Jedi_Stannis: no problem
22:00 cipher: can someone explain how to use the -> form
22:01 unlink: I guess one simple example of what I'm trying to do would be a basic implementation of map, where it accepts two parameters, a function and a list. I would like to pattern match on whether the list is empty or not; in the former case, map returns (); in the latter case, it retuns (cons (f x) (map f xs))
22:01 Jedi_Stannis: ,(macroexpand '(-> 1 (+ 2) (* 3))
22:01 clojurebot: EOF while reading
22:01 Jedi_Stannis: ,(macroexpand '(-> 1 (+ 2) (* 3)))
22:01 clojurebot: (* (clojure.core/-> 1 (+ 2)) 3)
22:02 Jedi_Stannis: bleh, doesn't expand all the way:( * (+ 1 2) 3)
22:03 unlink: you can't really pattern match in clojure like you can in haskell or other functional languages.... need to write a conditional or write some sort of pattern matching macro
22:03 unlink: oh.
22:04 Good excuse to learn reader macros, I suppose.
22:04 Jedi_Stannis: cipher: so if you want an imperative style, you can start with your data structure and list the functions you want applied to it
22:04 unlink: umm, clojure also doesn't have reader macros
22:05 ,(-> {} (assoc :a 1) (assoc :b 2) (assoc :c 3))
22:05 clojurebot: {:c 3, :b 2, :a 1}
22:05 Cark: hey how is it imperative to start with data structures ?
22:05 unlink: I guess regular macros might be powerful enough?
22:05 Jedi_Stannis: yeah, it just will change the way you write it
22:09 cipher: so I can almost think of it like doto?
22:09 unlink: Thanks, Jedi_Stannis.
22:12 Jedi_Stannis: cipher: similar to doto, except instead of it applying methods to an object for side effects, it passes the result from one function call to the next, building up the result
22:13 cipher: got it. alright thanks.
22:13 Jedi_Stannis: cark: its not really imperative, just lets you write things in the order they happen, instead of reverse order by having to nest all the calls
22:15 your welcome
22:17 emacsen: I've just learned the comparison operators < and > don't work on strings
22:17 Is there a deep reason for this?
22:17 Cark: i'll take the bait : what do you expect from the < operator on strings ?
22:17 Chouser: I think performance of numeric operations are generally cited.
22:18 Cark: byte by byte comparison ? character wise comparison ? what collating order then ?
22:18 emacsen: Chouser, right but shouldn't < be defmulti-ed
22:18 durka42: emacsen: exactly. that would be slow(er)
22:18 emacsen: okay, so is there a generic function for this?
22:18 gnuvince_: Cark: by the way, thanks for the suggestion of "compiling" my records this afternoon. I'm doing some rough tests here, but performance went from 115 seconds on my home PC for 1000+ files to ~90
22:19 lambda++
22:19 Cark: that's not as good as i imagined gnuvince ='(
22:19 gnuvince_: Cark: well it is the first time I've done something like this, so I may have not been as efficient as I could.
22:19 emacsen: in other languages you can compare numbers, or dates, or strings and they use some inferior operator overloading. Is there a function I can use generically?
22:19 gnuvince_: Cark: I'll push the code in a little while if you want to see the code.
22:20 Cark: gnuvince : i'd love to
22:20 emacsen : to me it does not make sense to use the same operator for strings and for numbers
22:21 is some kenji symbol smaller or bigger than the letter B ?
22:21 unlink: Is there a shorthand for (let [x (cond ...)] (if (nil? x) (...) x))
22:21 Or maybe something more robust which lets me return nil from cond and still not evaluate the second (...)
22:22 emacsen: Cark, Maybe. But then I guess I have to figure out the right function
22:22 and I won't know that ahead of time
22:22 Cark: emacsen : you have the full java stack at your fingertips
22:22 and pretty good docs too =)
22:22 emacsen: Cark, that's like saying "You have as much mud as you want to build the house of your dreams!"
22:23 durka42: :)
22:23 Cark: maybe but that's efficient mud you dobn't need to recreate !
22:23 durka42: unlink: if-let maybe?
22:24 unlink: I guess like cond-else in scheme
22:25 Cark: ,you want some kind of when-not-let ?
22:25 clojurebot: java.lang.Exception: Unable to resolve symbol: you in this context
22:28 unlink: After some googling it appears that (cond) excepts :else in place of a condition.
22:29 gnuvince_: Cark: http://
22:29 emacsen: okay, one last very dumb question. Why, if we have namespaces, can't I reuse names from the core?
22:29 Cark: gnuvince : checking it now
22:29 emacsen: eg I can't use "val" in my functions as an argument because it's already used in the core
22:30 Chouser: emacsen: you can, but you have to explicitly exclude those core names from being referred into your new namespace
22:30 Cark: emacsen : you can but you have to specifically import core
22:30 hiredman: ,((fn [val] val) 1)
22:30 clojurebot: 1
22:30 emacsen: Wow both those options suck ;)
22:31 Cark: that's the same option =P
22:31 emacsen: Then it sucks twice as hard ;)
22:31 unlink: How is recur not 100% equivalent to using the name of the function in a tail position recursive call?
22:31 Cark: that's CLish
22:32 unlink: emacsen: I agree, the semantics are very surprising.
22:32 hiredman: unlink: cond does not take :else, :else is just convient because it evals to not nil (true) all the time so if it is reached it's clause will run
22:32 unlink: hiredman: oh, of course.
22:32 Cark: gnuvince : you still have the lookup in read-field
22:32 hiredman: ,(cond (= 1 0) :foo 1 :bar)
22:32 clojurebot: :bar
22:32 emacsen: unlink, well it's just I have been writing code lately and finding out quickly that I need to change a lot variable names because they're already in the core
22:33 "val" has always been my default single value argument name
22:33 unlink: emacsen: I ran into the gotcha a few times today as well.
22:33 emacsen: and "seq" seemed like a good name for an argument which was a sequence passed in :)
22:33 unlink: I think the idiom is "coll" for that.
22:33 emacsen: fair nuff
22:33 gnuvince_: Cark: the lookup to select the getting function?
22:33 Cark: right
22:34 unlink: Ok, I guess except for the use of recur with loop.
22:34 Cark: gnuvince : you could have a make-read-field function, then in compile record you prepare that function, and just use it in the returned lambda
22:35 i usually name these lamba compiling functions like this : make-frobnicator-fn
22:35 as this is not really compiling
22:35 gnuvince_: ok
22:36 Cark: so that's one less lookup for you right there ...though i beleive this should not make a huge difference
22:36 gnuvince_: As for a make-read-field function, won't I need to lookup the type anyway to select the right one?
22:37 Cark: well the type is already given in the field-specs right ?
22:37 gnuvince_: Yes
22:37 Cark: mhh let me make a paste with some untested code
22:37 lisppaste8: url?
22:37 lisppaste8: To use the lisppaste bot, visit http://
22:40 cark pasted "untitled" at http://
22:40 Cark: that's only to give the idea
22:40 and is actually completely wrong =/
22:41 you want to prepare a list of functions
22:41 gnuvince_: I'll give it a whirl
22:41 Cark: very wrong i put it in the returned lambda =P
22:41 cipher: ,(make-array (. Byte TYPE) [1 2 3])
22:41 clojurebot: java.lang.ClassCastException: clojure.lang.LazilyPersistentVector cannot be cast to java.lang.Character
22:41 Cark: let me anotate again
22:42 cipher: What's the right way to do that?
22:43 Chouser: ,(into-array Byte/TYPE (map byte [1 2 3]))
22:43 clojurebot: #<byte[] [B@1eab16b>
22:44 lisppaste8: cark annotated #79053 "untitled" at http://
22:44 Cark: that's more like it
22:45 lisppaste8: cark annotated #79053 "untitled" at http://
22:46 Cark: gnih
22:46 gnuvince_: All right
22:46 I'll test it out tomorrow at work when I need to pretend like I'm working
22:47 Cark: disregard the last one, i need to edit in emacs instead of firefox =P
22:47 unlink: Am I missing some clojure programming construct which allows me to avoid writing a cond like this? http://
22:47 gnuvince_: hehe ;)
22:48 ,(map even? [1 2 3 4 5 6])
22:48 clojurebot: (false true false true false true)
22:48 gnuvince_: ,(mapgilter even? [1 2 3 4 5 6])
22:48 clojurebot: java.lang.Exception: Unable to resolve symbol: mapgilter in this context
22:48 gnuvince_: ,(filter even? [1 2 3 4 5 6])
22:48 clojurebot: (2 4 6)
22:49 unlink: Ok, yes, I know it is a bit contrived.
22:49 gnuvince_: unlink: the seq functions are prefered.
22:50 unlink: But the point of the function is not to return the even elements in the list, but rather the elements in even positions.
22:50 lisppaste8: cark annotated #79053 "untitled" at http://
22:50 Cark: gnuvince : notice on how the vector? call is now out of the loop
22:51 err though the first bracnh of the size if is wrong, you get the idea
22:52 gnuvince_: Yeah
22:52 I've bookmarked the page
22:52 Cark: pretty hard to give a solution without rewriting a whole bunch of it
22:52 gnuvince_: One thing I've had to do to get more performance is to close over data instead of using vars.
22:52 unlink: In Haskell, you would do: evens [] = []; evens x = []; evens (x:y:xs) = y:evens xs
22:52 Cark: well, the var there is only called once
22:53 not inside the loop
22:53 gnuvince_: Won't it be called every time I call make-read-field-fn?
22:54 Cark: yes, but you could do this a single time at compile time
22:54 or once a file
22:54 gnuvince_: unlink: you want only the even indexed elements?
22:54 Cark: once for every field in every record type
22:54 unlink: gnuvince: Yes.
22:54 gnuvince: starting at 1
22:55 gnuvince_: ,(take-nth 2 [1 2 3 4 5 6])
22:55 clojurebot: (1 3 5)
22:55 gnuvince_: This starts at zero however.
22:55 ,(take-nth 2 (cons nil [1 2 3 4 5 6]))
22:55 clojurebot: (nil 2 4 6)
22:55 gnuvince_: meh
22:55 * gnuvince_ is dumb tonight
22:56 unlink: I'm actually looking for a way to mimic the Haskell construction.
22:56 gnuvince_: Cark: is there any good literature on using lambdas like that to optimize code and "compile" code?
22:56 unlink: Clojure doesn't have pattern matching, so you're pretty much out of luck there.
22:57 Go with the length
22:57 unlink: So (cond (nil? ...)) is the right construction?
22:57 Cark: i don't know, i learned this reading the source code of cl-pcre (the common lisp regex compiler made by edi weitz which is faster than perl)
22:57 unlink: @gnuvince_
22:58 gnuvince_: Cark: ok.
22:59 Cark: gnuvince : too bad you don't have some test files in there, i would give it a go =)
22:59 lisppaste8: gnuvince pasted "evens" at http://
22:59 gnuvince_: Cark: I have a script to get a bunch of them
23:00 lisppaste8: gnuvince pasted "Download Starcraft replay files" at http://
23:00 unlink: gnuvince_: That doesn't lazily iterate the list, though.
23:01 s/list/collection
23:01 gnuvince_: Cark: this is screen scrapping, so hopefully they didn't change their entire site.
23:01 unlink: it's not too hard to change that
23:01 Cark: is this python ?
23:02 unlink: gnuvince_: you mean and still not check whether car and cadr are nil?
23:04 gnuvince_: Cark: yes.
23:04 Cark: i think i'll just download a couple files manually =P
23:06 gnuvince_: Cark: wait
23:06 I'll put up an archive on a webserver
23:07 lisppaste8: gnuvince annotated #79054 "lazy evens" at http://
23:07 unlink: ok, thanks, I have to run
23:10 gnuvince_: Cark http://
23:10 about 1050 files
23:10 Cark: quite a big file =)
23:11 gnuvince_: yeah
23:21 replaca: good evening, clojurians
23:21 Cark: hello replaca
23:51 are you still there gnuvince ?
23:54 replaca: this is the time of night when tumbleweeds begin to roll through #clojure
23:55 Cark: hehe