#clojure log - Oct 05 2009

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

0:00 arbscht: consider passing keyword arguments as a hash-map instead

0:01 rongenre: Yeah I can do that also. Although it makes the function calls look a bit weird, don't you think?

0:01 somnium: you could write a kwfn macro the binds them in a let for you

0:01 though that might be getting carried away

0:02 rongenre: Ah.. here I go http://groups.google.com/group/clojure/msg/51bb53ca077154f8

0:04 arbscht: rongenre: defnk is in clojure.contrib.def

0:04 but I've never seen it used in the wild

0:05 rongenre: Gotcha -- trying to get a feel for what's idiomatic. Is the usual idea just not to use optional params?

0:05 arbscht: I have seen the hash-map of options, though, and it doesn't really look bad

0:05 generally, optional args are taken care of with arity overloading

0:06 poet: Anyone using VimClojure have a problem where everything works but the local keybindings?

0:06 function completion, rainbow paren, everything but the local keybindings that are supposed to be set when a .clj file is opned

0:07 rongenre: arbscht: thanks!

0:08 arbscht: clojure code tends to use simple function protocols. there's not much benefit in keyword args, since binding forms inside the function can destructure a hash-map just the same, and it's easy to construct them with literal syntax

0:09 rongenre: Sure, or even a (let [foo (args :foo def) [...]]) looks ok

0:11 arbscht: ,((fn [{:keys [a b]}] [a b]) {:a 1 :b 2})

0:11 clojurebot: [1 2]

2:54 LauJensen: asd

2:55 oops - Morning guys

3:17 G0SUB: Hmm, so I am trying to parse an XML structure like this using c.c.lazy-xml http://pastebin.com/d18385f13

3:17 (zfxml/xml-> test-xml :item :email zfxml/text)

3:17 (zfxml/xml-> test-xml :item :name zfxml/text)

3:18 these work fine for me.

3:18 but I want to get the data out in groups all at once.

3:18 instead of ("Foo" "Bar" "Fubar" "Baz") and ("a@b.com" "x@b.com" "s@b.com" "q@b.com"), I want it like (["Foo" "a@b.com"][][]), etc.

3:18 any tips?

3:24 konr: G0SUB: well, you can create a map, I guess

3:24 something like

3:24 ,(map #(vec (list %1 %2)) (range 1 10) (list "foo" "bar" "baz" "bak"))

3:24 clojurebot: ([1 "foo"] [2 "bar"] [3 "baz"] [4 "bak"])

3:25 G0SUB: konr: yeah, but I was wondering if it can be avoided. I am not too well acquainted with the xml lib.

3:44 Fossi: hi

3:47 wooby: hello

4:26 snowwhite: Is there any debugging tool for clojure?

4:29 LauJensen: ~google clojure debugging

4:29 clojurebot: First, out of 12900 results is:

4:29 Clojure - getting_started

4:29 http://clojure.org/getting_started

4:29 Fossi: snowwhite: any java remote debugger will more or less work

4:33 snowwhite: Fossi, ok

4:34 Fossi: i rarely debug though. do people around here do it?

4:34 tests and log messages are so much more useful with a lisp imho

4:35 LauJensen: Yea the only time I go out of Emacs is for profiling... but Im thinking now, that there probably is a 'java-profiler-mode' for emacs

4:50 Raynes-: I've never used a debugger.

4:50 Ever.

4:50 * Raynes- is hardcore.

4:52 Raynes: Whoa, loloh has Factor listed in their languages, but not Clojure. O.O

4:54 jdz: lolwhat?

4:57 Fossi: ohlo i guess

4:59 Raynes: Oops.

4:59 ohloh*

4:59 jdz: Sorry, I never even noticed I did that. It's quite late here.

4:59 * Raynes goes to sleep.

5:41 wooby: how would one generate a lazy sequence of random nums?

5:41 i think i need to use iterate but i'm not sure

5:41 jdz: ,(doc repeatedly)

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

5:41 wooby: awesome thank you

5:41 jdz: that was just a guess :)

5:42 wooby: i'm still working on my guessing skills ;)

5:47 LauJensen: ~def memoize

6:13 Who was it that expressed an interesting in seeing an optimized version of Brians Brain ?

6:24 G0SUB: clojurebot: help

6:24 clojurebot: http://www.khanacademy.org/

6:33 namor_: Hmm, #clojure has more people in it than #scala.

6:34 arbscht: namor: how many bots does #scala have?

6:35 namor: Good question, I have no idea.

6:39 wooby: 2 that i know of

7:10 konr: Guys, am I setting a constructor when I extend a class with (def foobar-extension (proxy [Foo] [] (foobar-extension ....)))?

7:12 Also, how can I call the superclass function?

7:12 LauJensen: no and you cant - if I understand proxy correctly

7:13 (doto (foo-extension. ctor1 ctor2) (proxy [foo] (bar foo)) ... will pass a constructor and return an object with the overridden method

7:22 konr: LauJensen: where ctor1 and ctor2 are the arguments of foo or foo-extension's constructor functions?

7:23 LauJensen: foo

7:26 konr: so there is no way to write a constructor function for the extended class?

7:28 LauJensen: ~proxy

7:28 clojurebot: proxy is <Chouser> proxy teases with its ease of use, then suddenly betrays.

7:28 LauJensen: Proxy has some show-stopping limitations, when you need to get around them use gen-class or 'new new', which Im not is ready yet

7:29 sgtzx_, licoresse and anyone else who read Brians functional brain, I have a follow up post: http://www.dzone.com/links/brians_transient_brain.html

7:31 licoresse: yup

7:31 :-)

7:33 LauJensen: Constructive critisms are as always discouraged :)

7:33 (kidding ofc)

7:54 licoresse: my clojure does not understand transient

7:54 ,(doc transient)

7:54 clojurebot: "([coll]); Returns a new, transient version of the collection, in constant time."

