#clojure log - Jun 19 2009

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

0:08 replaca: rhickey_: are you around?

2:40 Xcalibor: greetings

2:41 i was wondering... is there any benefit in using :key instead of "key" in a hash-map?

2:57 hoeck: Xcalibor: it's more :lispy?

2:58 Xcalibor: If i understand the jvm and clojure correctly, both :key and "key" should be interned, so small strings are effectively the same as keywords

2:59 Xcalibor: but keywords implement IFn, they are functions of maps/sets

3:00 ,(:a {:a 1, :b 2})

3:00 clojurebot: 1

3:00 hoeck: ,(:c #{:a :b :c})

3:00 clojurebot: :c

4:02 frodef: gen-class/interface is really a hassle for smallish things. I think I'll rather proxy clojure.lang.IFn.

4:42 samuels: does clojure check the type hints at compile time?

4:44 jdz: no, it does not generate all possible programs to test whether the type hints hold for all of them

4:47 samuels: jdz: that's not necessary for checking at compile time

4:48 jdz: well, what is necessary then?

4:48 mapreduce: samuels: I just said that in #scala. Are you an elaborate proxy bot? :)

4:48 samuels: hehe

4:48 mapreduce: i just didnt' know what to say in reply, so i posted your one instead :)

4:48 mapreduce: All you need for compile time checking is some algorithm to follow. You don't need to generate all possible programs.

4:49 Though you might reject some programs that will never fail, like (if true 5 <type-error-here>)

4:49 jdz: implementation details! :)

4:50 mapreduce: Implementation details are often a language user's business even if they don't want them to be.

4:56 tsdh: Hi. I need to create an ImageIcon in my GUI. The clojure file is in the same directory as the images, so I've thought "image.png" would be ok, but it isn't. The ImageIcon docs say the file should be relative to the class the constructor is invoked...

4:56 Absolute paths work, but of course that's no solution...

4:57 dibblego: relative to System.getProperty("user.dir")

4:57 samuels: mapreduce: i think you won thatone

4:57 mapreduce: samuels: I was not competing.

5:00 tsdh: dibblego: Ah, I didn't look at the JavaDoc example. Thanks

5:23 rys: hooray, Clojure book has arrived!

5:27 tsdh: Hm, still no luck with the ImageIcon. The problem is that (ClassLoader/getSystemResource ".") points the the clojure git directory and not to my file...

6:14 frodef: when java code says "foo.class.getResource(bar);" is there a clojure equivalent (to the class member or whatever that is)?

6:15 AWizzArd: getResource is a static method in your example?

6:16 frodef: AWizzArd: I don't know what it is to be honest..

6:18 AWizzArd: frodef: if getResource is a static method then you would do this in Clojure: (foo.class/getResource bar)

6:20 Lau_of_DK: Has contrib changed in some way ? I just updated and now (import '(clojure.contrib.str-utils)) returns nil, but nothing is imported....

6:20 frodef: java.lang.ClassNotFoundException: foo.class

6:20 AWizzArd: frodef: then getResource is not a static method. Maybe you can try: (.getResource (.class foo) bar) ?

6:21 hmm no, I think that will also not work

6:21 rhickey: frodef: what are you trying to do?

6:22 frodef: rhickey: creating an icon for may swing app.. :)

6:22 seems I have to getResource, which is a method on java.lang.Class..

6:23 ..and so I have to do "(class-of foo)" it seems to me?

6:23 rhickey: (.getResource TheClass ...)

6:24 if you know the name of the class, else (.getResource (class an-instance) ...)

6:24 frodef: rhickey: ah, so clojure "class" is CL "class-of"? thanks!

6:26 sorry to ask silly questions, I just get quite confused trying to navigate the perimeter between clojure and java.

6:27 rhickey: np

6:39 frodef: is there something like an implicit class that the code lives in?

6:40 "the code" being my code in a foo.clj..

6:40 rhickey: frodef: every fn is an instance of a different class, but there is no class corresponding to a file, since files aren't proper entities in Clojure

6:41 ,(class rest)

6:41 clojurebot: clojure.core$rest__3736

6:41 frodef: ok

6:48 hm.. I guess this java resource stuff doesn't mesh so well with dynamic programming.

6:53 AWizzArd: frodef: you can program dynamically typed in Java too. Declare everything as type Object :-)

6:54 cheddar: Anyone know why ants.clj now seems to hang when I send-off all the ants? If I (send-off (nth ants 1) behave) that ant moves around. But when I (map #(send-off % behave) ants) the whole thing freezes. Is it the new version of clojure? Or something to do with JVM settings? It used to work.

6:54 frodef: programming interactively isn't going to be so easy I guess.

7:02 cheddar: strange, when I increase the sleep delays by 10 times, it works

7:02 but it used to work without that change

7:02 and CPU usage is not above 20%

7:03 is there a way to make behaviour degrade more gracefully?

7:03 frodef: cheddar: sounds race-conditiony, no?

7:04 cheddar: yeah, but that's strange isn't it?

7:05 isn't ants.clj written using agents and refs in order to avoid race conditions?

7:05 i'm not sure now that it's a race condition - at least it's not locking up

7:05 inspecting the ants in the repl, i see their coordinates are still changing

7:06 but the display isn't updating

7:09 hmmm, it seems maybe it works better when the JVM doesn't have the -server option

7:09 does that make sense?

7:13 rhickey: cheddar: I can reproduce - looking now

7:20 cheddar: it seems the ants are still moving around, but the screen redraws aren't occurring

7:20 actually it happens without -server as well

7:24 jgracin: hi! how do I dispatch on Java primitive byte array? I mean, my dispatch function is class and I'd like to add method for byte arrays.

7:29 rhickey: cheddar: fixed in master

7:40 cheddar: thanks!

7:49 hoeck: jgracin: I don't know whether clojure has array class-literals, but (defmethod foo (type (make-array Byte/TYPE 0)) [& args] ..) should work

7:55 jgracin: hoeck: thanks, I'll try that.

7:57 rhickey: jgracin: (Class/forName "[B")

7:58 http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html#getName()

8:27 jgracin: rhickey: thanks.

9:06 mtd: I have to manipulate and plot not-too-small data series (mostly priceA and priceB on the Y, time on the X) stored in an oracle db and I'd like to graph them. On the verrry off chance, is there any Clojure-REPL-hotness that I could play with?

9:07 Chouser: I have no idea how it handles large data sets, but I found this easy to use: http://www.markmfredrickson.com/code/

9:08 liebke: incanter should work, http://incanter.org

9:09 mtd: Chouser, liebke: thank you very much

9:09 Chouser: as for pulling the data out of oracle, I haven't done any of that yet. There are a couple sql apis you could look at.

9:10 clojure.contrib.sql

9:10 http://github.com/Lau-of-DK/clojureql/tree/master

10:36 stuarthalloway: is there a separate irc node for clojure-dev conversation, or is that all happening here? I have the day free to work on clojure, but don't want to clutter this form with dev talk if that is inappropriate

10:37 rhickey: stuarthalloway: here is fine

10:37 stuarthalloway: cool!

10:37 (1) just sent email to clojure-dev proposing the "simple way" to move clojure's tests into clojure

10:38 but I can imagine reasons that the simple way might cause problems, so willing to pursue some harder way if necessary

10:39 * rhickey hates the name test-is

10:40 stuarthalloway: if that is the most substantial problem we can probably reach an accomodation

10:40 Chouser: it was noted here recently that test-is has dependencies on several other contrib pieces.

10:40 rhickey: is there consensus around test-is? Is everyone in contrib using it for their tests? I'm fine with moving to clojure, but should be part of a broader plan to move some contrib bits to clojure, including pprint

10:40 right, and sorting out deps

10:40 stuarthalloway: those are both bigger problems

10:41 rhickey: this would be a good clojure-dev topic

10:41 stuarthalloway: bigger how?

10:42 stuarthalloway: the dependencies issue could lead to weeks of conversation going in circles

10:43 and, while important, is less important than making testing simple

10:43 I would even prefer the temporary expedient of a private subset of contrib buried in clojure for testing purposes only

10:43 to give the community time to consider dependencies at leisure

10:44 rhickey: stuarthalloway: well, someone should scope it so we're not speculating, I'm for test and pprint

10:44 Chouser: 2 versions of code, one in core and one in contrib, sounds a bit scary

10:44 stuarthalloway: Chouser: didn't say it was good

10:45 Chouser: :-)

