#clojure log - Oct 10 2010

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

0:15 sproust: There's nothing like doing some CL to remind you how cool Clojure is.

0:15 amalloy: sproust: augh, now i'm going to have nightmares

0:17 TeXnomancy: (cl-awesome-p) ;; => nil

0:17 amalloy: to be fair, CL is better than a lot of things. our ancestors had to make do somehow until clojure came along

0:18 sproust: I have to admit though, I'm a sucker for its zippyness, and being able to compile. Java drags me down a bit. I wish for Clojure-on-top-C.

0:20 TeXnomancy: "being able to compile" o_O

0:20 oh, you mean the ability to produce native executables?

0:20 sproust: Yes.

0:21 Java startup time makes Clojure prohibitive for a large number of "small" applications, IMHO.

0:22 I really like to be able to disassemble in CL, and make optimizations, be close to the metal.

0:30 freakazoid: If you want to be close to the metal I don't think you want a JVM language.

0:31 There are a ton of lisps that compile to C or assembly language or otherwise are designed for performance

0:31 sproust: I'd recommend Racket if you want something with its own VM

0:38 kryft: What's so terrible about CL? (I've never used it - Clojure is my first lisp.)

0:39 Well, I have had some scheme exposure, but I've never really used it.

0:39 TeXnomancy: kryft: it just hasn't moved forward since the 80s

0:42 kryft: TeXnomancy: In terms of the libraries?

0:44 scottj: Common Lisp: (concatenate 'string "foo" (write-to-string 1)) Blub: "foo" + 1

0:44 TeXnomancy: poor libraries, bizarre naming conventions, poor syntactic support for data structures, and overly-complicated OOP are the things I remember from trying to use it

0:47 gregh: CL is like a programming language construction kit

0:47 TeXnomancy: they actually expect you to use alists instead of hash-tables for simple code and then rewrite your code to use hash-tables once your discover your perf bottlenecks... rather than just providing convenient syntax for hash-table literals so you can do it right the first time through.

0:48 kryft: Ah. I'm glad I waited until clojure came along. :)

0:50 I've been wanting to learn a lisp for quite some time, but scheme seemed too minimalist for practical purposes, and Common Lisp... Well. Apparently my intuition was correct.

0:50 scottj: CL does have many great features we're ignoring :)

0:52 TeXnomancy: conditions is the only thing I can think of

0:53 freakazoid: kryft: well, Scheme is a big improvement on CL in terms of cleanliness, and Racket is pretty awesome, but Clojure has the benefit (to some) of running on the JVM and focusing more on immutable datastructures and good concurrency support

0:56 gregh: oh yeah, and in CL some of the pieces are metric and some are imperial :)

0:56 freakazoid: hehe

0:58 sproust: freakazoid: Racket is neat indeed, nicely packaged now, looks like; but I'm a bit invested in CL. I'd like to learn it.

0:59 kryft: freakazoid: Ah, I hadn't heard about Racket. :)

1:00 sproust: kryft: just like there is nothing other than culture from preventing LISPs from taking over the dynamic language space, there is nothing preventing people to make a compileable LISP with much of the nice features that Clojure has.

1:01 freakazoid: I think lispers are the big thing standing in the way of lisp's success

1:02 I get the impression most clojure users are relatively new to the whole lisp thing

1:03 sproust: freakazoid: be hopeful; there is a new generation of developers bred on dyn.lang like Perl/Ruby/Python and IMHO a Lisp is a natural next step. New blood on the horizon, this could be a big change in adoption. Any thoughts?

1:04 freakazoid: I am hopeful and I totally agree with you. Clojure is going to bring lisp into the mainstream

1:04 kryft: I guess I could be seen as part of that new generation. :) I've had a taste of functional programming using Python, and now I want the real thing. ;)

1:05 freakazoid: I assume by "functional programming" you are just referring to functions as first-class objects. There is a lot more to functional programming than that.

1:05 kryft: sproust: To me, running on top of the JVM is an advantage.

1:05 sproust: kryft: Exactly! Anyway, that's my hope.

1:05 freakazoid: Python makes waaay too much use of mutable datastructures

1:05 the traditional form of OOP depends on it.

1:06 Clojure agents make a lot more sense.

1:06 sproust: kryft: yeah, I suppose it depends on much Java exposure you've have; I can't decide for myself whether it's a gain or a liability.

1:06 freakazoid: I am not a Java user and I consider it an advantage just because of ease of deployment

1:06 sproust: freakazoid: I don't understand why agents couldn't just be part of a library. It's just a thread pool with some synchronization primitives, no?

1:06 freakazoid: and all the preexisting libraries you get

1:06 and really good interop with all sorts of other languages.

1:06 kryft: sproust: I've had very little Java exposure myself, but I want the libraries.

1:07 freakazoid: I'm sooo tired of all the shitty FFIs out there

1:07 kryft: freakazoid: You assume incorrectly. :)

1:07 sproust: freakazoid: Yes, but you can write any scripts, startup time is way too slow.

1:07 freakazoid: kryft: then I don't know what you mean. Id on't think most people would consider Python even remotely a fucntional programming language.

1:07 sproust: I've noticed that, and it kind of bugs me. I'm pretty sure it's possible to make java stuff start much faster

1:08 sproust: it's not that - default behavior is very important

1:08 sproust: I still need to check out nailgun, it's meant to do that, runs your code in a waiting VM.

1:08 freakazoid: sproust: the "right" way should be the most convenient way

1:08 I don't think keeping the VM running is the answer

1:08 sproust: Yep.

1:09 freakazoid: I've definitely heard of java apps starting much faster

