#clojure log - Apr 04 2008

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

3:17 cgrand: chouser: I put ClojureServlet.war in the group's file section.

9:45 Chouser: cgrand: thanks!

10:00 cgrand: chouser: rich was right about minimalism, even binding *out* to the response's writer is bad (it commits the encoding...)

10:00 Chouser: Hm.

10:01 rhickey: cgrand: thanks for posting that, perhaps a message in the group too...

10:01 I was just looking at the source, yes, it could do a lot less. The easy-mode stuff could happen in Clojure

10:02 cgrand: rhickey: easy-mode was added as an efter-thought (when I realized that I had already paint myself in a corner with binding *out*)

10:03 rhickey: easy-dispatch?

10:05 cgrand: rhickey: checking which of easy-dispatch or dispatch is set to reduce the need to modifiy web.xml?

10:10 rhickey: what I imagine is that people take Clojure (once it has the stub), modify web.xml to point to their dispatch function, and go. easy-dispatch is something they can use in their dispatch function. A library supplying stream binding, url decoding and dispatch could come with a web.xml pre-configured?

10:11 Chouser: What does "Bad version number in .class file" mean?

10:12 cgrand: chouser: I compiled with JDK 6...

10:12 rhickey: using something built for one version of Java with a different (previous) version

10:12 Chouser: ok

10:13 rhickey: cgrand: you could still target Java 1.5 with that

10:16 cgrand: rhickey: I know I had set them but apparently to no avail. Still, the project properties page says: "Compiler compliance level 5.0" and "generated .class files compatibility: 5.0". ..

10:17 rhickey: ok I remove features from ClojureServlet

10:20 rhickey: cgrand: A minimal version would be a welcome addition to Clojure. I think the one question I have is about where scripts go - hardwiring to / (e.g. loadResourceScript) seems rigid

10:23 cgrand: rhichey: it's juste the "boot" script of the webapp whose location is somewhat rigid. Once in the webapp's bootscript the user can call load to source any script. No ?

10:23 rhickey: cgrand: if you do Symbol.intern(dispatchFunctionName) it will pluck out the ns/name for you

10:25 cgrand: rhickey: thanks

10:26 rhickey: cgrand: yeah, I see, that's fine, as long as they don't have to rebuild clojure.jar, but I see the boot clj is in the war/classes

10:27 i.e. web boot script

10:28 Chouser: cgrand: I have it running in my tomcat server. Thanks!

10:29 cgrand: chouser: you're welcome

10:29 * rhickey wondering when Chouser will start liking servlets :)

10:30 Chouser: not yet!

10:30 ;-)

10:31 When I can run them on my DreamHost server, then I can start thinkging about liking them.

10:33 I used that class inheritence chart yesterday to determine that I wanted to be using sequential? instead of coll?

11:19 nsinghal_: rich i am trying to do the remote repl and getting parse error from read

11:19 java.lang.Exception: ReaderError:(22,1) No value supplied for key: Equality. Returns true if obj1 equals obj2, false if not. Same as

11:19 Java obj1.equals(obj2) except it also works for nil, and compares

11:19 numbers in a type-independent manner. Clojure's immutable data

11:19 structures define equals() (and thus =) as a value, not an identity,

11:19 comparison.

11:19 at clojure.lang.LispReader.read(LispReader.java:158)

11:20 at clojure.fns.clojure.read__425.invoke(boot.clj:1371)

11:36 rhickey_: nsinghal: you are reading a mal-formed map

11:43 nsinghal_: I have this functions

11:43 defn get-syms [ns]

11:43 (loop [syms (sort-by key (ns-publics ns))

11:43 ret (sorted-map)]

11:43 (let [sym (first syms)]

11:43 (if sym

11:43 (recur (rest syms)

11:43 (assoc ret (str (key sym)) (dissoc ^(val sym) :arglists :name :ns)))

11:43 ret))))

11:43 (defn get-tree []

11:43 (loop [nss (sort-by ns-name (all-ns))

11:43 ret (sorted-map)]

11:43 (let [ns (first nss)]

11:44 (if ns

11:44 (recur (rest nss)

11:44 (assoc ret (str (ns-name ns)) (get-syms ns)))

11:44 ret))))

