#clojure log - Jun 09 2010

The Joy of Clojure
Main Clojure site
Google Group
IRC
List of all logged dates

0:00 Raynes: technomancy: He uses Emacs now?

0:00 technomancy: yeah

0:00 Raynes: technomancy: Hot.

0:00 lancepantz: the kinesis was really difficult at first, but after a couple of weeks, you get used to it

0:00 technomancy: for the record, nothing beats keyboard pants: http://www.flickr.com/photos/technomancy/4397554484/

0:00 lancepantz: and it's awesome

0:00 LuminousMonkey: Maybe I should give Emacs another go, but I really think I need to figure out how to redo the keybinds.

0:01 Raynes: technomancy: Are you purposely requiring that each key -> value pair passed to add-query-params be a sequence?

0:02 maravillas: technomancy: not even a bacon maple eclair?

0:02 jartur: lancepantz: damn, I will order it someday. Though it would probably never ship to my country. Will get lost at customs office or smth like that

0:02 technomancy: Raynes: uh... that'd be unintentional. dang.

0:02 that's why they call it a snapshot I guess

0:02 lancepantz: jartur: if you have a problem with RSI, its a lifesaver

0:02 Raynes: technomancy: Aw man. Now I'll have to change all of sexpbot's plugins again. :(

0:03 technomancy: I'll fix it in a little while, if you want.

0:03 technomancy: that would be super

0:03 Raynes: I knew it seemed a little odd (add-query-params "http://blah.com" ["key" "val"])

0:04 technomancy: the new snazzy keyword params would be a good way to do it, except for how it requires 1.2

0:04 jartur: lancepantz: not that I have really. I play piano and position my fingers on the keyboard the same way.

0:04 lancepantz: maybe that helps me from getting any tension

0:05 technomancy: btw, is 1.2 going to be released soon?

0:06 lancepantz: just want to try something completely different =)

0:06 Raynes: technomancy: 1.2's keyword parameters would be a perfect match for the request function in client as well.

0:06 lancepantz: jartur: yeah, i'm sure it does, like i said, what really killed mine was playing fps'

0:07 technomancy: jartur: I wish I knew.

0:09 jartur: Clojure is so fast-moving... It scared me at first

0:09 Not that now I am in any way proficient with it. But a little less scared of what is going on.

0:10 scottj: has cemerick been explicit about what he feels is lacking in the big 3 ide plugins? It seems like things lacking are not company-size endeavors. a few refactorings and maybe better completion and paredit for the 2 that don't have it's basica functionality

0:10 jartur: scottj: which one has paredit?

0:11 scottj: jartur: not sure which, it's a limited version of paredit. I think eclipse

0:11 jartur: scottj: Ah... okay. Neve tried an eclipse one. Can't stand that product.

0:12 brweber2: can anyone point me to a decent blog/tutorial/etc on calling Clojure from Java?

0:12 jartur: Btw, does anybody know anything about the future of Clojure on .NET?

0:12 brweber2: I'd prefer to avoid the RT.* route if possible (I already have my classes compiled and jar'd up)

0:12 tomoj: Raynes: with keyword args, though, what do you do if you've built up the map elsewhere?

0:12 lancepantz: i dont think the market would be large enough for a commercial clojure ide

0:12 i guess we're growing

0:13 Raynes: tomoj: What do you mean? How would that effect anything?

0:13 jartur: brweber2: You mean you have :gen-class'ed java classes?

0:13 tomoj: I mean, given (defn foo [& {:as m}] m) (is that right?), what do you do if you've got a map?

0:14 you can't (apply foo the-map)

0:14 brweber2: jartur (I did a compile of the entire namespace actually, including some defprotocols...)

0:14 scottj: jartur: I think the future is to have more of clojure written in clojure. be more specific :)

0:14 Raynes: tomoj: What function are we talking about here?

0:14 tomoj: seems like you have to do (apply foo (flatten (for [[k v] the-map] [k v]))) or something

0:15 jartur: brweber2: Hmm. If you don't want to use RT.* use :gen-class and expose all the methods you want manually

0:16 tomoj: oh, good question

0:16 I didn't actually think about the function you were recommending keyword args for

0:16 probably no problem there, you're right

0:16 jartur: scottj: Rewriting clojure in clojure as much as possible is good. It will make it easier to be platform independend

0:16 Raynes: technomancy: Am I right in assuming that you want add-query-params to work like so: (add-query-params url key1 val1 key2 val2)?

0:16 brweber2: jartur is RT.* really the preferred way to do this? This is the nastiest side of clojure I've seen to do (calling Clojure from Java)

0:16 Raynes: tomoj: :)

0:17 jartur: scottj: I'm just thinking about clojure running on .NET. Imagine a nice XAML library. Writing XAML in lisp instead of actual XML looks nice.

0:17 tomoj: add-query-params seems like a place where a problem might happen, though

0:18 Raynes: tomoj: I'm not entirely certain what Phil was talking about, actually. But we aren't doing that right now anyway.

0:18 technomancy: Raynes: that'd be fine. keeping all the params in a map for the second arg would be just as good; whichever you prefer.

0:18 scottj: Do ruby projects specify their dependencies w/o version numbers often? It sounds convenient, and I wondered why lein doesn't support it (afaik), but I guess it could lead to projects that don't work after awhile because of changing dependencies. thoughts on versionless (latest) dependencies?

0:19 jartur: brweber2: Well... clojure's a little different from Java. I guess it's what we have

0:19 technomancy: scottj: everyone leaves off the version numbers at first. then they get bit by a "minor bugfix upgrade" that sneaks into production, and then they never do it again.

0:19 Raynes: technomancy: I think the way above would be better. If you have a map, you can just apply it. Less line noise when you don't want it.

0:19 technomancy: (IME)

0:19 tomoj: you can't just apply it, though, can you?

0:20 that's what I was trying to point out earlier

0:20 brweber2: jartur I love the Clojure side of Clojure, I had been misled into thinking that calling Clojure from Java is somewhat cleaner than I'm finding it to be. I have an inner class for example that I can't figure out how to call invoke on (should be not too hard...)

0:20 Raynes: tomoj: (apply add-query-params url {"foo" "bar"})

0:20 Oh wait.

0:20 tomoj: yeah :(

0:21 jartur: brweber2: I think clj->java interop was given more priority that java->clj when it all was designed

0:21 brweber2: jartur I'm sure that was the case

0:21 tomoj: brweber2: you have an inner class in clojure and you're trying to call invoke on it from java? I must be confused..

0:21 jartur: brweber2: I think that a really good two way interop would be too limiting

0:21 Raynes: $(letfn [(foo [& blah] blah)] (apply foo {"foo" "bar"}))

0:21 sexpbot: => (["foo" "bar"])

0:21 Raynes: Ouch.

0:22 brweber2: tomoj The inner class was generated by (compile 'my-ns)

0:22 jartur: brweber2: Hmm...

0:22 Raynes: $(letfn [(foo [& blah] blah)] (apply foo ["foo" "bar"]))

0:22 sexpbot: => ("foo" "bar")

0:22 Raynes: Indeed, guess we are going the map route.

0:22 technomancy: scottj: anyway, if you trust a project to use semantic versioning (which you probably shouldn't unless you control it) you can specify a dependency on it with a version range, which will be documented in the next lein release.

0:22 brweber2: interestingly, I have an inner class without an outer class (I had no idea that was allowed!)

0:22 tomoj: brweber2: did you already explain why you're not using gen-class?

0:23 jartur: brweber2: I think you do something rather un-idiomatic

0:23 brweber2: tomoj I used compile to compile the entire namespace

0:23 tomoj: that doesn't sound like a good explanation to me :/

0:23 jartur: brweber2: Yeah, but it's kust AOT

0:23 brweber2: should I use :gen-class to compile every method instead of the entire ns?

0:24 tomoj: just put a (:gen-class) in your ns

0:24 Raynes: technomancy: A side note: after I installed the 2010* slime and swank a few days ago, whenever I slime connect, it warns me that my slime and swank are unmatched (2009 slime, 2010 swank). However, when it starts up, the correct date is shown. "SLIME 20100404"

0:24 jartur: You should use gen-class and have methods with named like (defn -lalala .... )

0:24 Raynes: Not that it's causing any problems.

0:24 Just curious if that is expected.

0:24 jartur: these -lalala methods would be public methods of your class

0:25 Raynes: I have this every time I update

0:25 technomancy: Raynes: yeah, that's a bug in the slime build; the version number is set at compile time when the old version is still around. =\ delete the .elc file to fix it.

0:25 Raynes: technomancy: Cool. Thanks. :)

0:25 brweber2: jartur and tomoj (adding :gen-class, will be back in a second with the results)

0:26 jartur: brweber2: Have you read 'Practical Clojure'?

0:26 scottj: what's the elisp var for telling slime to ignore swank version diffs?

0:26 jartur: Btw, I really think that Clojure needs a nice CC book

0:26 brweber2: jartur No, I have Stu's book and The Joy of Clojure MEAP

0:26 jartur: brweber2: Okay. I think they do have chapters about :gen-class

0:26 And how it works

0:27 I think you should re-read them crefully

0:28 It's actually a rather powerful interface for generating java classes

0:29 Raynes: technomancy: Pull req sent. No hurry, but it would be great if you could toss out a new snapshot as soon as possible so that I can get sexpbot up to date. Pace yourself though, heaven knows you're a busy man. :p

0:30 scottj: jartur: by cc I imagine you mean creative commons, and I'm not sure I agree. I feel like from intro to clojure youtube, rhickey videos, website, and reading core.clj, you can get a better understanding than stu etc books with less time.

0:30 Lajla: Why are their two evaluating bots here?

0:30 jartur: scottj: Well, it depends on a person

0:30 scottj: I got from 'Practical Clojure' so much so fast

0:30 scottj: like 'It's super effective' on me =)

0:30 Raynes: Lajla: Always good to have a backup.

0:31 Lajla: Raynes, if that job pays well, I might consider signing up as third.

0:31 Those bots must have amazing typing speeds though.

0:31 Raynes: I don't use him for any specific reason over clojurebot. I just use him in every other channel but this one, so $ instead of , comes naturally.

0:31 Not that I'm not biased. <3

0:32 scottj: jartur: fair enough, personally I don't feel like I got much out of stu's or joy meap (particularly).

0:32 Lajla: $"string"

0:32 sexpbot: Command not found. No entiendo lo que estás diciendo.

0:32 Lajla: ,"string"

0:32 clojurebot: "string"

0:33 jartur: scottj: Maybe you are too awesome. =) And then I didn't get much of Stu's book as well

0:33 Lajla: Sexptbot, should've called it listbot.

0:33 jartur: scottj: Others I haven't read

0:33 $'a

0:33 sexpbot: Command not found. No entiendo lo que estás diciendo.

0:33 Raynes: Lajla: $eval "string"

0:33 jartur: $'(2 3)

0:33 sexpbot: Command not found. No entiendo lo que estás diciendo.

0:33 Raynes: $eval 'a

0:33 sexpbot: => a

0:33 jartur: ,'a

0:33 clojurebot: a

0:34 Raynes: That stuff doesn't work because $( is a normal command. $eval has to be used for stuff that doesn't start with a parenthesis.

0:34 jartur: ,'$(+ 1 2)

0:34 clojurebot: $

0:34 sexpbot: Command not found. No entiendo lo que estás diciendo.

0:34 Lajla: $(write "Do you support side-effects?")

0:34 sexpbot: java.lang.Exception: Unable to resolve symbol: write in this context

0:34 Raynes: Whoa! Bug!

0:34 tomoj: uh oh

0:34 Raynes: He's supposed to ignore clojurebot.

0:34 jartur: =)

0:34 * Raynes fixes.

0:35 tomoj: as long as clojurebot isn't buggy at the same time we'll be OK :)

0:35 jartur: Well, I don't think anybody would really like to execute Y on these two

0:36 Raynes: That isn't a bug. I never made him ignore clojurebot. I merely made him ignore links from clojurebot when the title scraper was on. I added the => stuff to evaluation so that infinite bot loops wouldn't be possible.

0:36 tomoj: ah

0:36 Raynes: Had a brainfart for a moment there.

0:37 He should still probably ignore clojurebot for annoyance's sake, but infinite loops shouldn't be possible regardless.

0:40 brweber2: tomoj and jartur thanks, I'm one step closer