1:09 kryft: freakazoid: To me, functional programming is a paradigm. It's quite possible to write small programs in python that are pretty functional.

1:09 freakazoid: kryft: ok, so you've done functional programming in python

1:10 it lacks any functional datastructures, though

1:10 there's some good functional stuff in numpy though

1:10 kryft: freakazoid: Yes; that's why I said that I've had a taste of functional programming, and now I want the real thing. :)

1:10 TeXnomancy: didn't they try to remove reduce in python 3?

1:10 freakazoid: in that you can do all sorts of things to arrays without ever mutating them

1:10 TeXnomancy: whether it's possible to do FP in python or not, that certainly signals to me that the community does not approve of it

1:11 freakazoid: TeXnomancy: if they did I'm guessing they would have replaced it with something else - list comprehensions are preferred to map, I think

1:11 sproust: TeXnomancy: yes.

1:12 Python list comprehensions give you map and filter, not reduce.

1:12 freakazoid: TeXnomancy: they just moved it to functools

1:12 they were just removing some random stuff from the global namespace.

1:13 sproust: that's why I said preferred to map and not to reduce ;-)

1:13 but it turns out they just moved it

1:13 reducing the number of global names

1:13 kryft: freakazoid: My 'functional' python programs were mostly list manipulations, and python does at least have lists. ;)

1:13 sproust: Python 3 is pretty neat actually, if people would port and get on with it. A lot of stuff was cleaned up.

1:14 freakazoid: re. functional Python: the iterator concept is Python is analogous to Clojure's use of Seqs.

1:14 freakazoid: kryft: yeah, though they're actually extensible vectors so copying one just to change one element is pretty inefficient

1:15 kryft: freakazoid: Ok; I never really used Python for anything where efficiency would matter. :)

1:15 sproust: freakazoid: I've been able to easily write some text processing programs in Python as networks of iterators (generators). They "feel" very functional (though the syntax would be more adequate in a LISP).

1:15 freakazoid: I've done some pretty heavy duty processing in Python

1:15 lots of image processing using numpy and scipy

1:15 I need to start playing with Incanter

1:16 sproust: yeah, Python is getting very good with that sort of stuff

1:16 sproust: freakazoid: re. vectors/performance: the Pythonistas generally believe there is no use case for lists (!).

1:16 freakazoid: and it's syntactically convenient to do a lot of things right

1:16 BUT it's still syntactically most convenient (and most efficient) to mutate in place in most cases

1:17 sproust: If you believe mutating data in place is the way to go, they're probably right.

1:18 Though even if you do, hash tables with linked lists for collision resolution are extremely common

1:18 because MTF is quite common

1:18 and very efficient

1:18 kryft: freakazoid: In the past I've used Python or Matlab when efficiency doesn't matter and C++ when it does. I'm hoping to use Clojure for everything. :)

1:18 freakazoid: Well, you may have to drop to Java for some things, then, since Clojure is not hugely more efficient than Python

1:19 At least, according to the programming language shootout

1:20 maybe about 2.5x as fast on a quad core machne

1:21 kryft: freakazoid: Others (including a certain Rich Hickey :) have said that you can get performance pretty close to Java if you know what you're doing.

1:21 freakazoid: That would be pretty awesome.

1:21 I wouldn't think your code would look very good, thoguh

1:22 Adamant: it's like trying to get C speed out of a language

1:22 kryft: freakazoid: [I am told that] the programming language shootout isn't very representative because most of the programs have such short runtimes.

1:22 Adamant: your code starts to look like C in any language

1:23 freakazoid: kryft: yeah, could be.

1:23 gregh: which is really just high level assembly

1:23 amalloy: kryft: and also you have to use the same algorithm, even when it doesn't make sense in your language

1:23 freakazoid: i dunno, Haskell manages to get pretty fast and I don't think your code is gonna look much like C in Haskell

1:24 kryft: Yup.

1:24 Mind you, it doesn't have to be exactly as fast as C, as long as the overhead isn't terrible.

1:25 (For my purposes)

1:25 scottj: I was just watching a haskell conference talk where the speaker mentioned how horribly un-haskell the benchmark competition code was as if everyone already knew it

1:27 kryft: freakazoid: Anyway, my first Clojure project will be to reimplement an algorithm that I wrote in C++, so we'll see. :P

1:27 TeXnomancy: the people who run the alioth shootout either don't understand how JIT warmups work, or they want to make runtimes that rely on JIT warmup look bad

1:27 Adamant: freakazoid: it does

1:28 freakazoid: you can write Haskell-accented C in Haskell

1:28 it's been done

1:28 freakazoid: scottj: oh, that's too bad.

1:28 Adamant: well, "C"

1:28 freakazoid: it's all in a mutable-state monad

1:29 which is basically C then

1:29 sorta

1:29 freakazoid: Stupid von neumann bottleneck.

1:30 scottj: TeXnomancy: Java does realy well in the shootout.

1:31 Adamant: yeah, Java has come a long way since they've thrown so many compiler gurus at it

1:31 it is optimized as heck these days.

1:31 freakazoid: I got excited about this obscure language called "ATS" that's right below C but then I found out it just generates C and it's a quite verbose language.

1:31 kryft: freakazoid: "Python is an amazing language for getting larger projects done right." Is this a different Sean Lynch? ;)

1:32 freakazoid: yeah, I think these days you should really have to justify writing your own VM.

1:32 there's no reason whatsoever for Python's or Parrot. Ruby's at least has microthreads and call/cc

1:32 kryft: did I say that?

1:33 I might have

1:33 gregh: well python's existed before jvm, so there's the excuse of legacy

1:33 freakazoid: gregh: that's true.

