#clojure log - Feb 26 2009

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

0:04 arohner: is there a clojure facility for compareTo?

0:07 durka42: arohner: what do you mean?

0:07 ,(.compareTo 2 3)

0:07 clojurebot: -1

0:08 arohner: I was disappointed to see <, >, <=, >= etc don't work on objects that implement compareTo

0:08 I was hoping there was a clojure fn for it

0:08 durka42: oh, i see

0:11 ,(compare 2 3)

0:11 clojurebot: -1

0:13 durka42: ,(< (Date.) (do (Thread/sleep 2000) (Date.)))

0:13 clojurebot: java.lang.ClassCastException: java.util.Date cannot be cast to java.lang.Number

0:13 durka42: ,(compare (Date.) (do (Thread/sleep 2000) (Date.)))

0:13 clojurebot: -1

0:13 durka42: arohner: clojure.core/compare

0:14 arohner: durka42: thanks

0:14 hiredman: (doc compare)

0:14 clojurebot: Comparator. Returns 0 if x equals y, -1 if x is logically 'less than' y, else 1. Same as Java x.compareTo(y) except it also works for nil, and compares numbers and collections in a type-independent manner. x must implement Comparable; arglists ([x y])

0:21 durka42: does y not have to?

0:21 hiredman: nope

0:21 ~def compare

0:22 ugh, my internet is so slow

0:25 durka42: hum, flip those three tweets

0:27 hiredman: flip?

0:27 durka42: so that al3x's reply to elazar would have shown up below

0:57 jwhitlark: What's a clean way to keep asking a user for input until a certain value is received? I'd use a loop in another language, but that's obviously not the right thing here.

1:02 hiredman: (doc repeatedly)

1:02 clojurebot: Takes a function of no args, presumably with side effects, and returns an infinite lazy sequence of calls to it; arglists ([f])

1:02 hiredman: (take-while some-pred (repeatedly read))

1:03 arohner: metadata question: If I do (defn foo "my metadata" [x] ...), where does the metadata live?

1:03 on the var, the fn or the symbol?

1:03 hiredman: the var

1:03 and that is not meta data, it is the docstring, which is stored in metadata

1:03 arohner: ok, so on clojure.org, where it says "Symbols and collections support metadata..." is that incomplete, or are vars collections?

1:05 jwhitlark: clojurebot, hiredman: thanks. This stuff gets tricky with side effects.

1:06 arohner: additionally, since the metadata for fns contains the source file and line number, that means you can be evil with it. i.e. (defn foo [x] ...), and then in the repl thread (binding [foo bar]), if you do (doc foo) inside the binding, you will see foo's docstring, not bar's, right?

1:06 hiredman: arohner: anything that implements IMeta can have metadata

1:09 stuhood: jwhitlark: i love that you thanked clojurebot =)

1:09 jwhitlark: heh, I'm new here.

1:10 but it's late, and it reminded me of pythons' Fbot...

1:10 clojurebot: hey, it wouldn't hurt anyone if people thanked me once and a while

1:11 arohner: hiredman: http://clojure.org/reader also indicates that the metadata lives on the symbol, not the var

1:12 and to "manually" add metadata to a var, you do (def #^{:doc "my docstring"} a). #^ says it attaches metadata to the next form read

1:12 hiredman: arohner: I am not 100% sure, but I am fairly sure that the docstring is on the var

1:12 jwhitlark: stuhood: you been here long?

1:12 hiredman: ,(var doc)

1:12 clojurebot: #'clojure.core/doc

1:13 hiredman: ,(meta (var doc))

1:13 clojurebot: {:macro true, :ns #<Namespace clojure.core>, :name doc, :file "core.clj", :line 2897, :arglists ([name]), :doc "Prints documentation for a var or special form given its name"}

1:13 hiredman: now I am 100% sure

1:13 jwhitlark: (var not=)

1:14 hiredman: ,(var not=)

1:14 clojurebot: #'clojure.core/not=

1:14 jwhitlark: ah. I see.

1:14 ,(var spit)

1:14 clojurebot: java.lang.Exception: Unable to resolve var: spit in this context

1:15 stuhood: jwhitlark: i've been following clojure for about a month now

1:15 jwhitlark: huh. clojurebot cant' look into contrib?

1:15 hiredman: where in contrib is spit?

1:16 jwhitlark: don't remember, that's why I was asking. I think it's in str-utils, just a sec.

1:16 stuhood: you'll need the fully qualified name if it is in another namespace

1:16 hiredman: ,(doc clojure-contrib.str-utils/spit)

1:16 clojurebot: java.lang.Exception: Unable to resolve var: clojure-contrib.str-utils/spit in this context

1:16 jwhitlark: ,(clojure.contrib.str-utils/spit)

1:16 clojurebot: java.lang.ClassNotFoundException: clojure.contrib.str-utils

1:16 hiredman: ,(use 'clojure-contrib.str-utils)

1:16 clojurebot: java.io.FileNotFoundException: Could not locate clojure_contrib/str_utils__init.class or clojure_contrib/str_utils.clj on classpath:

1:17 jwhitlark: grrr beat me to it.

1:17 Anyone know where the source for clojurebot is?

1:17 hiredman: ,(use 'clojure.contrib.str-utils)

1:17 clojurebot: java.io.FileNotFoundException: Could not locate clojure/contrib/str_utils__init.class or clojure/contrib/str_utils.clj on classpath:

1:17 hiredman: anyway

1:17 clojurebot: where are you?

1:17 clojurebot: http://github.com/hiredman/clojurebot/tree/master

1:20 hiredman: ,(doc clojure-contrib.str-utils/spit)

1:20 clojurebot: java.lang.Exception: Unable to resolve var: clojure-contrib.str-utils/spit in this context

1:22 jwhitlark: excellent.

1:22 That give me something to read tomorrow.

1:22 hiredman: you wrote the bot?

1:23 hiredman: I, uh, yes

1:24 jwhitlark: was it difficult? I've been looking into writing a clojure xmpp bot, so...

1:24 hiredman: actually I have done two xmpp bots

1:24 jwhitlark: anything you thought was particluarly interesting?

1:24 yes? are they os?

1:24 hiredman: I guess I should publish some of that code

1:25 jwhitlark: I would like to look at them.

1:25 hiredman: they where very lite on the features

1:25 jwhitlark: I've been struggling a little with using the smack libraries from clojure.

1:26 hiredman: one was just a repl over xmpp, it was one of the first things I did with clojure

1:26 yes, I used smack

1:26 I seem to recall have trouble with the latest smack, but it has been a few months

1:26 jwhitlark: I've been writing python code for the last 8 years, never took java, or lisp, and my C++ was ancient... so...

1:27 hiredman: I started working on a wrapper lib, but did not get very far, and was not very satisfied with it

1:28 I mean it worked, but it is not really pretty

1:28 jwhitlark: Where I ran into problems was the listener that the chat object needed, I've not seen that part of java before, and I'd swear it looked like an anonymous inner block. Does java even have those?

1:29 hiredman: http://gist.github.com/70695

1:29 jwhitlark: Hmm. We'll, I'd like to see you code in any case. xmpp is likely to figure heavy into what I'll be working on for a while.

1:29 tnx

1:31 hiredman: http://gist.github.com/70696

1:31 :/

1:32 jwhitlark: I've been through stewart's book once, and I've got agrasp on the basics, I trying to find the stuff to take it to the next level.

1:33 hiredman: clojure does seem to be hankering for some message passing based distributed solution

1:35 jwhitlark: I've started reading xmpp: the definitive guide, and I'm realy excited about the possibilities.

1:36 hiredman: xmpp is really cool, but I am not to fond of smack, and smack seems to be the best java xmpp lib

1:36 client lib

1:37 jwhitlark: When I get a little fartner, i'm going to dig out my paradigimes of ai, and see how it translates...

1:37 hiredman: Excellent

1:37 clojurebot could use some ai, it is written in lisp after all

1:38 jwhitlark: that would be a great place to play.

1:38 I'll poke around in the code, and let you know if I have time to work on it.

1:38 hiredman: cool

1:38 jwhitlark: if you don't like smack, what do you like?

1:39 hiredman: jwhitlark: I like nothing

1:39 jwhitlark: different language, or have you never seen a workable implementation that you approve of?

1:40 hiredman: the only other language I have used to play with xmpp was ruby

1:41 which, uh, I think I looked at xmppr and rbot(xmpp ruby bot framework ontop of some other xmpp lib)

1:42 jwhitlark: hmm. I did a bit with xmpppy, which worked out ok. didn't get very far, it's very proof of concept right now.

1:42 hiredman: I would have liked something a little simpler then xmppr but exposing more functionality then rbot

1:43 jwhitlark: you think it should be written in clojure?

1:43 hiredman: *shrug*

1:43 I mean yes!

1:43 * jwhitlark looks askance

1:44 hiredman: :)

1:44 jwhitlark: bigger question, are you interested in writing it?

1:44 hiredman: I want pircbot for xmpp

1:44 heh, no

1:45 pircbot is the java ircbot lib that clojurebot is ontop of

1:45 jwhitlark: hmmmm.

1:46 I'm looking for projects that will help me really learn xmpp and clojure.

1:46 I'll have to thing about that.

1:47 anyway, nice chatting with you, got to run

1:47 hiredman: #clojure should move beyond legacy irc to MUC xmpp

1:47 bye

1:47 jwhitlark: that would be very nice. If I meet the central committee, I'll put that to them.

2:28 owen1: http://blog.urbantastic.com/post/81336210/tech-tuesday-the-fiddly-bits#disqus_thread

2:29 interesting site - clojure and couchDB

2:30 are there any django/rails equivalents for clojure?

2:31 stuhood: owen1: i just heard about Compojure, but i wouldn't call it equivalent

2:31 http://ericlavigne.wordpress.com/2008/12/18/compojure-on-a-slicehost-vps/

2:32 owen1: stuhood: i am reading about it. it's more modular than rails. more in the lines of sinatra/merb.

2:33 stuhood: yea

2:34 hiredman: someone is working on some kind of django port

2:34 owen1: which rails will follow soon, after the merb merge.

2:35 * hiredman prefers ring

2:35 hiredman: ~ring

2:35 clojurebot: ring is http://github.com/mmcgrana/ring/tree/master

2:38 stuhood: hiredman: good to know there is competition

2:38 i'm going to need to pick one in a few months, so more choices will undoubtedly have sprung up

3:51 AWizzArd: clojurebot: max people

3:51 clojurebot: max people is 149

4:45 Bracki: What's the equivalent of update-in for StructMaps?

6:13 hoeck: kotarak: thanks for fixing LazyMap so fast!

6:13 kotarak: hoeck: np. Did it work?

6:13 I didn't do much testing. :/

6:15 hoeck: kotarak: as far as i can tell (test) it works fine

6:16 kotarak: hoeck: good to hear :)

6:16 I need some unit tests. But side-effects are so ugly to test. :|

6:24 hoeck: kotarak: or write a correct version in the first place :)

6:25 but how would one test the "forcing" of a delay?

6:59 kotarak: hoeck: I think something like (defn test-helper [x] (swap! some-atom inc) x) and then (lazy-hash-map :a (test-helper 1) :b (test-helper 2)) and then access things in various ways, checking the value of the helper-atom afterwards.

7:02 Chousuke: hm

7:02 interesting vandalism on wikipedia :P

7:03 The applications paragraph for haskell states "It can be also used to heapsort a heap."

7:07 * cemerick is "porting" to a lazy clojure now

7:09 cemerick: oddly, when I use clojure.assert-if-lazy-seq=true, an exception is thrown when a lazy-seq is passed to empty?, which of course implies using seq

7:09 rhickey: cemerick: that's funny

7:10 cemerick: rhickey: I thought so. I presume that's just an issue with the assert-if-lazy machinery. I mean, (if (seq coll) ...) is *the* way to test for empty (or, non-empty) colls, yes?

7:11 rhickey: cemerick: I don't think that's really happening

7:11 ,(empty? (lazy-seq nil))

7:11 clojurebot: true

7:11 rhickey: ,(empty? (lazy-seq [42]))

7:11 clojurebot: false

7:12 rhickey: ,(if (lazy-seq [42]) 2 3)

7:12 clojurebot: java.lang.Exception: LazySeq used in 'if'

7:13 cemerick: not sure what to say....

7:13 rhickey: cemerick: do you have a reproducible case?

7:13 lisppaste8: cemerick pasted "rhickey: exception out of empty?" at http://paste.lisp.org/display/76189

7:14 cemerick: I'm going to switch out jars and see if that test that uses empty? works. I'll see if I can prune things down to something simply repeatable

7:15 note that there's no cause trace after that particular stack

7:15 rhickey: cemerick: maybe the code in your lazy seq is itself testing a lazy seq with if?

7:16 cemerick: maybe. That should result in a 'caused by...' addendum trace, tho.

7:17 am I right in remembering that the current lazy impl doesn't bring the significant performance improvements that the stream impl would have brought?

7:23 rhickey: cemerick: lazy by itself, no

7:24 but lazy brings an important change in the contract of the sequence fns that opens other doors

7:36 Chouser: I've fallen off the wagon.

7:36 * cemerick is going to write a lot of buggy code before he's able to pull nil punning out of his head as an axiom

7:36 Chouser: There are 53 threads with messages I haven't read.

7:37 cemerick: really? I haven't found it to be a problem for new code.

7:39 cemerick: Chouser: That's just a projection. I'm going through tweaking our existing code to be lazy-friendly, and a lot of tight stuff is needing a bunch of "extra" seq calls (e.g. fns that were expecting seqs and returned seqs, but now return sequences).

7:39 lazy is making me work harder! ;-)