11:44 f i change the (get-tree) function to use (take 2 (all-ns)) instead of (all-ns) then it works and i get back an object from the read. In the (take 2 ), I am not getting the clojure namespace and hence it must be working.

11:44 when i read after the parsing error i am getting the rest of the string as follows

11:45 , "==" {:file "boot.clj", :line 530, :doc "Returns non-nil if nums all have the same value, otherwise false"}, ">" {:file "boot.clj", :line 506, :doc "Returns non-nil if nums are in monotonically decreasing order,\n otherwise false."}, ">=" {:file "boot.clj", :line 518, :doc "Returns non-nil if nums are in monotonically non-increasing order,\n otherwise false."}, "accessor" {:file "boot.clj", :line 1643, :doc "Returns a fn that, give

11:45 rhickey_: ns: this is too much code for here, use http://paste.lisp.org/ or something

11:46 nsinghal_: let me try that - sorry i knew this is too much code - but didnt know how to create a link or something

11:48 what channel should i put it on - i dont see #clojure channel there

11:49 rhickey_: just paste with no channel and put the link here manually

11:50 nsinghal_: http://paste.lisp.org/display/58600

11:50 this is a very nice way top do it.

11:53 rhickey_: ns: can't you just run the commands locally, or using a straight repl to the remote instance, look at the output and determine it's readability?

11:53 its

11:54 ns: the 'map' has "Equality. Returns true ...'" in a key position, if that helps

11:56 nsinghal_: i run locally and i get a clojure.lang.PersistentTreeMap - and its working. I will check may be because of some doc string, i might be getting this

11:56 rhickey_: ns: it is a doc string, search for it in boot.clj

12:13 cgrand: rhickey_, chouser: new war uploaded.

12:16 chouser: your "Bad version number in .class file" was caused by the clojure.jar being compiled with jdk 6 (fixed now)...

12:42 Chouser: cgrand: oh, ok, thanks.

12:43 actually, I don't know why I was using 1.5. I have 1.6 installed, and it seems to work fine.

13:51 * drewr likes the swank support

14:48 Chouser: drat. I've got an error in the design of the zip-filter API.

14:52 abrooks: Chouser: What's the issue?

14:53 Chouser: abrooks: thanks for caring... ;-)

14:54 The problem is I want [:table :tr] to match a <tr> inside a <table>. This implies navigating "down" either before or after a matching tag.

14:54 ericthorsen: rich: Is there a way to query clojure for a version?

14:54 Chouser: ..as in either after :table, or before :tr

14:56 rhickey: eric: no

14:56 ericthorsen: any plans for this?

14:56 rhickey: not sure - what's a version

14:57 ericthorsen: could just be a change list id as far as i need....a point in time

14:58 like a build number

14:59 rhickey: it could be the svn rev, but I'd need a really convenient way to capture that and embed it in the build, not interested in manually doing anything

14:59 ericthorsen: totally...that would be expected and desired

14:59 abrooks: Perhaps the command "svnversion" could be used to show (for svn checkouts) the working copy version and state (including modifications).

