#clojure log - Mar 30 2009

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

0:24 cooldude127: damn irc is boring at night

0:30 cmvkk: everyone's coding

1:14 Raynes: http://xkcd.com/289/

1:14 slashus2: What is the best way to represent a binary tree when coding in clojure?

2:33 Most of the examples of zippers that I find are in haskell :-(.

2:50 * Raynes is reading Twilight for some god awful reason.

3:17 l_a_m: i ve got a problem to setup Slime with clojure : http://paste.lisp.org/display/77765

3:17 SLIME works fine with my SBLC configuration but i can t setup clojure

3:17 any help ?

3:29 tsdh: Hi.

3:29 Is it possible to use clojure and swank to override a static method in java.lang.StrictMath?

3:39 antifuchs: l_a_m: the error says it all: you need to set swank-clojure-binary (to a script that will start clojure) or swank-clojure-jar-path (to the path where the clojure.jar file is located)

3:39 clojurebot: it is too

3:45 antifuchs: l_a_m: are you referring to bill clementson's notes? these were pretty helpful for getting me up to speed (:

3:46 MikeSeth: l_a_m: clojurebox has scripts to configure slime

3:46 dunno if that helps

4:04 l_a_m: antifuchs: yeah

4:04 antifuchs: but in my config i set the swank-clojure-jar-path

4:04 antifuchs: (setq swank-clojure-jar-path "/usr/local/src/clojure-language/clojure/clojure.jar") ?

4:04 antifuchs: oh, I think that's the same problem I ran into

4:04 l_a_m: so i don t really understand ...

4:04 antifuchs: you might have to set this before you require 'swank-clojure-autoload

4:04 l_a_m: ok

4:04 i try this one

4:04 antifuchs: I suppose you're loading slime before this block?

4:04 l_a_m: antifuchs: do you replace SBCL by Clojure ? :)

4:04 antifuchs: definitely not (:

4:04 both have their place in my setup (:

4:04 l_a_m: :)

4:04 my company wants only use Java ...

4:04 so Clojure could be a nice language :)

4:04 antifuchs: it is!

4:04 Raynes: It's the best thing evar.

4:04 antifuchs: let's not get carried away here. bacon is still pretty excellent.

4:05 Raynes: Oh yeah, I forgot about bacon.

4:14 MikeSeth: is this a reddit convention now? all sins written off for the sake of bacon?

4:29 antifuchs: it is happening all over the internet. I doubt this is reddit's doing.

4:31 anyway, my point should have been: don't believe universal best-ness claims for a second. everything has trade-offs.

4:32 clojurebot: for is not a loop

4:32 * antifuchs pats clojurebot

4:51 MikeSeth: is clojurebot written in clojure?

4:51 clojurebot: status

4:51 clojurebot: It's greek to me.

4:56 Holcxjo: MikeSeth: http://github.com/hiredman/clojurebot/tree/master

4:56 MikeSeth: The higher levels are -- the IRC comms are done by some Java lib I believe

5:08 MikeSeth: nice

5:11 AWizzArd: clojurebot: max people

5:11 clojurebot: max people is 164

5:18 rsynnott: MikeSeth: that'd be inverse judaism?

5:18 l_a_m: antifuchs: thanks

5:18 now i ve got this error : http://paste.lisp.org/display/77772

5:18 clojure repl seems working but not slime

5:20 rsynnott: l_a_m: recent versions of both clojure-swank and slime?

5:20 msingh: so is there a book to read to learn clojure?

5:22 l_a_m: rsynnott: i thought i updated them on friday ... i check

5:24 rsynnott: yes with git version of these 2 components

5:58 any idea for this error ?

6:16 hoeck: l_a_m: looks like swank tries to execute some common lisp code in clojure (swank::read-motd)

6:16 l_a_m: hoeck: strange

6:16 hoeck: maybe this comes from a slime extension package/module?

6:17 l_a_m: hoeck: i check ...

6:23 hoeck: l_a_m: they are activated with the slime-setup command

6:23 l_a_m: ok thanks it works fine now

6:36 MikeSeth: rsynnott: inverse judaism?

6:37 ah you mean bacon

6:37 lol

6:37 not really though, jewish sins get written off once a year unconditionally :P

6:37 is there a clojure port for smartphones?

6:40 hoeck: MikeSeth: there is remvee trying to run clojure on android: http://wiki.github.com/remvee/clojure

7:09 antifuchs: hm, is there an analogue to common lisp's CASE form in clojure?

7:09 hm, clojure.contrib.fcase, I suppose

7:13 hoeck: antifuchs: or condp

7:14 ,(condp = :b :a 'a :b 'b)

7:14 clojurebot: b

7:15 antifuchs: excellent

7:15 even gives me an IllegalArgumentException for unknown clauses. so it's like ecase, which I was actually looking for :

7:15 thanks

7:20 AWizzArd: antifuchs: you can specify a last form in condp which is used as default of no other match is found. It should not be a pair of test and expression, but only an expression.