1:33 kryft: freakazoid: I take it your homepage hasn't been updated in a while? :)

1:33 Adamant: freakazoid: ATS is a interesting language

1:33 clojurebot: make a note of http://scienceblogs.com/goodmath/2006/11/the_c_is_efficient_language_fa.php it is yet another article about picking c or c++ for performance being naive

1:33 freakazoid: kryft: http://literati.org/~seanl/ is my home page

1:33 Adamant: that guy is full of poop

1:33 the scienceblogs guy

1:34 freakazoid: C *can be* efficient. *your C* is buggy, unmaintainable, and still slow.

1:34 kryft: freakazoid: Ok, so probably it was a different Sean Lynch then. =)

1:34 freakazoid: there are a lot of us.

1:34 Adamant: like the Erics.

1:35 freakazoid: i used to be a pretty big Python fan.

1:35 It has a lot of the same advantages as clojure without having to have been hosted on the jvm to get them

1:35 i.e. large, vibrant community, huge number of libraries

1:35 in spite of having a pretty shitty API

1:35 well, now there's ctypes

1:35 which rocks

1:36 Adamant: freakazoid: Python is OK

1:36 freakazoid: with multicore and more distributed processing, I suspect Python's popularity will wane as languages like Clojure and Erlang pick up the clack

1:36 slack

1:36 kryft: Adamant: Full of poop how?

1:37 Adamant: kryft: I disagree with him on a lot of things and he's been wrong about at least one thing he's ranted on

1:37 although I'd have to go back through his blog and jog my memory as to which

1:37 kryft: Adamant: You disagree with him in general, or you disagree with something in that article_

1:37 Adamant: ?

1:38 Adamant: kryft: I haven't read the article, because I think he's full of poop and don't bother doing so at this point.

1:38 it's a general advisory.

1:39 freakazoid: He's claiming Fortran is better than C for writing efficient numerical code?

1:39 Adamant: no, that's true.

1:39 usually.

1:40 Fortress would be nicer and probably just as fast, but the current implementation is an interpreter, so no.

1:40 freakazoid: interesting

1:41 I wonder if Rust is going to go anywhere or if it will just die an early death

1:41 Adamant: freakazoid: would be nice if it went somewhere

1:41 freakazoid: yeah, it looks pretty neat

1:41 Adamant: since BitC hasn't really panned out

1:42 freakazoid: but it's not good enough to be slightly better than a bunch of other languages

1:42 that's the beauty of, say, clojure

1:42 it gets to benefit from a bunch of existing work and an existing community

1:43 Ruby'd probably never have gone anywhere if it weren't for Rails

1:43 I think most of the original Python users are perl refugees and scientists who couldn't stand lispers and got tired of fortran

1:44 I'm actually a perl refugee by way of tcl

1:45 Adamant: Ruby is nice

1:45 freakazoid: I liked ruby a lot when it came out but it has too many perlisms

1:45 Adamant: for what it is

1:45 freakazoid: there were a lot of Lispers that wanted to use Lisp but couldn't justify it

1:45 that went to Python

1:46 freakazoid: if you can't justify lisp, why can you justify python?

1:46 TeXnomancy: python can do sockets?

1:46 Adamant: if you're doing commercial work in the 2000-era?

1:46 that's how Google got hooked on Python

1:46 freakazoid: I don't know that much abotu lisp

1:46 just scheme

1:47 TeXnomancy: Google started using Python because you couldn't set the User-Agent header when doing HTTP requests in Java in the nineties

1:47 freakazoid: haha

1:47 wow

1:47 Adamant: the situation for Common Lisp is much better in 2010 than it was in 2000 or even 2005

1:47 TeXnomancy: freakazoid: true story: http://groups.google.com/group/comp.lang.java/browse_thread/thread/6923c024ed392c85/88fa10845061c8ba

1:48 freakazoid: Adamant: even so, whether or not it's part of CL it's gotta be part of every real-world implementation

1:48 Adamant: ?

1:49 freakazoid: anyway the current tech lead at Google is a ex-Lisper

1:49 freakazoid: Adamant: sockets

1:49 Adamant: freakazoid: oh yeah

1:49 freakazoid: brb, I'm changing themes to see if it'll improve performance

1:50 also possibly closing all my tabs will increase my performance

1:50 Much better

1:50 Might just have been too much scrollback

1:50 I'm diggin this theme though

1:50 very clean.

1:52 Heh, so Larry got into Python at the same time I did

1:58 * freakazoid wonders if he's actually here

2:00 Adamant: freakazoid: too much of the brown acid?

2:00 :P

2:01 freakazoid: heh

2:01 no, just hadn't heard anything since I came back into the channel

2:01 Adamant: well, my joke solved that

2:02 freakazoid: Indeed

4:57 yayitswei: what's a good way to split run-lengths, e.g. [1 1 1 2 2 3 3 3] => [[111] [2 2] [3 3 3]]

4:58 _ulises: morning all

4:58 yayitswei: _ulises: morning

4:59 _ulises: morning yayitswei

5:04 bytesource: Hi all! I am reading the Enlive tutorial by David Nolen. I have got a little problem. Whenever I make changes to the code and then reloade deftemplate or routes nothing changes on the website. Does anybody know how to make these changes happen?

5:05 hoeck: yayitswei: I would use reduce: http://gist.github.com/619097

5:05 yayitswei: bytesource: which repl are you using?

5:06 bytesource: I am using the Emacs REPL.

5:06 yayitswei: hoeck: ah thanks! taking a couple minutes to study it

5:07 bytesource: try pressing C-c C-k to recompile?

5:08 bytesource: OK, I'll try

