#clojure log - Aug 19 2009

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

0:00 konr: I want to learn how to use swing and clojure, but I'm wondering where I should start. Almost everything writter for swing is in java

0:01 hiredman: do you know java?

0:01 do you know clojure?

0:03 konr: I don't know java

0:03 arbscht_: doesn't Programming Clojure cover basic Swing usage from Clojure?

0:03 konr: I now know a bit of clojure

0:03 hiredman: well, in order to translate java to clojure you will need to know some java

0:03 so I would start with a java tutorial or two

0:04 tomoj: hmm.. what's a good way to generate all the n-tuples of natural numbers that add up to x?

0:06 right now I'm using selections from contrib.combinatorics to generate all possible n-tuples selecting from 0 to x, and then filtering by checking the sum

0:06 (which is obviously not a good way)

0:07 Anniepoo: hey, clojurebot's been rescued from the Scala people!

0:07 clojurebot: paste

0:07 clojurebot: lisppaste8, url

0:07 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

0:08 tomoj: oh, this reminds me of the donut problem

0:08 I could have a vector of n 1's, then pick all possible ways to partition the vector and sum the subvectors

0:08 lisppaste8: Anniepoo pasted "mapping def" at http://paste.lisp.org/display/85630

0:09 Anniepoo: can anybody suggest a clean way to do this without the ugly list of def calls

0:09 arbscht: multimethods?

0:09 hiredman: sounds good

0:10 or write a macro

0:10 Anniepoo: ok, it'd have to be a macro, wouldn't it?

0:10 tomoj: why?

0:11 hiredman: it looks like you writing a switch statement

0:11 you are

0:11 so use a multimethod

