#clojure log - Nov 02 2009

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

1:24 nipra: How can I get "First Line.\nSecond Line." to be printed as two separate lines in REPL?

1:25 wahjava: nipra, (println "First Line.\nSecond Line.") ??

1:27 nipra: wahjava, thanks a lot :-)

1:27 wahjava: you're welcome, nipra .

6:00 gerry`: hello

6:00 ordnungswidrig: hi

6:00 gerry`: in clojure, when to use "_", any docs about it?

6:00 ordnungswidrig: when you don't care about the binding

6:01 gerry`: ,(def a [1 2 3])

6:01 clojurebot: DENIED

6:01 gerry`: ,(let [a [1 2 3]]

6:01 clojurebot: EOF while reading

6:02 ordnungswidrig: If you define (defn foo [x _] x) foo must be called with 2 args but as you don't care about the second one, name it _

6:02 gerry`: ,(let [a [1 2 3]] (case a [1 _ 3] "ok" "oops"))

6:02 clojurebot: java.lang.Exception: Unable to resolve symbol: case in this context

6:02 gerry`: ,(doc deftype)

6:02 clojurebot: "clojure.contrib.types/deftype;[[type-tag constructor-name docstring? attr-map?] [type-tag constructor-name docstring? attr-map? constructor] [type-tag constructor-name docstring? attr-map? constructor deconstructor]]; Define a data type by a type tag (a namespace-qualified keyword) and a symbol naming the constructor function. Optionally, a constructor and a deconstructor function can be given as well, the defaults being

6:04 gerry`: case not support "_"?

6:04 hiredman: _ is not special

6:04 opqdonut: _ is just an identifier

6:04 gerry`: and?

6:04 opqdonut: you could use, for instance, "unused" instead of it

6:04 hiredman: ,(let [_ 1] _)

6:04 clojurebot: 1

6:04 hiredman: you don't have to "support" it

6:05 it's just a convention

6:05 gerry`: ,[1 _ 2]

6:05 clojurebot: java.lang.Exception: Unable to resolve symbol: _ in this context

6:05 hiredman: ,[1 x 2]

6:05 clojurebot: java.lang.Exception: Unable to resolve symbol: x in this context

6:06 gerry`: ,(defn hello [_] (println "hello"))

6:06 clojurebot: DENIED

6:09 gerry`: ,(let [a (fn [_] (println "hello"))] (a "ok"))

6:09 clojurebot: hello

6:11 gerry`: hiredman: any wild character in clojure just like _ in prolog?

6:11 [1 _ 3] could match [1 "ok" 3] [1 "anything 3] etc?

6:12 hiredman: clojure doesn't do pattern matching

6:13 there are at least two macros floating around that implement pattern matching, but it is built into the language

6:14 er

6:14 not built into the language

6:14 gerry`: which?

6:15 hiredman: which macros?

6:15 gerry`: yes

6:15 hiredman: there is one in contrib

6:15 ,(doc contrib)

6:15 clojurebot: Gabh mo leithscéal?

6:15 hiredman: er

6:15 ,(doc match)

6:15 clojurebot: "clojure.contrib.types/match;[[value & clauses]]; Given a value and a list of template-expr clauses, evaluate the first expr whose template matches the value. There are four kinds of templates: 1) Lists of the form (tag x1 x2 ...) match instances of types whose constructor has the same form as the list. 2) Quoted lists of the form '(x1 x2 ...) match lists of the same length. 3) Vectors of the form [x1 x2 ...] match vector

6:16 hiredman: ~google clojure pattern matching

6:16 clojurebot: First, out of 1560 results is:

6:16 brool » Pattern Matching In Clojure

6:16 http://www.brool.com/index.php/pattern-matching-in-clojure

6:17 gerry`: i think case should support pattern match

6:18 hiredman: I think Kings was an cool show and NBC made a bad movie canceling it

6:18 gerry`: just like "match" in scala, "case" in haskell

6:19 hmm

6:21 hiredman: gerry`: http://clojure-log.n01se.net/date/2008-10-09.html#13:32

6:22 gerry`: ok,thx

8:08 megane: chouser: i think shell-out/sh is leaking file handles

8:08 here's the reason http://dlinsin.blogspot.com/2007/02/javas-runtimeexec-openes-too-many-files.html

8:11 lisppaste8: megane pasted "shell-out/sh" at http://paste.lisp.org/display/89677

8:12 patricius_: i'm wondering, could a web server be written in clojure with the same kind of throughput that yaws, the Erlang-webserver, exhibits?

8:12 i'm trying to grasp the differences in terms of scheduling processes/threads

8:12 megane: that's my try at fixing sh

8:12 ambient: i wonder how easy it is to understand my project later when most of the stuff is just macroes upon macroes :p

8:13 hiredman: in some sense that is the measure of a macro

8:13 ambient: quess i have to crank up the documentation

8:13 chouser: megane: huh. I could have sworn I was carefully closing all the streams. :-P

8:13 megane: have you signed the CA?

8:24 ordnungswidrig: ambient: you mean "macros all the way down"? :-) en.wikipedia.org/wiki/Turtles_all_the_way_down

8:25 ambient: well, not all the way. just a lot of macros calling other macros calling other macros

8:29 it's actually constructing a whole sub-program... :|

8:29 defined by given parameters

8:29 oh wait... i think that's the definition of a macro

8:44 _ato: patricius_: Clojure doesn't have lightweight threads (aka green threads) etc that I assume Erlang's processes are

8:45 patricius_: but you could certainly write a high-performance web server by using non-blocking sockets, select() and a thread pool

8:49 megane: chouser: CA? what's that

8:49 chouser: Clojure's agents are not entirely unlike green threads

8:50 megane: ah.. contributor agreement.. no i haven't

8:52 _ato: chouser: true, though I assume in Erlang you can spawn a few thousand processes and have all of them block simulataneously on read() cheaply (which is probably implemented under the hood using select). You couldn't do that with agents as you'd use up the thread pool or create a few thousand OS threads (which would be bad)

8:52 chouser: _ato: true

8:53 welll, true that that's how Clojure behaves and that it would be bad for thousands of sockets. I don't know if it's ok in Erlang or not.

8:53 megane: chouser: you'll have to fix it yourself :P

8:53 chouser: megane: np

8:54 AWizzArd: Although Jetty for example can handle a few thousand threads concurrently.

8:55 And in the past I think Java had green threads and then switched to OS threads.

8:55 _ato: http://docs.codehaus.org/display/JETTY/Continuations

8:55 huh

8:55 interesting

8:56 it "suspends" a thread by throwing an exception and retries later

8:59 cemerick: is anyone writing web servers anymore? ;-)