15:00 The "perhaps" is somewhat conditional on what ant/maven can do at build time (I've never really used either) and what you would do for the case where the build tree is not an svn working copy (i.e. a tarball or svn export).

15:02 An svn exported tree could provide an svn:keywords "Id" in some file (which would cover the tarball case).

15:02 Actualy, probably "Rev" not "Id"... habbit caught me there.

15:06 Chouser: abrooks: but I also want [:table #(attr % :id)] to match the id of the table, which means I can't navigate down *after* the :table. Therefore I must navigate down before.

15:06 abrooks: Fricking stupid Subversion. I forgot again. "Rev" is always the revision of the file modification. It only gets updated when you update that file.

15:07 * abrooks takes is Subversion loathing elsewhere...

15:07 Chouser: this is what I've been doing, and it's been fine.

15:08 But now I'm adding predicates for navigating up or sideways, so I can do, for example [:div ancestors :table]

15:10 abrooks: Chouser: Does "ancestors" have a recognizable type?

15:10 Chouser: In that case I mean I want to find every <table> that is an ancestor of a <div>. But since I'm auto-navigating down before tags, I get all <table>s that are children of anything with <div> as a descendent.

15:10 abrooks: it's just a function.

15:11 so one solution would be to get rid of auto-nav, and use something like / to mean "expand down" (like xpath does)

15:12 but then you get [:table / :tr / :td / :div]

15:12 abrooks: Ew.

15:12 Is it the case that not auto-nav is the common case?

15:13 Chouser: right. ew. But at least [:div ancestors :table] and [:table #(attr % :id)] to work as expected

15:13 abrooks: What about a "here" designator

15:13 [:table :tr :td . :div]

15:13 Chouser: well, I think with chains of tag names, auto-nav down is common. Everywhere else, you probably want no auto-nav.

15:14 If that's true, I could try to allow a function to return something that means "nav down if the next function also tells you too"

15:15 The implementation would be problematic (use meta-data??) and I'm worried it would be to "magical" and hard to understand.

15:15 abrooks: I really need to play with zip-filter. I've only glanced at it as I've been tearing through Project Euler problems. :)

15:15 Chouser: yeah, it won't help you much there, probably.

15:15 abrooks: Heh. No, likely not.

15:15 Chouser: don't worry, nobody else has looked at it either. Well, rhickey did, but he was just humoring me.

15:16 ok, well, I'll go away and ponder this, and stop spamming the channel.

15:31 MarkJP: what part of the following is the actual java class name:

15:31 #<Var: user/foo>

15:31 user=> foo

15:31 clojure.fns.user.foo__1292@1145cc

15:32 sorry: (defn foo [] "asdf")

15:32 what part of clojure.fns.user.foo__1292@1145cc

15:32 rhickey: clojure.fns.user is the package, foo__1292 is the class name

15:32 MarkJP: thx

16:45 (defn char? [x] (instance? java.lang.Character x))

16:49 rhickey: markjp: ok?

16:49 MarkJP: oh, just something I thought might be usefull in boot.clj?

16:50 rhickey: ok

17:28 ericthorsen: ericthorsen: Rich: if i have a list of 2 item vectors what is the idomatic way to make that a hash-map?

17:28 [5:27pm] ericthorsen: (apply hash-map (apply concat '([] [] [] [] [])))

17:28 ?

17:34 Chouser: ericthorsen: I've been doing that some recently.

17:34 ericthorsen: the same solution?

17:34 Chouser: This is the best I've got: (reduce (fn [m [k v]] (assoc m k v)) {} '([] [] []))

17:35 hm, I think yours is better.

17:35 oh, mine used to doctor the key on it's way through.

17:36 (reduce (fn [m [k v]] (assoc m (keyword k) v)) {} '([] [] []))

17:44 ericthorsen: thx...i'll take a look

17:49 Chouser: well, I didn't really answer your question. Seems like a common case for which there should be a succinct solution.

18:07 abrooks: ericthorsen, Chouser: Funny, I've been stumbling around trying to find a good way to do the same. At least now I don't feel so dumb. I used ericthorsen's approach but felt like I was still missing something.

18:13 ericthorsen: since this is how map entries print it does seem too much typing for that

18:14 of-course there is always (defn to-map [v] (apply hash-map (apply concat v)))

18:14 maybe i'm just getting too lazy?

18:18 abrooks: This excercise did make me think about "flatten" and "fold" functions. (flatten ((1 2) (3 4) (5 6)) -> (1 2 3 4 5 6), (fold 3 (1 2 3 4 5 6)) -> ((1 2 3) (4 5 6)). Both functions could be generally useful I think.

18:19 Chouser: fold is called reduce

18:19 ericthorsen: yup

18:19 abrooks: (flatten looks like concat but it would recurse to depth -- my example didn't show that.)

18:19 Chouser: oh, what?

18:19 Scala's fold is called reduce.

18:20 ericthorsen: thinking the same...although it's hard for me to believe Rich did not have that on his radar....might be a simple thing we are missing?

18:20 abrooks: Ah. Clojure's reduce only operates on two items, right?

18:21 Chouser: no, 2 or 3

18:21 abrooks: Oh?

18:21 Chouser: what does the 3 in your foold example mean?

18:21 abrooks: take 3 items.

18:22 ericthorsen: (reduce concat [] [[1 2] [1 2]])

18:22 told you it was probably there

18:22 now that can be applied to a hash-map

18:23 feels cleaner

18:23 what do you think?

18:23 abrooks: ericthorsen: Much better. :)

18:23 Chouser: (split-at 3 '(1 2 3 4 5 6))

18:24 how is that reduce better than apply concat?

18:25 ericthorsen: good question

18:25 (apply hash-map (reduce concat [] [[1 2] [5 2]]))

18:25 not much less typing is it?

18:26 i gotta run...catch up with you guys later...thx

18:26 abrooks: Chouser: split-at only splits once. I'd want (fold 3 '(1 2 3 4 5 6 7 8 9)) -> ((1 2 3)(4 5 6)(7 8 9)). I'd tried split-at before.

18:32 rhickey: user=> (reduce conj {} '([:a 1] [:b 2] [:c 3]))

18:32 {:a 1, :c 3, :b 2}

18:32 abrooks: Now that "!" is reclaimed perhaps it could be an alias for "apply".

18:32 Ah, there is a better way. Thanks, rhickey.

18:36 I'm not sure how I missed the optional reduce val.

18:38 rhickey: it's a key data-structure-building idiom for Clojure, needs to be better known

18:44 drewr: I'm trying a simple contrived example to try and get my head around lazy sequences. http://paste.lisp.org/display/58623

18:44 How do I lazy-cons something up that wraps (matches m) in a seq?

18:44 I'd like to do something like:

18:45 rhickey: (re-seq #"a+" "foo bar baaz baaaz baaaaz")

18:45 ("a" "aa" "aaa" "aaaa")

18:45 drewr: (reduce conj [] (.... matches of m ... ))

18:46 Haha. Well, it's builtin.

18:46 rhickey: look at the def of re-seq to see how to do it yourself

18:46 4 lines

18:47 drewr: OK.

18:47 rhickey: lazy-cons is the key to writing your own seqs

18:48 drewr: Glad I picked an experiment for which there was a canonical implementation already.

19:13 rhickey: In re-seq, why do you type-hint re as Pattern when it'll be a string coming in?

21:07 gomer-nyc: Hi

21:08 Chouser: Hi!

21:08 gomer-nyc: I see there's an emacs mode for Clojure by Mathias Dahl; wondering whether anybody has managed to darcs get it recently - I'm trying now but my machine cannot connect to the host

21:10 OR, is anybody else maybe using a different hook for Emacs?

21:12 drewr: gomer-nyc: Just set up slime today with http://clojure.codestuffs.com/ and it's really good.

21:15 gomer-nyc: cool, great - I'm gonna give it a whirl

21:17 drewr: Not as full-featured as CL, but it's a good start.

21:17 gomer-nyc: I'm just getting started with Clojure so I figured I better have SOME editor support :-)

22:24 * drewr succeeded at writing a lazy random number generator.

22:34 Chouser: drewr: hey, congrats!

22:38 drewr: Is there any way to suppress most of the stacktrace when an error occurs?

22:38 Really just the top line is what I need.

22:43 rhickey: Is there a way to suppress all but the first line of a stacktrace?

22:44 All that's really relevant to me is "java.lang.IllegalStateException: Var x is unbound."

22:44 rhickey: not yet, there should be

22:44 with the option to grab the exception after the fact

22:45 drewr: as to you question re: pattern - #"blah" is a regex pattern

22:45 you/your

22:45 drewr: Also, and this may be impossible with the JVM, but do you have plans for conditions/restarts.

22:45 (Thanks, I saw that in reader.html later.)

22:45 rhickey: drewr: no need for conditions/restarts - can build with dynamic function binding

22:46 drewr: OK.

Logging service provided by n01se.net