0:40 Raynes: The behavior of $( always trips people who are used to clojurebot up. I tried to avoid adding special behavior for sexpbot's evaluation. I need to put "allow special plugin-specific prepends" to my TODO list.

0:47 Lajla: $(do [k 10 acc 0] (if (< k 0) acc (recur (- k 1) (+ acc 1)))

0:47 sexpbot: java.lang.Exception: EOF while reading

0:47 Lajla: $(do [k 10 acc 0] (if (< k 0) acc (recur (- k 1) (+ acc 1))))

0:47 sexpbot: java.lang.Exception: Unable to resolve symbol: k in this context

0:47 Lajla: $(loop [k 10 acc 0] (if (< k 0) acc (recur (- k 1) (+ acc 1)))

0:47 sexpbot: java.lang.Exception: EOF while reading

0:47 Lajla: I give up

0:48 Ohh, forgot brace

0:48 $(loop [k 10 acc 0] (if (< k 0) acc (recur (- k 1) (+ acc 1))))

0:48 sexpbot: => 11

0:48 Lajla: Salvation

0:48 Raynes: $(loop [k 10 acc 0] (if (< k 0) acc (recur (- k 1) (+ acc 1))))

0:48 sexpbot: => 11

0:48 Lajla: I salvated first.

0:48 Raynes: :p

0:49 Lajla: Raynes, cloj doesn't support named-let, does it?

0:49 Raynes: named-let?

0:51 Lajla: Raynes, basically like loop, but then like (let arbitrary-name ... ) where arbitrary name becomes a function in the body.

0:51 Like loop/recur, but not needing to be in the tail per se.

0:53 Raynes: If I understand you correctly, I don't think so.

0:54 $(let [x "hai"] x) ; We have let, in any case.

0:54 sexpbot: => "hai"

0:54 tomoj: fns can be named

0:55 not sure if that would work for what you're trying, though..

0:55 Raynes: Oh, is that what he was talking about?

0:55 tomoj: no, but seems similar

0:56 demo:

0:56 $(take 10 ((fn fib [x y] (lazy-seq (cons x (fib y (+ x y))))) 1 1))

0:56 sexpbot: => (1 1 2 3 5 8 13 21 34 55)

0:56 tomoj: could write a macro with a let-style binding form that expands to something like that I suppose?

0:57 Lajla: Raynes, well, a named is basically like loop/recur except that you can chose the name for 'recur' and it doesn't have to be in the tail position.

0:58 Raynes: Yeah, normal recursion. I know what you're talking about now.

0:58 Lajla: Like (let recur ... ) would be in the named-let style a loop/recur in which 'recur' needn't per se be called in the tail position.

0:58 Raynes: The way you said it was confusing. :p

0:58 Lajla: Raynes, well yeah, except that if you don't target the JVM you get tail recursion anyway. =P

0:58 A thing I don't get though, is that tail recursion is lexically inferrable.

0:58 tomoj: I think using a fn like above is equivalent?

0:58 Raynes: You can do that in Clojure, but it wont be optimized.

0:59 Lajla: So if loop/recur is optimized, why can't a normal tail call be?

0:59 Theoretically, a compiler could even rewrite your code to a loop/recur if you used tail recursion, right?

0:59 mmarczyk: Lajla: JVM bytecode which *might consider* attempting to modify the stack won't pass verification

0:59 so that would have to happen on the JVM level

1:00 and, as we all know, it doesn't currently

1:00 Lajla: mmarczyk, but I mean, say you have a source which has (let loop [x 0] ... (loop (+ x 1))

1:00 mmarczyk: what is possible in Java is to use break foo; / continue foo; for foo a label

1:00 Lajla: Surely the compiler can just rewrite that source to (loop [x 0] ... recur(+ x 1))

1:00 mmarczyk: to break out of a couple of nested loops... I wonder if whichever bytecode corresponds to this

1:01 jartur: mmarczyk: Lajla means pure sytactic transofrmations

1:01 Lajla: And then treat it as if it would with loop/recur?

1:01 mmarczyk: could be used for a named let-like recur

1:01 Lajla: jartur, well, no matter in what way, a tail-call is lexically inferrable.

1:01 mmarczyk: well, take a non-trivial scenario and try to rewrite it yourself :-)

1:01 Lajla: Surely the compiler can then recognise it and compile it to different code than a simple function call?

1:02 mmarczyk: you'll end up using some sort of flag to indicate which loop is to move forward next, I would guess

1:02 jartur: Lajla: I don't think lexically, I think syntactically?

1:02 Lajla: jartur, no, lexically.

1:02 mmarczyk: anyway, a full named let-like think is impossible without proper TCO

1:02 jartur: Lajla: why?

1:02 Lajla: I mean, as an obvious example in a C-style langauge, if a function call is directly following a return statement.

1:02 mmarczyk: because in the named let, say (let foo (...) ...)

1:02 Lajla: You have a tail-call.

1:03 mmarczyk: foo is really bound to a function

1:03 jartur: Lajla: lexical analysis is only a tokenization of the strea,

1:03 mmarczyk: which you can, in particular, pass to other functions etc.

1:03 ^named let-like thing

1:03 clojurebot: most horrible thing is http://tinyurl.com/b65o8e

1:03 jartur: Lajla: you can't infer anything from lexems

1:03 Lajla: jartur, as far as I know my terminology, lexical analysis is all a compiler can know without running any applications.

1:03 Such as static type errors.

1:03 jartur: Lajla: no.

1:03 Lajla: Or more properly proving no type errors are going to occur.

1:03 jartur: Lajla: it's static analysis

1:03 mmarczyk: that's actually called static analysis

1:04 right.

1:04 Lajla: Ah

1:04 I use the terms lexical and static interchangeable.

1:04 jartur: Lajla: it includes lexical analysis + syntax analysis + semantic analysis

1:04 at least

1:04 Lajla: As in, determinable from program source without running code.

1:04 But anyway, doesn't matter that much, it's still statically inferrable, before running, a tail call.

1:05 mmarczyk: so anyway, for the reason mentioned above, you cannot mimick Scheme's named let

1:05 jartur: Lajla: Ah, I see where you come from. It's lexical like in 'lexical scoping' =)

1:05 Lajla: So it could be compiled to different code than an ordinary call, right?

1:05 mmarczyk: some scheme to do local multi-level looping could be implemented as a macro, I guess

1:05 I'd give it a shot if I were less sleepy, but alas, another time maybe ;-)

1:05 Lajla: jartur, well, lexical scoping is an example yes.

1:06 mmarczyk, will you hug me for the idea when you succeed?

1:06 mmarczyk: I actually had the idea before :-)

1:06 Lajla: Then hug yourself first, and then me.

1:06 mmarczyk: sounds tricky

1:07 Lajla: mmarczyk, you are the fifth greatest programmer in the world, you can do all.

1:07 Except beat the Microsoft CSA and me amongst others.

1:07 mmarczyk: I'm not sure which ordering on the population of programmers you're using

1:08 I've ranked myself closer to 10^6th spot and I thought that bordered on hubris ;-)

1:10 Lajla: mmarczyk, we lispers are gods, you must realize.

1:10 Only the person that invented the FAT16 filesystem can beat us.

1:10 jartur: ,(for [x ['mmarczyk 'Lajla]] `(mmarzczyk hugs ~x))

1:10 clojurebot: ((sandbox/mmarzczyk sandbox/hugs mmarczyk) (sandbox/mmarzczyk sandbox/hugs Lajla))

1:10 mmarczyk: (loop [level 0 ...lots-of-other-locals...] (case level 0 (...outer loop body...) 1 (...middle loop body...) 2 (...inner loop body...)))

1:11 technomancy: mmarczyk: you had an idea for a lein patch that I think I missed earlier?

1:11 or more than an idea?

1:12 mmarczyk: technomancy: I've sent you a pull request adding handling of extra project.clj entries for inclusion in pom.xml, mailing list addresses, licenses, project url (I think that's all)

1:12 that was a while back

1:12 so, it includes some modifications to README to explain the usage of those

1:12 but now that you've added sample.project.clj, I could put stuff in there

1:13 in an updated version, if you feel like you might want to pull that in

1:13 technomancy: mmarczyk: that'd be great

1:13 Lajla: mmarczyk, well, since case, cond, and, or et cetera are all rewritten to if, the only thing you need to pay to is recursivelly it's a tail call if it's the last sub-form of the body, or part of a then or else branch of an if-form which is a tail call.

1:13 mmarczyk: technomancy: cool, I expect to have a super-busy day today, so I'll probably send a new pull request tomorrow

1:14 Lajla: That should be statically inferrable, after that, it can be compiled to a loop/jump on the JVM, and not an ordinary procedure call, right?

1:14 mmarczyk: technomancy: incidentally, that patch allows all of :licence, :license, :licences and :licenses to be used, where the singulars take single items and plurals take seqs... are you ok with that? :-)

1:16 tomoj: Lajla: those are rewritten to if?

1:16 mmarczyk: case is not rewritten to if, afair

1:17 I believe it's a hash-map-like dispatch

1:18 Lajla: I'm not sure what you're trying to achieve

1:19 if it's just the possibility to recur to the top of an enclosing loop from an inner loop

1:19 tomoj: Lajla wants TCO in the compiler, I thought?

1:19 mmarczyk: then the loop/recur form I offered above is one way of doing that and you could write a macro to expand to that

1:20 but a full named let is impossible

1:20 because, as I said above, in Scheme (let foo (...) ...) binds foo to a function

1:20 Lajla: mmarczyk, Clojure doesn't rewrite all conditionals to if with macros?

1:20 mmarczyk: most, but not case, I think

1:20 tomoj: "full named let" means with TCO?

1:20 Lajla: mmarczyk, yeah, but a compiler can statically check if a function is called in the tail.

1:21 And then compile to different code than an ordinary function call.

1:21 mmarczyk: tomoj: well, sure, since we can have named let without TCO

1:21 tomoj: but I mostly meant the fact that foo is a function

1:21 tomoj: ok, was just checking I wasn't confused

1:21 mmarczyk: Lajla: actually that's not true for Clojure's compiler

1:21 tomoj: oh, hmm, what's wrong with foo being a function?

1:21 Lajla: mmarczyk, why can't it?

1:22 mmarczyk: because it can't spit out code which could manipulate the stack

1:22 the stack is where the arguments need to be placed

1:22 in stack frames

1:22 Lajla: Ahhh

1:22 mmarczyk: prior to the jump to the top of the routine being called

1:22 Lajla: This JVM is a lot more complex than a typical instruction set I gather?

1:22 mmarczyk: not at all

1:23 but the bytecode gets passed through a so-called "verifier" when it's loaded

1:23 Lajla: mmarczyk, ahhh

1:23 mmarczyk: if it doesn't meet certain safety criteria, it won't be loaded

1:23 Blackfoot: has anyone built clojure-couchdb? when i try to ./lein jar I just get a zip/jar file with the clj files in it

1:23 mmarczyk: part of that is that it must not manipulate the stack in funky ways

1:24 meaning in a way except through regular JVM-supported method calling facilities

1:24 Lajla: mmarczyk, and why is it not possible to for instance compile normal functions in the tail position to the same java bytecode as loop/recur gets compiled to?

1:24 mmarczyk: Lajla: and how'd you go about that?

1:24 surely you wouldn't want to inline every function which happens to be mentioned in a tail position

1:24 at each tail call site

1:25 also, you might make a tail call where you don't statically know which function will end up being called

1:25 apply doesn't know which functions it might apply, for instance

1:25 Lajla: mmarczyk, I don't get you, you always statically know if a function is in the tail position.

1:25 mmarczyk: yeah, you might know that and yet not know which function it is

1:26 (fn [f] (f))

1:26 (lambda (f) (f)) in Scheme

1:27 Lajla: That can be lexically detected there and compile that form to a different code then if it wasn't tailed.

1:27 That's how Scheme does it I think.

1:27 mmarczyk: um, nope

1:27 Lajla: How then?

1:27 It decides it at runtime?

1:27 mmarczyk: depending on the implementation, Scheme programmes might be subjected to a full-programme CPS transform

1:27 then their function never "return"

1:28 I think Chicken does that

1:28 Lajla: Yeah, chicken compiles like that to C.

1:28 mmarczyk: an alternative would be to rewrite the last stack frame

1:28 I would say that this sort of CPS transform is problematic for Clojure

1:28 because it's meant to be callable from other JVM languages

1:29 so needs to follow standard calling conventions

1:29 Lajla: Well, if you say so, I still think I'm missing some vital info here.

1:29 tomoj: I trust rich will do what's best :)

1:29 mmarczyk: in fact, I should have mentioned this earlier, since this disqualifies quite a number of possible approaches :-P

1:29 Lajla: Trust no one, not even me.

1:29 Not even banknotes or He they say you must trust.

1:29 mmarczyk: well, if you can't touch the stack and can't do cps on all your functions

1:29 and also

1:30 tomoj: if the tradeoff were worth it to get people to stop saying "WTF NO TCO?!", I'm sure he'd do it

1:30 mmarczyk: you can't really jump to the top of another routine

1:30 Lajla: tomoj, I got that idea, that's why I'm puzzled.

1:30 mmarczyk: there's no goto in Java, I expect the JVM not to be accommodating if one tried to introduce it...

1:30 Lajla: I'm currently investigating writing a compiler, I'll guess I'll go with C-- though

1:30 C with TCO, amazing.

1:31 mmarczyk: gcc can do that for you, I believe :-)

1:31 though you might have to ask

1:31 Lajla: mmarczyk, actually, goto is a reserved word in Java, but cannot be used for any purpose.

1:31 Well, C-- is far more amazing than C to be honest.

1:32 You don't have types like 'int' and 'char', you have bits8, bits32 et cetera

1:32 mmarczyk: yeah, that's at the level of Java syntax, but I would be amazed if you could "goto" at the level of JVM bytecode

1:32 so, if you can't manipulate the stack, can't jump to arbitrary code, can't CPS transform your code...

1:33 you're left to petition to the platform developer for TCO & continuations

1:33 Lajla: Seems more complex than your average instruction set, or even C--, but I never read the JVM specs.

1:33 mmarczyk: if anything, this particular point makes it simpler

1:33 one less thing you can do :-)

1:35 it would be interesting to compare the performance of SISC, say, or ABCL if it provides TCO

1:35 Lajla: mmarczyk, well, I tend to define 'simple' as 'being composable from fewer axioms'

1:35 mmarczyk: to that of Clojure

1:35 Lajla: What's SISC?

1:36 mmarczyk: Lajla: I understand that neither of us knows which number of instructions the JVM and, say, x86-64 provide, so it'll be hard to decide on which is simpler just now

1:36 SISC is a JVM Scheme

1:36 not sure if it's maintained, though

1:37 Lajla: mmarczyk, well, I guess I don't measure complexity by the amount of instructions. I mean, one 'instruction' can have a more complex operation.

1:37 ADdition is a lot less complex than computing an arctangent (apparently x86 has this)

1:40 mmarczyk: ok, got to go for now; bbl -- see you!

1:42 Lajla: mmarczyk, you cannot, you are the fifth greatest programmer in the world.

1:49 Blackfoot: how does the classpath work for jars that lein produces with clj files in them? I'm 'use'ing a jar produced by lein, but my new method is not available in the namespace

2:10 TheBusby: the classpath will need to specify the jar

2:10 Example: export CLASSPATH=/home/foo/MyJar.jar

2:16 Blackfoot: TheBusby: ah ok. i think i figured it out. there was an older jar in the system classpath

2:20 nipra: Is it possible to give nicknames to a namespace using ns macro like defpackage in CL?

2:22 Blackfoot: when you (use) a namespace, you can give it a nickname with :as

2:22 or require: (:require [clojure.contrib [error-kit :as kit]])

2:23 (:use [some.long.identifier :as nick])

2:23 Raynes: ninjudd: In ns: (:use [some.sort.of.long.namespace :as ssoln]), outside: (use '[some.sort.of.long.namespace :as ssoln])

2:23 nipra: Sorry, wrong 'n'. :p

2:23 tomoj: weird that :use can do that

2:24 oh

2:24 :use :as refers to everything AND gives you a nickname

2:25 usually want (:require [foo.bar :as baz]) I think

2:26 nipra: Raynes, will (in-ns 'ssoln) work?

2:27 jartur: nipra: It will set ssoln as a current ns

2:27 nipra: Raynes, I want to use the nickname to change the namespace at repl from long ns to short ns.

2:27 tomoj: nope, won't work

2:28 jartur: I think (alias short long)

2:28 (alias 'db 'clojure.contrib.sql)

2:28 tomoj: still won't work

2:28 ideally your development environment will help you with switching namespaces in the repl

2:29 mmarczyk: (defn switch-ns [sym] (in-ns (if-let [full ((ns-aliases *ns*) sym)] full sym)))

2:29 tomoj: oh, cool :)

2:29 mmarczyk: :-)

2:32 ah, only it won't work... correction: (defn switch-ns [sym] (in-ns (if-let [full ((ns-aliases *ns*) sym)] (.getName full) sym)))

2:33 jartur: This is the first time I saw (if-let [b t] t e) form

2:34 So much to learn...

2:36 Like the other day I have constructed an atrocious monster construct with merge and filter to filter a few keys from a hash.... Then I read about dissoc

2:37 Blackfoot: if-let and when-let are great, i keep wishing i had them in other languages now

2:37 technomancy: what'll really blow your mind is the fact that it's pronounced "dissosh"

2:37 jartur: =)

2:37 mmarczyk: (defn switch-ns [sym] (if-let [target (or (find-ns sym) ((ns-aliases *ns*) sym))] (in-ns (.getName target))))

2:37 jartur: Yeah.

2:37 technomancy: not "dissock"

2:37 mmarczyk: more in line with the name, I guess...

2:38 jartur: dissauche

2:39 mmarczyk: jartur: in case you need to do the reverse, remeber about select-keys :-)

2:39 jartur: mmarczyk: thanks. I'll try to remember that =)

2:41 I have a design question. I have a set of functions, all of which are private and call each other. Each one does a little to process input and then passes it to the other function.

2:41 Now, the last function in the chain actually does use a database connection

2:42 Which my public function (the most abstarct one, it's the one that is the most far from the function that does the work)

2:42 gets when called

2:42 mmarczyk: maybe have them return the result of the processing, then use (-> input f1 f2 f3 ... (f-last db-connection)) ?

2:43 jartur: mmarczyk: Damn. It's not a dilemma anymore!

2:43 It's a trilemma =)

2:43 mmarczyk: ouch :-)

2:43 Blackfoot: heh what's the question?

2:44 jartur: I like this threading approach. Completely forgot about it already.

2:44 I was thinking about either passing the connection as a param through all the fns

2:44 Or using some var and call the chain with (binding ...)

2:44 I don't like this (binding stuff)

2:45 Cuz it looks os wrong

2:45 maxhodak: when something's a personal project, is the convention to do "maxhodak.foo.bar" or "com.maxhodak.foo.bar" or ...?

2:45 jartur: But having the same param everywhere is such a nuisance

2:45 mmarczyk: maxhodak: some examples of things which started out as personal projects include Clojure, Compojure, Ring, Enlive, ... :-)

2:46 Enlive does use net.cgrand.enlive-html as the main ns name

2:46 jartur: But now when I see (-> ...) I think I have to re-think some things

2:46 Like how not awesome I am =/

2:47 mmarczyk: jartur: I went through a period of not using -> / ->> at all in the beginning of my time with Clojure

2:47 to reimplementing it as a syntax-rules macro for use in Scheme :-)

2:47 jartur: mmarczyk: I come to clojure with some Scheme background.

2:48 mmarczyk: So for me making all just functional seems like the most 'right' thing

2:48 mmarczyk: yeah

2:48 jartur: mmarczyk: And writing macros in scheme is not painless =)

2:48 I can't believe how simple clj macro system is

2:48 mmarczyk: in this case, you'll just need to look around the standard lib and you'll feel right at home :-)

2:49 well, you probably already do

2:49 as for your private functions, I think it's a bit wasteful to have them call each other

2:49 rather than simply return the result of their little bit of processing

2:50 jartur: I just need to shift my approach to FP in general

2:51 Also I think one (me included) should resist any temptation to use vars as long as it doesn't *really* make things cleaner.

2:51 Lajla: jartur, pain is the essence of good programming.

2:51 To have a dark side.

2:51 mmarczyk: jartur: agreed on binding

2:51 jartur: Lajla: I love scheme macros actually

2:52 Lajla: define-syntax is awesome

2:52 Lajla: jartur, my own hygienic macro system is so much more awesome.

2:52 But I agree, it is.

2:52 jartur: Lajla: But not easy. Esp. when you do it your first several times

2:52 Lajla: I just miss sequencing in it.

2:52 jartur, it's fairly human readible, is it not.

2:53 It's almost WYSIWYG macroing.

2:53 jartur: Lajla: Yes, but getting to understand all this syntax-objects

2:53 Blackfoot: threading data through functions makes the functions easier to test, too

2:53 mmarczyk: (define-syntax -> (syntax-rules () ((-> x) x) ((-> x ()) (error)) ((-> x (y . ys)) (y x . ys)) ((-> x y . ys) (-> (-> x y) . ys))))

2:54 jartur: mmarczyk: you are a maniac, no?

2:54 mmarczyk: one of the nice cases where macro by example is simpler :-)

2:54 um? ;-)

2:55 Lajla: jartur, my system works like this: {define-syntax {let ((<symbol:name> <form:value>) ...) <form:body>} ({lambda (<symbol:name> ...) <form:body>} <form:value> ...)}

2:56 mmarczyk: Lajla: a fan of PL:AI?

2:56 Lajla: mmarczyk, what is that?

2:56 jartur: I used syntax-case

2:56 syntax-case is a little more difficult than syntax-rules I believe

2:57 Lajla: jartur, it's also not fully static.

2:57 Is my impression

2:57 it seems to be able to evaluate expressions, strangely.

2:57 mmarczyk: Programming Languages: Application and Interpretation, by Shriram Krishnamurthi

2:57 Lajla: mmarczyk, never heard of it.

2:57 mmarczyk, why?

2:57 They also use extremely complicated, barely readable hygienic macro systems?

2:58 jartur: =)

2:58 syntax-case is just a little mind-boggling

2:58 Lajla: jartur, and I believe, not static.

2:59 jartur, but one day, you'll be the third best programmer in the world, and understand it all.

2:59 mmarczyk: Lajla: just because of your use of {}

3:00 Lajla: mmarczyk, ohhh, nonononono, my lisp firmly destinghuishes {syntax . <list:parametres>} from (function-call . <list:arguments>)

3:00 Syntax is not data, you can kiss your eval goodbye.

3:00 jartur: http://gist.github.com/431147 - example of a relatively not simple syntax-case macro

3:00 mmarczyk: your lisp is not a lisp then, but of course it might still be a nice language ;-)

3:01 Lajla: mmarczyk, well, considerate point.

3:02 I found it particularly ideal to seperate syntax, which has its own evaluation model from functions, which do not in terms of compilation.

3:02 Raynes: Yo dawg, we herd u liek lisp, so we put a macro in your macro, so you can generate code while you generate code.

3:04 mmarczyk: jartur: ah, looks nice... regrettably I never spent much time with syntax-case

3:04 Lajla: Raynes, well, all people like lisp.

3:05 I consider revoking people status for those that don't.

3:05 Raynes: That's a lot of people, sir.

3:05 You give humans too much credit.

3:05 Lajla: So that we may lock them up into 1 by 1 prisons with five of them and feed them hormones so that we can eat their delicious meat.

3:05 jartur: mmarczyk: looks nice, but no so nice when you are newbie and try to write that

3:05 mmarczyk: I do recall having a paper by Dybvig on my pile which will probably lead to me learning about it, though :-)

3:05 Lajla: Raynes, it's hard not to overcredit people.

3:05 Raynes, but you, you I will always love.

3:06 mmarczyk: jartur: there's some mercy in the fact that a newbie will *not* try to write that :-)

3:06 jartur: mmarczyk: I did =)

3:06 Lajla: mmarczyk, I disagree.

3:06 Most people learn programming in reverse, they first do things, then they learn to understand what they did 4 years later.

3:06 mmarczyk: jartur: apparently you never noticed the point at which you ceased to be a newbie then ;-)

3:07 Lajla: hah! actually I think you're totally right

3:07 jartur: mmarczyk: About the time i've finished that and a couple of other macros =))

3:07 Lajla: It takes an average C programmer 5 years to realize the fact that "Hello, World!" as an expression evaluates to a char pointer and has the side effect of statically allocating a lot of chars and a 0 which is not larger than a short int into memory.

3:07 They also seem to forget a lot that the C standard actually allows for char to be the same size as int.

3:08 mmarczyk, I myself praefer to first be able to write a formal specification in a language before I begin printing hello world, it makes me feel intelligent.

3:08 Just like writing 'praefer' with ae, I think you all find me very intelligent and interesting then, amirite?

3:09 jartur: Lajla: most definitely so.

3:10 Lajla: And think that I have a bookshelf of Encyclopædiæ Britannicæ and various diplomata from academic institutes, and by my wise skills have never been caught by computer virus, whose linguistic use of mine is but surely only a mass noun.

3:10 I was thinking of putting 'octopodes' in that sentence, but found no adequate place.

3:10 Fossi: aught by computer virus octopodes

3:11 there you go

3:11 although i think pseudopodes is even better

3:11 Lajla: What's a pseudopod? An animal with incomplete legs?

3:11 Platypodes is also nice.

3:12 Or people that use plurals like mujihadeen and use the singlar 'talib' for one member of the taliban.

3:12 And use tullaab when it's an Arabian member of the Taliban.

3:12 jartur: I like my octothorps.

3:13 Lajla: jartur, I think we should not longer use the word 'to program' but drop it in lieu of 'prographize'

3:13 Or be really Icelandic and use 'to forewrite'

3:14 jartur: Though I have to admit that I don't know English that well. It's neither my native language nor a language of my surroundings.

3:14 Lajla: Might as well bring back the infinitives like forewriten.

3:15 jartur: And why do you need all these stupid articles like 'the' or 'a' which I never know how to place properly I don't know.

3:15 Lajla: jartur, I think this is more related to Greek than English, but as the second best programmer in the world I must make the impression of being very educated, which I'm not, I just make that impression well.

3:15 jartur, slavic?

3:15 jartur: Lajla: yes.

3:15 Lajla: jartur, which?

3:15 jartur: Lajla: La Russe.

3:16 Lajla: All I can say in Russian is 'I am a paederast'

3:16 I can even spell it in cyrillic, but that takes time.

3:16 jartur: Lajla: This is a very very important thing to know. Just don't ever use it when russians are around.

3:16 mmarczyk: are there any articles in Finnish?

3:17 jartur: Nope, I think

3:17 They don't even have prepositions.

3:17 IIRC 'finland' = suomi / 'in finland' = suomissa

3:18 Something like that anyway

3:18 They have lots of cases

3:18 Lajla: mmarczyk, nahh

3:18 Well, in some dialects.

3:18 jartur: Their language is not even indo-european

3:18 Lajla: THey use 'se' (it/that/he/her) also as 'the'

3:18 And yks (one) as 'a'

3:19 Or well, depends, like, if you say 'olla tai ei olla, se on se kysymys' you use 'se' an article, as in 'to be or not to be, that is the quaestion'

3:19 Without se it would sound like 'that's a quaestion' like 'that's a thing you could ask' or 'that's a problem you deal with'

3:20 Not 'that's the thing you should ask'

3:20 mmarczyk: Lajla: from "they use" I deduce you're not Finnish yourself?

3:20 jartur: Well some words which to some extend approximate articles are used in most languages

3:20 Lajla: mmarczyk, well, no.

3:21 jartur: But they are more like what the and a used to be

3:21 Lajla: Actually, my Finnish is superb crap, but quote inhumanly good unquote when you realize that I learnt it from hearing my roommate talk to her mother on the phone.

3:21 jartur: Not 'put me in every time I don't know why' kind of words

3:21 mmarczyk: Lajla: ah, cool :-)

3:22 Lajla: mmarczyk, I simply lack a lot of vocabulary, but it's grammatical and I have a feeling for the language and it's quite fluend and accentless, I just don't even know what a car is in Finnish.

3:22 jartur: Lajla: perkele!

3:22 Lajla: jartur, saatanan kyrvä!

3:22 kyrvät*

3:22 jartur: Suomi on suuri maa

3:22 And...

3:22 Kissa on valkoinen

3:22 Ei on musta

3:22 =))

3:22 Lajla: jartur, ei, on maa depressivalaisen kanssa, kaikki ja kaikkialla.

3:22 jartur: That's about my finnish

3:22 mmarczyk: oh good, I somehow managed to introduce Finnish to #clojure without speaking a word of it :-)

3:23 Lajla: mmarczyk, I thought you addressed me actually, because I some times speak Finnish here.

3:23 eevar2: ei saa peitaa!

3:23 mmarczyk: hm, I had a vague memory of "a mention of Finland", but that might be inaccurate

3:24 Lajla: I have no idea what verb sakaa or what it could be is or what verb peitaa is.

3:24 mmarczyk: so, you're the one to have performed the introduction then.

3:24 Lajla: mmarczyk, some one accused me of talking too much Finnish.

3:25 mmarczyk, well, I am eager to talk Finnish, a bit too much perhaps, I enjoy the boring work of inferring linguistic patterns, any patterns really, this is because I am very autistic, but I make up for all this by being a good cook.

3:25 mmarczyk, you are less autistic than I, surely because you are only fifth.

3:25 eevar2: "do not cover", stamped on ovens and such. probably missing some accents+++

3:26 Lajla: eevar2, google translate?

3:26 Imperative negation is with älä, not ei, namely.

3:26 mmarczyk: I envy your cooking ability.

3:26 eevar2: nah, oven vendor translation

3:26 Lajla: Like älä päästä koskaan <- don't ever let go. From a very cheesy Finnish chickflick which I watched.

3:26 Ahahaha

3:27 Fossi: :D

3:27 suomi <3

3:27 eevar2: have that phrase in a dozen or so languages. try googling it ,)

3:27 Lajla: mmarczyk, I like to think that all people envy me in all ways, they want to hate themselves like I do, but they can never parallel my fantastic level of self-harm and nightmares, never be as great as I.

3:27 Fossi: i learned all my finish at the same time as my toki pona

3:27 i mix them all the time

3:27 they are pretty similar in some ways

3:28 Lajla: Fossi, oletko säkin suomalaista?

3:28 Miksi, miksi, kaikki teitä on IRC:lla, ja mun kanavalla.

3:29 The point about learning Finnish from listening to some girl who's lived in another country since she was two is that you gain the impression that you can just coin new words on the fly in Finnish from English and Dutch roots.

3:30 Like, you think that 'internetti' and 'aipotti' and 'utrehti' are actually words.

3:41 cgrand: good morning #clojure!

3:42 Lajla: cgrand, mene pois tai puhu suomea.

3:42 Tää on kanava joka on puhumaks suomea.

3:42 cgrand, I'm just kidding.

3:45 Raynes: cgrand: Good morning.

3:45 jartur: cgrand: good evening

3:47 candera: cgrand: good whatever you call 3:45AM. :)

4:09 esj: Mroning All

4:14 LauJensen: Morning esj

4:21 Lajla: esj, terve, miten menee, on kaikki hyvää?

4:21 onko

4:21 esj: Lajla: I'm going to go for, "make it a double"

4:27 Lajla: esj, I agree

4:28 Shaken, not stirred.

6:53 korre: infoq relased an interview with John Hughes http://www.infoq.com/interviews/john-hughes-fp if anny one is interested :D

7:37 rhickey: so, if you needed symbols and letters to designate 64-bit integers and 64-bit floating point numbers, what would they be? taking a step back from the host words long and double (although they are candidates)

7:39 It's kind of a shame int and float terms are bound to 32-bit on the JVM/CLR

7:39 in a vacuum, they're probably what I'd pick

7:43 wlangstroth: rhickey: any objection to using something with "64" in it?

7:44 gregh: fixint?

7:44 rhickey: wlangstroth: well, 32 won't be an option. And the letter version might be used in places as well

7:45 gregh: too bad there isn't really a unified numeric tower where you can just call them "number"

7:45 jonasen: Z and R as in math?

7:45 rhickey: the letters might best be shortenings of the words

7:46 gregh: zinteger :)

7:47 wlangstroth: rhickey: for integers, "long" is difficult to beat

7:47 esj: ditto that for double

7:48 rhickey: wlangstroth: yes, l can be a problem as a suffix though, although mostly when i is also in play

7:49 wlangstroth: oh, I see what you mean now

7:52 axi: long=fat?

7:56 wlangstroth: how about "whole"?

7:57 esj: wide ?

7:57 wlangstroth: oh, right - you'd end up with "whole" as the integer, and "wide" as the float!

7:58 esj: not that clever, i was thinking wide_int & wide_float.

7:59 Licenser: cookies

7:59 wlangstroth: I was thinking in terms of rhickey's readable suffix problem

7:59 axi: but he wants unique letters for each type?

7:59 wlangstroth: wide is pretty good

8:00 axi: oh, he just wants them to be readable

8:01 Licenser: I'd go with long and double too, just my 2 cents, or int64 or somethinlike that

8:02 I'm against R and Z since 64 bit numbers are not really much more R or Z then 32 bit

8:02 wlangstroth: Licenser: but there won't be a 32 bit option

8:03 Licenser: ah it is not opposite to 32 bit?

8:03 rhickey: right, the idea is that these are big enough to subsume all of the primitive integer and floating point primitives on the platform

8:03 esj: Licenser: agreed. it doesn't seem that long & double, are 'broken' so why change ?

8:04 rhickey: esj: if you were to design a language from scratch that had only 64-bit integers and 64-bit floating point numbers, would you call them long and double?

8:04 wlangstroth: double, no

8:04 I've never been a fan of "double"

8:05 Licenser: actually I think their name, at least classically is host based, on a x64 system a C int is 64 bit (one register) when I remember right a long would be 128 ) two registers) or am I mistaken

8:05 rhickey: long and double only work as comparators to their shorter brethren

8:06 esj: rhickey: no, I'd call them int and real, but those terms are taken. Further, those using my language already have nouns that are familiar to them so it makes sense to use them.

8:06 axi: couldn't you implement int and float using a different case?

8:06 wlangstroth: exactly, but "long" isn't explicitly comparative

8:07 rhickey: wlangstroth: if there is only one thing, how to choose between long and short then?

8:07 esj: Licenser: I think you are correct in that.

8:07 Licenser: certainly i've used C in an embedded context where the length of primitives varies.

8:07 rhickey: long doesn't say anything about numbers the way int does

8:08 wlangstroth: rhickey: I mean it's not "longer", but fair point. I'd say "integer", naturally

8:08 ... but as you say, "i" is taken

8:08 axi: then use num(ber)?..

8:08 rhickey: integer and floating

8:09 ?

8:09 cgrand: intnum and floatnum? bleh :-(

8:09 wlangstroth: integer and floating

8:09 Chousuke: hmh

8:10 esj: and its a visual pun.... very clojure.

8:10 Chousuke: too bad the host has taken the good names :(

8:11 rhickey: esj: just to be clear, I'm playing devil's advocate here to see if there's something better than long and double, which win by default

8:11 Chousuke: if you want to separate between "clojure" primitives and host primitives, it would be better to call host integers hostint or something but that would be a breaking change :/

8:11 esj: rhickey: :)

8:13 wlangstroth: Haskell has "Integral", but that's pretty close to "int"

8:16 "floating" without "point" looks funny

8:16 (okay, I've stopped being helpful - carry on)

8:20 * axi blames the english language

8:20 axi: http://thesaurus.com/browse/integer

8:20 it looks like the only alternative word for integer is digit

8:26 Licenser: rhickey: integer sounds not to bad, but floating sounds a bit odd, I'd percive it more as a value type that does some kind of floatin between places (a thread that can float between different hosts for example)

8:27 what about fixednum for int, I know it's from the ruby world but it also kind of makes sense

8:28 axi: oh nvm, a digit would be a 4-bit integer =p

8:28 rava: hello

8:29 hugod: scientific - as in scientific notation?

8:36 cemerick: what likely Clojure host doesn't use long and double?

8:38 rhickey: cemerick: javascript

8:38 cemerick: heh

8:38 rhickey: not exactly a reasonable source of a veto w.r.t. numeric anything :-)

8:38 I don't know anything about LLVM, so that's a wildcard for me.

8:39 chouser: "fixed" and "inaccurate" -- f and i

8:39 cemerick: chouser: stop causing trouble ;-)

8:39 rhickey: cemerick: this is more of a what-if exercise. I agree any deviation from host is going to have use explaining the relationship between e.g. "integer" and ints and longs

8:39 us explaining

8:40 cemerick: yeah, I saw your devil's advocate msg above. I guess my Q would be, why is long and double bad in theory?

8:40 rhickey: everyone is ok with long and double being the only supported primitives in fns?

8:40 cemerick: (aside from their being defined in terms of smaller numerics)

8:40 rhickey: cemerick: you would never choose them in a clean-slate design

8:41 * cemerick goes looking for a scheme numerics refresher

8:42 * axi would prefer to use Int and Float

8:43 cemerick: clean-slate or not, primitive numerics always have host limitations. Just by calling things int and float (for example), that wouldn't make 64-bit primitive maths appear in javascript, or in a 32-bit embedded environment. *shrug*

8:43 wlangstroth: beside the fact that it's going to bother me all day now?

8:43 it's surprisingly hard to find accurate terms

8:46 Licenser: rhickey: whoat about just using int and float and then giving a special option to access the 'host version'

8:46 so h:int or h:float

8:46 while this might sound silly but it might be better suited when we deploy on multiple hosts

8:46 wlangstroth: with a colon?

8:46 Licenser: it is just an idea

8:47 wlangstroth: (oh wait, you're the @->-- guy)

8:47 Licenser: (<3 'clojure)

8:48 wlangstroth: haha

8:48 Licenser: when I stop waling funny I'll go and send rhicky the CA and some candy so he lets me put <3 in c.c!

8:48 wlangstroth: cemerick: but how close to the metal are we really talking in this context?

8:48 cemerick: wlangstroth: I understand "primitive" to be the unboxed (if relevant) numerics provided by a host.

8:49 rhickey: wlangstroth: all the way, to single instructions on chip

8:49 Licenser: What I see is that in java we might have doulbe and long, do we have it in .net? or javascript, or ObjC, or (I can go on here)

8:49 cemerick: rhickey: given that, the names have to correspond with whatever host you're targeting, no?

8:50 rhickey: cemerick: no, there will be one pair of names, and they'll map to whatever your host can do for 64-bit ints and floats

8:50 chouser: long and double were surely not intuitive when first introduced

8:50 rhickey: long and double work for JVM/CLR

8:51 chouser: still a mystery of C

8:51 cemerick: rhickey: what about decimal in .NET-land?

8:51 rhickey: cemerick: not covered by this

8:51 candera: CLR int/long broke with the C/C++ tradition for that name.

8:51 rhickey: the point of primitives is to reach the hardware

8:52 candera: followed Java in that

8:53 chouser: I'm not sure clojurescript would ever support primitives. Even if it did, it would have to map them to JavaScript types which show no sign of being unboxed ever.

8:53 Licenser: chouser: there are different js engines which might behave differently :P

8:54 rhickey: so, let's leave it at long and double for now. Is everyone ok with only long and double primitive support for fns?

8:54 chouser: if the unboxing or primitives are somehow automatic, then the clojure compiler need not worry itself with them. If not, declaring them would be a change to the language spec and that's exactly what I find unlikely in the forseeable future.

8:55 rhickey: chouser: ?

8:55 chouser: if the unboxing or primitives are somehow automatic in a particular JS engine, then the clojure compiler need not worry itself with them. If not, declaring them would be a change to the JS language spec and that's exactly what I find unlikely in the forseeable future.

8:55 rhickey: ah

8:56 wlangstroth: rhickey: expedience wins

8:57 cemerick: rhickey: you had a formal reason for not bothering with int and float, right? Overload counts, was it?

8:57 rhickey: cemerick: several. Simplicity, redundancy, no information loss moving up, combinatorics

8:58 also the 64-bit ops are proving to be no more overhead

9:00 but essentially, the smaller the footprint, the smaller the downstream overhead. This is a problem with e.g. CLR value types - they propagate complexity down the chain. It is easy to envision mapl, mapd...

9:02 cemerick: so while you may look at this as a host thing, it really is not. It's about reaching the hardware. Not providing a mapping to every host lang data type

9:03 e.g. most of the Java integer types are fictions - it has no bytecodes for things smaller than 32-bit

9:03 * dnolen is ok with long and double

9:03 cemerick: rhickey: that's where I get fuzzy, just because I lose sight of things under my nose. Java's "primitives" aren't necessarily machine primitives

9:03 rhickey: cemerick: ^^ not even bytecode primitives

9:03 cemerick: right

9:03 I'm not clear on that stuff at all. Mud, really.

9:06 Licenser: what about getting a license to use 'God wrote in Lisp' as clojurs theme song?

9:06 chouser: Clojure's not that kind of Lisp

9:07 Licenser: that does not matter, the song is cool

9:07 rhickey: the hardware's not written in or for Lisp, and we have to deal with that

9:08 cemerick: If I see one more "but it's not Genera"....

9:09 wlangstroth: cemerick: don't even

9:09 Licenser: what does Genera mean?

9:09 wlangstroth: a guy I used to work with would go off on that any chance he got

9:10 chouser: Licenser: http://en.wikipedia.org/wiki/Genera_%28operating_system%29

9:10 cemerick: wlangstroth: Oh, I won't! :-)

9:10 Licenser: way thank you chouser *reads*

9:10 cemerick: Licenser is going to be crawling ebay for a vintage model before COB.

9:10 ;-)

9:11 Licenser: cemerick: I have some cool old stuff already :P

9:13 wlangstroth: wait, Java's primitives aren't JVM bytecode primitives? I obviously have some reading to do.

9:13 dnolen: rhickey: so does this mean primitive support is on the table for 1.2 ?

9:14 cemerick: wlangstroth: I understood those things for about 3 weeks when I had to learn the details for some JNI work. Now it's all a muddle.

9:15 rhickey: dnolen: it's on the table with its guts hanging out :)

9:15 dnolen: haha

9:16 rhickey: this :static thing is bigger tha nprimitives

9:16 than

9:16 * rhickey had the majority of core switched over to :static last night

9:17 dnolen: rhickey: yeah, I wasn't totally understanding the repercussions of :static ...

9:17 chouser: statics are still vars at compile time, right? their varness goes away at call sites?

9:18 rhickey: chouser: there will be vars, and they have IFns in them. But calls made by name through the var get inlined into static method calls

9:18 name of the var

9:19 IFn methods just call the static ones, so no bloat

9:19 chouser: ah, interesting. hense the non-closure restriction

9:19 wlangstroth: cemerick: ditto, except my exposure was in school

9:20 rhickey: chouser: right. I'm trying to make the one of the few. Today I'm adding support for variadics and recursive calls

9:20 keyword callsites currently require 'this' as well, need to change that

9:21 chouser: keyword callsites as in (:foo bar) ...but surely bar needs to be an instance, thus 'this'?

9:22 rhickey: chouser: the callsite is in the caller of (:foo bar)

9:22 chouser: ah!

9:22 rhickey: so right now statics can't call (:foo bar)

9:22 chouser: got it

9:23 rhickey: surprisingly. not an issue for most of core. But variadics and recursion were

9:23 unacceptable limits

9:38 AWizzArd: I spread lots of functions and records over several namespaces. Now I would like to offer my users one single namespace which they can require and in which they find all the functions they need.

9:39 What is a good way to export my functions from the namespaces X, Y and Z into my public NS?

9:41 MrHus: AWizzArd why not use the ns macro and use :only

9:42 AWizzArd: Maybe I was not expressing clearly enough what I would like to do: I want that you can say: (require 'awizzards.ns :as wiz) and then you can call wiz/foo, wiz/bar and wiz/baz

9:42 But the function foo actually sits in the namespace awizzards.ns.X while bar sits in a.ns.Y and baz in a.ns.Z

9:43 cemerick: AWizzArd: there's immigrate

9:43 AWizzArd: I want to export a public user interface of all Records, constants and fns into one namespace, so as if I would have put all my code into that ns

9:43 ,(doc immigrate)

9:43 clojurebot: "clojure.contrib.ns-utils/immigrate;[[& ns-names]]; Create a public var in this namespace for each public var in the namespaces named by ns-names. The created vars have the same name, root binding, and metadata as the original except that their :ns metadata value is this namespace."

9:44 MrHus: (doc refer)

9:44 clojurebot: "([ns-sym & filters]); refers to all public vars of ns, subject to filters. filters can include at most one each of: :exclude list-of-symbols :only list-of-symbols :rename map-of-fromsymbol-tosymbol For each public interned var in the namespace named by the symbol, adds a mapping from the name of the var to the var to the current namespace. Throws an exception if name is already mapped to something else in the current name

9:44 cemerick: MrHus: refers are not visible to those that require the namespace that uses refer

9:45 djpowell: on other platforms what will 'long' be expected to map to? reminds me a bit of C99's http://en.wikipedia.org/wiki/Stdint.h

9:45 MrHus: cemerick Ok good to know

9:46 djpowell: ah, reading up, they'd be (at least?) 64-bit

9:46 AWizzArd: I could of course implement all public fns in my NS again and just call the real thing under the hood, but that would be an unnecessary indirection and would cost some performance too.

9:46 It seems that immigrate is doing exactly this.

9:47 djpowell: C99 has int_fast64_t - which is basically at least a 64-bit int

9:48 AWizzArd: It would just be userfriendly if the users of my system could require this one public interface NS and find there everything they want, instead of having to require 8 NSs and have all the goodies spread over those.

9:51 MrHus: AWizzArd maybe its the users job to select the functions they need out of your library :P

9:51 chouser: AWizzArd: I've heard vague warnings from people who've used immigrate

9:52 AWizzArd: you're sure it makes sense to define a logically-single public api in a bunch of different namespaces?

9:52 AWizzArd: MrHus: technically that's right, it just is more comfortable to hide 95% of my internal fns and just offer the users a friendly public interface.

9:53 MrHus: AWizzArd how about defn-

9:53 AWizzArd: chouser: I can maybe just remove the different NS names from the files. My main idea was to spread logical function units into different files.

9:53 MrHus: my code is full of those

9:54 I don't know how strongly Clojures namespaces are bound to Java packages, but a system that would allow me to publish a public api would be nice.

9:54 chouser: I've generally experienced more pain from splitting functionality into too many files/namespaces than from combining too much into one.

9:56 AWizzArd: Yes, in principle I would just need one .clj file, though this could also work out as not too easy to manage, as well as having 250 small .clj files. A good mix may be the right thing.

9:56 MrHus: I think its a habit, you just get so used to one class per file. And you feel like cheating when you put many functions in one namespace / file.

9:57 chouser: until your file passes core.clj in size, you shouldn't worry.

9:57 rhickey: chouser: not the same for files vs namespaces, though, right?

9:58 chouser: Well, I guess I hardly ever use multiple files per ns, but right that's another option clearly demonstrated by core

9:58 AWizzArd: This is something that I could do.

9:59 chouser: core.clj is 5664 lines. All the core .clj files together: 7154

10:00 rhickey: the bootstrapping nature is somewhat unusual. You should be able to break most namespaces into multiple files easily

10:01 nature of core

10:02 AWizzArd: Although core.clj then again is kind of a special case, as it wants to export everything, and most stuff in there is unrelated, whereas I have a good bit of code that I would like to hide per default from the user.

10:03 But yeah, splitting one NS into multiple files and heavily working with {:private true} could be one solution.

10:03 rhickey: with :static, making a ns that exposes an enumerated subset of stuff from several other namespaces is a macro away, and no overhead

10:03 chouser: core has several private things, but I understand the ratio may be very different from your ns

10:04 AWizzArd: rhickey: that sounds interesting

10:04 rhickey: AWizzArd: but tedious, and still probably wrong

10:04 arohner: I find myself not splitting nses into multiple files because I find the (in-ns 'foo) at the top of the file much less readable than the (ns foo)

10:05 in the (in-ns 'foo) file, I don't have the list of what's been required imported, etc

10:06 chouser: hm. you can require and import as needed in each file, though I wonder to what extent that defeats the tooling support that the ns macro is trying to provide

10:07 arohner: chouser: yeah, maybe that's a job for slime, to tell me whats in my ns

10:09 chouser: are there any editors that color locals differently from var names?

10:09 I asked around a bit yesterday about making that work in vim, and if it's possible at all it'll be rather tricky.

10:09 arohner: slime sometimes colors vars differently, but I haven't figured out the strategy yet

10:10 chouser: I'm thinking specifically of (map ...) vs (let [map x] (if map ...))

10:11 arohner: chouser: no, slime doesn't do that

10:11 it appears it colors vars and macros from clojure.core differently from everything else

10:11 felideon: hello. quick question, since my Googling is failing me. could a Clojure app run on Jave ME / CLDC?

10:14 chouser: I don't think I've heard of anyone actually attempting that.

10:18 AWizzArd: Currently I would think that when I want to split one NS across several files that I will have to (load them) in my original one, where the ns declaration sits. Is that right?

10:19 oh okay, core.clj is doing this too

10:25 felideon: chouser: thanks

10:31 AWizzArd: Is there a safe way to read the signature of a fn at runtime? I am not thinking about the :arglists meta data, as this can be changed.

10:31 I am thinking more about something like introspection.

10:32 chouser: AWizzArd: Java reflection on the class, but of course that's an implementation detail that rhickey is busily changing at this very moment. :-)

10:32 AWizzArd: great

10:36 chouser: is there any way to insert line numbers into code generated by eval?

10:37 bleh, what a vaguely-worded question.

10:41 arohner: chouser: I think you'll get line numbers as long as the code was read with a line numbering reader

10:44 or you can assoc the line numbers on to the forms

10:47 AWizzArd: (defn foo [a #^Integer b] (+ a b)) and then (vec (.getParameterTypes (first (.getDeclaredMethods (.getClass foo)))))

10:47 ==> [java.lang.Object java.lang.Object]

10:47 Any idea why the Integer did not end up in the result?

10:49 chouser: arohner: I do get line numbers, but stack traces point to the line where the eval was called, not to the line where the code that got sent to eval was built

10:50 AWizzArd: IFn instances only take Object args and always return Object

10:51 arohner: chouser: there's a small chance that might be caused by this bug: http://groups.google.com/group/clojure-dev/browse_thread/thread/1c2687d40f9b1a6f/0abf8719450457cd?show_docid=0abf8719450457cd

10:51 chouser: rhickey: you're not saying Clojure will never support primitive fn args on closures, are you? Just not yet?

10:52 arohner: hm, good point. though this is a runtime error, so I'm not sure.

11:05 noidi: how can I check if an object is a (byte) array?

11:05 arohner: noidi: (class object)

11:05 noidi: [B

11:06 how can I pass that to instance? ?

11:06 ,[B

11:06 clojurebot: EOF while reading

11:07 AWizzArd: ,(instance (class (byte-array 0)) (byte-array 100))

11:07 clojurebot: java.lang.Exception: Unable to resolve symbol: instance in this context

11:08 AWizzArd: ,(instance? (class (byte-array 0)) (byte-array 100))

11:08 clojurebot: true

11:09 noidi: isn't there a better way to get a hold of the array class?

11:10 chouser: ,(Class/forName "[B")

11:10 clojurebot: [B

11:10 chouser: noidi: not really

11:10 that is, not that I know of.

11:10 AWizzArd: (def +byte-array-class+ (Class/forName "[B"))

11:10 yacin: i'm trying to profile some code. when i call the -main function, it profiles correctly

11:11 AWizzArd: And then you can refer to that constant.

11:11 yacin: but when i make an uberjar and run it, it doesn't work

11:11 any idea why?

11:11 chouser: I guess Java has special syntax for array type names

11:11 yacin: (call the -main function in the slime repl)

11:11 AWizzArd: yacin: you say it does not work. What happens when you try it?

11:12 yacin: (profile ...) doesn't output anything

11:12 my main looks like

11:12 (defn -main [& args]

11:12 (profile (doseq [pcap-path args] (run pcap-path))))

11:12 run has:

11:12 (prof :feature-vector (get-feature-vector pcap-path))

11:13 AWizzArd: Does the profiler need to be turned on during compilation? I don't remember if it is a macro which can be compiled away, depending on some flags.

11:13 yacin: in the function get-feature-vector, i have (binding [*enable-profiling* true] ... )

11:13 around the function body

11:13 but i figured it was something like that

11:14 so i thought i'd ask here

11:15 AWizzArd: I did not use that profiler for quite a long time, but instead typed "jvisualvm" in the shell and used what popped up.

11:17 yacin: i like having the profile code built in

11:17 hmm

11:18 noidi: thanks arohner, AWizzArd, chouser

11:18 I'll go with Class/forName

11:18 AWizzArd: But maybe it is no longer built in. Perhaps when you created the Überjar the profiler code was not included.

11:22 HerrBlume: Hello, I want to format a subnet mask, I have a list of the form ("255" "255" "255" "128")

11:22 now i want dots betwen these values

11:23 AWizzArd: HerrBlume: better would be to have a look at http://java.sun.com/javase/6/docs/api/java/net/InetAddress.html

11:23 chouser: ,(apply str (interpose \. [255 255 255 128]))

11:23 clojurebot: "255.255.255.128"

11:23 HerrBlume: ahh, thank you very much!

11:24 AWizzArd: Or: (require '[clojure.contrib.string :as str]) ... (str/join "." ["255" "255" "255" "128"])

11:24 ,(doc join)

11:24 clojurebot: "clojure.contrib.str-utils2/join;[[separator coll]]; Returns a string of all elements in coll, separated by separator. Like Perl's join."

11:25 AWizzArd: ,(join "." ["255" "255" "255" "128"])

11:25 clojurebot: java.lang.Exception: Unable to resolve symbol: join in this context

11:25 AWizzArd: urgs, str-utils2 :-)

11:25 Btw, why was clojure.contrib.io renamed to clojure.java.io?

11:32 caljunior: I am having some troubled with circular references between namespaces.

11:33 is it legal to have two namespaces refer to each other with :use?

11:34 I have a gui namespace that initiates an event loop in a different namespace which in turn is firing table data updates to the gui tables.

11:36 Cannot get these namespaces to load in the repl as either the event loop initiator isn't loaded yet or the table model.

11:37 chouser: loading a namespace changes the state of the namespace world, so order matters.

11:37 is there a reason you can have it all in a single namespace?

11:37 can't

11:43 AWizzArd: Is there a get -like fn that throws an Exception if the specified key is not in the map?

11:46 hugod: zakwilson_: thanks - fixed. I've also include osx keychain integration (if your on a mac)

12:01 caljunior: chouser: sorry for the delay. I can put it all in one namespace. was hoping to keep to be able to seperate it for clarity.

12:02 chouser: you can use two files but still a single namespace.

12:04 caljunior: ok, thanks.

12:07 HerrBlume: hello, i want to create an uberjar using leiningen

12:07 if i start swank and load a namespace vie (require 'namespace.) it works fine

12:08 but 'lein uberjar' complains about the name space missing

12:09 LauJensen: HerrBlume: Have you declared your namespace in project.clj ?

12:10 HerrBlume: ah...

12:10 LauJensen: thank you

12:10 * HerrBlume added :main keyword to project.clj

12:12 caljunior: chouser: works perfectly. thanks again.

12:12 chouser: caljunior: np

12:13 LauJensen: HerrBlume: If you get stuck there's at least 1 or 2 blogposts on my site (bestinclass.dk) which shows how its done

12:22 HerrBlume: LauJensen: i will look at it...

12:26 rhickey: recursive statics are alive

12:27 cgrand: yeah!

12:28 rhickey: so (fib 38) now 425 ms

12:28 chouser: heh. nice.

12:29 rhickey: would like to get rid of the need for these (long 1) (long 2) bits

12:30 chouser: have you heard from any heavy Incanter users about your ideas for handling of numerics? Seems like they'd by the most likely source of push-back.

12:30 rhickey: chouser: why would they push back?

12:30 chouser: if they expect auto-promotion and that changes

12:30 rhickey: they use doubles for everything

12:31 chouser: oh, ok.

12:31 rhickey: Incanter is Colt, so no BigAnything

12:31 cgrand: rhickey: weren't you considering reader support for primitives earlier? or was the suffix thing only for mapd and mapl?

12:32 rhickey: cgrand: It ends up reader support doesn't help. The reader must read Objects in any case. But given a Long constant, the semantic difference prevents me from treating it like a long

12:33 powr-toc: damn it... I'm getting another Exception in thread "main" java.lang.NoSuchMethodError: clojure.lang.RestFn.<init>(I)V (cookie.clj:1) error

12:33 technomancy: clojurebot: restfn?

12:33 cgrand: yeah thought of the boxing right after hitting [enter]

12:33 rhickey: to fix, the semantics would have to be unified on throw-on-overflow

12:33 clojurebot: ant clean and rebuild contrib

12:33 technomancy: clojurebot: clojure.lang.RestFn.<init>(I)V

12:33 clojurebot: clojure is the best way to learn java

12:33 technomancy: ~botsmack!

12:33 clojurebot: Owww!

12:34 rhickey: ad you'd have to ask for 2big to get bigint semantics

12:34 technomancy: powr-toc: you've got .class files AOT'd with an older version of clj

12:34 powr-toc: technomancy: does ring AOT?

12:34 clojurebot: technomancy is to blame for all failures

12:35 powr-toc: ahh wait.. lets try a mvn clean first

12:36 phew... it's gone... technomancy thanks for the clue... now onto my next error :-)

12:37 I'd forgotten I had some AOT'd namespaces

12:38 cgrand: rhickey: and I guess that wrapping primitives in new Number classes has too many consequences, too much complexity

12:38 rhickey: cgrand: right

12:45 powr-toc: LauJensen / cgrand : out of interest is there a google group for moustache?

12:48 cgrand: powr-toc: good idea

12:48 powr-toc: cgrand: I take that as being "shortly" :-)

12:49 cgrand: Is there a function that'll wrap a standard java servlet into a ring handler? I know you can turn a handler into a servlet, but I need the reverse

12:54 cgrand: powr-toc: http://groups.google.com/group/moustache-club

12:54 powr-toc: cgrand: awesome name!

12:56 cgrand: powr-toc: none that I'm aware of but you are the second person I hear asking for such a facility

12:57 powr-toc: cgrand: it'd sure be handy

12:58 cgrand: yeah but it involves mocking servlet objects (request, response, context etc.)

12:58 powr-toc: as without it I have to maintain effectively two routes... one in moustache (or compojure) and the other as some hand rolled jetty wiring :-\

13:01 cgrand: ouch... might you be able to use clojure protocols to wrap those types into a clojure.lang.Associative ?

13:02 HerrBlume: my project name includes a '-', and lein gets confused. The compile task assumes prefix-suffix. The uberjar task assumes prefix_suffix.

13:03 powr-toc: or would it be going the other way...

13:03 HerrBlume: May the project name not include '-'?

13:03 clojurebot: project euler is http://ProjectEuler.net

13:07 cgrand: powr-toc: I think the simple path is to build upon something like http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/mock/web/package-summary.html

13:08 no wrapping: copy data to/from servelt objects from/to ring maps at the boundary

13:12 powr-toc: cgrand: yes... interesting idea... I wish I'd discovered that API a few years ago

13:20 patrkris: am I the only one who hopes Clojure doesn't gain too much in popularity? I like having a secret tool :)

13:21 HerrBlume: patrkris: no, look at common lisp

13:22 * HerrBlume uses no '-' in namespaces anymore, everything works fine now

13:24 _fogus_: dnolen: Thanks for the submission. :)

13:29 dnolen: _fogus_: no problem, nice post! Makes me want to write a Clojure.js ...

13:30 _fogus_: dnolen: Let me know and I'll submit it for you. ;-)

13:32 powr-toc: cgrand: btw... good call on allowing a single app call which works with middlewares!!! My big gripe with compojure was it's wrap call relied on mutation...

13:33 i.e. it would mutate the top level var... which seemed pretty nasty, and far less declarative

13:37 KirinDave: _fogus_: Charles Nutter must have shed a single tear when you talked about ruby.clj

13:37 "But what about jruby? :("

13:39 _fogus_: KirinDave: Oh man! I hate making him mad.

13:39 and sad

13:42 cgrand: powr-toc: it's all the def and redefing in Compojure that prompted me to write Moustache -- and the destructuring route syntax

13:43 powr-toc: cgrand: yeah... I gotta admit I found that part of it very frustating...

13:44 briancarper: power-toc: You don't have to use defroutes and wrap! in Compojure though, do you? Use (routes ...) and -> to do the wrapping and def the vars yourself.

13:44 powr-toc: cgrand: Though I quite like the sinatra style string syntax in clout... it feels very HTTP-like... more so than moustache... which feels less HTTPy and more Clojurey...

13:45 briancarper: s/power-toc/powr-toc, sorry

13:45 powr-toc: briancarper: thanks, I hadn't noticed that function

13:46 briancarper: defroutes is a very thin wrapper over routes. Though all the documentation uses defroutes and wrap!, so it's easy to miss.

13:48 cgrand: powr-toc: more "clojurey" is a design choice -- like I "clojurified" css selectors in enlive

13:48 powr-toc: briancarper: yeah... I found the whole 0.3.x -> 0.4 transition pretty confusing at first... and the fact the docs keep changing

13:49 dnolen: cgrand: are the routing vectors in moustache first-class like selectors are in Enlive now?

13:50 powr-toc: cgrand: absolutely... and it's obvious... so job well done! :-) It's just a comment, that superficially the clout syntax is more obviously routing HTTP than the moustache one... still I really like how flexible app is...

13:50 cgrand: dnolen: no, and they are binding forms so I won't be able to make them firstclass without changing the syntax or introducing an alternative syntax

13:51 dnolen: do you have a usecase?

13:51 dnolen: cgrand: 1) gotcha 2) no :)

13:51 cgrand: phew!

13:51 powr-toc: cgrand: though I do find the number of equivalent syntactic varients staggering and potentially confusing... i.e. knowing whether or not two forms are semantically equivalent or not

13:52 so some guidelines on what each variation is for... and perhaps the idioms to use might be useful

13:52 cgrand: powr-toc: I confess I may have crammed too many things in one poor macro

13:52 powr-toc: cgrand: still, must've been fun :-)

13:53 cgrand: it was liek designing a swiss-army knife :-)

13:53 like even

13:58 rhickey: variadics in statics now alive

13:59 scgilardi: let the retweets begin

14:00 rhickey: heh

14:01 powr-toc: rhickey: any idea on the time frame for 1.2.0 yet? (No rush - just curious)

14:02 dnolen: rhickey: so I'm taking it that statics will bring significant performance gains to the average Clojure program? (thus much bigger deal than primitive support :)

14:04 rhickey: dnolen: depends on what you are doing. potentially, yes. If you've ever (let [f f-in-a-var] ...) and it mattered, yes

14:52 cemerick: _fogus_: thankfully, your post's juice isn't killing my blog server today :-)

14:52 _fogus_: cemerick: Mine is just barely keeping up. I had to disable a bunch of plugins

14:53 cemerick: I got crushed yesterday, sadly. m1.small + cruddy old glassfish setup is not a good combo :-/

14:53 _fogus_: Your survey is going to inspire many a post. :-)

14:54 cemerick: Good. I did it (mostly) get people talking.

14:54 I wonder how many people within the community are really going through the results, taking the comments to heart.

14:54 _fogus_: Not sure, but I know I am

14:55 kotarak: cemerick: vim maybe ranks second, because it supports syntax highlighting, auto-indent, code eval, dynamic highlighting, omni completion and the like since Q3/2008. The "big three" (ccw, enclojure, la clojure) catch up only recently.

14:55 cemerick: But it think vimclojure's share will drop with wider adoption in the java world (which will boost the IDEs share, I would expect)

14:56 cemerick: kotarak: yeah, I'm sure it's a good env. I'm cursed with the prejudice that "vim isn't for lisps", etc. :-)

14:56 technomancy: kotarak: curious how you solve the "separate versions of clojure for vimclojure vs the projects running in it" problem.

14:57 or is that not an issue?

14:57 briancarper: _fogus_, cemerick: Should've written your sites in Clojure, mine survived reddit+YC yesterday. :)

14:57 cemerick: briancarper: I just use confluence, poorly set up in an old build of glassfish.

14:58 _fogus_: briancarper: I'm one step ahead of you, but sadly too late for today

14:58 kotarak: technomancy: the solution is "no clojure". The clojure used in vc is mostly version independent. The few things, that are are caught be conditional includes. The one part which would require gen-class (hence introduce harmfal AOT compilation) is written in Java. So I cheat a little bit.

14:58 technomancy: handy

15:06 lpetit: kotarak, technomancy: congratulations for your great scores in the survey !

15:07 kotarak: lpetit: you, too :D I think, you will catch in the near future. With Clojure becoming adopted in wider range, the share of the IDE will increase.

15:07 * technomancy is pretty sure he had little to do with it; people were using swank-clojure just as much before he took over maintenance. =)

15:08 * cemerick hopes lpetit or eric goes into the tools business full time :-)

15:10 lpetit: kotarak: there's also something I have in mind: I tend to think of emacs or vim users as "power user" individuals. Those individuals will certainly have catched the twitt or the email concerning the survey. I guess that maybe more classical "GIDE" users may not all be always reading the ml or following cemeric et a on twitter. So maybe there are even more users of graphical IDEs. Something...

15:10 ...like one person introduces clojure and one IDE in a company, surveys the language ml closely. And when he answers the survey, he is really answering for him and maybe 2-4 of his collegues as well :-p

15:11 cemerick: we'll wait for the end of your new survey :-)

15:12 cemerick: oh, damn. What if several people of the same company answer your survey ? Will you try to average the results given for a certain company (provided that it is possible at all to group the answers for a same company) ?

15:12 cemerick: FYI: we're now in production with DocuHarvest, a web application built using clojure, compojure, clutch, pallet, etc. http://bit.ly/9AvbUR

15:12 lpetit: or maybe create a Clojure Foundation :-)

15:12 chouser: lpetit: When answering the original survey, I passed it around at my company so others using Clojure could answer for themselves.

15:12 lpetit: cemerick: congratulations !

15:12 chouser: don't break my dreams :)

15:13 cemerick: lpetit: thanks :-) Just getting started.

15:14 lpetit: cemerick: working full time on ccw for one year would be for sure a fun experience !

15:15 chouser: cemerick: docuharvest looks really interesting!

15:15 cemerick: thanks :-)

15:16 lots of stuff in the pipeline

15:16 bobo_: ive read clojure in action / the joy of clojure, any point in reading programming clojure? want something on paper

15:17 briancarper: cemerick: Awesome idea. I wish I'd had that kind of service 2 years ago.

15:17 cemerick: briancarper: well, now you'll have it next time :-D

15:25 LauJensen: bobo_: Maybe, but I think the next logical step is http://conj-labs.eu :)

15:31 cemerick: ILC 2010 is in Reno? :-o

15:32 oh, colocated with splash *shrug*

15:33 chouser: cemerick: was fun last time. Won't be going this time. :-/

15:33 bobo_: LauJensen: i agree! so come to stockholm! :-)

15:33 cemerick: Nor will I. Reno? :-|

15:34 LauJensen: bobo_: You dont have that nice hotels in Stockholm :)

15:34 bobo_: sure we do! i guess, never been in one

16:14 silveen: hello, could anyone help me with a problem I'm been having? I've got a set of entities, and a painting thread trying to paint these entities, but the painter thread never seems to see them, if I copy and pase the exact same code to repl however they do show up. I'm using a ref for the set, what am I missing?

16:15 chouser: any agents involved?

16:16 silveen: yeah, an agent is running the rendering loop

16:16 aka the painter thread

16:16 rhickey: cemerick: congrats on docuharvest!

16:16 chouser: you're sure that loop is actually looping, and not stuck?

16:18 silveen: yes, I've got a little (println "I'm painting") just before the (for ..., if I put the same println expression inside the for, it doesn't spam

16:20 chouser: silveen: I can't think of any other common errors. Can you post the code somewhere so we can reproduce the problem?

16:20 preferrably as simple a version as possible

16:21 cemerick: rhickey: thanks :-) It actually made its debut at ClojureNYC, though it was in rough shape then :-)

16:22 rhickey: cemerick: I remember that, nice to see it go public

16:24 silveen: chouser: I'm not quite sure I got the meaning of reproduce there, but I've posted the interesting code here http://pastebin.com/SDYykHp4

16:25 * chouser looks up the docs for defstruct

16:26 chouser: silveen: I don't think #

16:26 silveen: Maybe I've misunderstood the entire thing (I'm new to this) with refs and agents, but isn't that supposed to set up a "shared state" between all threads?

16:26 chouser: (defstruct enemy (ref :health) :position :level :dir) does what you want

16:27 silveen: yes, values committed to a ref should be visible in all threads.

16:27 silveen: what you're trying to do sounds right, so it's just a matter of figuring out why that's not what's actually happening

16:28 silveen: yeah I've been trouble shooting this for a good hour now (learning syntax as I go)

16:29 chouser: ,(let [enemy (create-struct (ref :health) :position :level :dir), e (struct enemy 1 2 3 4)] e)

16:29 clojurebot: {#<Ref@1fed553: :health> 1, :position 2, :level 3, :dir 4}

16:29 chouser: ,(let [enemy (create-struct (ref :health) :position :level :dir), e (struct enemy 1 2 3 4)] (:health e))

16:29 clojurebot: nil

16:30 chouser: but I think the problem you're actually seeing is because 'for' is not an imperative loop

16:30 silveen: try replacing (for [enemy @horde] (do ...)) with just (doseq [enemy @horde] ...)

16:30 silveen: okey chouser, will try that :)

16:31 chouser: the reason it works at the REPL is because the lazy-seq returned by 'for' is forced in order to print it.

16:32 but in 'do-render' that lazy-seq is just thrown away, so it never does the work you want.

16:32 silveen: okey now I understand

16:32 it worked by the way, thanks alot chouser :)

16:32 chouser: you're welcome.

16:32 do see what I said about :health above. That defstruct isn't what you want.

16:33 And I'd recommend using a different name for the defstruct than for your locals. Using 'enemy' for both will hurt you later. You might use 'Enemy' or something for the defstructu

16:33 silveen: good point

16:35 chouser: Is this your first Clojure program?

16:36 silveen: yes actually it is, I've been fiddling a little in Java for a few years and heard about clojure about a week back, so this is all very new to me

16:36 chouser: silveen: well, it looks great so far. Welcome. :-)

16:37 silveen: thank you :)

16:37 chouser: silveen: thanks for using clojure-style indenting and formatting. much easier to help than if you didn't.

16:38 silveen: generally or in the pastebin? (I couldn't find clojure in their list of languages so I chose lisp)

16:39 chouser: in the pastebin. I see a lot of closing-parens-on-their-own-lines and such

16:40 so it's nice to debug perfectly-formatted code like this.

16:40 silveen: oh you mean you don't like seeing ))\newline)? yeah well it's difficult having matched curly bracers for so long, but I do try

16:49 chouser: about the :health issue, I don't fully understand it but I do see the problem, how should I go about creating a struct with a "thread safe" health value?

16:50 chouser: silveen: first of all, you probably shouldn't have a mutable value in there at all

16:50 will the enemy's position change?

16:51 it's direction? why treat health differently from those?

16:51 silveen: because towers will damage the monsters, while only the monster will change it's own position and direction

16:53 chouser: try to think about values separately from identities. An 'enemy' struct is a value, just like any of clojure's collection types -- you can compute a new value with various functions such as update-direction or accrue-damage

16:53 silveen: that way I was thinking I could do a (not sure about the exact syntax here) dosync commutative dec @health if (neg? @healt remove monster

16:54 chouser: you should do that, but you should do it for the whole enemy, not the health individually.

16:55 that is, the enemy should be stored in a reference object (ref, agent, whatever), and that's the mechanism through which all its value can be updated

16:55 silveen: ah okey, yeah that makes sense. I was thinking I could use smaller locks and avoid locking the entire enemy while he might want to move

16:56 because if I lock him like that, he basically stops moving whenever he gets damaged?

16:57 chouser: presumably there will be some kind of delay between updates in his position?

16:57 silveen: I wanted to avoid alot of failing transactions, "I can't move because I was damaged", but now that I think about it, that's not necessarily true

16:57 Chousuke: damage changes could be commutative.

16:57 chouser: but yes, if two threads try to change his state at the very same time, one of them will have to retry

16:58 silveen: yeah ofc there will be a sleep somewhere, you're right

16:58 yes Chousuke they will

16:58 chouser: silveen: you're right to be thinking about these things, but I'd recommend going for fewer refs and avoiding nested ones unless you actually see that it's a problem.

17:01 silveen: chouser: okey

17:01 thanks for all the tips and help by the way, I really appriciate it (it ain't being easy being new to things)

17:02 bmason: what's this mean? error in process filter, Wrong number of arguments: 0, nil

17:02 silveen: now that the painter seems to work fine, off to implementing the a* algorithm :)

17:02 bmason: that was in my slime status bar

17:03 chouser: silveen: We have a tidy little A* implementation in our book, though I'm not sure that chapter is public yet.

17:03 silveen: chouser: I found a pretty neat guide on the net already actually http://nakkaya.com/2010/06/01/path-finding-using-astar-in-clojure/

17:04 chouser: oh, actually it is -- chapter 6

17:06 silveen: chouser: what book? Might be good putting a bookmark before I forget

17:06 chouser: silveen: yeah, I saw that on etoo

17:06 silveen: http://joyofclojure.com/

17:07 it's not clear to me where the nakkaya.com one is examining paths in order of estimated total cost

17:07 but maybe I've just not read it carefully enough yet.

17:12 mmarczyk: chouser: he replaces old paths to any given square with new paths if their cheaper

17:12 they're

17:13 chouser: ah, I see, he re-sorts the seq for each 'add-nodes'

17:15 mmarczyk: I wonder how this compares to a priority queue on larger maps

17:16 I'm used to thinking of A* as essentially based on a PQ

17:32 chouser: mmarczyk: we used a sorted-set

17:33 O(log n) for inserts and removals.

17:33 a finger tree might be even better -- O(log n) insert, O(1) removal from front

17:33 mmarczyk: an "simple" sorted-set or a sorted-set-by ?

17:34 chouser: just sorted-set. Turns out sorted-set-by is often trickier to use.

17:35 mmarczyk: didn't mean that as a suggestion, I've yet to use sorted-set/map-by :-)

17:35 chouser: no, I mean I tried it but it turned out not to be useful in this case

17:35 mmarczyk: interesting

17:35 so, do you maintain a "closed set" and an "open set", like nakkaya does with lists?

17:36 cemerick: I often wish sorted-set-by would continue to use equality to determine duplicates vs. the result of the provided comparator.

17:36 mmarczyk: if you're willing to disclose that -- otherwise I can wait for MEAP to catch up with you guys :-)

17:37 cemerick: that seems to be brought up pretty often and is totally contrary to my intuitions

17:38 chouser: no, we don't have two lists. hm... what did we do...

17:38 mmarczyk: admittedly, these were formed in studying pure logic rather than data structure representations of sets.

17:39 cschreiner: what is a process-fitler in slime?

17:39 cemerick: mmarczyk: it makes total sense to me. Maybe that variant should be called a multiset?

17:39 * riddochc found The Art of Computer Programming, vol. 4, fascicles 1-4 at the public library!

17:39 mmarczyk: cemerick: I'm not sure which variant you're referring to :-)

17:39 cschreiner: it says: error in process filter: Args out of range: "(0) passed to: PersistentVector (slot.clj:0)", 14, 2

17:39 mmarczyk: riddochc: oh, cool

17:40 cschreiner: does anything actually break for you?

17:40 cemerick: mmarczyk: where equality is relevant for duplicates, comparator used only for ordering

17:40 cschreiner: mmarczyk: it does not compile

17:40 mmarczyk: cschreiner: I get "process filter" msgs from time to time and just ignore them with no further trouble

17:40 * cemerick wonders if a patch to offer an option along those lines would get past rhickey

17:40 mmarczyk: cschreiner: would you be using a particularly old or new version of swank-clojure?

17:40 cschreiner: totally fresh

17:41 mmarczyk: cemerick: ah, makes sense

17:41 cemerick: mmarczyk: the 'multiset' term, you mean?

17:41 mmarczyk: yup

17:42 cemerick: hrm, maybe I'll suggest it seriously then

17:42 mmarczyk: I distinctly remember this being brought up several times

17:42 as a problem people were having with sorted-set

17:43 cemerick: eh, the formal definition of multiset doesn't jibe with what I'd like

17:43 mmarczyk: so you'd probably have some supporters :-)

17:43 cemerick: at least according to http://en.wikipedia.org/wiki/Multiset

17:43 mmarczyk: as a function X -> Naturals or something?

17:44 cemerick: yeah, multiplicity, etc.

17:45 the point is not to count repeated values, but to ensure that members with the same sort order aren't treated as dupes

17:45 consider indexing points along a single axis, etc.

17:45 mmarczyk: but

17:46 what do you propose to do with things which compare as 0

17:46 I can't say I've thought about this much, but at first glance I'm worried about e.g. bogus rebalancing

17:46 cemerick: if they're not =, retain them in order relative to the other members that are -1 or 1 of them.

17:47 The order of members that compare as 0 would be undefined.

17:47 I can't remember how I worked around this when I last needed it.

17:48 mmarczyk: then we could use sorted-set-by as a practical device to form total completions of any partial ordering :-)

17:48 hm, then again not quite

17:48 actually

17:49 what's a zero supposed to mean

17:49 coming out of (compare x y)

17:49 cemerick: mmarczyk: watch out, I don't know jack about math :-)

17:49 mmarczyk: docs say "x is equal to y"

17:49 :-)

17:49 cemerick: shite :-)

17:50 mmarczyk: where does it say that?

17:50 ,(doc compare)

17:50 clojurebot: "([x y]); Comparator. Returns a negative number, zero, or a positive number when x is logically 'less than', 'equal to', or 'greater than' y. Same as Java x.compareTo(y) except it also works for nil, and compares numbers and collections in a type-independent manner. x must implement Comparable"

17:50 mmarczyk: yeah, right here

17:50 "logically" equal to

17:50 whatever that means

17:51 cemerick: The docs for java.util.Comparator are interesting.

17:51 mmarczyk: so according to what you're saying, it would be convenient for comparators to implement total orderings on partitions of their domains

17:52 then (compare x y) just means x and y both reside in the same block of the given partition

17:52 cemerick: (zero? (compare x y)), yes

17:53 mmarczyk: it can't possibly be a totally arbitrary partial ordering, e.g. with two two-element chain elements (members of either incomparable with members of the other one) + bottom + top it would break

17:53 rhickey: whew, adding :static to everything in core is a lot more work than the magic direct binding of clojure.*

17:53 mmarczyk: I mean break an attempt to construct a sorted-set-by with it

17:53 rhickey: does this entail no (binding ...) for core Vars with no earmuffs?

17:54 rhickey: mmarczyk: that's already been the case for a while with direct binding

17:54 * mmarczyk slaps his forehead

17:54 mmarczyk: right.

17:59 technomancy: rhickey: thanks for making the effort!

17:59 rhickey: technomancy: you're welcome, :static is coming soon...

17:59 technomancy: next time you could probably outsource the grunt work to the channel. =)

18:00 mmarczyk: I thought I had a rough idea of all the reasons why 1.2 is going to be awesome

18:00 rhickey: technomancy: I'm doing this myself in order to shake out any issues. If someone else did it they'd just be scratching their head when it didn't work :)

18:00 mmarczyk: guess I was to quick to jump to that :-)

18:00 technomancy: hah; right.

18:00 chouser: though we had a work-around by adjusting the metadata of the core var before compiling code that used it. Is that still the case?

18:01 technomancy: I think now it's opt-in instead of opt-out for clojure* only?

18:01 (FSVO "now" which may actually be in the future)

18:02 cemerick: mmarczyk: turns out I did something along these lines: https://gist.github.com/2f6cb5c287bd15d3bd79

18:02 rhickey: chouser: I don't understand that

18:03 chouser: I blogged it! :-)

18:04 rhickey: http://blog.n01se.net/?p=134

18:04 mmarczyk: cemerick: but that means that if (zero? (compare x y)), (not= x y), you have both x < y and x > y according to your comparator

18:05 cemerick: not sure if that is a cause for concern, maybe it's just me feeling uneasy...

18:06 rhickey: chouser: oh that. I can't promise any such hacking based on implementation details is going to work

18:06 cemerick: mmarczyk: in this case, yeah. I think I might have used a another comparison to establish a secondary sort order. As is, that should just make for undefined ordering of that partition though.

18:06 mmarczyk: would you be worried about poor amortized perf?

18:06 chouser: rhickey: right, I'm just wondering if there is some other work-around available for :static

18:07 Raynes: Wasn't a function to get all permutations of a sequence moved to core not too long ago?

18:07 rhickey: chouser: call with #^

18:07 chouser: ok

18:07 rhickey: sorry , #'

18:08 mmarczyk: cemerick: exactly, but that's not to say I know or even necessarily expect that problems would arise... I'd like to check, though

18:09 cemerick: also: ((conj (sorted-set-by funky-comparator [1 2 3] [4 5 6] [7 8 9]) [10 11 12] [13 14 15]) [7 8 9])

18:09 funky-comparator comes from the third revision of your gist

18:09 this evaluates to nil for me

18:10 yeah, that's why I feel uneasy

18:10 this breaks order-based lookup in the tree

18:11 cemerick: mmarczyk: interesting -- I was only ever using it to do traversals via subseq and rsubseq

18:11 mmarczyk: I could always use (compare (hash x) (hash y)) as a secondary source of ordering ;-)

18:12 mmarczyk: yeah, but than you don't need a special kind of sorted-set-by

18:12 since you're likely to have a total ordering anyway

18:13 cemerick: heh, no -- though this is a helluva wart in any codebase

18:13 mmarczyk: and if you might have hash clashes, then lookup will break in some other way

18:13 cemerick: that's what the ;-) was for

18:13 mmarczyk: :-)

18:14 I wonder if a reasonable conclusion might be that we really could use finger trees :-)

18:15 cemerick: In practical terms, I always have other stable sortable attributes, so the seconary/tertiary comparisons don't impact any lookups (were I to do them)

18:15 I can imagine that not being the case though.

18:17 mmarczyk: right

18:17 at any rate, the comparator needs to be useful for deciding which branch to take when going down the tree

18:17 a 0 would mean "umm, let's try both"

18:18 so perhaps there's no escaping custom solutions for 0 not meaning "dupe"

18:18 cemerick: bleh

18:20 mmarczyk: a fn similar to core/comparator that composed some number of fns in order to yield a final verdict on ordering would simplify things quite a bit

18:23 mmarczyk: like so? http://gist.github.com/432276

18:25 argh, still doesn't work.

18:26 (silly mistake, will fix)

18:27 (updated now)

18:27 cemerick: yeah, like that, though if I were the only one using it, I'd reify an actual Comparator.

18:28 mmarczyk: very nice :-)

18:28 mmarczyk: right

18:28 thanks :-)

18:28 oh, actually the first version was probably ok too -- I misapplied it later :-P

18:29 cemerick: I understand the convenience of having comparator take predicates, but the efficiency issues can be serious.

18:30 neotyk: where I can read more about :static?

18:30 mmarczyk: there are two version in the Gist now, one composing comparators, one composing predicates

18:31 you could rewrite the first one to reify an actual Comparator of course

18:31 neotyk: http://clojure-log.n01se.net/

18:33 neotyk: I found few messages today, but doesn't really explain what is it

18:34 ok, see a bit more yesterday

18:35 mmarczyk: cemerick: a reify-based version up now

18:35 neotyk: you know, it's not yet available on GitHub

18:35 not quite the stage where extensive documention is to be expected ;-))

18:35 neotyk: mmarczyk: but attracts interest already

18:36 mmarczyk: (multi-comparator: seems to work)

18:37 cemerick: mmarczyk: nice -- why not keep the reduce?

18:37 mmarczyk: neotyk: as well it should :-)

18:37 cemerick: hm, not sure actually

18:37 cemerick: might as well, now that you mention it :-)

18:38 cemerick: it's certainly prettier :-)

18:40 mmarczyk: yup, added a reduce-based version now :-)

18:41 the reduction function could have a ^Comparator type hint on c and use .compare

18:41 not sure there's much to be gained in that though...?

18:42 cemerick: mmarczyk: I'd add it so it doesn't matter whether you're using preds or java/reified comparators

18:42 mmarczyk: ah, good point

18:43 updated

18:54 darn, my Ubuntu box just crashed (!) :-(((

19:07 fanatico: Is case unable to dispatch off types/classes?

19:07 mmarczyk: $(case (class :foo) clojure.lang.Symbol :sym clojure.lang.Keyword :key)

19:07 sexpbot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.MapEntry

19:08 mmarczyk: hm.

19:09 ah, of course

19:10 Lajla: mmarczyk, what had you written first in C, a hellow world program, or understood the semantics of the string literal in source "Hello, World!"

19:10 mmarczyk: (eval `(case (type :foo) ~clojure.lang.Keyword :key :unknown))

19:10 case has implicit quoting

19:11 so the clojure.lang.Keyword in the version which doesn't work is treated as a symbol

19:13 if you really wanted case-like dispatch for classes, you could write a macro to attempt to resolve symbols and if they happen to resolve to classes, replace them by those classes...

19:14 fanatico: mmarczyk: of course, thanks.

19:14 mmarczyk: np

19:14 Lajla: well, let's see; I *have* written a hello world programme in C, but I'm not entirely sure that I understand the semantics of the string literal -- never spent enough time with C to think about it

19:15 if forced to guess, I'd say sth like you did yesterday, I think... too late to be sure now that I've read it, though :-P

19:16 Lajla: mmarczyk, noooooo

19:16 lancepantz: does slime-auto-connect work with swank?

19:16 Lajla: mmarczyk, also, programme is a faux-french, a folk etymology if one likes.

19:16 program comes from greek, not French.

19:16 cemerick: mmarczyk: that last version should go into contrib :-)

19:17 Lajla: It is a verbal noun of prographein, literally meaning 'to forewrite'

19:17 lancepantz: like if i ^d my lein swank process, and restart it, can slime reconnect automatically?

19:17 mmarczyk: cemerick: you think so? thanks :-)

