#clojure log - Aug 13 2008

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

6:31 StartsWithK: what should *use-context-classloader* do?

6:49 Chouser: StartsWithK: http://groups.google.com/group/clojure/msg/7d4fee85f7fc4cd4

6:50 StartsWithK: i did set it to true, nothing happened, but i am not using proxy

6:51 my osgi activator is scala (java) and i call clojure from it

6:52 for now i have to do RT.loadResourceScript(getClass, "file.clj") for this to work from inside Activator class

9:10 roblally_: I'm a little confused about macro's and how they handle literal parameters. Can anyone recommend a good resource?

9:10 Why I wrote "macro's" rather than "macros" is also confusing, I admit.

9:11 * roblally_ I think I'm misunderstanding something fundamental.

9:11 roblally_: (defmacro boink [actual]

9:11 '(println ~actual))

9:11

9:11 (println (macroexpand

9:11 '(boink 2)))

9:11

9:11 drewr: roblally_: This is a good intro to the concept of macros: http://gigamonkeys.com/book/macros-defining-your-own.html

9:11 roblally_: (boink 32)

9:11 drewr: lisppaste8: url

9:11 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

9:11 roblally_: Cool

9:12 drewr: roblally_: Use ^^^^^^^ to paste code.

9:12 lisppaste8: roblally pasted "Problem macro" at http://paste.lisp.org/display/65263

9:13 roblally_: Thanks, that's a neat resource.

9:13 I'm confused as to why when I execute that code I see clojure.lang.LispReader objects and not numbers.

9:14 drewr: roblally_: Switch that quote to a backtick.

9:14 user> (defmacro boink [actual] `(println ~actual))

9:14 nil

9:14 user> (macroexpand-1 '(boink 32))

9:14 (clojure/println 32)

9:16 roblally_: Thank-you so much. I've been banging my head off that for 3 days.

9:16 I shall read the article you linked to.

9:18 drewr: Note that it's a chapter from a book on Common Lisp, so it's not in any way a tutorial for Clojure macros. It will however give you an idea of how macros differ from functions.

9:19 roblally_: This explains why I found that I could copy code and edit it and it would be fine, but when I typed it in from scratch ... things didn't work out so well.

9:22 drewr: :-)

11:43 mada: evening!

11:44 To concat with a space strings in a list, I am doing this: (apply str (map (fn [x] (str x " ")) '("foo" "bar")))

11:45 kotarak: mada: (apply str (interpose " " (list "foo" "bar"))) is also possible, though I don't know the argument limit things like str.

11:48 Chouser: I think there is no argument limit

11:49 mada: it seems to work

11:49 so there is nothing like `mapconcat' in clojure?

11:49 I had a look at `mapcat' but did not understand how to use it.

11:51 Chouser: mapcat is good when your map function always returns a seq, and you want to flatten tham out

11:51 kotarak: There was a question on the list about reversing the keys and values of map. This can be done with mapcat: (apply hash-map (mapcat (fn [[k v]] [v k]) m). The anonymous fn return a list of vectors. mapcat flattens this into list.

11:52 Chouser: user=> (map #(range 0 %) [3 1 4])

11:52 ((0 1 2) (0) (0 1 2 3))

11:52 user=> (mapcat #(range 0 %) [3 1 4])

11:52 (0 1 2 0 0 1 2 3)

11:52 kotarak: ah, a much more useful example.

11:54 kotarak: Chouser: :) Rich did this with reduce, so I wondered whether there is some limit for apply or some other issue (eg. with performance)

11:55 Chouser: I've not ever heard him speak badly of apply for large arg lists.

11:57 mada: reduce worked as well for me: (reduce (fn [x y] (str x " " y)) '("foo" "bar"))

11:57 first time I used reduce :)

11:58 kotarak: many ways to Rome I guess. :)

11:58 mada: yes, which is good I guess

11:58 I am fiddling with webjure and doing some small web apps

11:59 kotarak: ah. Sometimes yes, sometimes no... I depends on the situation.

12:01 Chouser: (defn arg1 [a & r] a)

12:01 (apply arg1 \a \b \c (repeatedly \x))

12:02 argument lists are a lazy seq, so there shouldn't be any limit.

12:28 mada: Chouser: haha, I just got use for `mapcat' :)

12:28 replaced some ugly workaround with it

12:30 if I am mapping over a list, is there anyway to know when the last item is being processed so that I can handle it differently?

12:30 I have this code:

12:30 ~@(mapcat (fn [x] `((:a {:href ~(str (url "/list") "tag=" x)} ~x) ", "))

12:30 (get-file-tags name))

12:31 and I don't want the ", " to be generated for the last item in the list

12:32 I assume it is not possible and that I need another approach if I want to do this. Now I am using " " instead, and the extra space is not visible to the user, so it works.

12:38 kotarak: mada: (apply concat (interpose (list ",") (map (fn [x] (list :a {:href (str (url "/list") "tag=" x)} x)), does this help?

12:41 mada: ah, interpose only puts stuff inbetween... clever!

12:42 (interpose "x" "APA")

12:42 oops, not the REPL :)

12:43 it worked on a string as well though

12:44 drewr: Chouser: I remember when you and rhickey were talking a lot about xml support. I need to parse a large document and I'm wondering if startparse-sax is good for production use.

12:46 Chouser: drewr: I assume Java's SAX parser is good enough, but the existing xml.clj will load the whole document into memory as a tree of hashes and vectors before returning it to you.

12:46 drewr: OK, that's what the code was leading me to believe but I thought I was missing something.

12:47 Chouser: I've got a lazy-xml.clj thing going, but for you use it has a couple problems:

12:47 1. not quite perfect -- I haven't released it because it's got a couple problems with namespace handling

12:48 2. not well tested yet -- since only I've been beating on it, it would stretch anyone's definition of "good for production use".

12:48 drewr: I can just wrap SAXParser for my needs, unless you'd like me to pound on your code.

12:48 Chouser: It's really close though. It uses a 3rd party pull parser when available, which fits very nicely with Clojure's lazy seqs.

12:50 drewr: well, I guess it's up to you. I can show you what I've got. If you think it's close enough to what you want, I can patch up the known holes and we can see how it goes.

12:50 what kind of "processing" do you plan? have you looked at all at my zip-filter query stuff?

12:51 drewr: No I haven't. Basically just taking a large feed, munging the data a little, and stuffing it into a db.

12:53 Chouser: oh, ok. Well...

12:53 seems likely using sax directly would be a good bet. Although I really would recommend a pull parser.

12:54 http://www.extreme.indiana.edu/xgws/xsoap/xpp/

12:54 The API is so much better than SAX

12:54 drewr: Interesting.

12:59 Chouser: yep. No need for a subclass of anything (proxy), and it's easy to wrap in such a way that you can return a lazy seq.

12:59 plus it may be faster at runtime.

13:00 the lazy seq thing is huge for me -- doing that with SAX is impossible as far as I can tell, without resorting to coordinating threads.

17:56 arohner: grr.

17:56 (. clojure.lang.RT (loadResourceScript "clojure-contrib/lib/lib.clj"))

17:56 nil

17:56 user=> (clojure/refer 'clojure-contrib.lib)

17:56 java.lang.Exception: No namespace: clojure-contrib.lib

17:57 Chouser: clojure.contrib.lib

17:57 arohner: ser=> (. clojure.lang.RT (loadResourceScript "clojure.contrib/lib/lib.clj"))

17:57 java.io.FileNotFoundException: Could not locate Clojure resource on classpath: clojure.contrib/lib/lib.clj

17:58 my clojure-contrib directory is in ./lib/clojure-contrib

17:58 Chouser: heh

17:58 arohner: but since the loadResourceScript worked, why did the refer fail?

17:58 Chouser: the load was correct. the namespace as given to refer should use . not -

17:59 It'll be good when lib.clj is builtin.

17:59 arohner: oh, ok

17:59 thanks for the help :-)

17:59 Chouser: :-) sure. It's confusing, I know.

17:59 arohner: yeah, it will be nice when that's built in

18:46 does anyone here have svn access to clojure-contrib?

18:46 * Chouser raises his hand.

18:46 arohner: I'd like to fix the library namespace thing for seq-utils

18:47 Chouser: it looks like it already is.

18:47 seq_utils/seq_utils.clj

18:48 arohner: oh, I'm blind

18:48 Chouser: no, it's confusing -- there are two versions of several of the libs there.

20:06 arohner: does loadResourceScript screw with your line numbers?

20:06 Chouser: no

20:06 arohner: macros?

20:06 Chouser: macros sometime report bad line numbers in stack traces.

20:07 arohner: maybe that's it

20:07 Chouser: or I think perhaps the right line number of the wrong file

20:07 arohner: I have a file that's about 10 lines long. the stack trace says line 364

20:07 Chouser: yeah, macros

20:07 arohner: is there a way to macroexpand a file?

20:08 Chouser: that's a great question -- I'm not sure

20:09 arohner: I'm googling now to see if CL has that

20:09 it seems like it should be useful, but i don't remember hearing about it before

20:11 emacs has macroexpand-all which recursively expands everything in a form (rather than just the top level)

20:15 Chouser: yeah, that'd be instructive in itself, and then pretty trivial to apply to a whole file.

20:20 arohner: the other question I have is, why doesn't anyone else have this?

20:20 is there something about their environment that makes it not necessary?

20:21 i.e. their stack traces don't present weird numbers?

20:21 Chouser: that makes what not necessary?

20:21 oh, no, everybody sees those weird numbers.

20:21 I just use the rest of the stack trace to figure out what's going wrong.

20:22 arohner: I mean other lisps

20:22 is this not an issue in CL?

20:23 Chouser: oh! yeah, I think this is a specific interaction between the way Clojure implements macros and the way Java annotates bytecode to indicate file and line numbers.

20:23 I haven't gotten the impression from Rich that it would necessarily be impossible to fix, but maybe pretty hard and not worth it just yet.

20:25 slava: you need an s-exp data type distinct from a cons which stores file and line number information

20:25 Chouser: the file and line numbers are already stored in each var

20:26 arohner: but they're stored after macroexpansion

20:28 ok, here's another one

20:28 my exception is getting cut off

20:28 is there a way to make java print the whole thing?

20:28 Caused by: java.lang.Exception: No such namespace: compojure

20:28 at clojure.lang.Compiler.resolveIn(Compiler.java:3950)

20:28 at clojure.lang.Compiler.resolve(Compiler.java:3928)

20:28 at clojure.lang.Compiler.analyzeSymbol(Compiler.java:3911)

20:28 at clojure.lang.Compiler.analyze(Compiler.java:3642)

20:28 ... 60 more

20:28 Clojure

20:29 when I grep for .clj, the only reference is after my 10 line file is at line 164

20:29 I think there might be something useful in that 60 more

20:29 Chouser: oh, that's a compiler exception -- not runtime.

20:29 it suggests an exception is being thrown from inside a macro

20:39 arohner: grr. why does java just decide "oh, you don't need the rest of that stack trace"?

20:39 I don't see a method to change that either

20:39 Chouser: I think there's a command-line option

20:40 hm, maybe not.

20:41 arohner: want to paste your whole .clj and whole stack trace?

20:41 arohner: sure

20:41 Chouser: not inline here of course.

20:42 arohner: I'm just modifying compojure to work with recent clojure and clojure-contrib versions

20:42 Chouser: oh. ouch.

20:42 arohner: what's the paste url?

20:42 Chouser: lisppaste8: url

20:42 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

20:43 Chouser: there's a more recent framework mentioned on the forum. dunno if it would match your taste or not

20:43 arohner: AFAIK, compojure was the recent one

20:43 webjure was the older one

20:43 lisppaste8: arohner pasted "stacktrace" at http://paste.lisp.org/display/65294

20:44 Chouser: oh, of course you're right. sorry.

20:44 arohner: compojure shipped its own clojure.jar and clojure-contrib, and hadn't updated since the new source organization post

20:46 Chouser: what SVN version of clojure are you using?

20:46 arohner: 996

20:47 999 now

20:49 Chouser: still boot.clj:147: No such namespace: compojure ?

20:50 arohner: yup

20:50 stack trace looks the same

20:51 Chouser: maybe try :verbose on the use call, so you can then try each of its steps manually?

20:53 arohner: ah, that helped a lot

20:53 (clojure/in-ns 'user)

20:53 (clojure/refer 'compojure.json)

20:53 (clojure.contrib.lib/load-resource "file:/Users/arohner/Programming/clojure/compojure/lib/compojure/persist/persist.clj")

20:53 2008-08-14 00:01:42.166::INFO: Logging to STDERR via org.mortbay.log.StdErrLog

20:53 clojure.lang.Compiler$CompilerException: boot.clj:147: No such namespace: compojure

20:53 at clojure.lang.Compiler.analyze(Compiler.java:3669)

20:53 at clojure.lang.Compiler.analyze(Compiler.java:3627)

20:53 at clojure.lang.Compiler.access$100(Compiler.java:37)

20:53 at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:2626)

20:53 sorry, I need to get used to using paste

21:02 time for bed

21:02 Chouser: indeed. later!

21:02 arohner: thanks for the help Chouser

Logging service provided by n01se.net