#clojure log - Feb 23 2010

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

0:01 jcromartie: how would you typically combine an "application" template in enlive with other templates?

0:06 defn: i personally didn't see much need for enlive in things i wrote in compojure

0:06 jcromartie: hmm, yeah it is feeling a bit complicated at this point

0:06 what did you use?

0:09 dnolen: jcromartie: have you looked at this? http://github.com/swannodette/enlive-tutorial/blob/master/src/tutorial/template3.clj

0:09 it shows you can easily mix and match components together with Enlive.

0:09 it's not obvious but once you get it, you can really do nearly impossible things.

0:10 jcromartie: dnolen: that is a really great example

0:10 dnolen: that's 120 lines of code, and you can mix and match navs, headers, footers, widgets.

0:10 jcromartie: thanks

0:15 this is quite enlightening

0:22 herdrick: If one is going to fool around with hidden Markov models, are there any tools to use what should one use? I don't see anything specific within Incanter, though coding it up in Incanter wouldn't be so hard.

0:22 I ask because I don't see anything 'official' in Java

0:22 Don't say Python ;)

0:22 Unless you really mean it.

0:23 Oh, I should say, I mostly talking about the Viterbi algorithm

0:32 jcromartie: what's the deal with defsnippet selectors?

1:16 slyphon: woah, pre and post conditions

1:16 sweet

1:20 headius: judas!

1:20 oh wait

1:20 headius: i mean "HAI!"

1:21 headius: nice, what did I do now? :)

1:21 slyphon: you're in #clojure!

1:21 get back to working on duby!

1:21 * slyphon cracks the whip

1:21 headius: today is a Duby day

1:21 slyphon: yay!

1:21 :)

1:22 headius: mainly because that's the talk for JAX today

1:22 slyphon: oh nice

1:22 headius: I really need to add a clojure-mode that creates classes with all immutable fields initialize on construction

1:22 +refs where appropriately

1:23 * slyphon nods

1:23 slyphon: i had a real hard time getting gen-class to work and call protected methods

1:23 on a superclass

1:23 headius: that's a tough one for any dynlang

1:23 * slyphon nods

1:23 headius: clojure generates function classes which don't actually extend the original, so the JVM beats it up trying to call protected stuff

1:24 slyphon: ah

1:24 headius: jruby has the same problem, since we generate essentially the same structure

1:24 slyphon: yeah, i was told the only way to do it was wall-hack-method

1:24 headius: groovy works around it by doing setAccessible on the reflected methods everywhere (bleah)

1:25 jruby works around it where it can by generating synthetic methods on the actual subclass that act as helpers to call protected superclass methods

1:25 but it's tweaky

1:25 * slyphon nods

1:25 slyphon: well, it worked for me when i was wrapping PircBot in jruby

1:26 i'm pretty sure if i sat there and poked at it long enough i could probably get it working with clojure

1:26 i had a feeling i'd have to learn a bit more about JVM internals than i cared to at the moment though

1:27 headius: so, when do we get sexp mode for jruby?

1:27 headius: well, that's an interesting thought

1:27 * slyphon gives headius the eyebrows

1:27 headius: it would make writing transformations a lot easier than twiddling the ruby or duby ASTs

1:28 slyphon: someone proposed it for MRI and i jumped up and down on the mailing list, but to no avail

1:28 headius: and then: macros

1:28 headius: duby is basically a macro language as it is right now

1:28 slyphon: rather than doing instance_eval everywhere

1:28 orly?

1:28 headius: the "compiler" is really just a language transformer

1:28 slyphon: is that how you're handling the type-hints?

1:30 headius: http://github.com/headius/duby/blob/master/lib/duby/jvm/types/intrinsics.rb#L198

1:30 no, type hints are built-in; all AST nodes have an inferred_type attr that gets filled in during a late compiler cycle

1:30 but there's an example of how "each" is added to iterable

1:31 above it is a couple examples of how + is expanded

1:31 slyphon: wow, that's nuts

1:32 i somehow missed the compilers class in college

1:32 headius: me too

1:33 slyphon: hah

1:33 you're a better man than me, then

1:33 headius: which may explain duby's structure

1:33 * slyphon laughs

1:33 headius: http://github.com/headius/duby/blob/master/lib/duby/ast/type.rb#L23

1:33 there's a macro expanded in the earlier Ruby AST to Duby AST phase

1:33 essentially just replaces calls to "import" with appropriate Duby AST nodes

1:33 slyphon: wow, that's...disturbing

1:33 headius: yeah

1:34 something that was just tree transformations against a sexp would be cleaner

1:34 slyphon: you know you're not supposed to have methods that are 50 lines long

1:34 headius: I think there's an open bug for duby codebase cleanup

1:34 slyphon: hah

1:34 headius: the other committer has gone a little hog wild

1:34 slyphon: i think this is the part where you say "Patches accepted!"

1:36 headius: exactly :D

1:36 slyphon: ;)

1:37 headius: it would be nice to be able to show people macro expansion logic during a talk and have them understand it

1:37 slyphon: i kinda understand what you're doing there

1:37 i wouldn't want to try and write tests for it...

1:37 headius: it's not hard, it's just large

1:37 * slyphon nods

1:38 slyphon: that's what she said

1:38 headius: yeah, we don't have any tests for the transform phase really

1:38 slyphon: hahaha

1:38 headius: most of the tests are for the last couple phases that create actual code

1:38 they're more integration or functional tests

1:38 slyphon: you're taking the basic "atoms" of the language and poking them into place

1:38 headius: right

1:38 but I want it to be easier to do that poking and even defining new atoms

1:38 that's the essence of duby

1:39 * slyphon nods

1:39 slyphon: so you're coming to clojure for inspiration?

1:39 :)

1:40 headius: of course

1:40 I never really learned the power of sexps back in the day, but I've come to appreciate it

1:40 I just don't like the syntax :)

1:40 duby's all about kowtowing to syntax bigots

1:41 slyphon: hah

1:41 somnium: headius: if you could do something about all those 'end's while youre there youll be my hero

1:41 slyphon: somnium: no no, see, in ruby the 'end's justify the means

1:41 headius: I don't mind the ends so much

1:42 slyphon: thank you! i'll be here all week!

1:42 somnium: theyre twice as many characters as 2 parens! :)

1:42 slyphon: somnium: indeed

1:42 headius: yeah, but I know what "end" means

1:42 it means "end"

1:42 ) is half of a smiley

1:42 slyphon: i used to see all the 'end's there, but now i just see blonde, brunette, redhead

1:42 somnium: http://www.lrde.epita.fr/~didier/software/smilisp.php

1:43 headius: ) makes my code happy, but not me

1:43 somnium: it can be flexible

1:43 slyphon: the parens *really* aren't as bad as people make them out to be

1:43 esp. if you have an editor that indents stuff properly for you

1:44 somnium: I still wish ruby used python or haskell style indentation

1:44 slyphon: well...i dunno if i'd go *that* far

1:44 headius: significant whitespace is great until you start pasting code

1:44 somnium: but duby looks really promising even with the ends

1:44 slyphon: whitespace awareness FTTL

1:44 headius: then suddenly all hell breaks loos

1:44 loosing whitespace shouldn't break your code

1:44 losing

1:45 somnium: haskell mode in emacs makes it pretty effortless

1:45 slyphon: hrm

1:45 "effortless haskell"

1:45 somnium: the syntax

1:45 slyphon: that's an oxymoron

1:46 headius: if we all used emacs, everything would be better

1:46 except that we'd all be using emacs

1:46 slyphon: headius: hahahahaha

1:46 "Now you have two problems"

1:46 headius: hahah

1:46 yes

1:46 somnium: look, Im not trying to advocate the use of haskell :) (or emacs I suppose)

1:47 slyphon: i used emacs for a while, i just had so much damn fun getting my eirc scripts *just* right that i never got any work done

1:48 headius: yeah, we had a discussion at one javaone about who had the largest .emacs file

1:48 slyphon: hahaha

1:48 headius: I think nicksieger won, his was something like 120k

1:48 slyphon: oh man

1:48 jeeeeeeeeez

1:48 headius: pulled in a bunch of stuff though

1:48 twbray was a distant second

1:48 bbl

1:49 slyphon: lata

1:50 is there a clojure idiom for comparing a string to a number of regexen?

1:50 basically using a regex for dispatching

1:51 or is that a use case for multimethods?