19:18 cemerick: mmarczyk: have you filed a CA?

19:18 mmarczyk: cemerick: not yet, but I'd love to do that

19:18 cemerick: if not, do so, and yes, into contrib that should go

19:19 scottj: lancepantz: I run lein swank from a script that also tells emacs to reconnect slime

19:19 mmarczyk: cemerick: thanks for the encouragement :-)

19:19 I think I'll do that

19:19 lancepantz: scottj: how does that work? a shell script?

19:21 alvatar: ohmygod!

19:22 clojure has way more people than lisp and scheme!

19:22 scottj: lancepantz: http://paste.lisp.org/display/111307

19:22 Lajla: mmarczyk, you'ren't going to defend your abuse of etymology?

19:24 scottj: lancepantz: I just updated it with sl5 from .emacs

19:26 lancepantz: thanks scottj

19:27 jartur: Lajla: Maybe he was using the french word?

19:28 mmarczyk: Lajla: programme is the British spelling

19:28 Lajla: I can spell either way with my preferred way being consistent ;-)

19:29 Lajla: mmarczyk, well, not for the noun.

19:29 Only for the verb.

19:29 At least, not for a computer program.

19:29 mmarczyk: http://dictionary.reference.com/browse/programme

19:29 jartur: Lajla: J'ai ecrit un 'Hello world' programme.

