#clojure logs

2008-11-06

01:23Carkhello
04:50kib2hi, did someone read the first chapters and is it worth a look ? http://blog.thinkrelevance.com/2008/11/5/clojure-beta-book-available
06:20tomppahmm, 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.
06:24tomppaah damn. It was the Clojure side after.. forgot the laziness part in my benchmark
06:33Lau_of_DKtomppa, garbage ?
06:34tomppaI'm doing some simple performance tests and I get lots of annoying gc pauses
06:34tomppapart of it is probably because of awt but I have tried to factor that out
06:35tomppaI'm just writing the same thing in mzscheme for comparison
07:01tomppaI'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
07:03tomppaany clues on how I could improve the performance? I just have a list of particles [[posx posy] [[velx vely]] that I update and draw
07:19hoecktomppa: can you paste your code?
07:19tomppasure, just a sec
07:20hoecktomppa: there is *warn-on-reflection* and some math primitives
07:22lisppaste8tomppa pasted "Fireworks" at http://paste.lisp.org/display/69811
07:23tomppaI doesn't have all the code, graphics are handled by awt/java2d
07:23tomppa... and it isn't meant to look neat. Just a quick test
07:24Kerris0just found an online Lisp interpreter http://weblisp.net/
07:25tomppaI 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
07:35tomppaif someone wants to try it out here's the jar http://www.yellow-hut.com/blog/wp-content/uploads/fireworks.jar
07:45tomppaokay, when I set -XX:+UseConcMarkSweepGC it works a lot better. Just, umm, what does that flag do
07:47tomppaisn't incremental gc on by default on the client vm?
07:59tomppait seems that none of my extra and classpath args are used when I run clojure-slime
08:01Chouserkib2: 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.
08:10kib2Chouser: thanks, so I'll wait some time and then buy it. See you, I need to go to work :)
08:11tWipI think I'll need to buy them in bulk and sneakily distribute them to my coworkers' desks
08:25jkantzQ on maps... how would I map across a map, returning another map?
08:26jkantzdo I need to write something to do this or is there some built-in way?
08:26rhickeyjkantz: (into {} (map (fn [[k v]] ... [newk newv]) amap))
08:27jkantzthks
08:28rhickeyor: (reduce (fn [m [k v]] ... (assoc m newk newv)) {} amap)
08:29rhickeythe latter will allow you to conditionally add entries
08:39Chouserrhickey: it's nice to have you back.
08:40rhickeyChouser: nice to be back!
08:41gnuvincegood morning
09:22abrooksrhickey: How was tabulating? :)
09:25rhickeyabrooks: it's a lot more than tabulating, but it went well
09:26abrooksrhickey: I figured it was more that tabulating. I should have included a wink.
09:29abrooksrhickey: 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)?
09:29rhickeyhttp://www.exit-poll.net/
09:30rhickeyit's the exit poll that feeds every networks and newspaper - essentially everything you see about voter opinion on election day
09:30abrooksrhickey: Ah, cool. I was going to ask if there was any public information about it. Thanks.
09:39Lau_of_DKrhickey, how do you feel Clojure stacks against something like ATS?
09:43rhickeyLau_of_DK: do you mean this: http://www.cs.bu.edu/~hwxi/ATS/ATS.html
09:49Lau_of_DKyes, although I read about it at www.ats-lang.org
09:49Lau_of_DK@ rhickey
09:51gnuvinceLau_of_DK: what do you mean by "stacks against"?
09:53rhickeyLau_of_DK: never heard of it
09:53Lau_of_DKIm thinking pros/cons. ATS looks very (http://shootout.alioth.debian.org/u64q/benchmark.php?test=all&lang=all) powerful, and like it has some of the same features as Clojure, as in persistant lists
09:56gnuvinceall the ATS programs I've seen on that benchmark are 10x as long as all the other programs.
09:59Chouserseems like a very different language -- staticly typed, compiled, explicit pointer arithmetic, almost certainly no macros.
10:02gnuvinceDefinitely no leveraging existing Java code ;)
10:05Lau_of_DKAlright, thanks :)
10:15rhickeyaccepting proposals for sorted version of set and map literals
10:16Chouseryou want something syntaxy, not just #=(sorted-map 1 2,3 4,5 6)
10:16Chouser?
10:17Chouserit 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:18Chouser#>{:a 1, :b 2} ##>{:x :y :z}
10:38rincewindthe to-do-list mentions: arbitrary symbols in | |
10:40rincewindthere are currently no pipe symbols in the .clj files in trunk i think
10:54rhickeyChouser: yes, not #=(sorted...
10:55rhickeyrincewind: yes, thinking forward to |whatever including spaces| as a symbol
10:56rincewindwhen AOT compilation is available, will LispReader.java be ported to clojure?
10:56rhickeyrincewind: could be, not a top priority though
10:57rhickeyI guess a long-term goal might be a bootstrapped version of Clojure
10:58rhickeybut bootstrapping has its own set of complexities, few of which contribute to productivity
10:59rhickeyChouser: #>{:a 1, :b 2} #>#{:x :y :z} ?
11:00Chouserthese are starting to feel a bit like perl, or maybe regex.
11:01rhickeyyeah
11:01Chouser> is nice, but 3 symbols preceding the { is not so much.
11:01Chouser#> feels ok
11:02Chouser##{:x :y :z} ? less consistent, but fewer chars too
11:02rhickeyI'm not sure sorted literals are that important, and given the new reader extensibility, at least #=(sorted...) will work
11:03rhickeyfor print/read
11:03Chouseractually it doesn't, but I don't understand the new reader enough to know why
11:03Chouser(class #=(sorted-map :a 1, :b 2)) -> #=clojure.lang.PersistentHashMap
11:03rhickeyI do, it's due to compiler interpretation of maps - always yields hash-maps right now
11:03Chouseroh, ok.
11:03rhickeymaps in code are evaluated
11:06rhickeythese things are all connected, for instance, should sorted-maps in code be evaluated too, especially if there isn't literal syntax for them
11:09Chouserah, subtle. #=(sorted-map (keyword "a") 1) vs. {(keyword "a") 1}
11:10Chouser#= is an odd beast that I definitely do not have a feel for yet.
11:10rhickeyChouser: It's not intended for use by humans
11:10Chouserheh
11:12rhickeyfor instance above, there's no reason for #=
11:13ChouserI 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:13Chouseryeah
11:13Chouserskip eval'ing
11:14rhickeyIn CL, vector literals are constants, if you want evaluation you need to backquote
11:14rhickeyIn Clojure, I decided to make vector and map literals be evaluated
11:15rhickeythis has been very convenient, returning [a b] etc
11:19Chouseryes, I agree. It also feels more like python and javascript, which I imagine has eased many people's transitions.
11:19danlarkinChouser: I can vouch for that
11:19rhickeybut it's a basic fact that there can't be syntax for everything
11:20rhickey(sorted-map ...) works fine when you need it
11:21rhickeythe 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:21Chouseryep. And it's nice that #= can help hold back the need for ever more syntax.
11:22rhickeythe idea behind #=(what you would write anyway) is that you'll never be inclined to write #= yourself
11:24rhickeyit's strictly for read/print representation
11:25Chouserso fixing up the compiler such that #=(sorted-map ...) works should be sufficient.
11:25rhickeyfor some definition of works
11:25rhickeyI'm leaning towards unevaluated, as-read
11:26rhickeyconstant
11:26Chouseryeah
11:30rhickeythe other side I'm currently mulling over is whether this print-type-preserving shouldn't be separate from print-readably
11:31Chouserso 3 modes of printing (not including "pretty")?
11:31rhickeyat the repl, I'd like all my maps and sets to look the same
11:32rhickeybut when serializing constants, I need to distinguish precisely
11:34Chouserwould there be any difference for any type other than sorted mapand sorted set?
11:34rhickeysure, array-maps vs hash-maps
11:35rhickeymaybe different sorted sets with different implementations/perf characteristics
11:35Chouserah, array-maps.
11:35Chouserhm.
11:35rhickeygenerally, there will be N implementations
11:35rhickeyI think the repl should be about the abstractions
11:36rhickeythat sort of forces to type-annotated serialized versions
11:37Chouserbut that means this new format really will be just for serialization. Any reason not to hook into Java's serialization at that point?
11:37rhickey#=(java.util.HashMap. {:b 2, :a 1}), #=(clojure.lang.PersistentArrayMap. {:b 2, :a 1})
11:38rhickeyChouser: it's binary, tied to class versions etc
11:39Chouser...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:39Chouseroh, I didn't realize it was binary. bleh.
11:39rhickeythere is JAvaBeans serialization which is text and extensible, if somewhat verbose
11:39rhickeyvery verbose
11:39Chouserthat's xml?
11:39rhickeytoo verbose
11:39rhickeyyeah
11:40Chousercould that be used when there's no print-method though?
11:48rhickeyChouser: 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:51rhickeyKawa had an efficient way to store constants using Externalizable, but not many built-in classes implement that
11:57Chouseryou could base64 the binary serialization. #=(deserialize java.Whatever "...")
11:58Chouseranyway, that's secondary I guess to the core idea of 3 print types
12:02Chouserwould *print-meta* still be optional for the serialize form?
12:02rhickeyno, that's one of the current todos
12:03rhickeythis one is that: http://groups.google.com/group/clojure/msg/c77604094dba3b6c
12:03rhickeymetadata not serialized
12:06Chouserhuh. I couldn't make any sense of that.
12:07Chouserso this might make sense as modes on a linear scale from "undecorated" through "serialization": print, print-readably, readably with meta, and serialize
12:07rhickeybasically the value at the repl gets wrapped in a little fn, which when compiled, serializes the symbol constant, losing its metadata at present
12:08rhickeyChouser: yes, that's one way to look at it
12:09Chouserauto-indentation would still have to be a separate flag
12:28rsynnotthas anyone read this new book?
12:33Chouserrsynnott: I've read the half that's available.
12:33rsynnottI'm vaguely considering buying the PDF
12:34rsynnottthough I'm not sure whether I actually need it; the website was quite useful
12:56gnuvinceChouser: how is it?
12:57duck1123does 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:21danlarkinany better way to make a string of n spaces? (apply str (map (fn [x] \space) (range 4))) n being 4 for this example
13:24Chouserdanlarkin: (apply str (replicate 4 " "))
13:25danlarkinChouser: perfect, thanks
13:26Chousergnuvince: It's easy to read. I think it's the kind of ground-up tutorial a lot of people have been asking for.
13:31gnuvinceChouser: cool
13:31Chouserwe'll see when it's complete if it's also going to be a good reference.
13:51drewrlol. http://twitter.com/dysinger/statuses/993446623
13:52rhickeydrewr: I think he was just interested in distributed concurrency, which Clojure doesn't provide yet
13:58rhickeymade AFn's Comparator.compare work with predicates too, true values sorting first (sort > [1 2 3 4]) no longer needs comparator
14:10AWizzArdWhat are AFn's?
14:10danlarkinAbstract Functions, I assume
14:10danlarkinbut I know what happens when one assumes
14:11danlarkinso perhaps I should have kept my mouth shut
14:12AWizzArdregardless if it stands for Abstract Functions or not: what are Abstract Functions?
14:14wwmorganAFn is the abstract class that all functions inherit from
14:14cemerickrhickey: many thanks for that change to sort. *very* handy
14:21Chouseryeah, pretty.
15:04drewrAny particular reason why finally can't return a value in case a catch clause was invoked?
15:05Chouseryou get the specific catch-clause return value instead, right?
15:06drewrNo, I get a boolean.
15:08Chouserthis returns "c1": (try (throw (Exception.)) (catch Exception e "c1") (finally "f"))
15:12drewrThe 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:14fandahello all!
15:14fandacan I have a question about macros?
15:14Chouserdanlarkin: go for it
15:14Chousersorry
15:14Chouserfanda: go for it :-)
15:14danlarkinChouser: :-o
15:14fandai would like to create a macro 'mac
15:14fanda(mac (run-mac 1 2) (do-not-run-fn 1 2))
15:15fandawhen called like this, if expands run-mac macro
15:15fandabut it does not expand/run do-not-run-fn
15:15fandaa returns a list with results
15:16fanda(list expanded-expression-from-run-mac (do-not-run-fn 1 2))
15:16fandarun-mac is a constant name - not any macro
15:17Chouseryou want the raw symbol list '(do-not-run-fn 1 2) in your result list?
15:17fandayes
15:18Chouser(defmacro mac [a b] `(list ~a '~b))
15:18rhickeydrewr: finally is for cleanup side-effects, it runs even when the (returning) body succeeds, so can't define return
15:19fandathanks Chouser, let me try it, if that is what I need
15:28drewrrhickey: AH, good point.
15:30fandaChouser: still not there, I give you the concrete example of what I am trying to do
15:30fanda(defmacro equal-pairs [& expr] (map #(cons '= %) (partition 2 expr)))
15:30fandauser=> (macroexpand '(equal-pairs 1 1 2 2 1 4))
15:30fanda((= 1 1) (= 2 2) (= 1 4))
15:32fandanow I want to create a macro: (check (equal-pairs 1 1 2 2 1 4) (= 5 5) (= (+ 1 2) 3))
15:32fandawhich returns for the start this: '((= 1 1) (= 2 2) (= 1 4) (= 5 5) (= (+ 1 2) 3))
15:33fandait 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:34fandamore advanced version of macro 'check returns a list of (expression result) '(((= 1 1) true) ((= 2 2) true) ((= 1 4) false) ...)
15:34Chouseryou want "check" to be explicitly aware of the "equal-pairs" and treat it differently from "="?
15:34fandayes, exactly
15:35Chouserfirst of all, I think think there's any need for equal-pairs to be a macro
15:36Chouserbah. I mean I equal-pairs can be a fn
15:37fandano, I need to keep both - non-evaluated parameters and evaluated ones
15:37fandauser=> (macroexpand '(equal-pairs (+) 0 (+ 1) 1 (+ 1 2) 3))
15:37fanda((= (+) 0) (= (+ 1) 1) (= (+ 1 2) 3))
15:39fandaotherwise, I would have to quote everything - '(+) '(+ 1) ...
15:41rhickeyfanda: do you need equal-pairs on its own? can it just be syntax of check?
15:41Chouser(defmacro check [& s] (cons `list (map #(if (= (first %) 'equal-pairs) % `(quote ~%)) s)))
15:41Chouserbut you should listen to rhickey :-)
15:42Chouseroh, that's not right. sorry.
15:43rhickeyChouser: he shouldn't listen to me?
15:43rhickey:)
15:43AWizzArdI think he meant the macro
15:44fandajust a second guys...
15:46Chouserrhickey: that's right, you got a problem with that?
15:51Chouser(defmacro check [& s] `'(~@(mapcat #(if (= (first %) :equal-pairs) (for [p (partition 2 (rest %))] (cons '= p)) [%]) s)))
15:51Chouserwwwwwuser=> (check (:equal-pairs 1 1 2 2 1 4) (= 5 5) (= (+ 1 2) 3))
15:51Chouser((= 1 1) (= 2 2) (= 1 4) (= 5 5) (= (+ 1 2) 3))
15:53Chouseror for your original syntax: (defmacro check [& s] `'(~@(mapcat #(if (= (first %) 'equal-pairs) (macroexpand %) [%]) s)))
15:54Chouserbut that's kinda weird because the equal-pairs macro doesn't really work on its own.
15:54fandayes, it doesn't have to work on its own...
16:12jgracinrhickey: rich, could you please verify memfn definition. it seems to me that ~@args should not go into the arglist of lambda form.
16:19fandathanks guys for help!
16:19fandahaving phone calls and stuff to do...
16:19fandagreatly appreciate your help!
16:42rhickeyjgracin: methods aren't variadic - the args to memfn are names used to make a specific-arity call
16:46jgracinrhickey: Should this work: (filter (memfn endsWith ".clj") ["a.clj" "b.java"]) ?
16:46jgracinit doesn't seem to.
16:46rhickeyjgracin: no, it's not partial binding
16:53jgracinok, got it. thanks.
16:54rhickeyjgracin: I see how the docs could use clarification
16:58Chouserjgracin: memfn is hardly ever worth it. #(.endsWith % ".clj")
16:59jgracinChouser: that's what I went back to. (memfn endsWith ".clj") seemed nice, though.
17:00rhickeyChouser: right, it predates #()
17:19ChouserI've got a bunch of old projecteuler code that uses "thisfn"
17:19Chouserit also uses "true" instead of ":else" in conds
17:26danlarkinChouser: http://blog.danlarkin.org/2008/11/apply-is-lazy-and-i-was-wrong/
17:42Chouserdanlarkin: :-) thanks
17:53Chouserset and sorted-set are different arities!?
17:54wwmorganChouser: you're looking for hash-set I think
17:54Chouserhm.
17:55Chousergood point.
18:20blackdogis 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:21rhickeyblackdog: sure, but people choose lower case because upper is annoying, so if you have a choice...
18:21blackdogoh ok :)
18:21rhickeyconvention is Java is also all-lower for packages
18:22rhickeyin Java
18:32AWizzArdDoes the jvm support something like "green threads", some very lightweight threads?
18:39danlarkinAWizzArd: I don't believe so, but I think if you use a thread pool the effect is somewhat similar
19:00AWizzArdrhickey: do you see reader macros for users coming in 2009?
19:06ChousukeI haven't seen anyone present a really good argument for user-definable reader macros :/
19:09AWizzArdChousuke: 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:10ChousukeWell, you can define syntax with regular macros; though I can see the usefulness of reader macros if you *really* need something a lot.
19:11AWizzArdChousuke: and reader macros just look better for some stuff. Just think about #(foo 1 2 3) vs (# foo 1 2 3)
19:11AWizzArdThis is: reader macro vs macro
19:12Chousukewell, yeah, but that's quite a small difference.
19:12Chousukethe problem that reader macros are prone to name clashes should be somehow solved first.
19:13AWizzArdI don't agree. This difference is so huge that Rich luckily decided to implement it as a reader macro.
19:13ChousukeWell, in this case yes.
19:14Chousukeas anonymous functions are quite common.
19:14AWizzArdYes
19:14AWizzArdBut currently I can't implement fully featured currying support, which would even more commonly used in Clojure
19:15Chousukefully featured?
19:15AWizzArdyes
19:15AWizzArdClojure has no currying support, but instead #(..) which comes already close
19:15Chousukeclojure has partial though
19:16AWizzArdYes, but this makes not much sense in my opinion
19:16AWizzArdCurrying is syntactic sugar
19:16AWizzArdit's about brevity
19:16AWizzArdCurrying makes imo only sense when implemented as a reader macro
19:16gnuvince1As 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:16AWizzArd(map $(* 3) mylist)
19:16gnuvince1It's almost backwards Factor code.
19:17gnuvince1Where you need to remember what a function takes and what it returns
19:17AWizzArdgnuvince1: in fact currying makes code *easier*. That's why Rich implemented something like #(..) in the first place, which already comes close.
19:17gnuvince1AWizzArd: the difference is that with #(...) you must be explicit about arguments
19:18AWizzArdand I am not talking about implicit currying, but explicit one
19:18gnuvince1(map #(* 3 %) my-list) reads bery easily.
19:18gnuvince1*very
19:18ChousukeAWizzArd: that's not much of an improvement over (map #(* 3 %) sequence)
19:19AWizzArdand (map !(* 3) my-list) reads even better, and (map !(rgb _ 255) colors) is also better than (map #(rgb %1 255 %&) colors
19:20gnuvince1How does the first example read better?
19:20AWizzArdbecause it says: multiply with 3
19:20gnuvince1So do ours.
19:21AWizzArdhow does #(* 3 %) read better than (fn [x] (* 3 x))
19:21ChousukeIf you ask me !(rgb _ 255) looks really confusing
19:21AWizzArdI can read both perfectly and understand them very well
19:21AWizzArdhow can look #(rgb _ 255 %&) *non-confusing* to someone new to Clojure?
19:21ChousukeAWizzArd: #() doesn't have a superfluous name ("x") in the code
19:22AWizzArdChousuke: but it has a superflous % in the code
19:22Chousukeit's not superfluous
19:22Chousukeit's the placeholder
19:22AWizzArdthe x in fn also not
19:22Chousukeit's not a name, it's just %
19:22AWizzArdx is not a name, it is just a placeholder too
19:23Chousukebut x is a name.
19:23AWizzArdboth are either names or placeholders
19:23Chousuke% is part of the syntax of #()
19:23AWizzArdright
19:23AWizzArdbut it is superflous
19:23gnuvince_But it *does* help with shouwing explicitly what parameters a function takes
19:23AWizzArd(* 3) is a problem, I agree, as this would be implicit currying
19:24gnuvince_and !(* 3) is a nice example
19:24gnuvince_let's do something different
19:24gnuvince_subtract 3
19:24gnuvince_(map #(- % 3) coll)
19:24AWizzArdgnuvince_: how does #(* 3 %&) show explicitly what parameters * takes?
19:24ChousukeAWizzArd: again, once one knows the syntax for #(), it's clear
19:24AWizzArd(map !(- _ 3) coll)
19:25AWizzArdChousuke: same with the syntax for !(...)
19:25gnuvince_AWizzArd: how is that better than the syntactic sugar for fns?
19:25ChousukeAWizzArd: but what about (map !(- 3) coll)
19:25AWizzArdor whatever the symbol might be
19:25ChousukeAWizzArd: shouldn't that be possible too, since !(* 3) is?
19:25gnuvince_Chousuke: with subtraction, order matters
19:25Chousukegnuvince_: yeah, I know, and that's the problem
19:25gnuvince_3 * 4 == 4 * 3; 3 - 4 != 4 - 3
19:25AWizzArdChousuke: !(- 3) ==> #(- 3 %&)
19:26gnuvince_Anyway, I think we're talking in circles here
19:26ChousukeAWizzArd: the latter is better in this case.
19:26gnuvince_Since it *should* be a library, it wouldn't matter much to me
19:26AWizzArdthe better is !(...)
19:26gnuvince_I would never use it, but if AWizzArd wants to, his choice.
19:26gnuvince_That's the beauty of having extensible languages
19:26AWizzArdchances are you would use it all the time
19:26gnuvince_libraries can "modify" the language
19:27Chousuke! is not a very good macro character for your currying though.
19:27AWizzArdChousuke: I don't care for the character.. see it as a placeholder for the real thing, whatever that might be
19:27AWizzArdit could be a ! or $ or & or % or ~ or | or whatever
19:28Chousukebut I don't see how !(- 3) or !(rgb _ 255) are better than the explicit alternatives, really.
19:28Chousukeall they do is hide things.
19:28Chousukethat should be visible.
19:28AWizzArdbut that is the only reason why currying exists
19:28AWizzArdit is pure syntactic sugar
19:28AWizzArdand if it should be visible one can use (fn [x] ...)
19:28Chousukebut #() provides us with enough syntactic sugar already
19:29Chousuke(fn [x] ...) is too verbose; the benefit gained from #() is greater than the benefit of !() compared to the already existing #()
19:29AWizzArd#(foo %1 %2 %3 "hallo" %4 -100 %&) vs ~(foo _ _ _ "hallo" _ -100)
19:29Chousukeyeah
19:29ChousukeI'd take the former.
19:29rhickeyClojure doesn't allow user-defined reader macros because they can't be combined - there's no namespace support, unlike for regular macros
19:30rhickeybut the case for more currying support is very weak
19:30Chousukethe latter does look really nice but it doesn't allow easy changing of parameter order for example
19:31AWizzArdChousuke: yes, the benefit is greater from (fn [..] ..) to #(...), but it also misses some features
19:31rhickeyso you'll probably have to come to grips with that's how Clojure works
19:31AWizzArdChousuke: you could also say ~(* %1 %1)
19:32Chousukeand would that take an automatic "rest" parameter or not? it's pretty confusing :/
19:32AWizzArdrhickey: so probably there won't be reader macros any time?
19:33AWizzArdChousuke: it is not confusing at all if you would read (in the case currying was present) the then existing manual for 5 minutes
19:33Chousukeyeah but it looks like a #(* %1 %1)
19:34rhickeyAWizzArd: not in the plans as of yet
19:34Chousukewhich is different.
19:34AWizzArdChousuke: yes, that's right
19:34AWizzArdChousuke: 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:34AWizzArd(under the hood I mean)
19:35rhickeythe clash problem is significant - I don't want libraries that can't be combined. Macros work, user-defined reader macros don't
19:36AWizzArdMaybe one could enforce user-defined reader macros need some explicit "turning on" and "turning off"?
19:36AWizzArd(activate-infix-math)
19:36ChouserWhat about namespaced reader macros, like (chouser/regex .*$)
19:37AWizzArdand then you can say: (print ~[4x?-14]) or something like that
19:37Chouserlots of people who want reader macros might not be satisfied with that, but it would certainly grant some power.
19:37rhickeyChouser: how does that work?
19:38duck1123as 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:38rhickeyAWizzArd: CL has user reader macros and the consensus is to avoid them
19:38rhickeyduck1123: exactly
19:38AWizzArdsure, abosolutely, in 99% of all cases
19:38duck1123it's bad enough with the few that we have now (for a new user)
19:39Chouserat 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:39gnuvince_Is there demand for an infix arithmetic library?
19:39AWizzArdgnuvince_: yes
19:39Chousukemaybe 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:40rhickeyChouser: the issue isn;t how to implement user macros, but what happens when you have two libraries that define $ ?
19:40AWizzArdrhickey: so let's enforce to activate and deactivate them
19:40rhickeygnuvince: no
19:40Chousukethat might result in some mismatching conventions though, so you could have pieces of code that look similar but do some very different things
19:40rhickeyAWizzArd: you are unlikely to convince me they are a good idea
19:41AWizzArd(Well, if only one person asks for infix arithmetic from this moment on there is demand.)
19:41Chouserrhickey: the reader macro in my example is a function named regex in the chouser namespace. Existing namespace resolution and collision rules would apply.
19:41rhickeyChouser: so how do you use it?
19:42AWizzArdrhickey: 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:42Chouserit looks like a function or macro call, but it's actually a reader-macro call.
19:42rhickeyChouser: I don't see the point then
19:42rhickeydoesn't allow for syntax that regular macros don't
19:43Chouserit would allow you to have non-valid-symbol stuff inside the parens. like literal regex chars, or SQL code or something.
19:44ChouserLispReader, 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:44rhickeyChouser: ah, sort of an escape area
19:44Chouseryes
19:45rhickeyI don't like it :)
19:45Chouserheh. ok.
19:45Chouserbiab.
19:47rhickeyAWizzArd: I'd rather there be a consensus of need for something and add it in a way that everyone can use
19:47AWizzArdyes
19:49AWizzArdof course, every decision comes with its own advantages and disadvantages
19:51rhickeyAWizzArd: 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:52rhickeyspeaking a common language fosters library development, shared idioms etc. When everyone creates their own language there's less of that
19:53AWizzArdAnd I agree and think this is a good thing. Ironically reducing the amount of flexibility a little bit can have positive effects here.
19:53rhickeyand even standard reader macros pose an understanding challenge for newcomers
19:54Chouseresp. weird ones like #+ and #-
19:54Chouser:-)
19:55AWizzArdWell, 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:55rhickeyChouser: coming soon :)
19:56AWizzArdconcentrating on things that medicore to experts users like/want/need can be a good thing
19:56AWizzArdInstead of beeing nice to newcomers from the language side we need to write tons of examples and tutorials.
19:57AWizzArdI will see if I can do that for some german newcomers
19:57rhickeyprint-replica, print-clone(r) ???
19:58Chouser(set! *print-detail* :serialize)
19:58rhickeyChouser: talking about multimethod name
19:58Chouserserialize?
19:59rhickeyserialize is out, not a good name at all IMO, I think driven by flattening graph notion, but weak
19:59Chouserthe opposize of "read" is often "write"
19:59Chouseropposite
19:59AWizzArd(print-readable ...) maybe
19:59AWizzArdreadably
20:00ChouserAWizzArd: that would mean something different
20:00rhickeyunfortunately you can print to something readable that doesn't read as an identical copy, as happens now
20:00AWizzArdic
20:00rhickeythis is a stronger notion
20:00Chouserunless we change what is now *print-readably* to be named print-for-repl or something.
20:01rhickeyit's really print-replicator, but that's a mouthful
20:01Chouserprint-clone's not bad.
20:01rhickeyclone is so sci-fi though
20:02Chouserwhat get's printed is not the original, so there's not much need for the "-r"
20:02rhickeybut short, and people get clone
20:02AWizzArdreduplicate
20:02Chouserooh, print-dup
20:02rhickeyChouser: but it creates the clone when read back, the printed version is not itself a clone
20:03AWizzArd(print-twin ...) :-)
20:03rhickeynice - leave out enough letters and you can interpret it in many ways
20:04rhickeyprint-dup(licator)
20:05AWizzArdprint-genes
20:06rhickeyprint-dup wins - thanks Chouser !
20:07Chouserjust riffing on AWizzArd :-)
20:11AWizzArdwithout trying this in the repl, what result do you expect? ((symbol "+") 4 10) ==> ?
20:11duck1123error
20:11Chousercan't cast Symbol to IFn
20:12rhickeySymbol's are IFns, like keywords
20:12AWizzArdI thought: either error or 14.
20:12rhickey10
20:12AWizzArdyes :-)
20:12AWizzArdbut why?
20:12Chouserrhickey: nobody's impressed. ;-)
20:12rhickeylook up the symbol + in 4, if not found return 10
20:13Chouser4 not being a collection doesn't bother it?
20:14Chouserhm. (get 4 '+ 10)
20:14rhickeyChouser: no, get was generalized a while back
20:14AWizzArdfrom get I would not expect errors
20:15AWizzArdbut (nth 4 '+) instead should be an error
20:15ChouserAWizzArd: I bet you didn't get very far though -- this is a not a deep or hidden error, is it?
20:16AWizzArdI was just playing in the repl, so, not deep at all ;-)
20:16AWizzArd((symbol "+") {'+ 8 :a 13} 100) ==> 8
20:17rhickeySymbols were made to do self-lookup like keywords a while back, so they have parity for that use, with slightly different ns defaults
20:18rhickeyalso symbols used as keys can have metadata
20:18AWizzArdHow can one get somthing like (symbol-function '+)?
20:18Chouserresolve
20:18AWizzArdthx
20:19AWizzArdn8 n8
20:33ChouserI often use (apply X (map Y ...)) instead of reduce so that I can use #() for Y without the ugly %1 and %2
20:33ChouserI don't know if that's a defensible reason.
20:34rhickeyChouser: probably not
20:35rhickeywhat's an example?
20:38Chouser(apply + (map #(- (int %) 64) word))
20:39rhickeyvs?
20:40Chouser(reduce #(+ %1 (- (int %2) 64)) 0 word)
20:40Chouser(reduce (fn [a b] (+ a (- (int b) 64))) 0 word)
20:40rhickeyyou can say % instead of %1 there
20:40rhickeyleaves only one ugly
20:40Chouserhm, didn't know that.
20:41rhickeybut 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:42Chouserhm...
20:43rhickeyhttp://okmij.org/ftp/Haskell/Iteratee/DEFUN08-talk-notes.pdf
20:45Chouser91 slides?
20:45gnuvince_Chouser: that's Oleg for you
20:46gnuvince_91 slides of stuff that's gonna blow your brains out completely and make you wonder if you really know anything about programmming
20:47rhickeyr you could just wait for the Clojure version, after AOT
20:48rhickeythe idea is good, and I've got it mostly worked out for Clojure, in my head
20:50rhickeybasically 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:50rhickeyso can read multiple items per step
20:51rhickeybased around a new abstraction, an io, like a generating function, new value every time called
20:51rhickeybut threadsafe, unlike iterators
20:52rhickeystill working on EOS/EIO protocol
20:53rhickeyso you'll be able to reduce files/sockets/queues, blocking or non, resources always cleaned up
20:53drewcvery cool!
20:54danlarkinrhickey: you're too smart for me :-o
20:54rhickeythe Haskell guys came up with the core idea, Clojure won't be exactly the same of course
20:55rhickeythey have the same resource management problems with lazy IO as we've seen
20:56rhickeyClojure version should be about 3 slides
20:56rhickey:)
20:56abrooksHeh. Naturally.
20:56drewc"Lazy IO in serious, server-side programming is unprofessional" he says :)
20:57danlarkindestructuring works with strings too, hoorah!
20:57rhickeyan 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:59abrooksrhickey: Have you given any thought to a limited eager seq wrapper? Something to gobble, say, N at a time?
21:00abrooksThat would be more like buffering.
21:00rhickeyabrooks: partition?
21:00abrooksSure but partition alters the structure of the seq, right?
21:01abrooksI'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:01Chouserabrooks: there's also seque
21:02abrooksOh.. wait.. brain cells clicking... deja vu..
21:03abrooksseque is very, very close to what I was thinking of. Probably because I'VE BEEN HERE BEFORE... :-}
21:05danlarkinOT but deja vu totally freaks me out
21:07abrooksI just chalk it up to by brain failing miserably. Nothing freaky about that. Just annoying. :)
21:10drewci 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:10drewcdeja-vu described as*
21:19danlarkinso I guess that (take 2 "abcd") == (\a \b) and (\a \b) != "ab" is just the way it is?
21:19danlarkinI 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:21djkthxare there default paths LOAD-FILE looks in?
21:21djkthxif so, how can i change/add to it?
21:22gnuvince_danlarkin: into?
21:24abrooksStrings really aren't collections though they're seq-able. There's no (empty "abc") or (into "" \a \b \c)
21:24abrooksIt would be nice though.
21:25gnuvince_hmmm
21:25gnuvince_I thought it did
21:25gnuvince_Sadness :(
21:25abrooksTruly. If only there were someone in this channel who could fix it...
21:26Chousermost collections are not themselves seqs. (take 2 [1 2 3]) doesn't return a vector
21:27abrooksChouser: I know. But a string is somewhat like a collection and into/empty/etc. would be nice.
21:28abrooksIt's easy to break up a string (last "asdf") (rest "asdf") (first "asfd"), etc. Now what do you do with it?
21:28ChouserStrings aren't Persistent -- any change requires a complete copy.
21:28abrooksChouser: I know.
21:28Chouserthat's why conj and assoc shouldn't work.
21:29abrooksChouser: It still would be nice. Otherwise we're just lost in regex land.
21:29Chouserinto would be inefficient, but (apply str ...) uses a StringBuilder and thus works pretty well.
21:29abrooksI forget, are Java strings a reference type?
21:30abrooksCould Clojure build something which looks like a string but is persistent?
21:32ChouserI was thinking about something like that for a text editor data structure.
21:33Chouser(defn seek [n s] (= n (last (take-while #(<= % n) s))))
21:34Chouserthat returns true in n is in the ordered infinite seq s
21:34Chouseris there a better way?
21:37Chouserthis is not better: (defn seek [n [f & r :as s]] (if (< f n) (recur n r) (= f n)))
21:48mibuAnyone in here?
21:49aspectum yeah
21:49mibuHi.
21:49mibuI have two small suggestions for features, who do I turn to?
21:51Chouseryou can air it here or on the google group
21:51mibuOk then. One is multiple pairs on def, similar to setq.
21:52mibuThe other is cleaning up compiler error messages in the repl.
21:52mibuThoughts?
21:52mibuIs there a reason def does not work on pairs?
21:53Chouserthere 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:53mibuon multiple pairs?
21:53ChouserI don't know setq. Can you give an example of what you want?
21:54mibuRe 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:54mibuexample for multiple pairs is: (def a 1 b 2) to associate a with 1 and b with 2. Looks better on multiple lines.
21:54Chouserlatest repl only prints the first line of the exception. Is that not what you see?
21:55mibuReally? Mine dumps the stack trace. Which version is the latest?
21:55Chouseroh, just to avoid (def a 1) (def b 2) ?
21:55mibuyeah about the def
21:55Chouserlatest is always from svn :-)
21:56mibuI prefer the latest *stable* release.
21:56Chouserthere's a link at clojure.org
21:56mibubut it's good to know it's in the trunk.
21:56mibuIs there a release schedule?
21:57Chouserah. latest release is 20080916
21:57mibuI've got that release.
21:58mibuIn that release, it still dumps the stack trace, no?
21:58Chouserok. in svn the full exception is kept in *e and by default only the first line is printed.
21:58Chouseryep, that change missed the release by 3 days.
21:59mibuGreat, it's good to know it'll be in by default in the next release.
21:59mibuIs there a release schedule?
21:59ChouserI don't know of a predicted release date, but I think the next will be called 1.0
22:00mibuchouser, do you know if there are plans to expand def to multiple pairs?
22:01Chousernope, not heard that mentioned before.
22:01abrooksI thought someone created a "defs" macro at onepoint, perhaps as a lisp paste.
22:02ChouserYou can make a case for your change on the google group, and see what kind of response you get.
22:02mibuIt's not a problem making a macro, it'd just be nice to have it built-in.
22:03Chouserabrooks: there's declare, but that's not what mibu wants.
22:03mibuThat kind of small feature is not worth bothering the group about.
22:04Chouserit's not going to happen otherwise. You could provide a patch if you want.
22:05mibuWhat you guys use to for dev environment?
22:05Chouserthere's a pretty wide variety. lots use emacs, a few use netbeans (+ enclojure), I use vim.
22:05djkthxemacs
22:05djkthxpersonally
22:06djkthxafter getting used to slime, it's hard to use anything else
22:06danlarkinaye, aquamacs
22:06mibuI use the emacs with the clojure-mode, is there something better than that around?
22:06mibuI tried to get slime to work with clojure, but it messed up my config with sbcl.
22:06djkthxyeah, i'm wrestling with that right now actually
22:07mibudjkthx, I use slime2 and it's a mess. does the cvs version solve some of these problems?
22:08djkthxwell, i'll let you know in a minute if i get it working :P
22:08mibu:-)
22:08danlarkinI'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:10danlarkinI know that between the []'s is a list comprehension, but what is it iterating on?
22:11danlarkinor is it not iterating? is it just returning a list of one (or zero) elements?
22:20mibudo agents guarantee ordered execution of requests from a single thread?
22:22Chousermibu: I think so.
22:23Chouser"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:24mibuyeah, I just got to that section. premature question.
22:24Chouser:-)
22:25mibuSo, essentially you can use agents instead of producer/consumer queues, in most cases.
22:26mibuIs there a reason not to?
22:26ChouserI think that's fine. You might look at seque.
22:29mibuSeque is good only for efficiency issues. From the logic aspect, it's unnecessary, right? Or am I missing something...
22:33mibubtw chouser, where did you find out about seque? Does it only appear in the API page or is there another section about it?
22:34ChouserIt's probably only on the api page. I would also recommend reading through boot.clj -- very educational.
22:38mibueducational 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:40mibuboot.clj is kinda hard to read when you're new to clojure. also, much needed comments are very scarce.
22:42Chousernot every function fits well in any particular reference page, but I do think we could use some better way to discover functions
22:42Chouserabout the best we've got is (find-doc "queue")
22:44mibuThe 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:46ChouserI could never find functions in CL
22:46Chouser...for the week or two that I tried.
22:46mibudamn, now I think about all the useful functions I haven't discovered yet and possibly written unnecessarily.
22:47mibuyeah, CL is not very friendly. some say it's policy to exclude mere mortals from programming in it.... ;-)
22:47Chouser:-)
22:49mibuhey, 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:49mibua language can't be a real lisp without the smug attitude of it's followers...
22:50Chouseryet another way which Clojure is better than lisp. :-)
22:51duck1123I've been driving my self nuts trying to figure out why my connection is closed before I get to it
22:51duck1123turns out my parens were in the wrong place
22:55danlarkinduck1123: ouch
23:09djkthxmibu: i got it all working pretty harmoniously now
23:09djkthxwith sbcl/mzscheme/clojure
23:09djkthxif you want me to post my .emacs file
23:09mibuwhat's your .emacs slime section looks like?
23:10mibuyeah, I'd like that.
23:10djkthxyeah, jas
23:11djkthxmibu: http://pastebin.com/m5854a0fa
23:11djkthxif you were having a problem with progn
23:11djkthxwhich was the error i was getting
23:11djkthxyou just have to prevent certain things from being eval'd when you start slime with clojure instead of common lisp
23:11mibuwhich version of slime you use?
23:12djkthxcvs
23:12djkthxthe git version on github
23:13mibuI 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:13djkthxah
23:13djkthxhmm
23:18mibudjk, what's slime-fancy?
23:18duck1123does 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:18duck1123I keep getting errors whenever I try
23:19duck1123The only way I've managed to do this is to bind on a global variable like in clojure.contrib.sql
23:21mibudjk, thanks for the .emacs, but it seems my problem is not as simple as I thought.
23:21djkthxthat's too bad =\
23:21djkthxmibu: slime-fancy just adds the nice tab completion and other features
23:21djkthxi was having issue including it
23:22miburight 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:25danlarkinoh wow what are the chances... someone already wrote a parser combinator library for clojure, hooray!
23:26Chouserduck1123: the called of your macro is passing in the local name to be bound?
23:27duck1123I'm basically writing a bunch of with-* macros right now
23:27duck1123I want those macros to make a variable available to the body of those macros
23:28Chouser(defmacro let99 [a & body] `(let [~a 99] ~@body))
23:28duck1123I'd prefer to not have to specify the name of those variables when calling the macro, but I will if I have to
23:29Chouseroh, you want to "capture" the name.
23:29duck1123yes
23:29duck1123I want 'a to be available to body
23:30Chouser(defmacro let-foo [v & body] `(let [~'foo ~v] ~@body))
23:30Chousernaughty
23:30duck1123is that not good form?
23:31drewcduck1123: in general, variable capture is a no-no.
23:31Chouserin clojure, anyway. arc loves it.
23:31drewcentire macro systems have been written in an attempt to avoid even the possibility.
23:32Chouserdrewc: part of that is attempting to avoid un-intentional capture.
23:32drewcarc is a no-no as well... wanton variable capture being among the reasons :)
23:32drewcChouser: indeed, and i actually capture variables all the time in CL... but only for internal macros.
23:33Chouserintentional 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:33drewcexactly. If the macro will be used outside a few select places, best not capture a variable the programmer may be using.
23:34duck1123ok 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:34drewcif 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:35Chouserduck1123: you're using a pattern like let99 above?
23:36duck1123yes
23:36Chouser(let99 foo (+ 5 foo))
23:37duck1123lisppaste8: url
23:37lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
23:39lisppaste8duck1123 pasted "Trouble using macros" at http://paste.lisp.org/display/69887
23:39duck1123the part I'm working on is the with-resource
23:40duck1123and add-statement
23:40duck1123the code is not very clean yet, I'm still working on it
23:45duck1123hmm... maybe I forgot to evaluate something... I'm getting a different error now that I've restarted the repl
23:55djkthxso, is there a way to package clojure code into a jar or anything?