#clojure log - Nov 11 2008

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

7:48 tWip: what rev should I take as the latest is marked not to be used?

7:50 blackdog: i'm using 1037

7:51 hoeck: tWip: 1088 is the latest one without the do not use warning

7:52 * blackdog mmm, i thought i was upto date, been sleeping

7:52 tWip: okey, just checking

7:52 when was doseq changed, as my code using it does not work in 1088 either

7:53 hoeck: but i successfully tried the 1093 aot compilation, reveiving a 50% speedup in startup time, from 2s to roughly 1s

7:53 tWip: what was changed in doseq?

7:54 blackdog: takes a vector now

7:54 like let

7:54 tWip: yeah

7:55 basic usage like (doseq i (range 10) (println i)) should now be (doseq [i (range 10)] (println i)) I guess

7:55 but the api page still says (doseq item list & body)

7:58 hoeck: ah, it's stated in the svn logs (http://clojure.svn.sourceforge.net/viewvc/clojure?view=rev&sortby=log&revision=1090)

7:59 tWip: better start reading those then :)

9:27 SnowBuddy: good morning

9:30 so i was playing with the -> macro, and i can't figure out how i might use it in practice. how is (-> x (form ...)) different from (form x ...) and (-> x (form ...) (form)) different and/or preferred over (form (form x ...))?

9:33 Cark: snowbuddy : here is an example : (-> file FileReader. BufferedReader.)

9:34 instead of (new BufferedReader (new FileReader file))

9:34 rhickey: SnowBuddy: (sometimes (backwards (think (to (hard (be (can (it))))))))

9:34 SnowBuddy: :D

9:35 Cark: are new and class. interchangeable for creating a new object?

9:35 Cark: i beleive so

9:36 rhickey: also a nice fit for nested associative data structures

9:36 Cark: i use it a lot : (-> scroll-pane .getViewport .getView)

9:36 lot less parenthesis this way

9:37 SnowBuddy: that makes sense, thanks :)

9:40 cemerick: I'm trying to push for some sanity in how Netbeans works with dependencies that provide classfiles generated from non-Java-the-language sources: http://www.netbeans.org/issues/show_bug.cgi?id=152943

9:42 rhickey: cemerick: good luck! This is an area that really needs more attention - mixed lang projects, and removing Java presumptions from IDEs in general

9:43 cemerick: rhickey: feel free to vote it up, if you like

9:43 I have to think it'd be a super-easy change on their part.

9:45 I'll bet that that fellow comes back with "well, you should have a clojure/scala/groovy/fortress/jruby/whatever project type, rather than a Java project type"

9:47 Lau_of_DK: Afternoon gents

9:47 Quick question: I vaguely remember some talk about the Java libs being opensource - are they?

9:47 tWip: which java libs?

9:48 Cark: clojure api ?

9:48 dudleyf: Lau_of_DK: If you mean the Java standard library, almost all of it is GPL now

9:49 Lau_of_DK: ok, thanks dudleyf , thats what I mean

9:49 tWip: wikipedia seems to have a quite good article on OpenJDK

9:50 seems it's GPL+linking exception

9:50 dudleyf: tWip: Yeah, I think it's GPL with the Classpath exception

10:00 knobo: Does anyone have experience with clojure on symbian?

11:25 SnowBuddy: am i correct in thinking that assoc is basically a replace-value-at function?

11:26 leafw: SnowBuddy: wrong. It creates a copy of the map, with structural sharing, that has that key with its value changed.

11:29 SnowBuddy: unless you mean something i don't understand by "with structural sharing", that's what i said. it goes without saying that a copy is made, but the result is the same as if the value at a specific key was replaced. at least, that's how i'm reading it

11:31 Chouser: SnowBuddy: yes, assoc creates a new collection that has the value at "key" replaced with the "value" given.

11:31 for maps, you can also use assoc to add new keys

11:32 SnowBuddy: but not for vectors because the index has to be within [0, (count v)), right?

11:33 Chouser: you can assoc on a vector at the next largest index