0:11 Anniepoo: no (map #(def % not-handled) ('key-up 'mouse-down...)

0:11 yah, good idea

0:11 hiredman:

0:12 Anniepoo: I'm just trying to get out of all the swing ceremony

0:13 tomoj: oh, I see

0:13 def is not a function..

0:13 hiredman: well, you just created your own ceremony

0:13 Anniepoo: so it seems

0:14 tomoj: I don't understand how you could use multimethods there

0:15 hiredman: you have a handler multimethod

0:15 it dispatches on the type of event passed in, the default method does nothing

0:16 arbscht: http://gist.github.com/170156

0:16 tomoj: ah, I see

0:16 arbscht: sort of like that

0:16 Anniepoo: ok, but the java class of event isn't sufficient to know, for example, if it's mouse up or mouse down

0:16 so I suppose you have to mark it with a keyword or something

0:17 tomoj: certainly java gives you some indication of the type of the event?

0:17 hiredman: Anniepoo: you just write a dispatch function that contains the logic needed

0:17 arbscht: yes, just pass it as an argument for the dispatch fn to use

0:17 hiredman: by type I did not mean java class

0:17 Anniepoo: ok, sounds good

0:17 it's a nice use of a multimethod

0:18 I'm making a little starter shell for a clojure hack meetup

0:18 hiredman: multimethods are pretty dope

0:18 Anniepoo: I'll pass out a shell for a game and everybody can fill it in

0:18 tomoj: I wish there were clojure meetups here

0:19 Anniepoo: anybody in SF bay area who wants info, we'd love to have more clojure types at this

0:19 * arbscht is on the far side of the SF bay area...

0:19 Anniepoo: bunch of Java programmers 'in the wild' are interested, but nobody knows anything

0:19 lovely, it's in SF tomorrow evening,

0:20 getting the info now

0:20 arbscht: I mean I'm in the south pacific :)

0:20 the really, really far side

0:20 Anniepoo: LOL

0:20 hiredman: I'm going to be in sacramento next weekend, but I don't think I have enough time for anything

0:20 Anniepoo: too bad

0:21 hiredman: yeah

0:21 Anniepoo: http://www.ebig.org/index.cfm?fuseaction=Page.ViewPage&PageID=481

0:21 hiredman: I should get off my butt and go to seafunc sometime

0:29 Anniepoo: no docstring for defmethod?

0:29 hiredman: how would you lookup the docstring for a specific method?

0:30 Anniepoo: good point

1:08 hmm... I can't nest destructuring?

1:08 tomoj: sure you can

1:08 Anniepoo: the single arg to this function is something liek [[1 2] [3 4]]

1:09 hiredman: ,((fn []) [[1 2] [3 4]]

1:09 clojurebot: EOF while reading

1:09 hiredman: er

1:09 Anniepoo: ok, never mind

1:09 hiredman: ,((fn [[[a b] c]] a) [[1 2] [3 4]])

1:09 clojurebot: 1

1:09 Anniepoo: ok, cool, sorry, it's my mistake

2:47 konr: strange... awt seems to be missing but I've used it before. Any idea on what is going on?

2:49 hiredman: uh

2:49 what makes you say that?

2:50 konr: #<CompilerException java.lang.NoClassDefFoundError: java.awt.Container (imagem.clj:1)>

2:51 hmmm, actually this is a different error message

2:52 hiredman: weird

2:52 konr: anyway, I've solved it removing sun's jdk and installing open jdk... go figure

2:52 haha, and netbeans doesn't install with openjdk :(

3:05 Fossi: hi

3:08 Raynes: Yo.

4:25 cark: Dan Weinreb having a couple good words for clojure during the last 10 minutes of his google talk http://www.youtube.com/watch?v=xquJvmHF3S8

4:35 Fossi: hmm C-M-Backspace is not 'backward-kill-sexp' ;D

5:40 hamza: hey guys, how can i extend one class and implement other two i need to extend DefaultTableCellRenderer and implement MouseListener MouseMotionListener

5:41 dhaya: check out "proxy"

5:42 hamza: i know proxy but i can't get the synxtax right

5:42 i tried (proxy [DefaultTableCellRenderer MouseListener MouseMotionListener] []...

5:42 and (proxy [DefaultTableCellRenderer ] [ MouseListener MouseMotionListener]...

5:43 both did not work

5:43 cark: the first vector should have class and interfaces

5:44 could you paste your code somwhere ?

5:46 lisppaste8: hamza pasted "extend" at http://paste.lisp.org/display/85641

5:47 cark: looks ok at first glance

5:47 what error do you get ?

5:48 dhaya: you

5:48 hamza: it works but mouseClicked never gets called.

5:48 dhaya: oops.

5:49 cark: are you sure about that ? *out* might not be bound in the event thread

5:51 dhaya: *out* defaults to System/out in any case, i think.

5:52 cark: it has been a while since i did swing stuff, but i remember having problems with it ... might be wrong tho

5:53 maybe try throwing in there, you'll be sure then =)

6:19 alinp: hi

6:19 we have dosync macro

6:19 what if I want to make an alias or something ... call it transaction, for instance

6:19 how this can be done ?

6:19 using defmacro ?

6:20 cark: ye

6:20 s

6:20 alinp: that's the only way ? there is no alias concept for clojure ?\

6:20 cark: untested : (defmacro transaction [& params] `(dosync ~@params))

6:20 alinp: since I don't want to do much stuff ... just to change the name of dosync with transaction

6:20 ok, thanks cark

6:21 cark: usually you can "alias" any var

6:21 (def plus +)

6:21 AWizzArd: alinp: you should use a macro for that. It would look like the one that cark suggested, or very similar.

6:21 alinp: cark: your example worked

6:22 so you can consider it tested :D

6:22 tomoj: (refer-clojure :only '(dosync) :rename '{dosync transaction})

6:22 cark: great =)

6:23 alinp: tomoj: thanks

6:23 but keeping the spirit of lisp, I think macros are the most elegant way to do it

6:23 Chousuke: the ns macro can do it :P

6:24 alinp: btw, why dosync and not transaction ? :)

6:24 tomoj: refer-clojure is a macro :P

6:24 Chousuke: refer-clojure is a function.

6:24 tomoj: mine isn't

6:24 Chousuke: ,refer-clojure

6:24 clojurebot: java.lang.Exception: Can't take value of a macro: #'clojure.core/refer-clojure

6:24 Chousuke: oh. hmm.

6:24 cark: it's a macro here =)

6:24 tomoj: just a thin wrapper around the refer function

6:25 Chousuke: ah, I was thinking of require etc

6:25 cark: wouldn't tomoj solution hide the rest of core ?

6:26 tomoj: not if you've already got it (like in user)

6:26 cark: ok interesting

6:26 tomoj: but yeah if it's in your ns I guess you'd want to take out the only

6:27 cark: as for the naming, i guess rhickey didn't want a name clash with database stuff

6:35 AWizzArd: also one can think of the operations inside a dosync block happen all synchronous

6:58 tomoj: I wonder what the point of the first argument to sync is

7:27 cp2: has anyone seen http://www.youtube.com/watch?v=xquJvmHF3S8 yet?

7:27 they talk about clojure apparently

7:29 Fossi: they do? i thought it was implemented in common lisp

7:29 cp2: well, from the description:

7:29 I will also talk about the future of Lisp, which has three tracks: Common Lisp, Scheme, and Clojure.

7:29 i just started watching it

7:29 Fossi: ah, ok

7:30 but i'm definitely bookmarking that to watch it later

7:30 those guys have some serious mojo down

7:30 cp2: heh

7:32 mtd: cp2: I like the "CONFIDENTIAL" stamp in the bottom right of the presentation

7:32 cp2: haha

7:33 quick, download the flv before they delete it!

7:42 tomoj: the clojure mention is like 10 minutes before the end

7:43 around 50:00

7:44 cp2: ok

7:52 ole3: hi, i need loggin in my application, so is println thread save?

7:59 Fossi: eh, pimping your theatre group on a world wide broadcasted tech talk is funny ;D

8:02 Chousuke: ole3: send logging actions to an agent if you want to ensure that they're serialised.

8:02 ole3: you might also want to take a look at the logging library in contrib

8:05 ole3: Chousuke: thank you.

8:26 cp2: interesting talk

8:27 mtd: cp2: very - weinreb saying CL is "on life support" and clojure is "amazing" seems to me a big (new) deal.

8:28 cp2: hehe

8:28 cl is very much alive still

8:28 but i do agree

8:28 clojure is amazing

8:28 =P

8:28 mtd: cp2: "life support" != dead :)

8:28 cp2: well

8:28 i meant alive as in

8:28 alive and kicking

8:28 not needing life support

8:29 Fossi: yeah, but imho i can't see many areas where it's much superior to clojure

8:29 arbscht: I gathered he said it would eventually be on life support if the library distribution situation wasn't resolved soon

8:29 Fossi: except maybe for having hardware support on obscure plattforms :)

8:29 which is awesome

8:29 Chousuke: Fossi: Performance, at least for now :p

8:30 cp2: mhm

8:30 im waiting for my tail calls!

8:30 and a *real* compiler

8:31 Fossi: Chousuke: well, i guess that depends a whole lot on the job

8:31 Chousuke: The java compiler is pretty lazy I guess.

8:31 it just does the bare minimum of optimisations and leaves the rest to hotspot :)

8:31 cp2: yeah

8:31 Chousuke: but since it's written in java that's understandable. :P

8:32 cp2: hehe

8:32 has the development on the clojure clojure compiler started yet?

8:32 mtd: arbscht: "There is a lot of other interest [in library support and] doing things that will improve Common Lisp, but I mostly think that's life support. It can stay alive as a good language for another 5 years, or 10 years or something".

8:32 Chousuke: Chouser did start something in March but I think that work won't be used.

8:33 cp2: yeah thats about what i last heard of it

8:33 mtd: arbscht: "...but it's not really the way to go in the long run because there's just a lot of stuff in it that's old, that has to be that way for compatibility..."

8:33 Chousuke: I'm writing a reader, but it's not as important as the compiler :)

8:33 it's also a lot easier. :P

8:33 mtd: arbscht: that's not "eventually on life support" that is "[on] life support".

8:33 cp2: you must be written in java =P

8:34 Chouser: compiler is two parts: analyzer and bytecode emitter

8:35 cp2: i almost thought you were Chousuke

8:35 (almost)

8:35 for like the 50000th time

8:35 Chouser: yeah. :-/

8:35 Chousuke: We're used to that :P

8:35 Sometimes I get called Chouser and it doesn't even faze me anymore.

8:35 Fossi: Chousuke: is that bad? leaving the optimisations to the runtime?

8:35 cp2: heh

8:36 well, usually whenever that happens it means i need more coffee

8:36 brb

8:36 Chousuke: Fossi: Nah, but I'm quite sure there are some optimisations the compiler could more efficiently do before runtime.

8:36 Fossi: might be. then again, it seems to turn out quite well

8:37 i guess they would've improved the compiler by now otherwise

8:37 Chousuke: For example, the issue with locals getting cleared only on tail calls

8:37 and not upon last use.

8:38 Fossi: *shrug* i don't actually *know* anything about shit. just loosely interested ;)

8:38 Chouser: I think some of the optimisations the compiler does are actually un-done by the vm before it does its own.

8:42 cp2: mmm

8:47 raphinou_: hi

8:51 I'm trying to compile a class, but I don't see how I can implement its constructor

8:52 Fossi: what's not-empty for? i thought (seq coll) was idiomatic

8:53 actually, i can't figure out what value it adds at all

8:54 and since you need a pred for test-is/is, is there a better way than (not (nil? stuff))?

8:54 Chouser: raphinou_: using proxy or gen-class or ... ?

8:54 raphinou_: Chouser: I'm using gen-class

8:54 it extends another existing class

8:55 Chouser: raphinou_: look at :init and :post-init -- those are your constructor hooks

8:56 :init names a function that takes constructor args and feeds values into the base class constructor

8:57 raphinou_: but :init returns a vector with args and state

8:57 Chouser: :post-init gets run after the object has been created but before the object is returned to the client

8:57 raphinou_: yes

8:57 raphinou_: what's the state exactly?

8:58 Chouser: raphinou_: it's the one instance field you get with gen-class, described in the doc under :state

8:59 raphinou_: Chouser: is it possible I do not need to use the state?

9:01 Chouser: yes

9:01 esp. when extending an existing class that may store whatever state you need.

9:02 btw, I'd recommend using proxy instead, unless you know you need gen-class features that proxy doesn't support.

9:02 raphinou_: well, I started with proxy, but have read the gen-class is better if you need to specify the constructor

9:03 Chouser: raphinou_: yes, if absolutely need your own constructor and a clojure "factory" function won't suffice, then you need gen-class.

9:04 raphinou_: Chouser: might be a stupid question: is there an example of a clojure factory function somewhere? I don't understand what you mean

9:04 Chouser: not a stupid question -- the way clojure does these things can be a bit tricky to get your head around at first.

9:05 raphinou_: btw, I'm trying to translate this java code in clojure: http://www.webtoolkit.eu/jwt#/src/hello

9:06 I did the HelloMain with proxy

9:06 Chouser: (defn make-thing [ctor-arg] (proxy [Object] [] (toString [] (str "my arg was: " ctor-arg))))

9:06 raphinou_: thanks! I'll take the time to study it :-)

9:06 Chouser: there's a short example. its a fn that takes an arg, which is then used inside a proxy method

9:07 so then you can say (def x (make-thing "foo")) and when you call (.toString foo) later, it can still access ctor-arg

9:08 raphinou_: ok, I see

9:08 but here I think I really need the constructor

9:09 AWizzArd: http://www.google.com/insights/search/#q=clojure&cmpt=q

9:14 Chouser: raphinou_: why? All the code in HelloApplication's constructor could be in a make-hello-app fn that HelloMain would call.

9:15 if you want to use gen-class, that's fine, it just tends to demand a more complicated environment (AOT compilation, specific directories set up with specific classpath requirements, etc.)

9:15 AWizzArd: I want to slurp a file with a specific encoding, other than the default one (which is UTF-8 I think). What is the best way to do that? slurp inside some binding?

9:16 Chouser: ,(doc slurp)

9:16 clojurebot: "([f] [f enc]); Reads the file named by f using the encoding enc into a string and returns it."

9:16 raphinou_: Chouser: I'll try with proxy, I'm not pushing for gen-class (though I have everything set up now :-)

9:16 AWizzArd: oh good, is that new?

9:17 Chouser: AWizzArd: new-ish. June 19 http://www.assembla.com/spaces/clojure/tickets/125

9:18 AWizzArd: thanks Chouser, this is useful

9:21 Chouser: I always forget how to have clojurebot look up a ticket

9:29 raphinou_: Chouser: here's what I thought to do:

9:29 (defn make-hello-app [] (proxy [WApplication] [env] (setup-application [] (setTitle self "HelloWorld"))))

9:30 but it complains it doesn't know env, though from an example online this seems fine

9:30 Chouser: env would have to be a value you're passing in to WApplication's constructor

9:31 raphinou_: ok

9:33 so I should defn make-hello-app where env is available, which is in the createApplication from HelloMain... /me is trying

9:34 Chouser: you can pass the env into make-hello-app

9:34 (defn make-hello-app [env] (proxy [WApplication] [env] ...))

9:37 raphinou_: I seem to have valid code chouser. Now I'll see if it runs as hoped!

9:38 Chouser: :-)

9:44 rottcodd: is make-thing a more idiomatic name than new-thing or create-thing ?

9:53 Chouser: most of the built-in fns that create a foo are just named foo. symbol, keyword, atom, agent, etc.

9:55 raphinou_: chouser: the code runs fine, serves a page, but the elements I added to the page in the make-hello-app don't appear in page served

9:55 I put the code at http://pastebin.org/10239

9:56 if you have the time to look...

9:56 I might have missed something obvious

9:56 Chouser: defn's don't belong nested like that. Let me see how it should be re-arranged...

9:57 raphinou_: Chouser: yes, I put it there to have access to env

10:00 Chouser: ok, you can't create new methods with proxy, only override ones defined in a class you're extending or an interface you're implementing

10:01 raphinou_: hmm, does that mean gen-class should be used. I like the proxy better in the end :-)

10:01 Chouser: I'm looking; just a sec.

10:01 I don't know anything about WApplications...

10:02 raphinou_: I don't know much more actually :-D

10:02 Chouser: I don't think you need to proxy WApplication at all, at least not yet.

10:03 hm, unless getRoot is private or protected.

10:04 raphinou_: getRoot seems public

10:04 in case this helps, javadocs are here: http://www.webtoolkit.eu/jwt/latest/doc/javadoc/

10:05 Chouser: yes, thanks.

10:06 the pages on their site work very inconsistently for me.

10:06 raphinou_: do some pages not load you mean?

10:07 Chouser: right, they come up blank.

10:07 raphinou_: telle me your brower/os combination, I'll let them know

10:08 lisppaste8: Chouser pasted "raphinou_: try this?" at http://paste.lisp.org/display/85659

10:09 Chouser: this is often what you have to do when translating Java examples. They put all their code in classes, constructors, etc. when such are rarely needed in Clojure.

10:09 hm, I'm missing a close paren in there.

10:10 raphinou_: yes, there was a paren misplaced ;)

10:13 I still get a blank page. I'll look further to get it working. Thanks a lot Chouser!

10:14 Chouser: hmph.

10:14 ok

10:14 raphinou_: I learnt a lot today, thanks for your time!

10:14 Chouser: you're welcome. hope you figure it out.

10:15 raphinou_: I'll post it in the google group if I get it working

10:22 btw, what's your brower/os combination?

10:23 Chouser: I was getting similar behavior in firefox 3.0.13 and nightly chromium-browser for ubuntu.

10:24 no page failed consistently -- browsing around or reloading would sometimes cause a working page to fail or vice-versa

10:48 jweiss: i have a macro that takes 2 args, when i call the macro, it doesn't seem to evaluate the args I pass it. it just passes the forms straight into the macro

10:49 or maybe this only happens using macroexpand-1

10:51 stuartsierra: macros never evaluate their arguments

10:57 jweiss: stuartsierra: you mean if i have a macro blah and i do (blah (str "abc" "123")) the macro receives the form (str ...) rather than "abc123"?

10:57 liwp: jweiss: that's right

10:58 AWizzArd: (.foo #^ClassA (.bar #^ClassB *some-object*)) ==> gives me a reflection warning.

10:58 (let [x #^ClassA (.bar #^ClassB *some-object*)] (.foo x) ==> gives me a reflection warning.

10:58 (let [#^ClassA x (.bar #^ClassB *some-object*)] (.foo x) ==> works, no reflection warning. Why does only this last version work?

10:58 jweiss: liwp: stuartsierra: wow, i did not know that

10:58 how do i get around this?

11:01 i want to pass in a deref'd atom like @myatom, but the macro receives a IPersistentList, oddly which is what you get when you do

11:01 cemerick: jweiss: that's a pretty definitional characteristic of macros

11:02 jweiss: hm, maybe the fn that calls my macro also needs to be a macro

11:03 liwp: can you show the macro?

11:03 lisppaste8: jweiss pasted "untitled" at http://paste.lisp.org/display/85666

11:03 liwp: and have a look at the clojure documentation at http://clojure.org/reader

11:03 jweiss: apologies for the tabs

11:03 liwp: specifically the syntax-quote bit

11:03 jweiss: it's the macro define-all-methods

11:04 and it's called by define-all-tasks immediately below it

11:05 liwp: shouldn't you have ~obj in the get-methods call?

11:06 jweiss: liwp, yeah, i was just grasping at straws trying to figure out what's wrong, but the problem is that the define-all-methods macro receives '@task-obj as teh 2nd arg

11:06 which is an IPersistentList. i want just @task-obj

11:07 liwp: yeah you'll have to pass in a value rather than a ref

11:07 you can let-bind the value before the call to the macro

11:07 jweiss: liwp: but isn't @task-obj a value?

11:07 Chousuke: jweiss: @ is a reader macro. there's no way to pass it to anything as is.

11:08 jweiss: Chousuke: ah ok

11:08 Chousuke: @foo is equivalent with (deref foo)

11:08 Chouser: jweiss: you can probably do all this with no macro

11:09 jweiss: Chouser: yeah, that is starting to occur to me

11:09 Chouser: define-all-methods could be a fn that iterates through the obj and uses 'intern' to create the fn vars in the given namespace

11:10 jweiss: i'm so used to java that i assume doing defn's in a loop has to be in a macro, but that's not the case

11:10 i based this on lancet, and lancet uses macros to do something similar

11:12 Chouser: the part i am unsure about is doing a defn with a number of arguments not determined until runtime

11:13 Chouser: defn is a macro, so you can't pass in a variable name.

11:13 I'd try using intern instead.

11:13 (doc intern)

11:13 clojurebot: DENIED

11:13 Chouser: ,(doc intern)

11:13 clojurebot: DENIED

11:14 Chouser: sheesh

11:14 stuartsierra: Yes, you can do (intern *ns* symbol-name (fn ...))

11:15 jweiss: yeah, but can i pass intern a fn that has 3 args one time thru the loop, and 2 the next, 4 the next, etc

11:15 i don't know how to take a number and create a fn with that number of args

11:16 Chouser: (fn [& x] ...) takes any number of args.

11:17 oh.

11:17 you want to turn around and call a method with those same args

11:17 jweiss: yeah

11:18 stuartsierra: jweiss: I think you need to name your arguments.

11:18 Chouser: well, since you won't know the actual types of the args at compile time, Clojure's going to have to use runtime reflection anyway, so you could use reflection manually in your fn.

11:19 are you sure you want to do this?

11:19 jweiss: Chouser: pretty sure, i want to be able to call methods on a my java object using clojure fns, not the java interop syntax

11:20 Chouser: jweiss: but why?

11:20 jweiss: this isn't for me, it's for people who don't have a clue about clojure

11:20 Chouser: hm.

11:20 http://paste.lisp.org/display/67182

11:20 you can use jfn to create the fns you need

11:21 jweiss: Chouser: cool, i'll try that, thanks

11:21 Chouser: by bouncing every method call through a fn you're going to lose a lot of runtime performance -- no primitive args, no primitive return values, reflection on every call.

11:22 jweiss: Chouser: performance is not an issue here. it's an interactive console, so 1/100th of a second to do reflection is no biggie

11:23 stuartsierra: "Most Clojure programmers go through an arc.  First they think 'eww, Java' and try to hide all the Java.  Then they think 'ooh, Java' and realize that Clojure is a powerful way to write Java code." -quoting rhickey at http://stuartsierra.com/2008/08/08/clojure-for-the-semantic-web

11:23 jweiss: stuartsierra: like i said, this isn't for me :)

11:23 i am fine with using java :)

11:23 but lisp syntax is scary enough for my audience without adding java interop syntax to it

11:24 this would be the rest of the people on my qa team who i'm hoping will use this tool

11:25 no primitive args *could* be a problem, but if unboxing won't work, i can just change those method sigs to take Integer, Boolean etc. the java calling code will do autoboxing

11:27 stuartsierra: jweiss: Clojure can call methods with primitive args, they're automatically un-boxed.

11:29 * Makoryu lurks and waits for someone to talk about the "re-animated corpse" article

11:30 Chousuke: Makoryu: :P

11:33 If you really want comments, I think it's mostly drivel

11:33 cark: sounds like the guy didn't give a try to clojure

11:34 (beyond hello world)

11:34 cemerick: Makoryu: link?

11:34 Chousuke: It's fine to talk about purity and all, but a pure system that does not exist is not very useful for real-world problems. :/

11:34 cark: http://jng.imagine27.com/articles/2009-08-19-011225_clojure_the_false_lisp.html

11:35 cemerick: heh, even the URL is funny

11:36 cark: "Clojure epitomizes everything that's mediocre about modern computing"

11:36 right

11:36 Chousuke: And I hate the starting disclaimer. If there is a word that describes it better than "hubris", educate me, please. :P

11:37 cark: "Look at the sequences that wrap some of Java's collection types."

11:37 i guess he didn't try it at all actually

11:37 stuartsierra: "For years I've had problems with Clojure being called a Lisp," seems a bit extreme in that Clojure has existed for barely two years.

11:38 Makoryu: Let's see. His disclaimer is full of enterprise-quality hubris, and he was too impatient to actually learn Clojure, and too lazy to actually make any supporting arguments.... He should learn Perl!

11:38 Chousuke: The "you're sheep because you're not thinking BIG THOUGHTS like I am!" kind of attitude just offends me.

11:38 cark: stuart : some are doing 100years languages, other are doing 100years blog posts

11:38 stuartsierra: heh

11:39 Chousuke: cark: he tells you to look at the classes wrapping sequences, but... what about it? :/

11:39 it's as if looking at them is going to prove his point.

11:39 Chouser: I think that's meant to demonstrate the clash between java idioms and clojure idioms.

11:40 rhickey: Success is the best revenge - just write great things with Clojure and don't worry about it :)

11:40 Chouser: but I'm only guessing at that, because to me it demonstrates the beauty of the clojure idiom, that a lot of existing stuff can be packed into the same kind of box.

11:41 stuartsierra: I've tried to emphasize in my presentations that there are really only three viable platforms around right now: C/Unix, JVM, and .NET, and you've got to choose one if you want to get anything done.

11:41 Chousuke: I wonder where he got the idea that clojure is a pure functional programming language :/

11:41 Quote from him on reddit comments: "It's Clojure thats pushing pure functional programming. I for one am glad that Lisp does not do that."

11:42 Chouser: well, I tried to write something great, but ran out of time. So I wrote this instead: http://www.sunlightlabs.com/contests/appsforamerica2/apps/jobless/

11:44 cark: chouser : hum it crashed here =)

11:44 Unparseable date: "1976 Jan"

11:44 Chouser: yikes

11:44 lovely

11:44 cark: i may have some french settings here

11:45 stuartsierra: Chouser: cool, clever

11:45 Chouser: huh. I thought Java was write once, run anywhere... :-)

11:46 cark: anywhere in USA =)

11:46 stuartsierra: Oh, no, we meant "anywhere in the lower 48 states, not including the District of Columbia."

11:47 cark: want a full stacvk trace ?

11:47 Chouser: "SimpleDateFormat is a concrete class for formatting and parsing dates in a locale-sensitive manner" sure enough, documented right there.

11:47 cark: nope, thanks. Bad assumption on my part.

11:48 cark: allright, you better fix that because i want to see it !

11:48 Chouser: I don't know what they do if you change the app after the submission date.

11:48 cark: oh ok, bah no big deal

11:50 Chouser: oh, I bet it still breaks on Macs

11:50 I keep forgetting that.

11:50 Fossi: hmm. won't work for me on gentoo

11:51 prolly i haven't set the java plugin right though

11:51 Chouser: applets are apparently fragile. you can try downloading the jar and running it locally

11:51 might work around some of the issues.

11:52 I need to get a good place to host clojure web apps so I can stop messing with applets.

11:52 Fossi: "Unparseable date: "1976 Mar"" for me as well

11:53 cark: 1976 was a bad year for parsing

11:53 Chouser: heh

11:53 Fossi: you also have non-english locale?

11:53 Fossi: de_DE

11:54 setting it to something else helped

11:55 ole3: hi, is there a standard way to read a string of length n from a stream?

11:56 Fossi: nice though

11:56 ole3: i'd guess reader and take n

11:57 stuartsierra: No, reader won't work. You'd have to use the Java IO classes like InputStreamReader.

11:57 I mean clojure.core/read won't work.

12:01 Fossi: oh i would've thought that there is a lazy seq wrapper for streams around already

12:03 stuartsierra: only if you're reading a line at a time

12:03 Chouser: there is line-seq

12:04 ole3: thanks, i have written a loop.

12:11 * rhickey on day 2 of slogging through the mail for my zombie-reanimated corpse... 27 conversations to go

12:13 * stuartsierra feeds zombie-rhickey a rare steak

12:13 cemerick: I figured he'd prefer some offal. :-P

12:13 ugh, maven

12:14 Chouser: yay more ticket approvals.

12:14 * Chouser schedules some evening time for patch pushing.

12:15 * rhickey prefers the Dr. Frankenstein role to the zombie in this scene

12:16 Chouser: clojure already came alive once this week... came right into the channel and started talking

12:16 cemerick: rhickey: the mixed metaphor is funnier, though

12:17 rhickey: true

12:21 stuartsierra: Quoth the maven, "Nevermore."

12:21 cemerick: heh

12:21 Quite the macabre channel today.

12:22 More Poe references re: maven though, please. :-)

12:22 Chouser: quoththemaven.com

12:23 also http://www.amazon.com/Quoth-Maven-William-Safire/dp/0679423249

12:23 just in case your google isn't working.

12:23 * Chouser goes to lunch.

12:23 stuartsierra: http://www.shades-of-night.com/aviary/maven.html

12:27 Fossi: aaaand: i did it again. C-M-Backspace ftw \o/

12:31 * ole3 thought C-M-Backspace is an emacs command, and tried it

12:31 stuartsierra: Fossi: you can disable that in X

12:32 http://www.assembla.com/spaces/clojure-contrib/tickets/18-java-utils-as-str-could-be-variadic

12:33 ole3: how do i make a forward declaration?

12:34 Fossi: stuartsierra: and i should

12:34 stuartsierra: (declare foo bar)

12:34 Fossi: obviously

12:36 ole3: it *is* an emacs command

12:36 at least more or less

12:36 you can ESC-C-Backspace

12:37 ole3: Fossi: thanks

12:41 Chouser: Interesting. whitespace-sensetive clojure: http://github.com/onyin/pleajure/tree/master

12:43 sensitive

12:44 Fossi: given the number of sexp, i guess that could be highly confusing

12:44 then again you can prolly still use parenthesesis (sp?) for some things

12:44 cemerick: cute, but painful

12:45 Fossi: i'd love to see some source

12:46 * stuartsierra finally announced clojure.contrib.str-utils2

12:48 Fossi: stuartsierra: great. i have been waiting for it :)

12:48 and the other bad key combo :\

12:49 stuartsierra: Fossi: thx

12:49 technomancy: what's awesome about str-utils2?

12:49 other than being twice as good as str-utils, obviously...

12:50 stuartsierra: Speed. It's much faster than doing the equivalent with sequences over strings.

12:50 technomancy: cool

12:50 stuartsierra: That, and a much more complete, organized API.

12:50 technomancy: did a decision ever get reached about callable regexes?

12:51 stuartsierra: I believe the decision was "not yet."

12:52 I thought about (defn fnre [re] (fn [s] (re-find re s))) but didn't include it.

12:52 technomancy: right, unless it's integrated with the reader the benefits are slim.

12:52 stuartsierra: Exactly.

12:55 * stuartsierra goes out to lunch

12:58 raphinou_: Chouser: it's working now. problem was with the jwt jar I was using.

12:58 I need to go now. Bye!

13:27 Chouser: Well, now, this puts classpath issues in perspective: http://fuhm.net/super-harmful

13:35 m3lling: I've got this StackOverflow Clojure question with a bounty of 250 points that expires in 24h. Trying to gather great small Clojure programs in one place.

13:35 http://stackoverflow.com/questions/1261557/whats-the-most-useful-thing-youve-done-in-less-than-50-lines-of-clojure

13:36 cemerick: oh yeah, super in python is gnarly

13:37 saml: hey, is it reasonable to use clojure to write a script that does POST/PUT/DELETE... to a server?

13:37 or should i do it in java?

13:37 mrsolo: sure

13:37 * stuartsierra returns

13:37 technomancy: saml: you can use http://github.com/technomancy/clojure-http-client

13:37 stuartsierra: or clojure.contrib.http.agent :)

13:38 saml: thanks. i dont know clojure at all. i just thought it'd be faster for me to learn clojure + write the script than to do it in java

13:38 technomancy: http dance off!

13:38 stuartsierra: Oh no, not another one! :)

13:38 mrsolo: saml: hmm if you know java already, it is faster in java for you..

13:39 saml: mrsolo, ok. i know basic java syntax. i never used http api in java

13:39 stuartsierra: I expect you will find both Clojure HTTP libraries simpler than their Java counterparts.

13:40 mrsolo: right since your java fu isn't there either

13:40 clojurebot:

13:40 mrsolo: clojure is faster

13:40 saml: don't know why they let me use java.. if i ship them clojure files i might get fired. yay

13:41 mrsolo: why?

13:41 it is .jar

13:41 saml: oh coolz!

13:42 mrsolo: i mean the clojure itself the script is clojure

13:42 can be bundled into jar etc

13:43 saml: i'll investigate more.. i probably just need to fix ant build file.. then no one would notice that i did it in clojure

13:44 i can run repl.. do I start with The Reader document? and go through one by one under References ?

13:44 Chouser: that's certainly one way.

13:44 mrsolo: saml: i assume you have plenty of time to get this done?

13:44 java is better..documented :-)

13:44 saml: no. today!

13:44 okiez

13:45 mrsolo: you can probablly copy n paste some http java code off the web and get it rolling

13:46 saml: alrighty. i guess i'll investigate cljore at home

13:49 LauJensen: Guys - You can render an imageicon in a JLabel, but how do I align the image to the bottom left of the label? (hint: .setVerticalAlignment and .setHorizontalAlignment doesnt do it)

14:11 mrsolo: so am i reading this right? http://groups.google.com/group/clojure/browse_thread/thread/1036286a3f17bd56?hl=en writing clojure in pure functional style takes huge performance penality?

14:13 stuartsierra: Well, yes, compared to imperative and non-thread-safe code.

14:13 This will probably improve over time.

14:14 Chouser: currently clojure fns always have boxed args and return values, and clojure collections only store boxed things

14:14 technomancy: seems a bit odd that str on a lazy seq returns stuff like "clojure.lang.LazySeq@c1b2fa90"... I understand the desire to avoid realizing it, but it's still a bit funky.

14:14 stuartsierra: Yes, and Clojure collections are actually trees, which obviously have much slower access than simple arrays.

14:15 Chouser: if you're doing intensive work on things that could be primitives (longs, doubles) then those boxing rules will hurt you

14:15 technomancy: is there any function like str that works on lazy seqs too?

14:15 mrsolo: well i don't like to program the 'other way' my main point of learning clojure

14:15 but i hate doing 'perofrmance' excercise more

14:15 Chouser: technomancy: do you want pr-str ?

14:15 ,(pr-str (concat [1 2 3] [4 5 6]))

14:15 clojurebot: "(1 2 3 4 5 6)"

14:15 technomancy: Chouser: that's exactly it; thanks

14:15 I suppose that's what the repl uses?

14:15 stuartsierra: mrsolo: http://clojure.org/transients will probably help

14:16 Chouser: technomancy: yes, the repl uses pr stuff. these all use the print-method multimethod internally, so you can even extend it if you want to.

14:16 technomancy: excellent

14:18 mrsolo: staurtsierra: impressive..does transient still do boxing and unboxing?

14:18 stuartsierra: yes

14:19 Chouser: I believe rhickey has a plan for supporting limited primitive args, returns, and collections.

14:19 stuartsierra: loops can use unboxed primitives already

14:23 johnmn3: hello all

14:25 I've been wanting to work on clojure documentation recently. Specifically, I've always thought a more graphical explanation of functions would help me.

14:26 I think more geometrically than algebraically. So, I whipped up a graphic of reduce and I wanted to show it here to get some feedback

14:26 sivajag_: Hi All

14:26 johnmn3: http://imgur.com/UmQoT.png

14:27 sivajag_: I am new to Clojure ... infact just finished my helloworld program

14:27 johnmn3: hello sivajag_

14:27 Chouser: johnmn3: looks about right

14:27 sivajag_: My name is Siva and hoping to know you guys more and be helpful to this Community

14:28 Chouser: johnmn3: might want to do something to make it clear the green box is a collection, not a series of arguments.

14:29 johnmn3: I'm mostly looking for feedback on the graphic, not so much the text. Are there standards for the shapes or colors of functions, variables, literals, etc.

14:29 Chouser: true.. noted.

14:30 ok, that'll be fixed.

14:30 I was thinking about doing a few of these, especially for the ones that are confusing.

14:31 Chouser: good luck with 'for' :-)

14:31 but I would bet similar graphics for 'comp' and 'partial' might help a lot of people.

14:32 sivajag_: welcome.

14:32 johnmn3: thanks. writing that down.. any more that you, or anyone else, can think of? Anyone having trouble wrapping their heads around certain functions?

14:34 mrsolo: not really..but i think current api page is a dump

14:35 sivajag_: hey thanks Chouser

14:35 I am Java and Ruby programmer

14:35 I never done any functional programming

14:36 do u think I have to learn LISP before learning Clojur?

14:36 mrsolo: *cough* ruby is *somewhat* functional..*cough*

14:36 Chouser: sivajag_: nope. Common lisp won't help you much on the immutable side of functional

14:36 sivajag_: mrsolo: the problem is it is somewhat

14:36 mrsolo: the concept won't be that foreign to you

14:36 johnmn3: sivajag_: I don't think you have to learn another lisp first.

14:36 Chouser: sivajag_: the high-level functions you've probably tasted in ruby already.

14:36 stuartsierra: Ruby actually borrows a lot from Lisp. It uses lambdas all over the place, calling them blocks.

14:37 mudphone: 1.9 is getting more lispy

14:38 (Ruby 1.9)

14:38 sivajag_: ok cool

14:39 johnmn3: about the graphics in http://imgur.com/UmQoT.png does anyone think the parenthesis should be scrapped since the pink boxes are representing evaluation anyway?

14:39 rathore: without first-order functions, ruby can't get anywhere close to being lispy or functional

14:40 johnmn3: and the double left pointing arrows... which mean "result".. necessary? helpful?

14:41 stuartsierra: Ruby has first order functions with Proc.new {}.

14:41 cable_: i would leave the parens and turn the double pointed arrows into equals signs

14:41 rathore: blocks are first order, but the syntax is ridiculous

14:42 cable_: i'd also put parens somewhere at the top for consistency

14:42 Chouser: [1,2,3].map{|i| i+1} vs. (map #(+ i 1) [1 2 3]

14:42 )

14:43 rathore: chouser: thats not bad!

14:43 mrsolo: same difference

14:43 johnmn3: cable_: so do you think the ping boxes are unnecessary?

14:43 technomancy: rathore: blocks are certainly not first order in Ruby; they must be converted to Procs before they're usable as objects.

14:43 rathore: technomancy: there u go

14:44 mrsolo: i don't mind ruby's sytax..but man is it slow or what? psfftt

14:44 MarkVolkmann: JRuby performance seems pretty good ... at least for what I'm doing.

14:44 johnmn3: s/ping/pink

14:44 Chouser: ruby was my favorite language before clojure. There's a lot of good in there.

14:45 mudphone: Chouser: how about: class Fixnum; def add_one; self + 1; end; end ;;;; [1,2,3].map(&:add_one)

14:45 rathore: ruby is still my favorite imperative language :p

14:45 mrsolo: need to work on performance part that's all

14:46 stuartsierra: Chouser: same here.

14:46 Chouser: mudphone: huh. wow.

14:46 mudphone: symbol to proc is kinda cool, right?

14:46 rathore: the point is, u can't do the same kind of functional composition in ruby

14:47 mudphone: and the open classes

14:47 rathore: without lots of ugliness

14:47 cable_: johnmn3: maybe, i just think its inconsistent to have the parens in those and not up top

14:48 Chouser: brb

14:49 johnmn3: cable_: rgr

14:50 how about the dots... is that an accurate representation of & or would something else be better?

14:50 cable_: not sure about that

14:51 seems ok

14:51 Chousuke: phew.

14:51 done recreating my emacs.d :P

14:51 accidentally deleted it earlier.

14:51 ... took only the whole day.

14:52 (well, I was going to redo most of it anyway)

14:52 mrsolo: ..backup...backup...

14:52 Chousuke: mrsolo: I thought I had a backup, but I accidentally deleted it too.

14:53 I was moving around the dirs and deleting unneeded ones and somewhere in the process I deleted one dir too many.

14:53 mrsolo: i like this aspect of osx time machine

14:53 stick a usb drive and forget about it

14:54 Chousuke: I have time machine; I just had put emacs.d in a directory that's ignored by it.

14:54 technomancy: backups are weak; it belongs on github.

14:54 Chousuke: because it was in git, and I was supposed to push it there eventually.

14:54 to github, that is.

14:54 mrsolo: chousuke: wow :-)

14:54 Chousuke: but now I have a clojure-mode that doesn't cause lag with eldoc

14:55 mrsolo: my time machine isn't that picky backup everything

14:55 Chousuke: also automatic autoloads!

14:55 I still need to do something about the theme though.

14:55 the emacs-starter-kit theme is not good on my laptop :/

14:56 all the "highlights" are weak colours that get drowned by the white background.

14:57 which bring me to one of the reasons I prefer gist over lisppaste: gist actually highlights the code instead of just colouring it.

14:59 technomancy: there's no theme activated by default in the starter kit

14:59 Chousuke: Well, then it's Cocoa emacs default I guess.

15:05 drewr: does foo already exist? (foo {:bar 3} {:bar 5} {:quux 3}) => {:bar 8 :quux 3}

15:05 oh, merge-with I think

15:08 Chouser: just merge

15:10 drewr: I need the addition

15:10 Chouser: oh, whoops. sorry, didn't catch that.

15:15 hiredman: when I get around to it, I'll have clojurebot tag gist urls in delicious with "gist"

15:17 Raynes: http://jng.imagine27.com/articles/2009-08-19-011225_clojure_the_false_lisp.html Could they at least /try/ to down Clojure. :\ It seems like they aren't even enthusiastic about it.

15:19 Chousuke: whoops

15:20 with all my emacs tweaking I forgot I was also running an upgrade on my FreeBSD server. and of course it had stopped to ask for input ;(

15:20 hiredman: nice

15:21 Chousuke: I'm upgrading it to 8-BETA2 so I can set up NFS4

15:21 I had to use samba previously because NFS3 caused trouble with filenames.

15:21 hiredman: BATCH=yes is your friend

15:31 cemerick: interesting that that zombie article has 137 comments on proggit, but a score of 3

15:32 Chouser: i'm personally very pleased that such articles are written

15:32 and posted

15:32 somewhere other than our google group.

15:35 mrsolo: hmm anybody familiar with couchdb here?

15:36 cemerick: oh, I think they're the best geek marketing vehicle around. Nothing like a good, public flamewar against a huge pile of obvious straw men to gin up interest.

15:37 mrsolo: only a little :-)

15:37 mrsolo: danlarkin is your man, though

15:37 danlarkin: I'm no man's man!

15:38 cemerick: danlarkin: go-to guy? button? cheese?

15:39 danlarkin: mrsolo: AFAIK there are two clojure couchdb libs, mine (https://github.com/danlarkin/clojure-couchdb/tree) and Tunde Ashafa's clutch (http://github.com/tashafa/clutch/tree)

15:39 which you use will depend on your evaluation of both, I suspect

15:40 cemerick: danlarkin: have you gotten a view server together yet? A colleague of mine just started in with clutch's.

15:40 * cemerick loves *using* software :-P

15:41 danlarkin: cemerick: I've had no free hacking time this summer :'(

15:43 It is still on my list, but other things have been placed above it

15:45 Fossi: hmmm. common lisp error handling. yummy

15:49 Chouser: Fossi: ?

15:50 * Fossi is just watching the peter seibel techtalk and realised how much goodness that error handling is

15:51 Fossi: i like erlang's way too and it's much easier to simulate ;)

15:51 Chouser: I attempt to bring over what I could from CL's error condition system as error-kit. Not sure I'm pleased with the results, but there it is.

15:52 Fossi: ah. haven't seen that yet

15:52 will have a look

15:54 i always wonder how contrib is still full of plenty of goodness to discover after 2 months of clojure

15:54 clojurebot: contrib is http://github.com/richhickey/clojure-contrib/tree/master

15:55 Fossi: you say something like i just did and naturally, its already done in contrib :

15:55 danlarkin: error-kit is used in clojure-couchdb! woo

15:55 Fossi: hmmm. guess we didn't properly deal with errors when we used it ;)

15:56 danlarkin: :-o bugs in MY code? never!

15:57 Chouser: wow. a bunch of deferror's. Hm...

15:58 Fossi: danlarkin: your code?

15:58 ah. your code.

15:59 thanks for that then

15:59 we also added some stuff on top which might get commited sooner or later if you like :)

16:00 Chouser: very interesting.

16:00 danlarkin: Fossi: I would like that, yes

16:00 Fossi: dealing with views, parameters and such

16:01 Chouser: danlarkin: so it would be rather more clumsy if you didn't have deferror and instead specified everything you wanted to at kit/raise time.

16:02 I'm vaguely interested in trimming some fat out of error-kit, or breaking it apart somehow.

16:02 Fossi: just have to clean up all the code we produced so far and see what's general purpose :)

16:07 danlarkin: Chouser: Well deferror is nice... but, sortof procedural... it would be more "dynamic" to have a :type at runtime I suppose...

16:11 Chouser: right. but then your default message, fallback Exception etc. have to be repeated.

16:12 I guess you can make your own fn to raise a particular kind of error if you want...

16:13 mrsolo: danlarkin: thanks!

16:14 danlarkin: Chouser: true. It feels imperative to be defining "types" for errors, but maybe that's the right way to do it? I don't know. deferror has conveniences other than just what could be replicated by :type, as you point out

16:14 LauJensen: Does anyone remember what the standard java FTPClient is, ie. which class do I import?

16:17 cark: LauJensen: how about using org.apache.commons.net.ftp/FTPClient ?

16:17 LauJensen: cark: if I can avoid adding dependencies, I'll prefer that route

16:17 cemerick: looks like the Agent threadpools are stalling the exit of the test process: https://twitter.com/fogus/status/3411806496

16:17 cark: oh i see

16:18 cemerick: or, https://twitter.com/fogus/status/3411706217 (for what the waiting looks like if you don't know about Agent.shutdown() :-)

16:18 cark: ftp is hard, lots of different kinds, i'm not sure you'll find in the standard lib

16:19 LauJensen: cark: I did a project about a year ago, where I added some simple ftp upload/download functionality, and I'm almost certain I did it using a class called FTPClient from the standard libs. I just seemed to have lost the source

16:20 cemerick: LauJensen: FTP URLs will be loaded OK for the most part, but anything beyond a simple fetch in a vanilla context (e.g. firewalls) will fail

16:20 LauJensen: cemerick: loaded?

16:20 cemerick: I believe so. Might be totally making it all up.

16:21 cark: "un Microsystems provides an RFC959 implementation in the JDK, but it is internal, undocumented, and no source is provided"

16:22 http://www.javaworld.com/javaworld/jw-04-2003/jw-0404-ftp.html

16:22 LauJensen: cemerick: You should get into politics :)

16:22 cark: at least you can upload and download

16:22 cemerick: hey, who knows :-P

16:22 I seem to remember using straight FTP URLs in the distant, hazy past.

16:22 cark: so cemerick might be right, unless he's wrong, which is unlikely

16:23 LauJensen: cemerick: But what do you pass that url to ?

16:23 FileWriter?

16:23 cark: you have an example on the page i linked to you !

16:23 bottom of first page

16:24 cemerick: url.openConnection() or something like that

16:24 LauJensen: cark, that doesnt tell me what to import, theyre not using qualified names

16:24 ah ok, the io streams, gotcha

16:28 cemerick: heh, see, I never forget anything :-P

16:28 (-> (URL. "http://releases.mozilla.org/pub/mozilla.org/xulrunner/releases/") .getContent)

16:28 #<PlainTextInputStream sun.net.www.content.text.PlainTextInputStream@e2f97ff>

16:28 gah, that was supposed to be my ftp url

16:29 user=> (-> (URL. "ftp://ftp-test.mozilla.org/index.html") .getContent)

16:29 #<MeteredStream sun.net.www.MeteredStream@424c4ff8>

16:29 LauJensen: Awesome

16:30 Almost as seamlessly integrated as in .NET

16:30 cemerick: But seriously, that client *will* break

16:30 LauJensen: Yarly ?

16:30 cemerick: well, as much as any other client will break

16:30 cark: what's this meteredstream ... looks like i reinvented the wheel again

16:30 cemerick: FTP is pretty rough with modern firewalls, NAT, etc

16:31 LauJensen: cemerick: This is not a complicated case. My wife dislikes tinypic, so she wants an app where she can right click on an image, scale it quickly and then upload it to my ftp site, returning to her an url she can use to show the picture to her friends. I think it'll hold up for that challenge :)

16:32 cemerick: you hope. Get her on a wifi network configured just right, and she won't be happy *shrug*

16:32 LauJensen: hehe - So you have the gift of pessimism I take it ?

16:32 cemerick: I guess I'm just virulently anti-FTP

16:32 stuartsierra: LauJensen: sounds like a case for a web service. POST the image, get URL back.

16:33 Probably about 5 lines of PHP.

16:33 cemerick: stuartsierra: oooh, I'm calling the REST police on you. Shouldn't it be a PUT? :-P

16:33 stuartsierra: Either way.

16:33 LauJensen: stuartsierra: Nope, Swing app. When you start it with an image as a paramter, its render with X and Y axis shown in Sliders. You can drag those to quickly scale the image. Then upload when happy

16:33 I just need to implement cropping

16:34 cemerick: well, it was fun to make the comment, anyway

16:34 stuartsierra: Right, but you could upload via HTTP.

16:34 cemerick: :P

16:35 LauJensen: stuartsierra: I think its simpler to just code the client and use an existing ftp server

16:35 stuartsierra: ok

16:49 LauJensen: stuartsierra: But in the event that it wasnt, how do you post a file from java ?

16:49 stuartsierra: You can use clojure.contrib.http.agent or clojure-http-client.

16:51 LauJensen: Or loot them anyway :)

16:53 stuartsierra: (http-agent "http://example.com/&quot; :method "POST" :body (File. "image.jpg"))

16:54 LauJensen: Thats easy. But also async. Is there a progress callback or similar ?

16:54 hiredman: that is pretty nice

16:54 stuartsierra: Call (result (http-agent ...)) and it will block until finished.

16:54 * hiredman will have to remember that

16:54 stuartsierra: Or poll with (done? the-agent)

16:55 LauJensen: k

16:55 Thanks

16:55 stuartsierra: np

16:56 LauJensen: stuartsierra: You also mentioned 'clojure-http-client', where can I look that up ?

16:57 stuartsierra: http://github.com/technomancy/clojure-http-client

16:57 I think it uses Apache HTTP Client.

16:58 LauJensen: Doesnt look like it

16:59 stuartsierra: You're right, it doesn't.

16:59 LauJensen: Now you woke him up :)

16:59 stuartsierra: oops :)

17:00 LauJensen: The contrib version might be the way to go. It'd be great to implement some type of progress indicator though. When the client is the Mrs.' I'm not sure I can get away with "working"..."done" :)

17:02 technomancy: did I miss something?

17:02 stuartsierra: LauJensen: good point, hadn't thought of that.

17:03 LauJensen: technomancy: Dont think so

17:03 Just having a look at your http-client

17:04 stuartsierra: Trouble is, in your case the slow part would be uploading, and that's all under the control of HttpURLConnection.

17:05 well, not entirely

17:06 I suppose http.connection/send-request-entity could re-implement copy, and update an atom with the number of bytes copied.

17:07 likewise with the default response handler

17:07 LauJensen: Sounds good

17:07 Sometimes you cant avoid having to go to a lower level though

17:08 stuartsierra: I'll certainly think about it. It's a worthwhile feature to add, and fits with the asynchronous design I was aiming for.

17:09 LauJensen: Alright

17:12 Neronus: good lord, Dan Weinreb is really really excited about clojure...

17:12 stuartsierra: LauJensen: http://www.assembla.com/spaces/clojure-contrib/tickets/20-Report-progress-in-http-agent

17:12 LauJensen: I'm a little lost regarding the use of :use, :import, :require etc. When I want to refer stuartsierra's http-client, which options do I choose, and why ?

17:13 Chouser: :import is only for Java classes, not clojure libs.

17:13 LauJensen: k, thats an easy one to remember

17:14 hiredman: and :require is better than :use

17:14 :P

17:14 Chouser: :require provides only a subset of :use's features, so these days I recommend always using :use

17:14 stuartsierra: "use" copies symbols into the current namespace. "require" doesn't.

17:14 hiredman: require keeps symbols prefixed

17:14 Chouser: (:use [clojure.contrib.http-client :as hc :only []])

17:14 LauJensen: hiredman: haha

17:14 Ok, thanks guys

17:14 technomancy: stuartsierra: I ended up defining "get" in the "resourcefully" ns in my http client, forcing people to require it instead of using it, just like your str-utils2.

17:14 jury is still out on whether that's a win or not...

17:15 LauJensen: Chouser: :only [] ??

17:15 lowlycoder: does clojure run on java 7 yet?

17:15 stuartsierra: I think it's inevitable that many libraries will want to define things that clash with core.

17:15 Chouser: LauJensen: yes, that part makes :use act like :require

17:15 stuartsierra: The alternative is to put "my-lib-" prefixes on everything, and that's a pain.

17:15 technomancy: I guess it's good if it encourages people to not be sloppy about just dumping whole libs into their namespaces.

17:15 LauJensen: Chouser: And if I dont use :as, all funcs will be interned into my own ns ?

17:15 hiredman: lowlycoder: sure

17:16 Chouser: LauJensen: if you don't say :only [], all funcs will be refered into your own ns, yes.

17:16 we need :uses to replace :use and :require.

17:17 One big question I still have about :uses is how to provide a default alias without it being a name that magically shows up without beding declared.

17:17 technomancy: didn't realize you could :use with :as

17:18 Chouser: technomancy: I like it because then if I want to refer in a name I can just add it to the :only [] list, instead of having to move the whole lib from a :require to a :use block.

17:19 technomancy: yeah, if :as is supported in :use I don't see why :require is necessary.

17:19 for common usage anyway

17:19 Chouser: right. but the default behavior of :use (refering in everything) is undesirable.

17:21 LauJensen: I think its sweet

17:22 Chousuke: rah.

17:22 why can't I change the background of the hl-line face :(

17:23 stuartsierra: I do

17:23 Chousuke: you can

17:25 Chousuke: stuartsierra: no I can't. I'm trying to do it here via customise and it's just not taking effect.

17:25 LauJensen: stuartsierra: result and done?, where are they from?

17:25 stuartsierra: LauJensen: part of c.c.http.agent

17:25 LauJensen: Maybe I'm on an old version

17:25 Its spawns the agent, produces no result, and I dont have result/done?

17:26 Chousuke: stuartsierra: I tell it to make background black and it stays the default olive green.

17:26 technomancy: Chousuke: works for me: (set-face-background 'hl-line "black")

17:27 stuartsierra: same, works for me, sorry

17:27 Chousuke: curiously enough, edits to other attributes do take effect.

17:27 LauJensen: "Agent has errors" hmm..

17:27 Chousuke: maybe it's customize being weird...

17:27 Chouser: oh! emacs?

17:29 stuartsierra: LauJensen: can you show me what you're trying?

17:29 Chousuke: hm

17:29 LauJensen: stuartsierra: (def tst (http-agent "http://localhost:8888/backdoor/&quot; :method "POST" :body (File. *pic*)))

17:29 Chousuke: it says: invalid face: hl-face :/

17:30 technomancy: Chousuke: hl-line or hl-face?

17:30 stuartsierra: LauJensen: check (agent-errors tst)

17:30 LauJensen: stuartsierra: (#<IllegalStateException java.lang.IllegalStateException: Already connected>)

17:30 technomancy: Chousuke: if you do your IRC from Emacs you can eval it in-place. =)

17:30 stuartsierra: hmm, let's see

17:30 LauJensen: Thats unexpected, since my webserver should tell me when a POST is attempted

17:30 Let me clean up and try again

17:31 Chousuke: technomancy: complains about both :P

17:32 LauJensen: stuartsierra: Rebooted everything, server, client, slime, the works. Still goes to the same exception straight after being launched

17:32 clojurebot: slime is icky

17:32 LauJensen: Can somebody please ban clojurebot for that last remark ?

17:32 clojurebot: for is not a loop

17:33 stuartsierra: LauJunsen: ok, can you paste (.printStackTrace (first (agent-errors tst)))

17:33 LauJensen: stuartsierra: Sure: "nil"

17:34 stuartsierra: Are you using SLIME? The result will be in the *inferior-lisp* buffer.

17:34 LauJensen: ~paste

17:34 clojurebot: lisppaste8, url

17:34 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

17:34 LauJensen: (sorry)

17:35 lisppaste8: Lau pasted "Stacktrace http-agent" at http://paste.lisp.org/display/85688

17:36 stuartsierra: aha!

17:36 LauJensen: I think you've got an old version.

17:36 LauJensen: What do you see?

17:36 git pull + ant will give me the lastest right?

17:37 stuartsierra: If you're using the master branch, yes

17:37 LauJensen: I am

17:37 sec

17:37 updating

17:37 stuartsierra: HttpURLConnection.setFixedLengthStreamingMode is called in the wrong place, that's a bug that I fixed a couple of days ago.

17:38 LauJensen: stuartsierra: Updating actually worked, but fired an error on the server - That might be my wrongdoing though. java.lang.IllegalArgumentException: URLDecoder: Incomplete trailing escape (%) pattern

17:39 stuartsierra: Looks like a bad character in your URL.

17:39 LauJensen: http://localhost:8888/backdoor/ - Dont see what could be wrong with that

17:39 saml: do you have a hello world example? like writing (println "Hello World") to a file and run/compile the file?

17:40 stuartsierra: You're saying the *server* threw an exception in response to the POST?

17:40 LauJensen: Yes sir

17:41 stuartsierra: Ah, I see. The server may be trying to parse the POST body as application/x-www-form-urlencoded, which it isn't, because you're posting the file directly.

17:42 I haven't (yet) implemented multipart/form-data.

17:42 LauJensen: Sounds likely...Hmm

17:42 stuartsierra: You may need to set a "Content-Type" header on the POST, or modify your server code.

17:43 LauJensen: stuartsierra: Its simple to hardcode the content-type on my server, do you suppose this will work if its ust set to multipart/form-data ?

17:44 stuartsierra: No it dies the same way

17:44 stuartsierra: I don't think so. It's the content-type of the *request* that matters here, not the response.

17:45 LauJensen: k

17:45 stuartsierra: Cant I mangle the :body manually some how ?

17:45 stuartsierra: Sure, if you want to implement multipart/form-data :)

17:46 LauJensen: How about I implement a ticket on assembla and then you do it, and feel really productive? :)

17:46 stuartsierra: heh, ok

17:46 I'm not promising it for this week, but it is a feature I plan to add

17:46 LauJensen: Alright, cool. Although that leaves me a little stuck. technomancy can your http-client handle this?

17:47 technomancy: LauJensen: only one way to find out.

17:47 oh, form-data you mean?

17:47 LauJensen: And thats having you test it while I kick back and rela?

17:47 x

17:47 Yea

17:47 technomancy: yeah, it's supported.

17:47 stuartsierra: What's your server doing? It should provide a way to access the raw POST body without parsing it.

17:48 technomancy: I haven't used it in a while though... since around the release of 1.0

17:48 LauJensen: stuartsierra: I would think so, Im just not sure why its throwing the exception at the level its doing, ie. not even understanding the url

17:48 stuartsierra: It's not the URL. It's trying to URL-decode the POST body. I'm pretty sure.

17:49 HTML forms sent via POST are URL-encoded.

17:49 technomancy: it doesn't generate multipart/form-data requests, does it?

17:50 LauJensen: stuartsierra: this is being done before my handler ever evaluates, so I dont know where to work around it

17:50 technomancy: stuartsierra: no, I was thinking of application/x-www-form-urlencoded

17:50 my bad

17:50 danlarkin could have added it when I wasn't paying attention though.

17:50 LauJensen: I think I'll post it on Compojures google group, James Reeves usually has a 1-2-liner solution for this type of dilemma :)

17:51 stuartsierra: Just glanced at it, didn't see anything. Multipart is complicated, have to do base64 and everything.

17:53 * stuartsierra considers implmenting base64 in pure Clojure.

17:53 stuartsierra: ugh

17:54 technomancy: javamail has a lot of good mime functionality, but adding a dep sucks.

17:56 * stuartsierra sighs and begins (def *base64-alphabet* "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")

17:57 LauJensen: stuartsierra: Get some coffee, msg me when youre done :)

17:57 stuartsierra: LauJensen: *You* get me a coffee. :)

17:57 LauJensen: Haha :)

17:58 I would love to sir, but I have to get to bed now - Good night all, and thanks for the help

18:04 hiredman: I have uuencode/decode functions I started on, but it's finished or documented :(

18:05 er

18:05 it isn't

18:05 * stuartsierra looks at the source to Apache Commons Codec's Base64 class.

18:05 stuartsierra: This is not trivial.

18:06 hiredman: that would explain why I never finished it

18:06 and gist.github is not resolving :(

18:20 stuartsierra: http://paste.lisp.org/display/85694 Close but not correct.

18:26 Duh, use OR, not AND: http://paste.lisp.org/display/85694#1

18:29 hiredman: so for length less then 3 you just pad to 3 and recur?

18:29 stuartsierra: not quite, working on that now

18:31 http://paste.lisp.org/display/85694#2

18:36 Hah! http://paste.lisp.org/display/85694#3

18:37 (encode-str "hello") ;;=> "aGVsbG8="

18:38 doubtless not very efficient, but it does work

18:39 cark: cool addition to contrib =)

18:40 * stuartsierra works on adding line breaks

18:48 * stuartsierra finished adding line breaks

18:58 * stuartsierra pushed clojure.contrib.base64 to master.

18:59 stuartsierra: doesn't do decoding yet, but I need to go home

19:39 Chouser: rhickey: I added a chunked doseq to http://www.assembla.com/spaces/clojure/tickets/1 -- is that how you want it, or do you want separate tickets or ...?

20:15 rhickey: Chouser: that's fine, as long as they are separate patches

21:40 Chouser: ,(chunked-seq? (seq (map first (take-while identity (iterate next [1 2 3])))))

21:40 clojurebot: false

21:40 Chouser: is there a better way to un-chunk a seq (for testing)?

21:44 Chousuke: hm

21:46 ,(chunked-seq? (concat (map inc [1 2 3 4 5]) nil))

21:46 clojurebot: false

21:47 Chousuke: I guess the nil might be unnecessary :/

21:47 ,(chunked-seq? (concat (map inc [1 2 3 4 5])))

21:47 clojurebot: false

21:48 Chouser: ah! that'll do.

21:50 concat could become chunked though, I suppose

21:51 iterate too, at that rate.

21:52 rhickey: you have a list somewhere of the fns you want to support chunked seqs?

21:55 rhickey: Chouser: I imagine a seq1 function that will stream any seq as non-chunked

21:56 I don't have a list, 'for' would be a primary candidate, chunk handling only on fastest moving bit

21:57 Chouser: ooh

21:57 I've started looking at it, so reduced requirements are welcome.

21:58 doseq was meant as a warm-up. :-)

21:59 so just the innermost seq, because that controls the resulting chunks

22:00 rhickey: right, and dominates, being the inner loop

22:01 Chouser: I did a couple experiments translating 'for' forms into map/filter/take-while chains, hoping the chunking there would be good enough.

22:01 it's not.

22:03 current 'for' can be faster than that.

22:08 oh, but take-while doesn't chunk yet -- I missed that.

22:09 tomoj: hmm.. so the normal sequence operators will work faster with chunked seqs?

22:09 I thought it was a separate interface

22:10 Chouser: tomoj: it's a separate interface at the first/rest chunk-first/chunk-rest level, but the higher level functions abstract that away

22:10 if you're using map on a vector, it's already faster.

22:11 tomoj: nice :)

22:19 I spent a few hours yesterday trying to figure this problem out only to realize there was a much easier way to solve my original problem without solving this problem

22:19 if anyone's interested, https://gist.github.com/e45aa328bb180bae8fd9

22:30 rlb: Just got the first audio playing with clojure acting as a controller for a squeezebox -- clojure acts as the controller, and for now, mpd serves the audio stream.

22:31 It could be turned into a way to make a squeezebox track (and control) an mpd server.

22:31 (we'll see)

22:50 deleuze: Where would be a good place to start if I've never used clojure (but love scheme and know java) and want to write a terminal wrapper (I want to wrap rxvt or xterm or anything similar). I know this is very little to go on but terminals haven't been an easy thing for me to find info on.

22:52 I was hoping to learn clojure through this project.

22:52 Raynes: I would highly recommend purchasing Stuarts book, Programming Clojure.

22:55 rhickey: Keynote at the JVM Language Summit!: http://openjdk.java.net/projects/mlvm/jvmlangsummit/agenda.html

22:59 Chouser: rhickey: great! Congrats!

22:59 rhickey: now I just need something interesting to say :)

23:00 last year it was a terrific group of very experienced very smart people

23:02 rlb: Is DataOutputStream a reasonable way to create binary network packets from clojure, or is there something more clojure-specific?

23:06 Chouser: rlb: unlikely there's anything more clojure specific.

23:06 rlb: Chouser: OK, thanks

23:08 (I also managed to arrange it so that you have a java Graphics that you can transfer to the squeezebox display. Though it's very rough as yet.)

23:08 deleuze: Raynes: just ordered it :)

23:09 Raynes: I recently finished SICP, I'm very excited for something new.

23:09 Raynes: (just ordered it, on your suggestion I meant, thank you.)

23:11 Raynes: is writing a shell wrapper (enhancing the shell by wrapping it's output but having it remain interactive) an insane idea?

23:12 Raynes: I began by looking at the CLI class but it seemed more for handling getopt type func.

23:23 lowlycoder: which part of the clojure doc will tell me: "if all the fields of two structs are =, then they are =" ?

23:23 (some preliminary testing shows this to be true, but I want to know if it's guranteed)

23:25 hiredman: lowlycoder: clojure's = is egal, and that is a property of egal

23:26 rlb: (Why doesn't ByteArrayOutputStream have a rewind method...)

23:30 I'd like to leave a placeholder for the packet length, and fill it in at the end. I suppose I can just continue concatenating a length byte array and the command byte array.

23:31 Raynes: deleuze: I'm sorry I disappeared there!

23:32 deleuze: I don't think it's an insane idea at all, and you're very welcome. It's a good book.

23:35 rlb: I know I can concatenate two byte arrays like this (or use native java ops): (into-array Byte/TYPE (concat ar-1 ar-2)), but is there a better clojure idiom?

23:37 tomoj: that into-array thing seems inefficient

23:40 rlb: tomoj: I would assume -- as I mentioned, I much prefer to just leave 2-bytes at the head of the packet and then fill it in after the packet's finished, but offhand, I don't see any way to do that with ByteArrayOutputStream.

23:40 Of course I could just fill in the length bytes myself. I may do that.

23:41 It was just easy to use DataOutputStream's writeShort, writeInt, etc.

23:43 Of course none of this matters much, performance-wise. These are tiny packets.

23:43 (and not often sent)

23:45 tomoj: was there something like a DataOutputStream/DataInputStream that also had information about what type came next? I vaguely remember that from my java days

23:46 lowlycoder: how do I create a vertex of references?

23:46 *vector*

23:47 tomoj: ,[(ref 0) (ref 1)]

23:47 clojurebot: [#<Ref@149a2c8: 0> #<Ref@15e0eab: 1>]

23:47 lowlycoder: i need n of them, where n is a variable

23:47 create the list and then 'vec' it ?

23:48 hiredman: ,(vec (take 10 (repeatedly #(ref 1))))

23:48 clojurebot: [#<Ref@5789f3: 1> #<Ref@121ea24: 1> #<Ref@192e317: 1> #<Ref@7b0f4d: 1> #<Ref@12996d6: 1> #<Ref@16de641: 1> #<Ref@27de24: 1> #<Ref@1692a49: 1> #<Ref@157402b: 1> #<Ref@135f7f3: 1>]

23:48 hiredman: ,(doc repeat)

23:48 clojurebot: "([x] [n x]); Returns a lazy (infinite!, or length n if supplied) sequence of xs."

23:48 hiredman: ,(doc repeatedly)

23:48 clojurebot: "([f]); Takes a function of no args, presumably with side effects, and returns an infinite lazy sequence of calls to it"

23:49 tomoj: is vec better than into?

23:49 hiredman: possibly

23:50 I thin into uses reduce and conj

23:50 vec might do something clever

23:50 ~def into

23:50 ~def vec

23:50 tomoj: vec looks faster

23:51 rlb: s/aref/aget/...

23:51 lowlycoder: is there a more idiomatic way (not using #%) to write: (fn [f] (let [x (f :x) y (f :y) z (f : z)]

23:51 basically, I have a (defstruct face :x :y :z) ... and I want to deconstruct it

23:51 hiredman: ~destructuring

23:51 clojurebot: destructuring is http://clojure.org/special_forms#let

23:52 hiredman: everything you want to know

23:52 yeah

23:52 lowlycoder: {:keys [ ... ] } eh?

23:52 hiredman: vec just pulls out an array and stuffs it into a vector

23:53 lowlycoder: destructuring also works in the argument vector

23:53 lowlycoder: how so?

23:53 hiredman: just like in let

23:53 lowlycoder: whoa, so fn [{:keys [x y z]] ?

23:53 derrida: where does the vector data struct originate?

23:53 hiredman: ,((fn [{:keys [a b c]}] [a b c]) {:a 1 :b 2 :c 3})

23:53 clojurebot: [1 2 3]

23:54 hiredman: derrida: what do you mean?

23:55 derrida: sorry, was just wondering out loud what language(s) use vector the same way

23:55 lowlycoder: how do I add into a set?

23:56 derrida: hiredman: didn't mean to interrupt ;)

23:56 tomoj: ruby has similar in-language vectors, but they're called arrays

23:56 hiredman: ,(doc conj)

23:56 clojurebot: "([coll x] [coll x & xs]); conj[oin]. Returns a new collection with the xs 'added'. (conj nil item) returns (item). The 'addition' may happen at different 'places' depending on the concrete type."

23:56 lowlycoder: what? I can cons into a set too?

23:56 why should i use conj over cons?

23:56 derrida: tomoj: java class Vector is not quite the same, right?

23:57 r2q2: clojurebot: (cons [1 2] [3 4])

23:57 clojurebot: It's greek to me.

23:57 tomoj: derrida: not even close

23:57 r2q2: clojurebot: eval (cons [1 2] [3 4])

23:57 clojurebot: eval is evil

23:57 tomoj: oh, and of course ruby's aren't even close either

23:57 since they're not immutable

23:57 derrida: :)

23:57 Chouser: ,(cons [1 2] [3 4])

23:57 clojurebot: ([1 2] 3 4)

23:57 tomoj: clojure's vectors are unique, afaik

23:57 Chouser: ,(cons :x #{:a :b :c})

23:57 clojurebot: (:x :a :c :b)

23:57 r2q2: ,(conj [1 2] [3 4])

23:57 clojurebot: [1 2 [3 4]]

23:57 tomoj: but some other languages also have in-language vectors

23:57 hiredman: someone ported them to scala

23:57 r2q2: Notice the difference?

23:57 Chouser: ,(class (cons [1 2] [3 4]))

23:57 clojurebot: clojure.lang.Cons

23:57 derrida: yeah, what do you mean in-language?

23:58 Chouser: ,(class (conj [1 2] [3 4]))

23:58 clojurebot: clojure.lang.PersistentVector

23:58 lowlycoder: what's the inverse of get? (set is the set function, not actually setting a element)

23:58 tomoj: derrida: vectors are part of the language itself, no one had to go write a Vector class

23:58 derrida: tomoj: ah gotcha

23:58 tomoj: mostly I think a literal syntax for vectors is the big thing

23:58 clojurebot: for is not a loop

23:59 hiredman: lowlycoder: spent anytime with the docs?

23:59 derrida: tomoj: clojure's vector is the only vector i have encountered i felt deserved the title :)

23:59 tomoj: you don't have to screw around with ArrayList<FooBar> crap

23:59 lowlycoder: nope, what's irc for?

23:59 derrida: lowlycoder: procrastinating

Logging service provided by n01se.net