19:29 mmarczyk: n. & v. Chiefly British

19:30 Lajla: I'd rather not abide to the idosyncracies of any groupa nd rather spell sensibly.

19:30 mmarczyk: not a Brit I take it?

19:31 Lajla: mmarczyk, most Brits spell computer programs as this though.

19:31 jartur: Lajla: Sensible English spelling... It's like an oxymoron or something.

19:31 Lajla: A programme is a programme of a festifal or whatever.

19:31 jartur, I begt to differ.

19:31 Spelling needn't per se be systematic with respect to sound.

19:31 Can also be with respect to etymology.

19:31 mmarczyk: well, at any rate, you're free to follow your own aesthetic sense

19:31 Lajla: mmarczyk, but the point is that you're too.

19:32 Instead of being forced to do as I tell you, who created this awful place? What have I ever done to you, God!

19:32 mmarczyk: I'm inclined to agree, in fact that seems to be what I'm doing :-)

19:32 Lajla: mmarczyk, wouldn't you rather serve me? Like Clojurebot?

19:32 ,'serve-Lajla

19:32 clojurebot: serve-Lajla

19:33 Lajla: ,'I-worship-his-shadow

19:33 clojurebot: I-worship-his-shadow

19:33 jartur: Lajla: Lexx?

19:34 Lajla: jartur, on to me, aren't you.