11:33 (assoc [:hi] 1 :there)

11:33 but it's usually nicer to use conj for that.

11:43 SnowBuddy: does if use an implicit do, or will i have to use a do when the clause of an if has more than one expression?

11:43 Chouser: if does not have an implicit do, but when does.

11:44 SnowBuddy: ah, i forgot about when :P

11:46 Chouser: that's what I'm here for. :-)

11:47 SnowBuddy: i'll get it eventually :)

11:53 Chouser: I wonder how hard it would be to compile Clojure to elisp.

11:54 gnuvince: lexical vs dynamic scoping is probably gonna be a bitch to deal with.

11:55 Chouser: elisp has no lexical binding at all?

11:55 cooldude127: i don't think so

11:56 Chouser: I guess if you make sure you generate completely unique names for Clojure's lexicals, that would cover it.

11:56 cooldude127: why do we want clojure in elisp?

11:56 Chouser: you'd want a clean way to translate generated names back into Clojure names.

11:57 because emacs sings a siren song, but elisp makes my teeth itch

11:57 cooldude127: oh lol

11:58 i love emacs

11:58 but i don't write much elisp

11:58 my .emacs is a hodgepodge of copied-and-pasted code

12:09 drewr: I find I'm doing (apply conj ... ) a lot to flatten lists. Is there already a fn for that that I'm missing?

12:10 Actually, it's more like:

12:10 user> (reduce #(apply conj %1 %2) #{} [[1 2 3 4] [3 4 5 6 7]])

12:10 #{1 2 3 4 5 6 7}

12:11 wwmorgan: (apply concat [[1 2 3 4] [3 4 5 6 7]]) => [1 2 3 4 3 4 5 6 7]

12:12 Chouser: wwmorgan: actually, concat returns a seq

12:12 wwmorgan: Chouser is right

12:13 Chouser: but since drewr is going from vector to set, (set (apply concat ...))

12:14 drewr: Oh, duh, set incrementally adds the elements so there wouldn't be dups anyway.

12:14 Thanks.

12:31 duck1123: Chouser: there's a branch of emacs that provides lexical scoping

12:31 I haven't looked into it too much

13:18 Lau_of_DK: Good evening all

13:18 AWizzArd: does Clojure have something like CLs function "member" ?

13:18 Hi Lau

13:19 in principle it is similar to filter... only that member returns the nthcdr, including the found element itself while filter would just return that element and not necessarily the following ones

13:20 kotarak: AWizzArd: drop-while?

13:21 AWizzArd: let me have a look...

13:22 kotarak: yes, thx

13:30 Cark: what's the function that does that : (unkown f g) => (fn[x] (apply f (g x))) ?

13:31 Lau_of_DK: -> ?

13:31 Chouser: Cark: g returns a seq?

13:31 Cark: allright got it : comp

13:32 Chouser: comp's not going to do apply for you

13:32 Cark: function composition .... couldn't put the finger on the name of that operation !

13:32 i'll do it myself =P

13:32 thanks !

13:35 yes the apply was a mistake in the question

13:45 Lau_of_DK: Guys - I need to get a little into Clojures multi-threading capabilities, where do I start ?

13:45 cooldude127: Lau_of_DK: clojure.blip.tv

13:45 the concurrency talk is amazing

13:45 kotarak: Lau_of_DK: the ant example

13:45 cooldude127: yeah that one

13:45 Lau_of_DK: Alright, anything else?

13:45 kotarak: sorry. I'm not the in multi-threading myself..

13:53 duck1123: has anyone read that java concurrency book rich mentions?

13:53 Lau_of_DK: No

13:53 duck1123: and would it be worth reading?

13:57 AWizzArd: I remember that he mentioned one book.. if you have the video open: what is the name of that book?

13:58 duck1123: I think it was something like Java Concurrency in practice

13:58 I don't have the video open

13:59 AWizzArd: cooldude127: do you have the vid open? Did Rich mention http://www.javaconcurrencyinpractice.com/ ?

13:59 cooldude127: no i don't have it open, i watched it a few weeks ago

13:59 * AWizzArd too

14:02 gnuvince: It was "Java Concurrency in Practice".

14:02 duck1123: gnuvince: have you read it?

14:03 gnuvince: No.

14:06 dudleyf: duck1123: Read it

14:06 It's excellent

14:06 duck1123: fair enough, I shall

14:07 I know where I can get a hold of a copy, I just wasn't sure if it was worth my time

14:09 dudleyf: If you don't appreciate Clojure's immutability-by-default now, you will once you start reading it ;-)