7:54 LauJensen: please update :)

7:56 licoresse: trying now

7:56 LauJensen: I'm just in a regular git clone && ant version

7:57 licoresse: I'm not that advanced

7:57 after a M-x clojure-update it's all the same

7:57 LauJensen: oh

7:58 licoresse: this is a mess

7:58 *clojure-version* does not mention alpha though

7:59 so I guess I need to go over to an alpha-jar or something

8:03 Fossi: LauJensen: nice read, definitely another tool to look forward to

8:04 (not being on latest/greatest)

8:04 LauJensen: Yea

8:04 I actually thought this got into 1.0, but it seems I'm so bleeding edge I don't even notice it anymore

8:04 Fossi: then again we haven't even used type hints yet

8:05 LauJensen: we haven't ?

8:05 liwp: LauJensen: have you done something to your syntax highlighting on the blog? Changed a font maybe?

8:05 Fossi: as in, me and my collegue

8:05 LauJensen: liwp - Yea, font-family: mono

8:05 licoresse: LauJensen: It's too small

8:05 liwp: the old one looks better IMO - on windows

8:05 then again it's all subjective isn't it

8:06 licoresse: liwp: agree, on mac too

8:06 LauJensen: ok - I changed it because of comments actually, so I'll see what people say this time

8:07 liwp: LauJensen: you could try not using bold faces and / or increasing the size a bit...

8:07 LauJensen: liwp, Could I trouble you to email me a screenshot ?

8:08 liwp: LauJensen: sure, give me a minute. DO I have your email address? PM me.

8:08 LauJensen: If not it's in the right column on the blog

8:08 liwp: ahh :)

8:11 Fossi: yeah, monospace fonts are very different size on linux/mac/win :(

8:11 LauJensen: So what do people use? In Emacs I use inconsolata, but that's not gonna fly on the web

8:12 Fossi: can't do much about it really

8:12 liwp: I have no idea what my emacs font is. Is there an easy incantation to find it out?

8:12 ahh, got it

8:12 LauJensen: oh man that's ugly liwp

8:12 liwp: it's courier

8:13 LauJensen: From now on my blogposts will be a 800x9000 jpeg :)

8:14 liwp: I use courier on putty as well. I tried using other fonts, e.g. inconsolata, but courier seems to look better on an LCD without antialiasing or cleartype

8:14 I think I use monaco at home on OS X

8:21 licoresse: how can I stop the simulation without restarting slime?

8:21 LauJensen: ^^

8:21 LauJensen: change (while true...) to (while @running ..) and set a global atom to true, you can the use (ref-set! running false) to stop it

8:21 licoresse: thx

8:22 LauJensen: np :)

8:23 arbscht: ,(doc reset!)

8:23 clojurebot: "([atom newval]); Sets the value of atom to newval without regard for the current value. Returns newval."

8:24 LauJensen: that's the one :)

8:24 licoresse: you're always so helpful!

8:32 mathias`: I am using the clojure.contrib.shell-out package to execute a shell command. How can I make it asynchronous?

8:33 LauJensen: ,(doc future)

8:33 clojurebot: "([& body]); Takes a body of expressions and yields a future object that will invoke the body in another thread, and will cache the result and return it on all subsequent calls to deref/@. If the computation has not yet finished, calls to deref/@ will block."

8:33 chouser: mathias`: It doesn't support asynchronous [yet]. For now you can look at its code and use the Java libs directly as it does.

8:34 mathias`: LauJensen: Will try that.

8:34 chouser: mathias`: what's your use case? I'm still thinking about the best way to add async support.

8:34 ambient: LauJensen thanks for yet another great blog post :)

8:34 LauJensen: ambient, thanks :)

8:36 mathias`: chouser: I have a small compojure app running (started as a service, as root) and want to start mplayer within it. And when I do that I do not get the REPL back (I am using SLIME to connect to the server) until the player is done. To be able to control it (pause, quit etc) I need to get it released so that I can send it commands.

8:37 chouser: future seems to work great though

8:37 chouser: mathias`: you don't need to collect output from it along the way?

8:37 mathias`: chouser: nope

8:37 chouser: this is just for playing movies via a small web app

8:37 chouser: ah, yep. "future" it is. Or perhaps "agent"

8:43 mathias`: LauJensen: works, thanks!

8:44 LauJensen: sweet, np

10:30 rosejn: Can anyone recommend a good way to block and wait for an asynchronous operation to occur? I'm writing a network client, and in some situations I want to block waiting for a response message. How is this best done in Clojure?

10:31 A message handler thread gets all incoming messages, and then somehow I need to forward it to a waiting thread and wake it up.

10:31 It doesn't seem like awaiting agents or watcher functions or futures as they are setup in Clojure work for this case...

10:34 ?

10:34 Fossi: patience... ;)

10:35 duck1123: couldn't you just use an agent, have that agent perform the action that blocks on the IO, and then have it do something (send another agent) once it gets the data?

10:35 or is that a bad thing to do in clojure

10:35 um, I think it's send-off though

10:36 rosejn: Sorry, I wasn't sure if I was connected to the room since it was so quiet...

10:36 The problem is that there isn't an action to perform

10:36 I need to wait on a network packet

10:37 so I can't use a future or an agent, because there isn't any code to execute.

10:38 I can just use something from Java, like wait/notify or some kind of java.util.concurrent queue or something, but I was wondering if there was something that would be cleaner using clojure constructs...

10:39 cgrand: rosejn: promises?

10:39 ,(doc promise)

10:39 clojurebot: "([]); Experimental. Returns a promise object that can be read with deref/@, and set, once only, with deliver. Calls to deref/@ prior to delivery will block. All subsequent derefs will return the same delivered value without blocking."

10:39 cgrand: ,(doc deliver)

10:39 clojurebot: "([promise val]); Experimental. Delivers the supplied value to the promise, releasing any pending derefs. A subsequent call to deliver on a promise will throw an exception."