19:34 Worship me, my divine shadow, that is.

19:34 jartur: I stopped writing "Hello, World" programs some time ago. I always check with "Why, Hello!" now.

19:35 Lajla: I do 'Hello, Nurse!"

19:36 jartur, this one is the coolest: (extend standard-import-port/line "Hello, World!"), not only because it's 8 times harder to understand than that C variant.

19:36 technomancy: "Hello, sailor."

19:37 Lajla: 'h ': "ello, World!"

20:16 _rata_: hi

20:17 jartur: _rata_: Hello

20:21 rava: greetings

20:21 (defonce server (run-jetty #'chdweb {:port 8080 :join? false}))

20:22 could anyone tell me why that binding comes unbound after compiling and running in swank?

20:22 i did it this way so i could (.start/stop ) the jetty instance, but i get a "symbol unbound" error

20:22 tomoj: are you in the right namespace?

20:23 rava: yes

20:24 i'd C-c k the file, then in the slime repl i load up with swank-clojure-project /path/to/prj , i'd go into the namespace and try to do the start/stop in the repl

20:24 tcrayford: you tried using (var chdweb) instead of the reader macro?

20:25 (don't think that'll make a difference tho)

20:25 rava: nope

20:25 the odd thing is that i was able to get it working that way once

20:25 but i've not changed the code nor my init.el file

20:25 so i'm at a loss

20:26 fjunker: I'm currently trying to install vimclojure 2.1.2 on Mac OS X Snow Leopard and I cannot build vimclojure.jar. Says there is an Unmatched delimiter in de/kotka/vimclojure/backend.clj on line 171

20:26 tomoj: rava: the error is that 'server is unbound?

20:26 rava: fjunker: yeah i've never been able to compile vimclojure

20:26 fjunker: just grab the .jar file precompiled

20:27 fjunker: rava: I wonder how that one was compiled

20:27 rava: java.lang.IllegalStateException: Var chdweb.server/server is unbound. (NO_SOURCE_FILE:0)

20:27 [Thrown class clojure.lang.Compiler$CompilerException]

20:27 funny thing is swank sees the var

20:27 via tab completion in the repl

20:27 tomoj: oh, hmm

20:27 tcrayford: does it show up in ns-publics?

20:28 rava: {chdweb #'chdweb.server/chdweb, server #'chdweb.server/server}

20:28 tomoj: if server is unbound, defonce should bind it..

20:29 rava: if i try to run the defonce line again, i get an error that that port is already bound

20:29 tcrayford: is this for compojure?

20:29 rava: so an instance of jetty is running on that port

20:29 yes

20:29 i can gist the file, its not much

20:29 tomoj: well, you're going to have to kill your jvm I guess to get rid of the rogue jetty

20:30 tcrayford: I usually just run def the server from the repl, in the user namespace

20:30 rava: http://gist.github.com/432400

20:30 tcrayford: that way stuff still shows up when you reload whatever ns your app is in

20:30 tomoj: just curious, why "#'chdweb" instead of just "chdweb" ?

20:31 scottj: tomoj: so you can redefine chdweb

20:32 tcrayford: if your using compojure 0.4, use the wrap-reload middleware

20:32 s/your/you're

20:32 tomoj: I see

20:33 rava: the documentation is fairly sparse, am not aware of wrap-reload

20:33 tcrayford: if its 0.4, google for "mark watson compojure setup" and that should help

20:34 tomoj: that seems to use #'handler instead of wrap-reload :)

20:34 rava: tcrayford: thanks i shall

20:35 tcrayford: you still have to use a var somewhere, I think combining jetty with defonce is kinda eurgh at this stage

20:35 tomoj: oh, it uses both

20:35 I had used defonce with run-jetty successfully once

20:36 but I can't find it now

20:36 rava: i just checked out the compojure site and they have a funky line using future

20:36 (future (run-jetty (var your-app) {:port 8080}))

20:36 scottj: rava: that's the same as :join? false

20:37 tcrayford: so it just puts the server on another thread?

20:37 rava: not sure, i'm still fairly newby myself :)

20:37 ya pretty much

20:38 pretty slick actually, that way i don't have to ever worry about that instance again

20:38 just toss it at another thread, let it ref the ns var and go to town reloading at will

20:39 tcrayford: I'm debating atm wether to use 0.3.2 or 0.4 for a new app. Choice seems kinda hard

20:39 rava: see anything particularly tasty you want/need in .4?

20:40 scottj: tcrayford: I prefer 0.3.2 but since new extensions and features will be for .4 I deal with all the things I don't like

20:40 tcrayford: don't know enough about it I guess, I've used 0.3.2 in anger a lot though, so I'm pretty familiar with the api

20:40 rava: lol

20:41 afk

20:42 tcrayford: think I might as well use .4, seeing as its the way forwards (ish)

20:44 rava: tcrayford: you'd eventually have to update to it anyway

20:46 tcrayford: yeah, its a decent point. Night all

20:46 scottj: rava: resolve your prob?

20:54 rhickey: it's alive!: http://github.com/richhickey/clojure/tree/prim

20:55 :static, longs and doubles arg/returns

20:56 mmarczyk: !

20:56 great :-)

21:03 dnolen: rhickey: :D

21:04 cemerick: rhickey: looks like it was a massive pile of work

21:10 Lajla: mmarczyk, are you an expert on lambda calculus and its theorems?

21:14 dnolen: rhickey: do you have a gist or paste of your fib example that shows the syntax?

21:20 livingston: I would really like to mapcon right now, but I don't know the equivalent function in clojure

21:21 scottj: livingston: mapcat?

21:22 livingston: I need mapcat but on each rest of the list (map and mapcat give you the first each time)

21:25 I guess I don't need the appending part of the mapcon I can do that myself with (mapcat ... (but I need a function here that gives me all the rests of a list))

21:29 dnolen: hmm, prim branch and swank-clojure 1.2.1 don't like each other much, complaints about ARef

21:32 ysph: (doc ->)

21:32 clojurebot: "([x] [x form] [x form & more]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc."

21:32 ysph: (doc ->>)

21:32 clojurebot: "([x form] [x form & more]); Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc."

21:33 tomoj: livingston: dunno if there is already such a function, but

21:34 ,(take-while identity (iterate next [1 2 3 4 5]))

21:34 clojurebot: ([1 2 3 4 5] (2 3 4 5) (3 4 5) (4 5) (5))

21:34 livingston: huh

21:34 that's better than what I came up with

21:35 I just recursively built up a vector of the rests

21:36 _rata_: has somebody used fnparse? i'm trying to do a simple work with it but am not getting it right (I get a stack overflow)... how can I debug it? is there a way to track what's going on?

21:50 dnolen: uh, prim branch Clojure just got injected with jet fuel, yowza

21:50 rhickey: dnolen: fib primitive example http://gist.github.com/432465

21:51 dnolen: rhickey: I note that (:foo bar) is crazy fast now, or am I just seeing things

21:51 rhickey: thx

21:52 rhickey: dnolen: (:foo bar) hasn't changed, but there are a lot more inlining opportunities through core fns

21:53 tomoj: so what does ^:static mean?

21:54 rhickey: tomoj: a few things. First, calls made directly by name will be static method calls not going through the var. Also, static metods support long and double arg and return hints

21:56 dnolen: I'm seeing half a billion addition operations in about second. Bye bye boxing.

21:58 livingston: why can't I attach metadata to a string? that would be hugely valuable. I would have assumed meta just creates a container that wraps whatever... but I guess in practice that would be a real pain to code in everywhere,.. I guess that makes sense it's just a shame.

21:59 ataggart: livingston: clojure strings are java strings which are final. breaking that relationship would kill interop.

22:00 well, ignore the second part, there may be a way to do it; but the first part is true.

22:07 silveen: question: I've got a vector of strings and I'd like to get the 2D coordinate of a certain character, any idea on how I could get that?

22:09 livingston: silveen: you need the version of some that returns an index instead of the item

22:10 and then call that on a string inside of a call to the same function on each string in the vector

22:10 herdrick: question: is there any thought of adding the type-based dispatch of defmethod to variadic fns? Or is that already possible?

22:10 livingston: (more or less)

22:11 herdrick: if I understand you question, I think it is...

22:11 herdrick: related question: is there a way to get type-based dispatch like defmethod in a lambda?

22:12 livingston: oh?

22:13 livingston: well I have a pretty old version of 1.2 but your saying dispatch with functions of multiple args?

22:13 silveen: livingston: thanks for the pointer, however I can't seem to find any function that returns the index

22:14 livingston: silveen: you may need to write it by mapping on a counter to the string ... no wait there's a java string function that should get you the index in a string, right? use that

22:14 ataggart: ,(.charAt "hello" 1)

22:14 clojurebot: \e

22:15 livingston: herdrick: I remember seeing commentary that it wasn't allowed, but I have a defmulti that disapatchs to various functions that take different numbers of arguments - and it seems to work fine

22:15 silveen: ataggart: the other way around tho, but thanks anyway :)

22:15 ataggart: ah

22:15 herdrick: livingston: dispatch with the same number of args, but different types.

22:15 (fn

22:15 ([x] :int (foo x))

22:15 ([x] java.io.File (bar x)))

22:15 oops!

22:15 ataggart: ,(.indexOf "hello" \e)

22:15 clojurebot: java.lang.IllegalArgumentException: No matching method found: indexOf for class java.lang.String

22:16 ataggart: ,(String/indexOf "hello" \e)

22:16 clojurebot: java.lang.IllegalArgumentException: No matching method: indexOf

22:16 ataggart: what the...

22:16 ah

22:16 herdrick: ok, with defmulti then? That's the fully general option I think. ?

22:16 ataggart: ,(.indexOf "hello" "e")

22:16 clojurebot: 1

22:16 herdrick: livingston: thanks!

22:17 livingston: herdrick: no I think you just have to make that into a multi

22:17 I may have missed the point of your question

22:17 herdrick: make what into a multi? this: (fn ([x] :int (foo x)) ([x] java.io.File (bar x))) ?

22:19 livingston: yeah reify the function (name it) and give it a dispatch function on type, then defmethod each

22:19 herdrick: ok - i was looking for something more succint

22:19 thanks!

22:19 livingston: I know that will work - but I didn't realize what you were asking.

22:20 you can just use a cond if you need it packed into the same block

22:20 herdrick: yeah

22:23 TimMc: Is there a place I can download the Clojure API docs in HTML format?

22:25 dnolen: Clojure 1.2 is going to be crazeeee

22:25 awesome

22:26 tomoj: TimMc: the gh-pages branch

22:27 TimMc: tomoj: Ah, much obliged. http://github.com/richhickey/clojure/tree/gh-pages

22:28 Now, why would it be a branch of clojure?

22:29 tomoj: so that it shows up at http://richhickey.github.com/clojure/

22:29 and so that anyone who checks out the source gets the docs

22:29 TimMc: hmm

22:30 It seems like an abuse of the concept of a branch. Then again, I'm fairly new to git.

22:31 tomoj: it's pretty common

22:31 branches in git don't have to share any commits, they can be separate trees

22:34 Raynes: TimMc: Also, that's a github thing. Not a Rich Hickey thing.

22:34 TimMc: I guess it just offends my sensibilities or something. :-P

22:34 Raynes: ;P

22:35 TimMc: This Rich Hickey fellow seems to have done a bang-up job.

22:35 I'm very impressed by the language design.

22:39 tomoj: hear, hear

22:40 TimMc: (I've been watching the presentation he gave at some Lisp conference.)

22:40 tomoj: I imagine most language designers think hard about the choices they have to make

22:41 difference is, rich gets them right :)

22:42 TimMc: Well, I'm not convinced about all the choices he has made, but I have yet to finish watching that presentation -- he might justify them to my satisfaction for all I know.

22:44 hiredman: http://www.infoq.com/presentations/Towards-a-Universal-VM <-- "do what ever rich says, because he is normally right"

22:51 ,(doc doall)

22:51 clojurebot: "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. doall can be used to force any effects. Walks through the successive nexts of the seq, retains the head and returns it, thus causing the entire seq to reside in memory at one time."

22:52 dnolen: rhickey: should map/reduce be slower on microbenchmarks on the prim branch?

23:04 _rata_: can anyone help me with fnparse lib? I'm trying to write a parser for simple aritmetic expressions

23:05 and I could make one for extremely simple arithmetic expressions: one addition or one substraction

23:06 but when I try to make one for multiples additions and subtractions, I get a stack overflow

23:08 I have: (def digit-lit (lit-alt-seq "0123456789")) (def number-lit (rep+ digit-lit)) for number literals

23:09 is there a pastebin for clojure?

23:09 tomoj: use any you like

23:13 _rata_: is there any pastebin with clojure syntax highlighting?

23:13 tomoj: gist

23:14 pastie too Ithink

23:15 silveen: pastbin got a lisp mode which works kinda okey

23:17 _rata_: http://gist.github.com/432521

23:18 with the commented code I got it right for just one addition or one subtraction

23:19 but when I tried to make it work with multiple additions and subtractions it stopped working

23:20 tomoj: you probably need to remove the left recursion? I'm not sure, never used fnparse

23:21 _rata_: oh you are right

23:21 tomoj, thanks :)

Logging service provided by n01se.net