10:45 stuarthalloway: but freezing (and endorsing) a testing library is a separate step from wanting to test core

10:45 Chouser: Are there problems now that would be solved by having the clojure tests in clojure instead contrib?

10:45 instead of

10:46 stuarthalloway: YES!

10:46 rhickey: I think the number one issue is not being able to submit a patch with both code and test

10:47 stuarthalloway: having to coordinate patches in two different repos is a big hurdle to community contribution

10:47 rhickey: by "scope it out" do you expect (1) a writeup of what it would look like, or (2) a fork so you can see the ideas develop in code?

10:48 rhickey: stuarthalloway: a list of deps would be a start

10:48 stuarthalloway: rhickey: seems like the easiest way would be to try--I will do it

10:49 * Chouser see the merging of lots of test patches in his future.

10:49 rhickey: Chouser: I mentioned yesterday I saw the #1 use case for pulls versus patches ong-running contrib project, like pprint, brought into clojure

10:49 long-running

10:50 stuarthalloway: rhickey: the "git way" is for me to just fork and go -- "fork" not having the negative connotations it does with other SCMS

10:51 so my plan is to fork Clojure, move contrib bits in, and get tests to run -- understanding that this may be throwaway work

10:51 then we can take a look, argue about names of things, etc.

10:51 that sound good?

10:51 rhickey: this will trash test-is history?

10:52 stuarthalloway: test-is history will be unavailable in the clojure repos

10:52 rhickey: I think everyone can presume pulling the bits in can be made to work

10:53 stuarthalloway: but still available in the contrib repos if needed

10:53 eevar2: you can merge git repos while preserving history

10:53 stuarthalloway: eevar2: this isn't a fully merge, though -- just grabbing piece until things work to sort dependencies

10:54 rhickey: stuarthalloway: I want it to end up one place or another, so Stuart can continue to work on it, so it is unlikely your fork will be merged unless it deal with these details

10:54 eevar2: yes. still, you'd filter out the paths you don't want beforehand, then merge/rename whatever pieces of contrib you want to add to core

10:55 hmm.. filtering out paths may ruin some of the history in what you're merging in, and might be a bad idea

10:55 *of what you're..

10:55 stuarthalloway: eevar2: I don't care (much) about the history in this case.