10:39 rosejn: awesome!

10:40 Exactly what I was looking for.

10:40 Thanks cgrand. I guess I'd need to be checking diffs of the git tree to know about this?

10:41 If only it had a timeout option...

10:44 cgrand: rosejn: you can combine future and promises to mimick timeout

10:44 duck1123: hmm... You could send off an agent thet sleeps, then tries to deliver a null value to the ref. (catching the error on both sides)

10:46 cgrand: rosejn: (.get (future @my-promise) timeout unit)

10:47 rosejn: very cool

10:48 I hadn't thought about composing the reference type functionality like this... let alone promises. Thanks

10:52 cgrand: rosejn: or you can poll the future with future-done?

10:53 rosejn: cgrand: how do you know about all of these secret functions?

10:55 I guess I should be perusing core.clj...

10:55 Fossi: everybody should :D

10:56 cgrand: rosejn: read core.clj once and then stay up to date by reading commit logs and grepping irc logs -- it works for me

10:57 Chousuke: heh

10:58 rosejn: sounds good.

11:02 ngoc: How to compile a Clojure code to a class that has a static "main" method, so that I can run the method from command line?

11:03 tomoj: ngoc: see http://asymmetrical-view.com/2009/06/22/executable-clojure-jars.html

11:07 vy: ngoc: Also see http://clojure.org/compilation

11:10 ngoc: Thank you, vy's link is much easier to follow

11:32 How to access a static class inside a class? Like this one: http://jboss.org/file-access/default/members/netty/freezone/api/3.1/org/jboss/netty/handler/codec/http/HttpHeaders.Names.html

11:34 Names is not a function, so HttpHeaders/Names does not work

11:35 stuartsierra: The real Java name for that class is HttpHeaders$Names

11:55 ngoc: stuartsierra: Thanks a lot, this is really tricky

11:56 stuartsierra: np

12:04 ngoc: When doing "assign then process then assign then process", I use (let [x = 1, y = 2...] (process1) (process2) ...). But this seems to create too many nested "let"s. How to solve this problem?

12:16 stuartsierra: let is sequential

12:16 (let [x 1, y (process1 x), z (process2 y)]...)

12:24 Chousuke: if you don't need the intermediate values, you can do (-> x process1 process2) too

12:24 or just (process2 (process1 x)) :P

12:24 snowwhite: How can i check if "foo" is present in '("bar" "foo")

12:25 Chousuke: anyway

12:25 snowwhite: Chousuke, ?

12:25 Chousuke: snowwhite: you can use the .contains method

12:25 (provided by the Collection interface IIRC)

12:25 snowwhite: Chousuke, checked it only works on maps?

12:26 Chousuke: not contains?, .contains

12:26 ngoc: Chousuke: Do you mean (let [x 1, y (process1 x), (-> x process1 process2)]...) is valid? Sometimes I do not want to assign the result to anything.

