#clojure log - Feb 09 2010

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

0:00 JonSmith: so it would be something like (get array value) or something?

0:01 arohner: I'm trying to look up the javascript syntax for it

0:01 I know it's possible in scriptjure, I don't remember how

0:02 ninjudd: i noticed that it isn't efficient to get the size of a PersistentQueue, because counting the number of elements in the front list requires O(n) time

0:02 JonSmith: okay

0:02 i will do some research

0:02 just wanted to know it was possible :-)

0:03 is a really nice library btw

0:03 arohner: thanks

0:03 :-)

0:03 ninjudd: i can submit a patch to fix it

0:11 JonSmith: ah

0:12 i think the solution is to just use dot notation

0:12 arohner: JonSmith: how?

0:14 JonSmith: arrays are just like objects bc objects are associative arrays

0:14 so i think if i do

0:14 array.index

0:14 should be similar to array[index]

0:15 arohner: maybe this doesn't work after all

0:15 if you don't figure it out, file a bug

0:19 JonSmith: okay

0:22 hiredman: ,(counted? clojure.lang.PersistentQueue)

0:22 clojurebot: false

1:02 wdouglas: incanter's chrono is so nice <3

1:11 DeusExPikachu: I'm getting some weird behavior trying to modify swank.clj in lein-swank. I modifed it, built it with lein jar, installed it to local repo with lein install, then made a new project to test it, added it as a dev-dependency, lein deps, and lein repl'd the new project, when I enter the namespace and (doc swank), I get the old definition, even though the modified lein-swank jar exists (with modifications) in lib and it is

1:11 in the class path, what's going on?

1:21 wdouglas: is the old one in the classpath too? Might you have another swank around in ~/.swank-clojure?

1:24 DeusExPikachu: well at least in lib, theres only the modified lein-swank, I'm checking the whole class path, its a pretty big list

1:25 crap, it is in there... hmm seems like order is important in this case

1:26 is there a way to specify which definition you would like to be used?

1:42 TheBusby: so is it still possible to write scripts with clojure by having #!/usr/bin/clj at the top of the script? Clojure 1.1.0 doesn't seem to like the old clojure.lang.Script syntax...

1:42 er, I mean #!/usr/bin/env clj

1:43 nmind, answered my own question must supply "-" as a CL arg...

1:44 hiredman: don't use Script

1:44 clojure.main replaces Script and Repl

1:44 TheBusby: main with what options though?

1:45 hiredman: as far as I know there is no canonical script for starting clojure, so just saying 'clj' doesn't tell anyone anything about how you are starting clojure

1:45 TheBusby: I mean using a bash script called clj which sets up the classpath and executes the java command

1:46 evidently the switch to clojure.main has changed the execution syntax

1:47 it appears to be $JAVA_EXEC clojure.main $1 $@

1:47 hiredman: TheBusby: sure, but as I said, since I have no idea what is in your clj script or where you got it, just saying 'clj' doesn't tell me a lot

1:48 passing $1 and $@ together like that is weird

1:48 $@ contains $!

1:48 er

1:48 $1

1:49 TheBusby: hiredman: you're correct. I assumed most people were using something similiar http://pastie.org/815870

1:49 $1 so that java reads the script file

1:49 $@ so that clojure can see the script name it came from

1:49 argv[0] = program name

1:49 not necessary?

1:51 hiredman: hmmm

1:52 ,(doc *file*)

1:52 clojurebot: "; The path of the file being evaluated, as a String. Evaluates to nil when there is no file, eg. in the REPL."

1:53 TheBusby: I guess it depends if you want it as *file* for (first *command-line-args*)

1:54 /for/or/

1:54 hiredman: well you asked if it is necessary

1:56 TheBusby: yep, thank you

1:58 any thoughs on the best way to spawn off one million http-agents efficiently?

1:59 was hoping simply using map would leverage chunked seq's to do 20-30 at a time...

2:01 hiredman: ,(doc seque)

2:01 clojurebot: "([s] [n-or-q s]); Creates a queued seq on another (presumably lazy) seq s. The queued seq will produce a concrete seq in the background, and can get up to n items ahead of the consumer. n-or-q can be an integer n buffer size, or an instance of java.util.concurrent BlockingQueue. Note that reading from a seque can block if the reader gets ahead of the producer."

2:03 TheBusby: excellent, I can't wait until I get more of these tools under my belt

2:11 rrc7cz: assuming I have a seq like ["one" "two" "three" "four" "five"], is there a fn in core or contrib for (split-at "three" coll)?

2:11 hiredman: ,(split-at (partial = "three") ["one" "two" "three" "four" "five"])

2:11 clojurebot: java.lang.ClassCastException: clojure.core$partial__5034$fn__5036 cannot be cast to java.lang.Number

2:12 hiredman: oh

2:12 right

2:12 ,(split-with (partial = "three") ["one" "two" "three" "four" "five"])

2:12 clojurebot: [() ("one" "two" "three" "four" "five")]

2:12 hiredman: ,(split-with (partial not= "three") ["one" "two" "three" "four" "five"])

2:12 clojurebot: [("one" "two") ("three" "four" "five")]

2:15 rrc7cz: thanks hiredman

4:15 triyo: I'm in the process of learning defmacro handeling in Clojure. I wrote this trivial snippet: http://gist.github.com/299036 ... All it does is check if object is in the list of give choices.

4:16 macroexpand expands the macro to: (let* [insym__2791__auto__ 1] (clojure.core/or (clojure.core/= insym__2790__auto__ 1) (clojure.core/= insym__2790__auto__ 2) (clojure.core/= insym__2790__auto__ 3)))

4:16 its obvious in the expantion whats wrong

4:17 The insym is not being picked up from the let binding.

4:18 is it because binding of insym is quoted and hence delayed for runtime. Should it be bound outside the back-quoting?

4:19 hiredman: because of the unsyntax-quote and re-syntax-quote

4:19 auto gensyms are only the same inside the same instance of syntax-quote

4:20 triyo: Ah, that explains the different auto id

4:23 hiredman: thanks for your reply. How would you structure my macro to overcome the multiple syntax quote issue and still have the gensymed binding?

4:24 if you dont mind assisting. Just trying to get my head around it. thx in advance.

4:24 hiredman: I wouldn't write a macro

4:25 ,(some #{1} [1 2 3])

4:25 clojurebot: 1

4:25 hiredman: ,(some #{4} [1 2 3])

4:25 clojurebot: nil

4:25 LauJensen: hehe

4:25 hiredman: the guy is trying to learn HOW to write Macros, not WHEN

4:26 triyo: haha very funny

4:26 Thanks LauJensen

4:27 hiredman: the least amount of change would be an manual gensym

4:28 triyo: oh and I called my macro now in? as its more of a predicate. (And I know you could probably do this few ways event without use of macros, but I'm trying to learn Clojure macros a bit)

4:28 hiredman: ,(cons 'or (for [x (range 10)] (list '= x 5)))

4:28 clojurebot: (or (= 0 5) (= 1 5) (= 2 5) (= 3 5) (= 4 5) (= 5 5) (= 6 5) (= 7 5) (= 8 5) (= 9 5))

4:28 hiredman: triyo: writing that as a macro is a bad idea

4:29 (ins? 1 (range 10)) ; will be false

4:30 triyo: hiredman: sure because it would not expand the range in the map.. I see

4:31 esj: Lau: do you have jline running in your emacs slime ?

4:31 AWizzArd: Moin

4:32 esj: AWizz: wotcha

4:32 LauJensen: hejs, no

4:32 -h

4:32 AWizzArd: Hola

4:33 esj: Lau: so what do you use for command history ?

4:34 i'm having to scroll up an down in the repl provided by (swank-clojure-project) and its become tiresome

4:34 been randomly poking at swank and slime .el files, but to no great sucess

4:34 LauJensen: C-up C-down

4:35 esj: where are those bindings defined ?

4:35 i'm on OSX, so C-arrow is globally bound to switch desktops

4:36 LauJensen: I don't have access to Emacs right now, so I'm weak and withered, I cant help you... sorry....

4:36 :)

4:36 ordnungswidrig: esj: you mean C=Command or C=Control?

4:37 triyo: hiredman: manual gensym worked. http://gist.github.com/299036 . I know what you mean by why its a bad idea. thx again

4:37 LauJensen: I think my brain has transferred all knowledge of Emacs to my fingers - I really struggle to tell you what the keys, let alone the bindings are, but ask me again tonight, or check out my .emacs on my blog

4:37 esj: Lau: no problem

4:37 thanks for your help

4:37 by fiddling i've found the meta-p and meta-n do the trick too.... emacs!

4:37 ordnugnswidrig: yeah.

4:37 C=Control

4:39 LauJensen: C-h k and C-h b are great helpers

4:41 esj: annoyingly those throw: wrong type argument: symbolp, (quote normal)

4:41 thanks, what you told me will get me going though

4:44 LauJensen: Haven't seen those

4:47 esj: OK, I found the functions in slime-repl.el

4:47 slime-repl-next-input and friends

4:48 AWizzArd: Hi fatrow

4:48 LauJensen: Maybe we should hurry up and port Emacs to Clojure

4:48 Chousuke: :P

4:55 esj: Lau: Genius !

4:59 LauJensen: I'll create 'cmacs' on Github straight away :)

4:59 or 'clabango-macs', thats _even_ more catchy

4:59 AWizzArd: I have a macro which expands into defn. I support doc-string? and attr-map? as defn does. I merge them (if they are provided) into a map 'meta-data'. How do I attach this to my defn? `(defn #^~meta-data ~name ...) won't work because the reader macro changes my form before the macro can touch it.

5:00 Chousuke: `(defn ~(with-meta name blah) ...)

5:01 ie. you just need a symbol with the appropriate metadata as the name.

5:01 esj: emacj

5:01 AWizzArd: Chousuke: oki

5:02 dsop: is there a web framework for clojure?

5:03 AWizzArd: dsop: Compojure

5:04 LauJensen: dsop: Check out my blog for some examples using compojure, http://www.bestinclass.dk/index.php/blog

5:04 * dsop detects shameless self promotion :). I'll check it out

5:04 AWizzArd: *g*

5:04 LauJensen: Just trying to help out

5:05 dsop: LauJensen: just a joke. thanks, I'll already browsing it :)

5:22 gstratton: I'd be really grateful if someone could explain what's happening here to me: http://paste.lisp.org/display/94620

5:24 triyo: is there a case form in Clojure like in CL?

5:24 hiredman: ' is quote, not syntax quote

5:25 gstratton: hiredman: But why does my function behave differently from + when passed as an argument?

5:26 hiredman: what version of clojure?

5:27 gstratton: 1.1

5:27 LauJensen: ~source +

5:27 triyo: You're looking for cond, condp, cond*

5:27 simplechat: heyyas

5:27 AWizzArd: triyo: did you try case?

5:27 simplechat: is there any sane install method?

5:27 that doesn't involve pulling from git/etc?

5:28 triyo: AWizzArd: no case form....however found clojure.contrib.fcase

5:28 has case function

5:28 case macro I mean in clojure.contrib.fcase

5:28 AWizzArd: triyo: then you have an older version of Clojure.

5:28 LauJensen: simplechat: http://www.bestinclass.dk/index.php/2009/12/clojure-101-getting-clojure-slime-installed/

5:28 triyo: 1.1

5:28 AWizzArd: If you wish you can download a freshly compiled dev version here: http://build.clojure.org/

5:29 *clojure-version* ==> {:interim true, :major 1, :minor 2, :incremental 0, :qualifier "master"}

5:29 ,*clojure-version*

5:29 clojurebot: {:interim true, :major 1, :minor 1, :incremental 0, :qualifier "master"}

5:29 hiredman: gstratton: if you look at the definition of + you see it defines an inlinable version of the function, which is what I think causes the difference

5:29 triyo: hehe thats ver I'm running like clojurebot

5:30 I can switch latest

5:30 gstratton: hiredman: Right, thanks very much. I've spent hours trying to figure that out!

5:30 AWizzArd: triyo: I am always working with the newest development version. This may be 'dangerous', as it might break something. Anyway, you always get the newest features that way :)

5:30 triyo: and also you can support development this way, by filing bug reports.

5:31 JayM: there are 666 people watching clojure on github

5:31 simplechat: lol

5:31 triyo: I'm experiment a lot at the mo in the Clojure space, so wouldn't hurt me to switch to master from sourcse

5:31 simplechat: is it considered better to use the git versions of clojure?

5:31 krumholt_: gstratton, i don't have the problem you described with clojure "1.2.0-master-SNAPSHOT"

5:31 simplechat: or are those unstable?

5:31 * JayM goes back to idling

5:32 AWizzArd: simplechat: you will find a freshly compiled git checkout here: http://build.clojure.org/