10:56 drewr`: Is there a way, possibly through meta info, to access information about a fn's caller?

10:56 stuarthalloway: Stuart Sierra is the primary (only) developer, and he knows where to find the history if he needs it

10:56 eevar2: okies. just letting you know it can be done

10:57 drewr: I guess what I'm looking for is something like elisp's defadvice.

10:57 rhickey: looks like just template/walk/stacktrace as deps

10:58 AWizzArd: And anyway: how often is the history older than a few weeks *really* needed? How often does rhickey look at what he did at revision 631?

10:58 stuarthalloway: rhickey: the cool thing about git is the ease of showing you my ideas, vs. just discussing them. I think the fork will spur a conversation. If it never gets merged, then that is fine

10:58 drewr: I want to say (defn #^{:deprecated true} foo [& args] ...) and throw an exception if foo is called anywhere.

10:59 rhickey: stuarthalloway: of course there's no harm, but I'm not seeing too much benefit either, a 2 minute perusal of the source shows 3 deps

11:00 Chouser: drewr: You can use a java exception (does not need to be thrown) to examine the stack

11:00 stuarthalloway: drewr: why not a macro that implements (deprecated foo)?

11:00 Chouser: drewr: but I don't think you'll be able to get from the java stack to the fn or var metadata.

11:00 at least not easily

11:01 drewr: why not just replace the body of foo with (throw (Exception. ...))?

11:02 stuarthalloway: rhickey: we'll see. I am a big believer in the difference between "could" and "did"

11:03 * stuarthalloway will be back. Driving to the office.

11:03 drewr: Chouser: That's what I originally did, then I got into thinking about what was possible in capturing fn invocation.

11:04 Chouser: drewr: I guess I don't see the benefit of doing it via metadata. Is there some use case where just calling (throw ...) is less desirable?

11:05 drewr: I went from that to just putting (deprecated!) as the first line in the fn where deprecated! does whatever I need at the time.

11:05 Chouser: you could also use (binding [foo (fn [& x] (throw ...))] ...) to only check certain call chains.

11:06 drewr: Ah, that's a good idea.

11:06 Chouser: or alter-var-root to change it after-the-fact

11:06 drewr: I'm not quite sure which fns will be called though.

11:21 Chouser: bah.

11:22 rhickey: would it be terribly difficult to change my clojure-dev member address from n01se.net to gmail.com?

11:22 my mail client (gmail!) is insufficiently powerful to handle the permission requirements well on my end.

11:25 or add my gmail.com address as well, I suppose.

11:27 rhickey: Chouser: sure, just apply to the group using your other identity, I don't manage emails, just users from google's perspective

11:28 Chouser: oh, ok.

11:28 j-dot: Chouser: I was able to change my email address on the "Edit my membership" page ... try here:

11:28 http://groups.google.com/group/clojure-dev/subscribe

11:29 Chouser: j-dot: than what? I don't see any way to change my email address there.

11:37 j-dot: Chouser: Hmmm ... I have a "Which address do you want to use for this group" option

11:38 perhaps that's because I've registered multiple email accounts in my Gmail settings

11:38 Chouser: j-dot: ah, ok. thanks.

11:38 j-dot: np

11:45 eevar: stuarthalloway: +1 for moving clojure-core tests into the clojure repo, btw

12:57 dhaza: can anyone point me towards information on jars and packaging in java?

12:57 im coming at clojure from a lisp background and the entire jar process is pretty opaque to me

12:58 j-dot: I don't have any URLs, but a jar is just a zip file with your code/classes

12:58 slashus2: Jars are just zip archives as far as I understand it.

12:58 Chouser: jars can also have a specially-named file with a bit of extra info in it

12:59 DougC: java packages are similar to namespaces in Clojure.

13:00 The class java.lang.String is in the package java.lang and the source is in a file called String.java

13:00 In the file system this would be in a directory structure as java/lang/String.java

13:01 dhaza: you need to jar the compiled files to have the code loaded?

13:01 or does it read the source upon load?

13:01 DougC: When you compile a java source file the bytecode ends up in a .class file

13:01 clojurebot: the unit of compilation in clojure is the namespace. namespaces are compiled (not files). to compile a namspace the namespace needs to be on the classpath and so does ./classes/ (and the directory needs to exist) because clojure writes the class files to that directory. http://clojure.org/compilation

13:01 Chouser: for Clojure, compiling is independent of bundling into a .jar

13:02 a .jar can have .clj or .class files and still work fine.

13:02 DougC: So java.lang.String would compile into a file in the filesystem as java/lang/String.class

13:03 dhaza: i get it

13:03 DougC: The CLASSPATH tells the jvm where to look for classes and it can contain path elements which are either directories or .jar files.

13:04 If a path element is a directory then it defines the directory in which those relative paths live. So one element of the classpath might be ~/classes and in there you would find java/lang/String.class

13:05 For jar files, as other have said, they're just zip files where the class directory structures are all zipped up (there are other conventions for things but they're not important for this discusssion)

13:09 dhaza: okay, so if my package name is 'org.foo.blah.MyClass', it would be in the jar under org/foo/blah/MyClass.class

13:09 Chouser: exactly

13:10 and your .clj file for that would usually be in some element of the classpath at org/foo/blah/MyClass.clj

13:11 though it's fine to have it in a different element of the classpath, and therefore not in the same directory as MyClass.class

13:12 For any given project I like to have a 'src' and a 'classes' directory, with both in my classpath. That way I can blow away the contents of 'classes' anytime I want to be sure I'm getting a clean build.

13:12 ...and I don't have to look at .class files littering up up 'src' dirs.

13:13 then if I make a .jar for that, I can pick either just the class files, just the clj files, or both.

13:13 mattrepl: stuarthalloway: Cluje, eh? =)

13:14 stuarthalloway: I think I liked "Frak" best

13:15 Chouser: I like verily!

13:15 (verily (= (foo) 1)))

13:18 hiredman: is it name game again?

13:18 time

13:20 stuarthalloway: verily, I say unto thee all: I am stepping away for 30 minutes to do a video interview with @coreyhaines

13:21 if thou wouldst agree on a name for thy core testing framework while I am going, I will implement it, and submit the fork to our glorious emperor

13:28 j-dot: haha, I like verily ... but if I was that confident, why would I bother testing?

14:17 r2q2: Hello

14:18 Chouser: Hi

14:21 kefka: ,(inc (Long/MAX_VALUE))

14:21 clojurebot: java.lang.ArithmeticException: integer overflow

14:21 stuarthalloway: rhickey: I will rename clojure.contrib.test-is to clojure.test

14:22 what about the dependencies: stacktrace, template, and walk?

14:22 kefka: Is this a bug, or should we explicitly not use inc / dec if we want integer promoption?

14:22 stuarthalloway: each in their own namespace under clojure?

14:22 kefka: ,(inc 12345678901234567890123)

14:22 clojurebot: 12345678901234567890124

14:22 stuarthalloway: or maybe put walk into core?

14:22 (walk is way cool and I end up using it on every project)

14:23 Chouser: Long/MAX_VALUE is a primitive

14:23 ,(inc (Long. Long/MAX_VALUE))

14:23 clojurebot: 9223372036854775808

14:25 r2q2: I was wondering if there is a plan for clojure to use the new java 7 features that allow for dynamic languages?

14:26 http://openjdk.java.net/projects/mlvm/

14:27 hiredman: r2q2: mlvm is not java 7

14:28 mlvm is an experimental vm

14:28 clojure targets java 5, because that is everywhere

14:28 brett_h: Does anyone have a link to an explanation on what it means for something to be "composable", I'm specifically referring to the "locks don't compose, but STMs do" here: http://www.slideshare.net/jboner/state-youre-doing-it-wrong-javaone-2009

14:29 r2q2: hiredman: Yea thats what I thought.

14:29 hiredman: I meant JSR 292 but yea I was guessing its too far out there to support.

14:30 rhickey: ,(inc (num (Long/MAX_VALUE)))

14:30 clojurebot: 9223372036854775808

14:32 stuhood: brett_h: Mark Volkmann's Clojure article contains "The Bank Example": http://java.ociweb.com/mark/clojure/article.html#Refs

14:32 hiredman: brett_h: if you have a locking strategy for A and a locking strategy for B, just mashing those two locking strategies together doesn't work

14:32 dhaza: brett_h, composable is similar to nestable, you can nest STM transactions, you cant nest locks

14:33 well, i said that wrong

14:33 you can nest locks, but not arbitrarily

14:33 brett_h: hiredman: you mean it doesn't always work, where transactions do? like you don't have to think about it?

14:33 dhaza: yeah, arbitrarily is what I was thinking

14:33 ok that helps

14:33 stuhood: thanks I'll check it out

14:34 stuhood: brett_h: no problem... not really an explanation, but a great example

14:34 brett_h: oh yeah, I've read that

14:35 I was kind of hoping for a "see, locks fail here because they aren't composable" but I think I get what dhaza means

14:35 you can't arbitrarily combine things that lock and expect them to work

14:36 stuhood: brett_h: right, so in that example the withdrawals and deposits need to be atomic, so they would have to be protected with locks traditionally. but if you want to transfer money, you need another lock around the first two.. which means there is deadlock potential unless you start thinking about lock ordering

14:36 brett_h: right, thanks

14:38 rhickey: search for compose in: http://en.wikipedia.org/wiki/Software_transactional_memory

14:38 brett_h: rhickey: perfect, thanks

14:42 stuarthalloway: rhickey: I have renamed clojure.contrib.test-is to clojure.test on the fork: http://github.com/stuarthalloway/clojure/tree/c718835af09f238f8f9d57c330951e1a8e906475

14:43 remaining todo:

14:43 (1) rename the dependencies from clojure.contrib to ????

14:43 (2) fix contrib to match

14:45 rhickey: stuarthalloway: you can use one of the assembla wiki pages for this kind of punchlist

14:46 stuarthalloway: rhickey: ok doke

14:46 if you are ok with the renaming, I could just be done in another 30 mins or so

14:47 packages in question are stacktrace, template, and walk

14:47 rhickey: putting the issues in a single place will help me make a decision and others to chime in on any missing pieces or things you haven't thought of

14:48 stuarthalloway: should I create a ticket too, and link out to the wiki page?

14:48 rhickey: sure

14:52 I'm not sure how I feel about template, stacktrace and walk seem fairly straightforward

14:52 I'm talking about the contents, not the names

14:52 stuarthalloway: agreed!

14:52 I was about to move template into test

14:52 clojure.test.template

14:53 as a way of marking it to be internal detail

14:53 could also make the bits private to clojure.test

14:53 which would be a stronger statement of same

14:53 Ticket is at http://www.assembla.com/spaces/clojure/tickets/131-Move-Clojure-tests-from-contrib-into-Clojure

14:54 wiki page at http://www.assembla.com/wiki/show/clojure/Getting_Tests_Into_Clojure

14:54 rhickey: iirc Stuart said he needed template for 'are'?

14:54 stuarthalloway: yep

14:55 rhickey: are there other consumers of template?

14:56 stuarthalloway: checking...

14:57 only contrib.condt

15:04 ok, everything is renamed into clojure except template

15:04 gonna fork contrib and pull out the items added to clojure, and make sure *that* works

15:23 r2q2: ,{:a 1,,,,,,,,,,,,, :b 2,,,,,,,,,,,}

15:23 clojurebot: {:a 1, :b 2}

15:24 Lau_of_DK: Compojurefreaks - Anybody worked out, how one can benefit from the (with-session) macro ?

15:40 rzoom: what does max-key do if there are multiple keys with the max value?

15:41 hiredman: (doc max-key)

15:41 clojurebot: "([k x] [k x y] [k x y & more]); Returns the x for which (k x), a number, is greatest."

15:41 rzoom: seems to take the last key

15:41 shoover: there is a lot of forking going on here

15:42 gnuvince: here where?

15:42 shoover: this room, clojure in general

15:43 Chouser: so far nobody has forked with the intention to do anything other than either merge back into clojure, or throw it away. So no need to worry.

15:44 shoover: understood, it's interesting to see all the activity

15:44 hiredman: did we ever get that flag to stop read from evaling stuff?

15:54 Chouser: hiredman: looks like it: https://www.assembla.com/spaces/clojure/tickets/38

15:54 ,*read-eval*

15:54 clojurebot: true

15:54 Chouser: ,(doc *read-eval*)

15:54 clojurebot: "; When set to logical false, the EvalReader (#=(...)) is disabled in the read/load in the thread-local binding. Example: (binding [*read-eval* false] (read-string \"#=(eval (def x 3))\")) Defaults to true"

16:12 rhickey: saw some tweets re: test-is inclusion implying the end of testing frameworks, thoughts?

16:13 Chouser: I have no alegience, but the current clojure regression tests use test-is. That's a bit inescapable.

16:13 stuarthalloway: ruby having test::unit didn't stop rspec, shoulda, and micronaut...

16:14 Chouser: it can't be worth re-writing the tests to use something else.

16:14 dhaza: find/replace

16:15 stuarthalloway: also, the testing library used to test clojure needs to be (relatively) minimal compared to frameworks people might create to test clojure application code

16:15 Chouser: I suppose the core version of test-is could be made private, but that seems a bit dumb since it will be used and maintained.

16:15 rhickey: Chouser: no, but there may be other ways to organize things without seeming to bless one

16:15 stuarthalloway: I don't think it is a problem

16:16 Chouser: namespace doc string that says, "there are many clojure testing frameworks -- one of the others may fit your needs better than this one"?

16:16 stuarthalloway: +!

16:16 hiredman: ~ticket 38

16:16 clojurebot: Gabh mo leithscéal?

16:16 hiredman: clojurebot: why?

16:16 clojurebot: why not?

16:16 Chouser: ~ticket #38

16:16 hiredman: ~ticket #38

16:16 clojurebot: {:url http://tinyurl.com/mngulq, :summary "GC Issue 34: A Lisp reader without access to EvalReader()", :status :fixed, :priority :low, :created-on "2009-06-17T19:11:53+00:00"}

16:16 {:url http://tinyurl.com/mngulq, :summary "GC Issue 34: A Lisp reader without access to EvalReader()", :status :fixed, :priority :low, :created-on "2009-06-17T19:11:53+00:00"}

16:16 Chouser: whee!

16:16 dhaza: clojurebot, Trej buil listileace misceal

16:21 suresh: hello all.. am new to clojure.. can anyone help me understand these lines..

16:21 (defmacro #^{:private true} -?>

16:21 ([form] form)

16:21 ([form next-form & forms]

16:21 `(when-let [x# ~form] (-?> (-> x# ~next-form) ~@forms))))

16:21 r2q2: suresh: What are the lines supposed to do?

16:22 suresh: those lines are from Ring.. i'm curious what the macro does

16:24 slashus2: It only chains while the forms are true?

16:25 suresh: slashus2: can you help me understand by deconstructing those lines?

16:26 hiredman: suresh: it is a short circuiting version of →

16:26 r2q2: suresh: What is the name of the macro? It seems to be missing that?

16:26 hiredman: "->"

16:26 r2q2: -?>

16:27 r2q2: Oh

16:27 hiredman: it's in contrib these days

16:27 clojurebot: contrib is http://code.google.com/p/clojure-contrib/

16:27 hiredman: (doc -?>)

16:27 clojurebot: "clojure.contrib.core/-?>;[[x form] [x form & forms]]; Same as clojure.core/-> but returns nil as soon as the threaded value is nil itself (thus short-circuiting any pending computation). Examples : (-?> \"foo\" .toUpperCase (.substring 1)) returns \"OO\" (-?> nil .toUpperCase (.substring 1)) returns nil "

16:28 suresh: ah.. didnt know it was part of contrib

16:28 dnolen: i think it would look better if it was ->? or ?-> to preserve the arrow. -?> looks to much like line noise.

16:28 hiredman: it is now, it is possible that ring started using before it was in contrib

16:29 r2q2: (doc ->)

16:29 clojurebot: "([x form] [x form & more]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc."

16:35 rhickey: technomancy: you had some reservations about assembla the other day?

16:36 technomancy: rhickey: no, I don't think so. unless it was about the volume of email, which is pretty solvable.

16:36 rhickey: ah, ok

16:37 technomancy: rhickey: any further suggestions for CS papers? I got my Kindle yesterday and just finished Out of the Tarpit.

16:37 great stuff.

16:39 * rhickey looks at the 1569 pdf papers in his downloads dir in despair

16:39 technomancy: hah

16:39 ls ~/documents/papers | lisppaste

16:39 rhickey: unfortunately they are almost universally badly named

16:40 technomancy: heh, right.

16:40 well I've got enough to keep busy for the time being.

16:41 spent twenty minutes yesterday just clicking madly on download links at feedbooks.com for classics.

16:45 rhickey: 43 on STM, 257 on functional programming, 20 on persistent data structures, 54 on purely functional something, 111 on the cochlea ...

16:46 49 on RDF, 256 on concurrency...

16:47 * Chouser didn't know there were more than 3 papers on RDF

16:47 rhickey: 69 on datalog, 169 on locks, 379 on lisp

16:48 etc

16:48 * rhickey likes to read

16:48 stuarthalloway: how many on FP in dynamic languages?

16:48 rhickey: 100 on erlang

16:49 Chouser: what percentage of these have you read?

16:49 stuarthalloway: technomancy: not cs, but read Daniel Suarez's Daemon if you haven't already

16:49 rhickey: all

16:49 I read them as I get them

16:49 these go back to 2003 on this machine

16:49 technomancy: stuarthalloway: will check it out; thanks

16:50 rhickey: a lot of technical papers are only 12 pages

16:50 technomancy: oh, it's only available as a DRM'd ebook. =(

16:51 rhickey: but I've also read, e.g. Joe Armstrong's PhD thesis, quite good

16:52 obviously some of those numbers overlap, just doing a raw search

16:54 unfortunately there aren't many like Out of the Tarpit, research papers tend to be very narrowly focused, and in order to read one you almost always have to read one or more of the papers it references etc

16:55 stuarthalloway: technomancy: *loving* emacs-starter-kit, thank you!

16:55 technomancy: stuarthalloway: awesome.

16:55 rhickey: I should put together a list of at least the ones that mattered most in the end

16:55 dysinger_: stuarthalloway - for those of us on clojure 1.0 and depending on clojure-contrib for test-is and other things - If you refactor it out - then we have to freeze clojure-contrib for a while ......

16:55 stuarthalloway: still undecided about paredit-mode -- do most Clojurians use it?

16:55 dysinger_: no more march straight onward

16:55 hiredman: dysinger_: or cut a release

16:55 dysinger_: y

16:56 technomancy: stuarthalloway: it takes some getting used to, but I will never voluntarily go back.

16:56 dysinger_: technomancy showed me paredit-mode - I am hooked

16:56 wouldn't code without it now

16:56 rhickey: yes please, a contrib release corresponding to 1.0 would be hugely useful

16:57 technomancy: stuarthalloway: the big hurdle is there's no way to just explore it; a lot of its features are hidden until you just look through the list of keybindings it provides

16:57 maybe I should do a short focused screencast on paredit... hrm.

16:57 it's one of those things that's far easier to learn by example

16:57 stuarthalloway: technomancy: that would be a *great* screencast

16:57 esp. since people keep whining about IDE support

16:58 dysinger_: they'll never be happy :)

16:58 stuarthalloway: would be nice to see the benefits of coding in sexprs

16:58 dysinger_: y it's really cool

16:58 technomancy: yeah, most of the other features you see ported to IDEs, but I've never seen paredit duplicated.

16:58 dysinger_: you don't have to track down your paren ending out of ))))))))) anymore - just cut/paste/move etc

16:58 stuarthalloway: it would be lot harder to write a structural edit mode for a language with ... more structures

16:59 * rhickey needs to try paredit

16:59 rhickey: does it understand [] and {}?

16:59 technomancy: rhickey: recent versions do

16:59 * technomancy found this rather helpful: http://www.emacswiki.org/emacs/PareditCheatsheet

17:00 stuarthalloway: and it uses the close versions ] } ) to mean different things