1:53 somnium: ,(condp (fn [r s] (re-matches r s)) "bar" #"foo" :foo #"bar" :bar :FAIL)

1:53 clojurebot: :bar

1:54 slyphon: ahhh

1:54 so *that's* what condp is for

1:54 somnium: thats one way, you could also use a map of {regex fn}, mhich is a kind of handrolled multimethod I suppose

1:55 * slyphon nods

1:57 somnium: it would be cool if regexes implemented IFn and you could just call them with strings

1:57 slyphon: yeah, i was thinking of the ruby case statement

2:04 somnium: in your example, couldn't you do (condp re-matches "bar" ...)

2:04 since re-matches is a binary function?

2:05 somnium: slyphon: ah, yeah you could

2:05 slyphon: oh, cool, just wanted to make sure i was reading that right

2:05 somnium: I have this weird habit of using it with #(%1 %2) all the time to DRY-up cond statements

2:06 * slyphon nods

2:12 slyphon: the difference between re-matcher re-matches and their ilk is kind of confusing

2:16 somnium: re-matches or re-seq usually get me where I need to go

2:18 (I really like clojure but still despise reading javadocs)

2:18 * somnium must be determined not to learn to love java

2:23 slyphon: somnium: heh

2:32 defn: somnium: i dont think that ever goes away

2:32 (that feeling I mean)

2:37 somnium: hmm, anyone done anything with clojure + jambi?

2:58 defn: (def *blah* (ref []))

2:58 (dosync (alter *blah* (conj *blah* "foo")))

2:58 what am i doing wrong here?

3:04 LauJensen: defn: dont wrap (conj obj itm) in parens

3:05 defn: LauJensen: do i want to use ref-set or alter?

3:05 LauJensen: depends on the context - if its a single object, you might prefer an atom

3:06 defn: LauJensen: cool -- one more question...

3:07 I want to start a Thread/sleep for 20minutes, and then update the atom, and finally prompt for another 20minute interval

3:09 LauJensen: (still waiting for the question)

3:09 defn: (let [timer (Thread/sleep foo)] ...

3:09 i guess im just having trouble understanding how to do this functionally

3:10 Chousuke: if it involves IO, you can't.

3:10 defn: how do call timer and then dosync

3:10 Chousuke: call timer?

3:10 LauJensen: (defn job [] (Thread/sleep (* 1000 60 20)) (update-atom) (if some-condition? (recur)))

3:11 defn: run the timer i guess

3:11 Chousuke: Thread/sleep doesn't give you a timer

3:11 it just sleeps

3:11 defn: well it behaves like a timer, no?

3:11 one could use it to block for x seconds

3:11 no?

3:11 clojurebot: da da king of the road

3:12 Chousuke: yeah.

3:12 and only that.

3:12 not really. it just suspends the current thread for whatever

3:12 oops.

3:12 defn: right, which is all i need it for

3:12 Chousuke: -not really

3:12 (this is what I get for switching sentences in the middle of typing them)

3:13 LauJensen: defn: was that snippet I posted not what you were going for ?

3:14 defn: no that's great

3:14 my only question is how recur behaves there

3:14 Chousuke: just restarts the function

3:14 defn: is there an implicit loop target around the if statement, or the whole function?

3:14 okay

3:14 thanks Chousuke && LauJensen

3:15 Chousuke: recur is not just for loops, it also allows you to write tail-recursive functions

3:15 which are in effect loops, but that's another thing :P

3:15 LauJensen: recur goes back to the last point where it can restart the current body, in this case the top of the function, had there been a 'loop' it would have gone to that

3:19 defn: LauJensen: thanks

3:27 (swap! *blah* (conj @*blah* "abc")) ???

3:28 (swap! *blah* #(conj % "blah"))?

3:30 (swap! *blah* conj @*blah* "abc")?

3:30 * defn hangs his head in shame

3:32 avarus: morning

3:37 LauJensen: hehe

3:38 (swap! your-atom conj [1 2 3])

3:38 defn: that will conj a vector containing integers 1, 2, 3, to the current value of the atom

3:38 defn: ah -- i was worried i needed to include what i was conj'ing onto like i'd write a conj function normally

3:39 LauJensen: I think (reset! your-atom (conj @your-atom [1 2 3])) will produce the same result

3:42 defn: LauJensen: what if i have a (let [continue? (read-line)] (if (= continue? "y") () ()))

3:42 where does my recur go if that is in the job [] context?

3:42 LauJensen: ~doc recur

3:42 clojurebot: http://groups.google.com/group/clojure/browse_thread/thread/bba604cee3b232d9/28837d55525306d8?lnk=gst&q=recursive+macroexpand#28837d55525306d8

3:42 LauJensen: Still goes to the top

3:43 defn: hm weird

3:44 LauJensen: why?

3:44 clojurebot: why not?

5:06 caljunior: anyone around using Textmate in combination with Incanter?

5:09 avarus: I dunno what version of textmate you are running but when I tried some weeks ago it was horrible

5:10 the most confusing thing was that it didn't highlight the matching parens

5:11 I use emacs with clojure mode now

5:14 eevar2: foul lisps are spreading the corruption ;)

5:15 caljunior: I'm running version 1.5.8

5:15 avarus: well, don't waste your time with textmate

5:16 caljunior: it works reasonably well with Clojure, but I am trying to add Incanter to the mix

5:16 avarus: well? so you got it working to highlight matching parens?

5:17 caljunior: it is matching parens

5:17 avarus: and how did you do it?

5:17 caljunior: highlighting when you type or move the cursor over the,

5:18 closing paren

5:18 avarus: what bundle are you using then?

5:18 caljunior: Clojure.tmbundle

5:19 avarus: there's more than one with that name :)

5:19 caljunior: I believe it was the version forked by kek

5:19 avarus: ah ok

5:19 caljunior: not sure though

5:19 it's been a while

5:19 don't dare to update as I have it running now

5:19 :-)

5:20 avarus: hehe

5:20 caljunior: there should be an easy way to add Incanter and it's deps to the classpath

5:22 not planning on going over to emacs.

5:23 eevar2: don't, you'll never recover

5:23 avarus: I watched the peepcode video about emacs and could use basic things after half an hour

5:24 almost as good as my old friend "joe" :)

5:24 caljunior: me too

5:25 didn't need a peepcode video for textmate though

5:25 Raynes: I didn't need a video for Emacs, though.

5:25 * eevar2 used to prefer vim. now i just suck at both

5:25 caljunior: :-)

5:25 Raynes: It took me around 5 hours to be able to use Emacs, and over time I learned to do more powerful things.

5:26 I don't see the appeal of Vim.

5:26 avarus: joe > * :P

5:28 caljunior: I asked how I could change a tyre on my FIAT, not whether a Ferrari is a better car. :-)

5:28 avarus: it isn't :p

5:28 caljunior: wanna bet?

5:28 avarus: no

5:28 I think no one knows the answer to your problem

5:29 that's why :)

5:29 caljunior: that's what I concluded as well

5:29 Raynes: I'm quite sorry, it's just annoying when people whine about Emacs. :|

5:29 caljunior: thanks anyway

5:29 Raynes: Because they do it so often!

5:29 avarus: who whines in here?

5:30 Raynes: avarus: There is hardly ever any whining in here, fortunately.

5:31 avarus: :>

5:42 zab: Ultra noob question. How would I call a function from within a file inside a REPL?

5:42 Whenever I try (use 'name) it fails because that file requires other files to be loaded

5:51 esj: zab: put the appropriate (use ) clauses into the file you're loading

5:53 zab: yeah I have, but whenever I (use 'file) from the REPL, it still complains with java.lang.NoClassDefFoundError: Could not initialize class

5:53 and I'm fairly sure all files needed are in my classpath

5:54 esj: try load 'em individually from the repl

5:54 to find the missing one ?

5:54 AWizzArd: zab: (System/getProperty "java.class.path")

5:55 zab: ahh that's something I wanted to do but didn't know how

5:57 If the class I want is in a JAR file, how do I know which namespace to (use ')? Do I have to look at the source?

5:58 AWizzArd: zab: the documentation will explain it, or otherwise you can simply look at the .jar file with your favourite archive manager and loop up the paths yourself.

5:59 zab: k

5:59 powr-toc: Why does evaluating (promise) at the repl block the repl? Is there an implicit deref?

6:00 I was thinking the call toString might do the deref but, (. (promise) toString) returns fine

6:00 esj: because the promise blocks the repl thread

6:00 oh, sorry, missed you question

6:01 yeah I think the repl tries to pretty print the deref

6:02 powr-toc: Was just confused by the fact the repl was derefing the promise but a call like (when (promise) (prn "foo")) obviously doesn't

6:03 i.e. (promise) has a value when it's not derefed... but I can't see that value at the repl

6:07 Presumably the REPL deref's all IDeref's? What's the rationale for this?

6:08 esj: i think its just the pretty printing

6:09 so > (def a (atom 3), then > a will result in <#atom:xxxxxx : 3>

6:10 and i seem to recall it does the same with futures and promises

6:12 powr-toc: what method does the pretty print call?

6:12 LauJensen: side question: Wouldnt that be 'which' method ?

6:12 esj: Lau: I think so

6:13 powr-toc: no idea

6:13 LauJensen: Even on official websites, like news sites etc, I see people replace 'which' with 'what' and I have no idea why

6:13 powr-toc: Lau: yes it should

6:13 I was assuming that the deref was happening inside toString... but that's not the case

6:15 LauJensen: the only places where a reference type is implicitly deferenced, is when calling swap, reset!, alter, etc

6:20 lessthantristan: anyone know if the result of (/ 1 (/ -1 2)) being a ratio -2/1 the desired behaviour or a bug? (using 1.1.x branch)

6:21 powr-toc: LauJensen: so how come (promise) at the REPL blocks?

6:21 esj: lessthantristan: how is is this different from what you expected ?

6:22 LauJensen: lessthantristan: I'd say desired behaviour :)

6:22 powr-toc: no idea

6:23 lessthantristan: esj: i guess i expect it to reduce the ratio back to the integer -2 rather than leaving it as a ratio. it doesn't effect calculations, but it makes the output look weird :)

6:23 Raynes: powr-toc: Maybe it's promising to block the REPL, and is being sincere?

6:23 esj: lessthantristan: Clojure promotes to Ratio and stays there to ensure numerical precision

6:24 fogus and chouser's book has a good section on this

6:24 Raynes: Speaking of that, they should write faster.

6:25 lessthantristan: ok cool. maybe i should have a read. I was just taken back a bit when my code printed out a heap of 0/1 results :P

6:25 esj: for quality like that, i'm willing to wait (albeit impatiently)

6:26 Raynes: esj: Indeed.

6:26 esj: lessthantristan: i can sympathise

6:27 powr-toc: hmm... I'm confused, there's no derefs in main.clj

6:27 esj: it must do it though, because you see the value in the repl

6:28 LauJensen: can you run a blocking example on clojurebot?

6:29 esj: ,(promise)

6:29 clojurebot: Execution Timed Out

6:29 esj: sorry cb, Lau made me do it

6:30 LauJensen: ~source promise

6:30 esj: question: if I grab clojure and contrib 1.2 from github and compile em. What do I need to do to get clojure into my local maven repo so I can feed it to lein ?

6:31 i'm having issues trying to use 1.2, which is req'd by the latest Incanter

6:31 AWizzArd: ,(Thread/sleep 1234)

6:31 clojurebot: nil

6:31 esj: contrib goes right right with a >mvn install

6:31 but clojure is compiled with ant

6:32 how do I make all the poms etc ?

6:32 alternatively, how do I get a matched pair of clojure / contrib using clojars and save myself the suffering

6:33 Raynes: 1.2.0-master-SNAPSHOT

6:33 esj: for both ?

6:33 Raynes: Mhm.

6:33 esj: lemme give that a spin

6:33 Raynes: It's what I use for all my projects. They are compatible.

6:35 powr-toc: Ok, I'm trying to decipher this http://clj-me.cgrand.net/2009/11/18/are-pipe-dreams-made-of-promises/ and can't figure out why p is set to (second @promises)

6:36 because we deliver the value to a which is the cell prior to p in the lazy-seq

6:36 esj: Raynes: are you compiling your own leiningen ?

6:37 with 1.2.0 ?

6:37 Raynes: No.

6:37 esj: rats

6:37 Raynes: I just used lein self-install

6:37 esj: because using 1.2.0-master-SNAPSHOT for both results in my favourite

6:37 at clojure.lang.RestFn.applyTo(RestFn.java:147)

6:37 error

6:37 Raynes: That's odd.

6:37 It works fine for me. :\

6:37 esj: which usually means clojure / contrib have got out of sync

6:38 powr-toc: ahh wait, I thin I get it... the call to (swap! promises next) has shifted the seq along

6:38 Raynes: It's probably something to do with the fact that there hasn't been a new 1.2.0-master-SNAPSHOT build for like 2 months...

6:39 Yeah, that's it.

6:39 There has been a new clojure build, but not a new contrib build.

6:39 esj: aaah

6:39 Raynes: Who manages these things anyways? :\

6:39 esj: i dunno

6:39 ok, I think I can work around that

6:40 grab the clojure snapshot, build the contrib myself and mvn install that....

6:40 lets see....

6:43 LauJensen: Haha - Just got an email from 'Guusjevannoorden' subject: "CONGRATULATIONS!!!" - Apperantly my email has won quite a bit of money :)

6:44 esj: congratulations - i'm still waiting for mine

6:44 any day now...

6:44 Raynes: I get those every day.

6:45 LauJensen: I think I'll make a spamfilter in Clojure which is EVEN more effective than Paul Grahams (if (.contains (first (line-seq email)) "We are a china based")) (delete email))

6:45 Raynes: Hah.

6:48 esj: well.... that's just ugly. Some bits of lein work with 1.2.0 master etc, but not all. So I can make it start lein-repl at 1.2.0 which is what I'm after to get at Incanter, but have to use lein-stable for deps, clean etc. Life could be worse ;)

6:49 tomoj: hmm

6:49 deps worked for me with 1.2.0

6:49 oh, you mean lein 1.2.0?

6:49 LauJensen: hehe - esj could you prefix each line with "Dear Diary" just for context ? :)

6:50 tomoj: I'm confused

6:50 esj: but then I'd need a nice pink leather skin for my IRC window

6:51 tomoj: using lein built off clojure+contrib 1.2.0 crashes on lein clean and lein deps, but not lein repl

6:51 doubtless i'm doing something thunderously stupid and would love to hear what it is

6:53 tomoj: but what was the "have to use lein-stable" thing

6:53 the latest stable lein release works with 1.2.0, but master lein doesn't?

6:54 esj: oh sorry. lein-stable referers to the leiningen stable release.

6:54 so lein-stable is build on 1.1.0 or whatnot

6:55 tomoj: oh, hmm

6:55 I'd never considered the clojure version that lein uses, why does it matter?

6:55 esj: because lein repl uses that version

6:55 tomoj: oh

6:55 I only use lein swank, I guess that's immune

6:56 wonder why lein repl doesn't do the same thing as lein swank

6:56 esj: dunno, i've still not got my head around the slime / swank thing

6:57 tomoj: so you use lein swakn, and then slime connect from emacs ?

6:57 tomoj: yeah

6:58 I plan to make a screencast about it

6:58 esj: how does this differ from swank-clojure-project ?

6:58 tomoj: not much

6:59 except that leiningen handles setting up the classpath rather than swank-clojure

6:59 so, e.g., leiningen adds resources/ while I believe swank-clojure-project doesn't

7:00 also, lein swank can be used on a remote server, and you can forward the port over ssh to get a remote slime repl

7:01 esj: ok, I got tied up by the classpath with lein swank before, but I'll try again.

7:01 tomoj: I had issues before with the classpath as well (src/ wasn't added)

7:01 but now it seems to be resolved

7:02 esj: perfect, that's exactly what I had.

7:07 tomoj: you're right - they've fixed it :)

7:11 AWizzArd: Does anyone of you have a fast SSD?

7:11 edbond: AWizzArd: I have ssd, not sure if its fast. :)