9:01 _ato: but yeah, from a performance stand-point select and a thread pool (like what jetty does) is going to be just as good as whatever erlang does, because that's how erlang will be implented underneath. The only advantage with erlang is you don't have to be as explicit with state, you can use the call stack as your state

9:01 ambient: this can't be abstacted with macro-fu?

9:02 _ato: you could probably come up with something good enough, I think you'd need continuations to do it really nicely

9:05 cemerick: heh, if that were the case, apache would've been written in scheme

9:06 or lighty, or nginx, or...

9:07 _ato: for most HTTP stuff it doesn't matter as most HTTP is stateless

9:08 cemerick: oh, so we're talking about a seaside-esque thing?

9:08 _ato: yeah

9:09 cemerick: I remember enjoying working with webobjects, which had great transparent session management -- totally resumable, stateless as far as the developer was concerned, etc.

9:09 AWizzArd: Btw, when I want to read from an input stream there is the .available method that tells me how much i can read without blocking. Is there a way to have my thread sleeping for N msecs OR until some more data is available?

9:10 _ato: I have horrid memories of WebObjects, a major app at work is written in it and WO is buggy as hell. But yeah the continuations stuff is neat

9:11 cemerick: That's very surprising to hear. It was rock-solid when I used it.

9:11 _ato: AWizzArd: yes, but it's annoying. http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/Selector.html

9:11 cemerick: could be cause we're running on Solaris

9:11 actually WO itself is mostly okay, it's mainly the database layer EnterpriseObjects or whatever it is that we had trouble with

9:12 things like if you loop through a list of EO objects with a java for-each style loop half of the objects are null, where if you do a for (i=0; i<10; i++) {} style thing it works fine

9:12 cemerick: _ato: heh -- that's actually the piece of WO that is most widely acknowledged as being very innovative. Really set the bar w.r.t. ORM.

9:21 _ato: yeah, on paper it's great, but we just ran into lots of implementation problems. Like I said though, we're running on Solaris inside Tomcat which is not really what it's designed for and it's huge (poorly designed) app with a insanely complicated database schema. (I work at a library and boy do libraries love overcomplicated data schemas)

9:25 AWizzArd: _ato: oh :(

9:25 Can you give one or two short examples of where Tomcat is not doing what it was designed for?

9:27 _ato: AWizzArd: sorry that wasn't clear, I mean WebObjects isn't designed to run in Tomcat on Solaris. It's supposed to run on OS X server... and I don't think it normally runs in a container

9:36 tomcat is fine

9:36 well mostly fine, it has some weirdnesses but mostly they're due to JVM limitations

9:44 cemerick: Tomcat is pretty darn solid. Holds its own against just about any other servlet container for 95% of use cases.

9:51 anyone pay github for private git hosting, and want to share experiences?

9:56 AWizzArd: What is a good way to follow the flow of (or debugging support for) my app? contrib.logging?

9:56 chouser: I think there is at least once "trace" lib around

9:58 raek: has there been any effort to make DWIM-like things for clojure?

9:59 and another question: are the original s-expressions kept when code is compiled?

10:02 chouser: raek: 1) I don't know what you mean. 2) no.

10:08 ambient: i have a java callback function that i need to create with clojure. how do i enforce the types that are used to call that function?

10:08 like "int javafunc(float[] foo, int bar)"