7:20 antifuchs: that makes sense; for this case, the exception is better, though (:

7:51 AWizzArd: antifuchs: yesterday we were talking about defining a my-apply, and I mentioned your macro which can fake it for some cases of apply. Maybe we should try a clojure version of it?

7:55 antifuchs: which of my macros? (-:

8:04 AWizzArd: you once wrote a macro that can create apply like functions

8:17 tsdh: Sorry for asking again, but is it possible to override a static method of a standard java class using swank and clojure?

8:19 rhickey_: tsdh: there's really no such thing as 'overriding' a static method. Do you want to replace it, or have a same-named function in a derived class?

8:19 AWizzArd: tsdh: I am not a Java man, but I would say that it is not possible to override any method. The official way to do that could be to derive a class and have a method there with the same name.

8:20 tsdh: rhickey_: Right, I want to replace it.

8:20 rhickey_: tsdh: not possible

8:20 tsdh: Too bad. Thanks anyway.

8:21 AWizzArd: tsdh: I think it is not bad, but instead extremly good. One should not be able to do that. Also one should not be able to replace 14 with a -3.

8:23 tsdh: At least in my situation it would be handy. I have to use a component which is just a blackbox (jar), and profiling shows that most time is spent in StrictMath.floor(). But nothing relies on complience of StrictMath, so Math.floor() would be as good, but possibly much faster.

8:40 in-code-we-trust: is planned to port clojure to .net/mono framework?

8:50 hoeck: in-code-we-trust: http://code.google.com/p/clojure-contrib/source/browse/#svn/trunk/ClojureCLR is the beginning of a clojure port to .net

8:50 in-code-we-trust: hoeck: thnx

10:06 hiredman: http://blogs.sun.com/CoreJavaTechTips/entry/closing_a_urlclassloader

10:10 cemerick: heh. I remember having to implement that sort of thing in my own home-baked classloader years ago. Nice to see it's going to be available in jdk *SEVEN*!

10:10 * cemerick sighs

10:11 AWizzArd: Will jdk 7 also support tagged numbers?

10:11 * rhickey_ sighs too

10:11 cemerick: AWizzArd: I thought not, but I'll bet rhickey_ has the latest scoop there.

10:11 clojurebot: latest is 1337

10:11 rhickey_: AWizzArd: nope

10:12 AWizzArd: I see.

10:12 cemerick: of course it's jdk *SEVEN*, which likely won't be released for another 9-12 months, nevermind usable for redistributed libraries, etc. :-/

10:13 * cemerick is in a jvm-development-pace-bashing mood today, apparently

10:13 cemerick: probably brought on by grumpiness associated with being back in Swing-land

10:14 AWizzArd: ah, but will they not have improvements for Swing in jdk 7?

10:14 cemerick: Chouser: FYI, titanium isn't fully-baked yet, BTW.

10:14 AWizzArd: you're just trying to bait me :-D

10:23 danlarkin: morning clojurecrats!

10:23 WizardofWestmarc: morning danlarkin

10:23 btw finally got around to getting madison loadable in my repl last weekend

10:40 gnuvince: Is anyone here knowledgeable about java.nio? Specifically, I need to know if I can have a view Buffer (for example, (.asIntBuffer byte-buf)) where change in the position of one affects the other?

10:41 Cark: gnuvince : if you find out let me know

10:41 may i ask what you're doing with nio ?

10:41 gnuvince: Cark: http://bitbucket.org/gnuvince/clj-starcraft/src

10:42 Cark: I found that the program that is backed by the unpacking Java library that I use is more than an order of magniture faster than my Clojure implementation.

10:42 I've been toying around for the past 2-3 weeks trying to find some way to give my program a boost

10:42 I've been unsuccessful so far.

10:43 Cark: so you turning to nio ?

10:43 gnuvince: I used nio, but I used getShort and getInt on the byte buffer

10:44 I'm want to try with view buffers (which the documentation says could improve performance), but if I can't keep track of what's been read, I don't gain a lot.

10:45 Cark: i see ... i'm working on a TCP server

10:45 with ssl

10:45 gnuvince: More useful than what I'm doing :)

10:45 Cark: haha well who cares =P

10:46 it's too ugly right now to let anybody see it

10:46 clojurebot: it is too

10:46 antifuchs: AWizzArd: (about the apply macro) omg, that was supposed to be humorous (:

10:46 gnuvince: Hmmm

10:46 Well I guess I'll have to manually move the buffer :-/

10:48 AWizzArd: antifuchs: Was a nice hack anyway. And it even worked for several cases.

10:49 Cark: i found this buffer business is all very imperative

10:49 clojure isn't so well suited for that

10:49 antifuchs: AWizzArd: you're starting to scare me ((-:

10:49 but I'm glad that it works (:

11:08 danlarkin: WizardofWestmarc: sweet! Wish I had more (any) time to improve on it, work picked up as we near a launch

11:13 duderdo: Hello!

11:13 How can I step through my clojure code to debug?

11:14 hiredman: as far as debuggers go, most people use jswat

11:15 I think

11:15 I just write little functions and test them

11:15 duderdo: But there's no step like in SBCL?

11:15 Hrm, okay thanks

11:16 AWizzArd: Btw, did anyone here use Maven for her Clojure projects?

11:17 hiredman: woa

11:31 triddell: FYI: I just posted links to some android/clojure tutorials I wrote to the google group.

11:31 android with emacs and clojure that is

11:31 AWizzArd: Is there a problem to have a namespace having the name of some Java class? Example (ns com.company.XmlRpcClient (:include (org.apache.xmlrpc.client XmlRpcClient)) (:gen-class))

11:32 danlarkin: AWizzArd: perhaps you meant :import instead of :include?

11:32 AWizzArd: right, :import

11:33 danlarkin: oh, thought that might've been in your actual code

11:33 AWizzArd: No sorry, my thoughts were drifting away a bit while I typed that.

11:45 WizardofWestmarc: danlarkin: understandable. At some point (not now, not at lappy w/the setup) I will probably need to pick your brain a bit to get it actually running a web page

11:45 and once I get going I may see about doing updates myself to help you out if need be.

11:45 danlarkin: rad

12:16 kefka: I may have found a bug (?) in clojure.set/difference:

12:16 ,(clojure.set/difference #{0 1 2} [0 2])

12:16 clojurebot: #{1}

12:16 kefka: ,(clojure.set/difference #{0 2} [0 1 2])

12:16 clojurebot: #{}

12:16 hiredman: ,(doc clojure.set/difference)

12:16 clojurebot: "([s1] [s1 s2] [s1 s2 & sets]); Return a set that is the first set without elements of the remaining sets"

12:16 kefka: ,(clojure.set/difference #{"0" "2"} ["0" "1" "2]")

12:16 clojurebot: Unmatched delimiter: )

12:16 kefka: ,(clojure.set/difference #{"0" "2"} ["0" "1" "2"])

12:16 clojurebot: #{"0" "2"}

12:16 stuhood: hmm.

12:16 kefka: It worked fine for the difference of #{0 2} [0 1 2], returning the empty set.

12:16 stuhood: ,(class #{"1"})

12:16 clojurebot: clojure.lang.PersistentHashSet

12:16 hiredman: ,(clojure.set/difference #{"0" "2"} #{"0" "1" "2"})

12:16 clojurebot: #{}

12:16 hiredman: if you are doing set operations, use sets

12:16 kefka: Yes, it works properly if you convert it into a set.

12:16 It's not a major issue, but it threw me off, because I had assumed that the 2nd element could be an arbitrary collection.

12:16 hiredman: the fact that it works on non-sets should be considered an accident

12:16 AWizzArd: That could be easily done, but you need to be aware that this is potentially a very slow operation.

12:16 hiredman: the doc string only mentions sets

12:17 kefka: It's also awkward that this bug (as easy as it is to work around) works on integers but not strings.

12:17 AWizzArd: It is very fast to loop up if X is an element of a set. But to test if X is an element of a vector is in general not a fast operation.

12:18 hiredman: I fail to see how having undefined behaviour for something not covered by the docstring is a bug

12:18 ~def clojure.set/difference

12:18 slashus2: ,(clojure.set/difference #{0 1 2} #{1})

12:18 clojurebot: #{0 2}

12:19 slashus2: ,(clojure.set/difference #{0 1 2} [1])

12:19 clojurebot: #{0 2}

12:19 slashus2: That is what you are trying to do?

12:19 You take the elements in the first set, and remove the elements in the remaining set.

12:28 AWizzArd: what this function could do is maybe throwing an exception

12:28 if not both args are sets

12:28 slashus2: ,(clojure.set/difference [0])

12:28 clojurebot: [0]

12:28 AWizzArd: Even better if it would throw a compile time exception. This could be done with Gradual Typing. See http://groups.google.com/group/clojure/browse_frm/thread/7a48f48e4b197a15

12:28 hiredman: AWizzArd: if you want it, it would be great if you could write it :P

12:28 AWizzArd: Unrealistic, as I have no time for that. *sigh*

12:28 hiredman: I think it would be nice, but I don't constantly bring it up, because I am not actively working/thinking about it

12:29 AWizzArd: I also think it would be nice, even very nice. As long it is optional.

12:30 And I think it is also no problem at all to bring up an issue from time to time, even if one is not the right person for implementing it.

12:30 hiredman: sure

12:30 AWizzArd: What I can offer is to be an extensive tester for this.

12:34 hiredman: ,(- 2176 - 2009)

12:34 clojurebot: java.lang.ClassCastException: clojure.core$___3339 cannot be cast to java.lang.Number

12:34 hiredman: ,(- 2176 2009)

12:34 clojurebot: 167

13:45 Lau_of_DK: Hey guys

13:47 danlarkin: Hello to my favorite dane

13:48 Lau_of_DK: Uh what an honor :)

14:02 kefka: Is there a fast way O(log n) of getting the min. and max. elements from a sorted set?

14:04 Lau_of_DK: (apply max set)

14:04 ?

14:04 kefka: I'm thinking that would call max with all the elements as args.

14:04 (first (seq set)) should work for the minimum.

14:04 cgrand: kefka: first and peek ?

14:04 kefka: (doc peek)

14:04 clojurebot: For a list or queue, same as first, for a vector, same as, but much more efficient than, last. If the collection is empty, returns nil.; arglists ([coll])

14:04 cgrand: maybe not

14:04 hiredman: erm

14:04 kefka: peek does not work on sorted-sets

14:04 hiredman: ,(last (seq set))?

14:04 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: core$set__4299

14:04 hiredman: ,(sort-set 1 4 3 2)

14:04 clojurebot: java.lang.Exception: Unable to resolve symbol: sort-set in this context

14:04 cgrand: ,(.last (sorted-set 1 4 3 2))

14:04 clojurebot: java.lang.IllegalArgumentException: No matching field found: last for class clojure.lang.PersistentTreeSet

14:04 kefka: ,(let [the-set (apply sorted-set (range 100000))] (time (first the-set)))

14:04 clojurebot: 0

14:04 "Elapsed time: 0.111 msecs"

14:04 kefka: ,(let [the-set (apply sorted-set (range 100000))] (time (last the-set)))

14:04 clojurebot: 99999

14:04 "Elapsed time: 133.447 msecs"

14:04 kefka: ,(let [the-set (apply sorted-set (range 100000))] (time (first (reverse the-set))))

14:04 clojurebot: 99999

14:04 "Elapsed time: 160.627 msecs"

14:05 cgrand: clojure's sorted sets don't implement java.util.SortedSet !?

14:05 kefka: ,(let [the-set (apply sorted-set (range 100000))] (time (first (subseq the-set > -1000))))

14:05 clojurebot: 0

14:06 "Elapsed time: 2.758 msecs"

14:06 durka42: (doc subseq)

14:06 clojurebot: sc must be a sorted collection, test(s) one of <, <=, > or >=. Returns a seq of those entries with keys ek for which (test (.. sc comparator (compare ek key)) 0) is true; arglists ([sc test key] [sc start-test start-key end-test end-key])

14:07 cgrand: ,(first (rseq (sorted-set 2 4 3 1)))

14:07 clojurebot: 4

14:07 kefka: ,(let [the-set (apply sorted-set (range 100000))] (time (first (rseq the-set))))

14:07 clojurebot: 99999

14:07 "Elapsed time: 0.065 msecs"

14:08 kefka: rseq is the trick.

14:08 Apparently rseq is smart enough re: sorted sets to read efficiently from the max-end.

14:11 cgrand: rseq works on anything that implements IReversible

14:59 hiredman: I wonder if there is someway to make ring play with quercus

14:59 ~ring

14:59 clojurebot: ring is http://github.com/mmcgrana/ring/tree/master

14:59 durka42: ick, why would you want to use php :)

14:59 marklar: How do you call the super class constructor when you are extending a Java class with gen-class?

15:00 erm, sorry I meant a super class method, not constructor

15:02 hiredman: you would use :exposes-methods

15:02 http://clojure.org/API#gen-class

15:04 marklar: hiredman: thanks, I read that completely wrong

15:36 Raynes: hiredman: You're still my hero <3

16:07 cemerick: rhickey: it looks like AOT compilation hangs if a JFrame is created and .pack()'ed as a side effect of loading the file(s) being compiled. That's obviously not good in general (I hit this while mucking around casually), but perhaps some mechanism should exist so that the compilation process is safe from non-referentially-tranparent expressions being def'ed? This sort of thing would be a *bear* to debug in anything other than a trivial file.

16:26 hiredman: ~ticker JAVA

16:29 clojurebot: JAVA; -7.54

16:29 rsynnott: sun still in its IBM-acquisition-possibility glow, I see

16:29 danlarkin: haha

16:29 rsynnott: (they only want it for the ticker symbol)

16:29 clojurebot: it is too

16:29 cemerick: the #1 thing that will come out of that acquisition will be the elimination of the JAVA ticker :-)

16:29 danlarkin: which exchanges does clojurebot know about?

16:29 hiredman: that is triggered far to often

16:29 danlarkin: ~ticker CHINA

16:29 clojurebot: CHINA; -5.26

16:29 danlarkin: :( china

16:29 rsynnott: cemerick: nah, IBM will start using it for themselves

16:29 they have a bit of a java fetish these days

16:29 hiredman: I have no real idea how to read the json data from google for finance stuff

16:29 cemerick: not enough that they'd drop IBM...

16:29 danlarkin: hiredman: how do you mean? to get info other than the delta for the day?

16:29 hiredman: yeah

16:29 http://www.google.com/finance/info?q=JAVA

16:30 durka42: ~ticker GM

16:30 clojurebot: GM; -25.41

16:30 hiredman: I remove junk at the begining and at the end of that and use your json parser on it

16:30 danlarkin: yeah this is oddly formatted

16:30 / [

16:30 er double slash open bracket, wonder what that's about

16:30 hiredman: and the closing bracket

16:30 durka42: a comment

16:30 danlarkin: json doesn't have comments, but even if I were to accept it was supposed to be a comment... why is it in the production feed? and why is the closer still there? it's wacky!

16:30 hiredman: ~ticker IDSGX

16:30 clojurebot: IDSGX; -2.17

16:52 cooldude127: do we already have a clojure library for writing CSV files?

16:53 clojurebot: clojure is the brand

16:53 hiredman: I don't think so. I have used supercsv in the past with clojure http://supercsv.sourceforge.net/

16:53 it seems decent enough

16:53 zakwilson: cooldude127: I wrote my own library to read/write CSV. It's simple, but it works.

16:53 hiredman: writing csv parses :(

16:53 cooldude127: zakwilson: you have a link to the code? i'm feeling lazy

16:53 zakwilson: http://github.com/zakwilson/zutil-clj/tree/master

16:53 May be out of date.

16:53 cooldude127: we'll find out, i probably could write something on my own, but CSV is not my focus right now

16:55 hiredman: why not supercsv?

16:56 cooldude127: just trying to get a job done, real quick for a project, so if i don't have to mess with the classpath right now, it's better

16:57 zakwilson: cooldude127: if it's simple enough, my library will do.

16:58 cooldude127: yeah just generating some values in clj, need to plot them on a graph

16:59 zakwilson: Give it a try. BSD license.

17:13 danlarkin: NIHsyndrome.com

17:13 hiredman: I guess its not too bed if you are generating your own csv file

17:58 duderdo: What's the best way to figure out how to use swing components in clojure? Looking at the java docs is overwhelming to say the least

17:59 danlarkin: ughhhh bitten again by not being able to give metadata to Strings

17:59 grrrrrrrrrrrrrrrrr

17:59 zakwilson: danlarkin: if you're talking about my CSV library as NIH syndrome, that may be the case, but using the first couple Java libs I found looked harder than just writing one in Clojure.

17:59 slashus2: It may be useful to make it to where strings can accept metadata.

18:00 danlarkin: I would even accept (with-meta "foo" {:foo :bar}) returning a clojure.lang.String, which could implement IObj

18:00 slashus2: I guess it is for compatibility purposes.

18:00 ?

18:01 danlarkin: well it's so strings can be java.lang.Strings

18:01 AWizzArd_: danlarkin: you could write your own with-meta macro which expands into with-meta for all data, but for strings it will write the data into your own hashmap

18:01 danlarkin: and metadata-able classes must implement IObj, which java.lang.String does not

18:02 AWizzArd_: but I don't want to return a hashmap, I want a string :/

18:02 AWizzArd_: the macro could return a string, but under the hood write into your own metadata container

18:03 instead of using the official getter/setter for metadata you write your own

18:03 and use those instead

18:03 danlarkin: except in the case that I want to ignore the metadata... I can't, because now I'm returning a hashmap instead of a string

18:03 AWizzArd_: (danlarkins-with-meta ...)

18:04 danlarkin: might as well just return a hashmap with a :text attribute and whatever metadata I wanted, put it right in the hashmap

18:05 AWizzArd_: Yes, but then all your code needs to deal with a hashmap, and not a string

18:05 danlarkin: but wouldn't that be the case with the way you're suggesting too, or am I missing something?

18:06 AWizzArd_: what i was thinking about was more: you have a (def string-metadata (ref {})) into which you put the metadata for your strings, when you use your (danlarkins-with-meta ...)

18:07 danlarkin: ohhh. hm

18:07 that's awful ugly :-/

18:07 AWizzArd_: why?

18:07 hiredman: zakwilson: supercvs's CVSReader is very nice

18:08 AWizzArd_: danlarkin: instead of (meta ..) for reading metadata, you can use (danlarkins-meta ..). And instead of (with-meta ..) for attaching meta data, you will use danlarkins-with-meta.

18:09 It would look basically the same to what you have now, only the name changes.

18:09 hiredman: http://gist.github.com/87909 is kind of a bad example because the data I was reading was very, uh, dirty

18:10 danlarkin: AWizzArd_: sorta... except for some crucial areas, like two different "copes" of the same string couldn't have different metadata, which I need

18:11 sorry, "copies"

18:12 instances would actually be a better word

18:12 welp... I guess I just have to return a map with :text

18:12 hiredman: having a metadata slot is so nice, I wonder if sun would consider adding one to Object :P

18:12 AWizzArd_: danlarkin: if Java makes it possible to fetch the address of an object in ram, then you would have a unique key for your meta data store

18:13 makes it possible ==> allows

18:15 Also you could work around this and add all strings into a vector, which you traverse and then check for identity.

18:15 danlarkin: I think Java does... doesn't it? how does identical? work

18:15 AWizzArd_: The actual string + the index in that vector could be the key then

18:15 Of course it must be possible somehow, otherwise the GC couldn't work. I just don't know if Sun gives users access to that information.

18:16 danlarkin: I think I'm going with the path of least resistance

18:17 AWizzArd_: danlarkin: anyway, if you don't care strongly about amazing performance for retrieving metadata, and if you don't intend to have millions of copies of otherwise identical strings, then the trick with a hashmap + vector would be ok

18:17 hiredman: ,(identical "a" "a")

18:17 clojurebot: java.lang.Exception: Unable to resolve symbol: identical in this context

18:17 hiredman: ,(identical? "a" "a")

18:17 clojurebot: true

18:18 AWizzArd_: because those are constants

18:18 hiredman: ,(identical? "a" (str \a))

18:18 clojurebot: false

18:18 AWizzArd_: good :)

18:18 so, make that macro store these strings in a vector

18:18 hiredman: ,(identical? (str \a) (str \a))

18:18 clojurebot: false

18:19 hiredman: ,({(str \a) 1 (str \a) 2} "a")

18:19 clojurebot: 1

18:19 hiredman: ugh

18:19 hmmmm

18:19 AWizzArd_: when reading the metadata you make a lookup for that string. If that key does not exist, traverse your vector (filter #(identical? % s) vector-of-metadata-strings)

18:19 clojurebot: for is a loop...in Java

18:19 AWizzArd_: if that returns something, then make another lookup in the hashmap for the vector ["String here" index]

18:20 and that will then return the metadata for you

18:20 even for copies

18:21 bah, my filter above misses the indexes of course

18:21 hiredman: ~def c.l.IObj

18:21 hmmm

18:21 ~def c.l.IMeta

18:21 danlarkin: AWizzArd_: I think that's just too much hassle for what I'm doing

18:22 AWizzArd_: well, it first sounded as if you really want metadata for strings

18:22 hiredman: you could proxy String Imeta and IObj

18:22 danlarkin: I do... but not at the cost of totally uglifying the program

18:22 AWizzArd_: And Clojure is a Lisp, so for a lot of things you won't need its implementor to do work for you.

18:22 But where would that program become ugly?

18:22 We are talking here about writing two macros of 5-10 lines each

18:22 hiredman: ,(proxy [String] [IMeta IObj] [])

18:22 clojurebot: java.security.AccessControlException: access denied (java.lang.RuntimePermission accessDeclaredMembers)

18:22 hiredman: oh

18:23 String is final

18:23 AWizzArd_: yes

18:23 hiredman: of course

18:23 Jerks

18:23 AWizzArd_: hehe :)

18:23 danlarkin: having to use a ref to store metadata is ugly

18:23 AWizzArd_: Why?

18:23 It is state

18:24 danlarkin: not really

18:24 AWizzArd_: mete data is about side effects / state change

18:24 Some memory cells in your computer change their electric charge

18:24 danlarkin: haha cmon that's being silly

18:25 AWizzArd_: Why?

18:25 clojurebot: why not?

18:25 AWizzArd_: clever bot

18:25 danlarkin: qed

18:25 hiredman: clojurebot: botsnack

18:25 clojurebot: thanks; that was delicious. (nom nom nom)

18:25 AWizzArd_: got too many botsnacks or what?

18:25 hiredman: ~ticker GOOG

18:25 clojurebot: GOOG; -1.44

18:25 AWizzArd_: what is ticker?

18:25 zakwilson: hiredman: superCSV looks quite usable. I'll probably use that next time I need CSV.

18:25 stuhood: ~ticker RAX

18:25 clojurebot: RAX; -7.04

18:25 AWizzArd_: ah

18:26 ~ticker CLJ

18:26 hiredman: java.io.IOException: Server returned HTTP response code: 400 for URL: http://www.google.com/finance/info?q=CLJ

18:26 stuhood: hahaha

18:26 AWizzArd_: danlarkin: instead of a ref you can use a java.util.Hashmap

18:27 I mean, how does Clojure store its meta data?

18:27 danlarkin: AWizzArd_: but that'd still be state... but worse state

18:28 hiredman: a persistant map

18:28 stuhood: clojure stores its metadata in a clojure datastructure

18:28 clojurebot: clojure is far closer to perfection then python

18:28 AWizzArd_: danlarkin: then how is Clojure doing it right now?

18:28 hiredman: it sure is

18:28 stuhood: that's why (with-meta) doesn't modify the argument you give it

18:28 hiredman: but alter-meta! does

18:28 stuhood: well, yea... because namespaces are magical =(

18:28 hiredman: ~def alter-meta!

18:28 AWizzArd_: thx hiredman

18:29 hiredman: ,(meta *ns*)

18:29 clojurebot: {:killroy-was-here #<Date Sun Mar 29 14:41:43 PDT 2009>, :a 1}

18:29 stuhood: haha

18:29 danlarkin: ha!

18:29 AWizzArd_: wtf? ;)

18:29 hiredman: ,(alter-meta! *ns* update-in [:killroy-was-here] conj (Date.))

18:29 clojurebot: java.lang.ClassCastException: java.util.Date cannot be cast to clojure.lang.IPersistentCollection

18:29 hiredman: ,(alter-meta! *ns* update-in [:killroy-was-here] cons (Date.))

18:29 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Date

18:30 hiredman: ,(alter-meta! *ns* update-in [:killroy-was-here] list (Date.))

18:30 clojurebot: {:killroy-was-here (#<Date Sun Mar 29 14:41:43 PDT 2009> #<Date Mon Mar 30 15:28:43 PDT 2009>), :a 1}

18:31 AWizzArd_: oh

18:33 lisppaste8: hoeck pasted "danlarkins-with-meta" at http://paste.lisp.org/display/77793

18:33 hiredman: ,(alter-meta! *ns* assoc :update (fn [] (alter-meta! *ns* update-in [:killroy-was-here] conj (Date.))))

18:33 clojurebot: {:update #<sandbox$eval__4753$fn__4755 sandbox$eval__4753$fn__4755@16aee36>, :killroy-was-here (#<Date Sun Mar 29 14:41:43 PDT 2009> #<Date Mon Mar 30 15:28:43 PDT 2009>), :a 1}

18:33 AWizzArd_: there you go

18:33 hoeck ist schnell

18:34 hiredman: ,((:update (meta *ns*)))

18:34 clojurebot: {:update #<sandbox$eval__4753$fn__4755 sandbox$eval__4753$fn__4755@16aee36>, :killroy-was-here (#<Date Mon Mar 30 15:32:44 PDT 2009> #<Date Sun Mar 29 14:41:43 PDT 2009> #<Date Mon Mar 30 15:28:43 PDT 2009>), :a 1}

18:35 stuhood: somebody could probably run clojurebot out of memory like that, right?

18:35 hiredman: I guess

18:35 AWizzArd_: yes, and hiredman would then ban her

18:35 :-)

18:35 danlarkin: why not add alter-meta! to the blocked forms?

18:36 hiredman: because it's a drag

18:52 devo: Is there a way to defn a function with a name that is generated at runtime?

18:52 for example, here's what I'm trying:

18:52 (def f "foo")

18:52 (defn (symbol f) [x] (+ x 1))

18:52 Cark: why do you want to do this ?

18:52 hiredman: sure

18:52 you can use gensym

18:52 (defmacro defnsym [& body] `(defn ~(gensym) ~@body))

18:52 something along those lines

18:52 Cark: that's generated at compile time

18:52 hiredman: right

18:52 AWizzArd_: gensym is just an ordinary function

18:52 hiredman: runtime

18:52 AWizzArd_: call it at runtime

18:53 hiredman: yeah

18:53 AWizzArd_: And if you need many functions, then store them in a hashmap, with the name that you generate some time during runtime

18:53 hiredman: I agree with Cark

18:53 why do you want to do this?

18:53 Cark: hum another question along the same line : how do you add a def to a namespace at runtime ?

18:53 a var i mean

18:53 hiredman: I would check the namespaces page on clojure.org

18:53 Cark: ,(find-doc "ns-assoc")

18:53 clojurebot: nil

18:53 dnolen: ,(doc intern)

18:53 clojurebot: "([ns name] [ns name val]); Finds or creates a var named by the symbol name in the namespace ns (which can be a symbol or a namespace), setting its root binding to val if supplied. The namespace must exist. The var will adopt any metadata from the name symbol. Returns the var."

18:53 devo: I'm reading in an XML file that represents database relationships, I was thinking I could essentially define a function for each table that contains its relationships

18:53 so, if I have tables: A, B and C and I know A joins to B, and B joins to C, I could call something like (A (B C)) which would give me all the join info I need to dynamically build sql

18:53 Cark: ah intern of course ><

18:53 sot here you have it ... intern the name, then assicoate a lambda with it

18:53 hiredman: devo: use a map

18:53 clojurebot: map is *LAZY*

18:53 hiredman: clojurebot: shut your pie hole

18:54 clojurebot: Excuse me?

18:54 hiredman: clojurebot: you heard me

18:54 clojurebot: Excuse me?

18:54 AWizzArd_: *g*

18:55 devo: I'll try it. I'm still dusting the cobwebs off of my LISP.

18:55 hiredman: you most likely will want (def table-functions (ref {}))

18:57 gnuvince_: ~seen cgrand

18:57 clojurebot: cgrand was last seen quiting IRC, 56 minutes ago

18:58 Cark: ,(intern *ns* (symbol "bleh") (fn [] "bleh!"))

18:58 clojurebot: #'sandbox/bleh

18:58 Cark: ,(bleh)

18:58 clojurebot: "bleh!"

18:59 Cark: hehe hiredman =P

18:59 hiredman: ~you heard me is <reply>#who: I'm just giving you a second chance

18:59 clojurebot: Ack. Ack.

18:59 hiredman: ~you hear me!

18:59 clojurebot: excusez-moi

18:59 hiredman: ~you heard me!

18:59 clojurebot: hiredman: I'm just giving you a second chance

19:00 hiredman: Cark: shhh

19:03 Cark: though i can't imagine a single instance where creating a named function at run time would be usefull

19:04 maybe creating the functional interface to an object system ...

19:05 hiredman: yeah, but how would you use it?

19:05 you need some kind of handle on the names

19:05 Cark: right

19:41 hjlee: someone said contributors can't accept patchs from non-contributor.

19:42 is that right?

19:43 danlarkin: the clojure and clojure-contrib codebases cannot, yes

19:43 hjlee: can anyone be contributor, then?

19:43 chessguy: err, is there a multi-line comment in clojure?

19:43 dnolen: ,(doc comment)

19:43 clojurebot: "([& body]); Ignores body, yields nil"

19:43 danlarkin: hjlee: clojure.org/contributing

19:43 chessguy: sorry, i'm new to clojure and i'm not sure how to read that

19:43 clojurebot: new Class(x) is (Class. x)

19:43 chessguy: wow, thanks clojurebot , that's helpful!

19:43 :)

19:43 Chousuke: ,(comment works like this)

19:43 clojurebot: nil

19:43 chessguy: cute

19:43 hjlee: danlarkin: thank you.

19:44 chessguy: Chousuke: thanks

19:46 durka42: ,(+ #_3 4 5)

19:46 clojurebot: 9

19:47 durka42: ,(+ #_(this type of comment is ignored completely, not even nil) 4 5)

19:47 clojurebot: 9

19:50 gnuvince_: How do I specify a type hint in a macro?

20:09 chessguy: so i'm looking at the macros page on clojure.org

20:10 it has this example:

20:10 user=> (macroexpand '(-> {} (assoc :a 1) (assoc :b 2)))

20:10 (assoc (clojure.core/-> {} (assoc :a 1)) :b 2)

20:10 am i reading this right, that the -> is left in the result of the macro expansion?

20:10 clojurebot: this is not a bug

20:10 chessguy: (macroexpand '(-> {} (assoc :a 1))

20:10 ,(macroexpand '(-> {} (assoc :a 1))

20:10 clojurebot: EOF while reading

20:10 stuhood: chessguy: i think it is defined recursively

20:10 chessguy: ,(macroexpand '(-> {} (assoc :a 1)))

20:10 clojurebot: (assoc {} :a 1)

20:10 stuhood: so -> expands to calling itself if you give it multiple forms

20:10 chessguy: stuhood: so the reader will automatically expand it again?

20:10 (or whatever does the expansions)

20:10 stuhood: i believe so... there might be another macroexpand that expands recursively like the reader would

20:10 chessguy: interesting

20:10 stuhood: "Note neither macroexpand-1 nor macroexpand expand macros in subforms."

20:11 clojurebot was right... it wasn't a bug =x

20:11 chessguy: haha

20:11 that's one smart bot!

20:34 gnuvince_: ,(let [x 0] (time (dotimes [_ 1000000] x)))

20:35 clojurebot: "Elapsed time: 87.759 msecs"

20:36 gnuvince_: ,(time (dotimes [_ 1000000] map))

20:36 clojurebot: "Elapsed time: 103.385 msecs"

20:36 stuhood: ,(map)

20:36 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$map

20:50 hiredman: ,(let [x map] (time (dotimes [_ 1000000] x)))

20:53 clojurebot: "Elapsed time: 86.389 msecs"

20:53 durka42: so the 20ish ms comes from looking up vars?

20:53 texodus: Is there any way to check the metadata of a symbol passed as an argument to a macro?

20:53 hiredman: yes

20:53 would you like to know what it is?

20:53 durka42: #^symbol

20:53 that's not it

20:53 ^#'symbol if you want the metadata of the var that the symbol names

20:53 texodus: reader metadata?

20:53 dnolen: durka: i don't think will work from the macro because it's a reader macro, you'll have to use (meta (var sym)), am I wrong?

20:53 texodus: hmm - when I use ^#'symbol in a defmacro, it does not compile

20:53 dnolen: #' is a reader macro

20:53 so it won't work from your macro definition.

20:53 texodus: ah, makes sense, the symbol is not bound yet

20:54 durka42: (meta (var symbol))

20:54 maybe `(meta (var ~symbol))

20:55 ,(let [s 'map] (macroexpand `(meta (var ~s))))

20:55 clojurebot: (clojure.core/meta (var map))

20:55 durka42: ,(macroexpand '^#'map)

20:55 clojurebot: (clojure.core/meta (var map))

20:58 slashus2: ThreeBot: clj (print "Test\nQUIT :This bot has been hacked")

20:59 Sorry, pasted it wrong.

20:59 texodus: (var symbol) causes this same problem

21:00 dnolen: yeah because var is a special form

21:00 texodus: ic

21:08 lisppaste8: dnolen pasted "macro to grab meta on var" at http://paste.lisp.org/display/77797

21:11 dnolen: texodus: hopefully that will help, if anyone knows a better way please chime in.

21:11 qualify-sym is Chouser's great handywork, lifted from error-kit

21:15 slashus2: hiredman: If you ran (print "Test\nQUIT :test") on your bot would it run the QUIT command? It did on mine :-( I had to strip out \n and \r to keep that from happening.

21:15 hiredman: ,(print "Test\nQUIT :test")

21:15 clojurebot: Test QUIT :test

21:15 hiredman: is there a QUIT command?

21:16 I am not aware of one

21:16 durka42: (.write *out* "Test\nQUIT :test")

21:16 ,(.write *out* "Test\nQUIT :test")

21:16 clojurebot: Test QUIT :test

21:16 slashus2: The reason it worked on my bot is because it printed the lines by themselves.

21:16 hiredman: well, I strip newlines anyway

21:17 slashus2: I am doing that now.

21:17 QUIT makes it leave the network.

21:17 hiredman: ~quit is <reply>QUIT

21:18 clojurebot: c'est bon!

21:18 slashus2: Apparently. That is what it did to mine.

21:18 hiredman: ~quit

21:18 clojurebot: QUIT

21:18 slashus2: If you turn off line stripping, and run that command, it will work.

21:18 You can also make it send private messages that way too.

21:32 texodus: ah, this works well, thanks dnolen

21:34 dnolen: texodus: cool.

21:48 chessguy: are there other code-as-data languages, besides lisps?

22:33 danlarkin: Aw nuts:

22:33 ,(instance? clojure.lang.IObj (delay))

22:33 clojurebot: false

22:33 hiredman: ,(ancestors (class (delay)))

22:33 clojurebot: #{clojure.lang.IDeref java.lang.Object}

22:33 hiredman: you could proxy IDeref IMeta and IObj

22:35 danlarkin: yeah I could proxy clojure.lang.Delay

22:44 hiredman: Delay takes a Fn

22:50 I guess you could just use a atom

23:29 arohner: rhickey: can you please go into more detail about why (get ref :foo) should return nil?

23:32 danlarkin: (delay (println "foo"))

23:32 ,(delay (println "foo"))

23:32 clojurebot: foo #<Delay@1bce011: nil>

23:32 danlarkin: why does that print foo without the delay having force called upon it?

23:32 hiredman: print a delay drefs it

23:32 danlarkin: doh

23:33 ,(let [d (delay (println "foo"))] 5)

23:33 clojurebot: 5

23:33 danlarkin: tada

23:38 wow... that was a really annoying bug to track down

23:39 and it was, of course, entirely my fault

23:39 clojurebot: map?

23:39 clojurebot: map is *LAZY*

23:39 danlarkin: yes, yes it is

23:52 gnuvince_: -Xprof reports that 20% of my program is spent in java.lang.reflect.Array.set; I have a type hint for that array, is there anything else to avoid reflection?

Logging service provided by n01se.net