7:11 AWizzArd: Do you have 2 minutes to try something?

7:12 http://pastie.org/838378

7:12 Please tell me how fast you are for: (time (dotimes [i 1000] (schreib1 (str "Line " i))))

7:12 And for schreib2 the same

7:13 Maybe for schreib2 you begin with dotimes [i 100], because that could already take 2 secs

7:13 But perhaps your SSD is so fast that [i 1000] will be ok

7:14 edbond: AWizzArd: should i copy that to file? I have user/fos is unbound in repl.

7:15 AWizzArd: You can copy it into your repl

7:15 _ato: ~40 ms for 1

7:15 clojurebot: mea culpa!

7:15 AWizzArd: _ato: yes, that is very possible, because this will only write into some caches

7:16 _ato: 2 varies a lot but is around 2.2 to 2.7 seconds

7:16 on an OCZ Vertex SSD in a generation 2 macbook running linux

7:16 on ext3

7:20 edbond: first varies from 27msec to 400, second is about 5500msec

7:21 128Gb samsung, ubuntu 9.10, ext4

7:21 noop scheduler

7:26 _ato: I'm using the cfq schedular and the drive is 64 GB

7:31 AWizzArd: I use a simple IDE disk, Win XP, 32 Bit, Java 6 Update 18. Schreib 1 can do 10k writes in 200 msecs. But Schreib2 can do only 55 Writes within one second.

7:32 _ato: schreib 2 varies you say. Is that for [i 100]?

7:32 edbond: thanks for testing. Your 5.5 seconds for schreib2, was that with a [i 1000]?

7:33 _ato: for 1000

7:33 edbond: yes

7:33 _ato: for 100 it varies around 150-250

7:34 AWizzArd: cypher23 explained that for example Apple only waits on fsync until the data is in the HD cache. It does not block until the HD has actually written the data. So on Leopard the .sync version runs about as fast as schreib1.

7:34 edbond: I got about 550 for i 100

7:35 AWizzArd: So, on your SSDs you can do 200+ writes per second, while I can do only 50 on my IDE disk.

7:35 Thanks for testing guys.

7:37 _ato: no worries. SSDs make a massive difference on many workloads

7:39 we run lucene indexes off them at work, they're many times faster than even fast SCSI disks

7:42 Chousuke: http://gist.github.com/312137 <- I implemented monads using protocols. :P

7:42 I suspect there may be some failure in that implementation though

7:42 but it seems to work

7:50 boojum: is there a way to disable sequence chunking?

7:51 Chousuke: boojum: http://paste.lisp.org/display/90536 here's one

7:52 boojum: Chousuke: thanks

7:54 cemerick: is the lisppaste8 bot permanently out of commission?

7:55 anyway...

7:55 Feedback welcome: agent-based finite state machines: http://paste.lisp.org/display/95483

7:56 nothing particularly fancy, but I couldn't find anything similar out there.

7:58 avarus: uhoh... in the following source http://paste.lisp.org/display/95484 I can't call the defn link from this one http://paste.lisp.org/display/95485 <-- what's wrong? it says "No such var: ws/link"

7:58 cemerick: Chousuke: that's a riot :-D

7:59 boojum: wait, reify is not in 1.1

8:00 Chousuke: boojum: proxy will probably work too

8:01 just won't be as fast.

8:01 but I suppose you're not looking for speed if you're explicitly disabling chunking

8:02 AWizzArd: Chousuke: do you use the official 1.1 release?

8:02 Chousuke: I tend to use master

8:02 AWizzArd: ok, good to know that I am not alone :)

8:03 Chousuke: I wonder if I can write a monad transformer using protocols too

8:04 AWizzArd: Would they serve a real purpose for you, or is that just of theoretical interest, to implement such a thing?

8:04 Chousuke: just playing around

8:08 LauJensen: cemerick: very clean implementation!

8:09 cemerick: LauJensen: Thanks. I don't suspect I'll add much -- probably just have the dispatcher clean up ::stop states and return them to a runnable state.

8:09 I was thinking of trying to verify the state transitions, but allowing arbitrary fns to determine next states makes that a little rough.

8:11 I suppose I could force the next-state-fns to be pairs of conditionals and next states that would get dropped into a cond, but I'm really not that motivated.

8:15 avarus: how to tell the bot to show me something regarding "require" :)?

8:17 http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/require found it

8:21 mhh...what am I doing wrong...

8:21 cemerick: this is unfortunate:

8:21 ,(assoc {} :foo 5 :bar)

8:21 clojurebot: {:bar nil, :foo 5}

8:22 AWizzArd: oh indeed

8:28 chouser: I suppose you'd prefer an exception?

8:30 AWizzArd: yes

8:30 ,(hash-map :foo 5 :bar)

8:30 clojurebot: java.lang.IllegalArgumentException: No value supplied for key: :bar

8:33 headius: technomancy|away: I thought you had a bouncing ball example of Duby

8:33 was I mistaken?

8:33 tomoj: avarus: hmm, looks ok to me

8:34 except, put the requires in the ns

8:34 (ns foo (:use bar) (:require (baz [bim :as b])))

8:34 it should work your way too, though...

8:34 cemerick: chouser: it seems like too likely of a typo to not catch

8:35 chouser: cemerick: yeah, I can see that

8:40 avarus: tomoj: perhaps I am returning the vector the wrong way?

8:41 tomoj: well, yeah

8:41 but that shouldn't cause "no such var"

8:43 oh, wait

8:43 you have a circular dependency, I believe

8:43 admin-header requires websites, and websites requires admin-header

8:49 cemerick: ha! Of course, await doesn't do one any good if you're trying to wait for a send that occurs within an already-running send. :-P

9:00 avarus: tomoj: oh

9:02 so this is not allowed I guess

9:02 k, I put the "helper" function in the helper.clj then :)

9:04 yep, did the trick

9:04 thanks tomoj

9:05 goal achieved: learned something new today

9:06 cemerick: am I correct in thinking that there is no support for namespaced keywords when doing map destructuring via :keys?

9:09 ohpauleez: has anyone tried to use higher level networking libraries in a clojure project, specifically JXTA?

9:10 nvm, I just dug up some articles

9:40 jcromartie: what is mapcat for?