17:00 ...regardless of what form you are closing

17:00 r2q2: rhickey: yes.

17:00 dysinger_: I love that they call it barfage and slurpage

17:01 r2q2: rhickey: Documentation is sort of lacking the cheatsheet or the comments in paredit.el are your best bet in understanding what it does.

17:01 dysinger_: It's easy when someone shows you it in action. Technomancy showed it to me and I was like "ah" and mimicked like a monkey in 5 minutes

17:02 technomancy: yeah, sounds like a screencast is in order. =)

17:02 r2q2: rhickey: Actually it doesn't understand {} but it does understand []

17:02 dysinger_: the editing and the cut and paste without worrying about () {} [] is awesome

17:03 ah - haven't tried with {} yet

17:03 r2q2: Hrm oops I'm running an older version

17:04 dhaza: why cant the editor call into clojure to get help with the parse tree and how to indent?

17:04 technomancy: dhaza: totally possible. emacs does that with CL, but nobody's hooked up the wiring to do it w/ clojure yet.

17:04 clojurebot: emacs is best configured for Clojure with instructions at http://technomancy.us/126

17:05 technomancy: dhaza: it's preferable to have static indentation rules imho though since if you auto-indent in Emacs (where it understands those rules) and someone else on the project uses a different editor, you won't be able to achieve consistency.