12:26 Chousuke: ,(.contains '("foo" "bar") "foo")

12:26 clojurebot: true

12:27 Chousuke: ngoc: no

12:27 snowwhite: Chousuke, contains?

12:27 Chousuke: snowwhite: "contains?" does something entirely different from .contains

12:28 chouser: ,(contains? #{"foo" "bar"} "foo")

12:28 clojurebot: true

12:28 chouser: ,(contains? '("foo" "bar") "foo")

12:28 clojurebot: false

12:28 ngoc: Chousuke: How to write like in C: x = 1, y = 2, do_some_thing(x, y), z = 3, do_some_thing2(y), ...

12:29 mtm: 'contains?' vs. '.contains' seems to be a common point of confusion

12:29 chouser: ngoc: you really don't care about the return values of the do_some_things? They're side-effecty?

12:30 ngoc: yes

12:30 Chousuke: ngoc: side-effects are generally bad, but if you don't care about the return values, you can assign them to _

12:30 which conventionally means "I don't care"

12:31 eg, (let [x 1, y 2, _ (evil-fn), z (+ x y)] ...)

12:33 ngoc: For serial programs, is "let" the most used form in Clojure?

12:33 Chousuke: let is very common in any kind of program :P

12:34 Fossi: and yet, you wouldn't need it at all

12:34 Chousuke: true. you can use fn to do most of what let does

12:35 danlei: most?

12:35 Chousuke: not all, because fn doesn't support primitive locals.

12:35 danlei: "primitive"?

12:35 Fossi: "int" etc

12:35 Chousuke: as in, not Object or descendant :P

12:35 technomancy: danlei: unboxed

12:35 danlei: ah, ok

12:36 tomoj: ngoc: serial programs? :(

12:36 ngoc: tomoj: I mean x = 1, y = 2, do_some_thing(x, y), z = 3, do_some_thing2(y), ...

12:36 Fossi: imperative

12:36 ngoc: I feel that most programs are in this way

12:37 Fossi: ngoc: why use a funtional language then?

12:37 Chousuke: most programs in Clojure should *not* be like that. except locally :)

12:37 you do need some side-effects for every program

12:37 Fossi: with a very good escuse

12:38 Chousuke: but it's not difficult to keep most of the code functional.

12:38 well, hm. not after you get used to it, at least :P

12:38 tomoj: let is such a beautiful thing

12:38 I feel you are trying to rape it

12:39 Chousuke: ngoc: let is sometimes useful like that, but you shouldn't see it as a tool to write imperative programs in Clojure.

12:39 raek: (do (side-effects1) (side-effects2) ...) is common when interfacing with imperative code

12:39 like printing or using java classes

12:42 ngoc: Thank you all, I think I must write more in Clojure to feel convenient with the syntax

12:43 Chousuke: I don't think the syntax is the issue. what you need to learn is a whole different way of thinking about your programs :)

12:44 functional programs don't tell the computer what to do, they tell it what you want. :P

12:45 chouser: I've heard that before, but I'm still not sure I buy it.

12:45 Chousuke: of course, this being the real world and all, you often need to pay attention to what the computer actually does, too, eg. when dealing with performance.

12:55 ambient: i dont see any other differenct in functional programming except that mutation is just an implementation of time. with functional programming one has to model time separately

12:56 Chousuke: I don't know if imperative programming languages model time either :/

12:56 it just exists, and you have to deal with it.

12:56 ambient: well they have state and state by definition exists in a point of time

12:57 Chousuke: Rich makes a good point in his newest presentation why having variables is a broken model for state :)

12:58 jfields: I'm trying run a Clojure script with java -classpath "/path/to/jars/*:" clojure.main my_file.clj and I get Exception in thread "main" java.io.FileNotFoundException: my_file.clj (No such file or directory) - my_file.clj is in a jar file that's in the dir that my -classpath points to. Any ideas?

12:59 chouser: jfields: try @my_file.clj instead

12:59 ngoc: How to refer to Java's "this" in a proxy method?

12:59 Chousuke: ngoc: it's "this"

12:59 ngoc: :D

12:59 Chousuke: ngoc: the symbol is implicitly bound inside a proxy form

13:00 jfields: chouser: thanks

13:00 clojurebot: chouser is ruthless about breaking other people's code

13:00 chouser: clojurebot: botsnack

13:01 clojurebot: thanks; that was delicious. (nom nom nom)

13:01 rsynnott: heh

13:03 ambient: i wish there was a video archive of clojure talks. i hate to use flash :/

13:03 technomancy: +1

13:03 sorry, inc

13:04 chouser: how would the archive be distributed?

13:04 ambient: bittorrent if no else

13:04 chouser: ah

13:05 technomancy: youtube and bitly let you download the videos

13:05 well, you have to use a script for youtube, but it beats watching it in the browser

13:07 ngoc: Why when declaring a namespace, we write (ns a.b), but when using a namespace we write (use 'a.b) (with a quote?)

13:07 technomancy: ngoc: ns is a macro, while use is a function

13:07 so the args to use get evaluated

13:08 ngoc: Why not make them all macros or all functions? So that Clojure looks consistent.

13:09 technomancy: ngoc: you're not supposed to use "use" directly; you should use the ns macro

13:09 sproingie: ns is the thing making it consistent :)

13:12 hiredman: blip.tv lets you download the talks as well

13:12 the only clojure talks you cannot download are the ones on infoq

13:12 chouser: import used to be a function but is now a macro

13:14 The package-importing API isn't finallized yet, I think -- there's been some talk of replacing both 'require' and 'use' with something else, maybe called 'uses'

13:14 hiredman: chouser: it's finalized for 1.0

13:14 chouser: hiredman: so true!

13:14 probably for 1.1 as well

13:29 danlei: what would the semantics of that "uses" roughly be like?

13:29 since require and use are quite distinct to me

13:30 chouser: most of what use and require do are in common (finding a clj or class file for a given namespace, loading that and making the namespace available)

13:31 danlei: well, use is a superset of require, ok

13:31 chouser: both even support :as for aliasing the namespace

13:31 danlei: but still they do different things and I can't imagine atm how they shall be merged

13:31 or, if it's feasible to merge them

13:32 I always felt about require more as a "module" thing, whereas use is more "namespace" to me

13:32 (not well said, but maybe it's comprehensible)

13:33 chouser: so the weaknesses I see are (1) use by default refers in all the foreign var names, but I think this should be discouraged, and (2) require doesn't provide any way to refer in specific vars

13:34 so I'd want a single thing that discourages refering all vars but makes it easy to refer specific vars and/or alias the whole namespace.

13:34 danlei: hm ... I do follow clojure-user but somehow I completely missed this discussion :)

13:35 I see the point, though

13:35 konr: The first version of my code has 109 lines. A simple java widget that I'm import has almost the triple.

13:35 chouser: there's also been talk of having a default alias per namespace, so perhaps (uses clojure.zip) would be default use the alias zip ... and I like that except that then new words may show up without ever explicitly declaring their origin.

13:35 konr: *ing

13:36 chouser: konr: but half the .java lines are blank except for close-curly-brace. You might have to let those slide. :-)

13:36 danlei: I somehow like that idea (default alias)

13:37 on the otherhand, typing :as ... doesn't bother me that much

13:37 chouser: danlei: this conversation has come up once or twice here -- I don't think it's ever made it to email.

13:37 danlei: ah, ok

13:37 G0SUB_: Is there any way to write a http client which downloads files in parellel using agents?

13:42 danlei: chouser: about use referring all vars; how about a more "traditional" approach, in that vars are local to a namespace and must be exported in order to be referred by use?

13:42 s/exported/explicitly exported/

13:43 chouser: danlei: well, that's sort of how it is now. defn creates a "public" var, and defn- a private one -- only public vars are pulled in by 'use'

13:43 danlei: yes, but I'm talking about switching the semantics of defn- and defn

13:43 or intruducing an (export ...) facility

13:43 chouser: my problem with it is if you 'use' a namespace (or worse a few of them) and then I'm trying to read your code, I can't tell what most of your functions are.

13:44 that is, I read (fix-up foo) and I have no idea which namespace is providing fix-up

13:44 technomancy: slime helps a lot with that

13:44 stuartsierra: GOSUB_: that's exactly what clojure.contrib.http.agent is designed to do

13:44 G0SUB_: stuartsierra: cool.

13:44 danlei: hm ...

13:45 chouser: technomancy: yes, once you've downloaded and installed all the dependencies, and loaded up the source you're trying to read, right?

13:45 technomancy: chouser: well that's a whole nother mess

13:45 a lousy build process is orthogonal to readability

13:46 not that I don't think that's important; it bugs me how people act like it's not a problem

13:46 chouser: my point is a perfect build process is orthogonal to readability. :-)