7:40 rhickey: cemerick: you are using next instead of rest when possible for that?

7:41 Chouser: well, you could be right. But as it was I had to think a bit to make sure I couldn't have a collection when nil punning. So now I don't have to think more times, just use different criteria.

7:42 cemerick: rhickey: yeah. I actually just did a global F&R for (rest => (next. A solid chunk of the tests are passing, so I'm hopeful.

7:43 rhickey: using next will leave all of you local loops eager, leaving only nil puns of sequence fns like map/filter

7:44 Chouser: so is that the right terminology now? something that returns a seq will return nil instead of an empty collection, but most of the library functions return sequences?

7:45 If the answer is "no", I'll go read Halloway's post again.

7:45 cemerick: Chouser: I'm just blowing smoke at the moment. I admit I honestly don't see the benefit of the lazy changes, but my brain is tiny and I'm probably just having a blub problem.

7:45 rhickey: Chouser: I think that would be good, haven't been consistent enough about it, doc strings need audit

7:46 Chouser: would 'seq?' need a new name?

7:46 rhickey: I don't think so, sequences are seqs

7:47 Chouser: but (seq? (seq x)) may return nil, which seems a little surprising.

7:47 sorry, false

7:47 rhickey: There were twp types, people were confused, now there is one, people are confused :(

7:47 Chouser: ,(seq? (seq []))

7:47 clojurebot: false

7:48 Chouser: well ... when there were two, I was confused. Now there is one and I'm mearly uncertains as to which words to use when.

7:48 rhickey: seq tries to get a seq but might not

7:48 cemerick: wha?

7:48 rhickey: doesn't make nil a seq

7:48 cemerick: wow, (seq? (seq [])) definitely => false

7:49 ,(doc seq?0

7:49 clojurebot: EOF while reading

7:49 cemerick: ,(doc seq?)

7:49 clojurebot: "([x]); Return true if x implements ISeq"

7:49 Chouser: rhickey: ok, that's not a bad way to think about it.

7:49 cemerick: ,(doc sequence?)

7:49 clojurebot: java.lang.Exception: Unable to resolve var: sequence? in this context

7:49 cemerick: wasn't there a sequence? at some point?

7:50 rhickey: Chouser: after rereading Stu's sequences chapter I realized adding precision here doesn't help much, easier to just doc returns nil or returns empty sequence

7:50 Chouser: there's no predicate for 'seq-or-nil?', I assume because nobody's ever needed it.

7:50 rhickey: ick

7:52 there's no getting around sequences are chains of seqs, and, a seq can be treated as the sequence of things starting with it

7:53 rather than treat the return values of seq as some sort of unified type, just treat it as something/nothing

7:54 read seq as "seek (to first)", nil if no first

7:55 cemerick: there was and people were confused

7:55 the types were a bit tricky too, no empty seqs, only empty sequences. It made sense to me, but...

7:56 cemerick: people will always be confused

7:57 Chouser: at least now the word "sequence" is free now, and can be used more casually without undue fear

7:57 cemerick: pre-lazy, it was pleasantly convenient to explain the state of play as "it basically works like python w.r.t. empty lists => false"

7:57 Chouser: oh dear

7:57 rhickey: Chouser: yeah, as I said, they can be used interchangeably, seqs don't constitute a different type

7:57 cemerick: that was never true

7:58 nil was not the empty list and () was not false

7:58 cemerick: heh. Well, that's how I thought of it.

7:58 I knew the formalism, but that didn't interfere with my coding. :-)

7:59 rhickey: I thought of it as eos was false, and still do, just now the sequence functions return collections

8:00 seq brings me to my something/nil world, and next keeps me there

8:01 Chouser: yes, I now think of sequences as always collections instead of sometimes being nil.

8:02 rhickey: yes, sequence => collection, seq => cursor

8:02 but not distinct from a type perspective

8:03 Chouser: I've never thought of seq as a cursor. cursors are very tied to mutation in my mind.

8:03 rhickey: location?

8:04 Chouser: cons cell or nil

8:04 rhickey: what about ()

8:04 ?

8:05 cemerick: rhickey: () was never an issue before -- () was emitted as nil by all of the std fns, and any other good fns that one might write

8:05 rhickey: cemerick: it seriously wasn't, there was a proper notion of an empty list

8:05 distinct from nothing

8:06 the list of groceries could have nothing on it or you might not have made it yet, distinct

8:06 nil was eos

8:06 no more

8:07 nil is no more a list than it is a vector or string

8:08 Chouser: hm. well, previously the only () was an empty list, so that was outside of my concept of seq as "cons cell or nil"

8:08 cemerick: rhickey: formally, sure. However, in pre-lazy clojure, (filter pos? [-2]) => nil, not ()

8:08 rhickey: Chouser: right and () wasn't a seq then

8:09 Chouser: but (pop '(1)) was (). I think.

8:09 rhickey: cemerick: right, that's the change, sequence functions now return collections

8:09 Chouser: right, because pop was a list, not seq, function

8:09 cemerick: well, that's what I meant by '() was emitted as nil by all of the std fns'

8:10 true, insofar as one could ignore the difference between colls and seqs for predicates

8:10 rhickey: cemerick: no, seq fns returned non-empty seqs or nothing, they never returned empty collections

8:11 cemerick: you never could ignore colls/seqs for predicates and still can't (if [] ...) (if {} ...)

8:11 [], (), {} are all true

8:11 always have been

8:12 you could use the something/nothing protocol in predicates, but now the sequence fns don't use that protocol

8:13 since knowing there's nothing is eager

8:13 cemerick: rhickey: yes, I know that. But '() was never returned by seq fns, as you said. Insofar as one's fns were seq-oriented, nil and '() were functionally identical.

8:13 We're in total agreement, I think. I'm just far, far less precise in my terminology.

8:13 * cemerick thinks this must all be thoroughly frustrating for rhickey :-(

8:14 rhickey: these kinds of discussions are important, it all makes sense to me but I want to understand how it doesn't to others, also how best to describe things

8:16 cemerick: you are more patient than I, thankfully :-)

8:17 Chouser: well, that was fun. Now, what about Vars implementing Named?

8:18 rhickey: Chouser: why?

8:18 they might not be

8:18 Chouser: so I can use them in a heirarchy

8:18 * Chouser smiles sweetly

8:18 * rhickey shudders

8:19 rhickey: On today's agenda is watches

8:19 Chouser: you haven't looked at error-kit

8:19 ah, good enough. I'll leave you alone, then.

8:20 rhickey: I'm going to make them synchronous, and I'll see if I can pass both old/new values

8:20 leave it to clients to do change detection

8:21 Chouser: perfect. I seem to recall that the lack of notification on non-changes made my one use case more difficult.

8:21 cemerick: I was going to bother rhickey about serialization and such today, but I think I spent my token on the lazy stuff. :-P

8:23 rhickey: Chouser: I still don't know how that complicates transactions, the other references are easy

8:23 Chouser: ah, sure.

8:23 rhickey: clojurebot: translate

8:23 clojurebot: Excuse me?

8:24 * Chousuke guessess it says something about the clojure algebraic data type implementation.

8:25 Chouser: google says: just put algebraic data types Clojure gradually we reimplement Haskell: "VIVAT academia, vivant professores

8:25 rhickey: yeah, I wanted the last bit

8:26 something about life/living

8:27 Chouser: maybe an idiom for celebration. perhaps facetious.

8:27 durka42: it says "they just put algebraic data types in clojure"... that isn't quite true, is it?

8:27 Chouser: ah, "Long live the academy! Long live the teachers!"

8:28 according to http://www.newfoundations.com/Gaudeamus.html

8:28 durka42: clojurebot: translate acaban de meter tipos algebraicos de datos en Clojure, poco a poco estamos reimplementando Haskell from es to en

8:30 Chousuke: heh, we had to sing that song in the graduation ceremony from upper secondary school... Well, part of it at least

8:34 Lau_of_DK: Chouser: I fixed that problem we discussed yesterday, turns out LD_LIBRARARY_PATH needed some more .so files :$

8:35 oh, and before you say "Oh, does that mean Sofiaba now supports dynamic transparent water and real physics that affect every object" then let me reveal that, yes, thats what it means :)

8:43 rhickey: In the time it took me to get through the group's overnight messages, there were 10 more...

8:44 Lau_of_DK: I understand, I had to give up on the group :(

8:44 * rhickey can't give up on the group

8:44 Lau_of_DK: I know - I really appreciate and respect your dedication to the Clojure community btw, dont think I ever told you, but thanks alot

8:45 hoeck: Lau_of_DK: are you playing with the jMonkeyEngine and/or the jme-physics???

8:46 Lau_of_DK: and

8:46 hoeck: cool, you got something to show off?

8:46 Lau_of_DK: I'll do the final testing tonight, but it seems like Ive got a beautiful island, rendering in the middle of an active ocean and when you hit a key, a huge sphear with a picture of my daughters falls from the sky and bounces off the island

8:47 http://wiki.github.com/Lau-of-DK/sofiaba <-- I show off features as I go along on this project-site, I'll update it tonight with the ocean/physics stuff

8:48 hoeck: wow, and is it usable from clojure, i mean, really interactive object manipulation like in the story of this common-lisp game shop (naughtydogs) or so?

8:48 and how is the performance?

8:48 * hoeck calls git clone

8:48 Lau_of_DK: Yea, fully useable from Clojure, you drive the 3d engine from 1 thread while maintaining a repl in another

8:49 The performance - I'll have to test tonight, last time I checked it ran about 800 fps with a large ImagedBasedHeightMap + Detailmap

8:49 hoeck: sounds like a dream comes true :)

8:49 Lau_of_DK: Felt like it too when I got it working :)

8:50 hoeck: i have read the jme physics tutorial few days ago .. and wondered wether it may work with clojure

8:52 and i spend one day figuring out how to compile jme and jmephysics on my machine

8:55 Lau_of_DK: Yea that part was a little tricky, specially getting jmephysics to work in the same project as Jme2.0, but it looks like its working now, I've tried to describe in the README how I did it

8:55 Maybe it'd be a good idea to include the LIBRARY_PATH files...

8:56 8.3 MB

8:56 Chouser: That's a big LIBRARY_PATH

8:56 Lau_of_DK: and besides those, you need jme2.0.jar, jmephysics.jar, odejava.jar...

8:56 Chouser: oh, the files are 8.3MB. I guess that make more sense.

8:56 Lau_of_DK: 8.3 isnt really that big is it? these days I mean? :)

8:57 hoeck: no, not really

8:57 Lau_of_DK: Just to save people the trouble of having to compile and setup the whole thing themselves

8:57 Chouser: I thought you were saying the env var itself was 8.3MB. I was a bit surprised.

8:58 Lau_of_DK: jme2.0 is 16 mb and jmephysics is 197 kb... :)

8:58 hoeck: before trying to use it with clojure, I wanted to be sure that I'm able to compile all those deps by myself

8:59 Lau_of_DK: k, I downloaded the precompiled jme-2.0.jar

8:59 hoeck: there are a lot of abandoned graphics-game-physics project out there

8:59 Lau_of_DK: then svn'ed down jmephysics and just ran

8:59 ant release.all -lib /path/to/jme-2.0.jar

8:59 hoeck: s/project/projects

9:37 cemerick: this is totally OT, but: Peter Norvig (of PAIP fame) used some of my code, and I'm just as giddy as a schoolgirl about it. See: http://blog.snowtide.com/2009/02/26/whoa-peter-norvig-used-some-of-my-code

9:38 Lau_of_DK: uuh congratz :)

