2008-08-13
| 06:31 | StartsWithK | what should *use-context-classloader* do? |
| 06:49 | Chouser | StartsWithK: http://groups.google.com/group/clojure/msg/7d4fee85f7fc4cd4 |
| 06:50 | StartsWithK | i did set it to true, nothing happened, but i am not using proxy |
| 06:51 | StartsWithK | my osgi activator is scala (java) and i call clojure from it |
| 06:52 | StartsWithK | for now i have to do RT.loadResourceScript(getClass, "file.clj") for this to work from inside Activator class |
| 09:10 | roblally_ | I'm a little confused about macro's and how they handle literal parameters. Can anyone recommend a good resource? |
| 09:10 | roblally_ | Why I wrote "macro's" rather than "macros" is also confusing, I admit. |
| 09:11 | roblally_ | (defmacro boink [actual] |
| 09:11 | roblally_ | '(println ~actual)) |
| 09:11 | roblally_ | |
| 09:11 | roblally_ | (println (macroexpand |
| 09:11 | roblally_ | '(boink 2))) |
| 09:11 | roblally_ | |
| 09:11 | drewr | roblally_: This is a good intro to the concept of macros: http://gigamonkeys.com/book/macros-defining-your-own.html |
| 09:11 | roblally_ | (boink 32) |
| 09:11 | drewr | lisppaste8: url |
| 09:11 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 09:11 | roblally_ | Cool |
| 09:12 | drewr | roblally_: Use ^^^^^^^ to paste code. |
| 09:12 | lisppaste8 | roblally pasted "Problem macro" at http://paste.lisp.org/display/65263 |
| 09:13 | roblally_ | Thanks, that's a neat resource. |
| 09:13 | roblally_ | I'm confused as to why when I execute that code I see clojure.lang.LispReader objects and not numbers. |
| 09:14 | drewr | roblally_: Switch that quote to a backtick. |
| 09:14 | drewr | user> (defmacro boink [actual] `(println ~actual)) |
| 09:14 | drewr | nil |
| 09:14 | drewr | user> (macroexpand-1 '(boink 32)) |
| 09:14 | drewr | (clojure/println 32) |
| 09:16 | roblally_ | Thank-you so much. I've been banging my head off that for 3 days. |
| 09:16 | roblally_ | I shall read the article you linked to. |
| 09: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. |
| 09: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. |
| 09:22 | drewr | :-) |
| 11:43 | mada | evening! |
| 11:44 | mada | 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 | mada | so there is nothing like `mapconcat' in clojure? |
| 11:49 | mada | 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 | Chouser | ((0 1 2) (0) (0 1 2 3)) |
| 11:52 | Chouser | user=> (mapcat #(range 0 %) [3 1 4]) |
| 11:52 | Chouser | (0 1 2 0 0 1 2 3) |
| 11:52 | Chouser | 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 | mada | 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 | mada | 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 | Chouser | (apply arg1 \a \b \c (repeatedly \x)) |
| 12:02 | Chouser | 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 | mada | replaced some ugly workaround with it |
| 12:30 | mada | 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 | mada | I have this code: |
| 12:30 | mada | ~@(mapcat (fn [x] `((:a {:href ~(str (url "/list") "tag=" x)} ~x) ", ")) |
| 12:30 | mada | (get-file-tags name)) |
| 12:31 | mada | and I don't want the ", " to be generated for the last item in the list |
| 12:32 | mada | 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 | mada | (interpose "x" "APA") |
| 12:42 | mada | oops, not the REPL :) |
| 12:43 | mada | 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 | Chouser | 1. not quite perfect -- I haven't released it because it's got a couple problems with namespace handling |
| 12:48 | Chouser | 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 | Chouser | 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 | Chouser | 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 | Chouser | seems likely using sax directly would be a good bet. Although I really would recommend a pull parser. |
| 12:54 | Chouser | http://www.extreme.indiana.edu/xgws/xsoap/xpp/ |
| 12:54 | Chouser | 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 | Chouser | plus it may be faster at runtime. |
| 13:00 | Chouser | 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 | arohner | (. clojure.lang.RT (loadResourceScript "clojure-contrib/lib/lib.clj")) |
| 17:56 | arohner | nil |
| 17:56 | arohner | user=> (clojure/refer 'clojure-contrib.lib) |
| 17:56 | arohner | 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 | arohner | java.io.FileNotFoundException: Could not locate Clojure resource on classpath: clojure.contrib/lib/lib.clj |
| 17:58 | arohner | 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 | Chouser | It'll be good when lib.clj is builtin. |
| 17:59 | arohner | oh, ok |
| 17:59 | arohner | 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 | arohner | does anyone here have svn access to clojure-contrib? |
| 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 | Chouser | 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 | arohner | it seems like it should be useful, but i don't remember hearing about it before |
| 20:11 | arohner | 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 | arohner | is there something about their environment that makes it not necessary? |
| 20:21 | arohner | i.e. their stack traces don't present weird numbers? |
| 20:21 | Chouser | that makes what not necessary? |
| 20:21 | Chouser | oh, no, everybody sees those weird numbers. |
| 20:21 | Chouser | 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 | arohner | 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 | Chouser | 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 | arohner | ok, here's another one |
| 20:28 | arohner | my exception is getting cut off |
| 20:28 | arohner | is there a way to make java print the whole thing? |
| 20:28 | arohner | Caused by: java.lang.Exception: No such namespace: compojure |
| 20:28 | arohner | at clojure.lang.Compiler.resolveIn(Compiler.java:3950) |
| 20:28 | arohner | at clojure.lang.Compiler.resolve(Compiler.java:3928) |
| 20:28 | arohner | at clojure.lang.Compiler.analyzeSymbol(Compiler.java:3911) |
| 20:28 | arohner | at clojure.lang.Compiler.analyze(Compiler.java:3642) |
| 20:28 | arohner | ... 60 more |
| 20:28 | arohner | Clojure |
| 20:29 | arohner | when I grep for .clj, the only reference is after my 10 line file is at line 164 |
| 20:29 | arohner | I think there might be something useful in that 60 more |
| 20:29 | Chouser | oh, that's a compiler exception -- not runtime. |
| 20:29 | Chouser | 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 | arohner | I don't see a method to change that either |
| 20:39 | Chouser | I think there's a command-line option |
| 20:40 | Chouser | hm, maybe not. |
| 20:41 | Chouser | 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 | arohner | 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 | arohner | 999 now |
| 20:49 | Chouser | still boot.clj:147: No such namespace: compojure ? |
| 20:50 | arohner | yup |
| 20:50 | arohner | 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 | arohner | (clojure/in-ns 'user) |
| 20:53 | arohner | (clojure/refer 'compojure.json) |
| 20:53 | arohner | (clojure.contrib.lib/load-resource "file:/Users/arohner/Programming/clojure/compojure/lib/compojure/persist/persist.clj") |
| 20:53 | arohner | 2008-08-14 00:01:42.166::INFO: Logging to STDERR via org.mortbay.log.StdErrLog |
| 20:53 | arohner | clojure.lang.Compiler$CompilerException: boot.clj:147: No such namespace: compojure |
| 20:53 | arohner | at clojure.lang.Compiler.analyze(Compiler.java:3669) |
| 20:53 | arohner | at clojure.lang.Compiler.analyze(Compiler.java:3627) |
| 20:53 | arohner | at clojure.lang.Compiler.access$100(Compiler.java:37) |
| 20:53 | arohner | at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:2626) |
| 20:53 | arohner | sorry, I need to get used to using paste |
| 21:02 | arohner | time for bed |
| 21:02 | Chouser | indeed. later! |
| 21:02 | arohner | thanks for the help Chouser |