13:47 technomancy: I do agree that it's better to be readable to the un-augmented reader as well; I'm just saying what works for me.

13:48 chouser: technomancy: I'm looking forward to someone solving the dependency and build problem. But even then, all it takes is for some code I'm trying to help with or borrow to use a single proprietary namespace and a few 'use' calls, and I no longer have any clue at all what's going on.

13:49 technomancy: yeah. I tend to do that for "glue" namespaces only. (the shell-zapper namespace calls shell commands on zap-related data, etc.)

13:49 danlei: chouser: I guess I'd prefer aliases to explicitly listing all imported vars as far as that is concerned. I still think that making exported vars the special case and private the default would be feasible.

13:50 chouser: danlei: I don't have an opinion on that -- either default seems fine to me at the moment, I would just like people to be explicit about where they're getting their functions from.

13:51 danlei: chouser: I see ... I already have that problem in my mud client, which is split in 5 namespaces, and I think I'm going to switch to short aliases

13:52 chouser: danlei: yes, I find that to be a nice solution for app-specific namespaces. 3-letter (or even 2- or 1-letter) aliases

13:52 * danlei nodes

13:53 danlei: *nods

13:56 (btw, that's one thing I really dislike about CL's packages: aliases are there written in the package definition, not when using that package)

14:00 G0SUB_: stuartsierra: is it possible to somehow put some extra meta data in the http-agents? I could use that info in the handler to determine the file name to save the reponse to.

14:10 jfields: what's the correct way to convert "2" to 2?

14:10 Integer/parse?

14:10 drewr: ,(Integer/parseInt "2")

14:10 clojurebot: 2

14:10 LauJensen: ,(Integer. "2")

14:10 jfields: thanks.

14:10 clojurebot: 2

14:10 drewr: ,(type (Integer/parseInt "2"))

14:10 clojurebot: java.lang.Integer

14:11 stuartsierra: GOSUB_: not sure what you mean

14:11 drewr: oh I didn't realize there was constructor for string

14:12 G0SUB_: stuartsierra: the handler function takes only one arg (the agent). I am dealing with many agents and want to save each response in a different file.

14:13 stuartsierra: for that purpose I thought I would keep some extra data in the agent itself.

14:13 stuartsierra: right now, I am doing this (:file-name (:clojure.contrib.http.agent/options @ag))

14:14 stuartsierra: to access the file name. is there a better way?

14:14 stuartsierra: hmm, I intended the agent to be an opaque object.

14:14 G0SUB_: I need to download data from a bunch of URLs.

14:14 stuartsierra: I'd recommend making your handler function a closure, and creating it with the file name

14:14 G0SUB_: stuartsierra: makes sense.

14:20 wooby: has anyone tinkered with neural networks in clojure?

14:22 G0SUB_: stuartsierra: worked fine. many thanks for the awesome work.

14:23 stuartsierra: welcome

14:32 namor: Hmm, why does println not work from within an agent?

14:32 clojurebot: http://clojure.org/rationale

14:33 chouser: ,(let [a (agent 42)] (send-off a println))

14:33 clojurebot: #<Agent@916ab8: 42>

14:33 chouser: hm. worked here.

14:33 namor: happen to be using slime?

14:33 LauJensen: namor, in SLIME it'll show up in the *inferior-lisp* buffer

14:33 namor: Ah, that's the reason! Yes, I'm using slime. Thanks.

14:34 jfields: is there something in clojure similar to Ruby's array.join?

14:34 technomancy: jfields: str-join in contrib's str-utils, I think

14:34 jfields: technomancy: thanks

14:35 chouser: jfields: or join in clojure.contrib.str-utils2

14:35 LauJensen: ,(apply str (interpose "," ["foo" "bar" "baz"]))

14:35 clojurebot: "foo,bar,baz"

14:36 hiredman: chouser: clojurebot's *out* and such are setup in a binding, so you need to lexically capture and setup a new dynamic binding in the agent action

14:36 LauJensen: jfields, or roll your own

14:36 chouser: hiredman: yeah, I figured.

14:37 hiredman: I still wading through the evolution of lisp

14:37 I am

14:38 G0SUB_: stuartsierra: is there any way to limit the number of agents running in parallel? the webserver supports upto 15 parallel connections.

14:39 stuartsierra: GOSUB_: not explicitly. The Clojure agent thread pool will limit it to something like 2 * number_of_cores, though

14:39 chouser: but that limit is only for 'send' not 'send-off'

14:39 no limit at all on 'send-off'

14:40 stuartsierra: oh, then never mind

14:40 G0SUB_: stuartsierra: that formula doesn't seem to be working, as the server bails out quickly.

14:40 stuartsierra: If you need to control the number of agents/threads, you're probably better off creating your own fixed-size pool of agents and calling an HTTP client (like Apache's) within the action functions.

14:41 G0SUB_: stuartsierra: I can understand. but that's too much pain for an one-off thing like this.

14:41 stuartsierra: I don't know what else to offer.

14:42 got to go, for now

14:42 G0SUB_: stuartsierra: see you.

14:43 Is partition lazy?

14:43 chouser: G0SUB_: yes

14:43 G0SUB_: cool

14:45 kotarak: When was intern added?

14:46 chouser: neat, alter-var-root trick, btw. :)

14:46 chouser: I think it's very old

14:46 itern, I mean. alter-var-root is newish

14:46 kotarak: Hmm.. I would have expected it the other way around. alter-var-root old and intern new...

14:46 chouser: intern is in 1.0 -- you need more detail than that?

14:47 kotarak: No.

14:47 :)

14:47 chouser: hm, alter-var-root is in 1.0 as well. :-)

14:49 ...and you may be right. "added intern" Nov 26 2008

14:52 alter-var-root showed up with "isa-based multimethods, a la carte hierarchies" Jul 28 2008

14:53 kotarak: Hehe... I was right for some suitable definition of "new". ;)