9:39 Chouser: cemerick: nice

9:39 cemerick: I guess it's sort of like the Rolling Stones doing a cover of some song from an out-in-the-wilderness folk musician or something.

10:20 cooldude127: i just discovered the factor language, and it's pretty cool, and then i noticed the persistent data structures in the library list

10:20 Chouser: :-)

10:20 cooldude127: factor's persistent vectors are based on clojure's

10:21 it says it right there

10:21 Chouser: yup. someone ported them to work with Scala as well, I believe.

10:21 cooldude127: wow, i didn't realize how influential clojure was already

10:21 that's really cool

10:22 WizardofWestmarc: yeah everyone's been drooling over them throughout the programming language land it seems like, constant references to them come up.

10:22 But they're so awesome it makes sense :)

10:22 cooldude127: yeah, persistent data structures are awesome

10:27 Holcxjo: Persistent data structures are maybe like static scoping? An idea that people considered theoretically interesting but impractical for real use until they were proven wrong by an implementation...

10:28 WizardofWestmarc: holcxjo: wouldn't surprise me, they've certainly been mentioned before

10:29 Holcxjo: WizardofWestmarc: But were they really used somewhere?

10:29 Chouser: hm, the clojure log pages don't show clojurebot tweet parroting

10:30 WizardofWestmarc: Holxcjo: Not that I know of, which is why I was agreeing with you...

10:35 p_l: hmmm, what do you mean by persistent data structures?

10:36 WizardofWestmarc: p_l: http://en.wikipedia.org/wiki/Persistent_data_structure