5:11 jarpiain: ,(letfn [(rl [xs] (lazy-seq (when (seq xs) (let [[h t] (split-with (partial = (first xs)) (rest xs))] (cons h (rl t))))))] (rl [1 1 1 2 2 3 3 3]))

5:11 clojurebot: ((1 1) (2) (3 3))

5:11 bytesource: yayitswei: That seems to work!

5:12 jarpiain: ,(letfn [(rl [xs] (lazy-seq (when (seq xs) (let [[h t] (split-with (partial = (first xs)) (rest xs))] (cons (cons (first xs) h) (rl t))))))] (rl [1 1 1 2 2 3 3 3]))

5:12 clojurebot: ((1 1 1) (2 2) (3 3 3))

5:14 yayitswei: bytesource: perfect. reloading the templates and routes should work too though, maybe you weren't actually evaluating them?

5:15 jarpiain: awesome thanks

5:18 bytesource: yayitswei: After making changes, e.g. adding a selector, I pressed C-x C-3 both for deftemplate and routes.

5:18 Sorry, C-x C-e

5:32 LauJensen: Morning guys

5:45 esj: hey Lau

5:45 _ulises: morning LauJensen

5:52 how good a style is to have a (let [] ...) with a fair bit of bindings that has a single expression in its body that uses them all (or most) as the result of the fn?

5:52 e.g. (let [x 10 x-times-2 (* 2 x) y 5 y+x (+ y x)] (* 10 y+x))

5:52 (I know it's a silly example)

5:53 AWizzArd: _ulises: this can be very clear in some cases. Decide on a case-by-case basis.

5:53 _ulises: is it better to break the function into a set of smaller functions that perform the steps in the bindings?

5:54 right, my question was because it feels very imperative, but it usually results in much clearer functions (especially when you have lots of maps, etc.)

5:54 AWizzArd: _ulises: where are those side effects that give you this feeling? :)

5:54 _ulises: oh, it's not the side effects but the sequence of steps

5:54 in my mind sequence of steps = imperative

5:55 AWizzArd: What you wrote is declarative. You are not even programming, you just say how you name things.

5:55 _ulises: whereas chain of applications = more functional

5:55 true

5:55 I think it may also be am issue of trying to do too much inside an fn too :/

5:55 AWizzArd: For those small math expressions I personally would find this too verbose, but if you mean the general principle and not this concrete example, then this can be totally fine.

5:56 _ulises: oh, yes, this example is very small

5:56 AWizzArd: You communicate with the readers of your code, and it is nice to let them easily break down into pieces that humans can consume.

5:56 The compiler can read thousands of those per second, even if brutally deep nesting :-)

5:56 if ==> with

5:56 _ulises: in general I have things like [some-result (map f (a seq from params)) extra-stuff (map g (other-seq)) zipped-results (partition 2 (interleave some-result extra-stuff))]

5:57 right

5:57 AWizzArd: _ulises: it can also be fine to say: (let [x (foo 1), x (bar x)] ...)

5:58 _ulises: take this for instance: http://pastebin.com/E1hGVGxG

5:59 AWizzArd: _ulises: yes, I would be thankful of being able to read it with the single elements broken down into their own vars. It is totally idiomatic to use a let for readability.

5:59 _ulises: great then :)

6:00 AWizzArd: If you repeat a single expression, then it is even important to use let. But also for expressions that appear only once it can be great, if those expressions don't happen to be something like “5”.

6:00 _ulises: oh, indeed

6:00 the example I provided here was far from good

6:01 I was actually talking about the idea of breaking things down inside the let bindings

6:01 for some reason it felt silly to do it that way

6:05 ,(defn f [{v :foo}] v)

6:05 clojurebot: DENIED

6:05 _ulises: ugh

6:05 in any case, it would seem sensible (at least to me) to allow the reverse to be valid as well: (defn f [{:foo v}] v)

6:05 (just a comment)

6:32 snaund: is there any good documentation / example available about how to use the functions that (defentity ...) from appengine-clj's appengine.datastore creates ?

6:42 raek: _ulises: "the reverse" is reserved for things like :as, :or, :keys, :strs and :syms

6:45 _ulises: raek: oh, I didn't know, thanks

6:46 raek: if the key is a symbol, then it is a binding thingy. if it is a keyword, then it is some kind of option

6:46 the options would look very strange if they were reversed

6:49 ,(let [{x :x, :keys [a b], :strs [c d], :syms [e f], :or {x 0}, :as m} {:a 1, :b 2, "c" 3, "d" 4, 'e 5, 'f 6}] [x a b c d e f])

6:49 clojurebot: [0 1 2 3 4 5 6]

6:52 _ulises: hum

6:53 right.

7:34 fbru02: hey guys stupid question time how can i convert a string into a token??

7:36 AWizzArd: fbru02: depending on what a “token” is there will be a converter function or a constuctor.

7:36 +r

7:36 Are you possibly talking of symbols?

7:36 ,(symbol "fbru")

7:36 clojurebot: fbru

7:37 fbru02: AWizzArd: I was thinking abut tokens for this : :token :fbru02

7:37 AWizzArd: ,(keyword "fbru")

7:37 clojurebot: :fbru

7:38 AWizzArd: Those are (instances of the class) Keywords

7:38 fbru02: AWizzArd: thanks a lot !!

7:57 bytesource: I have a question about the folder structure using Enlive. The source of deftemplate is "templates/coffee/subpage.html". I have no problem with this template, however, the css file (href="coffee.css") that is in the same folder as the html file cannot be found.

8:00 raek: you use the html in deftemplate and serve the other file with ring?

8:00 deftemplate looks for files on the classpath

8:01 where the ring wrap-file middleware looks for the files can be configured