14:55 G0SUB_: I have a vector of agents. how do I run await on them?

14:55 (await [vec1 vec2]) gave an error

14:55 (await [agent1 agent2]), rather

14:57 hoeck1: GOSUB: maybe: (doseq [a agents] (await a))

14:58 G0SUB_: hoeck1: hmm, would have been great if the vector could be spliced somehow and passed to await all at once.

14:58 megane: or (apply await vec-of-agents)

14:59 G0SUB_: megane: better

15:01 chouser: ah, the implementation of await is so beautiful and simple

15:04 kotarak: Well, it certainly is asynchronous.

15:09 drewr: does clojure.main prefer class files over clj?

15:09 hoeck1: chouser: somehow, I never really enjoyed reading other peoples code, clojure changed this for me by 180 degrees

15:09 kotarak: drewr: it prefers clj if they are newer. If reading from a jar, I think, it always prefers clj.

15:10 drewr: at least there was some issue, that, when reading from a jar, it prefered always on over the other. But it may also be the other way around...

15:12 drewr: kotarak: yeah, I was thinking in a jar

15:12 confusing that it's not consistent

15:17 rosejn: ,(doc use)

15:17 clojurebot: "([& args]); Like 'require, but also refers to each lib's namespace using clojure.core/refer. Use :use in the ns macro in preference to calling this directly. 'use accepts additional options in libspecs: :exclude, :only, :rename. The arguments and semantics for :exclude, :only, and :rename are the same as those documented for clojure.core/refer."

15:43 Jetien: hi! is there a reason why the PersistentQueue hasn't made it to the standard api yet?

15:47 chouser: Jetien: my understanding is that it could be easily abused with polling and multi-threading.

15:48 I think it may also be that there are plans for more general queuing API, and I'm not sure how that might influence how PersistentQueue is exposed.

15:49 but using PersistentQueue/EMPTY and conjing onto it should be pretty stable.

15:49 Jetien: it's just that sometimes it's mentioned in the api - i.e. in the doc for (peek) - but you can't easily create one

15:49 yeah, found your post http://markmail.org/message/brvozelsgmr5a3ba :)

16:06 ambient: hoeck1 what have you read? i'm thinking that would be a good way to learn clojure for me also

16:08 arbscht: ambient: clojure core is a good read

16:09 hoeck1: ambient: clojure code

16:10 ambient: clojure.* and clojure.lang.*.java, especially the Persistent* data structure implementations

16:11 ambient: ok, will do

16:12 wooby: for something like a condp, is there a way to do some kind of pattern matching?

16:13 a la scala's _

16:13 kotarak: wooby: there are libraries, but Clojure does not provide pattern matching out of the box. let-like things provide destructuring, though.

16:14 wooby: what do you want to do with condp? Maybe we can give you a tip

16:15 wooby: kotarak: cool thanks, here's what i'm playing with: http://gist.github.com/202421

16:18 kotarak: by the way, are you the vimclojure guy?

16:18 kotarak: wooby: And you want more something like #(condp = [(mod % 3) (mod % 5)] [0 0] ... [_ 0] ... %)?

16:18 wooby: yes

16:18 wooby: kotarak: thanks! it's awesome

16:19 kotarak: wooby: good to hear you find it useful. :)

16:19 Guest92834: vimclojure <3

16:19 clojurebot: vimclojure is http://kotka.de/projects/clojure/vimclojure.html

16:20 wooby: kotarak: and yes... that's how i'd go about it in scala more or less

16:20 kotarak: wooby: No. That's not possible in Clojure. At least not that I am aware of...

16:21 Chousuke: anything is possible with enough macros :)

16:21 wooby: that's true

16:21 kotarak: Chousuke: hehe, yes. And I know there are libraries doing that.

16:21 wooby: the whole macro thing has been mindblowing

16:22 i'd never gotten far enough with lisp to get into them... been enjoying the holloway book

16:22 Chousuke: syntactic abstraction is neat, yeah :)

16:25 wooby: i ran into something the other day i thought might be related

16:25 a macro called condt

16:25 but i can't find it now

16:25 anyone heard of it? i think it's in contrib somewheres

16:25 kotarak: it's in clojure.contrib

16:26 It uses stuartsierras template thing, IIRC.

16:26 It was a possible other version for condp.

16:26 Before condp was included.

16:27 wooby: i see

16:39 technomancy: is there a function that combines these two calls? (var-get (ns-resolve 'my-ns 'foo))

16:39 kotarak: @(ns-resolve 'my-ns 'foo)?

16:39 technomancy: (and don't say comp) =)

16:39 you can deref vars?

16:39 kotarak: yes, think so.

16:40 technomancy: who'd of thought.

16:40 thanks

16:41 kotarak: technomancy: http://groups.google.com/group/clojure/browse_frm/thread/603c9e832e855b20 scroll down to Stephen's reply.

16:45 Chousuke: Vars are one of the reference types, so I suppose it makes sense that you can dereference them. :P

16:45 makes me wonder why there is a var-get though.

16:45 since @ works

16:46 technomancy: I never thought of them as references, but it makes sense

16:46 I guess I don't work with raw vars hardly at all

16:46 kotarak: Chousuke: maybe it predates the IDeref stuff?

16:46 Chousuke: probably

16:46 kotarak: technomancy: Rich called them in his recent infoq talk a "special case". (or something along the lines...)

16:47 I hardly ever use Vars besides definitions.

16:47 perdalum: I've just tried to run a simple example from clojure-neo4j, but I get a java.lang.NoClassDefFoundError: javax/transaction/TransactionManager (NO_SOURCE_FILE:0) error in the REPl. Any ideas of what I'm doing wrong?

16:47 kotarak: (There were some cases in the Compiler for the line info of the VC Repl, but that is exceptional case, I guess)

17:01 perdalum: I thought that javax.transaction.* was available without any special (imports …)?

17:03 and why can't I import it with (import 'javax.transaction.TransactionManager)? Well, it'll have to wait until the Sn rises again...