10:37 rhickey: sync watches in svn 1308 - testing help appreciated

10:37 p_l: I think many people used their own implementation through Red-Black trees for a long time

10:38 cooldude127: p_l: all the data structures in clojure. they are immutable, where operations efficiently produce new structures by sharing data with the old one

10:38 s

10:38 p_l: cooldude127: I know. I referred to the fact that people _outside_ functional languages probably used those :-)

10:39 cooldude127: oh

10:40 Chouser: "watch" is synchronous and "watcher" not, eh?

10:40 yason: Was there a map-like doseq that consumes all sequences in parallel (unlike (for))? Or do I have to use (loop ..recur) ?

10:40 clojurebot: svn rev 1308; interim checkin - needs testing - made watches synchronous, send old+new state, added add-watch, remove-watch, redefined add-watcher in terms of add-watch

10:40 svn rev 1309; interim checkin - needs testing - made watches synchronous, send old+new state, added add-watch, remove-watch, redefined add-watcher in terms of add-watch

10:41 p_l: cooldude127: In a way, classical virtual memory on unix systems is a form of persistent data structure (not fully persistent usually)

10:41 rhickey: aargh, core.clj changes didn't make it into 1308 - use 1309

10:41 cooldude127: rhickey: that's the problem with SVN :)

10:41 rhickey: Chouser: watcher may go away, this was to make it least disruptive, watcher being an agent implies async

10:41 * Chouser nods

10:42 Chouser: cooldude127: what vcs doesn't have that problem?

10:42 rhickey: cooldude127: that's the problem with not hitting save :)

10:42 cooldude127: some vcs's like git allow you to rewrite the history, merging commits

10:42 git rebase -i

10:43 rhickey: feedback welcome, add-watch should be fully powered for all needs I hope

10:46 Chouser: yikes. I'd much rather document a revision as bad than try to claim it never existed.

10:46 cooldude127: Chouser: it's good for situations like this. you just commit, what you missed, run that command and squash them together

10:47 ideally you'd probably do this before you push

10:48 * cooldude127 is still exploring factor and is now trying to figure out if there is something it DOESN'T have a library for

10:49 Chouser: I've got some background in RPN. It makes me panicky. I suppose I should try to get past that...

10:50 cooldude127: i'm trying to get past it too, cuz otherwise it seems like a pretty awesome language.

10:50 the emacs environment (FUEL) is almost as good as slime

10:51 WizardofWestmarc: stack based languages weird me out for some reason

10:51 though I should probably look at factor at some point

10:52 Chouser: normally, arity becomes a desperately important detail of a func to keep in mind. Perhaps factor has something to mitigate that.

10:53 yason: WizardofWestmarc: I guess it's Forth the trouble sometimes :)

10:53 cooldude127: LOL

10:53 WizardofWestmarc: groan

10:54 yason: But about doseq? Anyone?

10:55 cooldude127: yason: i'm not sure i understand what you were asking for

10:55 yason: cooldude127: In python I would write it like this: for item1, item2 in zip(seq1, seq2): ...

10:56 cooldude127: yason: are you using it for side-effects?

10:56 * p_l will have to learn forth one time. It's certainly easier to write firmware in than writing a compiler for Lisp that will run on bare hw :)

10:56 yason: cooldude127: that is, to "do" two seqs at the same time. Yes, for side-effects (=drawing).

10:57 cooldude127: yason: my first instinct is a (dorun (map #(blah %1 %2) seq1 seq2))

10:57 Chouser: yeah, the way to run seqs in parallel is 'map' or perhaps 'zipmap'

10:57 yason: cooldude127: ok, I was thinking about map but thought I'd fish for an existing construct first

10:57 Chouser: so either as cooldude127 suggested, or (doseq [[x y] (map vector xs ys)] ...)

10:59 yason: Chouser: all right then. The manual construction+deconstruction just bothered me but if I can't do it more simply, then it's ok.

10:59 Thanks.

11:02 Chouser: if doseq could do it for you, what would the syntax look like?

11:03 (doseq [:parallel [x y] [xs ys]] ...) ?

11:04 (doseq [x xs :with y ys z zs] ...), where x and y would run together, and z would be nested inside?

11:05 yason: Chouser: or a variant like pdoseq with the same syntax except that the prefix 'p' is already taken

11:05 Chouser: that wouldn't allow you to mix nested and parallel in the same construct.

11:05 Chousuke: what about some kind of destructuring? (doseq [[x y] [xs ys] z zs] ...)

11:06 Chouser: Chousuke: that's already valid, but means something else.

11:06 Chousuke: hm.

11:06 Chouser: ,(doseq [[x y] [[1 2] [3 4]]] (prn x y))

11:06 clojurebot: 1 2 3 4

11:07 Chousuke: ah, right.

11:07 yason: Chouser: Destructuring could do it if it was clear enough to distinguish from the basic doseq

11:08 Chouser: I think the use of (map vector xs ys) and destructuring is relatively clear, but it's not very efficient.

11:08 I think doseq could do the parallel case very efficiently if it knew that's what it was supposed to do.

11:09 yason: Yup, there's nothing much "doing" to it after all

11:09 Chouser: (doseq [[x y] :zip [ys zs]] ...) ?

11:10 except with, you know, corrected names

11:10 :-)

11:10 yason: keywords do stick out but it's not immediately clear that which items belong together

11:10 Chousuke: something like (doseq [(:parallel x xs y ys) z zs]) would look okay to me

11:11 yason: better.

11:11 Chousuke: perhaps with the parallel forms in a vector as well

11:12 yason: I'd vote for plain parentheses if they only stood out better

11:12 Chousuke: I mean like (:parallel [x xs y ys]) so it can support destructuring

11:12 yason: (doseq [([x y] [xs ys]) z zs] ...)

11:12 the "[([" part looks horrible :)

11:13 Chouser: (doseq [(x xs, y ys) z zs] ...)

11:13 yason: That's cleanest so far.

11:14 Chouser: I have no reason to think rhickey would accept such a feature. :-)

11:14 rhickey: exactly