17:05 dhaza: cool. because reader macros are groovy o_o

17:06 wlr: paredit dwim re: () {} [] "" for me at least

17:06 technomancy: oops. I bundled an older version of paredit in the starter kit so it doesn't auto-insert balancing {} chars.

17:07 it understands them when enforcing sexp validity, but it just doesn't insert closing ones for you. will update.

17:10 wlr: wrapping n exprs with M-n ( or M-n [ or M-{ or M-" as appropriate is really handy

17:12 * r2q2 Doesn't understand why {} isn't being matched in paredit on his system...

17:12 technomancy: r2q2: you need paredit 21 or higher

17:13 r2q2: I self installed v21

17:13 I even evaluated and loaded paredit 21

17:14 technomancy: oh... clojure-mode is expecting paredit to be loaded before it loads, which is not always the case.

17:14 * technomancy investigates

17:15 r2q2: Oh yea thats probably the problem. I was manually enabling paredit as a minor mode.

17:16 technomancy: looks like it needs to be enabled in a hook

17:16 r2q2: (add-hook 'clojure-mode-hook (lambda () (paredit-mode +1)))

17:16 technomancy: which is what it says in the docs at the top, but it's easy to miss.

17:17 r2q2: If you have questions about paredit riastradh is on #scheme.

17:18 dysinger_: I had to add a clojure-mode hook for paredit too

17:18 and I installed paredit with elpa

17:18 r2q2: As long as that is evaluated before clojure-mode that mode hook should work.

17:20 dysinger_: I have autoload for clojure based on file extension and then the paredit clojure-mode hook after

17:20 r2q2: Well

17:20 dysinger_: which I think accomplishes the same

17:20 anyway it works

17:21 r2q2: Yea thats fine I was probably doing something funny. Nevermind

17:26 Anyone use redshank ?

17:27 technomancy: r2q2: I think redshank is pretty cl-specific

17:27 lisppaste8: dysinger pasted "my el init" at http://paste.lisp.org/display/82154

17:28 dysinger: kool lisppaste is nice

17:28 r2q2 there's my el init (based on emacs-starter-kit) (as tim.el)

17:32 r2q2: technomancy: Yea I know some of it is. The mouse copy function was usable in scheme.

17:32 technomancy: It was the only feature that was actually useful.

17:32 technomancy: what's it for?

17:33 r2q2: Well

17:34 It allows you to write a lisp expression and insert it at an arbitrary point

17:36 It copies an sexpr from the point that you click at to the point of your cursor

17:37 I'm doing a horrible version of actually telling you what it does. http://lispm.dyndns.org/news?ID=NEWS-2007-11-18-1 is much better

18:08 rhickey: Clojure bookshelf: http://www.amazon.com/Clojure-Bookshelf/lm/R3LG3ZBZS4GCTH/ref=cm_lm_byauthor_title_full

18:09 technomancy: rhickey: nice; thanks!

18:10 liebke: rhickey: great list!

18:10 arohner_: rhickey: that is really cool

18:10 I only have 1/7th of that list...

18:12 rhickey: I'm not sure I got the latest edition of every book in the links

18:13 technomancy: Dylan, huh? wouldn't have guessed that.

18:14 mrsolo: thats a lot of books

18:15 technomancy: a good portion of them you can find as PDFs

18:15 mrsolo: lisp in small pieces is one expensive book

18:16 technomancy: mrsolo: there was a mistake on amazon.ca that had it being sold for $4 for a while

18:16 mrsolo: missed that heh

18:16 technomancy: they didn't deliver, but they sent a coupon to everyone who ordered it. =)

18:16 n

18:16 mrsolo: purely functional data structures was way over my head firt time i read it

18:23 ataggart: rhickey: do you have a personal site, where you stick links like the one to the bookshelf?

18:23 rhickey: ataggart: no

18:29 r2q2: I'm probably being nitpicky but the semantics of (identical? "foo" "foo") has changed since the video Clojure Data Structures has been made. At the time of the video was made (identical? "foo" "foo") => false , while in clojure 1.0 (identical? "foo" "foo") => true . The time that this occurs is at 32:00.

18:31 dreish: My guess would be that the difference is strings passed to eval are all getting interned now.

18:31 More of an eval change than an identical? change.

18:32 rhickey: r2q2: it wasn't guaranteed then (string literal interning), it is now

18:33 r2q2: Oh okay.

18:34 rhickey: ,(identical? (str "str" "ing") "string")

18:34 clojurebot: false

18:46 mrsolo: why is clojure designed in the way so that (+ nil) doesn't raise NPE?

18:47 ,(:a nil)

18:47 clojurebot: nil

18:47 mrsolo: ,(nil :a)

18:47 clojurebot: java.lang.IllegalArgumentException: Can't call nil

18:47 mrsolo: ,(+ nil 3)

18:47 clojurebot: java.lang.NullPointerException

19:13 banister: hey what's the diff bw multimethods and functional overloading

19:14 ataggart: the former uses an arbitrary dispatch function, and the latter is based on arity (if I understand your meaning of "functional overloading")

19:15 banister: overload

19:16 thanks

19:16 hey can type hints be used to check for type correctness

19:16 Chouser: no

19:17 banister: hmm ok

19:17 hiredman: ~deft

19:17 clojurebot: deft is http://gist.github.com/128259

19:17 banister: why not?

19:17 hiredman: because no one has written something to do it yet

19:17 Chouser: well, it will catch some circumstances, but not all.

19:18 banister: do you think they will ? cos it seems the only major criticism I hear about clojure to date

19:18 Chouser: I wrote up an example once showing a case where it doesn't catch the type difference. I wonder where i put it.

19:19 banister: are you talking about runtime or compile time type checking?

19:19 banister: compile time

19:20 can't you just take the system from scala?

19:21 technomancy: open source doesn't work like that. =)

19:21 ataggart: sounds like an IDE feature waiting to be written

19:22 banister: but I mean both scala and clojure blatantly take from erlang why doesn't clojure take this one thing from scala?

19:22 r2q2: You can't just blindly import a system from an opensource language and plop it to another. You would have to rewrite it.

19:22 hiredman: banister: deft does very simple compile time type checking

19:23 (and completely ignores types at runtime)

19:23 drewr: What has clojure "blatantly" taken from erlang?

19:23 Chouser: technomancy: I think it's more of languages not working that way than open source.

19:24 technomancy: Chouser: yeah, it was a joke.

19:24 sort of.

19:24 Chouser: banister: I expect clojure will evenutally have a system for making assertions about the code at compile time.

19:24 ataggart: can someone remind me how odl clojure is again?

19:24 *old

19:25 Chouser: banister: I imagine it will not be based solely around Java classes

19:25 technomancy: banister: that's the joy of young languages; you get to be involved in writing that kind of stuff. =)

19:25 hiredman: younger than the mountains, older than the trees

19:25 mrsolo: drewr: function dispatch based on arity very handy

19:25 Chouser: mrsolo: also very fast on the JVM.

19:25 mrsolo: sorta..although erlang does a lot more

19:25 hiredman: mrsolo: hardly exclusive to erlang

19:25 mrsolo: hardly

19:26 inspired i guess

19:26 hiredman: even java can do that

19:26 ataggart: "even" lol

19:26 technomancy: "even my grandma can do that"

19:26 "... and she's been dead for seven years"

19:26 mrsolo: only rick can answer what language inspired that part <shrug>

19:27 hiredman: I think C++ can do that too

19:27 Chouser: ataggart: I think Nov. '98 was 1 year since it was first "released"

19:27 hiredman: but my c++ is shakey

19:27 mrsolo: erlang is listed in the book list.. clojure must have taken something out of that langauge

19:28 may be distrubted programming in the future release? :-)

19:28 Chouser: ataggart: I believe rhickey was working on it for 1.5 to 2 years or before that initial "release"

19:28 ataggart: chouser: 1998?!

19:28 Chouser: heh

19:28 2008

19:28 sorry

19:28 ataggart: ahh ok

19:36 mrsolo: ,(/ 1)

19:36 clojurebot: 1

19:36 mrsolo: ,(/ nil)

19:36 clojurebot: java.lang.NullPointerException

19:37 mrsolo: ,(* nil)

19:37 clojurebot: nil

19:41 ataggart: the one-arg arithmetic ops seem to have alternate behavior

19:41 r2q2: Yea

19:41 I was going to say that

19:41 ,(*)

19:41 clojurebot: 1

19:41 ataggart: (-)

19:41 r2q2: ,(+)

19:41 clojurebot: 0

19:41 r2q2: ,(-)

19:41 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$-

19:41 r2q2: ,(/)

19:41 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$-SLASH-

19:42 r2q2: Hrm + and * like being called without anything.

19:42 ataggart: as (+ 5 1) =>6 and (- 5 1) =>4, I would expect (+ 5) and (- 5) to both => 5

19:42 ,(- 5)

19:43 clojurebot: -5

19:43 r2q2: ,(+ 1)

19:43 ataggart: so it's more like operator overloading

19:43 clojurebot: 1

19:43 banister: do you guys think of scala as the enemy

19:43 ataggart: it's a language

19:43 r2q2: I have no opinion of scala. I know its a language I know it has static typing.

19:44 hiredman: ~scala

19:44 clojurebot: Unfortunately the standard idiom of consuming an infinite/unbounded resource as a stream can be problematic unless you're really careful -- seen in #scala

19:44 drewr: I find Scala less interesting than Clojure, but that's mostly out of ignorance.

19:44 hiredman: #scala is a scary place

19:44 banister: competing with scala clojure for the functional concurrency crowd on jvm?

19:44 Chouser: banister: not at all. It's got pretty different goals around dynamism, type systems, metaprogramming, etc.

19:45 technomancy: banister: they target very different audiences. to appreciate scala you have to think that on some level, Java (the language) is almost a good idea.

19:45 drewr: I know that I have questions about a functional language whose programming tome has mutable state in its first code example. :-)

19:45 hiredman: banister: I cannot concieve of competition between clojure and scala, in my mind there is no competition

19:45 mrsolo: use both of them <shrug>

19:45 banister: I own the programming scala book but it's size scares me

19:45 hiredman: I hang in #scala too, and my impression is that the scala language is a train wreck

19:46 mrsolo: hiredman: is it? hmm

19:46 i went through scala book and tutorial. thats about it

19:46 hiredman: mrsolo: that is just my impression from the irc channel

19:47 mrsolo: i didn't find any major flaw other than the toolchain was a bit buggy

19:47 ataggart: count me among the cadre that has no opinion of scala

19:47 hiredman: clojure is just so much more elegant and simpler

19:47 r2q2: Is lazy-seqs prefered now to lazy-cons?

19:47 Chouser: I did a couple dozen projecteuler problems in scala before learning clojure.

19:47 r2q2: lazy-cons is gone

19:47 ataggart: r2q2: it replaces it

19:47 r2q2: Yea thats what I thought.

19:48 technomancy: I read through a lift tutorial, but I got turned off by the fact that there was more XML than scala code in the first chapter.

19:48 hiredman: ~literal [0] scala

19:48 clojurebot: also<reply>"we are completely screwed on ==." -- seen in #scala

19:48 hiredman: bah

19:48 r2q2: Because the website says that it is the prerelease in SVN trunk

19:48 The video says to use lazy-cons.

19:48 ataggart: old video is old

19:48 hiredman: svn is old

19:48 technomancy: too bad you can't patch videos like you can code. =\

19:48 hiredman: ~literal [1] scala

19:48 clojurebot: <reply>Unfortunately the standard idiom of consuming an infinite/unbounded resource as a stream can be problematic unless you're really careful -- seen in #scala

19:49 Chouser: hiredman: is that one not true in Clojure as well?

19:49 hiredman: ~literal [2] scala

19:49 clojurebot: 2 is out of range

19:49 hiredman: Chouser: well clojue nulls locals for you

19:49 clojure

19:49 scala does not

19:49 Chouser: hiredman: oh, they're not just talking about trying to consume the whole thing?

19:50 oh. my.

19:50 r2q2: How should I learn clojure other than using the website or the videos?

19:50 hiredman: r2q2: the videos are fine, just old

19:50 ataggart: write some

19:50 hiredman: euler it up some

19:50 technomancy: r2q2: read some. then write some more.

19:51 ~mire

19:51 clojurebot: mire is http://github.com/technomancy/mire/tree/master

19:51 technomancy: ^an example project that might be helpful

19:52 hiredman: nah, you should make clojurebot less of sprawling disaster

19:52 :)

19:52 ataggart: d'oh

19:53 ,(< 5)

19:53 clojurebot: true

19:53 ataggart: ,(> 5)

19:53 clojurebot: true

19:53 ataggart: it's a miracle

19:53 hiredman: ,(doc >)

19:53 clojurebot: "([x] [x y] [x y & more]); Returns non-nil if nums are in monotonically decreasing order, otherwise false."

19:53 slashus2: 5 is greater and less than

19:54 hiredman: "5" is in monotonically decreasing order

19:54 and increasing too

19:54 ataggart: ,(<)

19:54 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$-LT-

19:54 Chouser: ,(< 2 5 9)

19:54 clojurebot: true

19:54 ataggart: semms like zero- and one-args should behave the same

19:54 mrsolo: ,(< nil)

19:54 clojurebot: true

19:55 hiredman: ok

19:55 thats cute

19:55 ~def <

19:55 must be a fast path

19:55 ataggart: ([x] true)

19:55 slashus2: fast path?

19:56 hiredman: slashus2: fastest path is the shortest

19:56 one arg to < is always true

19:56 so one arg gets the shorest bit of code possible to always return true

19:56 ataggart: I can't think of a case where you'd care about having one-arg work, but not care about zero args working

19:57 technomancy: I can't think of a case where you'd care about having one-arg work, period

19:57 seems like an implementation detail to allow for a more concise definition

19:57 hiredman: technomancy: apply?

19:57 ,(apply > '(5))

19:57 clojurebot: true

19:58 ataggart: ,(apply > '())

19:58 technomancy: hiredman: would need a little more context than that.

19:58 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$-GT-

19:58 mrsolo: i like the behavor around nil a bit consistent.. i mean this is very nice suprise

19:58 ,(-> {:1 {:a 3}} :2 :b)

19:58 clojurebot: nil

19:58 hiredman: technomancy: if you want to check if a list of numbers is ordered

19:59 technomancy: I guess so... but I don't think that's the intention behind the implementation.

20:00 hmm... actually that doesn't seem to be the case; never mind.

20:00 the >1 arities don't call the 1-arity body

20:01 ataggart: ah good catch

20:03 hiredman: that would be very silly

20:04 technomancy: yeah, doesn't make sense now that I look at the code.

20:05 hiredman: the fast path is there for no reason but to make (> 5) fast

20:07 slashus2: Why does < put (first more) and (next more) in symbols... they use them so often.

20:08 ataggart: s/does/doesn't ?

20:08 hiredman: hopefully first and next are fast

20:08 slashus2: It seems increases the performance when that is done, but it isn't very much unless you are comparing 10000000 numbers.

20:09 900 msecs compared to 660 msecs or so.

20:09 I ran them each 10 times.

20:11 Tested with (dotimes [_ 10] (time (apply < (range 10000000))))

20:13 Am I right? :-(

20:14 rhickey: slashus2: this kind of microbenchmarking really isn't productive at this stage. If you make any decisions based upon it they could be completely blown in the future

20:15 slashus2: rhickey: I know, I was just making sure my observation was correct. I wasn't suggest that we change anything. Premature optimization is not the current goal.

20:17 sorry :-(

20:19 rhickey: np, I always wonder about such uses of apply

20:24 diff much small for me, jdk 6 os x: 760 vs 620

20:25 slashus2: I just did (let [next-more (next more) first-more (first more) ... and used those throughout the bottom part.

20:25 I am running jdk 6 on os x too.

20:25 rhickey: with chunks, 612 vs 513

20:25 ataggart: does let have any more overhead than declaring local variables in java?

20:26 slashus2: :-D

20:26 rhickey: ataggart: not unless you do destructuring, then there's some logic too

20:27 better to spend time writing interesting software...

20:31 ataggart: agreed, more curiosity than anything else. plus its good to know when someone asks later on.

22:22 holmak_: In a (dosync ...) expression, does the expression block until the transaction completes?

22:25 so, if i "(dosync (alter some-ref inc)) @some-ref", am i guaranteed to get the incremented value of some-ref when i dereference it?

22:33 Chouser: holmak_: inside dosync, things may block, but also the whole transaction may be retried.

22:34 holmak_: Okay... so my question is, when you leave the (dosync ) block, does that mean the change has gone through successfully?

22:34 Chouser: yes

22:35 of course it may have been changed by something else in the mean time

22:35 holmak_: Awesome, thanks

22:35 Yeah, but only one thing changes this -- i'm using the ref to pass a value back across an async Swing call

22:36 Chouser: if you're only ever changing one value at a time in a dosync, you might want to look at 'atom'

22:36 holmak_: does swap! have the same kind of guarantee?

22:36 Chouser: yes

22:37 holmak_: I know the concurrency stuff guarantees consistency and all that, but I wasn't sure if it just acknowledged the transaction and would keep working at it while your code continues

22:37 Thanks for the clarification

22:37 Chouser: this is synchronous behavior -- some of the concurrency is synch, other is asynch.

22:38 agents, for example, are async. (send-off my-agent inc) @my-agent ... at the deref, the inc may not have happened yet.

22:38 clojurebot: for is not a loop

22:38 holmak_: I had also considered using an agent, since i knew i could 'send' then 'await', but async wasn't the behavior i needed here

22:39 I'm pretty okay with the concurrency stuff, its quite neat. There are just a lot of nuances to concurrency guarantees...

22:41 Chouser: indeed

22:41 holmak_: Good times though, that's why I love playing with Clojure. Doing locks correctly is certainly beyond me. :D

22:55 samuels: hey

23:20 Chouser: do you have a link to your clojure snakes program

23:22 Chouser: samuels: wow. not sure...

23:23 hey look at that, it's on github

23:24 http://github.com/Chouser/programming-clojure/blob/02485e760de2cbfa5c58d9f97f4f8205c15f1286/examples/snake.clj

23:26 samuels: thanks!

23:27 Chouser: I haven't touched it for ages -- dunno if it even works anymore.

23:28 samuels: does your version have much mutable state?

23:30 Chouser: samuels: I really don't remember, but looking at it I see very little.

23:31 there are two 'dosyncs', both changing a single game-state reference

23:35 samuels: thanks

23:40 durka42: ~logs

23:40 clojurebot: logs is http://clojure-log.n01se.net/

Logging service provided by n01se.net