17:11 sfuentes: hey chouser

17:11 chouser: sfuentes: hi [I'm barely here]

17:14 sfuentes: was just curious if you have completely abandoned any use of scala

17:15 * cemerick just realized that chouser went lowercase (for who knows how long now)

17:18 ambient: capitalization is just useless metadata, really

17:19 sfuentes: ambient: can be classified as shouting ....

17:20 Chousuke: it does make a difference in real writing though :P

17:21 chouser: it helps differentiate chouser from Chousuke

17:22 kotarak: pfff.. not for Colloquy :/

18:02 sfuentes: its so quiet in here

18:05 raek: is there an opposite to (filter)?

18:05 chouser: remove

18:05 raek: ah, thanks!

18:06 hiredman: (filter (comp not …

18:07 technomancy: isn't there already an HOF for (comp not %) ?

18:07 complement

18:08 hiredman: comp not is shorter

18:08 technomancy: true

18:09 sfuentes: chouser: so any comment to the scala question?

18:10 chouser: sfuentes: yes, abandoned scala

18:10 hiredman: for great justice

18:15 ambient: you know what you doing.

18:23 wooby: so i'm working on a bitty http server here, running into some io situation if anyone would care to help

18:23 http://gist.github.com/202551

18:24 i'm not getting anything from the input stream until the client kills the connection... is this a buffer flush situation?

18:24 thanks in advance for any help

18:34 hiredman: wooby: println is waiting to realise the entire lazy-seq

18:35 (doseq [line (line-seq rdr)] (println line))

18:35 wooby: hiredman: i tried throwing a doall in there to no avail... is there a preferred way to do it?

18:35 aha

18:36 hiredman: println is trying to print the whole seq at once, so it is waiting until the seq is complete

18:36 wooby: i see

18:36 and that works perfectly, thank you sir

18:36 hiredman: my pleasure

18:47 technomancy: I hate it when a macro-expansion runs, but it doesn't work as a regular macro call. =\

19:01 hiredman: did you see the other day where the dude was makeing symbols that started with a colon in his macro? and then expansion of his macro expected keywords, so it failed to run, but of course when he pasted the expansion it worked, because the reader read the symbols starting with a colon as keywords

19:01 amazing

19:11 chouser: hiredman: that's a bit freaky. It'll be nice to have such kinks worked out

19:12 hiredman: chouser: worked out as in not let people make symbols that start with colons?

19:14 wooby: hiredman: so, the part of the seq i'm trying to realize is the first element... not sure how to do it

19:15 chouser: right

19:15 wooby: i have this: (doseq [path (first (line-seq rdr))] but it's unrolling the first line into a character for each body call

19:15 hiredman: right

19:15 forget the doseq

19:15 wooby: which makes sense i suppose, but since doseq itself returns nil... not sure how i get at that first line

19:15 hiredman: (first (line-seq rdr))

19:16 that will return the first line "foo" which is handed off to doseq in your example there

19:16 and doseq calls seq on it and gets (\f \o \o)

19:16 wooby: oh wow, duh

19:16 hiredman: :)

19:17 wooby: i was getting all caught up in forcing it but i guess if i just ask for the first it hooks me up

19:17 thanks again man

19:17 this is so much fun

19:18 lisppaste8: technomancy pasted "bizarre binding behaviour" at http://paste.lisp.org/display/88259

19:18 technomancy: that snippet results in "Var minions/info is unbound."

19:18 or I guess user/info if you run it there

19:18 but clearly binding is getting called

19:19 hiredman: lisp paste error

19:19 technomancy: weak sauce. here it is again: http://p.hagelb.org/bizarre-bindings.html

19:21 sfuentes: its very uncommon to try to do OOP in clojure, correct?

19:21 dysinger: no

19:21 :)

19:21 hiredman: unfortunately not

19:22 dysinger: what I meant is that java interop is OOP

19:23 hiredman: technomancy: info# or ~'info in the macro

19:23 ~'info I guess

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

19:23 hiredman: clojurebot: buzz off

19:23 clojurebot: No entiendo

19:23 technomancy: hiredman: yeah, we want symbol capture I guess is the problem

19:24 sfuentes: well i mean "pure" clojure ...

19:25 dysinger: sfuentes: yeah I haven't seen any OOP clojure

19:25 sfuentes: ok. thought so, but was curious.

19:25 hiredman: ~google clojure socrates

19:25 clojurebot: First, out of 46 results is:

19:25 #clojure log - Dec 01 2008

19:25 http://clojure-log.n01se.net/date/2008-12-01.html

19:26 hiredman: ha ha

19:26 technomancy: hiredman: ~'info just makes it bind info in the caller namespace rather than the ns that contains the macro, right?

19:26 if you're in the same ns, it shouldn't make a difference

19:35 wooby: is there a way to get the argument list as a vector?

19:36 lisppaste8: danlei pasted "untitled" at http://paste.lisp.org/display/88261

19:36 danlei: oh ... too late

19:36 hiredman: technomancy: eh?

19:37 (binding [~'info @(ns-resolve the-ns# 'info)] …)

19:38 danlei: well ... look at my paste

19:38 isn't that what you wanted?

19:38 I'm not sure, but just 'info would expand to user/info

19:38 and I'm not sure if that's wanted

19:39 hiredman: ,`'info

19:39 clojurebot: (quote sandbox/info)

19:39 hiredman: hmmm

19:39 danlei: `'~'info

19:39 ,`'~'info

19:39 clojurebot: (quote info)

19:39 danlei: ugly as hell, but ... *shrug*

19:40 technomancy: ah; quote-unquote-quote on the _other_ info

19:40 gotcha

19:40 wow

19:41 danlei: :)

19:42 technomancy: what's the difference there then?

19:42 they look like they macro-expand to the same thing

19:43 hiredman: really?

19:43 technomancy: according to macroexpand-1

19:44 danlei: what exactly expands to the same thing?

19:44 technomancy: '~'info vs 'info

19:44 danlei: 'foo -> user/foo, ~'foo -> foo, '~' -> 'foo

19:44 at least in my macroexpand-1

19:45 hiredman: technomancy: it's syntax quote that qualifies symbols

19:45 so you need to include syntax quote (like in the macro) to see what is going on

19:45 ,`info

19:45 clojurebot: sandbox/info

19:45 hiredman: ,`~'info

19:45 clojurebot: info

19:46 hiredman: ,`'~'info

19:46 clojurebot: (quote info)

19:46 hiredman: hmmm

19:46 danlei: hmmm?

19:47 hiredman: I don't think you need '~' there

19:47 just ~' again

19:47 danlei: hm

19:47 well, if it should expand to 'foo, then you'd have to, I guess

19:47 hiredman: ,(cons '2' (seq 4))

19:47 clojurebot: (2 seq 4)

19:47 danlei: and ns-resolve takes a symbol

19:47 technomancy: hiredman: cool; thanks for the explanation

19:47 yeah, I need the double-quote

19:48 hiredman: danlei: ooooh

19:48 macros :)