5:32 simplechat: is that what i want tho?

5:32 AWizzArd: you can compile it yourself, you will need Maven tho and thus download 88% of the internet for compilation ^^

5:32 simplechat: i think you want that

5:32 simplechat: AWizzArd, atm i have the ubuntu package clojure

5:32 but i'm unsure if i want to stick with that or grab a newer version

5:33 or if the newer versions are unstable/etc?

5:33 AWizzArd: I suggest you to just get the newest thing

5:33 Chousuke: simplechat: isn't the ubuntu package 1.0? That's relatively ancient already :P

5:33 AWizzArd: They are more unstable, in theory. In practice however they are not really breaking code regularily.

5:33 simplechat: so i grab clojure.jar

5:33 AWizzArd: ja

5:33 simplechat: this might be very stupid, but where do i put it?

5:33 AWizzArd: Oh, Ubuntu placed your current clojure.jar somewhere...

5:34 simplechat: yeah

5:34 just overwrite it?

5:34 AWizzArd: simplechat: do you use emacs? Enclojure? VimClojure?

5:34 Chousuke: simplechat: in the classpath. which is specified when you start the JVM

5:34 simplechat: so the location does not really matter

5:34 simplechat: AWizzArd, i'm aiming to just use vim/etc

5:34 Chousuke, but i already have one version

5:34 Chousuke: simplechat: ~/.java/ or something might be okay

5:34 simplechat: in /usr/share/java/clojure.jar

5:35 Chousuke: simplechat: you can have many. don't overwrite anything the package manager has installed.

5:35 AWizzArd: If you know Vim well then try VimClojure, and place the downloaded clojure.jar where Chousuke suggested. And edit your VimClojure config file so that it points there.

5:35 simplechat: ok

5:35 AWizzArd: (Maybe you even want to use Synaptics and uninstall Clojure from Ubuntu)

5:35 simplechat: so i then need to vimclojure?

5:35 AWizzArd: Not need. But as a Vim user this is suggested.

5:35 It will help you.

5:35 simplechat: mmmm

5:36 yeah, i wouldn't want ubuntu changing the packages out from under me

5:36 gstratton: krumholt_: Hmm, me neither. Is using the 1.2 branch recommended at the moment? I assumed 1.1 was least likely to have unexpected problems

5:36 simplechat: how would i test clojure-contrib is working?

5:36 krumholt_: gstratton, i don't know i use 1.2 and it seems very stable

5:39 simplechat: should base64 be a defined symbol?

5:40 yeah

5:40 ok

5:40 i really don't get this, lol

5:43 scottj: What do you guys prefer, a config file or environment variables for telling a webapp whether it's in production or development mode?

5:44 yuuki: Is emacs the most popular editor for clojure?

5:44 scottj: yuuki: yeah, but quite a few ppl use java ide's or vim

5:44 simplechat: but yeah, how would i test that clojure-contrib is working?

5:44 scottj, eclipse?

5:45 yuuki: java ide, meaning jedit?

5:45 tomoj: I think someone said earlier that there was a poll and about half used emacs, the other half anything else

5:45 scottj: java ide meaning netbeans, intellij, eclipse, probably in that order of popularity

5:45 tomoj: some vim as well

5:45 oh you said that

5:47 yuuki: I'm starting to like vim for programming. I think it will help to learn to manipulate windows and buffers better

5:47 scottj: simplechat: start a repl w/ contrib on the classpath and then (use 'clojure.contrib.somenamespace) and run a function in it?

5:47 underdev: i'm using emacs, and am very impressed, but the netbeans plugin is very impressive

5:48 as well

5:48 it will code complete on the java as well as the clojure

5:50 ive used vim for about 10 years, so emacs is a big adjustment

5:50 scottj: underdev: using vipermode?

5:50 yuuki: is there a big cost to mutating references?

5:50 underdev: but too many times its been vital that i could connect to my editor remotely

5:50 like TOO MANY TIMES

5:50 neotyk: I switched for clojure from Vim to emacs as well

5:50 yuuki: vim doesn't support that?

5:51 underdev: no, it totally does

5:51 so does emacs

5:51 but emacs is so lisp-centric

5:51 neotyk: It's just better supported by emacs

5:52 yuuki: key chords make me sad

5:52 as a dvorak typist

5:52 underdev: scottj: no, i'm really taking the plunge

5:52 neotyk: and it's so nice to get away from java ide for a while

5:52 triyo: AWizzArd: do you run 1.2.0-master-snapshot with swank? Swank-clojure-project doesnt fire up a repl if running 1.2.0. If I switch back to Clojure 1.1.0, all works fine. Is there a later Swank version that works?

5:52 underdev: yeah, viper mode is always an option

5:53 and if i had to guess, i'll probably end up using it

5:53 but i figured i'ld give emacs qua emacs a shot

5:53 but, you know, yesterday i was editing my .emacs with vim

5:53 yuuki: my vi keys are scattered all about, because I'm doing them in dvorak, but I've gotten used to them

5:54 underdev: yuuki, you are a total fucking geek :)

5:54 yuuki: haha

5:55 if I was a total geek I would've configured my vi keys to be more sane

5:55 ordnungswidrig: yuuki: you totally missing the point with emacs :-)

5:55 arg

5:55 s/emacs/vi/

5:55 yuuki: haha

5:55 AWizzArd: triyo: I run indeed 1.2.0 in swank. But: I use an old version of SLIME.

5:55 yuuki: yes, my navigation keys are c, v, j and p, so it takes two hands to move around

5:56 Several weeks of nethack cemented my navigation skills :p

5:56 ordnungswidrig: I added (test-ns *ns*) to my source file and now the tests are run when I compile/load with SLIME. I like that.

5:56 However it reports NO_SOURCE_FILE:1 for every error :-(

5:56 AWizzArd: triyo: you can see however if this helps you: http://github.com/technomancy/swank-clojure

5:56 underdev: yuuki: thats awesome

5:56 yuuki: haha

5:56 underdev: yuuki: you fucking geek

5:57 yuuki: i want to follow you on twitter

5:57 yuuki: haha

5:57 I don't really have a twitter account

5:57 underdev: rats, oh well

5:57 yuuki: haha

5:58 Some day!

5:58 underdev: lemme know

5:58 yuuki: I am thinking about using clojure to port a language to the JVM

5:58 underdev: tcl? tell me its tcl,

5:58 ordnungswidrig: I imagine using vi with dvorak is like typing on a rot13 keyboard.

5:59 underdev: LOL

5:59 yuuki: The language has mutable data structures, and I'm wondering if that makes clojure a bad choice for implementation

5:59 ordnungswidrig: apl

5:59 ?

5:59 yuuki: factor :p

5:59 ordnungswidrig: *duck*

5:59 yuuki: not so bad

5:59 yuuki: I would basically have to use references, for each mutable object, right?

5:59 triyo: AWizzArd: strange, I'm not seing anything obvious in log. Settings look fine. I have a leiningen generated project layout that suite swank-clojure-project. And I'm running ordnungswidrig slime/slime-repl 20091016

6:01 ordnungswidrig: triyo: um, you're running me?

6:01 triyo: lol, sorry ordnungswidrig

6:01 that might be the cause of my problem

6:02 ordnungswidrig: hehe. I just checked but I did not for slime on github :-)

6:03 AWizzArd: I always used jochus swank-clojure. But one day he stopped updating his repo.

6:03 A bit later slime changed something. I think they used symbol names that are not valid in Clojure or something like that.

6:04 triyo: technomancy seems to have taken over...thats the one I've been using

6:04 AWizzArd: And now some elpa stuff is needed, and technomancy made updates, etc.

6:04 yuuki: I'm thinking the best way to go is to immutable-ize the language

6:05 LauJensen: hiredman: Are you writing the scripts for CSI ? I just heard their discussion about finding some criminal where one of them says "I'll create a GUI using Visual Basic to track the IP address", lol :)

6:05 underdev: lolololol

6:05 yeah, do that

6:06 hiredman: LauJensen: huh?

6:06 LauJensen: http://www.youtube.com/watch?v=hkDD03yeLnU

6:06 Just sounded like something you would say :)

6:07 hiredman: 2009:Apr:09:12:30:42 hiredman : I still hate writing guis, and avoid it

6:08 LauJensen: oooh thats right, you said that back in April - I just forgot

6:09 hiredman: I just don't see how anything I've said here would lead you to belive I would say anything like that

6:09 triyo: AWizzArd: I got it to work. it was actually slightly incompatible swank-clojure version. (Was a snapshot 1.1 ver, so I switch to 1.1.0 final) + contrib 1.2.0)

6:10 LauJensen: hiredman: Just yanking your chain - Have you dissoc'ed your sense of humor?

6:12 AWizzArd: triyo: what swank-clojure do you use? technomancy's stuff? Do you also use ELPA? What version of SLIME?

6:13 triyo: slime 20091016 - swank-clojure -> lein project: :dev-dependencies [[swank-clojure "1.1.0"]]

6:14 works fine now

6:14 ordnungswidrig: clojure-test-mode is acutally nice

6:14 triyo: I had the older snapshot of swank-clojure when it didnt work with clojure 1.2.0

6:15 neotyk: anyone here planing to join tomorrows AMS.clj meetup?

6:16 underdev: what's ams?

6:16 neotyk: amsterdam

6:16 http://bit.ly/agptrb

6:16 tomoj: wish I could

6:18 LauJensen: This is fun - I was just looking at todays referrers on my blog, and this IP pops up, running from port 8080, so I follow the link and its someone running the Reddit Clone :D

6:20 neotyk: very nice Lau, best source of clojure lessons on the market lately

6:20 LauJensen: What is your machine I connected to ? :)

6:21 underdev: Yeah Lau, i guess i have you to blame for getting interested in clojure

6:22 LauJensen: Really? Man thats great to hear!

6:22 neotyk: you do very good publicity for Clojure, I like it a lot :)

6:23 triyo: LauJensen: you started a reddit clone war few days ago. Congrats.

6:23 LauJensen: Great - Thanks guys :) I must say it's been a lot of fun starting a blog - also a good way to remember things

6:23 triyo: Yea I noticed - I loved the QBasic version - I'm thinking of further extending the example, with user registration, search and whatever I can think of

6:24 neotyk: natural would be to give it some clojureql love :P

6:25 AWizzArd: triyo: yeah, I use slime from 26. October

6:25 LauJensen: I know - But you have to be a little patient as we're rolling Frontend 2.0 - Its going to be great, but there's a lot of working involved - hopefully after a couple of weeks it'll be ready

6:26 neotyk: no wories

6:26 triyo: LauJensen: I think it'd be a good idea to show off how clojure can handle some of the tougher parts of the system. For istance, reddit has some fancy ways of handeling the newly generated link identifiers, etc.

6:26 neotyk: till that time i might be ready with really async http client

6:26 one that doesn't user thread per request approach

6:28 triyo: LauJensen: reddit guys would be jealous as they loved CL but decided to switch to python when they had some deployment prod issues

6:29 LauJensen: triyo: You accidentally said that they used CL twice, but I forgive you :)

6:29 What exactly to you mean by new link identifiers ?

6:31 ordnungswidrig: ,{0}

6:31 clojurebot: java.lang.ArrayIndexOutOfBoundsException: 1

6:31 triyo: They don't reference URL submissions by autogen ID of any sort, they create some other form of unique identifiers. I remember looking at the source about 2 years ago. You see them in the urls http://www.reddit.com/r/blog/comments/azkrk/you_requested_him_and_we_got_him_ask_noam_chomsky/ the "azkrk" part

6:32 ordnungswidrig: Is there a ticket for this? Or for this kind of misleading error message?

6:32 triyo: The code behind that looked pretty cool

6:32 LauJensen: triyo: that ID is looks very trivial - You'll notice from the scraper that did for the Hadoop job, that those random characters are repeated for every 20 posts

6:34 similar to (for [page pages id (range (count posts-on-page))]) - but instead of ints they use something random

6:34 ordnungswidrig: isn't it a autogen id in base35 encoding?

6:37 triyo: Hmm, ok you might be right, I remember looking at the source and some parts were very impressive... The good thing is that reddit is open sourced so you can see some interesting parts and how they wen about implementing them and perhaps find better ways to approach those parts. Your first tutorial is cool but that is the really trivial part in many languages today. You need Part two, where the real gems lie :)

6:38 LauJensen: Or a small series perhaps - You can make this stuff as big as you like :)

6:39 Generally the feedback I get, is that the Compojure docs are leaving people wanting, so I might as well try to fill the gap

6:40 triyo: I agree on the last point

6:42 LauJensen: Have you ever had a look at Django project docs? In my opinion, best I have seen in years. (Constantly updated and in informative in great depth. Their commits require full working support docs)

6:42 Would be amazing to see something like that in Clojure space.