8:04 (wrap-file ... "resources/templates")

8:04 bytesource: I am not quite sure. I just started with the Enlive tutorial and wanted to test my new knowledge.

8:04 That looks interesting. I'll take a look...

8:05 raek: ah

8:05 see http://github.com/swannodette/enlive-tutorial/blob/master/src/tutorial/utils.clj#L42 and http://github.com/swannodette/enlive-tutorial/blob/master/src/tutorial/utils.clj#L9

8:06 bytesource: Thanks!

8:07 raek: I usually keep my html templates in resources/

8:07 lein makes that available on the classpath just like src/

8:08 bytesource: Thats good to know! I only knew about the src and classes folder. Is it OK to just add the resources folder or do I have to adjust project.clj, too?

8:09 raek: no, it already done

8:09 (you can confirm these things by running "lein classpath")

8:14 bytesource: Yes, you are right, the 'resources' folder is already on the classpath: /home/sovonex/Clojure/enlive-tutorial/resources

8:23 Just to make sure I understood correctly: My html and css files are now located at resources/templates/coffee/ , the corresponding deftemplate is located at scr/tutorial/menu.clj. *webdir* is set to"/src/tutorial/" by default. Now when I set the source of deftemplate to "templates/coffee/subpage.html" I get an error.

8:24 raek: I wonder if you have to restart clojure if the resources dir did not exist before

8:25 bytesource: I did 'lein deps' but this did not work.

8:25 OK, I'll restart Clojure...

8:25 raek: I vagely recal having some problem with that

8:28 bytesource: raek: Great! Now my html file gets found!

8:30 raek: However, one problem remains: The css file that is in the same folder as the html file and referenced in the html file as href="coffee.css" still does not get loaded.

8:41 LauJensen: bytesource: gets loaded when? are you mixing it into the html or serving it on some web interface?

8:44 raek: bytesource: can you access it directly with the browser?

8:44 bytesource: I am sorry, I don't quite understand your question. I have three files: subpage.html and coffee.css that are both located at resources/templates/coffee/. Then there is menu.clj which is located at src/tutorial

8:44 raek: http://localhost/coffee/coffe.css

8:45 bytesource: raek: No, I cannot directly access coffee.css in the browser

8:45 raek: hrm, add port number to that example

8:45 bytesource: I already did that

8:45 raek: what was *webdir* set to?

8:45 bytesource: http://localhost:8080/coffee.css

8:46 *webdir* is set to /src/tutorial/

8:47 This is where I get confused. There is the classpath and then there is also *webdir*

8:48 mtopolnik: ,(time (dotimes [i 1000000] (keyword "a")))

8:48 clojurebot: "Elapsed time: 1007.993 msecs"

8:48 mtopolnik: ,(time (dotimes [i 1000000] (symbol "a")))

8:48 clojurebot: "Elapsed time: 667.325 msecs"

8:51 bytesource: raek:, LauJensen: Tomorrow I'll take a closer look at this problem. Thanks a lot for your help!

8:52 LauJensen: bytesource: np, if you want I can find a link to one of my blogposts where I demo this type of thing

8:53 bytesource: LauJensen: That would be great!

8:53 LauJensen: sec

8:54 bytesource: 1) http://bestinclass.dk/index.clj/2009/12/dynamic-interactive-webdevelopment.html 2) http://bestinclass.dk/index.clj/2010/02/reddit-clone-in-10-minutes-and-91-lines-of-clojure.html 3) http://bestinclass.dk/index.clj/2010/02/reddit-clone-with-user-registration.html and optional) http://bestinclass.dk/index.clj/2010/06/best-in-class--now-open-sourced.html

8:55 bytesource: This is fantastic! Thank you very much!

8:55 LauJensen: np :)

8:55 Feel free to shoot back if anything is unclear

8:55 raek: bytesource: *webdir* should be set to "/resources/templates/" in your case

8:55 LauJensen: In the first 3 posts, I think Im using Compojure, but nowadays I mostly use Moustache

8:56 raek: Moustache <3

8:56 *webdir* is where static files are served from

8:57 bytesource: I haven't head so much about Moustache and therefore thought everybody is using Compojure anyway.

8:57 raek: maybe resources/static/ would be a good place to put static files. that way you don't accidentally serve the template files

8:57 bytesource: reak: That sounds good!

8:57 raek: http://groups.google.com/group/clojure/msg/64e8ed91791d81d2

8:58 James Reeves (author of Compojure) summarizes the clojure web ecosystem

8:58 LauJensen: bytesource: moustache is very nice to work with. Once you learn the basic syntax of Enlive and Moustache, its easy to work with

8:58 bytesource: Thanks for this link. I will take a look at it later. Right now I cannot open it because Google Groups is blocked here.

8:59 raek: http://pastie.org/1211070

8:59 bytesource: LauJensen: Then I guess I should take a closer look at Moustache, too :-)

8:59 raek: only 16 lines

8:59 LauJensen: bytesource: I'd recommend it. The entire site bestinclass.dk is run on nothing but Moustache and Enlive, and it took a very short time to build

9:00 mtopolnik: ,(dotimes [i 3]

9:00 (time (dotimes [i 1000000] (keyword "a")))

9:00 (time (dotimes [i 1000000] (symbol "a"))))

9:00 clojurebot: EOF while reading

9:01 bytesource: raek: I cannot open this site, either. But that's no problem. I'll use a VPN than every site is accessible.

9:01 LauJensen: mtopolnik: You can query the bot and give it commands in private if you like

9:01 mtopolnik: sorry...

9:01 how do i do that?

9:01 LauJensen: type /query clojurebot

9:02 mtopolnik: Thanks

