1:23 Cark: hello
4:50 kib2: hi, did someone read the first chapters and is it worth a look ? http://
6:20 tomppa: hmm, AWT/Java2d seems to produce an awful lot of garbage. At first I thought it was Clojure but luckily it seems that wasn't the case.
6:24 ah damn. It was the Clojure side after.. forgot the laziness part in my benchmark
6:33 Lau_of_DK: tomppa, garbage ?
6:34 tomppa: I'm doing some simple performance tests and I get lots of annoying gc pauses
6:34 part of it is probably because of awt but I have tried to factor that out
6:35 I'm just writing the same thing in mzscheme for comparison
7:01 I'm testing a simple particle system, kind of an fireworks effect and currently the mzscheme version seems to be a lot faster than the clojure one and doesn't have much noticiable gc pauses
7:03 any clues on how I could improve the performance? I just have a list of particles [[posx posy] [[velx vely]] that I update and draw
7:19 hoeck: tomppa: can you paste your code?
7:19 tomppa: sure, just a sec
7:20 hoeck: tomppa: there is *warn-on-reflection* and some math primitives
7:22 lisppaste8: tomppa pasted "Fireworks" at http://
7:23 tomppa: I doesn't have all the code, graphics are handled by awt/java2d
7:23 ... and it isn't meant to look neat. Just a quick test
7:24 Kerris0: just found an online Lisp interpreter http://
7:25 tomppa: I don't mind if my code is a bit slow but the GC pauses are annoying. mzscheme version is ~identical but doesn't exhibit any gc problems. And is some 3-4 times faster
7:35 if someone wants to try it out here's the jar http://
7:45 okay, when I set -XX:+UseConcMarkSweepGC it works a lot better. Just, umm, what does that flag do
7:47 isn't incremental gc on by default on the client vm?
7:59 it seems that none of my extra and classpath args are used when I run clojure-slime
8:01 Chouser: kib2: the book is good. it's still a bit rough at this point, but the narrative flows very nicely. I think it'll be quite good for anyone who wants to learn Clojure.
8:10 kib2: Chouser: thanks, so I'll wait some time and then buy it. See you, I need to go to work :)
8:11 tWip: I think I'll need to buy them in bulk and sneakily distribute them to my coworkers' desks
8:25 jkantz: Q on maps... how would I map across a map, returning another map?
8:26 do I need to write something to do this or is there some built-in way?
8:26 rhickey: jkantz: (into {} (map (fn [[k v]] ... [newk newv]) amap))
8:27 jkantz: thks
8:28 rhickey: or: (reduce (fn [m [k v]] ... (assoc m newk newv)) {} amap)
8:29 the latter will allow you to conditionally add entries
8:39 Chouser: rhickey: it's nice to have you back.
8:40 rhickey: Chouser: nice to be back!
8:41 gnuvince: good morning
9:22 abrooks: rhickey: How was tabulating? :)
9:25 rhickey: abrooks: it's a lot more than tabulating, but it went well
9:26 abrooks: rhickey: I figured it was more that tabulating. I should have included a wink.
9:29 rhickey: Is the system that you were working on part of the federal election system or something used by a private/commercial entity (or something else entirely)?
9:29 rhickey: http://
9:30 it's the exit poll that feeds every networks and newspaper - essentially everything you see about voter opinion on election day
9:30 abrooks: rhickey: Ah, cool. I was going to ask if there was any public information about it. Thanks.
9:39 Lau_of_DK: rhickey, how do you feel Clojure stacks against something like ATS?
9:43 rhickey: Lau_of_DK: do you mean this: http://
9:49 Lau_of_DK: yes, although I read about it at www.ats-lang.org
9:49 @ rhickey
9:51 gnuvince: Lau_of_DK: what do you mean by "stacks against"?
9:53 rhickey: Lau_of_DK: never heard of it
9:53 Lau_of_DK: Im thinking pros/cons. ATS looks very (http://
9:56 gnuvince: all the ATS programs I've seen on that benchmark are 10x as long as all the other programs.
9:59 Chouser: seems like a very different language -- staticly typed, compiled, explicit pointer arithmetic, almost certainly no macros.
10:02 gnuvince: Definitely no leveraging existing Java code ;)
10:05 Lau_of_DK: Alright, thanks :)
10:15 rhickey: accepting proposals for sorted version of set and map literals
10:16 Chouser: you want something syntaxy, not just #=(sorted-map 1 2,3 4,5 6)
10:16 ?
10:17 it could be implicit -- if the keys are printed in order, read them into an sorted collection. I'm sure that would never cause nasty surprises.
10:18 #>{:a 1, :b 2} ##>{:x :y :z}
10:38 rincewind: the to-do-list mentions: arbitrary symbols in | |
10:40 there are currently no pipe symbols in the .clj files in trunk i think
10:54 rhickey: Chouser: yes, not #=(sorted...
10:55 rincewind: yes, thinking forward to |whatever including spaces| as a symbol
10:56 rincewind: when AOT compilation is available, will LispReader.java be ported to clojure?
10:56 rhickey: rincewind: could be, not a top priority though
10:57 I guess a long-term goal might be a bootstrapped version of Clojure
10:58 but bootstrapping has its own set of complexities, few of which contribute to productivity
10:59 Chouser: #>{:a 1, :b 2} #>#{:x :y :z} ?
11:00 Chouser: these are starting to feel a bit like perl, or maybe regex.
11:01 rhickey: yeah
11:01 Chouser: > is nice, but 3 symbols preceding the { is not so much.
11:01 #> feels ok
11:02 ##{:x :y :z} ? less consistent, but fewer chars too
11:02 rhickey: I'm not sure sorted literals are that important, and given the new reader extensibility, at least #=(sorted...) will work
11:03 for print/read
11:03 Chouser: actually it doesn't, but I don't understand the new reader enough to know why
11:03 (class #=(sorted-map :a 1, :b 2)) -> #=clojure.lang.PersistentHashMap
11:03 rhickey: I do, it's due to compiler interpretation of maps - always yields hash-maps right now
11:03 Chouser: oh, ok.
11:03 rhickey: maps in code are evaluated
11:06 these things are all connected, for instance, should sorted-maps in code be evaluated too, especially if there isn't literal syntax for them
11:09 Chouser: ah, subtle. #=(sorted-map (keyword "a") 1) vs. {(keyword "a") 1}
11:10 #= is an odd beast that I definitely do not have a feel for yet.
11:10 rhickey: Chouser: It's not intended for use by humans
11:10 Chouser: heh
11:12 rhickey: for instance above, there's no reason for #=
11:13 Chouser: I guess if there was a general warning -- don't use #= literals in your hand-written code -- it wouldn't be too bad for #=(sorted-map ... to skip eval its arguments
11:13 yeah
11:13 skip eval'ing
11:14 rhickey: In CL, vector literals are constants, if you want evaluation you need to backquote
11:14 In Clojure, I decided to make vector and map literals be evaluated
11:15 this has been very convenient, returning [a b] etc
11:19 Chouser: yes, I agree. It also feels more like python and javascript, which I imagine has eased many people's transitions.
11:19 danlarkin: Chouser: I can vouch for that
11:19 rhickey: but it's a basic fact that there can't be syntax for everything
11:20 (sorted-map ...) works fine when you need it
11:21 the few times I've wanted a map other than hash-map for syntax has been when I've wanted array-map for order preservation
11:21 Chouser: yep. And it's nice that #= can help hold back the need for ever more syntax.
11:22 rhickey: the idea behind #=(what you would write anyway) is that you'll never be inclined to write #= yourself
11:24 it's strictly for read/print representation
11:25 Chouser: so fixing up the compiler such that #=(sorted-map ...) works should be sufficient.
11:25 rhickey: for some definition of works
11:25 I'm leaning towards unevaluated, as-read
11:26 constant
11:26 Chouser: yeah
11:30 rhickey: the other side I'm currently mulling over is whether this print-type-preserving shouldn't be separate from print-readably
11:31 Chouser: so 3 modes of printing (not including "pretty")?
11:31 rhickey: at the repl, I'd like all my maps and sets to look the same
11:32 but when serializing constants, I need to distinguish precisely
11:34 Chouser: would there be any difference for any type other than sorted mapand sorted set?
11:34 rhickey: sure, array-maps vs hash-maps
11:35 maybe different sorted sets with different implementations/perf characteristics
11:35 Chouser: ah, array-maps.
11:35 hm.
11:35 rhickey: generally, there will be N implementations
11:35 I think the repl should be about the abstractions
11:36 that sort of forces to type-annotated serialized versions
11:37 Chouser: but that means this new format really will be just for serialization. Any reason not to hook into Java's serialization at that point?
11:37 rhickey: #=(java.util.HashMap. {:b 2, :a 1}), #=(clojure.lang.PersistentArrayMap. {:b 2, :a 1})
11:38 Chouser: it's binary, tied to class versions etc
11:39 Chouser: ...or at least make the new format compatible with dropping in Java-serialized versions of Java objects that don't have a clojure-print method.
11:39 oh, I didn't realize it was binary. bleh.
11:39 rhickey: there is JAvaBeans serialization which is text and extensible, if somewhat verbose
11:39 very verbose
11:39 Chouser: that's xml?
11:39 rhickey: too verbose
11:39 yeah
11:40 Chouser: could that be used when there's no print-method though?
11:48 rhickey: Chouser: it could, but there's no registry for persistence delegates AFAIK, and the default uses bean properties, not likely to be useful in many cases
11:51 Kawa had an efficient way to store constants using Externalizable, but not many built-in classes implement that
11:57 Chouser: you could base64 the binary serialization. #=(deserialize java.Whatever "...")
11:58 anyway, that's secondary I guess to the core idea of 3 print types
12:02 would *print-meta* still be optional for the serialize form?
12:02 rhickey: no, that's one of the current todos
12:03 this one is that: http://
12:03 metadata not serialized
12:06 Chouser: huh. I couldn't make any sense of that.
12:07 so this might make sense as modes on a linear scale from "undecorated" through "serialization": print, print-readably, readably with meta, and serialize
12:07 rhickey: basically the value at the repl gets wrapped in a little fn, which when compiled, serializes the symbol constant, losing its metadata at present
12:08 Chouser: yes, that's one way to look at it
12:09 Chouser: auto-indentation would still have to be a separate flag
12:28 rsynnott: has anyone read this new book?
12:33 Chouser: rsynnott: I've read the half that's available.
12:33 rsynnott: I'm vaguely considering buying the PDF
12:34 though I'm not sure whether I actually need it; the website was quite useful
12:56 gnuvince: Chouser: how is it?
12:57 duck1123: does anyone know if you buy the PDF first if you can still get the discount on the print version, or do you have to buy them together
13:21 danlarkin: any better way to make a string of n spaces? (apply str (map (fn [x] \space) (range 4))) n being 4 for this example
13:24 Chouser: danlarkin: (apply str (replicate 4 " "))
13:25 danlarkin: Chouser: perfect, thanks
13:26 Chouser: gnuvince: It's easy to read. I think it's the kind of ground-up tutorial a lot of people have been asking for.
13:31 gnuvince: Chouser: cool
13:31 Chouser: we'll see when it's complete if it's also going to be a good reference.
13:51 drewr: lol. http://
13:52 rhickey: drewr: I think he was just interested in distributed concurrency, which Clojure doesn't provide yet
13:58 made AFn's Comparator.compare work with predicates too, true values sorting first (sort > [1 2 3 4]) no longer needs comparator
14:10 AWizzArd: What are AFn's?
14:10 danlarkin: Abstract Functions, I assume
14:10 but I know what happens when one assumes
14:11 so perhaps I should have kept my mouth shut
14:12 AWizzArd: regardless if it stands for Abstract Functions or not: what are Abstract Functions?
14:14 wwmorgan: AFn is the abstract class that all functions inherit from
14:14 cemerick: rhickey: many thanks for that change to sort. *very* handy
14:21 Chouser: yeah, pretty.
15:04 drewr: Any particular reason why finally can't return a value in case a catch clause was invoked?
15:05 Chouser: you get the specific catch-clause return value instead, right?
15:06 drewr: No, I get a boolean.
15:08 Chouser: this returns "c1": (try (throw (Exception.)) (catch Exception e "c1") (finally "f"))
15:12 drewr: The boolean was coming from the return value of what I thought was causing the exception. I guess it wasn't, though my catch clause was getting invoked.
15:14 fanda: hello all!
15:14 can I have a question about macros?
15:14 Chouser: danlarkin: go for it
15:14 sorry
15:14 fanda: go for it :-)
15:14 danlarkin: Chouser: :-o
15:14 fanda: i would like to create a macro 'mac
15:14 (mac (run-mac 1 2) (do-not-run-fn 1 2))
15:15 when called like this, if expands run-mac macro
15:15 but it does not expand/run do-not-run-fn
15:15 a returns a list with results
15:16 (list expanded-expression-from-run-mac (do-not-run-fn 1 2))
15:16 run-mac is a constant name - not any macro
15:17 Chouser: you want the raw symbol list '(do-not-run-fn 1 2) in your result list?
15:17 fanda: yes
15:18 Chouser: (defmacro mac [a b] `(list ~a '~b))
15:18 rhickey: drewr: finally is for cleanup side-effects, it runs even when the (returning) body succeeds, so can't define return
15:19 fanda: thanks Chouser, let me try it, if that is what I need
15:28 drewr: rhickey: AH, good point.
15:30 fanda: Chouser: still not there, I give you the concrete example of what I am trying to do
15:30 (defmacro equal-pairs [& expr] (map #(cons '= %) (partition 2 expr)))
15:30 user=> (macroexpand '(equal-pairs 1 1 2 2 1 4))
15:30 ((= 1 1) (= 2 2) (= 1 4))
15:32 now I want to create a macro: (check (equal-pairs 1 1 2 2 1 4) (= 5 5) (= (+ 1 2) 3))
15:32 which returns for the start this: '((= 1 1) (= 2 2) (= 1 4) (= 5 5) (= (+ 1 2) 3))
15:33 it calls the macro equal-pairs and joins its result with all other expressions - unless it is equal-pairs again, which gets called and joined...
15:34 more advanced version of macro 'check returns a list of (expression result) '(((= 1 1) true) ((= 2 2) true) ((= 1 4) false) ...)
15:34 Chouser: you want "check" to be explicitly aware of the "equal-pairs" and treat it differently from "="?
15:34 fanda: yes, exactly
15:35 Chouser: first of all, I think think there's any need for equal-pairs to be a macro
15:36 bah. I mean I equal-pairs can be a fn
15:37 fanda: no, I need to keep both - non-evaluated parameters and evaluated ones
15:37 user=> (macroexpand '(equal-pairs (+) 0 (+ 1) 1 (+ 1 2) 3))
15:37 ((= (+) 0) (= (+ 1) 1) (= (+ 1 2) 3))
15:39 otherwise, I would have to quote everything - '(+) '(+ 1) ...
15:41 rhickey: fanda: do you need equal-pairs on its own? can it just be syntax of check?
15:41 Chouser: (defmacro check [& s] (cons `list (map #(if (= (first %) 'equal-pairs) % `(quote ~%)) s)))
15:41 but you should listen to rhickey :-)
15:42 oh, that's not right. sorry.
15:43 rhickey: Chouser: he shouldn't listen to me?
15:43 :)
15:43 AWizzArd: I think he meant the macro
15:44 fanda: just a second guys...
15:46 Chouser: rhickey: that's right, you got a problem with that?
15:51 (defmacro check [& s] `'(~@(mapcat #(if (= (first %) :equal-pairs) (for [p (partition 2 (rest %))] (cons '= p)) [%]) s)))
15:51 wwwwwuser=> (check (:equal-pairs 1 1 2 2 1 4) (= 5 5) (= (+ 1 2) 3))
15:51 ((= 1 1) (= 2 2) (= 1 4) (= 5 5) (= (+ 1 2) 3))
15:53 or for your original syntax: (defmacro check [& s] `'(~@(mapcat #(if (= (first %) 'equal-pairs) (macroexpand %) [%]) s)))
15:54 but that's kinda weird because the equal-pairs macro doesn't really work on its own.
15:54 fanda: yes, it doesn't have to work on its own...
16:12 jgracin: rhickey: rich, could you please verify memfn definition. it seems to me that ~@args should not go into the arglist of lambda form.
16:19 fanda: thanks guys for help!
16:19 having phone calls and stuff to do...
16:19 greatly appreciate your help!
16:42 rhickey: jgracin: methods aren't variadic - the args to memfn are names used to make a specific-arity call
16:46 jgracin: rhickey: Should this work: (filter (memfn endsWith ".clj") ["a.clj" "b.java"]) ?
16:46 it doesn't seem to.
16:46 rhickey: jgracin: no, it's not partial binding
16:53 jgracin: ok, got it. thanks.
16:54 rhickey: jgracin: I see how the docs could use clarification
16:58 Chouser: jgracin: memfn is hardly ever worth it. #(.endsWith % ".clj")
16:59 jgracin: Chouser: that's what I went back to. (memfn endsWith ".clj") seemed nice, though.
17:00 rhickey: Chouser: right, it predates #()
17:19 Chouser: I've got a bunch of old projecteuler code that uses "thisfn"
17:19 it also uses "true" instead of ":else" in conds
17:26 danlarkin: Chouser: http://
17:42 Chouser: danlarkin: :-) thanks
17:53 set and sorted-set are different arities!?
17:54 wwmorgan: Chouser: you're looking for hash-set I think
17:54 Chouser: hm.
17:55 good point.
18:20 blackdog: is it significant that all package names in contrib are lower case? can i use proper case without any problems with AOT in the future?
18:21 rhickey: blackdog: sure, but people choose lower case because upper is annoying, so if you have a choice...
18:21 blackdog: oh ok :)
18:21 rhickey: convention is Java is also all-lower for packages
18:22 in Java
18:32 AWizzArd: Does the jvm support something like "green threads", some very lightweight threads?
18:39 danlarkin: AWizzArd: I don't believe so, but I think if you use a thread pool the effect is somewhat similar
19:00 AWizzArd: rhickey: do you see reader macros for users coming in 2009?
19:06 Chousuke: I haven't seen anyone present a really good argument for user-definable reader macros :/
19:09 AWizzArd: Chousuke: to not depend on what Rich thinks is the best syntax for all tasks and all upcoming problems/datastructures etc. If this is a good argument depends on your opinion.
19:10 Chousuke: Well, you can define syntax with regular macros; though I can see the usefulness of reader macros if you *really* need something a lot.
19:11 AWizzArd: Chousuke: and reader macros just look better for some stuff. Just think about #(foo 1 2 3) vs (# foo 1 2 3)
19:11 This is: reader macro vs macro
19:12 Chousuke: well, yeah, but that's quite a small difference.
19:12 the problem that reader macros are prone to name clashes should be somehow solved first.
19:13 AWizzArd: I don't agree. This difference is so huge that Rich luckily decided to implement it as a reader macro.
19:13 Chousuke: Well, in this case yes.
19:14 as anonymous functions are quite common.
19:14 AWizzArd: Yes
19:14 But currently I can't implement fully featured currying support, which would even more commonly used in Clojure
19:15 Chousuke: fully featured?
19:15 AWizzArd: yes
19:15 Clojure has no currying support, but instead #(..) which comes already close
19:15 Chousuke: clojure has partial though
19:16 AWizzArd: Yes, but this makes not much sense in my opinion
19:16 Currying is syntactic sugar
19:16 it's about brevity
19:16 Currying makes imo only sense when implemented as a reader macro
19:16 gnuvince1: As I said before, I prefer that #(...) anonymous functions be used instead of currying in general, because currying + function composition lead to some really hard to understand code in haskell IMO.
19:16 AWizzArd: (map $(* 3) mylist)
19:16 gnuvince1: It's almost backwards Factor code.
19:17 Where you need to remember what a function takes and what it returns
19:17 AWizzArd: gnuvince1: in fact currying makes code *easier*. That's why Rich implemented something like #(..) in the first place, which already comes close.
19:17 gnuvince1: AWizzArd: the difference is that with #(...) you must be explicit about arguments
19:18 AWizzArd: and I am not talking about implicit currying, but explicit one
19:18 gnuvince1: (map #(* 3 %) my-list) reads bery easily.
19:18 *very
19:18 Chousuke: AWizzArd: that's not much of an improvement over (map #(* 3 %) sequence)
19:19 AWizzArd: and (map !(* 3) my-list) reads even better, and (map !(rgb _ 255) colors) is also better than (map #(rgb %1 255 %&) colors
19:20 gnuvince1: How does the first example read better?
19:20 AWizzArd: because it says: multiply with 3
19:20 gnuvince1: So do ours.
19:21 AWizzArd: how does #(* 3 %) read better than (fn [x] (* 3 x))
19:21 Chousuke: If you ask me !(rgb _ 255) looks really confusing
19:21 AWizzArd: I can read both perfectly and understand them very well
19:21 how can look #(rgb _ 255 %&) *non-confusing* to someone new to Clojure?
19:21 Chousuke: AWizzArd: #() doesn't have a superfluous name ("x") in the code
19:22 AWizzArd: Chousuke: but it has a superflous % in the code
19:22 Chousuke: it's not superfluous
19:22 it's the placeholder
19:22 AWizzArd: the x in fn also not
19:22 Chousuke: it's not a name, it's just %
19:22 AWizzArd: x is not a name, it is just a placeholder too
19:23 Chousuke: but x is a name.
19:23 AWizzArd: both are either names or placeholders
19:23 Chousuke: % is part of the syntax of #()
19:23 AWizzArd: right
19:23 but it is superflous
19:23 gnuvince_: But it *does* help with shouwing explicitly what parameters a function takes
19:23 AWizzArd: (* 3) is a problem, I agree, as this would be implicit currying
19:24 gnuvince_: and !(* 3) is a nice example
19:24 let's do something different
19:24 subtract 3
19:24 (map #(- % 3) coll)
19:24 AWizzArd: gnuvince_: how does #(* 3 %&) show explicitly what parameters * takes?
19:24 Chousuke: AWizzArd: again, once one knows the syntax for #(), it's clear
19:24 AWizzArd: (map !(- _ 3) coll)
19:25 Chousuke: same with the syntax for !(...)
19:25 gnuvince_: AWizzArd: how is that better than the syntactic sugar for fns?
19:25 Chousuke: AWizzArd: but what about (map !(- 3) coll)
19:25 AWizzArd: or whatever the symbol might be
19:25 Chousuke: AWizzArd: shouldn't that be possible too, since !(* 3) is?
19:25 gnuvince_: Chousuke: with subtraction, order matters
19:25 Chousuke: gnuvince_: yeah, I know, and that's the problem
19:25 gnuvince_: 3 * 4 == 4 * 3; 3 - 4 != 4 - 3
19:25 AWizzArd: Chousuke: !(- 3) ==> #(- 3 %&)
19:26 gnuvince_: Anyway, I think we're talking in circles here
19:26 Chousuke: AWizzArd: the latter is better in this case.
19:26 gnuvince_: Since it *should* be a library, it wouldn't matter much to me
19:26 AWizzArd: the better is !(...)
19:26 gnuvince_: I would never use it, but if AWizzArd wants to, his choice.
19:26 That's the beauty of having extensible languages
19:26 AWizzArd: chances are you would use it all the time
19:26 gnuvince_: libraries can "modify" the language
19:27 Chousuke: ! is not a very good macro character for your currying though.
19:27 AWizzArd: Chousuke: I don't care for the character.. see it as a placeholder for the real thing, whatever that might be
19:27 it could be a ! or $ or & or % or ~ or | or whatever
19:28 Chousuke: but I don't see how !(- 3) or !(rgb _ 255) are better than the explicit alternatives, really.
19:28 all they do is hide things.
19:28 that should be visible.
19:28 AWizzArd: but that is the only reason why currying exists
19:28 it is pure syntactic sugar
19:28 and if it should be visible one can use (fn [x] ...)
19:28 Chousuke: but #() provides us with enough syntactic sugar already
19:29 (fn [x] ...) is too verbose; the benefit gained from #() is greater than the benefit of !() compared to the already existing #()
19:29 AWizzArd: #(foo %1 %2 %3 "hallo" %4 -100 %&) vs ~(foo _ _ _ "hallo" _ -100)
19:29 Chousuke: yeah
19:29 I'd take the former.
19:29 rhickey: Clojure doesn't allow user-defined reader macros because they can't be combined - there's no namespace support, unlike for regular macros
19:30 but the case for more currying support is very weak
19:30 Chousuke: the latter does look really nice but it doesn't allow easy changing of parameter order for example
19:31 AWizzArd: Chousuke: yes, the benefit is greater from (fn [..] ..) to #(...), but it also misses some features
19:31 rhickey: so you'll probably have to come to grips with that's how Clojure works
19:31 AWizzArd: Chousuke: you could also say ~(* %1 %1)
19:32 Chousuke: and would that take an automatic "rest" parameter or not? it's pretty confusing :/
19:32 AWizzArd: rhickey: so probably there won't be reader macros any time?
19:33 Chousuke: it is not confusing at all if you would read (in the case currying was present) the then existing manual for 5 minutes
19:33 Chousuke: yeah but it looks like a #(* %1 %1)
19:34 rhickey: AWizzArd: not in the plans as of yet
19:34 Chousuke: which is different.
19:34 AWizzArd: Chousuke: yes, that's right
19:34 Chousuke: and in this case #(* %1 %1) is probably even more efficient as no apply would be needed, as it would be the case for a curried object
19:34 (under the hood I mean)
19:35 rhickey: the clash problem is significant - I don't want libraries that can't be combined. Macros work, user-defined reader macros don't
19:36 AWizzArd: Maybe one could enforce user-defined reader macros need some explicit "turning on" and "turning off"?
19:36 (activate-infix-math)
19:36 Chouser: What about namespaced reader macros, like (chouser/regex .*$)
19:37 AWizzArd: and then you can say: (print ~[4x?-14]) or something like that
19:37 Chouser: lots of people who want reader macros might not be satisfied with that, but it would certainly grant some power.
19:37 rhickey: Chouser: how does that work?
19:38 duck1123: as much as I would like reader macros for my own use, I would hate to see them used by other people and figure out what it means
19:38 rhickey: AWizzArd: CL has user reader macros and the consensus is to avoid them
19:38 duck1123: exactly
19:38 AWizzArd: sure, abosolutely, in 99% of all cases
19:38 duck1123: it's bad enough with the few that we have now (for a new user)
19:39 Chouser: at read-time the macro name would be resolved, recognized as a reader macro, and called with the input stream. It would return the s-expression, with the stream advanced to the end of the expression.
19:39 gnuvince_: Is there demand for an infix arithmetic library?
19:39 AWizzArd: gnuvince_: yes
19:39 Chousuke: maybe have some dispatch-character for user-defined reader macros, and for any defined macros, unless explicitly imported, would have to be qualified with the namespace?
19:40 rhickey: Chouser: the issue isn;t how to implement user macros, but what happens when you have two libraries that define $ ?
19:40 AWizzArd: rhickey: so let's enforce to activate and deactivate them
19:40 rhickey: gnuvince: no
19:40 Chousuke: that might result in some mismatching conventions though, so you could have pieces of code that look similar but do some very different things
19:40 rhickey: AWizzArd: you are unlikely to convince me they are a good idea
19:41 AWizzArd: (Well, if only one person asks for infix arithmetic from this moment on there is demand.)
19:41 Chouser: rhickey: the reader macro in my example is a function named regex in the chouser namespace. Existing namespace resolution and collision rules would apply.
19:41 rhickey: Chouser: so how do you use it?
19:42 AWizzArd: rhickey: I don't want to convince anyone that reader macros are a good idea in general. But I think that you can't forsee everything, and people might come into situations where 1 or 2 reader macros are really helpful
19:42 Chouser: it looks like a function or macro call, but it's actually a reader-macro call.
19:42 rhickey: Chouser: I don't see the point then
19:42 doesn't allow for syntax that regular macros don't
19:43 Chouser: it would allow you to have non-valid-symbol stuff inside the parens. like literal regex chars, or SQL code or something.
19:44 LispReader, upon seeing a symbol at the head of a list, would attempt to resolve it. If it resolves to a reader macro, it would pass the input stream to it, and accept back the s-expression to use in it's place.
19:44 rhickey: Chouser: ah, sort of an escape area
19:44 Chouser: yes
19:45 rhickey: I don't like it :)
19:45 Chouser: heh. ok.
19:45 biab.
19:47 rhickey: AWizzArd: I'd rather there be a consensus of need for something and add it in a way that everyone can use
19:47 AWizzArd: yes
19:49 of course, every decision comes with its own advantages and disadvantages
19:51 rhickey: AWizzArd: yes, I recognize fully this is less flexible than CL in this area, OTOH, I'd like to think Clojure will engender less desert-island programming than did CL
19:52 speaking a common language fosters library development, shared idioms etc. When everyone creates their own language there's less of that
19:53 AWizzArd: And I agree and think this is a good thing. Ironically reducing the amount of flexibility a little bit can have positive effects here.
19:53 rhickey: and even standard reader macros pose an understanding challenge for newcomers
19:54 Chouser: esp. weird ones like #+ and #-
19:54 :-)
19:55 AWizzArd: Well, I just think it is not overly important to be too nice to newcomers. Being a newcomer is a phase in which people are only a short time. Most of your life you have been an expert in programming.
19:55 rhickey: Chouser: coming soon :)
19:56 AWizzArd: concentrating on things that medicore to experts users like/want/need can be a good thing
19:56 Instead of beeing nice to newcomers from the language side we need to write tons of examples and tutorials.
19:57 * rhickey doesn't like print-serializably
19:57 AWizzArd: I will see if I can do that for some german newcomers
19:57 rhickey: print-replica, print-clone(r) ???
19:58 Chouser: (set! *print-detail* :serialize)
19:58 rhickey: Chouser: talking about multimethod name
19:58 Chouser: serialize?
19:59 rhickey: serialize is out, not a good name at all IMO, I think driven by flattening graph notion, but weak
19:59 Chouser: the opposize of "read" is often "write"
19:59 opposite
19:59 AWizzArd: (print-readable ...) maybe
19:59 readably
20:00 Chouser: AWizzArd: that would mean something different
20:00 rhickey: unfortunately you can print to something readable that doesn't read as an identical copy, as happens now
20:00 AWizzArd: ic
20:00 rhickey: this is a stronger notion
20:00 Chouser: unless we change what is now *print-readably* to be named print-for-repl or something.
20:01 rhickey: it's really print-replicator, but that's a mouthful
20:01 Chouser: print-clone's not bad.
20:01 rhickey: clone is so sci-fi though
20:02 Chouser: what get's printed is not the original, so there's not much need for the "-r"
20:02 rhickey: but short, and people get clone
20:02 AWizzArd: reduplicate
20:02 Chouser: ooh, print-dup
20:02 rhickey: Chouser: but it creates the clone when read back, the printed version is not itself a clone
20:03 AWizzArd: (print-twin ...) :-)
20:03 rhickey: nice - leave out enough letters and you can interpret it in many ways
20:04 print-dup(licator)
20:05 AWizzArd: print-genes
20:06 rhickey: print-dup wins - thanks Chouser !
20:07 Chouser: just riffing on AWizzArd :-)
20:11 AWizzArd: without trying this in the repl, what result do you expect? ((symbol "+") 4 10) ==> ?
20:11 duck1123: error
20:11 Chouser: can't cast Symbol to IFn
20:12 rhickey: Symbol's are IFns, like keywords
20:12 AWizzArd: I thought: either error or 14.
20:12 rhickey: 10
20:12 AWizzArd: yes :-)
20:12 but why?
20:12 * rhickey didn't look
20:12 * AWizzArd believes
20:12 Chouser: rhickey: nobody's impressed. ;-)
20:12 rhickey: look up the symbol + in 4, if not found return 10
20:13 Chouser: 4 not being a collection doesn't bother it?
20:14 hm. (get 4 '+ 10)
20:14 rhickey: Chouser: no, get was generalized a while back
20:14 AWizzArd: from get I would not expect errors
20:15 but (nth 4 '+) instead should be an error
20:15 Chouser: AWizzArd: I bet you didn't get very far though -- this is a not a deep or hidden error, is it?
20:16 AWizzArd: I was just playing in the repl, so, not deep at all ;-)
20:16 ((symbol "+") {'+ 8 :a 13} 100) ==> 8
20:17 rhickey: Symbols were made to do self-lookup like keywords a while back, so they have parity for that use, with slightly different ns defaults
20:18 also symbols used as keys can have metadata
20:18 AWizzArd: How can one get somthing like (symbol-function '+)?
20:18 Chouser: resolve
20:18 AWizzArd: thx
20:19 n8 n8
20:33 Chouser: I often use (apply X (map Y ...)) instead of reduce so that I can use #() for Y without the ugly %1 and %2
20:33 I don't know if that's a defensible reason.
20:34 rhickey: Chouser: probably not
20:35 what's an example?
20:38 Chouser: (apply + (map #(- (int %) 64) word))
20:39 rhickey: vs?
20:40 Chouser: (reduce #(+ %1 (- (int %2) 64)) 0 word)
20:40 (reduce (fn [a b] (+ a (- (int b) 64))) 0 word)
20:40 rhickey: you can say % instead of %1 there
20:40 leaves only one ugly
20:40 Chouser: hm, didn't know that.
20:41 rhickey: but I'd advise you to get friendly with reduce, it's likely to be much faster, and more reduce-based idioms are on the way, including some that solve the lazy io problem
20:42 Chouser: hm...
20:43 rhickey: http://
20:45 Chouser: 91 slides?
20:45 gnuvince_: Chouser: that's Oleg for you
20:46 91 slides of stuff that's gonna blow your brains out completely and make you wonder if you really know anything about programmming
20:47 rhickey: r you could just wait for the Clojure version, after AOT
20:48 the idea is good, and I've got it mostly worked out for Clojure, in my head
20:50 basically IO becomes an enhanced reduce, where the reducing fn can communicate that its done with the reducee, the reducee can clean up, also reducing fn gets passed a source of data rather than one item
20:50 so can read multiple items per step
20:51 based around a new abstraction, an io, like a generating function, new value every time called
20:51 but threadsafe, unlike iterators
20:52 still working on EOS/EIO protocol
20:53 so you'll be able to reduce files/sockets/queues, blocking or non, resources always cleaned up
20:53 drewc: very cool!
20:54 danlarkin: rhickey: you're too smart for me :-o
20:54 rhickey: the Haskell guys came up with the core idea, Clojure won't be exactly the same of course
20:55 they have the same resource management problems with lazy IO as we've seen
20:56 Clojure version should be about 3 slides
20:56 :)
20:56 abrooks: Heh. Naturally.
20:56 drewc: "Lazy IO in serious, server-side programming is unprofessional" he says :)
20:57 danlarkin: destructuring works with strings too, hoorah!
20:57 rhickey: an overstatement of course, you could do lazy io within a with-open and be fine, but handing off the lazy seq is the problem
20:59 abrooks: rhickey: Have you given any thought to a limited eager seq wrapper? Something to gobble, say, N at a time?
21:00 That would be more like buffering.
21:00 rhickey: abrooks: partition?
21:00 abrooks: Sure but partition alters the structure of the seq, right?
21:01 I'm talking about something like a lazy-cat with a delay in the fn slot which will yield N more items at once when the delay is hit.
21:01 Chouser: abrooks: there's also seque
21:02 abrooks: Oh.. wait.. brain cells clicking... deja vu..
21:03 seque is very, very close to what I was thinking of. Probably because I'VE BEEN HERE BEFORE... :-}
21:05 danlarkin: OT but deja vu totally freaks me out
21:07 abrooks: I just chalk it up to by brain failing miserably. Nothing freaky about that. Just annoying. :)
21:10 drewc: i once heard deja-vu as simply your write-head getting a little ahead of your read-head, and reading (remembering) what you just wrote.
21:10 deja-vu described as*
21:19 danlarkin: so I guess that (take 2 "abcd") == (\a \b) and (\a \b) != "ab" is just the way it is?
21:19 I know I could apply str to the list, but I'd like to make it more generic and not have built in behavior for strings specifically
21:21 djkthx: are there default paths LOAD-FILE looks in?
21:21 if so, how can i change/add to it?
21:22 gnuvince_: danlarkin: into?
21:24 abrooks: Strings really aren't collections though they're seq-able. There's no (empty "abc") or (into "" \a \b \c)
21:24 It would be nice though.
21:25 gnuvince_: hmmm
21:25 I thought it did
21:25 Sadness :(
21:25 abrooks: Truly. If only there were someone in this channel who could fix it...
21:26 Chouser: most collections are not themselves seqs. (take 2 [1 2 3]) doesn't return a vector
21:27 abrooks: Chouser: I know. But a string is somewhat like a collection and into/empty/etc. would be nice.
21:28 It's easy to break up a string (last "asdf") (rest "asdf") (first "asfd"), etc. Now what do you do with it?
21:28 Chouser: Strings aren't Persistent -- any change requires a complete copy.
21:28 abrooks: Chouser: I know.
21:28 Chouser: that's why conj and assoc shouldn't work.
21:29 abrooks: Chouser: It still would be nice. Otherwise we're just lost in regex land.
21:29 Chouser: into would be inefficient, but (apply str ...) uses a StringBuilder and thus works pretty well.
21:29 abrooks: I forget, are Java strings a reference type?
21:30 Could Clojure build something which looks like a string but is persistent?
21:32 Chouser: I was thinking about something like that for a text editor data structure.
21:33 (defn seek [n s] (= n (last (take-while #(<= % n) s))))
21:34 that returns true in n is in the ordered infinite seq s
21:34 is there a better way?
21:37 this is not better: (defn seek [n [f & r :as s]] (if (< f n) (recur n r) (= f n)))
21:48 mibu: Anyone in here?
21:49 aspect: um yeah
21:49 mibu: Hi.
21:49 I have two small suggestions for features, who do I turn to?
21:51 Chouser: you can air it here or on the google group
21:51 mibu: Ok then. One is multiple pairs on def, similar to setq.
21:52 The other is cleaning up compiler error messages in the repl.
21:52 Thoughts?
21:52 Is there a reason def does not work on pairs?
21:53 Chouser: there are lots of different error messages coming from lots of spots in the code. There's an ongoing effort to improve individual messages as they come up.
21:53 mibu: on multiple pairs?
21:53 Chouser: I don't know setq. Can you give an example of what you want?
21:54 mibu: Re errors, I'm not talking about something fancy. As simple as replacing e.printStackTrace() with if (!(e instanceof Compiler.CompilerException)) e.printStackTrace(); in the main repl loop's catch clause.
21:54 example for multiple pairs is: (def a 1 b 2) to associate a with 1 and b with 2. Looks better on multiple lines.
21:54 Chouser: latest repl only prints the first line of the exception. Is that not what you see?
21:55 mibu: Really? Mine dumps the stack trace. Which version is the latest?
21:55 Chouser: oh, just to avoid (def a 1) (def b 2) ?
21:55 mibu: yeah about the def
21:55 Chouser: latest is always from svn :-)
21:56 mibu: I prefer the latest *stable* release.
21:56 Chouser: there's a link at clojure.org
21:56 mibu: but it's good to know it's in the trunk.
21:56 Is there a release schedule?
21:57 Chouser: ah. latest release is 20080916
21:57 mibu: I've got that release.
21:58 In that release, it still dumps the stack trace, no?
21:58 Chouser: ok. in svn the full exception is kept in *e and by default only the first line is printed.
21:58 yep, that change missed the release by 3 days.
21:59 mibu: Great, it's good to know it'll be in by default in the next release.
21:59 Is there a release schedule?
21:59 Chouser: I don't know of a predicted release date, but I think the next will be called 1.0
22:00 mibu: chouser, do you know if there are plans to expand def to multiple pairs?
22:01 Chouser: nope, not heard that mentioned before.
22:01 abrooks: I thought someone created a "defs" macro at onepoint, perhaps as a lisp paste.
22:02 Chouser: You can make a case for your change on the google group, and see what kind of response you get.
22:02 mibu: It's not a problem making a macro, it'd just be nice to have it built-in.
22:03 Chouser: abrooks: there's declare, but that's not what mibu wants.
22:03 mibu: That kind of small feature is not worth bothering the group about.
22:04 Chouser: it's not going to happen otherwise. You could provide a patch if you want.
22:05 mibu: What you guys use to for dev environment?
22:05 Chouser: there's a pretty wide variety. lots use emacs, a few use netbeans (+ enclojure), I use vim.
22:05 djkthx: emacs
22:05 personally
22:06 after getting used to slime, it's hard to use anything else
22:06 danlarkin: aye, aquamacs
22:06 mibu: I use the emacs with the clojure-mode, is there something better than that around?
22:06 I tried to get slime to work with clojure, but it messed up my config with sbcl.
22:06 djkthx: yeah, i'm wrestling with that right now actually
22:07 mibu: djkthx, I use slime2 and it's a mess. does the cvs version solve some of these problems?
22:08 djkthx: well, i'll let you know in a minute if i get it working :P
22:08 mibu: :-)
22:08 danlarkin: I'm trying to translate this haskell function to clojure but I'm having a brain lapse... satisfy p (x:xs) = [ (xs,x) | p x ]
22:10 I know that between the []'s is a list comprehension, but what is it iterating on?
22:11 or is it not iterating? is it just returning a list of one (or zero) elements?
22:20 mibu: do agents guarantee ordered execution of requests from a single thread?
22:22 Chouser: mibu: I think so.
22:23 "Actions dispatched to an agent from another single agent or thread will occur in the order they were sent, potentially interleaved with actions dispatched to the same agent from other sources."
22:24 mibu: yeah, I just got to that section. premature question.
22:24 Chouser: :-)
22:25 mibu: So, essentially you can use agents instead of producer/consumer queues, in most cases.
22:26 Is there a reason not to?
22:26 Chouser: I think that's fine. You might look at seque.
22:29 mibu: Seque is good only for efficiency issues. From the logic aspect, it's unnecessary, right? Or am I missing something...
22:33 btw chouser, where did you find out about seque? Does it only appear in the API page or is there another section about it?
22:34 Chouser: It's probably only on the api page. I would also recommend reading through boot.clj -- very educational.
22:38 mibu: educational yes, but not informative. If you hadn't told me about it, I wouldn't have found out about it. When I look for something I need, I check the relevant section in the reference, I don't scan every single function.
22:40 boot.clj is kinda hard to read when you're new to clojure. also, much needed comments are very scarce.
22:42 Chouser: not every function fits well in any particular reference page, but I do think we could use some better way to discover functions
22:42 about the best we've got is (find-doc "queue")
22:44 mibu: The hyperspec managed to cram every single function in CL to a category, and it's very helpful when you're checking out a new area you don't know much about.
22:46 Chouser: I could never find functions in CL
22:46 ...for the week or two that I tried.
22:46 mibu: damn, now I think about all the useful functions I haven't discovered yet and possibly written unnecessarily.
22:47 yeah, CL is not very friendly. some say it's policy to exclude mere mortals from programming in it.... ;-)
22:47 Chouser: :-)
22:49 mibu: hey, we can adopt a similar smug policy. want to write in clojure? read the boot.clj. if someone complains about the lack of comments, tell them it's intentional. :-)
22:49 a language can't be a real lisp without the smug attitude of it's followers...
22:50 * duck1123 shouldn't lisp while drunk
22:50 Chouser: yet another way which Clojure is better than lisp. :-)
22:51 duck1123: I've been driving my self nuts trying to figure out why my connection is closed before I get to it
22:51 turns out my parens were in the wrong place
22:55 danlarkin: duck1123: ouch
23:09 djkthx: mibu: i got it all working pretty harmoniously now
23:09 with sbcl/mzscheme/clojure
23:09 if you want me to post my .emacs file
23:09 mibu: what's your .emacs slime section looks like?
23:10 yeah, I'd like that.
23:10 djkthx: yeah, jas
23:11 mibu: http://
23:11 if you were having a problem with progn
23:11 which was the error i was getting
23:11 you just have to prevent certain things from being eval'd when you start slime with clojure instead of common lisp
23:11 mibu: which version of slime you use?
23:12 djkthx: cvs
23:12 the git version on github
23:13 mibu: I want to see if there's a way to make it work with slime2. I have some programs running with swank of that version, and it's a bad idea to mix versions of slime and swank.
23:13 djkthx: ah
23:13 hmm
23:18 mibu: djk, what's slime-fancy?
23:18 duck1123: does anyone know how I can 'let' a local variable in a macro to be made available to forms in the '& body' of the macro?
23:18 I keep getting errors whenever I try
23:19 The only way I've managed to do this is to bind on a global variable like in clojure.contrib.sql
23:21 mibu: djk, thanks for the .emacs, but it seems my problem is not as simple as I thought.
23:21 djkthx: that's too bad =\
23:21 mibu: slime-fancy just adds the nice tab completion and other features
23:21 i was having issue including it
23:22 mibu: right now, clojure-mode does the trick for me. if clojure is as good as it seems, maybe I won't need sbcl and slime anymore.
23:25 danlarkin: oh wow what are the chances... someone already wrote a parser combinator library for clojure, hooray!
23:26 Chouser: duck1123: the called of your macro is passing in the local name to be bound?
23:27 duck1123: I'm basically writing a bunch of with-* macros right now
23:27 I want those macros to make a variable available to the body of those macros
23:28 Chouser: (defmacro let99 [a & body] `(let [~a 99] ~@body))
23:28 duck1123: I'd prefer to not have to specify the name of those variables when calling the macro, but I will if I have to
23:29 Chouser: oh, you want to "capture" the name.
23:29 duck1123: yes
23:29 I want 'a to be available to body
23:30 Chouser: (defmacro let-foo [v & body] `(let [~'foo ~v] ~@body))
23:30 naughty
23:30 duck1123: is that not good form?
23:31 drewc: duck1123: in general, variable capture is a no-no.
23:31 Chouser: in clojure, anyway. arc loves it.
23:31 drewc: entire macro systems have been written in an attempt to avoid even the possibility.
23:32 Chouser: drewc: part of that is attempting to avoid un-intentional capture.
23:32 drewc: arc is a no-no as well... wanton variable capture being among the reasons :)
23:32 Chouser: indeed, and i actually capture variables all the time in CL... but only for internal macros.
23:33 Chouser: intentional capture is less bad, but still -- for example, you may shadow a name the user has been using for a while, forcing them to rename their own variables just to use your macro.
23:33 drewc: exactly. If the macro will be used outside a few select places, best not capture a variable the programmer may be using.
23:34 duck1123: ok the, assuming I want to pass in the name of the var I will use, I get the error: Unable to resolve symbol: resource in this context
23:34 drewc: if it's for hack, or will only be used internally in some module of code and doesn't even make sense outside that context, then go ahead and capture IMO.
23:35 Chouser: duck1123: you're using a pattern like let99 above?
23:36 duck1123: yes
23:36 Chouser: (let99 foo (+ 5 foo))
23:37 duck1123: lisppaste8: url
23:37 lisppaste8: To use the lisppaste bot, visit http://
23:39 duck1123 pasted "Trouble using macros" at http://
23:39 duck1123: the part I'm working on is the with-resource
23:40 and add-statement
23:40 the code is not very clean yet, I'm still working on it
23:45 hmm... maybe I forgot to evaluate something... I'm getting a different error now that I've restarted the repl
23:55 djkthx: so, is there a way to package clojure code into a jar or anything?