14:13 zak_: I think Clojure really gets the right mix of immutability and workarounds.

14:15 duck1123: I've been feeling guilty for changing variables in other languages

14:17 drewr: duck1123: I know how you feel. Mutating makes me feel dirty.

14:26 Chouser: I have more a feeling of manic daring. for( var i = 0; i < 10; ++i!!! mua-ha-ha!!!

14:27 I'm in ur code, changing ur variables. Whacha gonna do about, huh!?

14:28 zak_: If I caught a lolcat doing that, I might have it neutered.

14:29 duck1123: of course, I had to keep stopping myself from putting the parens outside the function call yesterday when doing c++

14:29 cooldude127: i've sometimes put parentheses around my sentences

14:30 i feel so dumb

14:30 duck1123: I've nested 3 deep when writing.

14:30 cooldude127: lol

14:31 zak_: I sometimes unconciously type an opening paren when I'm thinking about what I'm about to write.

14:31 cooldude127: hehe

14:35 abrooks: drewr: Thanks for the string/name patch. I've been thinking that it was missing.

14:39 Hun: zak_: that happen's to me when i'm writing python. wrote a small script to remove the parens afterwards

14:44 drewr: abrooks: Thanks. I was wondering if it was a valid suggestion.

15:00 Lau_of_DK: Has anybody else experienced (read-line) crashing the Slime repl ?

15:06 AWizzArd: is there a != or something like that in Clojure, or do we have to say (not (= ..)) ?

15:06 kotarak: not=

15:06 AWizzArd: thx

15:12 Chouser: also when-not

15:15 AWizzArd: Instead of CL's unless. And I am quite happy with that. As a non-native speaker I always said to myself "when not" when I saw a unless to understand better what happens.

15:16 How can I find the current directory in Clojure/Java?

15:17 gnuvince: (System/getProperty "user.dir")

15:18 AWizzArd: danke

15:19 dudleyf: Java doesn't really have a concept of "current directory" like in a shell or a scripting language, though

15:20 does it?

15:20 leafw: dudleyf: it does

15:20 System.getProperty("user.dir");

15:20 aka (System/getProperty "user.dir")

15:21 there is also java.io.tmp.dir and user.home ....

15:21 dudleyf: Huh. I always read that as "user.home"

15:22 leafw: "usr.dir" is the current dir :)

15:23 AWizzArd: And is there a way to change it in a relative way? (System/setProperty "user.dir" "..") makes (System/getProperty "user.dir") return ".."

15:24 leafw: hum

15:25 System/getProperties returns you the actual table

15:25 perhaps you can change that

15:25 there's also System/setProperties <a new Properties object>

15:26 Hun: in my experience, changing directory in a program is a bad idea

15:26 using a path api with absolute paths works better

15:26 leafw: same experience here.

15:26 dudleyf: The stuff I'm reading suggests that user.dir is read-only

15:26 leafw: plus the Properties object has limited priviledges access control or something weird

15:27 Chouser: looks like "no": http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4045688

15:27 Hun: it tends to make your program shellscripty

15:34 deklund: quit

15:34 jgracin: hi! how do I construct an empty List<String>?

15:34 ArrayList that is

15:35 duck1123: /whoami

15:35 wwmorgan: jgracin: in clojure or java?

15:35 Lau_of_DK: ./You are duck

15:35 jgracin: wwmorgan: clojure

15:35 duck1123: lol, I thought that would work