6:43 LauJensen: No I haven't, but it sounds interesting

6:43 tomoj: seems like there isn't much to document about new compojure

6:43 only one source file (!)

6:43 + clout I guess

6:43 then you need ring docs too, maybe?

6:43 LauJensen: http://compojure.org/docs

6:44 tomoj, you don't need to know ring to know compojure

6:44 triyo: LauJensen:here is the example: http://docs.djangoproject.com/en/1.1/ (note the 1.1 in the url. All previous and beta versions can also be referenced)

6:45 LauJensen: Wow

6:45 I wonder where they find the time

6:45 triyo: LauJensen: the forst part is amazing, well tested, tutorials

6:45 then rest is very detailed docs for all parts of the framework

6:46 tomoj: LauJensen: well, what's there to know about compojure, then?

6:46 not much?

6:47 I just mean that django docs may be great, but I don't think we have enough to write about :)

6:48 LauJensen: hehe, I get your point

6:48 tomoj: I hope that someday there will be lots of separate projects which can easily be plugged in

6:48 for authentication, file uploads, etc

6:49 powr-toc: Is there an existing predicate equivalent to (complement nil?)

6:49 tomoj: most of that kind of stuff can just be plugged in by decorating with middleware, I'd bet

6:49 LauJensen: There was an attempt at porting Django at one point by danlarking, don't know what happend to it

6:50 triyo: tomoj: thats the thing. Getting people to build "plugins". Compojure has no pluggable well defined concept of what these plugins are. I know middleware is the answer, but I think there needs to be some more abstract way to register these plugins "components"

6:50 tomoj: I guess a lot of the rails plugins are model-layer stuff

6:51 which is not compojure's concern

6:51 raph_amiard: test

6:53 tomoj: personally I kind of like the idea of just requiring the with-* function and decorating

6:54 I think one of the goals of compojure's design was not to be opinionated like rails

6:54 we can't make any assumptions and so can only provide functions which people can use

6:55 triyo: tomoj: sure but I think there is a need to encourage people in developing on top of compojure. And I think thats the key.

6:55 tomoj: ah, yeah

6:56 what are some of the important things we're missing

6:56 so far I've missed authlogic and paperclip from the rails world

6:57 powr-toc: Is that a predicate that tests for truthiness?

6:57 tomoj: no, it tests for nil-ness

6:57 LauJensen: hehe

6:57 truthiness? :)

6:58 tomoj: er, non-nil-ness

6:58 there is no need for a predicate that tests for truthiness

6:58 LauJensen: (contains? truthiness? "clojure is cool" )

6:58 true

6:58 tomoj: by definition

6:59 underdev: truthy and falsy are now official words- too useful to not be considered proper english

6:59 LauJensen: truthy

6:59 powr-toc: I want to filter nils... At the moment I have (filter (complement nil?) [nil 1 2 3 nil]) is that idiomatic?

6:59 tomoj: (remove nil? ..)

6:59 powr-toc: ahh cool

7:00 tomoj: false will remain

7:00 LauJensen: ,(filter identity [1 2 nil 3])

7:00 clojurebot: (1 2 3)

7:00 tomoj: filter identity gets rid of false as well

7:00 powr-toc: sweet

7:01 which of those options is more idiomatic?

7:01 underdev: language is descriptive, not prescriptive, and anyone who say different ain't right!

7:01 LauJensen: depends on what you want

7:02 if its just nils you want removed, (remove nil?) makes the most sense

7:02 tomoj: I like (remove nil? ..) when you don't care about false, because it is so readable

7:02 powr-toc: yeah makes sense

7:03 tomoj: are there functions for conjunction/disjunction of predicates?

7:03 powr-toc: in this case (remove nil? ..) conveys intent better... but I quite like (filter identity ...)

7:03 tomoj: I always forget

7:04 like (remove (disjunct nil? odd?) ..) to get rid of nils and odds

7:05 LauJensen: (remove #(or (nil? %) (odd? %)) )

7:05 :)

7:05 tomoj: eek points

7:05 I think I saw that there will be a section in the new book about point-free clojure

7:05 :)

7:07 LauJensen: Meikel already blogged about it :)

7:07 If you want point-free, use Haskell or better yet, J

7:07 http://kotka.de/blog/2009/12/Pointfree_vs_Pointless.html

7:08 tomoj: but those aren't lisps :(

7:09 I agree though, clojure isn't quite right for it

7:09 LauJensen: tomoj - I'm really hammered on time these days, but I would so so so looove to plug the J.dll into Clojure - Would be incredible

7:10 (defn average [coll] (j "# % +/"))

7:10 tomoj: that looks... odd

7:11 LauJensen: oops, I meant "+/ % #" ofc

7:11 AWizzArd: rhickey: is there an easy way to overwrite the public :arglists metadata for a defmacro or defn? I have a function and want its arglist to look like that of your defn, but internally (like your defn) have a different arglist.

7:11 LauJensen: +/ = sum, % = divide, # = count

7:12 AWizzArd: I could do it as you did in core.clj, but that means to repeat most of the defn code, and it feels very lowlevel.

7:13 rhickey: AWizzArd: you could alter-meta! on the var

7:14 AWizzArd: ok, good idea, thanks

7:16 tomoj: full disclojure might be the clojurecasts I was looking for

7:18 underdev: tomoj: yeah, they're great

7:32 AWizzArd: rhickey: btw, the alter-meta! doc string could mention symbols and fns too.

7:32 rhickey: AWizzArd: no, it can't, since they don't have alterable metadata

7:33 reference types have alterable metadata, value types have value semantics for metadata (i.e. with-meta)

7:37 triyo: I am translating an example form OnLisp book into clojure (or at least trying to). CL has a case for like this http://gist.github.com/299163 I see the clojure 1.2.0 has a case form too, how does it work? Doesnt seem to be the same as CL ver.

7:38 cemerick: triyo: my CL is really rusty, but you're probably looking for condp

7:39 tomoj: case would work here, wouldn't it?

7:40 since we're looking for literal symbols

7:40 Chousuke: (doc case)

7:40 clojurebot: "clojure.contrib.fcase/case;[[test-value & clauses]]; Like cond, but test-value is compared against the value of each test expression with =. If they are equal, executes the \"body\" expression. Optional last expression is executed if none of the test expressions match."

7:41 Chousuke: hm. not the right one :P

7:41 triyo: clojurebod runnign 1.1.0

7:41 case only checked in 1.2.0

7:41 I checked ealrier

7:41 cemerick: I've not used case yet, but I didn't think it matched on symbols.

7:42 I feel like I'm overusing bound vars lately -- e.g. offering 6 vars to be bound for a 10-fn API, instead of having each fn take a map arg or something.

7:42 triyo: cemerick: I tried now and it doesnt match on symbols, unless i'm doing it wrong

7:42 tomoj: matches on any literals, no?

7:42 http://github.com/richhickey/clojure/blob/master/src/clj/clojure/core.clj#L4609

7:42 warning, big file

7:43 cemerick: tomoj: sure seems like it *shrug*

7:43 Chousuke: looks like it does.

7:43 * cemerick looks forward to jumping to HEAD later this month.