9:41 AWizzArd: ,(map val {:a #{10 20 30}, :b [1 2 3]})

9:41 clojurebot: (#{10 20 30} [1 2 3])

9:41 AWizzArd: ,(mapcat val {:a #{10 20 30}, :b [1 2 3]})

9:41 clojurebot: (10 20 30 1 2 3)

9:41 jcromartie: ah, so it kind of flattens the result

9:41 AWizzArd: When your map fn returns a collection, then map returns a collection of collections, and.. yes

9:41 jcromartie: by concat'ing each one together

9:42 the stuff I was trying didn't make that too clear

9:43 I guess it sort of works around not having multiple return values

9:45 AWizzArd: mapcat or the thing you try to do?

9:45 jcromartie: the Enlive source reads nicely

9:46 I was just fiddling with mapcat and coming back with results that didn't really illustrate a good use for it

9:46 but now I understand

9:46 AWizzArd: Indeed, cgrand writes hq code.

9:53 jcromartie: yeah reading code is something I should do more often

9:54 I didn't realize that (:foo x bar) translates to (get x :foo bar)

9:54 chouser: rhickey: would direct linking of vars allow calls to gen-class methods to be fully inlined? that is, same performance as reify?

9:56 stuartsierra: At what scale does pmap become worthwhile?

9:58 chouser: stuartsierra: it has to do with the amount of work per item, not the size of the seq

9:58 stuartsierra: Yeah, I was coming to that conclusion.

9:58 chouser: ,(time (vec (map #(do (Thread/sleep 100) (inc %)) [1 2])))

9:58 clojurebot: [2 3]

9:58 "Elapsed time: 202.517 msecs"

9:58 chouser: ,(time (vec (pmap #(do (Thread/sleep 100) (inc %)) [1 2])))

9:58 clojurebot: [2 3]

9:58 "Elapsed time: 102.413 msecs"

9:58 stuartsierra: got it

9:59 chouser: that makes it look like an op that take more than a msec or two would benefit

10:01 caljunior: another attempt: anyone using TextMate with Incanter? what would be the most simple way to get Incanter and it's deps playing nice with clojure.tmbundle?

10:02 chouser: ,(doseq [m [map pmap]] (time (vec (m (fn [x] (Thread/sleep 1)) (range 10)))))

10:02 rhickey: chouser: nope

10:02 clojurebot: "Elapsed time: 19.663 msecs" "Elapsed time: 3.833 msecs"

10:02 chouser: even at just 1 msec, pmap still wins. much below that it doesn't.

10:03 AWizzArd: how about this vmap?

10:03 chouser: rhickey: hm, ok.

10:03 stuartsierra: chouser: Yeah, at 0.1 msec, pmap takes longer

10:03 AWizzArd: In the PAR branch

10:03 rhickey: genclass is designed to go through the vars in order to support dynamic dev

10:03 AWizzArd: I won't use pmap before my fn runs longer than 1-2 msecs

10:03 chouser: Yeah, I understand. I'm trying to figure out a good way to generate a bunch of classes and provide factory methods for them to Java

10:04 rhickey: chouser: things deftype can't do?

10:06 chouser: deftype could do it, as could reify -- I need some pre-calculated fields, so I was leaning toward reify.

10:06 but either way, I need a Java API -- something AOT compiled to for Java to call.

10:06 rhickey: chouser: pre-calculated meaning constants?

10:07 chouser: yes -- they would be static final fields if I were hand-writing the code in Java

10:07 rhickey: AOT-compiled deftypes have stably named types and ctors

10:07 chouser: yes, but the ctors would be wrong

10:08 rhickey: so this begs for gen-statics or gen-factory or something

10:08 chouser: (gen-proto-stub Foo) then from Java something like ProtoAPI.newFooStub(c)

10:08 stuartsierra: How about defconst?

10:09 chouser: the instance created by that has methods that need access to some constants computed by gen-proto-stub at compile time

10:09 rhickey: (gen-statics Classname sig clojure-fn sig clojure-fn ...)

10:09 stuartsierra: yes, defconst is a todo

10:09 stuartsierra: yay

10:11 rhickey: gen-statics would have no code-gen needs other than arg/return conversion

10:12 could even do 'direct-linking' kind of stuff

10:12 chouser: rhickey: yeah, gen-statics would do it. I don't think gen-class's var lookup is deal-breaker here, just trying to make sure understand my options so I don't design an API compatible with the fastest possible implementation.

10:13 (gen-proto-stubs Foo Bar Baz ...) ; if I want a single class with multiple factory fns...

10:14 hm. I don't -- too closed. I guess for each instance type I want one class with a single factory method.

10:15 rhickey: but if you had an arbitrary ctor sig would you need the factory?

10:16 chouser: not if I also had static fields or the methods were closures or something.

10:16 rhickey: chouser: what about defconst for those?

10:18 Chousuke: rhickey: I wrote a couple more revisions of the gen-iter macro yesterday http://gist.github.com/311629 and http://gist.github.com/311647 (this one is missing a name for the mapx iter)

10:18 Designing good macros is interesting work :P

10:18 chouser: hm... maybe I don't need statics at all. Maybe I can generate method bodies with constants right there in them.

10:19 defconst would probably work, though their names would be long.

10:20 rhickey: these constants are of what types?

10:20 chouser: ints

10:20 rhickey: we really need to unify the semantics of boxed/primitive integers

10:20 rys: hmm, I seem to remember there was a presentation some moons ago by you, rhickey, where you explained with a nice diagram how PersistentHashMap tries work, but I can't find it. Anyone got a link?

10:23 chouser: rys: this isn't exactly it, but may have what you want: http://blog.higher-order.net/2009/09/08/understanding-clojures-persistenthashmap-deftwice/

10:23 remleduff: Hi everyone! Has anyone happened to have set up an Amazon Machine Image for running a clojure dev environment under EC2?

10:23 chouser: though ... I'm not sure that's accurate anymore

10:23 are LeafNodes gone now?

10:25 Chousuke: I had an idea for "code mixins" for reify and deftype yesterday. Something like (define-mixin foo :as this Iface (method [] ..) (method2 [args]) Iface2 ...) and then reify could have a :mixin [foo bar] option, and then merge the code data structure from foo, bar and its own body before the final evaluation. The biggest problem I could see was making sure that the this symbol from

10:25 the mixins is replaced with whatever the reify invocation uses (or with a gensym)

10:25 chouser: rhickey: gen-statics would produce a single class with only static methods?

10:25 rhickey: chouser: yeah

10:25 Chousuke: this should be implementable using only macros so maybe I'll throw something together. I'm not sure if there's an actual use case for these though.

10:26 maybe not enough to justify the complexity

10:45 stuartsierra: Is there currently a function to force non-chunked sequences?

10:45 I.e., to make a chunked sequence into a non-chunked sequence?

10:47 Chousuke: http://paste.lisp.org/display/90536

10:47 chouser: http://paste.lisp.org/display/93650

10:48 _fogus_ updated that second one for more recent versions of reify

10:48 stuartsierra: Ok. I just made an unchunked-map, http://paste.lisp.org/+21OJ

10:49 chouser: out of curiosity, what did you need it for?

10:50 stuartsierra: In lazytest, I wanted a map that was truly lazy, so that I could verify that my test runner was also truly lazy.

11:05 brandonw: are futures basically just very simple agents?

11:06 crowbar7: What would be the best way to be able to use aspell with Clojure?

11:07 clojurebot:,(*1 2 3 4)

11:07 clojurebot: 5 (for large values of 2)

11:07 crowbar7: so "," is the keyword for code. neat-o

11:07 clojurebot: help

11:07 clojurebot: http://www.khanacademy.org/

11:19 ordnungswidrig: crowbar7: I just found http://jaspell.sourceforge.net/javadocs/pt/tumba/spell/Aspell.html

11:23 crowbar7: ordnungswidrig: Thanks, I found that already just wondering if there was something built into clojure.

12:18 ieure: So I have an infinite lazy-seq of timestamps. And I want an infinite lazy-seq of deltas between timestamps. I’m really not sure how to make this happen, can someone give me some guidance?

12:18 If I was using Python, I’d do something like zip the seq with the rest of the seq, then map subtract across the pairs.

12:18 stuartsierra: ieure: (map - (partition 2 1 timestamps))

12:19 Even simpler: (map - timestamps (rest timestamps))

12:19 rhickey: yes, please

12:20 stuartsierra: my first example was wrang

12:20 *wrong

12:20 ieure: stuartsierra, Aha, I did not know that map could map across seqs like that. Handy, and it explains why there’s no zip.

12:21 stuartsierra: yep

12:43 brandonw: are futures basically just very simple agents?

12:44 stuartsierra: not really

12:45 Both run in a separate thread.

12:45 But deref of a future can block; deref on an agent never blocks.

13:15 brandonw: stuartsierra: okay, thanks

13:16 so, similar use case in terms of starting something asynchronously, but getting the result (if there is one) of the async operation is different between the future and agent

13:17 cemerick: I don't think the use cases are similar at all.

13:17 I'd say the use cases of delays and futures are very similar, with the latter being asynchronous.

13:19 rhickey: right, an agent is an identity with various states over time. delays/futures are simply pending computations of a single value

13:23 chouser: http://www.indeed.com/jobtrends?q=Java%2C+Python%2C+clojure&l=&relative=1

13:24 jcromartie: holy crap

13:24 nice

13:24 chouser: if that surprises you, note that's "percentage growth", not absolute terms at all

13:24 jcromartie: yes

13:24 ieure: Interesting.

13:24 brandonw: is that accurate?

13:24 holy crap

13:24 jcromartie: 6000% over 0

13:24 :)

13:24 chouser: click "absolute" for something closer to what you'd expect

13:25 brandonw: still though

13:25 it wouldn't take long at that growth rate..

13:25 jcromartie: hey what would you call a function that takes this: {:foo.bar 1, :foo.bat 2, :zort 3} and returns {:foo {:bar 1, :bat 2}, :zort 3}

13:25 chouser: a parser

13:25 :-)

13:25 jcromartie: brandonw: 6000% over the prior level of Clojure jobs is not a lot of jobs

13:25 cemerick: brandonw: that's a growth rate with zero as a baseline

13:26 chouser: nice :-)

13:26 jcromartie: chouser: a parser, really?

13:26 chouser: well that's one of the things it's doing, right? extracting meaning from a string

13:27 jcromartie: the intended use is taking query/form params and turning it into a more complex map

13:28 brandonw: well, given that clojure is very young still, the inital burst of popularity probably accounts for most of the spike

13:28 * ieure smacks his forehead

13:29 brandonw: still, that is some crazy growth. i checked out scala and it has gotten extremely popular, especially with foursquare and twitter giving it free advertisting. it still has only 1/6th of the growth as clojure

13:29 ieure: Scala still has too much Java for my taste.

13:29 jcromartie: oh Foursquare is using it?

13:29 brandonw: yep

13:29 jcromartie: we're building a location based service in Clojure :) so there

13:29 brandonw: lift too, not jus the backend

13:29 jcromartie: we've got a sinatra frontend at the moment but I'd like to make it compojure

13:30 cemerick: actually, this is quite a bit more interesting: http://www.indeed.com/jobtrends?q=clojure%2C+scala&l=

13:30 chouser: yes

13:30 cemerick: ~ 50% of scala market

13:30 clojurebot: certainly petrus

13:31 cemerick: but this makes me question the entire dataset: http://www.indeed.com/jobtrends?q=clojure%2C+scala%2C+jruby&l=

13:31 chouser: the common timing of the uptick is very interesting. What happened last summer?

13:31 jcromartie: layoffs

13:31 ?

13:31 or hiring

13:31 of course

13:31 startups

13:31 _fogus_: cemerick: Because solutions require 50% of the code compared to Scala. ;-)

13:32 chouser: heh

13:32 cemerick: stellear

13:32 stellar

13:32 that is

13:32 _fogus_: and here I thought you were mostly agnostic towards scala

13:32 chouser: good point -- if you can hire half the developers to get work done at the same rate, the job market is smaller.

13:32 _fogus_: cemerick: Oh I am... but truth is truth

13:32 chouser: Rich, what have you done!?

13:33 cemerick: chouser: we are all in business to eliminate jobs...should happen to us every now and then.

13:33 chouser: hm, good point

13:34 * _fogus_ realizes that truth is relative and entirely a man-made construct

13:34 cemerick: or, I should say, most interesting software exists to eliminate jobs.

13:34 chouser: I'll just try to stay on top of things so I don't have to find work painting houses or something.

13:34 hiredman:

13:34 chouser: hiredman: no offense!

13:34 * _fogus_ decides not to mention plans for the paint-o-matic 5000

13:34 hiredman: :P

13:35 chouser: :-)

13:35 http://www.indeed.com/jobtrends?q=clojure,twitter

13:36 jcromartie: what the hell

13:36 chouser: http://www.indeed.com/jobtrends?q=clojure,painting

13:36 cemerick: _fogus_: sexprs are a categorical imperative

13:36 jcromartie: what's a twitter job?

13:36 ieure: A job at Twitter.

13:36 Those dudes are hiring like crazy.

13:36 chouser: jcromartie: I assume any job posting that includes the word "twitter"

13:36 jcromartie: really?

13:36 chouser: well yeah

13:37 I mean in a practical sense

13:37 _fogus_: gaining on the muffins market http://www.indeed.com/jobtrends?q=clojure%2Cmuffins&l=

13:37 ieure: jcromartie, We’ve lost a number of candidates to Twitter.

13:37 chouser: social advertising jobs, integration jobs, etc.

13:37 jcromartie: of course everything we are doing involves Twitter now, but I wouldn't call it a Twitter job

13:37 all you have to know is a few POST methods

13:37 LauJensen: http://www.indeed.com/jobtrends?q=clojure,drinking&l=

13:37 Still more money to be made drinking :(

13:37 ieure: jcromartie, Their APIs are simple, but that’s not really true.

13:38 jcromartie: well I exaggerate a bit

13:38 ieure: I wrote an app to stream the Twitter firehose into HDFS… In Clojure. :)

13:38 jcromartie: I have spent a lot of time with their APIs

13:38 :)

13:38 ieure: nozzle, right?

13:38 chouser: LauJensen: that's hilarious.

13:38 LauJensen: chouser: how so? You thirsty ?

13:38 ieure: jcromartie, No, I had no idea that existed.

13:38 chouser: but looks like lots of "drinking water sales" and "drinking water treatment specialist"

13:39 ieure: jcromartie, http://github.com/ieure/Twidoop is what I wrote.

13:39 licoresse: ,(take 10 (iterate str 3))

13:39 clojurebot: (3 "3" "3" "3" "3" "3" "3" "3" "3" "3")

13:39 licoresse: why is the first different?

13:39 LauJensen: ,(Math/pow 10 999)

13:39 clojurebot: Infinity

13:39 LauJensen: Can I work with the actual number, instead of 'Infinity' ?

13:40 stuartsierra: LauJensen: use BigIntegers

13:40 _fogus_: Clojure overtakes the market for crap http://www.indeed.com/jobtrends?q=clojure%2Ccrap&l=

13:40 ohpauleez: licoresse: the first is the arg you passed in

13:40 ieure: licoresse, Because iterate returns x (f x) (f (f x)) etc.

13:41 licoresse: I need to chew on that...

13:41 ohpauleez: (rest (take 11 (iterate str 3)))

13:41 ieure: licoresse, You pass 3 in. 3 is an int. "3" is a string.

13:41 ohpauleez: ,(doc iterate)

13:41 clojurebot: "([f x]); Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects"

13:41 ieure: Right. And x is 3. And the second is (f x) -> (str x) -> "3".

13:42 licoresse: ok

13:42 and I got 9 "3"

13:42 ohpauleez: you don' want to use iterate here though

13:42 LauJensen: stuartsierra: ah yes - Why wouldnt that be the default/default coersion ?

13:42 ieure: licoresse, ohpauleez, Right, just use (repeat "3")

13:42 licoresse: ohpauleez: I see that. Just needed to understand

13:42 ohpauleez: right

13:43 (take 10 (repeat "3"))

13:43 licoresse: you're so helpful! thanks!

13:45 jasapp: maybe someone did this already:

13:45 http://www.indeed.com/jobtrends?q=clojure%2Clisp&l=

13:45 I thought that was really cool

13:46 stuartsierra: LauJensen: Math/pow is a Java method, returns a double

13:59 jcromartie: hmm, I guess you can't make middleware that operates on params in compojure?

13:59 or at least I can't just apply it to my main compiled route

13:59 hiredman: why not?

14:00 I'm not entirely familar with it, but isn't it just function composition?

14:00 jcromartie: there are no params at the point where the middleware is run

14:01 that is I have a big defroutes that combines all of my routes, and then I decorate that with this middleware, and when the middleware runs :params is nil

14:02 hiredman: interesting

14:05 LauJensen: Anyone here who speaks fluently Ruby ?

14:05 stuartsierra: yes

14:06 lancepantz: true

14:06 * jcromartie sorta

14:07 jcromartie: what's the best way to do several update-in on a map?

14:07 hiredman: I guess you have to write your own defroutes-with-middleware macro

14:07 jcromartie: something like that

14:07 hiredman: reduce

14:08 ,(reduce #(update-in %1 (first %2) (second %2)) {:a 1} {[:a] inc})

14:08 clojurebot: {:a 2}

14:09 jcromartie: -> seems to work for more varied situations

14:11 I think I could stand to write some kind of "how to read Clojure" or something to help myself and hopefully other noobs

14:12 because it took me a while to get -> and ->> and such

14:12 but now I kind of read them in English

14:14 ohpauleez: jcromartie: http://java.ociweb.com/mark/clojure/article.html

14:14 AWizzArd: jcromartie: they are very helpful, aren’t they?

14:16 defn: jcromartie: -> was an idiom i was so well acquainted with i had trouble believing it worked the way it did

14:16 outside of clojure I mean

14:20 jcromartie: defn: is it available in other lisps?

14:21 the-kenny: jcromartie: Should be possible to implement it in every other lisp which supports lisp-mactos

14:21 s/mactos/macros/

14:21 jcromartie: you say you were so well acquainted with it

14:22 I assume that means it's in other lisps?

14:22 the-kenny: I'm not sure if it's defined in the hyperspec for common lisp, but it's easy to implement

14:22 (yes it should be in other lisps too)

14:23 AWizzArd: in CL there is no ->

14:23 defn: jcromartie: im sorry -- what i meant was i was used to that order of computation

14:23 and that i felt comfortable with -> as soon as i realized that's all it was

14:23 i was initally quite confused by it

14:23 jcromartie: ah I see

14:24 the-kenny: AWizzArd: But it's easy to implement it. It just isn't defined in the hyperspec

14:24 chouser: roughly similar to foo().bar(5).baz(1,2) in C-ish syntax

14:24 defn: it clicked once i saw ..

14:25 AWizzArd: the-kenny: right

14:28 the-kenny: Is there a name for "->"? It's impossible to search for "->" on google

14:29 (If there isn't a name, we should give it one)

14:29 chouser: no consistently used name

14:30 ordnungswidrig: btw. can bing search for special characters?

14:31 ohpauleez: the-kenny: I call it threading an expression, but someone else used a real good term for it just the other day

14:32 ordnungswidrig: perhaps the haskell boys have a name for it

14:32 LauJensen: I'm wondering about the Chunky seqs. Is a (lazy-cat) sequence chunked, and how is the chunk size determined?

14:32 chouser: well, it's a little like composition of partials, but it's a macro not a function so it breaks down in the details.

14:33 lancepantz: the-kenny: it's called a thread

14:33 the-kenny: lancepantz: ok, thanks :)

14:33 lancepantz: in 'programming clojure' that is

14:34 rhickey: is their paredit magic for turning (a (b ...)) into (b (a ...)) ?

14:34 chouser: LauJensen: lazy-cat will return a chunked seq for any of its args that are chunked seqs, and the chunks are passed through unchanged in size or any other way.

14:34 rhickey: there

14:35 LauJensen: chouser: As I understood the chunky principle, if I realize 50 items, 75 could in fact be realized under the hood - its the number of calculations I'm looking for

14:35 chouser: LauJensen: yeah, and I'm saying "it depends" :-)

14:36 LauJensen: chouser: yeah, and I'm saying, on what ?

14:36 chouser: and I told you, on the size of the chunks of the seqs you give it.

14:36 (lazy-cat foo bar)

14:37 if foo is un-chunked, and bar is a chunked seq with all chunks of size 32, then lazy-cat will return a seq that is unchunked until you exhaust foo, then chunks of size 32 after that.

14:37 LauJensen: ok, thanks, now go write a book :)

14:42 chouser: But since you mention chunks, you saw that rhickey has exploratory code for something that could replace chunked seqs entirely?

14:42 * chouser looks sorrowfully at the source of 'for', but isn't really rooting for its survival.

14:43 LauJensen: chouser: No I didn't - Where is it ?

14:44 chouser: http://gist.github.com/306174

14:50 LauJensen: Thanks

14:53 a_strange_guy: chouser: that iter stuff looks wierd but interesting

14:53 chouser: I think that's accurate. :-)

14:53 a_strange_guy: oh damn, that not yours ^^

14:54 chouser: heh, nope. definitely not

14:55 a_strange_guy: the one thing that i dont understand is why one needs a deftype

14:55 for Range

14:55 rhickey: a_strange_guy: for the mutable

14:55 a_strange_guy: hmm

14:55 rhickey: no mutables in reify yet

14:55 a_strange_guy: wouldn't a closed over atom not work?

14:56 or is that too slow

14:57 brandonw: lancepantz: where in programming clojure is -> mentioned? I didn't catch it on the first read through, although I might have missed it since it (also) uses -> to mean the result of an expression being evaluated

14:58 chouser: hm, not in the index, though .. is.

14:59 a_strange_guy: I believe an atom would work fine for Range, though as you note the speed would be different

15:00 lancepantz: brandonw: yeah, i don't see it in the index either, i may have been mistaken

15:02 it's in the core api docs though, http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/-%3E

15:02 brandonw: yep

15:02 speaking of the core api docs

15:02 and clojure docs in general

15:03 i found clojure.org/transients somehow, but i don't know if it is actually linked from anything else

15:03 lancepantz: i guess i just remember it being called the thread macro :/

15:04 a_strange_guy: hmm, i wonder if a dead-simple reference type would be as fast as a field

15:05 like a ref rom ML

15:05 with no concurrency semantics whatsoever

15:06 chouser: ,(.val (clojure.lang.Box. 5))

15:06 clojurebot: 5

15:07 chouser: ,(let [box (clojure.lang.Box. 5)] (set! (.val box) 10) (.val box))

15:07 LauJensen: chouser: I dont think that code explains itself very well - How does it replace chunked seqs?

15:07 clojurebot: 10

15:08 a_strange_guy: chouser: nice (of course it isn't xD ), is that used anywhere?

15:08 chouser: LauJensen: it implements some of the seq library functions (takez, reducex, etc.) in a way that allows a chain of seq operations to run faster than similar chunked seqs.

15:09 LauJensen: since the only point of chunked was performace, this is a potential replacement.

15:09 LauJensen: What makes it faster ?

15:09 a_strange_guy: LauJensen: it doesn't allocate

15:09 Chousuke: the seq actually doesn't exist

15:10 chouser: a_strange_guy: well, it's not a reference type. ...but yes, it's used in a few places internally in clojure

15:10 LauJensen: ah ok, interesting

15:10 chouser: a_strange_guy: mostly for "out" args, it looks like

15:11 a_strange_guy: chouser: maybe a unsynchronized-box and a volatile-box could eliminate most uses of mutable fields in deftype

15:12 duncanm: dum de dum

15:12 a_strange_guy: mutable fields "feel wrong" for me, as if the don't really exist because they arent objects

15:13 duncanm: what's an idiomatic way of generating a grid (vector of vectors), which each element is a pair (x, y)?

15:13 i can write (replicate 10 (replicate 10 'x)), but then i can't specify the (x,y) easily

15:13 LauJensen: chouser: the old chunky-seq stuff was written in Java right ?

15:13 Licenser: does c.c 1.1.0 has templates already or is it a 1.2.0 thingy?

15:14 hiredman: ,(((vec (replicate 10 (vec (replicate 10 'x)))) 0) 0)

15:14 clojurebot: x

15:14 chouser: a_strange_guy: such boxes would each require an extra allocation, and couldn't support primitive values as well as a mutable field could.

15:14 a_strange_guy: Licenser: 1.1 has them

15:14 AWizzArd: whar are templates?

15:14 Licenser: a_strange_guy: thank you!

15:14 hiredman: ,(get-in (vec (replicate 10 (vec (replicate 10 'x)))) [0 0])

15:14 clojurebot: x

15:14 chouser: LauJensen: some layers of it, yes.

15:15 a_strange_guy: AWizzArd: http://vimeo.com/8360422

15:16 don't think that anybody uses them

15:16 duncanm: hiredman: is it important that I put in the vecs?

15:17 AWizzArd: a_strange_guy: thanks. I did not use them because I never heared about it.

15:18 hiredman: duncanm: yes

15:18 the other option would be a set of nested nth's

15:30 Licenser: *sigh*

15:35 Licenser_: why are simple things at times so complicated in clojure? Or other question, what am I doing wrong?

15:35 Chousuke: what are you doing?

15:35 Licenser_: I just try to get my code work with clojure (and cc) 1.1, now noething works any more

15:36 slime is broken, saying it can't use swank any more, lein does not compile and refuses to allow me to use any of the new c.c classes like c.c.template

15:36 tecnically nothing is working correctly any more

15:37 I thought it would be as easy as changint 1.0.0 in the project.clj to 1.1.0, apearently it isn't :(

15:38 chouser: 1.1 is almost completely backward compatible with 1.0. You may want to make sure you're cleaning everything before rebuilding.

15:39 is that what I mean? I mean code written to work with 1.0 will almost all work just fine on Clojure 1.1.

15:39 Licenser: yes I know but it seems something is not 1.1'ish

15:39 clojurebot: amespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it

15:40 Licenser: I mean i unpackt c.c-1.1.0.jar, and there is no c.c.template

15:40 something seems very much not correct

15:40 somnium: Licenser_: its clojure.template in 1.1, same for walk

15:41 Licenser: oh

15:41 and what about c.c.io? is that c.io?

15:42 or c.c.json seems odd too :(

15:42 somnium: Licenser: look in the respective jars?

15:44 * a_strange_guy digs through clojure.lang.* ... and is horrified

15:47 jcromartie: struct definitions don't support metadata?

15:47 a_strange_guy: jcromartie: no, but their vars do

15:48 jcromartie: ah

15:49 a_strange_guy: eg: (defstruct #^{:my-meta :metadata} mystruct :a :b :c)

15:49 (meta (var mystruct)) => {:my-meta .....}

15:50 jcromartie: I am trying to attach validation to structs

15:50 but I think I'll just keep it in a function

15:53 chouser: a_strange_guy: I'm curious what horrified you.

15:56 Licenser: :) working again!

15:57 a_strange_guy: chouser: Settable, Streamable, Stream, Range ... possibly more

15:58 i'm trying to find out which Interfaces/Methods/Classes are used where

15:58 jcromartie: (ancestors (type x))

15:58 ,(ancestors (type []))

15:58 clojurebot: #{clojure.lang.Sequential clojure.lang.IEditableCollection clojure.lang.IPersistentCollection java.lang.Iterable java.util.List clojure.lang.APersistentVector java.lang.Comparable clojure.lang.Seqable clojure.lang.Obj java.util.RandomAccess clojure.lang.ILookup clojure.lang.IObj clojure.lang.IMeta clojure.lang.Reversible java.lang.Object clojure.lang.IFn clojure.lang.Indexed clojure.lang.IPersistentVector clojure.lang.Asso

15:59 jcromartie: that's a lot

15:59 chouser: a_strange_guy: http://tinyurl.com/clojure-classes

15:59 that that chart is probably a bit out of date.

15:59 though

16:00 you can see that the seq types are grouped mostly at the top, collection types mostly in the middle, and reference types on the lower right

16:01 a_strange_guy: that's a big help

16:02 the Stream classes are obslete I suppose

16:03 chouser: yes, they were never officially in the language.

16:05 a_strange_guy: after reading all that Java I *reaally* want to see clojure defined in itself

16:05 chouser: :-)

16:27 jcromartie: is lein test broken?

16:27 [null] java.lang.Exception: No such var: clojure.test/successful? (NO_SOURCE_FILE:1)

16:43 a_strange_guy: http://gist.github.com/312749

16:43 I think I found a compiler bug

16:43 with deftype

16:44 hiredman: you know clojure fn's are runnables, yes?

16:45 a_strange_guy: that's not the point

16:45 mutable fields don't work

16:46 can someone explan this?

16:46 chouser: a_strange_guy: you're using a very recent master branch?

16:46 a_strange_guy: brand new

16:47 in the same repl the Iter/Cell stuf works

16:47 ^stuff

16:47 duncanm: hmm

16:48 I thought (merge {:foo ["bar"] } {:foo "baz"}) would give me {:foo ["bar" "baz"]}

16:48 woohoo netsplit

16:48 licoresse: woohoo

16:48 ,(merge {:foo ["bar"] } {:foo "baz"})

16:48 clojurebot: {:foo "baz"}

16:49 duncanm: oh

16:49 hiredman: I don't know what the syntax for the mutable stuff is

16:49 chouser: a_strange_guy: I've got a simpler deftype with mutable field working here.

16:49 duncanm: "If a key occurs in more than one map, the mapping from the latter (left-to-right) will be the mapping in the result."

16:49 chouser: trying yours now

16:49 duncanm: boo

16:49 hiredman: a_strange_guy: are you sure you have it right?

16:49 duncanm: is there a way to write that without having to get ahold of the original value and then conj onto it?

16:50 otherwise, merge and assoc are kinda the same...

16:50 a_strange_guy: chouser: same here, a simpler deftype works

16:51 clojurebot: paste

16:51 clojurebot: lisppaste8, url

16:51 chouser: a_strange_guy: ok, I'm reproducing your exception.

16:52 a_strange_guy: even stranger: http://gist.github.com/312749

16:52 using an explicit "this" helps

16:52 it compiles, but doesn't run

16:55 * a_strange_guy is debugging the compiler

16:56 chouser: simplest error case I've found yet: (deftype Bench [#^{:unsynchronized-mutable true} val] Runnable (run [] (let [x (loop [] (set! val 5))])))

17:00 ska2342: Hi. Has anybody ever tried to combine multi-methods with arity-overloading? Is that supposed to work at all?

17:01 chouser: sure. the most common mistake is to not accept all arities in the dispatch fn

17:03 ska2342: I think I had some problem in the method (don't have access to that session right now). For the moment it's enough for me to know, that it's supposed to work. Thank you.

17:05 hugod: technomancy: did my patch for swank-clojure-find-package make sense?

17:06 technomancy: hugod: I've been hugely backlogged on incoming patches... haven't done any OSS in a week due to a big deployment at work. =\

17:06 44 pull requests pending.

17:07 hugod: ok, :-) just making sure it was in the queue

17:07 technomancy: I think someone volunteered to help with swank-clojure maintenance, but I haven't even had a chance to contact him.

17:22 hiredman: so isMutable is called twice on val, first time is true, second time is false

17:23 chouser: so ... it mutated? ;-)

17:25 hiredman: ,(identical? 'val 'val)

17:25 clojurebot: false

17:25 hiredman: I wonder if that is the issue

17:25 missing metadata?

17:26 debugging java is such a pain

17:26 AWizzArd: hiredman: I could imagine that two distinct and fresh symbols are created by the reader and they are thus not identical

17:26 hiredman: sure

17:26 ska2342: hiredman: 'val and 'val are not identical because a new symbol is created every time, if I understood things correctly

17:27 hiredman: hey guys

17:27 thanks, but I am well aware

17:27 ska2342: hiredman: looked like a question. nevermind.

17:28 chouser: bleh -- I find myself tempted to copy data from a vaguely structure-like thing (protobuf message) into a deftype instance, just so I can use fast :keyword lookup. :-P

17:28 hiredman: did you ask rhickey about the keyword lookup?

17:29 chouser: yes, and he seemed to suggest things that I could do, a way I could wrap the protobuf msg and have keyword lookup with site caching work. ...and then he took it all back.

17:29 AWizzArd: chouser: what is bad about this?

17:29 I mean that you use deftypes?

17:30 chouser: AWizzArd: what's bad is it feels like exactly the kind of think clojure is generally good at helping you escape.

17:31 much better would be to just wrap the protobuf msg -- ooh, or extend ILookup to it! -- but then I apparently can't have performance that matches using the protobuf msg directly.

17:32 hiredman: it would be nice to see a document describing how the keyword call site stuff works

17:33 chouser: what, reading the byte-code producing ASM lib calls in Compiler.java isn't enough for you!?

17:33 hiredman: actually I was reading the generated bytecode

17:33 * chouser goes to do something mindless...

17:33 AWizzArd: hiredman: so you can read the Matrix?

17:33 hiredman: AWizzArd: I put it through javap first

17:34 there is some kind of complex (at least when you don

17:34 't under stand it) feedback between functions that use use keyword callsites and deftypes

17:36 * a_strange_guy should stop reading Compiler.java, or else he'll lose his sanity

17:36 chouser: javap's a fantastic idea

17:37 hiredman: yes

17:37 the classes of fn's with keyword callsites in them have a few extra fields

17:39 a_strange_guy: I suppose only rhickey touches Compiler.java?

17:42 chouser: I've made a couple very minor patches.

17:44 a_strange_guy: I think that I found the reason why mutable fields fail sometimes

17:45 hiredman: I added a new special form once!

17:45 (not something that ever got merged or anything)

17:46 a_strange_guy: I'll just file a ticket with some pointers to the problem

17:46 * a_strange_guy needs to send in a CA

17:46 hiredman: a_strange_guy: what is the problem?

17:47 a_strange_guy: http://gist.github.com/312749

17:48 hiredman: right

17:48 that is the symptom

17:48 a_strange_guy: mutable fields + loop fails

17:48 hiredman: oh, I thought you had found something in the compiler

17:48 a_strange_guy: i did

17:49 line 4857 in Compiler.jave is the problem

17:50 the loop special form gets turned into a fn sometimes

18:02 duncanm: ,(doseq [{foo bar} [{:a 'b}]] (print foo bar))

18:02 clojurebot: java.lang.Exception: Unable to resolve symbol: bar in this context

18:02 duncanm: doesn't destructuring work in doseq?

18:05 hiredman: duncanm: it would if you destructured correctly

18:05 destructuring?

18:05 clojurebot: destructuring is http://clojure.org/special_forms#let

18:08 duncanm: hiredman: i don't see where i got it wrong

18:08 (let [{k v} {:a 1}] (print k))

18:08 ,(let [{k v} {:a 1}] (print k))

18:08 clojurebot: java.lang.Exception: Unable to resolve symbol: v in this context

18:10 hiredman: duncanm: paste an example from that page please

18:11 duncanm: hiredman: oh, the names of the keys has to match?

18:12 hiredman: right

18:13 duncanm: oh, but i don't know what the keys would be.... too bad

18:14 scottj: How would you create a macro defn2 that's like defn but evaluates the name arg and converts to symbol instead of requiring a symbol w/o evaluation? are macros right for this?

18:15 tomoj: why would you want to do that?

18:15 hiredman: why would you do that?

18:16 scottj: I have some code that defines a bunch of functions and the names of the functions are things like (str "foo" "bar") and need to be evaluatd and turned into symbols then used in defn

18:17 hiredman: why?

18:17 clojurebot: why not?

18:17 the-kenny: scottj: Are you sure you want this?

18:17 Couldn't you use a map which maps string to fn-objects?

18:17 jcromartie: scottj: there are other ways to attach things to namespaces

18:17 hiredman: if you are doing dynamic stuff I oubt you want to use defn anyway

18:17 jcromartie: I create a map of keywords to functions

18:17 then I can intern them if I want to or just use the map itself

18:18 (doseq [[k v] x] (intern *ns* (symbol (name k)) v))

18:18 but I am not liking it so much anymore

18:19 I don't like magic variables

18:21 duncanm: ,(doseq [[k v] (vec {:a 1 :b 2})] (print k v))

18:21 clojurebot: :a 1:b 2

18:21 duncanm: that works

18:23 scottj: jcromartie: that's cool I didn't know I could do that. defn of course does the arglists and line/file for me.

18:23 the-kenny: I guess I just want the functions to behave the same as if I'd written the code by hand

18:24 hiredman: sounds dreadful

18:24 jcromartie: so I feel like I've gone down the wrong path here

18:25 scottj: jcromartie: what's magic about the variables btw?

18:25 jcromartie: scottj: variables in namespaces that you didn't explicitly def

18:25 not cool

18:25 or variables that are available in a macro body that are not visible in the definition

18:26 I think I should be using the type system and multimethods to implement this data layer but I'm not sure

18:26 right now I'm creating maps that contain create/fetch/update/destroy function closures around the collection name

18:27 but don't want to define the same insert/etc. functions in each namespace for each resource in the app

18:27 somnium: Ive taken to using symbols like $magic-foo $magic-bar in macros with variable capture, is it really evil?

18:29 er, symbol-capture

18:34 scottj: in (defmacro defn2 [name body] `(defn ~(symbol name) ~'[x] ~body)) how do I tell it to evaluate name as well?

18:35 jcromartie: scottj: seriously, ask yourself why you want to do this

18:35 if you can create the fn you can define it another way

18:35 I mean create a var for it

18:35 but try to figure out a way that doesn't create vars in namespaces that can't be seen and comprehended by human beings

18:36 scottj: jcromartie: I want the vars to be seen and comprehended by humans, that's why I'm doing this

18:38 jcromartie: if you can't just type them, then they're being generated in some other way, right?

18:38 i.e. you're probably iterating over something creating fns

18:40 AWizzArd: scottj: anyway, you could try ~(eval (symbol name))

18:40 hiredman: AWizzArd: sshhh

18:40 AWizzArd: though as jcromartie said, it may be worthwhile to think such a design over and see if it really is needed

18:40 scottj: AWizzArd: I have a version working w/ eval, but ppl always say not to use it so I was looking if there was something else in macros

18:41 jcromartie: so the big picture for me is that I want to map structs into mongodb

18:41 AWizzArd: in most cases where eval is used eval is not needed and an inefficient hack

18:41 in most cases where eval is used by Lisp/Clojure beginners, eval is not needed and an inefficient hack

18:41 hiredman: scottj: why listen to everyone when they tell you not to use eval if you are going to ignore everyone when they tell you not to do what you are doing?

18:41 jcromartie: AWizzArd: especially in JavaScript :)

18:42 I've seen some scary stuff

18:42 scottj: hiredman: bc I don't think any of the reasons given so far have been very good :)

18:42 jcromartie: scottj: what's the overall goal?

18:42 like, of the lib or whateever

18:42 hiredman: scottj: you're not even listening when people tell you not to use def or defn for this

18:42 scottj: I don't see what's wrong with defining a bunch of functions that have good names and have proper metadata

18:43 jcromartie: unit conversions

18:43 hiredman: scottj: the problem is def has particular compile time semantices, and you are going to run into issues if you try and use this macro in another namespace

18:44 jcromartie: OK so you probably are wanting to define functions like from-f-to-c etc.

18:44 right?

18:45 scottj: jcromartie: yep, http://gist.github.com/276662#file_units.clj

18:46 hiredman: so if the macro is defined in foo and called in bar then the functions (and their symbols) will be in namespace foo?

18:47 hiredman: scottj: I forget exactly, to be honest

18:47 scottj: I don't get why

18:47 scottj: I don't get why 15:35 sarah : having been exposed

18:47 er

18:47 weird

18:48 somnium: scottj: why not just build the names you want in a helper and put them in the expansion?

18:48 jcromartie: yeah I'd say that's pretty weird

18:48 somnium: :P

18:48 hiredman: scottj: I don't get why ["fahrenheit" "celsius"] is better than [fahrenheit celsius]

18:49 scottj: hiredman: defconv-3d doesn't have to be a macro

18:51 somnium: I'm sorry, I don't understand. Can you explain?

18:55 a_strange_guy: chouser: I did some (really unscientific) benchmarking on the idea of a "box" reference type I talked earlier

18:55 http://gist.github.com/312873

18:56 performance seems to be equivalent to a normal mutable field

18:56 * a_strange_guy likes the jit

18:57 somnium: scottj: I just noticed that create-function is doing (eval (list 'defn (symbol s) ...))

18:58 a_strange_guy: allocation shouldn't be a problem in most cases

18:58 especially if we get escape analysis

18:58 somnium: scottj: I dont understand why its not a macro

19:00 scottj: somnium: I'm trying to write the macro version but having trouble having it evaluate a parameter that's a list and call symbol on that

19:03 somnium: ,(let [f (fn [name] `(defn ~(symbol name) ...))] (f (str "bar" "foo")))

19:03 clojurebot: (clojure.core/defn barfoo ...)

19:03 somnium: or maybe Im not understanding...

19:06 scottj: that evaluates name bc it's a fn not a macro right? I'm still new at macros but whereas that just returns the code, a macro would run the expansion I think, which is what I want

19:10 jcromartie: sometimes I wish I could thumbs-up a song on Pandora ten times

19:10 somnium: jcromartie: what song? (Ive been digging ratatat for clojure hacking)

19:10 jcromartie: hah, not really hacking music: Charlotte Sometimes by The Cure

19:12 somnium: scottj: where is the list argument coming from?

19:12 scottj: somnium: I like ratatat 9 beats

19:12 clojurebot: namespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it

19:13 pthatcher: ,(def *a* "a")

19:13 clojurebot: DENIED

19:13 jcromartie: ratatat, I'll have to check it out, is that some IDM or what?

19:14 scottj: somnium: the arglist ([x])? it's always that

19:14 jcromartie: (sounds good so far)

19:15 this guy is some good hacking music, but it's hard to get ahold of the actual songs http://www.myspace.com/signaldrift

19:16 pthatcher: ,(case *clojure-version*

19:16 clojurebot: EOF while reading

19:16 pthatcher: *clojure-version* true

19:16 false)

19:16 jcromartie: a little bit Boards of Canada, a little bit Aphex Twin

19:16 pthatcher: ,(case *clojure-version* *clojure-version* true false)

19:16 clojurebot: java.lang.Exception: Unable to resolve symbol: case in this context

19:16 pthatcher: Hmm.. not running Clojure 1.2?

19:16 In Clojure 1.2, that evaluates to false.

19:17 Knekk: for hacking I lean more towards the techno... I guess most people do

19:18 jcromartie: wow apparently Google is blocking the ol' intitle:"index of" trick

19:18 it thinks I'm a botnet

19:20 Knekk: try Infected Mushroom, Chemical Brothers, Prodigy

19:20 somnium: this signaldrift is alright

19:21 pthatcher: Example of bug in Clojure 1.2 case macro, and a temporary work around: http://gist.github.com/312898

19:24 scottj: first song on infected mushroom's myspace is matisyahu. I heard some low-tempo dub before a matisyahu concert that I thought would be really good for hacking, if a bit repetitive

19:25 Knekk: Banco de Gaia, Aphrodite

19:25 Underworld

19:25 anyway

19:25 jcromartie: yeah dub is good

19:26 scottj: jcromartie: any you especially like?

19:26 jcromartie: I have only ever heard some novelty stuff like Dub Side of the Moon, which I know is serious, but still :P

19:27 Knekk: try the RiverRun Project

19:27 jcromartie: Knekk: woah, it looks like a band of Stings

19:27 Knekk: without the suckage

19:28 jcromartie: hey don't know Sting... he might be a cheesy old bastard now but The Police are alright

19:28 don't knock, that is

19:28 * somnium somnium wonders if its the first time Sting has been mentioned in #Clojure

19:28 Knekk: they had some decent songs, sure

19:32 jcromartie: OK I think attaching metadata to the var in defstruct is a much better way to get structs into the database

19:32 and some macros

19:32 I am liking this much better than my GIANT BALL OF FNs that I previously was using

19:32 (def users-resource (resource :users user-struct :validate validate-users)) ;; NASTY

19:33 (defstruct #^{:coll :users :validate validate-users} user :email :hash :created ...) ;; much better

19:34 oh and before it would be ((:fetch-one users-resource) {:email "whatever"}), where now it's (struct-fetch user :where {:email "whatever"})

19:37 somnium: scottj: last try, if you make defconv a macro, it seems that something like `(do ~@(for [[units eq] ...] (defn ~(make-name ...) ~(make-arglists ...) ...) would suffice.

19:38 er, missing a syntax-quote

19:43 tomoj: anyone have any thoughts about testing side-effecty code (e.g. c.c.http.agent stuff)? I found http://github.com/amitrathore/conjure but something about this approach feels wrong to me

19:44 jcromartie: structs in mongo with validation and delete rules: http://gist.github.com/312918

19:44 oops, I forgot update

19:47 (update and struct-conform is there now)

19:55 scottj: somnium: you mean ` before (defn?

19:55 somnium: scottj: yeah

20:23 jfkw: Is there any java http server along the lines of unicorn (ruby) and gunicorn (python port), "designed to only serve fast clients on low-latency, high-bandwidth connections and take advantage of features in Unix/Unix-like kernels."

20:23 for hosting clojure http apps, of course.

20:25 chouser: jfkw: seems likely, but I'm sorry I don't know for sure.

20:26 scottj: jfkw: I don't know about those but netty uses NIO and will use some java 7 stuff that I think's like of like the linux kernel stuff nginx uses

20:26 s/like of like/kind of like

20:27 chouser: rhickey: Do you think there's any value in me trying to get ILookupThunk to work beyond deftypes?

20:27 KarlThePagan: jfkw, grizzly (or glassfish) with the right threadding strategy works well in high-bandwidth situations

20:29 scottj: jfkw: grizzly not netty is what I meant

20:42 KarlThePagan: yea grizzly has worked out all the java 7 kinks

20:48 jcromartie: ugh with the circular dependencies again

20:49 I have users and messages in separate libs

20:49 chouser: is that valuable?

20:49 jcromartie: and since they are related, they both need to know about each other

20:49 I could probably just have a model.clj lib with all of the data models and validation logic in it

20:50 and then have api libs for the compojure stuff

20:50 how about it?

20:50 ugh I run into these all the time

20:50 84K of clojure code here already and I can't figure out the deps :P

21:03 chouser: I hardly ever run into these. maybe split things up less?

21:05 jcromartie: yeah that seems to be the answer

21:05 coming from a lot of languages, having more than one thing in a file seems like a crime

21:06 I also feel like my validation functions are getting awfully close to being able to create a struct at the same time...

21:07 seems like it could turn into a declarative data model

21:30 how can I attach metadata to a var created using def inside a macro?

21:33 chouser: either use with-meta on the symbol name of the def, or use alter-meta! afterwards

21:35 jcromartie: like this: (defmacro x [name y] `(def (with-meta ~name {:y ~y}) nil)) ?

21:35 ah

21:35 no

21:35 chouser: right, no.

21:36 ~(with-meta name {:y y})

21:36 clojurebot: http://www.slideshare.net/mudphone/fun-with-vars

21:37 jcromartie: ah ha

21:37 TheBusby: for compojure, what do you need to do to have it use grizzly instead of jetty?

21:42 scottj: TheBusby: it's really easy, in compojure.clj change jetty to grizzly

21:43 TheBusby: scottj: That's great!

21:44 thank you

21:46 chouser: well, implementing IKeywordLookup and ILookupThunk is sufficient for getting correction values out

21:46 hiredman: what is ILookupThunk?

21:47 chouser: I think it's the think that gets swapped in at the call site

21:47 the thing

21:49 hiredman: hmmmm

21:51 chouser: but I'm not sure how to confirm it's getting used in a way that gets all performance a deftype does

21:53 hiredman: so what implements ILookupThunk? the same object that implements IKeywordLookup?

21:56 chouser: no, looks like one ILookupThunk obj per keyword*deftype

21:58 the Thunk is passed only the object (an instance of a deftype) and returns the right value.

21:58 jcromartie: yay, defining a struct and its validation function in the same swipe

22:00 (defmodel user :users (required :email non-empty-str) (optional :first str) (optional :last str))

22:01 hiredman: what about passing in a predicate function instead of str

22:01 like string?

22:01 ,(doc string?)

22:01 clojurebot: "([x]); Return true if x is a String"

22:01 jcromartie: I want to actually transform the value sometimes

22:01 like parse-int

22:01 or parse-float

22:02 (required :key f) throws if the result is nil or false

22:02 optional just takes whatever

22:02 this is mostly for consuming parameters from a web request

22:03 and it uses update-in so it also works with key paths

22:03 (required [:loc :lat] parse-double)

22:04 but that doesn't quite work yet (it only requires :loc, techincally)

22:04 or wait, does it work?

22:06 dnolen: jcromartie: that sound like a really cool piece of reusable code for RESTFUL resources.

22:07 jcromartie: that's the idea

22:07 dnolen: RESTful, anyways, are you going to release when it's further along? I'd totally use that.

22:07 jcromartie: possibly

22:07 I would like to

22:07 but I have to just finish this stuff first :P

22:09 dnolen: heh, no rush. sounds like a great idea tho. I much rather validate that way over regexes. It would be cool if there was someway to map the model to urls. Like automatically provide the proper regexes.

22:09 (defroutes (routify my-model)) would be cool.

22:10 jcromartie: already on it

22:11 dnolen: :)

22:11 jcromartie: (defroutes user-api (json-REST-routes user))

22:11 it's all a little bit rigid for my current purposes

22:11 adds access restrictions etc.

22:49 brandonw: what is the easiest way to check for sure if your version of clojure.contrib has the seq library

22:49 it is failing on a use call saying FileNotFoundException, but I checked the source and clojure.contrib.seq is pretty old, right?

22:49 i'm not sure how arch linux's repo version of clojure.contrib couldn't have it...

22:50 hiredman: uh

22:50 I don't think so

22:50 I think seq-utils was very recently renamed to seq

22:51 brandonw: oh actually

22:51 you're right

22:51 my mistake

22:52 i just remembered when whoever told me about it initially, they called it seq-utils, too

22:52 i looked up the docs and saw it was called just seq and just forgot about it

23:39 rads: when does it make sense to use dynamic binding over passing around a struct everywhere?

23:40 slyphon: rads: i was told that it doesn't, really

23:41 progski: I'm writing a loop that continuously reads data from a socket, and I was using a loop/recur to emulate something like while(true) {}. Inside the loop I will pass the data to a callback function. I feel like there may be something more idiomatic or is this okay?

23:41 hiredman: it's annoying if you ever what to use the same functions on two structs

23:41 ,(doc while)

23:41 clojurebot: "([test & body]); Repeatedly executes body while test expression is true. Presumes some side-effect will cause test to become false/nil. Returns nil"

23:41 rads: slyphon: is it a different case if you're passing something like a database connection around?

23:42 progski: bah, that was obvious, thanks

23:42 slyphon: rads: well, hiredman was the one that said "don't do that" so i defer to him

23:43 rads: the problem is that dynamic bindings are thread-local only

23:43 so you can run into trouble if you're dealing with agents, for example

23:45 rads: well, c.c.sql has with-connection, clojure-redis has with-redis, etc... is it just because it looks nicer?

23:45 slyphon: honestly, i'm a n00b, so i can't speak with any authority

23:45 hiredman: well, I am just some dude on irc

23:46 slyphon: hiredman: you wrote clojurebot!

23:46 hiredman: clojurebot is just some bot on irc

23:46 slyphon: i mean, wow!

23:46 hiredman: clojurebot: hiredman

23:46 clojurebot: hiredman <3 XeLaTeX

23:46 slyphon: hiredman: you're ruining my illusions

23:46 people need heros, hiredman

23:48 hiredman: rads: they do and they are fine in some cases, but if you ever want to operate on more than one of whatever you passing via dynamic binding at once it is a pain

23:50 * slyphon cheers!

Logging service provided by n01se.net