15:35 wwmorgan: (list)

15:36 er, (java.io.ArrayList.)

15:36 jgracin: wwmorgan: I need to pass it to java code which expects List<String>

15:37 wwmorgan: jgracin: I believe that works. What error are you getting?

15:38 jgracin: wwmorgan: java.utll.ArrayList creates List<Object> which is not List<String>

15:39 maybe something with 'empty'...

15:39 wwmorgan: jgracin: generics in java are handled through type erasure. By the time the java code is compiled, it doesn't care what's in the collection

15:40 AWizzArd: jgracin: if you can test it easily: do you still get the same message when you do #^strings(list) ?

15:40 wwmorgan: lisppaste8: url

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

15:41 jgracin: I'm actually getting no matching ctor because List<String> is expected... I think, let me recheck

15:41 AWizzArd: does List<String> mean that it *must be* a list of Strings? Or is a super class like Object also fine?

15:42 jgracin: AWizzArd: must be Strings.

15:42 AWizzArd: ok

15:42 Chouser: it's a generics thing, which only matters at Java compile time. By the time it's running and clojure's calling into it, the generic doesn't matter.

15:42 deklund: gotta theoretical functional question.... it looks like (re-groups ...) only works after a call to (re-find ...)

15:42 does this violate the concept of immutability?

15:43 jgracin: wwmorgan and Chouser: that must be it. I'll recheck

15:43 Chouser: deklund: yes it does, as do many Java classes.

15:43 deklund: i.e. why do I need to re-find first on that match object before I can get the groups?

15:43 ahhh

15:43 Chouser: deklund: use re-seq instead to regain the illusion of immutability. :-)

15:44 deklund: so... once I start integrating with java classes, I sacrifice pure functionality... makes sense

15:44 thanks a bunch

15:45 Chouser: yep

15:47 danlarkin: so where's planet.clojure.org in the pipeline

15:51 duck1123: we could probably set something up with Yahoo Pipes

16:05 3B

16:22 abrooks: Hm. There's no Clojure swag at cafepress.com.

16:24 dudleyf: abrooks: http://www.zazzle.com/clojure

16:25 duck1123: there needs to be better slogans

16:26 I still like my: I get more work done when I'm lazy

16:26 or similar

16:27 abrooks: duck1123: ;-)

16:27 dudleyf: Ah, zazzle, right.

16:28 Zak: There doesn't appear to be a black men's shirt.

16:28 Chouser: Zak: you can customize the back women's shirt, I think.

16:32 yeah, click on the black shirt (so you get the logo colors that look good on black) and then "select a different shirt style"

16:32 hiredman: is this coljure swag, or libertarian swag?

16:32 Chouser: hehe

16:36 * Zak wouldn't mind expressing both sentiments at once.

16:38 duck1123: not one of those designs has a collar

16:40 kotarak: lazyness is the source of intelligence

16:40 SnowBuddy: quick question. when i say (conj (conj nil 1) 0) i expected (1 0) as a result, but it's actually (0 1). am i missing something?

16:40 AWizzArd: SnowBuddy: compare conj on lists and on vectors

16:41 wwmorgan: SnowBuddy: lists grow at the head

16:42 SnowBuddy: ah, i see. thanks :)

16:47 how does cons compare with conj? can i use a vector with cons as well?

16:47 danlarkin: SnowBuddy: cons is for lists only

16:47 AWizzArd: give it a try in the repl

16:47 hiredman: cons is for seqs

16:48 SnowBuddy: AWizzArd: i did, that's why i asked to be sure ;)

16:48 wwmorgan: cons returns a seq, conj returns whatever was passed into it

16:48 SnowBuddy: so is seq a list?

16:48 Chousuke: no

16:48 danlarkin: sorry, yes, cons is for seqs

16:48 Chousuke: SnowBuddy: but a list is a seq

16:49 Hun: but a seq is not in every case a list.

16:49 Chousuke: yeah

16:49 you can make seqs out of vectors or maps for example