9:02 LauJensen: np

10:23 AWizzArd: Hi rhickey, good morning.

10:33 fast question, someone may know it: do swing text components (JEditorPane, JTextPane) support Drag&Drop on specific words?

10:37 LauJensen: AWizzArd: IIRC you implement your own D&D handlers. Wouldnt be tricky to get the selected word

10:39 AWizzArd: sounds good

10:41 LauJensen: btw, when you want to display styled texts (different fonts/colors/backgrounds, italic, bold, etc), would you then do it via the RichText capabilities of Swing, or put a html string into the component.

10:41 I was actually thinking about using one of those html generator macros :)

10:41 LauJensen: AWizzArd: I used html to keep it simple

10:41 AWizzArd: Yes, sounds less complicated to me too.

10:42 LauJensen: Easy to work with, easy to debug, read, etc

10:42 AWizzArd: With a html macro one could write down the styled text as a tree and have the chatty html stuff being generated.

10:45 LauJensen: AWizzArd: Would also be trivial to implement some kind of markup *word* = <b>word</b>, **word** </italic></b>world... etc etc

10:46 AWizzArd: yes true

10:46 Our own "wiki style markup"

10:46 good idea too

10:46 LauJensen: thanks :)

11:02 jaley: hi guys - leiningen question... if I add java source to my project, e.g. under src/myproject/java/... whill leiningen "just do it", or is something more scary required?

11:03 TeXnomancy: jaley: it will just work in 1.4.0 (which hasn't been released yet). for now try the lein-javac plugin. I don't think it's scary, but I've never used it myself.

11:05 jaley: TeXnomancy: ah ok thanks. I'm trying to figure how to get the client stubs generated by Axis from a WSDL into my clojure project. ideally i'd like leiningen to run the code generator first too, but this is sounding like adding ant/maven tasks? :/

11:13 raek: jaley: making a leiningen plugin is really simple, iirc. something like making a function called my-plugin in the namespace leiningen.my-plugin and putting the code in the right place

11:13 http://github.com/technomancy/leiningen/blob/master/PLUGINS.md

11:13 micrypt: Hi, quick question: When does one use "defn-"?

11:14 jaley: raek: cool, thanks!

11:14 micrypt: for function you don't want to be visible outside the namespace you define it in

11:15 micrypt: jaley: Oh, thanks. Google kept correcting my search query to "defn". :)

11:20 TeXnomancy: you don't need to write a plugin for compiling java; just declare a dev-dependency on the existing lein-javac

11:26 jaley: TeXnomancy: ah ok. it also looks like I might be able to use a hook to run the code generator tool before compiling

11:31 TeXnomancy: yeah, sounds right

11:34 jaley: TeXnomancy: awesome. leiningen has prevented java tools from ruining my day again!

11:37 raek: How do the models of Leiningen and Cake differ? I've heard that Cake has a "dependency based task model", but what model does Leiningen have?

11:39 LauJensen: raek: plugin model

12:04 TeXnomancy: raek: in leiningen tasks are just functions

12:05 so you get composability, familiarity, memoization, and all the things you're used to with functions

12:10 jaley: how can i create a String[] from clojure? to-array will create an Object[].. is there a way to cast? or is this the wrong way to do it?

12:12 oh it's cool, into-array seems to do it

12:12 AWizzArd: yes

12:26 gilbertleung: hi

12:47 jaley: with hooks for leiningen... is it at all necessary/recommended/sensible to create them in the leiningen namespace (as with plugins)? or would they be better in my own project namespace?

12:52 TeXnomancy: jaley: it should be under the leiningen.mytask namespace

12:52 I think the plugin guide is explains it; you can see other plugins for examples

12:53 jaley: TeXnomancy: yes it does, specifically for plugins - i guess my question really is, "are hooks the same?"

12:55 TeXnomancy: actually... thinking about it. having a seperate task for this makes more sense anyway. so i'll go with a plug-in

13:29 does a leiningen plugin *have* to be a seperate project? is it not possible to create a local task for a particular project?

13:30 raek: robert.hooke question: "Then users can place files that call add-hook under a specific namespace prefix (my.program.hooks.*) which they can rely on getting loaded at startup." How do I make my project load all such files?

13:30 jaley: I don't think they need to be spearate projects

13:30 "So writing a Leiningen plugin is pretty straightforward; as long as it's available on the classpath, Leiningen will be able to use it."

13:31 this would include hooks placed in src/, I think. at least I have seen that be done.

13:31 jaley: raek: that's what i thought... but i'm having trouble getting it to pick up my task

13:32 raek: oh, one must also add the :hooks [the.ns.with.the.hooks] to project.clj...

13:32 jaley: raek: for plugins? i thought that was just hooks

13:32 raek: * :hooks [[the.ns.with.the.hooks]]

13:32 ah

13:33 also, disregard the correction...

13:33 is your plugin in the correct namespace?

13:33 jaley: ;; (ns leiningen.axis-wsdl)

13:34 raek: and there is a (defn axis-wsdl ...)?

13:34 jaley: raek: yeah

13:34 raek: and the file is in src/leiningen/axis_wsdl.clj ?

13:35 jaley: raek: it's in src/clj/leiningen/axis-wsdl.clj, with src-path set to src/clj. should the file be named with the underscore instead?

13:35 raek: yes

13:35 jaley: raek: i'll give that a go then. do you know the reasoning behind that, out of interest?

13:35 raek: this has to do with valid java class names

13:36 * jaley isn't surprised

13:37 raek: src/leiningen/axis_wsdl.clj can be AOT compiled into classes/leiningen/axis_wsdl__init.class

13:37 and the class name has to match the file name