19:48 danlei: :)

19:48 technomancy: just when you think you understand 'em...

19:48 danlei: ... you should use macroexpand ;)

19:49 technomancy: danlei: macroexpand told me it was just info

19:49 not user/info

19:50 danlei: I just wanted to make your sentence complete :)

19:50 technomancy: oh... crap

19:50 danlei: in your case it was ` that caused confusion

19:50 technomancy: slime's macroexpand does the wrong thing

19:50 it conflates user/info with info

19:50 gah!

19:50 danlei: huh?

19:51 sfuentes: anyone use a mac in here?

19:51 technomancy: danlei: slime's macroexpand gives me (do (binding [info @(ns-resolve 'clojure.contrib.logging 'info)] info))

19:51 where the second-to-last info there is actually 'user/info

19:51 I guess it assumes they're the same thing.

19:51 yuck

19:52 danlei: I just tested on cygwin, latest slime and it does 'foo for the '~', and user/foo for plain 'foo in the macro

19:52 so it works here

19:53 technomancy: danlei: using C-c RET?

19:53 danlei: well, M-x slime-macroexpand-1

19:53 * danlei always forgets those keybindings

19:53 technomancy: looks like the same thing

19:53 weird

19:53 are you on clojure 1.1?

19:54 danlei: built it yesterday

19:55 btw is there a way to get the clojure version from the repl?

19:55 technomancy: ,(clojure-version)

19:55 clojurebot: "1.1.0-alpha-SNAPSHOT"

19:55 danlei: ah, thanks

19:55 technomancy: danlei: quite strange; I can't duplicate that behaviour.

19:55 danlei: hm

19:56 strange indeed

19:56 clojure is alpha-snapshot, cygwin emacs, slime/swank-clojure/clojure-mode built yesterday or the day before

19:57 technomancy: danlei: jochu's swank-clojure or mine?

19:57 danlei: jochu's

19:57 technomancy: hmm... I haven't been paying attention to his

19:59 danlei: I'll double-check, just to be sure

20:00 definitely works over here

20:00 technomancy: I need to take a look at his branch anyway.

20:01 danlei: he recently merged with stuart(?)

20:01 technomancy: yeah, he pulled in a big wad of maven dependencies

20:01 danlei: yes

20:01 technomancy: that's why I've been putting it off. =)

20:01 danlei: :)

20:01 technomancy: (I like maven better than the alternative, but you can use maven and keep it simple.)

20:01 danlei: I had some trouble yesterday

20:02 because I don't like that clojure-install stuff, and don't know much about maven

20:02 then I got it to build, but my completion was gone

20:02 don't ask me how I got it working ...

20:02 but now it works again

20:03 technomancy: you just like handling the checkouts yourself, or is it something else about M-x clojure-install?

20:04 danlei: well, it said my clojure was already installed and broke of. besides, I want to know what's going on, and I connect via swank.swank/server-start anyway

20:05 so I just want to build my swank.clojure.jar and that's it

20:06 swank.swank/server-start & slime-connect, to be correct

20:06 *start-server

20:08 but I'm still not sure why my completion wouldn't work

20:09 I think it was that ;(remove-ns 'swank.commands.completion) line in swank.commands.completion, but I'm not sure

20:09 rebuilt it after messing around and it worked

20:09 * danlei shrugs

20:22 danlei: technomancy: btw. are you aware of the (read)/(read-line) problem under win? If I do a (read) or (read-line) in the slime-repl, It will hang

20:23 technomancy: danlei: it's not just a windows thing; swank just plain doesn't connect *in* right

20:23 danlei: hm, is there a way to get around that?

20:23 technomancy: probably... I kind of inherited swank-clojure without really understanding large portions of it

20:23 clojurebot: clojure is a language to use if you want to up your game

20:23 technomancy: it could be trivial to fix; I just haven't written any programs that use *in* yet. =)

20:23 danlei: I see

20:24 ok, I don't understand large portions of swank-clojure either atm

20:24 but if I get the time to investigate and find a solution, I'll let you know

20:24 technomancy: I think only jochu does, and he doesn't write clojure any more. =\

20:24 cool

20:25 danlei: it used to work, some time ago

20:25 anyway, I think I should call it a day

20:25 * danlei gets some sleep

20:39 slashus2: What happened to jochu?

21:56 somnium: is anyone aware of any projects or wrappers for BerkeleyDB? I found one mailing list post but the repository seems to have vanished.

21:56 just wondering before I start rolling my own

23:36 hiredman: clojurebot: tupac is <reply> when I write functions I go blind and let the lambda do its thing

23:36 clojurebot: Ok.

Logging service provided by n01se.net