7:45 tomoj: (case 'and (and 3)) gives 3

7:45 Chousuke: in CL?

7:45 tomoj: no, clojure

7:45 though, strange

7:45 (case 'or (and 3) (or 4)) gives an error

7:46 while (case 'and (and 3) (or 4)) returns 3

7:46 Chousuke: you have too many parentheses

7:46 tomoj: oh, I see

7:46 (case 'or and 3 or 4)

7:46 so, triyo, I think you just need to get rid of some parens

7:47 yuuki: should clojure-contrib be in the clojure directory?

7:47 ordnungswidrig: re

7:47 tomoj: and then instead of "t default-value" at the end, just "default-value"

7:47 Chousuke: yuuki: doesn't matter.

7:47 tomoj: e.g. (case 'foo and 3 or 4 5) gives 5

7:47 triyo: hehe, thank worked. I kept trying with the parans

7:48 rhickey: ,(case 'b 'a 1 'b 2 'c 3)

7:48 clojurebot: java.lang.Exception: Unable to resolve symbol: case in this context

7:48 tomoj: I guess in general clojure tries to get rid of them when they're unnecessary

7:48 clojurebot doesn't have it yet :(

7:48 rhickey: case should work with ant values with stable hashcodes

7:48 any

7:49 cemerick: tomoj: same with cond, etc. Each case is likely to be on its own line anyway, so no need for the noise.

7:49 tomoj: yeah

7:49 triyo: rhickey: how do I specify the "default" case if none is met?

7:49 tomoj: e.g. (case 'foo and 3 or 4 5) gives 5

7:50 rhickey: triyo: "A single default expression can follow the clauses"

7:51 AWizzArd: rhickey: I could update the :arglists metadata for foo, my (defmacro foo ...). Is that a reference type?

7:51 triyo: I see, thanks.

7:51 AWizzArd: rhickey: nevermind.. "var".. ok

7:52 Chousuke: AWizzArd: I don't know what you even asked :P

7:52 triyo: A lot less parens than CL ver of case

7:52 Chousuke: triyo: you can do away with many parens through implicit grouping

7:53 triyo: Chousuke: what is implicit grouping?

7:53 Chousuke: eg. (let [a b, c d, e f] ...)

7:54 rather than (let ((a b) (c d) (e f)) ...)

7:54 triyo: Oh sure, I see what you mean

7:54 AWizzArd: Chousuke: it was some minutes earlier, about alter-meta!. I thought its docstring could need an update, but it doesn't. It already mentions vars, and a var's meta-data I updated. So, all fine :)

7:55 Chousuke: It does mean that you need to use do if you want multiple expressions evaluated on a condition, but that's pretty rare.

7:59 yuuki: maven is complaining about the maven-resources-plugin

8:02 tomoj: I wonder if applying constraints to functions like middleware would be a good idea

8:05 AWizzArd: tomoj: in Compojure?

8:12 tomoj: AWizzArd: I meant, copy compojure's middleware decoration idea

8:12 but use it for applying constraints

8:13 so (defn some-fun []) (add-constraint some-fun some-constraint)

8:13 something like that

8:13 except need a better way to do it so that you can apply specific preds to specific args, maybe

8:14 LauJensen: tomoj: You mean a more flexible post/pre args thing ?

8:14 tomoj: yeah, basically

8:14 I just watched the full disclojure about constraints and he mentioned the idea of separating the constraints from the functions that use them so that the constraints can be reused

8:15 but I think I like the idea of applying them using something compojure.control.decorate style

8:15 LauJensen: Can't recall ever having the need

8:15 tomoj: yeah, heh, I've never used constraints at all

8:15 yuuki: does clojure-contrib contain its own version of clojure.jar?

8:15 tomoj: maybe I should try to use the feature before I start dreaming up abstractions around it

8:16 AWizzArd: tomoj: you can always add constraints after you defined a function. Functional programming allows you to decorate fns with other fns (such as constraints).

8:16 tomoj: that sounds great if :pre/:post is just a shortcut for that

8:16 and whatever it uses behind the scenes is reusable

8:18 cemerick: yuuki: no, they need to be obtained separately

8:18 yuuki: Hmm

8:18 I did mvn package and it builded successfully without reference to clojure.jar

8:19 cemerick: that's because maven retrieves contrib's dependendies automatically

8:19 I thought you were referring to the downloadable jars.

8:19 yuuki: Ah I see...

8:20 So when I did maven package, clojure itself was downloaded and built into clojure-contrib.jar?

8:20 cemerick: No, clojure is not built into clojure contrib.

8:21 They are both going to be needed by any apps you use them with downstream.

8:21 yuuki: I guess I don't understand how contrib compiled and was tested without clojure itself

8:22 hmm...

8:22 cemerick: maven downloads the version of clojure that is required by the version of contrib you have the source for

8:22 rhickey: yuuki: maven grabbed a release of clojure for you

8:22 yuuki: Ah, I see... thanks!

8:23 tomoj: I hope a full disclojure about datatypes/protocols is on the way

8:23 triyo: How do I check what the first character of a given symbol is?

8:24 tomoj: symbols are named

8:24 ,(name 'foo)

8:24 clojurebot: "foo"

8:24 cemerick: an uberjar profile should probably be added to contrib's pom

8:24 tomoj: ,(first (name 'foo))

8:24 clojurebot: \f

8:25 chouser: cemerick: that would be cool. a single jar with clojure and contrib, all ready to go...

8:25 triyo: tomoj: nice and easy, thx

8:26 cemerick: chouser: super-trivial to do. I'd do it right now, but I'm nowhere near contrib's head.

8:28 chouser: you can badger SS about it when he gets in :-) Point at http://maven.apache.org/plugins/maven-shade-plugin/

8:28 chouser: "shade"?

8:29 cemerick: hey, I didn't name it :-/

8:29 There's no collisions, so it should be as simple as adding a profile with the shade plugin bound to the package phase.

8:45 ordnungswidrig: hmm, clojure-test-mode higlighting collides with my rainbow parens. any ideas?

8:46 toggling rainbow-parens after running the test fixes this. Can I hook this in somehow?

8:46 rhickey: has autodoc fallen behind on contrib?

8:46 I tried grabbing the latest docs from github, but are from Jan 14

8:47 chouser: I'm not sure the docs were ever being auto-updated.

8:47 rhickey: ah

8:47 AWizzArd: rhickey: is there something like swap! for with-local-vars? I found only var-set so far.

8:49 rhickey: chouser: I got the impression they were from http://groups.google.com/group/clojure-dev/msg/836e9381f87a6515

8:49 AWizzArd: (var-set myvar (inc @myvar)) vs. (var-update inc)

8:49 cemerick: AWizzArd: swap! has semantics specific to atoms.

8:49 AWizzArd: yes

8:50 rhickey: AWizzArd: there can't be any contention for a settable var

8:50 thread-local

8:50 AWizzArd: yes, I know

8:50 just like c++;

8:50 rhickey: so, var-set is it

8:50 AWizzArd: vs c = c+1

8:50 rhickey: not like c++

8:50 AWizzArd: syntactic sugar

8:51 rhickey: bleh - why are you using local-vars?

8:51 should be ugly and painful

8:51 AWizzArd: They are used as in-transaction value to update a DB.

8:51 rhickey: yikes

8:51 AWizzArd: The DB itself is in an atom. So I can not use swap! or reset! during the transaction, because readers outside the transaction could see that.

8:52 LauJensen: clojurebot: code-review is <rhickey> yikes

8:52 clojurebot: Ok.

8:52 LauJensen: :)

8:52 AWizzArd: rhickey: this is what chouser and I came up with as currently best solution.

8:52 rhickey: AWizzArd: ok - leave me out of it :)

8:52 cemerick: This sounds like those scary CLOS-based orthogonal persistence thingamabobs.

8:52 AWizzArd: rhickey: well, you could offer a "plugin" to dosync.

8:53 rhickey: AWizzArd: not trivially

8:53 AWizzArd: A mechanism that would allow me to do io when the transaction has in principle completed, but is not visible right now.

8:53 rhickey: also, bleh, very fragile

8:53 AWizzArd: So multiple dosyncs won't repeat the io (writing the transaction log to disk) and block each other out.

8:53 rhickey: this is why they invented transaction cooridinators

8:53 LauJensen: AWizzArd: You seem to have totally forsaken functional programming

8:53 AWizzArd: And the io part could still prevent the transaction from going live if the write to disk fails.

8:54 LauJensen: nope, but there currently is no obvious mechanism for that purpose in Clojure.

8:55 LauJensen: Is the code public somewhere?

8:55 AWizzArd: not yet, but in some weeks

8:55 LauJensen: when you have a dosync and want to write data to the disk just before the dosync ends.

8:56 If 5 threads are running this dosync, then they can block each other, because writing to disk is so slow.

8:56 LauJensen: AWizzArd: Isn't it the case, that futures spawned within transactions only launch if the transaction is successful ?

8:56 cemerick: AWizzArd: IO within a transaction is a sure path to disaster. This is why io! exists.

8:56 AWizzArd: And if I need a lock around dosync anyway to prevent that I can use the faster atoms, as chouser suggested.

8:56 tomoj: ordnungswidrig: after advice on whatever function from clojure-test-mode you're using?

8:57 LauJensen: AWizzArd: I remember doing some trick with threads once, when I wanted to log something from the transaction

8:57 AWizzArd: cemerick: but io within the transaction is a requirement

8:57 cemerick: AWizzArd: transactions can, by definition, be repeated. You've got it backwards.

8:58 AWizzArd: nope :)

8:58 rhickey: http://java.sun.com/javaee/technologies/jta/index.jsp

8:58 cemerick: There may be *some* STM system that can support semantics like that, but clojure's cannot as-is.

8:58 AWizzArd: cemerick: I am talking about my db transactions here.

8:58 tomoj: is it just a lot of work to add on? or is it fundamentally wrong for clojure's stm?

8:58 AWizzArd: Inside such a db transaction, before it completes, a log entry must be written to disk. Otherwise the consistency is in danger.

8:59 cemerick: tomoj: There's nothing wrong with it, it's just not a database-in-a-box.

8:59 AWizzArd: rhickey: I will have a look at this.

9:00 rhickey: cemerick: it is a database in a box. It's not 2 databases in a box :)

9:00 cemerick: rhickey: ah, sure. I guess I should have said it's not a durable database-in-a-box. :-)

9:00 rhickey: right

9:00 AWizzArd: And I want to make it durable.

9:00 So, that is why I need the io.

9:01 rhickey: AWizzArd: no, you want 2 databases in sync

9:01 LauJensen: rhickey: isn't it true that either agents or futures are only dispatched once from transactions?

9:01 rhickey: LauJensen: agent sends are held until commit, yes

9:01 AWizzArd: rhickey: well, you can say that what I have in RAM is one, and the other is what I have on disk.

9:01 LauJensen: Great - Then AWizzArd should be able to leverage that

9:01 AWizzArd: In that case I have two dbs.

9:02 rhickey: LauJensen: no, because the agent action can fail, in which case he wants to roll back the STM work

9:02 AWizzArd: LauJensen: I first wanted to use agents. But they can.. yeah, what rhickey said.

9:02 LauJensen: ah

9:02 AWizzArd: I discussed this with chouser some days ago.

9:03 rhickey: AWizzArd: these are old problems, that's why there is two-phase commit etc

9:03 any homemade solution is going to have problems

9:03 AWizzArd: While this JTA stuff looks interesting, it seems to be very heavy compared to my homemade solution.

9:03 rhickey: until you reinvent two-phase commit

9:04 LauJensen: rhickey: two-phase commit ?

9:04 AWizzArd: http://en.wikipedia.org/wiki/Two-phase_commit_protocol

9:04 rhickey: AWizzArd: but once Clojure's STM is JTA enabled, it will sync with just about anything Java

9:04 dbs, message queues etc

9:04 AWizzArd: well, as soon this is true I will happily use Clojures STM for that purpose.

9:04 cemerick: hah, I didn't realize that was on the drawing board.

9:04 tomoj: oh, great, so this is on the way?

9:04 rhickey: not on the drawing board

9:05 tomoj: well, at least it's feasible? :)

9:05 AWizzArd: rhickey: I just need a solution that works now. And what I have is very lightweight and I am under the impression that it will work perfectly fine.

9:05 rhickey: because I'm not sure you can truly participate in distributed transactions without a pre-commit log of some sort

9:05 AWizzArd: So, it's no problem to use var-set, I can add syntactic sugar myself.

9:06 rhickey: I'm happy to have others look into this. If possible to satisfy the semantics from an ephemeral participant like an STM, it would be great

9:06 AWizzArd: do you mean by distributed transactions those that occur over different JVM processes?

9:07 rhickey: AWizzArd: that doesn't matter - distributed just means >1 participant

9:07 AWizzArd: As in RAM and HD?

9:07 rhickey: need to succeed or fail together

9:07 AWizzArd: right

9:08 rhickey: a transaction involving more than one transactional participant needs to be coordinated

9:08 AWizzArd: Well, my plan currently is to first do the in-memory stuff. If no constraints or exception occur then I write to disk.

9:08 rhickey: AWizzArd: good luck

9:08 AWizzArd: Thanks, but it seems I pretty much solved this.

9:09 And it was pretty simple, given that Clojure has these amazing fully persistent data structures.

9:09 They do the hardest part.

9:10 tomoj: but.. don't you lose isolation?

9:10 AWizzArd: no

9:10 the in-transaction modifications are done to a snapshot of the atom, hosted in a with-local-vars

9:10 tomoj: oh

9:10 AWizzArd: the snapshot can be modified in any way, and nobody will see that

9:11 Because everything in Clojure is fully persistent *thumbs up*

9:11 tomoj: so, what's the downside?

9:11 no downside? :O

9:11 AWizzArd: The downside is that I as the implementor of the DB need to use locks and w-l-v.

9:11 Not as beautiful as using Clojures STM.

9:11 tomoj: ah

9:13 AWizzArd: Each insert/update/delte only modifies the w-l-v. And if that does not fail for any reason, then the w-l-v already contains the perfectly updated DB in RAM. Now only the changes get written to disk. And if that also not fails the atom will get its new value and everybody can then see it.

9:13 tomoj: I would love to see something like cassandra or hbase in clojure someday

9:14 cemerick: tomoj: you mean implemented in clojure?

9:14 tomoj: so you must ensure by locking that only one person can do this w-l-v stuff at a time, I guess

9:14 cemerick: yeah

9:14 starting work on thrift for clojure so that I can play with them from clojure now

9:15 cemerick: plenty of people are using both of those from clojure

9:15 AWizzArd: tomoj: yes. Without detailed knowledge it is always only possible that one thread can update a collection.

9:15 tomoj: maybe clojure wouldn't be a good fit, I dunno. I just know if it could exist, it'd be much more pleasant than java crap

9:15 cemerick: sure, wrapping over java stuff I guess for now?

9:16 cemerick: tomoj: perhaps...though I don't see how that's bad.

9:16 tomoj: I'd rather not have to deal with java thrift in clojure :/

9:16 maybe there is an easier way bypassing thrift

9:17 * cemerick gets tired of the drumbeat to reimplement the world in clojure :-(

9:17 AWizzArd: Clojures stm is doing it in a similar way. If only one threads runs a dosync it will always win and do its isolated changes. If many threads are running a dosync then also only one can win, and the others must repeat. The result will be equivalent with my locks, only that no retries can occur.

9:18 Sometimes it would be okay to concurently modify a collection, without locks and retries. But you can do this only when you understand what you are doing there.

9:18 tomoj: to me it's object-functional impedance

9:18 (mismatched)

9:19 cemerick: tomoj: if that's the case, that's what a good wrapper will fix. But there's zero value in reimplementing heavily-tested and widely-used impls of nontrivial functionality.

9:19 tomoj: sure, I don't want to rewrite cassandra

9:19 rhickey: AWizzArd: "then also only one can win" above is not true

9:19 tomoj: if someone else did, I'd just be happy :)

9:20 rhickey: AWizzArd: non-overlapping transactions can both succeed without retry

9:20 otherwise STM would devolve into a single global lock

9:21 AWizzArd: Yes, if they don't overlap it is fine.

9:21 rhickey: AWizzArd: but not true of yours, is it?

9:21 AWizzArd: indirectly it is also true for mine

9:21 Because each thread would work on its own clone of the db

9:22 And thus will be the only user updating it.

9:22 rhickey: which get merged how?

9:22 chouser: AWizzArd: I thought you were using one lock per db

9:22 AWizzArd: Only later, when he merges databases it will be a global lock.

9:22 chouser: yes

9:23 The merge is done with snapshots too, and after those are merged we see if the original db is still the same version. If yes it can get swaped.

9:24 chouser: and if not?

9:24 rhickey: it is serialized

9:24 the STM is a parallel world view

9:24 AWizzArd: yes

9:24 chouser: if the original db was changed then you can retry the merge.

9:25 It may succeed, it may now run in a constraint

9:25 rhickey: AWizzArd: then just use a global lock, that's what you end up with

9:25 chouser: AWizzArd: so retries happen, but only before the write?

9:25 AWizzArd: like in a Clojure dosync, where two threads try to get mony from an account which may have a balance less than 0. One thread wins and gets the money first, the other one will fail.

9:26 rhickey: I don't need a global lock, only during merges.

9:26 And also then not a global lock, but just around the slave and master

9:26 rhickey: AWizzArd: but you are testing for success with a global db version, so all work is serialized - might as well do that up front

9:26 AWizzArd: All other DBs can be updated at the same time

9:27 rhickey: all right, lock per db. You aren't really leveraging STM

9:27 doind speculative work only to fail on not-serial is a waste, just serialize the work with a lock

9:27 AWizzArd: rhickey: during a (merge db1 db2) I want to merge changes in db1 into db2. I will make a snapshot of db2 and merge that. If db2 did not change I can replace it with the merged snapshot.

9:28 chouser: AWizzArd: I thought you were taking the one lock per db up front

9:28 AWizzArd: chouser: yes, that is true for non-merge operations

9:28 chouser: the one feature over a simple lock is the thread-local version of the db to allow unlocked reads of old versions.

9:29 AWizzArd: rhickey: is dosync not doing speculative work? When I try to take money from an account in two different threads, then only one can win, because the balance my not be less than 0. 1000 is in the account, 800 both threads want to take.

9:29 rhickey: AWizzArd: but dosync overlap granularity is the ref, not the world/db

9:29 AWizzArd: Both concurrently take the 800 but then see that another thread already tried that and one needs to repeat and is now confronted with a different balance.

9:29 rhickey: aargh

9:30 AWizzArd: chouser: yes

9:30 rhickey: the db could be in the ref. Not every table and index is its own ref.

9:32 rhickey: the STM world is a set of identities. transactions can encompass any arbitrary subset. transactions on non-overlapping subsets can simultaneously succeed

9:32 AWizzArd: non-overlaying subsets means: different refs yes?

9:32 rhickey: your dbs are fixed subsets

9:32 AWizzArd: Not two different key/value pairs inside one hashmap

9:33 (def db (ref {}))

9:33 Now two dosyncs want to assoc something onto db.

9:33 rhickey: I don't have any more time for this, sorry

9:33 AWizzArd: Can they both do it concurrently?

9:33 Thread 1 adds :a 1, Thread 2 adds :b 2

9:33 No retries, no speculative work, no global lock?

9:34 rhickey: thanks for your time so far :)

9:38 chouser: AWizzArd: Based on the scheme we discussed with one lock per db, I don't see any value in allowing speculative work and retries.

9:38 AWizzArd: chouser: those would be only for merges.

9:39 chouser: I don't see any value in separating merges from other write work on the db.

9:40 AWizzArd: maybe that will not be needed, it is just an idea with which I am currently playing. Maybe merges will indeed have the same locking mechanism.

9:40 chouser: the reason speculative work can make sense for STM transactions is because the overlapping set of refs involved in each transaction is discovered within the transaction, and could even change on each retry.

9:41 but none of that applies to these db's, where you'll declare up front the one or more dbs you're going to touch.

9:41 AWizzArd: Yes, maybe that is not needed.

9:41 jcromartie: hmm, I seem to have lost the ability to hit C-up in my Clojure slime repl

9:41 oh, nevermind... stupid OS X Spaces shortcut keys!

9:41 AWizzArd: chouser: I will decide more about merges in the coming days. Currently the lock system seems to be very okay.

9:43 Also it can later be updated to do more granular locking and indeed allow concurrent updates to different parts of the db.

9:43 Completely separated modifications can then be divided and happen concurrently.

9:44 * _fogus_ hates snow

9:44 cemerick: _fogus_: can you move around down there yet?

9:44 _fogus_: In theory yes... in practice no

9:44 cgrand: AWizzArd: http://www.assembla.com/spaces/clojure/tickets/213-Invariants-and-the-STM

9:45 cemerick: _fogus_: and more to come, yes?

9:46 * cemerick is a little bitter that _fogus_ is getting all the snow, and we have *nothing*

9:46 _fogus_: cemerick: Yes, another 10-20 on top of the 30 on the ground. :-(

9:46 AWizzArd: cgrand: yes, like this. And if Clojures STM supports that and io, then I can switch to that system within 1-2 days, and without breaking user code.

9:46 cgrand: i only need something now, so what I do will be mostly equivalent in practice.

9:47 cemerick: What I don't understand is why I keep hearing people talk about "the northeast" getting pounded, when no notable amounts are falling north of Jersey.

9:48 cgrand: AWizzArd: use a ref of map of refs and a special-assoc fn

9:59 ordnungswidrig: Anybody uses genetic algorithms on sexps for machine learning?

9:59 tomoj: I remember someone talking about that a long time ago in here

9:59 it may have been you? :(

10:00 AWizzArd: ordnungswidrig: yes

10:01 Well, I am doing Genetic Programming, not GA.

10:01 ordnungswidrig: tomoj: no, just thought of it. there was a java chess application which did evolve an algorithm on a dsl.

10:01 tomoj: does that actually work at all?

10:01 ordnungswidrig: tomoj: somewhat, yes :-)

10:01 AWizzArd: tomoj: Genetic Programming?

10:01 tomoj: I always sort of imagined that random code would suck

10:01 but never tried it

10:01 AWizzArd: it works very well for some problems

10:01 ordnungswidrig: if think of evolving some code for the google ai challange

10:02 tomoj: maybe particularly if you can restrict the language?

10:02 whoever was talking about it before in here was trying it with just arithmetical functions, I think

10:04 AWizzArd: yes, in GA and GP you restrict the language.

10:07 ordnungswidrig: tomoj: airthmetic is way to unspecific. although I heard of attempts to generate formulas for certain numbers as the fine structure constant

10:15 jkdufair: anyone happen to have binaries of the CLR version of clojure? i don't have visual studio on this machine

10:21 triyo: Whats the best way to check if something is a non-sequence type? (not (coll? x))

10:22 Draggor: (not (seq? x))?

10:23 cemerick: triyo: you probably want (not (or (sequential? x) (seq? x)))

10:24 unless you really, honestly only want non-seqs, in which case (not (seq? x)) will do as Draggor said.

10:27 triyo: cemerick: thanks, what is cool?

10:27 oops

10:27 type

10:27 typo

10:27 cemerick: ,(doc coll?)

10:27 clojurebot: "([x]); Returns true if x implements IPersistentCollection"

10:27 triyo: cemerick: thanks, what is coll? then

10:27 cemerick: ,(doc sequential?)

10:27 clojurebot: "([coll]); Returns true if coll implements Sequential"

10:27 cemerick: ,(doc seq?)

10:27 clojurebot: "([x]); Return true if x implements ISeq"

10:28 cemerick: triyo: see http://github.com/Chouser/clojure-classes/blob/master/graph-w-legend.png for the complete view

10:29 triyo: cemerick: oh nice link, thanks

10:30 cemerick: chouser: what do the colors mean on that diagram again?

10:32 chouser: cemerick: the colors have no meaning, they're just to help to follow traces as the cross, converge, etc.

10:32 cemerick: ah

10:33 chouser: and I imagine that thing's probably out of date again.

10:35 jkdufair: if one were to add durability (via the filesystem, say) to clojure's STM, would that require a two-phase commit?

10:35 or just a lot of blocking, or what?

10:51 jcromartie: you know what would be good for the web? a distributed URL shortening service

10:52 (just thinking out loud... I know it's OT)

10:52 tomoj: ordnungswidrig: unspecific?

10:52 I would've guessed the opposite

11:04 rhickey: cgrand: one problem with http://www.assembla.com/spaces/clojure/tickets/213-Invariants-and-the-STM is how to avoid races? the STM no longer knows where the contention is and can't park conflicting attempts like it can at the ref level

11:08 cgrand: rhickey: you're right as usual and I would already be happy with single-ref invariants. (I over generalized the problem or the solution or both :-/)

11:09 or do you mean "in-ref" races?

11:09 rhickey: yes, in-ref

11:10 it's an important part of the Clojure STM design that it doesn't spin

11:11 perhaps spinning in-ref not so bad, but I don't know

11:11 dsop: rhickey: I tried to initialize clojure classes from a jar using urlclassloader and failed

11:12 rhickey: it seems that the clojure rpl tries to use the system class loader to get the .clj file

11:12 rhickey: as the jar file is not in the classpath it doesn't find the .clj file and aborts.

11:15 cgrand: rhickey: ok, the real problem that made me think of invariants is being managing concurrent changes to a ref holding an associative datastructure.

11:15 dsop: rhickey: is that 'expected' to happen?

11:15 cgrand: rhickey: Another solution could be a commute-in fn (a mix of commute and update-in): (commute-in a-map-in-a-ref [:a :b] inc), there the STM knows both the ref and the path.

11:16 dsop: ah yes, and I gen-classed the necessary .class files for the jar

11:20 rhickey: cgrand: how is that not ordinary commute?

11:26 cgrand: commute-in would commute as long as (get-in @a-map-in-a-ref [:a :b]) doesn't change between in-txn value and commit-time. (so commute-in is a bad name)

11:28 rhickey: cgrand: that's still spin prone, as we'll allow two destined-to-conflict transactions to proceed

11:29 I guess it could have the blocking characteristics of a write, but right now once blocked a txn is presumed failed

11:34 yuuki: are library routines with side effects marked? (like pop!)

11:34 chouser: frequently.

11:40 rhickey: dsop: can you make a simple test case?

11:41 dsop: rhickey: yes for sure.

11:42 rhickey: dsop: ok, then please attach that to a ticket on assembla - thanks

11:43 dsop: rhickey: I cannot open tickets, have to make sure first if I'm allowed to sign the cla

11:44 rhickey: dsop: anyone can create tickets via: https://www.assembla.com/spaces/clojure/support/tickets

11:44 no CA required

11:44 dsop: oha, must have overseen this, thank you. will do

12:00 yuuki: (apply (peek '(+)) 2 3 ())

12:00 Why should this not give 5 as the answer?

12:01 (apply (peek (list +)) 2 3 ()) works

12:02 rhickey: ,(class (peek '(+)))

12:02 clojurebot: clojure.lang.Symbol

12:02 rhickey: ,(class (peek (list +)))

12:02 clojurebot: clojure.core$_PLUS___4518

12:03 yuuki: ,(+ 5 5)

12:03 clojurebot: 10

12:03 yuuki: neato

12:03 I thought quote was a macro for (list ...)

12:04 chouser: no, they are rather different.

12:04 list is a function, so all its args are evaluated first, then passed to 'list' which returns a list object.

12:05 'foo is the same as (quote foo)

12:06 yuuki: Hmm

12:06 chouser: which causes foo, however complex and nested it may be, to remain unevaluated, returning whatever literal datastructures you have there.

12:06 yuuki: I see

12:07 so '(+) returns a list containing the symbol + and (list +) returns a list of the definition of +

12:08 chouser: yes

12:08 ,[1 (+ 2 3)]

12:08 clojurebot: [1 5]

12:08 morphling: yuuki: `(~+) would be the same as (list +)

12:08 chouser: ,'[1 (+ 2 3)]

12:08 clojurebot: [1 (+ 2 3)]

12:08 yuuki: ,`(~+)

12:08 clojurebot: (#<core$_PLUS___4518 clojure.core$_PLUS___4518@1b38815>)

12:08 yuuki: neato

12:08 chouser: ,`[1 (+ 2 3)]

12:08 clojurebot: [1 (clojure.core/+ 2 3)]

12:09 yuuki: what is the deal with `?

12:09 chouser: that's an example from the section on evaluation and quoting in _fogus_'s book.

12:10 yuuki: interesting

12:10 chouser: ` is provided to make the writing of macros more convenient

12:11 dnolen: ,(let [x '+] `(~x 2 3))

12:11 clojurebot: (+ 2 3)

12:11 morphling: ,(apply (peek `(+)) 2 3 ())

12:11 clojurebot: 3

12:11 morphling: (apply (peek `(~+)) 2 3 ())

12:12 ,(apply (peek `(~+)) 2 3 ())

12:12 clojurebot: 5

12:24 underdev: anyone recommend a good sytax highlighting theme for clojure?

12:24 emacs

12:27 pjackson: There's not /really/ much to highlight. I use "arjen"

12:28 which is part of color-theme.el...

12:28 underdev: great, ty

12:29 hard to get a straight answer about color-theme

12:29 now i know

12:33 noidi: underdev, I like zenburn

12:33 looks like this http://slinky.imukuppi.org/zenburn/ , emacs port available here http://brockman.se/2003/zenburn/

12:39 underdev: noidi: ty

12:39 pretty nice

13:21 DeusExPikachu: I'm getting more strange behavior modifying server.clj in swank-clojure, I'm passing to function setup-server the option :dont-close true, to opts. I'm printing out the value of opts before the call to start-swank-socket-server! and its set to true, but if I print out the last map {:annount ... (opts :dont-close) [by wrapping it in a let, printing, then returning], :dont-close turns to nil. The only way this is possibl

13:21 e is if something is mutating opts, however, I don't see any code mutating opts... What's going on?

13:45 ninjudd: getting an error compiling clojure-contrib master using maven

13:45 Reason: POM 'com.theoryinpractise:clojure-maven-plugin' not found in repository: System is offline.

13:48 cemerick: ninjudd: are you running maven in offline mode (e.g. -o)?

13:48 ninjudd: yes

13:49 from the README: mvn package -o -Dclojure.jar=/Users/ninjudd/lib/java/clojure.jar

13:49 cemerick: doing that will prevent maven from obtaining the necessary dependencies

13:49 that's only necessary if you're using your own clojure.jar, but even so, you need to let it run normally once so it can pull down the necessary plugins, etc.

13:50 ninjudd: i am using my own clojure.jar

13:50 cemerick: ok, so run mvn package so that the necessary plugins can be obtained, and then do an offline build with your own clojure jar.

13:50 ninjudd: is that the kind of thing i would know if i'd ever used Maven before? or should it be added to the README?

13:51 cemerick: yeah, that's sorta basic :-)

13:52 in general, building offline is entirely unnecessary.

13:52 ninjudd: ok

13:52 cemerick: I actually don't think it'd be necessary when using a particular clojure jar either *shrug*

13:53 technomancy: it's pretty important if you're using mvn for tests and you have a lot of snapshot dependencies

13:53 otherwise you can double or triple the time a test run takes

13:54 stuartsierra: Should I remove the "-o" in the command line on the README

13:54 cemerick: stuartsierra: I think so. It doesn't do anything w.r.t. ensuring that the provided clojure jar is used.

13:55 ninjudd: hmm, looks like master clojure-contrib won't compile with master clojure

13:55 Compiling clojure.contrib.fnmap.PersistentFnMap to /Users/justin/projects/clojure-contrib/target/classes

13:55 Exception in thread "main" java.lang.VerifyError: class clojure.contrib.fnmap.PersistentFnMap$loading__4759__auto____1 overrides final method meta.()Lclojure/lang/IPersistentMap;

13:55 stuartsierra: ok

13:55 Ankou: hi, I have a nested map structure and want to change something in an inner map(say I have {:a {:b 0 :c 0}} and want to change c) what's the best way to achieve this?

13:55 cemerick: technomancy: I dunno -- then you're going to be (potentially) testing against stale artifacts

13:55 stuartsierra: ninjudd: that sounds like a bug in fnmap, which is obsoleted by deftype/defprotocol anyway

13:55 technomancy: cemerick: that's almost always what I want

13:56 cemerick: Ankou: try assoc-in or update-in

13:56 technomancy: I mean vs waiting 60s to make sure they're not stale

13:56 ninjudd: ankou: assoc-in or update-in

13:57 technomancy: slight exaggeration, but we have a _lot_ of snapshots, and have five repositories to check against; it adds up fast

13:57 each snapshot must be checked in each repository

13:57 ninjudd: stuartsierra: so what should i do get it to compile?

13:57 stuartsierra: leave out the -o

13:58 Ankou: okay, thanks

13:58 stuartsierra: oh, wait

13:58 ninjudd: to compile, see instructions for skipping tests in the README

13:58 Wait, that won't help either.

13:58 Remove the line for PersistentFnMap in pom.xml

13:59 cemerick: technomancy: I'd almost say that what you've described is a symptom of not cutting releases often enough ;-)

14:00 stuartsierra: Hudson reports no failures on latest builds.

14:01 technomancy: cemerick: probably. but in most cases we don't have control over that.

14:03 stuartsierra: Pushed 9aecba5c5133d1a5017bc52b7def9a85b2ec3cef - remove -o from command line in README

14:09 DeusExPikachu: has there existed a bug in clojure where deferencing an item in a map using keywords with hyphens in their name?

14:10 stuartsierra: DeusExPikachu: not that I can think of

14:10 re your problems with swank, maybe there's an issue with how the default options get merged

14:11 hiredman: DeusExPikachu: deferencing?

14:11 cemerick: DeusExPikachu: this is a slot in a deftype instance?

14:11 DeusExPikachu: I'm not familiar with default options, at least in the definition of setup-server, I don't see any code involving defaults

14:12 perhaps I'm not using correct terminology, but I'm referring to something like this (let [opts {:a 1 :b 2}] (opts :a))

14:13 what do you guys use to paste code?

14:14 chouser: DeusExPikachu: http://paste.lisp.org/new/clojure

14:16 DeusExPikachu: http://paste.lisp.org/+2118

14:17 I pasted my modified version of setup-server, which includes some print statements, and the output (forgot to paste the word "setup-server but that's not relevant)

14:17 if you look at the output, :dont-close becomes nil when I (opts :dont-close) it, but opts never changed

14:19 cemerick: DeusExPikachu: and you're getting an error when accessing opts?

14:19 DeusExPikachu: no error, just that it returns nil

14:19 Chousuke: DeusExPikachu: are you sure the code is exactly like that?

14:19 DeusExPikachu: in the code (opts :dont-close)

14:19 Chousuke: DeusExPikachu: maybe you have a typo?

14:19 DeusExPikachu: Chousuke, I just copied pasted it

14:20 cemerick: A couple months ago, I ran into a bug where deftype slots with dashes caused errors (because the java name munging wasn't in place yet).

14:20 DeusExPikachu: that's what I figure

14:21 something of that nature must be the problem, cause the code looks fine

14:22 stuartsierra: but opts is an ordinary map, right?

14:22 DeusExPikachu: stuartsierra, correct

14:22 cemerick: oh, nevermind then

14:23 anyway, deftype doesn't support non-java field names (at least in my current build)

14:24 stuartsierra: must be a typo

14:24 DeusExPikachu: the function start-server, creates a new map generated by this (let [opts (apply hash-map opts)] ..., start-server passes this to setup-server

14:25 there is no typo

14:25 stuartsierra: http://paste.lisp.org/+2118/1

14:25 Wait

14:25 (apply hash-map opts)

14:25 If opts is already a map, that won't work.

14:26 DeusExPikachu: it wasn't, opts was a vector

14:26 stuartsierra: ,(apply hash-map {:a 1, :b 2})

14:26 clojurebot: {[:a 1] [:b 2]}

14:26 DeusExPikachu: (apply hash-map (apply concat {:a 1 :b 2}))

14:26 thats basically what happens earlier

14:26 stuartsierra: ,(apply hash-map (apply concat {:a 1 :b 2}))

14:26 clojurebot: {:a 1, :b 2}

14:26 stuartsierra: hmmmm

14:27 DeusExPikachu: btw, to be clear, I'm not running this function in a repl, its the output after running my modified version of lein-swank

14:30 stuartsierra: dunno, good luck!

14:30 DeusExPikachu: :(

14:31 cemerick: DeusExPikachu: try (println (keys opts)), just as a sanity check?

14:31 DeusExPikachu: cemerick, ok

14:31 cemerick: eh, that won't help

14:32 perhaps one of the :dont-close keys has an unprintable char in it

14:33 DeusExPikachu: ... I probably quadrillion checked that already

14:33 I can't make an unprintable typo 20 times ina row

14:34 cemerick: DeusExPikachu: you've got a repl in to this code?

14:35 DeusExPikachu: cemerick, haven't called it in a repl yet, no, only grabbing output after running it as part of a larger system

14:36 cemerick: DeusExPikachu: that's your next step. Just def the opts somewhere, and then poke at the thing until you know what's up.

14:37 DeusExPikachu: thing is, I've been printing verbose information of all the function calls leading up to this call

14:40 ok, so in the repl it works correctly, but in the system it doesn't

14:47 so that means the problem lies not in my code

14:48 cemerick: It doesn't sound like you can infer anything from that.

14:48 There's certainly *some* code that's faulty, and it's nearly certainly not clojure's map impl.

14:50 DeusExPikachu: when I say it works correctly in the repl, I mean that it prints correctly, it ultimately fails cause the other args are missing instances of classes that are made unless I simply run everything from the beginning

14:50 just to be clear

14:51 btw, http://paste.lisp.org/display/94652#2 I printed other ways to refer to the :dont-close item, which all return nil

14:51 LauJensen: Extended the Reddit Clone a little bit: http://www.bestinclass.dk/index.php/2010/02/reddit-clone-with-user-registration/

14:56 DeusExPikachu: cemerick, in the class path, there are multiple versions of clojure being used, is it possible a conflict can arise with multiple versions? That would be a problem not caused by any "faulty code" per say , but faulty configuration

14:57 cemerick: heh, that's a bad idea in general. All bets are off if you've got multiple versions of *any* library in your classpath.

14:57 DeusExPikachu: unfortunately, leiningen seems to setup running environments like that a lot

14:59 or I should say, its easy to do so

14:59 and difficult to do otherwise

15:00 cemerick: I'd try manually fixing up the classpath and seeing what happens.

15:01 cgrand: is there any reason why I shouldn't use enlive's emit for general use? clojure.xml's emit is broken.

15:07 DeusExPikachu: hmm, tried it with no multiple versions, still have the problem

15:07 wouldn've been great had that been it

15:21 cemerick: I wonder if anyone has any interest in a json -> XML conversion fn?

15:22 dakrone: have any for the other way around?

15:23 cgrand: cemerick: none that I can think of (apart from namespaces as usual)

15:23 cemerick: dakrone: that's a lot tougher

15:23 so, no :-)

15:24 cgrand: sure. Maybe rhickey can be convinced to pull yours in as a replacement. ;-)

15:25 xp_prg: anyone want to help a newbie learn some clojure?

15:25 * the-kenny just ordered "The Joy of Clojure" printed version :)

15:25 BrandonW: that depends how newbie you are :)

15:26 if you are less newbie than me, then no :D

15:26 chouser: the-kenny: thanks! :-)

15:27 the-kenny: chouser: I wanted to buy it for some weeks now, but I only just figured out how to buy it with paypal w/o a credit card

15:28 chouser: the-kenny: ah, good. I didn't even realize Manning was using paypal until you mentioned it a while ago. For some reason I haven't felt compelled to buy the book. :-P

15:28 the-kenny: chouser: mh... but I think it's an interesting book, you should buy it :p

15:29 chouser: :-)

15:35 the-kenny: huh

15:35 "aus seinem Herzen keine Mrdergrube machen"

15:35 rhickey: rhickey: would gladly take patches to improve emit

15:36 the-kenny: "Mrdergrube" is missing an "ö" after the "M"

15:38 rhickey: what's with the run-test3369805950334031482.clj in contrib tests?

15:43 chouser: rhickey: I don't see that.

15:44 rhickey: ERROR in (can-print-json-null) (run-test3369805950334031482.clj:45)

15:44 expected: (= "null" (json-str nil))

15:44 actual: java.lang.NullPointerException: null

15:45 chouser: I just pulled a new contrib, and in master branch did "mvn test" ... Ran 256 tests containing 1203 assertions. 0 failures, 0 errors.

15:46 rhickey: yes, but I made a change to core that broke contrib with that message

15:46 chouser: oh, I see.

15:46 but I don't have a file named anything like that in contrib either.

15:47 rhickey: reverted it, rebuilt both, re-inserted it, now tests pass - aargh

15:47 chouser: hm, perhaps it's temporary while maven does its thing?

15:47 oh

15:47 :-(

15:47 "Multiple deliver calls to a promise"

15:47 * chouser stares harder at his obviously broken logic...

15:48 cemerick: rhickey: that file is a temp file that clojure-maven-plugin generates to require all namespaces found in the project, and run tests over them.

15:48 look in your /tmp (or whereever java puts temp files on your system)

15:49 The file is uninteresting, just the root from where tests are run.

15:50 rhickey: are you only interested in incremental patches to emit, or would you be open to a replacement?

15:50 * cemerick points at enlive/emit

15:51 rhickey: almost any patch would be a replacement - there's next to nothing there

15:51 cemerick: are you tied to the idea of printing, as opposed to, say, a seq of strings?

15:52 returning a seq of strings, that is

15:53 rhickey: cemerick: strings that start and stop where?

15:56 cemerick: rhickey: e.g. enlive emits ("<" "root" "></" "root" ">") for {:tag :root, :attrs nil, :content ""}

15:58 rhickey: cemerick: to what end?

16:00 cemerick: rhickey: not following you.

16:00 chouser: so you can lazily pull from that seq instead of dancing with binding *out*, I assume.

16:00 rhickey: but there isn't a rule about what is in the strings or where they break, is there?

16:01 cemerick: chouser: that's nice, but not a huge deal IMO -- the real improvements would be proper content output (e.g. no inappropriate newlines, etc), basic attribute value escaping, etc.

16:01 rhickey: i.e. what else are you going to do with them but dump on a stream?

16:02 cemerick: the printing vs. seq issue is only important vis á vis API compatibility

16:02 rhickey: one can be built on the other

16:03 cemerick: true enough

16:03 rhickey: but it is more efficient to put the characters right on a stream than to allocate all those strings

16:04 cemerick: I really dislike rebinding *out* -- I can never remember what specific type of stream/writer/printer/whatever it's supposed to be.

16:05 But anyway, that's neither here nor there.

16:05 chouser: pretty often those individual strings will already exist in the tree being emitted

16:05 though of course the lazy-seq objects would have to be created.

16:05 rhickey: cemerick: fair enough, but the solution there is to make it easier to do the right thing, not abandon streams

16:06 cemerick: sure

16:07 cgrand: would you have any objection to my attempting to package up the enlive emit stuff as the basis for a new clojure.xml emit?

16:09 chouser: cemerick: fwiw, there's an emit in lazy-xml that also escapes attr values and has an option to not insert extra newlines.

16:10 looks like it does a lot of string allocating though. :-/

16:11 cemerick: hrm, quite the profusion

16:12 it seems like one of these should get into clojure.xml for 1.2

16:12 chouser: was the :pad option just to stay compatible with clojure.xml/emit?

16:12 chouser: cemerick: yes

16:13 jimt: Is there a standard/best way to do serial port communication with clojure? Just use Java/rxtx? Or is there a more lispy wrapper?

16:14 ordnungswidrig: re

16:15 cemerick: perhaps a better idea would be to build a clojure-xml->DOM fn that produces java DOM elts, and feed that into the xerces/xalan stuff in the JDK to emit XML. There's a perf hit, but otherwise someone's going to be reimplementing all the escapes, pretty printing, blah blah blah.

16:16 chouser: perf hit + 3rd party lib to avoid escapes that have already been translated to clojure (a few times) doesn't seem worth it.

16:16 cemerick: I would draw the line at pretty-printing, though. If you want more complex kinds of transformations then by all means use a java lib that does it for you.

16:17 cemerick: chouser: what 3rd-party lib? All that stuff is baked into the JDK.

16:17 chouser: xerces/xalan is? oh, is that JDK not JRE?

16:17 cemerick: There's also the issue of emitting namespaced xml eventually, as well as non-UTF-8 encodings.

16:18 sorry, I shouldn't have said xerces/xalan -- the JRE/JDK starting with 1.4 or 1.5 includes an XSL transformer, which ropes in all this serialization stuff.

16:19 I don't actually know what the specific impl is.

16:19 chouser: oh. if it's included, that sounds like a good route.

16:19 to me. though if rhickey was concerned about allocating string, allocating DOM objects may be right out.

16:20 cemerick: chouser: yeah, javax.xml.transform and friends are all there.

16:22 XML serialization doesn't seem like a perf-sensitive thing to start with, but reimplementing all that can go into it seems a little crazy regardless.

16:24 rhickey: I'm definitely for the path of least wheel-reinventing

16:26 cemerick: The only issue is that this would be the first step out of the java.lang/io/util packages...which doesn't matter to me, but makes things just a little harder for someone porting to another host.

16:49 rhickey: cemerick: but some all-clojure things already exist (enlive)?

16:49 * rhickey is constantly amazed at how complex XML got

16:51 rhickey: did anyone aver submit a patch for inline bit shifts?

16:51 ever

16:52 cemerick: rhickey: enlive is very good in my experience so far, but it has no pretty-printing option, I don't know what one would do if emitting non-UTF-8 was required, and even once clojure.xml/parse and friends support namespaces, serializing them properly is wickedly difficult.

16:53 rhickey: cemerick: still seems like a proper subset of the final solution, what/whenever that may be

16:53 cemerick: rhickey: you mean something like enlive?

16:53 rhickey: yes

16:54 cemerick: hrm

16:54 rhickey: unless it is doing something that will become wrong in the future

16:54 cemerick: I'm quickly becoming convinced that having an easy clojure.xml <-> DOM bridge is critical in general, and if that exists, why bother having a clojure-based emit?

16:55 rhickey: makes sense - have you got a clojure.xml -> dom thingy?

16:55 cemerick: um...no :-)

16:56 * cemerick struggles to not say "it can't be that hard"

16:56 rhickey: because there's a sense in which that can become more generic, even though the DOMs might differ per host, we just cover to/from host DOM

16:56 cemerick: yeah

16:57 replaca: rhickey: I have to apologize. Autodoc is broken on post-1.1 clojure & contrib (the prob of using code to document itself)

16:57 rhickey: except everyone knows DOMs are unusable pigs sometimes

16:57 replaca: no problem

16:57 replaca: rhickey: I've not had too much time to work on it because we just had a baby and that's kind of all consuming, but I should be thee soon :-)

16:58 cemerick: rhickey: yeah, this is purely a library leverage strategy

16:58 rhickey: replaca: congrats!

16:58 replaca: rhickey: thanks :)

16:58 lancepantz: how can i get the exception message from a catch? i'm trying (catch Exception e (foo (.getMessage e)))

16:59 replaca: now that the baby is actually born, I'm taking some time off and while she's napping (a lot) I should have some time to get things put back together

16:59 rhickey: cemerick: no one would look askance at a to/from DOM option

16:59 lancepantz: which returns null

17:00 cemerick: rhickey: FYI, all the DOM stuff is interfaces, but they're pretty hairy and super-mutable, and I wouldn't rule out a nightmare scenario where transformers have implementation-specific dependencies, etc.

17:00 StartsWithK: lancepantz, can you paste a bigger code snippet?

17:00 cemerick: but, I'll take a stab at it soon-ish. :-)

17:00 rhickey: do you have any idea as to how namespace support might work out in clojure.xml/parse, etc?

17:01 lancepantz: http://www.pastie.org/817149

17:01 this is my first clojure project, so don't laugh :)

17:02 StartsWithK: rhickey, in clojure.xml you use Keyword/intern to convert string to keywords in parse, and not keyword, can you explain why?

17:03 i just finished json parser on jackson, and keyword vs Keyword/intern is something like 4x speed up

17:03 if i use intern

17:04 rhickey: StartsWithK: probably because keyword didn't exist yet

17:04 replaca: going back over today chatting: the reason enlive returns a seq of strings is because it builds things up from small chunks with function applications and Christophe wanted to avoid building up successively larger strings at each layer

17:05 instead you just assemble the parts at the end

17:05 StartsWithK: rhickey, any reason why keyword has a instance check for keyword?

17:05 lancepantz: anyone mind taking a look at my exception handling code, i'm trying to get the message from the exception: http://www.pastie.org/817149

17:05 rhickey: replaca: understood, but not really important to the consumer

17:05 StartsWithK: i don't think that is a main reason for such a drastic difference in speed

17:06 but it looks out of place

17:06 rhickey: StartsWithK: do you see this difference in master?

17:07 StartsWithK: rhickey, yes, i am on 1.2, and when converting jsonk string keys to keywords i get 4x bether performance with Keyword/intern, i also checked with c.c.json, and it can get up to 2x only by changing keyword to Keyword/intern

17:07 but if i wrap Keyword/intern in a function, problem returns

17:08 i wanted to do something like (read json-stream :key keyowd) so user can pass a covertor function

17:08 DeusExPikachu: technomancy, I've got a two part patch that depends on each other for both leiningen and swank-clojure to extend lein-swank to accept more arguments and pass them to start-repl, how should i send them to you, email? mailing-list for clojure/leiningen/swank-clojure?

17:08 StartsWithK: but now i'm stuck at :key true/false, sending anything but identity will trash performance

17:12 rhickey, http://paste.pocoo.org/show/175941/

17:12 technomancy: DeusExPikachu: thanks. I prefer being given a git url to pull from to patches. the mailing list for leiningen would be fine.

17:15 StartsWithK: and if i do (def make-keyword (fn [#^String s] (clojure.lang.Keyword/intern s))) (time (dotimes [i 100000] (make-keyword (str i)))) i get almost the same results as Keyword/intern

17:15 chouser: it seems plausable that the org.xml stuff in java may provide a away to emit xml from a stream of SAX events instead of a DOM. Ought to be more efficient and probably no less simple to implement than converting clojure.xml to a dom.

17:19 StartsWithK: rhickey, (defn make-keyword2 [name] (if (keyword? name) name (clojure.lang.Keyword/intern #^String name)))

17:20 with added typehint it works just like a direct call

17:21 maybe the hint should go inside the symbol too

17:21 cgrand: cemerick: feel free to borrow any of my code

17:22 chouser: perhaps using javax.xml.transform.Transformer and providing something that implements SAXSource on a clojure.xml structure

17:25 StartsWithK: is this http://clojars.org/repo/nstools/nstools/0.2.0/nstools-0.2.0.pom a good template for creating a pom?

17:25 rhickey: StartsWithK: http://paste.pocoo.org/show/175950/

17:26 StartsWithK: rhickey, yeah, that works, can you do the symbol too

17:27 rhickey: ?

17:27 StartsWithK: symbol function is missing type hints at the same places as keyword

17:28 rhickey: StartsWithK: doesn't need them

17:28 keyword had a reflection warning, symbol doesn't

17:28 StartsWithK: oh, your right

17:31 rhickey: StartsWithK: ok, fixed on my machine, will go up with next push - thanks for the report!

17:31 chouser: that looks like it should do it. should give you options like encoding, indent, xml-declaration, media-type, entities...

17:32 StartsWithK: that will speed up c.c.json/read-json by 2x :)

17:33 other problems i found in c.c.json are, it consumes stack while reading (and in write, but that is not such a big deal)

17:34 replaca: rhickey: (sorry, jumping around) you're right, of course, but the issue was that there's no difference between the inside and the outside and Christophe didn't want to create an extra layer that was just (apply str ...) and duplicated the whole mechanism of deftemplate.

17:34 StartsWithK: and it will parse invalid json like "1" "[1,,,,2]" "{\"a\":::::2}" ...

17:36 romanroe: emacs/slime always asks to save the files when I eval the buffer etc. Is it possible to set something like autosave=true?

17:43 fro0g: I'm looking for a sparql interface for clojure

17:43 agraph-java-client seems to contain one, but is it only for allegro graph ?

17:52 DeusExPikachu: technomancy, I'm sending you the pull request via github's pull request, I don't know how to link a pull request manually. Is that ok?

17:58 technomancy: that's fine

17:58 DeusExPikachu: if you can keep work in a topic branch you get bonus points

17:59 but if it's on master that's OK too

17:59 DeusExPikachu: hmm, next time I suppose, I sent them

18:00 technomancy: I should write up a post about best practices for submitting patches to the projects I maintain. =)

18:00 DeusExPikachu: the changes are simple, but it took me forever to test it to make sure it worked... the print not printing quotation marks really got me, it would've saved me sooooo much time

18:01 technomancy: yeah, that's put me off hacking swank more myself; it's so annoying to test manually =\

18:01 DeusExPikachu: what sucks is I wanted to use lein swank, and slime and all that goodness I"m used to, but couldn't cause thats the thing I'm actually working on

18:03 technomancy, I agree a brain dead simple guide would expand the people who would submit patches to you :) Maybe a new video from in the works sean devlin?

18:03 technomancy: oh, that's a great idea

18:42 ninjudd: if i want to submit a patch do i still need to fill out the contributor agreement and mail it in?

18:45 neotyk: ,(doc proxy)

18:45 clojurebot: "([class-and-interfaces args & fs]); 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 provide

18:45 neotyk: does proxy work with generics?

18:46 like "interface I<T> ..."

18:50 right, generics are compile time, so I don't really care, thanks :)

18:58 raek: hmm, if I add a class into the classpath after the start point of a clojure program, can I use it without having to restart the program?

19:02 technomancy: raek: if you add a .class file to a directory that's already on the classpath it should work

19:09 raek: aww, I realized what where wrong...

19:09 I'm using swank on my server and slime on my laptop

19:09 I only have the class-file on my laptop...

19:32 can I re-import a class if I have changed it?

19:35 rhickey: raek: not without restarting the jvm, no

20:12 raek: Why does LazySeqs catch exceptions and wrap them in RuntimeExceptions?

20:32 qed: http://www.infoq.com/interviews/hickey-clojure

20:32 i missed that one

20:41 xp_prg: anyone want to teach a newbie some clojure?

20:42 qed: xp_prg: anything in particular

20:42 xp_prg: im sort of a noob myself, but maybe i can help

20:42 xp_prg: how to make a custom programming language with it

20:43 qed: xp_prg: like a DSL?

20:43 xp_prg: what is that?

20:43 Domain specific language?

20:43 qed: like CSS

20:43 xp_prg: like a cascading style sheet?

20:43 qed: yes

20:44 xp_prg: that is what DSL means?

20:45 qed be my friend right now

20:47 am I talking to myself?

20:48 qed just be my friend right now, no biggie

20:51 qed?!!!!!!!!

20:51 qed: http://en.wikipedia.org/wiki/Domain-specific_language

20:52 xp_prg: ok so how do I do that in clojure then?

20:52 qed: xp_prg: very carefully

20:52 xp_prg: it's best to learn clojure before trying to do things with it

20:52 ;)

20:53 xp_prg: right, so help me to learn it then do a DSL

20:53 qed: i dont think i will be doing that

20:53 xp_prg: and remember to be nice as I am new

20:53 qed? :(

20:53 qed: if you have specific questions id be happy to offer some help, but the request you are making right now is rather unreasonable

20:53 xp_prg: how come?

20:54 are you a playa hata?

20:54 qed: dont hate the player, hate the game

20:54 xp_prg: right

20:54 I want to learn the game don't hate on a playa

20:55 so you gonna hate on me?

20:56 qed: xp_prg: if you have a specific question about implementing something in clojure that is not as vague as creating some vague DSL, then I can help you more, but like I said, you're asking something which has many answers, could require every core clojure feature available, etc.

20:56 xp_prg: even for a simple little example?

20:57 qed: xp_prg: if you have a specific question about specific code i can help, otherwise i suggest you google around

20:57 xp_prg: but how about a simple little DSL?

20:57 I learn quick I have CS, MSCS, and MBA

20:57 qed: so surely you could pick up a book...

20:58 xp_prg: ya, that is the hard way to do it

20:58 qed: it is the correct way to do it

20:59 xp_prg: ya I guess I am just too overwhelmed, oh well

20:59 qed: xp_prg: i felt the same way, but there is no substitute for diving in

20:59 you will be glad you did

20:59 xp_prg: I have stuided some stuff

21:00 qed: i suggest projecteuler.net

21:00 start doing some problems with clojure -- it will get you a bit more comfortable

21:00 underdev: xp_prg: google sicp, breaze through that, you'll be able to make a dsl

21:01 qed: shouldnt take you more than 2-3 hours ;)

21:01 danlarkin: stop with this dsl nonsense

21:01 what you mean is "library"

21:03 * qed shrugs -- clojureql is a library, but it's also a DSL -- i see no problem with calling something a DSL

21:06 underdev: lisps are great for dsls

21:06 xp_prg: read some paul graham essays, grep for "bottom up"

21:06 xp_prg: dude I have cs degree I am not a fool

21:06 I just want someone to hold my hand for a while

21:07 underdev: graham

21:07 seriously

21:07 qed: xp_prg: i dont think anyone is calling you a fool

21:07 xp_prg: actually I am a fool :>

21:07 but I am a fool with two cs degrees

21:07 qed: xp_prg: one cannot ask meaningful questions without knowing the problem they need to solve first

21:08 underdev: i have a degree in philosophy, and i've read some paul graham essays

21:08 xp_prg: well the truth is I just want to understand why clojure is so cool

21:08 qed: xp_prg: read http://clojure.org/rationale

21:08 that should sum it up

21:09 underdev: yeah, for "whats cool", get some of the videos, grab them locally, and play them at 2.5x in vlc

21:09 blow your mind, not take a lot of time

21:09 qed: xp_prg: here's a good video to watch

21:09 xp_prg: sweet passive learning

21:09 that is how I am now, I am too old to be like all active learning and stuff

21:09 qed: xp_prg: http://channel9.msdn.com/shows/Going+Deep/Expert-to-Expert-Rich-Hickey-and-Brian-Beckman-Inside-Clojure/

21:09 xp_prg: especially when this is just for fun

21:10 ninjudd: xp_prg: check out http://www.amazon.com/Programming-Clojure-Pragmatic-Programmers-Halloway/dp/1934356336/ref=sr_1_1?ie=UTF8&s=books&qid=1265767791&sr=8-1

21:10 xp_prg: there is a section in there about writing your own DSLs

21:10 underdev: i put the flvs (or that case mov) throuugh winFF and listen to them on my mp3 player while doing chores

21:11 that first one is streamed, so it takes a long time to capture it

21:11 xp_prg: sweet man

21:11 qed: very sweet.

21:11 xp_prg: I am humbled by your ways

21:11 underdev: i think his keynotes are really great for whats cool

21:11 qed: rich is a great presenter

21:12 underdev: stm mvcc data structures

21:12 yeah he is

21:12 qed: i liked "Are we there yet?"

21:12 it's all the clojure you need, without the clojure

21:12 tomoj: the philosophy stuff really made me happy :)

21:12 qed: tomoj: im a philosophy guy as well

21:12 underdev: rt

21:12 had a few issues with it, but you know...

21:12 it applys to the concrete

21:13 implementation stuff

21:13 qed: nod

21:14 tomoj: I guess most of my previous exposure to language evangelism was about accidental stuff

21:14 qed: i loved the commenter at the end of are we there yet who talks about rich capitulating the history of philosophy

21:14 sort of synthesizing the two halves of philosophy

21:14 tomoj: like "oh the syntax is so nice and we have features XYZ"

21:14 rather than "nearly everyone else is fundamentally wrong" :)

21:14 qed: haha yes

21:14 underdev: ANW FTW!

21:16 i think there was a bit of conflating epistemolgy with metaphysics in there

21:16 qed: yeah

21:16 underdev: but im a jerk about such things

21:16 an orinthologist having some issues with birds

21:17 as it were

21:17 but hey, he implemented clojure, i'm on day two of configuring emacs

21:17 so who should you listen to? :)

21:18 chouser: cemerick: looked at emitting xml any more since this afternoon?

21:20 cemerick: A little. Producing DOM node impls looks possible, but the interfaces are pretty hairy, and I'm scared that stuff like the transformer has hidden dependencies on some default implementation in the accompanying DOM parser(s).

21:20 chouser: cemerick: I think it can be done without a DOM

21:20 cemerick: Either way, I'm very convinced that a clojure.xml <--> DOM conversion process is the way to go for a lot of stuff.

21:20 chouser: Oh?

21:21 chouser: cemerick: I'm not quite sure yet, but it looks like transformers might be able to take as input a thing that's delivering sax events

21:21 cemerick: I was hoping for that too, but I don't think so.

21:22 chouser: oh

21:23 cemerick: everything related to sax grounds out in an InputSource, which must be backed by an inputstream or a reader.

21:24 I'm certain we could implement a sax event source for a specific parser impl (like xerces), but that's a no-no.

21:24 chouser: cemerick: I'm looking at this. it seems so close... http://stackoverflow.com/questions/1977504/what-is-the-most-memory-efficient-way-to-emit-xml-from-a-jaxp-sax-contenthandler

21:27 cemerick: chouser: hrm, that does look promising. I'll have to go trolling some more tomorrow. :-)

21:27 chouser: it's just like snapping together Lego bricks.

21:27 Lego bricks that are giant misshapen lumps with wildly incompatible surfaces.

21:28 cemerick: heh

21:28 g'night :-)

21:38 qed: k

21:42 hiredman: lisppaste8: url?

21:45 oh, whoops

21:47 qed: 'http://lib.store.yahoo.net/lib/paulgraham/jmc.lisp -- what is the purpose of the dots after function names?

21:47 evcon. assoc. eval. etc.

21:53 tomoj: is it just me or are compojure requests stateful

21:53 I mean, not values

21:54 e.g. get-multipart-params from compojure.http.multipart seems to only work once

21:54 is this for efficiency, or was it just convenient to use java crap, I wonder

21:59 TheBusby: So what's the clojure/java way of handling getopt?

22:00 chouser: TheBusby: there's a weak simple little thing in contrib: command-line

22:01 TheBusby: chouser: thanks! will look there first!

22:01 qed: tomoj: my guess re: efficiency vs java is that it's a little of both

22:05 tomoj: oi

22:05 the problem is with the java code anyway

22:05 so I guess compojure's statefulness in this case is not actually so bad

22:05 was annoying to debug thoug

22:06 now, though, the problem is inside apache commons

22:06 which I really don't want to hack up with debugging crap

22:16 hah

22:17 a few hours wasted because the objective-c code my partner copied from the internet had two extra hyphens in a string literal

23:05 JonSmith: arohner: I have a patch for scriptjure that makes array access possible

23:17 yuuki: is there a function to show the definiton of a function?

23:19 chouser: yuuki: clojure.contrib.repl-utils/source

23:19 yuuki: thanks!

23:19 chouser: though it's a bit of a hack -- requires the function be named by a var and the definition be in a source file that's on the classpath.

23:20 devlinsf: And it must be Tuesday

23:20 chouser: it actually reads the source from the clj when you ask, so it could theoretically be out of date.

23:20 yuuki: hmm

23:20 chouser: devlinsf: right! use it quick, before midnight...

23:20 yuuki: I thought that functions might carry around their source

23:21 chouser: they do no

23:21 not

23:21 tomoj: yuuki: using emacs yet?

23:21 yuuki: nope, vimclojure

23:21 tomoj: oh, maybe they have something?

23:21 yuuki: I was hoping to inspect the definition of m-bind

23:22 tomoj: emacs has yelled at me for trying to compile files that are in jars, and I guess I'm thankful

23:22 not sure what I was thinking really

23:22 chouser: yuuki: should work. (source m-bind)

23:22 yuuki: (defsymbolmacro m-bind m-bind)

23:23 chouser: heh. that's what it said?

23:23 tomoj: @def m-bind

23:23 how do you do it

23:24 ah

23:24 m-bind doesn't really have a definition, does it?

23:24 yuuki: I don't know?

23:24 I was hoping clojure would tell me :)

23:25 tomoj: I think it did

23:25 in a strange way

23:25 somnium: yuuki: try (source monad)

23:27 tomoj: I guess I should try to learn how to use clojure's monads sometime

23:27 yuuki: I am trying to understand the idea of monads

23:27 tomoj: for me, clojure tutorials I read were confusing

23:27 made more sense in haskell

23:27 but I guess it's just a confusing subject

23:28 somnium: the fact that clojure fns are typeless makes it still harder to reason about (for me)

23:29 devlinsf: I get the impression that they aren't required as much in Clojure

23:29 yuuki: the idea of using monads to do I/O without side effects reminds me of plausible deniability for mob bosses

23:29 "What if Johnny were to ... disappear?"

23:30 devlinsf: :)

23:31 JonSmith: you could write a macro to put the source in metadata

23:31 but it might be inefficient

23:32 devlinsf: JonSmith: And you lose it when you partial

23:32 JonSmith: right that would be bad

23:32 tomoj: somnium: yeah, when I played with some monad clojure tutorial code, I just got back fns

23:32 with their ugly names

23:32 and no way to tell their types

23:33 then gave up :(

23:33 somnium: Ive been experimenting with a deftype that implements ifn and has :source and :type fields, could extend it to partias args too

23:33 I think metadata on fns will really come in handy

23:33 devlinsf: It can be dangerous, though

23:33 JonSmith: would be neat if you wanted to do reflection

23:34 devlinsf: That's exactly what you don't want to do

23:34 chouser: fns support metadata now

23:34 JonSmith: well yeah, most of the time :-)

23:34 tomoj: devlinsf: are you the full disclojure person?

23:34 devlinsf: chouser: Oh, that's new

23:34 chouser: devlinsf: yes

23:34 yuuki: is being purely functional important in clojure?

23:34 devlinsf: The same

23:34 somnium: Id just like to be able to do (:type (*comp f g h)) and get back (seqable -> seqable -> seqable) or something similar

23:35 JonSmith: but if you had a specific purpose like code that bugfixes itself, it could be neat

23:35 chouser: ,(meta (with-meta take {:my :meta}))

23:35 clojurebot: java.lang.UnsupportedOperationException

23:35 devlinsf: somnium: What about (comp f identity g)

23:35 chouser: ah, well, that works in master

23:36 somnium: devlinsf: ah well, the types would have to live in the type-system defined by *comp I guess

23:36 tomoj: somnium: isn't that anti-clojurian?

23:36 somnium: oh, its in master already? time to upgrade

23:37 devlinsf: somnium: Granted, in some respects I'd like that too. It would be nice to define a protocol that guarenteed a certain type

23:37 somnium: tomoj: its just an experiment

23:37 I was playing with a multimethod that could compose fns of various types safely

23:37 devlinsf: somnium: Really? That'd be cool to see.

23:37 Link?

23:38 somnium: hmm, I can put some in a gist I guess

23:38 devlinsf: somnium: If you get a chance

23:39 somnium: ah, found it

23:40 http://gist.github.com/300031

23:40 was just playing with at the repl (a week or two ago), no idea if I left it broken or not

23:41 tomoj: devlinsf: I'd pay for an episode on datatypes/protocols

23:41 :)

23:41 devlinsf: somnium: Just checking out new ideas

23:41 $100 :-p

23:42 tomoj: They are so on the list. I'm just waiting to get closer to a release of 1.2 I don't want to cover something while Rich is still working out his own ideas.

23:43 tomoj: good thinking

23:43 devlinsf: I'm thinking to seriously start work when 1.2 is in late beta/RC1

23:47 somnium: compojure handlers are like (m -> m), and middleware is like ((m -> m) -> (m -> m))

23:49 but sometimes middleware operates on m1 or m2 or both, wondering if there's some way to make that composition more explicit/transparent

23:54 devlinsf: btw, I really liked your & and p aliases, started using them myself

23:55 devlinsf: somnium: I noticed :)

23:55 somnium: People love 'em or hate em

23:57 somnium: Interesting code. I'll have to sleep on it to fully get it. That, and I need to get a basic unstanding of Haskell

23:59 somnium: Ive only solved euler #1 and read monad tutorials in haskell so far :)

23:59 devlinsf: Oh, okay. Then where do your A,B,C... types come from?

Logging service provided by n01se.net