13:39 sorry for mixing up hooks and plugins... now I need to eat

13:39 jaley: raek: cool - thanks for the help

13:43 uninverted: What's the simplest way to create a directory in clojure?

13:48 dnolen: uninverted: (require '[clojure.java.io :as io]) (.mkdir (io/file "/some/path"))

13:52 uninverted: dnolen: Thanks

14:03 freakazoid: I'd like to use the BitTorrent mainline DHT from Clojure. Anyone know of a java or clojure library that will let me do this?

14:03 looks like Snark is gone and never supported the DHT in the first place.

14:03 And I don't think Azureus suppors the mainline DHT

14:11 Hmm, maybe I should use JXTA instead

14:43 jaley: hmmmm.. lein repl, (use 'leiningen.mytask) -> nil ; seems to work fine. but lein mytask tells me that's not a valid task, and lein help mytask gives me a FileNotFound exception. any suggestions?

14:48 DanielGlauser: /msg NickServ identify 1l2gbOGH

15:29 LauJensen: /query hugod ping?

15:30 hugod: LauJensen: hi

16:04 petrilli: zeromq

16:11 Has anyone ever gotten ZeroMQ and Clojure working on Mac OS X?

16:20 jaley: argh... so it seems leiningen only detects plugins in src/leiningen - ignoring :source-path from the project.clj file. anyone know if this is intentional?

16:21 LauJensen: jaley: I think it is, maybe you should try cake

16:21 TeXnomancy: jaley: the classpath for leiningen is fixed at boot; you can't change it at runtime

16:22 so once you've read project.clj, it's too late

16:22 you can only change the classpath of your project

16:22 LauJensen: well, you can acccess both leins cp and your projects cp

16:24 jaley: TeXnomancy: ok it's cool. my project had a src/clj and a src/java, so I assumed the cp for leiningen would be the same as specified in my project.clj. this works fine though

16:24 TeXnomancy: jaley: a few things have to be hard-coded in due to the inflexibility of the JVM

16:24 sad but true

16:24 LauJensen: TeXnomancy: Which inflexibility?

16:25 TeXnomancy: I guess it comes down to the deprecatedness of add-classpath

16:26 LauJensen: Guess so. Still works though. But Ive never had a build task which needed more than the actual projects cp

16:27 ihodes: wow, a few hour respite from school-work and i've finished up the draft of the first half of my Clojure IO essay/tutorial/howto

16:27 TeXnomancy: yeah, and I've never seen the point of changing :source-path either, so there you have it.

16:28 ihodes: LaTeX is the cause of much of my lost time. i see NO HUMOR in your name, Technomancy

16:28 ;)

16:28 LauJensen: ihodes: I think TeXnomancy != technomancy

16:29 ihodes: haha alright

16:29 LauJenson: then i doubly object!

16:30 LauJensen: hehe. I gotcha. TeXnomancy your nick is a little bit unfortunte to be honest, would you consider using 'clabango!' instead please?

16:54 TeXnomancy: ~suddenly

16:54 clojurebot: CLABANGO!

17:07 Nikelandjelo: Is there a way to "clean" memory for function, which was memoized?

17:08 To reset it

17:11 LauJensen: Nikelandjelo: Just re-memoize it ?

17:17 Nikelandjelo: Laujensen: Actually, I have a bit different problem: my function is recursive, so it should be defined as (def my-fun (memoize (fn [] ... ) ) ) .But it also depends on some outer vars. This vars change sometimes, but already memorized something. I think I should pass this outer vars as parameters to function.

17:19 nex_: does it make sense to you that when using the functions from clojure.set, and any of the atributes is not a set, then it could be considered a set with only that object? for example (clojure.set/intersection 5 #{3 4 5}) => #{5}

17:22 jaley: sounds a bit dangerous... i've done that a few times by mistake, and treating it as a set would've masked a bug

17:27 nex_: jaley: true, it might not be too convenient in practice

17:27 jaley: (Runtime/getRuntime)

17:27 arse, sorry

17:28 amalloy: Nikelandjelo: yes, it is in general very dangerous to depend on global variables. that makes a function impure, and a lot of the things that operate on functions (eg memoize) depend on purity

18:49 alpheus: Nikelandjelo: If you need access to the cache used my memoize, see http://www.paullegato.com/blog/memoize-reset-clojure/ -- the caveats others mentioned apply, of course

18:50 s/used my/used by/

18:50 sexpbot: <alpheus> Nikelandjelo: If you need access to the cache used by memoize, see http://www.paullegato.com/blog/memoize-reset-clojure/ -- the caveats others mentioned apply, of course

18:51 alpheus: that's a cute bot feature

18:57 amalloy: alpheus: personally i'd rather it didn't do that; it's not hard to do the substitution in your head, and it takes up screen real estate

18:58 sexpbot: i wonder, are you as chatty as clojurebot?

18:58 clojurebot: see, sexpbot just isn't as smart as you are

18:58 clojurebot: sexpbot is there is another

19:00 amalloy: clojurebot: sexpbot is an impostor

19:00 clojurebot: Ack. Ack.

19:08 freakazoid: "sexp" in scheme should be "sex?"

19:09 coldhead: close as most programmers get to it amirite

19:09 :(

19:11 airolson: no, you're not :P

19:14 coldhead: sorry, i was wryly self-deprecating. as a matter of fact i am having sex right now

19:16 freakazoid: yeah, not me eihter.

19:16 I get a ton of sex in second life.

19:17 amalloy: freakazoid: now you're just encouraging him

19:19 freakazoid: What, are you saying SL sex isn't real sex?

19:21 kutku: SL sex? hahaha

19:26 amalloy: so i've noticed that using destructuring in function arglists causes (doc f) and slime's prompting for (f <point>) to look ugly. i can add {arglists} metadata to my functions to present a cleaner look, but is there a way to have it automatically use :as my declarations in the arglist?

19:27 eg (defn myfunc [{name :fname last :lname :as person}]) automatically get the simple arglist of [person]?

20:00 http://gist.github.com/619722 is a version of max-key that doesn't apply the key more often than is necessary; anyone think this should get into contrib?

20:20 defn: what's the best way to talk to mongo with clojure?

20:21 the wrapper i found seems awfully dated (2009)

20:36 dakrone: defn: http://github.com/somnium/congomongo perhaps?

20:36 Raynes: defn: I use congomongo.

20:36 defn: It's definitely not dated.

20:36 duck1123: +1 for congomongo

20:39 notsonerdysunny: what happens when I do "cake swank" ..? I was expecting that all the ".clj" files in the project will be in loaded when I start a swank-clojure in that project. but it seems like I have to load them explicitly via" C-c C-k " .. can anybody help?

20:39 Raynes: notsonerdysunny: cake swank only puts them on the classpath.

20:39 You still have to load files that you want to use.

20:39 notsonerdysunny: Also, we have a #cake.clj channel. :>

20:40 In case you have more questions.

20:40 notsonerdysunny: Raynes: is it possible to make it load all the clj files when I start the swank server

20:46 dbleyl: hello - looking for a way to call a final protected method of a base class extended with gen-class.

20:47 seen several posts, but nothing recent.

20:55 Raynes: I believe wall-hack-method does what you want. It's in contrib somewhere. Not sure where.

20:57 dbleyl: Thanks, I'm checking it out now...

21:00 Raynes: dbleyl: Looks like it's in c.c.java-utils

21:01 amalloy: M-q in paredit mode behaves strangely for me if my function has a metadata map. does this happen to anyone else?

21:18 bhenry: which java should i install for clojure in ubuntu?

21:19 Raynes: bhenry: openjdk is fine.

21:19 dbleyl: Raynes: thanks - I'm running 1.3 master, and it's looks like those methods have been moved.

21:19 Raynes: bhenry: It's in the Ubuntu software repositories, so you can grab it from synaptic.

21:19 dbleyl: Oh. Didn't know that.

21:20 bhenry: the first line in this guide http://riddell.us/ClojureOnUbuntu.html didn't work for me on ubuntu server 10.10

21:20 package has no installation candidate

21:20 Raynes: One moment.

21:21 bhenry: Try sudo apt-get install openjdk-6-jdk

21:21 clojurebot: slime-installer is http://github.com/technomancy/clojure-mode/blob/0f28b61de90ce8a09d75bf1668ef3f1c200f9c52/clojure-mode.el#L560

21:21 dbleyl: Raynes: looks like it's in c.c.reflect and is called call-method now.

21:22 Raynes: dbleyl: Oh, neat.

21:22 bhenry: Raynes: thanks

21:23 Raynes: bhenry: The package that it was trying to install appears to exist int he Lucid Lynx repositories. Might have been removed in 10.10

21:24 bhenry: That guide looks kind of old. The official github repos for Clojure and contrib are github.com/clojure/clojure and github.com/clojure/clojure-contrib respectively.

21:25 We also have things like cljr and cake for starting REPL and running individual files, which pretty much kills the point of rolling your own clj script in most cases.

21:26 bhenry: i searched for "install java for clojure on ubuntu" and that was the first hit. i do everything with lein and don't actually ever install clojure

21:27 Raynes: Oh. I just assumed... ;)

21:29 bhenry: yeah i just needed the java package. i'm playing with ubuntu server for the first time. i want to familiarize myself with running apps on virtual machines.

21:38 dbleyl: :Raynes call-method did exactly what I needed. Thanks a bunch.

21:38 bye.

22:19 freakazoid: oh look at that, I don't actually need clojure installed. Just lein

23:05 TaigerRobocot: I need to convert 1 Java method to clojure, anybody could help me?

23:20 Bahman: Hi all!

23:25 freakazoid: I don't know java :(

23:26 Hey Bahman likes both erlang and clojure too

23:26 Bahman: Yo freakazoid!

23:28 freakazoid: http://programming-puzzler.blogspot.com/2010/08/racket-vs-clojure.html complains about the fact that an agent's mailbox can consume all resources - but the same is true of Erlang, so clearly it's something that can be dealt with.

23:29 And the complaint about STM (that long-running transactions might never finish) seems like it also exists in RDBMSes and in Haskell's STM

23:31 I guess much of that's already addressed in the comments

23:36 ossareh: TaigerRobocot: can you expand on your request a bit?

23:41 TaigerRobocot: public static int testarQuadradoPerfeito(int aux, int num, int numero) { if (aux > numero) { return 0; } else { if (aux == numero) { System.out.println(numero + " is a perfect square."); return numero; } else { aux = aux + num; return num + testarQuadradoPerfeito(aux, num + 2, numero); } } } }

23:42 ossareh: erg, could you put it on pastebin please?

23:42 TaigerRobocot: yeah

23:44 ossareh: I created this code in java and I need to convert to clojure because I am making a university homework. Clojure is dificult - Link: http://pastebin.com/g7MnnTMW

23:45 I am calculating if a number is a square perfect without use Math library

23:55 amalloy: TaigerRobocot: you probably want to look into the (cond) function in clojure - it's the lispy way of doing if/elseif/else

23:57 so a sketch of your code (not doing homework for you!) might be (cond (some-condition) 0, (condition-2) (recur some-val), :else false))

Logging service provided by n01se.net