16:50 danlarkin: speaking of... is seq? acting properly? (seq? (seq [])) == false

16:50 SnowBuddy: so if it says it works on a seq, why does cons seem to only produce a list?

16:51 Chousuke: SnowBuddy: I suppose that's because seqs print as lists

16:51 danlarkin: oh--- nevermind, it's empty

16:51 wwmorgan: (instance? clojure.lang.ISeq (cons 1 [2 3])) => true

16:52 Chousuke: when a seq is evaluated I suppose its most natural form is a list.

16:53 SnowBuddy: so to get a vector from a seq i would need to say something like (vec (cons 1 (cons 2 nil)))?

16:53 Chousuke: yeah

16:53 user=> (list? (cons 1 [1 2])) -> false, though :)

16:54 hiredman: (apply vector :a [:b :c])

16:54 Lau_of_DK: Isnt there some trick in Java like (Date/now) which just gives me 22:51:22 ?

16:54 SnowBuddy: user=> (seq? (cons 1 [1 2])) -> true :)

16:54 hiredman: SnowBuddy: that will add :a to the beginning of the vector

16:54 wwmorgan: (conj (conj [] 1) 2) => [1 2]

16:55 SnowBuddy: phew, i'll get it...eventually

16:55 hiredman: if that is what you want to do

16:56 danlarkin: SnowBuddy: running #'clojure/class on each of these forms can be illuminating... (class (cons 1 [2 3]))