11:14 Chouser: :-(

11:14 rhickey: how often do you need parallel + sequential together?

11:14 yason: well that's why we have macros, anyway

11:15 Chouser: I need parallel for side effects infrequently enough -- adding any other qualifier pushes it off the bottom of the curve for me.

11:15 yason: rhickey: can't think of many cases. But parallel occurs semi-regularly

11:15 rhickey: could have doseqs or something that looked like doseq but was parallel

11:16 mixing the two seems very confusing

11:16 * Chouser remembers CL loop and backs away slowly.

11:16 rhickey: My next pet addition for for/doseq is :let

11:16 Chouser: for non-seqs, right? yeah, I've wanted that.

11:17 rhickey: for anything you'll need to use twice, like in a :when plus in the expression

11:17 Chouser: I've even written things like (for [x xs, y ys, z [(+ x y)]] ...)

11:18 rhickey: ow

11:18 right, :let is for that

11:18 yason: rhickey: sounds useful

11:22 Chouser: (dopseq [x y, xs ys] ...)

11:22 * Raynes wishes read-line wasn't broken.

11:23 * yason goes home, bye

11:35 Chouser: calling seq the second time on a lazy-seq is free now?

11:37 well, anyway, the new add-watch works beautifully on an agent, which is the only test case I have laying around.

11:38 rhickey: Chouser: nothing is free, and I can't promise there won't be different kinds of lazy seqs for which it matters (i.e. functional seqs that recalc every the time), but right now seq on lazy-seq is fast

11:38 Chouser: ok

11:46 djpowell: I wanted to create a decorator pattern class that implemented an interface and allowed a delegate implemenation to be passed in, and added some instrumentation to some of the methods. I ended up doing it in Java cause it just seemed very awkward to do with gen-class. Is that typical? Are there any helpers for doing that kind of thing?

11:47 Chouser: did you look at proxy?

11:50 djpowell: the instrumention records some stuff to a map, and I wanted to add a method to get hold of the map.

11:50 also, i'd have to implement all of the methods, when it'ld be better if I could just default them to call super

11:51 Chouser: the class created by proxy already takes a map of methods, and for methods that are not given defaults to calling super

11:53 djpowell: hmm, sry I was confused there, i'd want them to default to calling the method on the delegate instance

11:56 perhaps it might be best to use DynamicProxy directly, and write some sort of framework for adding before/after/around advice to the methods

12:11 Chouser: example of new add-watch usage: http://gist.github.com/32494

12:14 durka42: so watchers are no longer agents?

12:14 Chouser: well, there's still add-watcher which uses an agent

12:15 but that's built on top of add-watch, which takes a fn and calls it synchronously.

12:15 leafw: Chouser: why do you call vec on the returned list of the inner map call in parse-grid [s] ?

12:15 Chouser: just curious.

12:16 * durka42 remembers windows api hooks from back when he used windows

12:17 Chouser: leafw: I do indexed lookups on it.

12:18 it's a vector of vectors so I can get the value at x,y in constant rather time.

12:18 leafw: Chouser: I see, parse-grid returns a vec of a vec.

12:18 Chouser: right

12:18 leafw: thanks.

12:18 Chouser: np

12:20 leafw: that's a great example, thanks for sharing.

12:23 * drewr tries to figure out why slime doesn't automagically create a *slime-repl* buffer anymore out of his *inferior-lisp*

12:25 shoover: drewr: (slime-setup '(slime-repl))


12:25 you need that now

12:26 I put it in my (swank-clojure-config) form

12:27 drewr: shoover: Thanks, that works.

12:27 I hadn't updated since Dec!

12:33 I wonder if slime-fancy is only for CL.

12:52 shoover: I couldn't see any useful difference loading slime-fancy

12:55 drewr: shoover: Yeah.

13:22 Chouser: clojurebot: not useful.

13:22 clojurebot: I don't understand.

13:23 Chouser: me either

13:25 rhickey: has anyone tried: http://www.mongodb.org/ ?

13:26 danlarkin: seems a lot like couchdb on first glace

13:26 glance

13:28 rhickey: I know they were trying to make their Java driver more palatable to JVM dynlangs like Clojure

13:34 p_l: danlarkin: Except developed in inferior language ;-)

13:40 * Chouser started looking at hbase yesterday.

13:40 rhickey: anyone try the new watches?

13:42 Chouser: I ported my euler solution, in case you missed it: http://gist.github.com/32494

13:45 * drewr is sifting through endless nil puns

13:46 drewr: Chouser: I've been doing some research with it as well.

13:47 rhickey: Chouser: did it get easier with watch vs watcher?

13:47 Chouser: rhickey: very much so.

13:47 drewr: Is (seq ...) the canonical approach to fixing stuff like (when (re-seq #"foo" s) ...)?

13:48 Chouser: drewr: for regex in particular, look at using re-find instead of re-seq

13:48 but otherwise, yes.

13:49 drewr: em

13:50 (wrong window)

13:50 Chouser: Cool

13:50 rhickey: I'm thinking -seq fns should still be eager...

13:53 Chouser: I don't know. re-seq on an mmap'ed file works well, and I don't know that I'd want that any more eager than necessary.

13:53 rhickey: just seq/nil eager

13:54 Chouser: oh, for the first ... thing. cell?

13:55 rhickey: right, so re-seq still punned, just like (seq any-collection) does

13:58 Chouser: So far the most annoying has been (seq (filter identity (map foo coll)))

13:59 that's a whole lot of words to say something that seems conceptually rather simple

14:02 rhickey: if you're throwing away the seq why not use some ?

14:03 Chouser: Right, but I'm not. That goes into an if-let or similar.

14:05 * rhickey would welcome patch making all blah-seq fns return seq/nil

14:08 drewr: So is concat fully lazy now?

14:09 I see there's still lazy-cat, so maybe not.

14:09 Chouser: it's still not a macro, so its args are evaluated.

14:09 drewr: Chouser: Oh, good poitn.

14:09 rhickey: 99% of all lazy-cat calls could become concats now

14:09 Chouser: if all its args are fully-lazy, I think it amounts to roughly the same as concat now

14:25 durka42: couldn't this error message be more helpful?

14:25 #<CompilerException java.lang.IllegalArgumentException: No matching method found: replaceAll for class java.lang.String (REPL:14)>

14:25 what it meant was: Exception: method replaceAll called with wrong number of arguments

14:27 Chouser: or the wrong types of arguments

14:27 or there's a typo in the method name

14:29 durka42: well "no matching method repalceAll" is true

14:29 i guess the problem is it doesn't reveal the reason behind no matching method

14:29 maybe the compiler doesn't know

14:33 Chouser: I thought rhickey posted briefly recently about using datalog to support type checking of some kind. Anyone got a link?

14:46 * Raynes stabs Chouser with a parenthesis.

14:47 drewr: rhickey: Would this be all of them? http://gist.github.com/71059

14:51 Chouser: Raynes: ?

14:51 Raynes: ?

14:52 * Chouser parries with an immutable collection.

14:52 Raynes: :o

14:52 rhickey: drewr: looks like it - iterator-seq and enumerator-seq are probably already seq/nil, and file- xml- fall out of tree-

14:53 drewr: rhickey: k

14:56 Chouser: (doseq [x xs, y ys :let z (+ x y) :when (< z 5)] (prn z)) ?

14:56 (doseq [x xs, y ys :let [z (+ x y)] :when (< z 5)] (prn z)) ?

14:57 pjstadig: hey all

14:57 i've been experimenting with terracotta and clojure

14:58 i've run into a snag with Keyword

14:58 hiredman: Neat.

14:58 pjstadig: since Keyword doesn't implement hashCode, when they're used as keys into a map it duplicates entries

14:59 gnuvince: Holy crap...

14:59 http://sardakcode.blogspot.com/2009/02/litterate-programming-in-clojure.html

14:59 (.replaceAll (.replaceAll (.replaceAll st "&" "&amp;") ">" "&gt;") "<" "&lt;"))

14:59 pjstadig: i verified that it works by just adding a simple hashCode method to Keyword

14:59 durka42: ,(reduce #(.replaceAll %1 (first %2) (second %2)) "stu&ff<goo>" {"&" "&amp;" "<" "&lt;" ">" "&gt;"})

14:59 clojurebot: "stu&amp;ff&lt;goo&gt;"

14:59 rhickey: Chouser: the second, due to (for [x xs :let [foo (bar x)] y ys...

15:00 hiredman: gnuvince: indeed

15:00 pjstadig: is it possible to add a hashCode method to Keyword? or is that not a good idea?

15:00 rhickey: of else only one let local per :let

15:00 bbl

15:00 Chouser: ah, good point.

15:00 gnuvince: ,(reduce #(.replaceAll %1 (key %2) (val %2)) "stuff & <goo>" {"&" "&amp;" "<" "&lt;" ">" "&gt;"})

15:00 clojurebot: "stuff &amp; &lt;goo&gt;"

15:01 hiredman: gnuvince: yes

15:01 Chouser: (zipmap "'<>\"&" (map #(str \& % \;) '[apos lt gt quot amp]))

15:01 oh, that just builds the map

15:01 gnuvince: yah :)

15:01 Chouser: (apply str (map #(escape-xml-map % %) text))

15:02 half of one, six dozen of the other...

15:02 * hiredman has a <fix> fn that he is happy with

15:02 durka42: ,(.hashCode (keyword "blah"))

15:02 clojurebot: 19152757

15:02 gnuvince: It must be a sure sign that Clojure is becoming popular when we have code that could be submitted to the DailyWTF :)

15:02 durka42: pjstadig: ^^

15:03 pjstadig: the problem is there is no hashCode method on the Keyword class

15:03 it returns the memory address of the instance

15:03 which is different for different JVMs, even if the object is shared by Terracotta

15:03 hiredman: Oh

15:03 interesting

15:04 pjstadig: so (assoc {:a :b} :a :b) returns {:a :b, :a :b}

15:05 well if the original hash was shared across JVMs anyway

15:05 Chouser: because within one jvm they're interned and .hashCode would be the same.

15:05 pjstadig: right

15:05 if you share the hash

15:05 and then do (assoc some-hash :a :b) you would get {:a :b, :a :b}

15:06 simply adding hashcode(){return this.sym.hashCode();} fixes it

15:07 identical? will return true for a distributed keyword and a local keyword

15:07 but the hash is different

15:07 Chouser: ah, interesting.

15:08 hiredman: that is what I said

15:09 Chouser: hiredman: you're right. it is.

15:10 except you said Oh and I said ah

15:11 pjstadig: actually i said that wrong

15:11 if you pull a keyword out of terracotta it will hash the same as a locally interned keyword

15:11 because they're in the same jvm

15:11 but what happens is that PersistentHashMap caches the hash value of each key that it adds

15:12 and on a different jvm when you try to add the same keyword as a hash key the cached value (a memory location from another JVM) and the local hash value (the memory location from the local JVM) don't match

15:12 so it adds the same key twice

15:12 hiredman: Oh

15:13 hmmmm

15:13 pjstadig: is there any reason not to add hashCode() {return this.sym.hashCode();} to the Keyword class?

15:15 durka42: what if you had a map like this { 'sym "symbol" :sym "keyword" }

15:15 pjstadig: well we could make a more interesting hashcode method for Keyword if we want, but i don't think hashcodes are required to be unique

15:16 durka42: actually, i guess it wouldn't matter if the code calling .hashCode checks type first

15:16 pjstadig: the javadocs for Object say hashcodes should be equal if the objects are equal (i.e. a.equals(b) returns true), but they are not required to be different if the objects are unequal

15:17 so i guess technically hashCode() {return 1;} is valid

15:18 though not the most performant

15:23 Chouser: pjstadig: it seems likely to me that such a change would be accepted

15:24 pjstadig: k

15:24 Chouser: pjstadig: the symbol has already computed its hash anyway, so I wouldn't expect any performance issue.

15:24 pjstadig: i'd submit it but i haven't submitted a CA :-/

15:25 i hate to beg, but it's such a small change :0

15:25 :)

15:25 Chouser: pjstadig: just bring it up on the google group with your description and test case or whatever.

15:25 pjstadig: k

15:25 Chouser: without a CA it's better not to include code.

15:25 rhickey: pjstadig: hang on...

15:25 Chouser: I mean it's better not to include in your message code that might be useful to have in the code base.

15:26 pjstadig: yeah rich?

15:26 Chouser: pjstadig: ooh, you may have just gotten a fastpass.

15:26 * hiredman waits on clojurebot

15:27 hiredman: it might be another few minutes

15:28 clojurebot: svn rev 1310; gave Keywords non-identity hashCodes

15:28 pjstadig: that was easy :)

15:29 thanks rich!

15:29 rhickey: np

15:30 hiredman: it would be great if you could post anything about working with terracotta to the group

15:30 rhickey: yes, please

15:30 pjstadig: i'm working on a blog post

15:30 hiredman: Excellent

15:30 pjstadig: it's been pretty easy so far

15:30 i've only been experimenting for a couple of days

15:36 hiredman: do companies offer jvm hosting? like you don't get access to the underlying OS, you just upload a jar file and they run it in a sandboxed jvm?

15:37 durka42: ~google shared jvm hosting

15:37 clojurebot: First, out of 74000 results is:

15:37 Private/Shared JVM Hosting Solution - HostIgnition

15:37 http://www.hostignition.com/index.php?page=jsp-servlets

15:38 durka42: those are servlets though

15:38 Chouser: hm, might be sufficient.

15:39 hiredman: JVM Restarts: 5 Times Every 24 Hours

15:39 I lol'ed

15:40 Chouser: I thought someone said they got a Clojure app working here: http://www.stax.net/

15:41 hiredman: interesting

15:41 StartsWithK: hi

15:41 durka42: ,(.startsWith "StartsWithK" "K")

15:41 StartsWithK: how can i construct proxy for given interface?

15:41 clojurebot: false

15:42 hiredman: StartsWithK: with proxy ...

15:42 StartsWithK: durka42: (.startsWith "Kresimir" "K") :)

15:42 uff, i meant dynamic construction

15:42 durka42: cloudjure :)

15:42 * Raynes points to the Java interop chapter of Stu's book.

15:43 StartsWithK: i give it something like base interface and map of methods and names

15:43 durka42: that sounds kinda like a proxy

15:43 StartsWithK: do i need to use java.lang.reflect.Proxy

15:43 Chouser: ah, here it is. Compojure on stax: http://groups.google.com/group/compojure/msg/7142fd318e0f45d0

15:43 hiredman: that is more or less what (proxy ...) does

15:43 StartsWithK: or is there something like that in clojure

15:43 Raynes: (doc proxy)

15:43 clojurebot: class-and-interfaces - a vector of class names args - a (possibly empty) vector of arguments to the superclass constructor. f => (name [params*] body) or (name ([params*] body) ([params+] body) ...) Expands to code which creates a instance of a proxy class that implements the named class/interface(s) by calling the supplied fns. A single class, if provided, must be first. If not provided it defaults to Object. The interfa

15:44 StartsWithK: i'm looking in clore_proxy.clj and see construct-proxy and init proxy

15:44 cemerick: it would be great if one could define rough "cost" values for each test-is test, and then test-is would run your tests in increasing order of cost -- run the shorter tests first, keeping test/fix cycles small.

15:44 hiredman: (proxy [someInterface] [] (someMethod [someArg] ...))

15:44 StartsWithK: Raynes: i don't know what interface it is before runtime

15:45 Raynes: That sucks.

15:45 StartsWithK: so more like (new-proxy Interface {'method (fn [] ..)})

15:45 hiredman: uh

15:45 you are making this way too hard

15:45 StartsWithK: i see construct-proxy will do: (. Reflector (invokeConstructor c (to-array ctor-args))))

15:46 hiredman: have you tried using proxy?

15:46 StartsWithK: yes, that won't work

15:46 i will find the name of interface i want to implement on runtime

15:46 with method i shoudl implement

15:48 hiredman: that sounds like a bad idea

15:48 StartsWithK: docs for init-proxy say that they can take proxy and map of name function mappings

15:49 and they will update my proxy with them

15:49 Chouser: StartsWithK: everything you need is there

15:49 StartsWithK: but i don't know how to construct that proxy

15:49 Chouser: StartsWithK: get-proxy-class

15:49 StartsWithK: construct-proxy

15:49 StartsWithK: init-proxy

15:50 StartsWithK: thats is a correct order?

15:50 * hiredman will wait for StartsWithK to show up and ask how to created a new method with proxy

15:50 StartsWithK: get-proxy-class says "Takes an optional single class followed by zero or more interfaces."

15:50 Chouser: I've not done it, but it seems likely.

15:51 StartsWithK: i take it optional class can be interface too

15:51 or i will need (get-proxy-class Object Interface)

15:52 Chouser: if they're all interfaces, order shouldn't matter

15:52 * StartsWithK will use gen-class to create stubs with new methods and won't ask such a question

15:52 Chouser: if there's a class, it must be listed first.

15:52 StartsWithK: so i'm fine to skip Object as first argument

15:52 Chouser: you'll have the class object at runtime, or a string?

15:53 StartsWithK: class object

15:53 and string for method name i should implement

15:53 Chouser: multiple interfaces, or just one?

15:53 StartsWithK: just one

15:54 i know method i will implement has sig ? -> Void

15:54 and know it has that one argument

15:54 but it's type will be unknown to me

15:57 Chouser: (defn proxy-one-method [c meth fn] (doto (construct-proxy (get-proxy-class c)) (init-proxy {meth fn})))

15:58 (let [d (proxy-one-method clojure.lang.IDeref "deref" #(str "hello from:" %))] @d)

16:01 StartsWithK: lisppaste8: help

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

16:02 StartsWithK pasted "Dynamic proxy construction, it works" at http://paste.lisp.org/display/76216

16:02 StartsWithK: it worked, thans everyone

16:03 Chouser: StartsWithK: note that if you use 'proxy' directly, you get the class file when compiling AOT

16:03 the way you're doing it you won't.

16:03 StartsWithK: i know, i hope i don't

16:04 but this will not construct any proxy classes with aot?

16:04 Chouser: hm, I guess it may depend on how/when you call it.

16:08 StartsWithK: class type is clojure.proxy.java.lang.Object$ActionListener in that paste

16:08 shoudn't it be clojure.proxy.java.awt.event.ActionListener

16:09 or is it that implementing only interface defaults to Object as base class

16:09 Chouser: it uses the superclass name followed by interface names

16:10 StartsWithK: is that name part of the 'abi', can i count on it?

16:10 Chouser: No, I wouldn't think so.

16:11 you can call 'class' on an instance at runtime to get the class object, though.

16:12 StartsWithK: true, i should not look at class string names at all i guess

16:12 as a side quetion, not related

16:12 is there any way to covert class names generated by clojure back to clojure names

16:14 Chouser: oh, for functions and such?

16:14 StartsWithK: yes

16:14 Chouser: many of those functions don't have any name.

16:14 but anyway, no, not as far as I know.

16:15 StartsWithK: i was thinking integrating code coverage tool with test, cobertura to be exact

16:15 and looking how it spits a lot of weird names for scala code, it will do the same for clojure

16:16 ok, i have more questions :) hehe

16:17 in rev1230 macro now returns Var, for what can this be used?

16:18 Chouser: oh, that's mainly for consistency with defn and def, I think.

16:18 Vars often have useful metadata

16:18 StartsWithK: i still can't take value of macro?

16:18 Chouser: ,^#'proxy

16:18 clojurebot: {:macro true, :ns #<Namespace clojure.core>, :name proxy, :file "core_proxy.clj", :line 249, :arglists ([class-and-interfaces args & fs]), :doc "class-and-interfaces - a vector of class names\n\n args - a (possibly empty) vector of arguments to the superclass\n constructor.\n\n f => (name [params*] body) or\n (name ([params*] body) ([params+] body) ...)\n\n Expands to code which creates a instance of a proxy class th

16:18 Chouser: right

16:19 heh. poor man's macroexpand:

16:19 ,(#'lazy-cat [1 2] [3 4])

16:19 clojurebot: (clojure.core/concat (clojure.core/lazy-seq [1 2]) (clojure.core/lazy-seq [3 4]))

16:19 StartsWithK: ok, in rev1253 IRef was split to IRef and IDeref, why was it done? for futures, they don't have watchers?

16:20 Chouser: delays and futures aren't refs, but you can use @ on them

16:21 * cemerick <3 @ for delays

16:21 StartsWithK: oh, and in rev1232 there was a change in class loader, but i didn't understand what does that mean, what is a new behaviour, and why it was changed

16:22 hiredman: you can also rebind vars

16:22 oh

16:22 nm

16:24 Chouser: StartsWithK: that helps close up a potential memory leak when doing lots of evals

16:26 StartsWithK: and, some time ago, someone posted a patched version on add-classpath that should solve problems with using add-classpath, but cant find when it was merged

16:26 was that accepted?

16:26 Chouser: not sure what you're referring to, sorry.

16:28 StartsWithK: ah.. can't find a post anymore..

16:29 here it is: http://is.gd/l11v

16:30 Chouser: no issue, no CA, no response. I would assume it's not been applied.

16:31 StartsWithK: i see

16:32 in rev1309 there are now add-watch and add-watcher, will add-watcher be removed then?

16:34 Chouser: StartsWithK: possibly. It's currently implemented on top of add-watch

16:37 StartsWithK: and last question :) if i jump to revision after lazy branch merged, all i need to do is rename all (rest) to (more) and check that i check for seq with (if (seq x)) and thats it?

16:37 Chouser: StartsWithK: http://clojure.org/lazy#toc6

16:39 StartsWithK: flag works for (and) (or) too?

16:39 that will help a lot

16:40 Chouser: yep

16:42 StartsWithK: Chouser: thanks for help

16:42 Chouser: StartsWithK: sure, I'll send you the bill.

16:42 StartsWithK: :)

16:45 danlarkin: How's "Nantes" for a name

16:49 pjstadig: maven doesn't compile clojure anymore?

16:50 r1299 seems to have gutted the pom.xml

16:50 there is no source directory defined anymore

16:53 digash`: pjstadig: http://tinyurl.com/dyxsku

16:54 pjstadig: broken link

16:54 digash`: pjstadig: http://code.google.com/p/clojure/issues/detail?id=70&can=1&colspec=ID%20Type%20Status%20Priority%20Reporter%20Owner%20Summary#c23

16:56 pjstadig: looks like the issue is closed now, but my patch was not applied.

16:57 pjstadig: hmm

16:57 of course running ant works fine, but mvn doesn't build anymore

16:58 digash`: pjstadig: the idea is to use ant to drive maven local install

16:59 pjstadig: apply the patch and ant install, you will get clojure in the local mvn repo

17:19 Lau_of_DK: Good evening gents

17:20 danlarkin: Hiya Lau!

17:20 "Nantes"?

17:25 hiredman: why hasn't someone written a wikimarkup poster with fnparse yet?

17:26 parse

17:26 r

17:27 :P

17:27 Chouser: hiredman: I don't know about anyone else, but I haven't because I kinda hate wikimarkup.

17:28 hiredman: make sense to me

17:28 Chouser: :-)

17:34 camponoblanco: Hello

17:36 durka42: hi camponoblanco

17:40 __marius__: are notes supposed to work w/ clojure & slime

17:40 ?

17:49 hircus: hi all

17:49 the answer is probably very silly, but...

17:49 ... how do you instantiate a Clojure class from Java?

17:50 durka42: ,(Date.)

17:50 clojurebot: #<Date Thu Feb 26 14:50:15 PST 2009>

17:50 durka42: oh, the other way

17:50 sorry

17:51 don't they work like normal classes?

17:51 Chouser: if AOT-compiled and gen-classed, yes.

17:51 hircus: Chouser: will try. Netbeans (with Enclojure) is not auto-completing it, for some reason

18:01 could someone go over the constructor syntax again?

18:01 the return value is a vector of two-elements... which is which?

18:09 hiredman: the second arg is the initial value for state

18:09 I dunno about the first

18:48 gnuvince_: ~seen rhickey

18:48 clojurebot: rhickey was last seen joining #clojure, 81 minutes ago

19:51 dreish: Any idea why the tweets don't show up on http://clojure-log.n01se.net/ ?

19:52 hiredman: notice

19:53 dreish: Ah, I see.

19:55 Chouser: should they?

19:55 I imagine they could be made to.

19:55 dreish: Time for rhickey to hit the talk circuit again: http://www.google.com/trends?q=clojure%2Cjruby%2Cjython&ctab=0&geo=all&date=ytd&amp;sort=0

19:56 * rhickey just got confirmation of 2 Java One talks

19:56 dreish: Nice.

19:56 gnuvince_: And there's QCon in two weeks or so?

19:57 rhickey: yup

19:57 then ILC

20:02 Chouser: ILC!

20:02 gnuvince_: http://www.youtube.com/view_play_list?p=AC43CFB134E85266

20:02 You guys seen this?

20:02 Oh

20:03 rhickey: now that you're here. I sent my CA application last week. Did you receive it?

20:03 rhickey: gnuvince_: just today

20:03 Chouser: gnuvince_: haven't seen that, have you?

20:03 gnuvince_: ah cool

20:04 Chouser: watching it now, it was posted on reddit just today.

20:05 dreish: That guy needs a pop guard.

20:08 gnuvince_: I'm at video #2, and so far the guy is not bad at all

20:11 Chouser: as long as he's accurate

20:13 gnuvince_: There was an inaccuracy, but it was about Haskell

20:13 So I can let it slide :)

20:18 Chouser: heh

20:22 gnuvince_: Do you guys pronounce data "dah-tah" or "day-tuh"?

20:22 dreish: I like it so far, but he implies adding something to the end of a list shares data, but I believe that's a case where it wouldn't.

20:22 day-tuh

20:23 WizardofWestmarc: day-tuh

20:24 danlarkin: these videos are very well produced

20:24 gnuvince_: Yes

20:25 WizardofWestmarc: hm

20:27 trying to access a static enum in a java class and I can't seem to get the syntax right. Classname/Enumname it doesn't like the namespace (when I just (new Classname) it gives me an instance so it isn't lack of importing).

20:27 dreish: I've never heard anyone say "may-tuh-dah-tuh".

20:27 WizardofWestmarc: any pointers on what dumb thing I'm missing?

20:28 for reference here's the javadoc of the enum: http://www.igniterealtime.org/builds/smack/docs/latest/javadoc/org/jivesoftware/smack/packet/Message.Type.html

20:29 danlarkin: whoopsie, this guy has a error in example code in video 7

20:36 durka42: ,(let [ls '(1 2 3 4 5) ls2 (concat ls '(6))] [ls ls2 (identical? (nth ls 3) (nth ls2 3))]) ; dreish

20:36 clojurebot: [(1 2 3 4 5) (1 2 3 4 5 6) true]

20:37 dreish: ,(identical? 2 2)

20:37 clojurebot: true

20:37 dreish: I don't think that proves anything.

20:38 durka42: i'm not sure either, but

20:38 dreish: (Not saying I can't be wrong, though.)

20:38 durka42: ,(identical? 2 (Integer. 2))

20:38 clojurebot: false

20:38 durka42: (doc identical?)

20:38 clojurebot: Tests if 2 arguments are the same object; arglists ([x y])

20:38 durka42: as i typed that, briantwill explained identicality ;)

20:40 dreish: WizardofWestmarc: So org.jivesoftware.smack.packet.Message.Type/chat doesn't work, for example?

20:41 That syntax seems to work for, e.g., java.util.concurrent.TimeUnit/SECONDS

20:42 Chouser: WizardofWestmarc: org.jivesoftware.smack.packet.Message$Type ... something

20:43 WizardofWestmarc: ah ha

20:44 dreish: That sounds promising. Looks like Type is a whatchamacalit ... inner class?

20:44 WizardofWestmarc: hm

20:44 Chouser: WizardofWestmarc: org.jivesoftware.smack.packet.Message$Type/groupchat ?

20:45 WizardofWestmarc: that did it

20:45 <3 Chouser

20:45 * WizardofWestmarc saves that buffer so he can't forget.

20:46 WizardofWestmarc: teach me to take so long to interop with java beyond basic io, etc

21:23 cp2: oh nice

21:23 a clojure plugin for idea

21:33 WizardofWestmarc: sweet, finally got my xmpp client code recieving messages

21:34 turns out the end set of my problems was not understanding how the server was working <__<

21:36 __marius__: user> (or nil "two")

21:36 "two"

21:36 user> (or '() "two")

21:36 ()

21:37 did this behavior change recently ?

21:37 gnuvince_: no

21:37 nil != ()

21:37 __marius__: since inception? :-)

21:37 gnuvince_: Only nil and false are false values. Everything else (including the empty list) is true

21:38 __marius__: k. so this is wrong? http://en.wikibooks.org/wiki/Clojure_Programming/Examples/Norvig_Spelling_Corrector

21:39 (in correct)

21:39 WizardofWestmarc: nil punning went away with the lazy branch merge

21:40 did (if get modified to auto test for empty btw? I'd heard it was being considered but I'm still not on lazy.

21:40 durka42: ,(if () 1 2)

21:40 clojurebot: 1

21:41 WizardofWestmarc: so no, you have to be explicit on empty? I guess

21:41 really should get onto the new stuff since it's guaranteed in at this point.

21:43 stimuli: hi

21:45 is there a function that takes a boolean function and returns not-that-function .. in other words (something fred) would be the same as #(not (fred %)) ??

21:48 Chouser: complement

21:48 (doc complement)

21:48 clojurebot: Takes a fn f and returns a fn that takes the same arguments as f, has the same effects, if any, and returns the opposite truth value.; arglists ([f])

21:52 stimuli: thanks !

22:26 Chouser: rhickey: :let http://code.google.com/p/clojure/issues/detail?id=88

22:28 gnuvince_: Chouser: cool feature!

22:30 Chouser: :-) not my idea, of course.

22:30 gnuvince_: Oh

22:30 Well

22:30 Still cool :)

22:30 Chouser: we'll turn doseq into CL's loop yet.

22:30 gnuvince_: You know, that's exactly the kind of thing that keeps me wondering whether I prefer dynamic or static typing :)

22:32 WizardofWestmarc: IMO depends on what you're doing how good each is

22:32 exploratory programming gimme static every time.

22:32 but having the compiler help you avoid weird bugs via static typing, doubly so if it's also strict, can be huge.

22:32 err dynamic for exploratory *durr*

22:33 Chouser: :-)

22:34 WizardofWestmarc: Good thing I seem to mostly do exploratory programming <_<

22:34 gnuvince_: I work with Python at work (Django development mostly) and sometimes I'd kill for Haskell's static typing

22:36 Chouser: by the way, what kind of thing were you referring to?

22:36 doseq??

22:36 cmvkk: if i do (let [[x & xs] a-lazy-seq] ...) can xs be empty?

22:37 Chouser: nope. seq or nil

22:37 um, non-empty or nil

22:37 & is like next

22:37 cmvkk: oh really. so "& xs" is like doing 'next' rather than 'rest'.

22:38 Chouser: right

22:38 cmvkk: thanks.

22:38 actually, why is that?

22:38 Chouser: ,(let [[x & xs] (lazy-seq 1 ())] xs)

22:38 clojurebot: nil

22:39 Chouser: most of the time when iterating you don't mind being a little extra eager, which is why & and next are recommended.

22:40 if you specifically want extra laziness, then you can use rest and watch your nil punning.

22:40 cmvkk: hmm, okay.

22:40 erohtar: i have a question about how bindings and laziness work together...

22:40 Chouser: that's my understanding anyway

22:41 erohtar: mostly they get in each others way

22:41 erohtar: chouser: i've had a hard few hours going crazy working this out...

22:42 chouser: if i use bindings to create a lazy sequence, and i rebind later, how does the earlier sequence behave?

22:43 Chouser: when the fns in the lazy seq execute, they pick up whatever the dynamic context is when they run, which may be completely different from what it was when they were created.

22:43 true of all closures, actually, but lazy seqs are the most likely to be surprising.

22:43 erohtar: chouser: damn

22:43 chouser: maybe im using dynamic vars incorrectly

22:44 danlarkin: erohtar: but like Chouser just implied, they're closures, which means they can capture state

22:44 cmvkk: ha i hadn't thought of that. although to me that seems to speak more to the dangers of special variables than it does to lazy seqs

22:44 erohtar: chouser: i've used them so that i dont have to pass these two 'configuration' paramers around this set of mutually supporting functions

22:44 chouser: is that an OK use of vars?

22:44 bradbev: I've just upgraded from an older Clojure (circa r1100) to head. Require statements that used to work, can no longer find the files (java.io.FileNotFoundException: Could not locate memorytool/src/memorytool/globals__init.class or memorytool/src/memorytool/globals.clj on classpath: (NO_SOURCE_FILE:0) Am I missing something?

22:45 my classpath (set with -cp) has a root that contains memorytool

22:45 Chouser: erohtar: maybe, but you have to be careful.

22:45 hiredman: what is the require statement?

22:46 bradbev: (require 'memorytool.src.memorytool.globals)

22:46 Chouser: I agree with cmvkk -- dynamic vars are touchy and need to be used with care.

22:46 erohtar: chouser: ok, but what is the pattern of good usage? is it true that a binding form will only affect within its call chain?

22:46 bradbev: BTW, I think this is just a hack so I can put my project in a root dir rather than have lots of classpath entries. I'm open to better setups

22:47 Chouser: erohtar: yes

22:47 ,(take 5 (binding [*print-dup* true] (repeatedly (fn [] *print-dup*))))

22:47 clojurebot: (false false false false false)

22:48 Chouser: there's a lazy seq, defined while *print-dup* is true, but not realized until outside that dynamic scope.

22:48 erohtar: chouser: hmm... but if that seq was lazy, and before it was realized, if i changed binding of *print-dup*, then...?

22:48 cmvkk: that's what happened.

22:49 hiredman: bradbev: I would recheck your classpath

22:49 Chouser: ,(take 5 (binding [*print-dup* true] (let [q (repeatedly (fn [] *print-dup*))] (doall (take 3 q)) q)))

22:49 clojurebot: (true true true false false)

22:49 erohtar: cmvkk: i see, ur right, that is what happened

22:49 hiredman: (System/getProperty "java.class.path")

22:49 bradbev: hiredman: (println (. System (getProperty "java.class.path"))) ...

22:49 (println (. System (getProperty "java.class.path"))) ...

22:50 argh, is that appearing?

22:50 erohtar: chouser: ok, so vars are dangerous

22:50 hiredman: is the namespace declared correctly in globals.clj?

22:50 bradbev: hmm, perhaps not

22:51 (ns memorytool)

22:51 erohtar: chouser: what is the pattern for not having to pass params around through a call-chain?

22:51 hiredman: uh

22:51 so no

22:51 (ns 'memorytool.src.memorytool.globals)

22:51 Chouser: erohtar: Hard to say. Generally I'd recommend passing the params around.

22:52 erohtar: you can pass a map full of data and destructure as needed

22:52 erohtar: chouser: yea - that makes sense

22:52 Chouser: erohtar: that would allow you to pass a single arg around, not knowing exactly what's in it.

22:52 erohtar: chouser: i will do that... this vars thing has really messed me up the entire day

22:52 Chouser: or you can carefully use 'binding', just make sure you don't let any closures or lazy seqs leak out.

22:52 erohtar: chouser: i thought i was being smart by using vars...

22:53 bradbev: hiredman: so each namespace must be scoped to the path & filename?

22:53 erohtar: chouser: whats a good example of a var usage?

22:53 Chouser: :-/ sorry about that.

22:53 bradbev: I really wanted one namespace, with multiple files

22:53 Chouser: they also lose their bindings when you do threads -- pmap, agent, etc.

22:53 erohtar: chouser: that i also learnt the hard way about a month back...

22:54 hiredman: bradbev: sounds like you want multiple namespaces

22:54 erohtar: chouser: but i was using the same value for all binding forms in all agents... so it didnt matter, once i re-bound in each agent

22:54 chouser: but now, trying to use different bindings... messed up!

22:54 bradbev: hiredman: so namespaces have a 1:1 mapping with files

22:54 erohtar: chosuer: thanks for ur help

22:55 Chouser: erohtar: sure.

22:55 hiredman: bradbev: they don't have to, but I think it is a good idea

22:55 bradbev: Ah, OK.

22:55 Chouser: I generally think of binding as a sort of clever hack. when nothing else will do, they can be useful.

22:56 core uses them almost exclusively for repl and print configuration.

22:57 I think print config hurts less because it's already stateful IO stuff -- you're less likely to be using closures and lazy seqs.

22:58 though you can still get in trouble: (with-open [f (java.io.BufferedReader. (java.io.FileReader. "graph.dot"))] (line-seq f))

22:59 lazy seq on a file, close the file, try to walk the seq. *boom*

23:00 hiredman: I guess scopes don't completely solve that problem

23:00 erohtar: chouser: got it

23:01 makes sense...

23:01 too clever for my own good

23:01 hey

23:01 thanks everyone, chouser

23:02 cmvkk: that file example seems a little more obvious at least. wrap it in a lazy seq if you want, but you're clearly still reading in lines from a file.

23:10 bradbev: I might understand it now. require is used to load a whole module. I guess that module can contain multiple files (?). So how do I build a project that has multiple files. Docs anywhere?

23:37 cmvkk: ,(seq (str 'c5))

23:37 clojurebot: (\c \5)

23:37 cmvkk: ,(pop '(\c \5))

23:37 clojurebot: (\5)

23:37 cmvkk: ,(pop (seq (str 'c5)))

23:37 clojurebot: java.lang.ClassCastException: clojure.lang.StringSeq cannot be cast to clojure.lang.IPersistentStack

23:37 cmvkk: :(

23:38 Raynes: :(

23:51 bradbev: should there be a difference in my classpath when I (add-classpath "foo") at run time vs java -cp foo? There is - require won't work for #2, but will for #1

23:54 danlarkin: add-classpath is really only intended to be used at the REPL

23:55 bradbev: danlarkin: I'm using Slime, I guess that counts though

23:55 danlarkin: yep

Logging service provided by n01se.net