10:09 (fn [#^floats foo ??? bar] 0) is my best idea so far

10:10 cemerick: ambient: type hints do not enforce types, they provide a way to avoid reflection

10:11 ambient: ok

10:11 cemerick: if you need to provide a typed API to some Java code, you should proxy or gen-class an interface

10:24 AWizzArd: Who of you used clojure.contrib.logging? I would like to know where the log output is landing, and how I can turn logging of.

10:48 Does contrib have a without-exception macro, which returns nil in case of an exception? (try (some-operations-here) (catch Exception e nil))

10:53 dakrone: AWizzArd: (defmacro trycatch [f] `(try ~f (catch Exception e#))) ?

11:10 stuartsierra: ,(binding [+ -] (+ 1 1))

11:10 clojurebot: 2

11:10 stuartsierra: Why doesn't that work?

11:11 rhickey: + has inlining

11:11 stuartsierra: ah, ok

11:11 ,(binding [mod -] (mod 1 1))

11:11 clojurebot: 0

11:12 danlarkin: bad example :)

11:22 arsatiki: I just finished Halloway's book. Time to pass it around

11:23 blackdog_: stuartsierra, I'm having issues with http.agent, it doesn't seem like it's blocking, on a simple get, with one request relying on another to finish

11:23 AWizzArd: blackdog_: you mean (string (http-agent ...)) yes?

11:23 blackdog_: yes

11:23 AWizzArd: I noticed the same phenomenon.

11:23 blackdog_: i've just replaced httpagent with apache httpclient and my code and server are both good

11:24 ok, as long as I'm not alone, I'll send some details to the list later

11:24 AWizzArd: And that's really strange, because string under the hood calls result which uses await to finish.

11:24 But it is important that there must be some delay until await gets called.

11:24 blackdog_: i get a connection not closed error

11:24 AWizzArd: yes

11:25 blackdog_: when it tries to set the options for the next connection

11:25 AWizzArd: but if you (let [a (http-agent ...)] (Thread/sleep 1000) (string a)) then it would work

11:25 blackdog_: like it didn't disconnect,

11:25 AWizzArd: or even better use (await-for a 1000) instead of Thread/sleep

11:25 blackdog_: yes, if I wait at the repl and reissue, it's all good

11:26 that's scalable ;)

11:26 AWizzArd: Maybe stuartsierra has an idea why this explicit await-for is needed.

11:29 churib: is there a fn like "some" which returns the first element for which pred is true?

11:30 stuartsierra: This was reported on the list; there's a patch, working on it now

11:30 rhickey: ,(first (filter odd? (range 1000000000000)))

11:30 clojurebot: java.lang.ExceptionInInitializerError

11:31 blackdog_: stuartsierra, ok, thanks

11:31 rhickey: ,(first (filter odd? (range 1000000)))

11:31 clojurebot: 1

11:31 churib: thanks!

11:31 rhickey: churib: leverages the fact that filter is lazy

11:32 churib: yeah, easy solution - i was to blind to see it :)

11:38 spuz: rhickey: do I need to sign the CA to raise issues in clojure or clojure contrib?

11:39 rhickey: spuz: no, you can use the Support tab there

11:42 spuz: ah not sure how i missed that

11:43 stuartsierra: blackdog_: should be fixed on master now

11:47 AWizzArd: stuartsierra: sounds good, thx

11:48 spuz: stuartsierra: you applied the patch?

11:48 (this is alex by the way)

11:48 rhickey: stuartsierra: thanks for fix to http://www.assembla.com/spaces/clojure-contrib/tickets/41

11:51 stuartsierra: welcome

11:51 spuz: no, I fixed it a different way

11:52 spuz: cool

11:52 You got a good number of tickets closed today :)

11:53 stuartsierra: yeah, working my way through

11:55 rhickey: when a core patch is ready, should I assign it to you or just mark it "Ready to Test"?

11:56 rhickey: stuartsierra: just mark as ready to test, thanks

12:24 Kjellski: Hi there...

12:29 replaca: Kjellski: hi

12:29 Kjellski: replaca : hiho =)

12:30 Anyone got the enclujure shortcut for switching to repl and back in mind?

12:32 ,(doc loop)

12:32 clojurebot: "([bindings & body]); Evaluates the exprs in a lexical context in which the symbols in the binding-forms are bound to their respective init-exprs or parts therein. Acts as a recur target."

12:37 cemerick: Kjellski: Cmd-T on mac, probably Alt-T on windows.

12:39 Kjellski: cemerick : thanks!

12:40 cemerick : it was C-t but the hint did the trick =)

12:40 cemerick: The mapping between Cmd and Alt/Ctrl is tough to nail down in general.

12:43 Kjellski: Sure it is... do you have a Enclojure Cheat Sheet? I´m actually switching from emacs and on the homepage they just wrote look at the context menus...

12:43 blackdog_: stuartsierra, thanks, http-agent working as advertised

12:45 cemerick: Kjellski: if you open the netbeans preferences dialog, and go into the keybindings section, you can look at just the clojure bindings

12:46 Kjellski: cemerick, something I could have done... sorry, a bit frightened from the emacs options "menu" ...

12:46 cemerick: Kjellski: you're in a much more hospitable land now :-)

12:48 Kjellski: cemerick : *laughing*

12:48 cemerick: I'm surprised there's no one around to yell at me for my emacs trolling. :-P

12:49 * tomoj yells

12:49 Kjellski: *g* thought so too...

12:50 How can I get the key-value pairs out of a map?

12:50 cemerick: ,(seq {:a :b :c 5})

12:50 clojurebot: ([:a :b] [:c 5])

12:50 Kjellski: Outch... thanks again...

12:52 replaca: but maps can be used directly as seqs in most cases, so you usually don't need the (seq ...)

12:52 Kjellski: cemerick: and anotherone for you, how can I force enclojure to just indent when it´s neccessary? like tabbing in a new line will not add tabs when it is already indented the right way?

12:53 tomoj: replaca: what is an example of a case where they can't?

12:53 cemerick: right, most forms wrap inputs in an implicit seq

12:54 Kjellski: hitting return will put the new line in the right place. 'Tab' is not 'reformat' like it is in emacs. Try Ctrl-R.

12:54 Kjellski: cemerick : now its M-r ... weird... ^^

12:55 cemerick: See what I mean? :-)

12:57 Kjellski: cemerick : yes, pretty annoying

12:58 cemerick: it's worth filing a bug over. In the meantime, you can just rebind things to what you want.

12:59 Kjellski: cemerick : okay, so I´ll do that if it comes up again...

13:01 cemerick: Actually rebinding Reindent Clojure Code to TAB works just fine =)

13:01 cemerick: ha. I never tried it. I've almost forgotten that that key is there.

13:01 Kjellski: cemerick : exactly what I wanted.

13:02 cemerick : it just sais "not recommended"... but it´s heaven... =)

13:04 replaca: tomoj: I can't think of one

13:05 chouser: ,(nil? (seq {}))

13:05 clojurebot: true

13:05 chouser: ,(nil? {})

13:05 clojurebot: false

13:27 replaca: chouser always knows the subtlety!

13:27 chouser: I'm really looking forward to your book - I was happy to hear you're doing it

13:28 Kjellski: replaca : how is it called?

13:29 chouser: replaca: thanks, that's great to hear!

13:30 replaca: chouser: remind Kjellski of the title. It's in my mind as "Idiomatic Clojure"

13:30 which translates to "Chouser" in my dictionary

13:31 chouser: that's the working title, but it has it's detractors so we'll see. :-)

13:31 Kjellski: replaca : *laughing*

13:31 cemerick: a clojure book by chouser? Where do I buy? :-D

13:31 Kjellski: ./signed

13:31 chouser: aw, you guys. It's actually Fogus' book, I'm just helping.

13:31 Kjellski: Can we see drafts or is it closed till release?

13:32 cemerick: chouser: First I've heard of it. Is there an announcement somewhere? (It's been a very busy morning.)

13:32 uh, day.

13:32 chouser: Nobody's even supposed to know about it yet, but I guess it leaked. :-)

13:33 Kjellski: chouser : somewhere, somehow...

13:33 chouser: There will be a MEAP which is what Manning calls their on-line pre-release PDF thing

13:33 but we're not quite there yet. Once there's a page for it, we'll make sure everyone knows. -)

13:33 :-)

13:33 Kjellski: chouser: I´m very interested... can I just subscribe somewhere?

13:34 chouser : okay.

13:34 chouser: either fogus or my twitter, or either of our blogs I imagine.

13:34 ...for any announcements.

13:35 cemerick: chouser: well, at least you know there's a pile of interest. I'm sure everyone here will blog about it. It's about time someone banked some coin for irc time. :-)

13:35 chouser: heh. Right, I've been doing research for it right here for the last almost two years.

13:37 fogus_: My ears are burning ;)

13:37 cemerick: whoa, #clojure has a strong echo

13:37 fogus_: congrats :-)

13:38 fogus_: Thanks sir

13:38 Kjellski: *laughing* that´s what came in my mind... nice timing fogus...

13:39 fogus_: I was warned by chouser that I was getting slammed in here. ;)

13:40 cemerick: chouser: quick, trunc those logs, eh?

13:40 chouser: heh

13:40 hamza: hey guys, i have a vector of bytes [115 116 114] how can i build a string out of this? convert each byte to char then append?

13:41 chouser: ,(apply str (map char [115 116 114]))

13:41 clojurebot: "str"

13:42 chouser: ,(->> [115 116 114] (map char) (apply str))

13:42 clojurebot: "str"

13:42 leafw: what is ->> ?

13:42 ,(doc ->>)

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

13:42 chouser: just what I showed there -- allows rearranging a set of nested forms.

13:44 hamza: thx, that worked which namespace is ->> defined ?

13:44 tomoj: clojure.core

13:45 hamza: thank you, i guess my build is out of date..

13:45 leafw: would be nice to have a fn like 'doc' or 'class' that lists the complete namespace and source package of a fn.

13:45 Kjellski: chouser can I ask for your blog?

13:46 chouser: Kjellski: http://blog.n01se.net/ -- I actually share it with some friends, but everything they post is at least as interesting as what I do. :-)

13:50 Kjellski: chouser : thanks, that´s in my reader now... =)

13:50 chouser: Kjellski: thanks! No worries -- you won't be overwhelmed with posts...

13:50 What little effort I put into blogging now goes into the book instead. :-P

13:51 plus some, I should say.

13:51 Kjellski: Actually I can see a ")); at the very bottom of the blog... just my first feedback before reading ... ;)

13:52 chouser : Okay, that´s nice... I´ll wait for it...

13:57 chouser : can you see that too?

13:57 tomoj: I can

13:57 chouser: yeah, thanks.

14:00 Kjellski: Okay, nevermind... first thought that was a bit hard as a first feedback ^^

14:01 chouser: no, not at all. working on it.

14:01 but I hardly understand this blog software. so difficult. so much PHP

14:02 huh. I think I broke it.

14:03 Kjellski: I think so too...

14:04 So, sorry about killing you blog with my suggestions... but I have to leave... happy php'ing ... ;)

14:04 chouser: heh. ok, bye.

14:04 Kjellski: bye

14:15 technomancy: chouser: just make sure the book doesn't end up with the title "Programming Clojure" =)

14:15 chouser: technomancy: heh. got it.

14:17 fogus_: technomancy: Is that one taken? ;)

14:17 Chousuke: I had to code some Qt today in C++ and the machine I coded on was kind of slow so each compilation took at least a minute ;/

14:17 technomancy: fogus_: we don't want Clojure to be seen as just a copycat of Scala you know...

14:17 Chousuke: made me wish C++ were a dynamic language.

14:18 hiredman: Chousuke: that's not bad for C++

14:18 Chousuke: hiredman: mind you, it's not a big application.

14:18 fogus_: technomancy: I guess that doesn't bode well for my planned chapter "Adding a Type System to Clojure"

14:18 hiredman: while I was working on my reader I routinely rebuilt clojure over and over, which when I was on my netbook sometimes took five minutes

14:19 fogus_: (just kidding BTW)

14:19 Chousuke: it wasn't really fun to have to wait for a minute after you make some quick ten second edit and check that it works ;P

14:20 cemerick: developing on a netbook? ouch.

14:20 chouser: "How to work around Clojure deficiencies: immutability and dynamic typing"

14:20 hiredman: D:

14:20 deficiencies?

14:20 chouser: that's chapter 2!

14:21 it includes macros that let you have mutable locals: mlet

14:21 clojurebot: Holy Crap.

14:21 hiredman: I use my netbook a lot

14:22 tomoj: I develop on my netbook almost all of the time

14:22 Chousuke: chouser: are you really going to call them deficiencies? :P

14:23 * chouser takes it up another notch

14:23 hiredman: it's just so easy, the computer is so small and it's right there, and you're just going to do some exploritory coding *500 lines of code later* huh, I guess I'm done

14:24 chouser: Chapter 4 is entirely devoted to a reader patch that allows you to use C++ syntax to generate Clojure so you never have to look at parens.

14:25 hiredman: http://gist.github.com/223246 <-- :P

14:25 tomoj: I can't bring my imac out onto the patio while I smoke

14:26 Chousuke: hiredman: argh.

14:27 chouser: ok, just so it's clear I was kidding about every bit of book content info above.

14:28 hiredman: cc is a macro that, at macro expansion time, generates a .c file and compiles it, then returns a fn that when executed executes the native binary

14:31 sort of a prototype, ideally you'd want to generate a shared library, not an executable, and have the macro return a fn that calls functions from the shared lib via jni or jna or something

14:47 chouser: for anyone that cares, my blog is un-broken again. :-P

15:02 djork: http://www.jwz.org/doc/java.html <-- Clojure sure goes a long way towards addressing these complaints

15:03 hiredman: I finished coders at work this morning

15:04 gyom: nice

15:04 hiredman: djork: it's also at least ten years old

15:04 gyom: hiredman : they all rant against C++, or almost all of them

15:04 hiredman: gyom: and the last few against C

15:04 gyom: hiredman : but I'm halfway through

15:05 djork: its ten years old but Java hasn't fixed much of it in that time

15:05 gyom: I read an older book, something like "Programmers at work", and I thought the interviewer was doing a better job

15:05 hiredman: djork: generally there are two classes of complaints against java, jvm issues and The Java™ Programing Language

15:06 djork: the JVM is much much better, that's for sure

15:06 gyom: in Coders at work it seems like the interviewer jumps back to the literate programming thing when it's not that relevant

15:07 hiredman: gyom: well it's interesting that taocp is mentioned in every interview, but no one uses Knuth's literate style

15:07 chouser: djork: clojure also doubles-down on some of those (like interfaces)

15:07 djork: yeah

15:08 gyom: hiredman : Yes, they all have a copy of taocp, all they all discuss whether math is relevant or not.

15:09 hiredman: you need a certain bit of math just to be able to use taocp as a reference

15:10 gyom: sure, you need math to understand why log(n) is O(n^{1+epsilon}), at least

15:10 hum

15:10 n log n, that is

15:11 hiredman: the bibliography of coders at work shall be mined for material

15:11 there were some nice quotes here and there too

15:11 ~programmer

15:11 clojurebot: "There has to be something a little wrong with you for you to be a really good programmer." -- L Peter Deutsch

15:13 hiredman: there is another one about programmers being the worst optimizers

15:52 * tmountain just discovered clojure.contrib.repl-utils/source

15:52 tmountain: one more reason to love clojure

15:54 chouser: I live by doc/source/show and occasionally javadoc

15:55 hiredman: javadoc javadoc javadoc

15:55 froog: has there been any discussion about docstring format, something like doclet?

15:56 hiredman: javadocs are so great

15:58 * chouser can't tell if hiredman is kidding

15:59 hiredman: I'm not

16:00 chouser: hm... still sounds like sarcasm. :-)

16:00 hiredman: ~hiredman

16:00 clojurebot: hiredman is an evil genius.

16:07 cemerick: one of these days, I'm going to have to bite the bullet and put together a javadoc generator for clojure projects.

16:08 hiredman: *huge list of IFn's that take Objects*

16:09 cemerick: having defclass around should make it somewhat easier to do, actually

16:11 technomancy: I'd have a lot happier time with javadoc if it didn't use frames for everything

16:12 makes mouseless browsing trickier

16:12 hiredman: *shrug*

16:12 technomancy: but I find that usually the slime inspector is a much more convenient alternative ... need to get a blog post up about that.

16:12 tomoj: does the slime inspector show javadoc comments?

16:13 froog: technomancy: that's more a result of how the javadoc was generated, isn't it?

16:13 technomancy: tomoj: no, but usually javadoc comments are stuff like getFoos: gets all the foos from the object.

16:13 hiredman: hyperlinked autogenerated docs are genius

16:13 technomancy: so you're usually not missing much

16:13 tomoj: yeah

16:13 hiredman: http://www.igniterealtime.org/builds/smack/docs/latest/javadoc/

16:13 technomancy: there are exceptions, but that's the common case

16:14 froog: there are nicer templates, but they are not often used. I guess I could generate my own.

16:15 hiredman: clojuredoc should generate some kind of wikifiable information

16:15 froog: technomancy: I meant that you can generate the doc with another doclet, like texidoclet, if it was up-to-date

16:15 then you could generate info files from there

16:16 technomancy: froog: yeah, having a copy of the source checkout can be a hassle at times. but if you have it and the docs are good, that's probably the way to go.

16:16 chouser: I use 'show' until I need a more meaningful javadoc comment like "make sure you always call foo before bar"

16:16 technomancy: yeah... slime inspector is like a hyperlinked version of repl-utils/show

16:16 froog: technomancy: true, you need the source for that

17:06 ordnungswidrig: hi all

17:07 djork: hi!

17:07 my friend wants to start learning programming tonight

17:07 I want to teach him Clojure

17:07 but...

17:07 the Java part might be a problem

17:07 ordnungswidrig: djork: could be a magic night then

17:08 hiredman: teach him lua by writing a lisp interpreter in lua

17:08 ordnungswidrig: djork: or start with the lambda calculus. a solid theoretical founding cannot be wrong ;-)

17:08 djork: so why do you think the java part is a problem?

17:09 djork: Lua might be good

17:09 Java is troubling because he has no OO experience

17:09 no programming at all in fact, just web markup

17:10 jasapp: what's wrong with clojure?

17:10 ordnungswidrig: djork: I see, clojures stack traces must be frightning to him them

17:11 jasapp: scheme, drscheme in particular, is great for that sort of thing

17:11 djork: yeah the stack traces might be rough

17:13 DrScheme could be good

17:13 ordnungswidrig: btw. is there a plan to improve the stack traces anyway?

17:13 hiredman: ordnungswidrig: maybe after or as part of cinc

17:13 ordnungswidrig: cinc?

17:13 hiredman: clojure in clojure

17:14 ordnungswidrig: turtles all the way down, again :-)

17:14 hiredman: lua is a neat little language, a simple lisp would be, maybe a few hundred lines

17:15 ordnungswidrig: slime masters available? how to I "slimify" a buffer after connecting to a running swank using slime-connect?

17:15 technomancy: M-x slime-mode

17:15 but that should happen automatically for you

17:16 you should launch slime using M-x slime rather than M-x slime-connect btw

17:16 ordnungswidrig: technomancy: I start swank by maven

17:16 technomancy: To avoid all kinds of classpath issues

17:17 technomancy: oh gotcha. it still should activate slime-mode for you though. wonder what's going on.

17:17 ordnungswidrig: M-x slime-mode enables slime[clojure] but the keybindings are missing...

17:17 technomancy: maybe it's a slime-swank-emacs-version isssue. using slime 2009-05-17

17:18 should I switch to the epla branch?

17:20 technomancy: actually the "maven" branch is the current release candidate

17:21 check the swank-clojure mailing list, I haven't updated the docs in the project yet.

17:21 ordnungswidrig: huh, I don't see this one on github

17:25 djork: oh hey, nice clojure cheatsheet for http://cheat.errtheblog.com/

17:26 hmm, not the best ever

17:31 ordnungswidrig: hmm, string contains in clojure? Only via java or is there an idiomatic way?

17:35 tomoj: I think there are generally not clojure wrappers for things that are very easy to do with java

17:36 ordnungswidrig: which makes sense in a way

17:38 dnolen: ,(re-find #"e" "Hello")

17:38 clojurebot: "e"

17:38 dnolen: ordnungswidri ^

17:38 ordnungswidrig: *g*

17:41 * technomancy wishes for callable regexes. =\

17:41 technomancy: they would make such great predicates

17:42 ordnungswidrig: technomancy: can't you macro it?

17:42 dnolen: ordnungwidri: technomancy means something like (#"e" "Hello") -> "e", can't macro that.

17:43 technomancy: in a turing-tarpit kind of sense such a thing might be technically possible, but not practically.

17:43 hiredman: technomancy: fnparse :D

17:43 spuz: How does one retrieve input from the stdin or repl?

17:44 hiredman: *in* is boundg to System.in by default

17:47 ,(hiredman.clojurebot.factoids/predicate-style-definition {:remainder "foos | are | great"})

17:47 clojurebot: hiredman: Pardon?

17:47 hiredman: clojurebot: jerk

17:47 clojurebot: excusez-moi

17:48 hiredman: ,(predicate-style-definition {:remainder "foos | are | great"})

17:48 clojurebot: [{:subject "foos", :object "great", :predicate "are"} {:remainder nil}]

17:48 hiredman: ,^(first (predicate-style-definition {:remainder "foos | are | great"}))

17:48 clojurebot: {:type :predicate-style-definition}

17:50 hiredman: clojurebot: foos | are | great

17:50 clojurebot: c'est bon!

17:50 hiredman: clojurebot: foos?

17:50 clojurebot: foos are great

17:51 hiredman: clojurebot: forget foos | are | great

17:51 clojurebot: I forgot that foos are great

17:52 ordnungswidrig: hiredman: what's that goog for? Teachning clojurebot?

17:52 s/goog/good/

17:52 hiredman: clojurebot's factoid stuff uses fnparse for parsing

17:52 ordnungswidrig: me is not expected to understand fnparse, right?

17:53 hiredman: ordnungswidrig: clojurebot by default assumes "is" as the predicate

17:53 but using that style with the predicate seperated out by the bars you can use arbitrary predicates for factoids

17:54 ordnungswidrig: ah, I see.

17:54 hiredman: clojurebot: I | can | dance

17:54 clojurebot: Ok.

17:54 hiredman: clojurebot: I?

17:54 clojurebot: I can dance

17:54 hiredman: clojurebot: forget I | can | dance

17:54 clojurebot: I forgot that I can dance

17:54 ordnungswidrig: something different. How can I use functions that will be declared later?

17:54 hiredman: declare

17:55 ordnungswidrig: hiredman: hmm, some things are just too obvious

17:55 spuz: hiredman: This appears to work, but do you know if there's a pre-baked function in clojure or clojure contrib that does the same? (defn prompt [msg] (println msg)(second (read-lines *in*)))

18:07 ordnungswidrig: http://clojure.pastebin.com/m648ea526

18:07 how can I simplify this one?

18:08 basically I'm passing a context through a serieas of function applications

18:09 hiredman: ->

18:10 ,(1 (+ 2) (* 4))

18:10 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

18:10 hiredman: grrr

18:10 stupid inlining

18:10 ,(1 (#'+ 2) (#'* 4))

18:10 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

18:10 hiredman: oh

18:10 mea culpa

18:10 ,(-> 1 (+ 2) (* 4))

18:10 clojurebot: 12

18:11 ordnungswidrig: hiredman: no with destructurizing?

18:11 hiredman: hmmm

18:11 yeah

18:12 ordnungswidrig: cries for a monad, I think.

18:13 hiredman: (-> ctx do-foo ((juxt first (comp do-bar second)))

18:13 etc etc :P

18:14 ordnungswidrig: hiredman: nice. event point-free

18:14 hiredman: pointless :P

18:15 ordnungswidrig: yes :-) clojure is acutally often point-free. I wonder it's because of the style in #clojure or if the language encourages a point-free style.

18:16 The-Kenny: Because point-free = good :)

18:16 ordnungswidrig: The-Kenny: up to a limit

18:17 The-Kenny: ordnungswidrig: Of course.

18:17 ordnungswidrig: I remember really scary pint-free expression in #haskell

18:17 the flip-apply-flip-flip-apply-of-death

18:18 The-Kenny: haha :D

18:18 ordnungswidrig: more a solution to rubic's cube than a haskell function

18:18 hiredman: oh man

18:19 * hiredman greps his logs

18:19 ordnungswidrig: where, hmm, the haskell folks love algebra. so this seems all reasonable.

18:21 hiredman: ,((partial (comp seq reduce) (comp (partial apply conj) (juxt first (comp (partial + 1) second)) list) []) (range 10))

18:21 clojurebot: (1 2 3 4 5 6 7 8 9 10)

18:22 ordnungswidrig: hiredman: is this id on seqs or a general identify?

18:22 hiredman: or on seqs of ints?

18:23 hiredman: it's (partial map (partial + 1))

18:23 but strict using reduce

18:24 ordnungswidrig: I see. This wasn't an identity at all.

18:24 hiredman: hmmm

18:24 ordnungswidrig: need to sleep soon :)

18:24 ,(range 10)

18:24 clojurebot: (0 1 2 3 4 5 6 7 8 9)

18:24 hiredman: I should pull the mapped fn out to be the second arg to make it general

18:29 ordnungswidrig: Is wraping an sexp with an (do (println (str "xxxx")) sexp) idiomatic for debug printing?

18:29 Or is there a better way?

18:30 hiredman: (doto something prn)

18:30 but sure that works

18:30 ordnungswidrig: hiredman: this will print the result of something?

18:31 hiredman: yes

18:31 and return something

18:31 jhawk28: hiredman: does clojurebot have a limit on the output?

18:31 hiredman: evaluated to

18:31 yes

18:31 I always feel dirty when I saw "return"

18:31 Chousuke: ordnungswidrig: it would be more idiomatic to use a debug macro I think :)

18:31 ordnungswidrig: it like ? (let [x something] (do (println x) x)

18:32 hiredman: ordnungswidrig: yes, but with prn instead of println

18:32 ordnungswidrig: Chousuke: a reader macro? Like !(something) will evaluate to (doto something prn)

18:32 tomoj: I always feel dirty when I see "prn"

18:33 hiredman: say

18:34 ordnungswidrig: say what?

18:34 hiredman: correcting my earlier statement about return

18:35 say return not saw return

18:36 ordnungswidrig: hiredman: oh dear, but that was a late one. Event regex wouldn't helped out and I don't know, if sed expressesions are commonly well understood on IRC.

18:36 s/Event/even/

18:37 hiredman: I see regexs on irc everywhere

18:38 the other day I saw someone correct themselves with a regex that used back references

18:38 jasapp: that's kind of disturbing

18:38 technomancy: I'm still waiting for a client that can automatically DTRT when it sees someone type things like s/foo/bar/

18:40 hiredman: http://luaforge.net/docman/view.php/83/95/ANoFrillsIntroToLua5VMInstructions.pdf <-- nice

18:44 chouser: technomancy: wave will come first

18:44 ^ random expression of hope disguised as an unlikely prediction

18:44 hiredman: hmmm

18:48 jasapp: does clojurebot have a way to refer to someone's last comment?

18:48 hiredman: ~seen jasapp

18:48 clojurebot: jasapp was last seen in #clojure, 0 minutes ago saying: does clojurebot have a way to refer to someone's last comment?

18:49 jasapp: ahh, interesting

18:50 is there a way to call seen from clojurebot's clojure evaluator?

18:51 hiredman: possibly

18:52 it would be some work because clojurebot tries to discourage digging around in its own internals from the sandbox

18:52 jasapp: it'd be kind of cool to feed him/her a regular expression and run it over someone's last comment

18:52 but it'd also be a big waste of time, too

18:53 hiredman: I suspect it would end up like clojurebot's tinyurl plugin

18:53 The-Kenny: I think something like this would be cooler in a client, not a bot.

18:53 ordnungswidrig: hiredman: I was the one with the backreference

18:53 jasapp: true

18:53 The-Kenny: Personally, I would like to see a irssi plugin :)

18:53 ordnungswidrig: sounds like a no-brainer for erc

18:53 The-Kenny: s/ a / an /

18:55 arbscht: you can probably bend /lastlog in irssi to do that

18:55 ordnungswidrig: it's 01:00am local time which means bed time. *moahn*

18:56 cu all

18:56 The-Kenny: It's not 01:00 am here, it's 00:57 am :D

19:39 technomancy: drewr: I'm looking at your use of swank in clot; what's the purpose of wrapping start-server in that repl call with the stop atom like you did?

21:08 weissj: i'm trying out some project euler problems, one is to return the 10001st prime. my strategy is to have a primes function return a lazy seq of primes. and a prime? function that iterates over previous primes and divides the current candidate by that list.

21:08 how can i make sure the list of already-calculated primes doesn't get recalculated each time

21:09 ie, each call to primes accesses the same list

21:11 _ato__: (def primes-seq (primes)), then just use prime-seq instead of calling your primes function each time?

21:11 or use memoize on primes

21:13 weissj: note there's a clojure.contrib.lazy-seq/primes but I guess you want to solve it yourself :)

21:13 weissj: _ato__: yeah :)

21:15 would be a bit too easy to use that: (nth primes 10001)

21:28 lisppaste8: jweiss pasted "untitled" at http://paste.lisp.org/display/89704

21:28 weissj: can someone tell me what's wrong with this ^

21:29 i get: java.lang.RuntimeException: java.lang.ClassCastException: clojure.core$num__5233 cannot be cast to java.lang.Number (NO_SOURCE_FILE:0)

21:29 on the line that starts with (take

21:31 nevermind - used "num" instead of "mynum"

21:41 anyone know why this happens?

21:41 (take 1 (lazy-seq (conj (primes) 2)))

21:41 java.lang.StackOverflowError

21:41 i wrote the primes function which obviously has infinite recursion problems, but why does it even get called? i only want 1 item in the seq, and that should be the 2 i conj'd on there first

21:43 chouser: I think you mean (lazy-seq (cons 2 (primes)))

21:44 what you have is a bit interesting, though.

21:46 ,(take 1 (lazy-seq (cons 1 (lazy-seq (prn :hi) '(2)))))

21:46 clojurebot: (1)

21:46 chouser: ,(take 1 (lazy-seq (conj (lazy-seq (prn :hi) '(2)) 1)))

21:46 clojurebot: (1)

21:46 chouser: hm, clojurebot doesn't show that :hi gets printed on the second but not the first

21:48 ,(take 1 (lazy-seq (conj (lazy-seq (prn :a) (cons 2 (lazy-seq (prn :b) '(3)))) 1)))

21:48 clojurebot: (1)

21:57 chouser: and that one prints :a but not :b

21:58 conj on a lazy seq forces one extra step

22:15 qed: hello all

22:16 * qed curses a 1.2gb latex distribution

22:21 solussd: is there a easier way to access something in a vector of vectors? e.g. easier than this?: (def grid [[1 2 3] [4 5 6]]) ((grid 1) 2)

22:30 chouser: ,(get-in [[1 2 3] [4 5 6]] [1 2])

22:30 clojurebot: 6

22:30 chouser: solussd: ^^^

22:30 solussd: excellent.

22:47 emit: sessions in compojure, where exactly do I use the decorate with-session... by itself? inside defroutes?

22:57 ok to answer my question I can just decorate the route itself...

22:57 tomoj: I would think you would decorate the handler

23:09 saml: hey, I do C-c C-d d to see document of symbol.. and C-x o, q to kill the document buffer. can i kill it faster?

23:09 in Clojure Box

23:19 hiredman: qed: well, at least you get all the batteries that way

23:20 <3 XeLaTeX

23:20 _ato: saml: hmm.. for me (not using Clojure Box just my own emacs) C-c C-d d makes the doc buffer focusued, so I just press q.

23:21 saml: _ato, oh i see. weird

23:21 hiredman: clojurebot: hiredman | <3 | XeLaTeX

23:21 clojurebot: Ok.

23:22 hiredman: clojurebot: hiredman?

23:22 clojurebot: hiredman <3 XeLaTeX

23:22 _ato: saml: Otherwise you could just leave the buffer open but hide it (C-x 1) it'll get reused next time you C-c C-d d, so you don't have to worry about it make hundreds of them

23:23 saml: _ato, yah but wouldn't it leave hundreds of buffers?

23:24 _ato: nah, it'll just reuse the same one

23:24 at least, again, that's what it does for me

23:27 saml: _ato, ah thanks. kinda hard to see what's going on for a noob like me :P

23:29 _ato: yeah, I'm not too good with emacs either. A real emacs guy would either know a key combo for kill other window or would have some 10 keypress way of defining one and adding it to your .emacs :P

23:31 I know the first steps: you could define a keyboard macro with C-x ( C-x o q C-x ) and then name it with M-x name-last-kbd-macro, but I'm not sure how to then bind that to a short keystroke

23:32 j3ff: is there a built-in function that returns the max value in a sequence?

23:32 tomoj: well

23:32 _ato: j3ff: yes, funnily enough it's called "max" ;)

23:33 tomoj: (apply max the-seq)

23:33 samUL: _ato, ah thanks

23:33 j3ff: thanks

23:33 tomoj: not sure how well it scales to very large seq

23:33 s

23:33 perhaps reduce max would perform better

23:34 _ato: ,(time (apply max (range 1000000)))

23:34 clojurebot: 999999

23:34 "Elapsed time: 545.892 msecs"

23:34 _ato: ,(time (reduce max (range 1000000)))

23:34 clojurebot: 999999

23:34 "Elapsed time: 239.206 msecs"

23:35 j3ff: interesting

23:35 _ato: ,(time (apply max (range 1000000)))

23:35 clojurebot: 999999

23:35 "Elapsed time: 403.153 msecs"

23:35 j3ff: one more question, is there another function to return said index of the max? :)

23:35 _ato: hmm

23:35 tomoj: 'I feel uneasy about passing very large seqs to functions with apply

23:35 no, you will have to write your own for that I believe

23:35 but it's not very hard

23:36 j3ff: alright, thanks

23:36 yeah

23:36 tomoj: most clojure doesn't like thinking about indices

23:36 _ato: ,indexed

23:36 j3ff: yeah its because im implementing an algorithm into clojure

23:36 clojurebot: #<seq_utils$indexed__697 clojure.contrib.seq_utils$indexed__697@ec0f07>

23:37 _ato: ,(apply max-key second (range 10000))

23:37 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer

23:37 _ato: hmm

23:37 oh right

23:38 ,(apply max-key second (indexed [8 2 4 9 5 5]))

23:38 clojurebot: [3 9]

23:38 _ato: (as in index 3, value 9)

23:38 j3ff: whoa cool

23:39 thanks!

23:41 tomoj: ah I didn't know max-key existed

23:41 nice

23:43 j3ff: is indexed part of a library?

23:43 _ato: clojure.contrib.seq-utils

23:43 j3ff: thanks

23:44 _ato: btw, about using apply, functions that take an arbitrary number of arguments like + and max are defined like: (defn max [x y & more])

23:44 that will happen is the first two values of the seq will get assigned to x and y and the rest of the seq to more

23:44 so that's really cheap

23:45 and then max will just deal with the first two cases and recurse

23:45 so it's usually about the same as doing reduce

23:46 ,def max

23:46 clojurebot: java.lang.Exception: Unable to resolve symbol: def in this context

23:46 _ato: clojurebot: def max

23:46 hiredman: I seem to recall max using reduce internally

23:46 _ato: yep

23:47 hiredman: and I remember using reduce externally was faster than using apply max and max's internal reduce

23:47 but I don't remember why

23:48 _ato: yeah, that's strange, in theory it should be doing almost exactly the same thing

23:48 just one more or two more function calls

23:49 hiredman: this was all gone over, maybe six months or so a go in here

23:52 tomoj: well

23:52 when you apply a function to a huge seq

23:52 does some large tail of the arguments just get left inside a seq, to be reduced inside the call?

23:53 hiredman: yes

23:53 tomoj: calling functions with a huge number of arguments always makes me feel uneasy

23:55 hiredman: for more than four args I like to use map destructuring

Logging service provided by n01se.net