16:56 Chouser: and compare that to (class (cons 1 '(2 3)))

16:57 * drewr doesn't get why strings can't have names

16:57 SnowBuddy: ah

16:57 bbl. thanks

17:00 johnwayner: Just to confuse things more, I think that ISeqs print as lists at the repl, but they aren't necessarily lists.

17:01 Nafai: So did I hear AOT compilation for Clojure is in the works?

17:02 rhickey: Nafai: the AOT compiler is done, just working through the library and API logistics

17:02 Nafai: rhickey: Cool!

17:03 rhickey: Clojure can AOT compile its bootstrap script and run from that bytecode

17:03 just working on the interactions between AOT compiled code and load/require et al

17:04 Nafai: Will this need any special classloaders to work?

17:04 Lau_of_DK: rhickey, are you going to write a lengthy document that explains all this, the work behind it and its many uses in Clojure?

17:04 rhickey: Lau_of_DK: probably not

17:05 Nafai: no special classloaders if you AOT compile - still thinking about AOT proxy, which currently needs a classloader

17:05 jgracin: rhickey: does compiling to .class files mean we won't have to use gen-and-save-class?

17:05 to interact with Java frameworks.

17:05 rhickey: jgracin: folding genclass into AOT is next

17:06 jgracin: cool!

17:06 Nafai: This is exciting

17:08 AWizzArd: My new signature for usenet (like comp.lang.lisp): "Lisp is not dead. It's just the URL that has changed: http://clojure.org" :-)

17:08 hoeck: haha

17:09 Nafai: AWizzArd: Nice!

17:11 Chouser: AWizzArd: can I put that on a shirt?

17:11 AWizzArd: of course

17:11 kib2: AWizzArd: excellent

17:13 Chouser: http://www.zazzle.com/i_get_more_done_when_im_lazy_clojure_shirt-235544064302391169

17:14 AWizzArd: hehe

17:19 rhickey: From Stuart Halloway's book: "Clojure feels like a general-purpose language beamed back from the near future"

17:20 * Zak won't dispute that.

17:20 H4ns: i like the book so far, it is quite an easy read and conveys a lot of information.

17:21 Zak: Though I think any general-purpose language in an early stage of development SHOULD feel like it comes from the future.

17:21 AWizzArd: rhickey: yeah, a job well done.. even small details are nice, like when-not vs. unless. I already told Chouser that for me (as a non-native speaker) a translation was needed.. I always read "unless" as "when-not".

17:21 H4ns: what i find a little disturbing is that it refers to the manual.pdf file in the google group, which is propably outdated today, but certainly in a few weeks.

17:22 rhickey: have you ever considered adding a (or my) style sheet for the printable version of the wiki pages? that way, it would be easier to maintain a current version. my manual process was rather tedious.

17:25 jgracin: I'm trying to use Spring from Clojure. Spring has ClassPathXmlApplicationContext which loads resources from classpath. However, it cannot find anything. Only RT/ROOT_LOADER can getResource() stuff...

17:25 which I would expect SystemClassLoader would.

17:26 What am I doing wrong?

17:26 basically, (new org.springframework.context.support.ClassPathXmlApplicationContext "classpath:appcontext/spring-initial.xml")

17:26 says it cannot find resource

17:27 and via RT it's there (minus "classpath:" prefix which is mandatory in Spring)

17:27 and (.getResource (classLoader/getSystemClassLoader) can't find it either

17:31 Chouser: jgracin: are you using add-classpath instead of -cp on the command-line?

17:31 hiredman: have you tried it without the classpath prefix?

17:31 Chouser: http://www.zazzle.com/lisp_is_not_dead_shirt-235516896396062966

17:31 jgracin: Chouser: yes

17:31 oh, I get it

17:32 Chouser: thanks!

17:36 rhickey: H4ns: my brother Tom is in charge of the style sheet stuff

17:36 H4ns: rhickey: so i could send him my suggested style sheet changes.

17:37 rhickey: H4ns: he's heard, I think

17:38 H4ns: rhickey: ok.

18:04 AWizzArd: Guys, we should also see if we can make some additions to the computer language shootout in Clojure.

18:07 Lau_of_DK: (defn time-it

18:07 [expr]

18:07 (let [start (System/nanoTime)

18:07 result (expr)]

18:07 #^{:time (/ (double (- (. System (nanoTime)) start)) 1000000.0)}

18:07 result))

18:07 Drinks are on Rich for the person who spots the error? :)

18:10 duck1123: just guessing, result is evaluated in the let

18:10 wwmorgan: (expr) needs to be an IObj ?

18:10 Lau_of_DK: an IObj ?

18:10 * duck1123 doesn't have a running clojure on him

18:11 wwmorgan: yeah. If you passed in (fn [] 4) it'd break I think

18:12 AWizzArd: Lau_of_DK: not wrong but evil: this function has only one arity but still you put it's parameter vector on a separate line (and not to the function name, where it belongs)

18:13 wwmorgan: Also #^ is reader syntax. You probably want with-meta

18:14 H4ns: AWizzArd: you are wrong. in clojure, the docstring goes between the function name and the argument vector, so it is not uncommon to put the argument vector on a new line

18:14 wwmorgan: otherwise you're attaching metadata to the symbol result, when what you want is to be attaching metadata to the IObj result

18:15 AWizzArd: H4ns: yeah, only that there is no docstring.

18:15 Zak: Does the new AOT compiler have the ability to generate a main method for the class files it creates (e.g. from an appropriately-named fn)?

18:15 wwmorgan: then that's the bug: there should always be a docstring

18:15 Lau_of_DK: defmacro time

18:15 "Evaluates expr and prints the time it took. Returns the value of

18:15 expr."

18:15 [expr]

18:15 `(let [start# (. System (nanoTime))

18:15 ret# ~expr]

18:15 H4ns: AWizzArd: i did not say that there is one. i said that in clojure, there is nothing wrong with putting a newline after the function name.

18:15 Lau_of_DK: (prn (str "Elapsed time: " (/ (double (- (. System (nanoTime)) start#)) 1000000.0) " msecs"))

18:15 ret#))

18:15 H4ns: Lau_of_DK: would you consider using a pastebin?

18:15 lisppaste8: url

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

18:15 Lau_of_DK: This is the original, and I just want to wrap the result around the return as meta

18:15 hiredman: if you add a docstring that describes the bug, it is now a feature

18:15 Lau_of_DK: H4ns, no thank you

18:16 H4ns: Lau_of_DK: thank you! very kind.

18:16 Lau_of_DK: H4ns, no probs :)

18:17 wwmorgan: Lau_of_DK: use with-meta instead of #^, but you still have the problem that expr has to be an IObj

18:18 AWizzArd: H4ns: it is also not wrong in CL, but not common. I can't see it being common in Clojure. When I look at Richs ants.clj or into the book by Stuart Halloway I see the parameters in the same line as the function name, as long there is no docstring present or the function has 2+ arities

18:18 Lau_of_DK: wwmorgan, can you just educate me on what IObj is ?

18:18 H4ns: AWizzArd: *shrug* i'm not the one to argue here. i'd just not claim that it is "evil"

18:19 wwmorgan: Lau_of_DK: this chart may be old but it should be accurate: http://clojure.googlegroups.com/web/chart.png?gda=0kdaHzsAAABoLitVpBTEcNIQc_NHg39SwaZsbT3VqBTlVOBvdHb7yiuq-FEWrXmgYiTWWcOQKecGRdr3QrylPkw2aRbXD_gF

18:19 AWizzArd: H4ns: well okay, when you present it like this then I agree that evil is maybe not the right word.

18:20 wwmorgan: IObjs include vars, symbols, and clojure collections

19:03 gnuvince_: I am using HTMLParser to extract information from a web page. HTMLParser does not allow filtering the value of an attribute with a regular expression, so I need to use their visitor pattern method. The .visitAllNodesWith method returns void. How can I accumulate the tags I'm interested in into a collection? I'm using a proxy object for the method call: (proxy [NodeVisitor] [] (visitTag [tag] (what goes here?)))

19:05 Global ref?

19:06 Chouser: well, since it's all happening in a single thread (presumably) you could use (binding ...) and (set! ...)

19:07 have you considered tagsoup and zip-filter? That's how I've done web-page scraping.

19:07 gnuvince_: I looked at TagSoup.

19:07 Didn't like it.

19:07 There's no documentation on the website.

19:08 Chouser: ok. It worked well for me because I could plug it into the clojure.xml parser and then use zip-filter on it.

19:08 gnuvince_: HTMLParser seems closer to what I want to do anyway.

19:09 Chouser: ok

19:09 gnuvince_: How is binding different from let?

19:10 Chouser: binding is dynamic rather than lexical

19:10 gnuvince_: ah

19:10 this should be mentioned in the documentation stirng.

19:10 string

19:10 Chouser: heh, yeah, perhaps. :-)

19:12 gnuvince_: I'm unsure how to use binding...

19:12 Shouldn't: (let [x 10] (binding [x 20] (prn x)) (prn x)) work?

19:15 hiredman: gnuvince_: do you get unable to resolve symbol x?

19:15 gnuvince_: yes.

19:15 well, var x

19:16 hiredman: nm

19:17 oh

19:17 you need to create the var

19:17 before you can bind

19:17 gnuvince_: Isn't it created in the let?

19:18 hiredman: *shrug*

19:18 Chouser: yeah, now that I think about it, the differences between binding and let are more profound than just "lexical" and "dynamic"

19:18 binding is for vars. A var is a real object that manages mutable state. let creates an immutable local.

19:18 hiredman: let seems to override binding

19:19 Chouser: hiredman: shadow them, yes.

19:19 hiredman: Chouser: the s-exp gnuvince_ pasted prints 10 twice for me

19:19 so even inside the binding, x is still 10

19:20 Chouser: (def x) (defn px [] (println "x is" x)) (binding [x 10] (px))

19:21 hiredman: yeah, now wrap the binding in a (let [x 20] ...)

19:21 gnuvince_: I'll paste the code in a couple minutes

19:21 We'll see if binding could make it better

19:21 hiredman: Chouser: nm, my repl must be unclean

19:22 Chouser: hiredman: heh, ok.

19:31 gnuvince_: lisppaste8: url

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

19:31 gnuvince pasted "html parser" at http://paste.lisp.org/display/70171

19:32 gnuvince_: Could this be improved (i.e. made more modular) with binding?

19:34 Hmmm

19:34 Chouser: I don't think the structure of your code would be significantly different.

19:34 gnuvince_: I still need to pre-define imgs outside the let

19:34 Chouser: you'd still need a (def imgs ...)

19:34 right

19:35 though actually, you don't need that with ref

19:35 you could put your (ref []) inside your let

19:36 Chousuke: hmm, is that a proper way to use refs? what if some thread alters the ref to point somewhere else between (empty? @imgs) and the rest?

19:36 gnuvince_: I don't know if it's the proper way

19:36 Chouser: similarly you could use with-local-vars to get a local var and then use set!

19:37 gnuvince_: all I know is that .visitTag returns void.

19:37 So I need to store my results *somewhere*

19:37 Chousuke: maybe you should do something like (let [images @imgs] ..

19:40 gnuvince_: Chouser: with-local-vars allows mutations?

19:41 lisppaste8: Chouser annotated #70171 with "a couple untested alternatives" at http://paste.lisp.org/display/70171#1

19:41 Chouser: gnuvince_: yep

19:42 both those alternatives should satisfy Chousuke -- no external access to imgs, so no way some rogue thread could mess you up.

19:45 sohail: is there a ctypes for java?

19:45 Chouser: JNA

19:46 sohail: that's the one

19:46 Chouser: sohail: http://groups.google.com/group/clojure/browse_thread/thread/77e626c5440bf1a0

19:46 sohail: have any experience with it Chouser ?

19:46 gnuvince_: Chouser: thanks for the help

19:46 Chouser: gnuvince_: np!

19:46 sohail: nope, just what abrooks has told me.

19:46 gnuvince_: Your first suggestion is what I should've thought of :-/

19:46 sohail: looks good

19:47 gnuvince_: I'm embarassed

19:47 sohail: that's nothing

19:47 gnuvince_: By the way, does this style of coding happen to anyone else: lots of things in the let declaration, but only a few lines in the actual body?

19:48 sohail: one time in grade 3, we were supposed to change for gym and I thought I had my shorts underneath my pants

19:48 gnuvince_: sohail: ok, that's more embarassing

19:48 sohail: it is

19:50 gnuvince_: I've had the good fortune to repress all bad childhood memories.

19:50 Maybe that,s why I couldn't remember this...

19:50 Maybe this conversation has happened before!

19:50 danlarkin: freaking deja vu!

19:53 Chouser: gnuvince_: sometimes, yes. Feels kind of imperative, doesn't it.

19:53 you know it's really bad when you start re-using the same name

19:54 gnuvince_: Chouser: it does, but is it really better to have a 6 line expression like people in Haskell sometimes end up with

19:54 Chouser: (let [x 10 x (/ x 5) x (replicate x x) x (map inc x)] x)

19:54 gnuvince_: yeah, I don't know.

19:55 * gnuvince_ smells a blog post ;)

20:31 lisppaste8: Chouser annotated #70171 with "tested alternative using zip-filter" at http://paste.lisp.org/display/70171#2

20:32 Chouser: not the most impressive showing for zip-filter, I'll admit.

20:33 gnuvince_: What's zip-filter?

21:01 Chouser: clojure.contrib.zip-filter, for selecting particular nodes from a zip tree.

22:02 bradbev: how does one do modulus in Clojure? ie, 2 % 5

22:04 duck1123_: rem

22:04 hiredman: mod

22:04 bradbev: (rem ...)

22:04 thanks :)

22:04 hiredman: bah, that is horrible

22:04 I was so sure I knew the answer

22:05 bradbev: I expected mod also

23:43 sohail: Chouser, jna is pretty awesome man :-)

23:43 no messy JNI needed

23:43 just like cffi from CL

23:47 Nafai: Any decent language has a built in FFI :)

23:49 sohail: it was only a matter of time before someone did it for Java

23:49 though CL doesn't have a cffi

23:49 *ffi

23:50 Nafai: Probably more correct to say any decent language implementation

Logging service provided by n01se.net