#clojure log - Jan 23 2011

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

1:26 technomancy: so calling .read on a reader that's hooked up to a file or stdin will eventually return -1 for EOF. is there any way to get that effect for a reader hooked up to a socket? closing the socket just causes exceptions.

1:30 zztr: do you close the output stream from the socket before closing the socket?

1:32 technomancy: pretty sure; maybe I could double-check the ordering on that

2:33 scode: raek: Thanks!

2:33 (SOrry for the late ack :))

3:01 jli: yay clojure

3:02 Zeiris_: What are some really clutch use-cases for Clojure? Erlang has backend servers, Haskell has parsers, Ruby has Rails... What does Clojure excell at?

3:11 (I want to use clojure a bit, but have really limited time, so I'd like to pick a project really well suited to the domain.)

3:44 SergeyD: hi. Does anybody know the url of that article that describes the drawbacks of Lisps, that inspired the creation of Clojure? I want to answer the opponent in the discussion, but can't find it

3:53 hoeck: Zeiris_: clojure excels at a lot of things, for me the ability to hook into existing java apps/frameworks/libs is one of them

3:54 Zeiris_: so maybe there is some java lib that you wanted to play with and now can because you don't have to use java

3:54 for me that was at first jbox2d, processing and swing

4:40 robonobo: Is there a way to get the agent of the thread that sent the message?

4:44 Zeiris_: Ugh, I was afraid that was the answer... Java libs don't excite me, sadly :(

4:59 hsaliak: has anyone had any luck using proguard to shrink clojure based apps ?

4:59 bobo_: Zeiris_: for me clojure excels as a multi purpose language. Id use it for most things.

6:29 raek: robonobo: no. sends do not have to originate from an agent (any code can perform them). you could just pass the sending agent as an arg to the transition function: (defn do-something [state sender] ...) (send a do-something *agent*)

7:05 fliebel: morning

7:09 dedeibel: morning

7:19 fliebel: Idiomatic Clojure is slow :(

7:22 &(let [v (doall (range 1e6))] (time (dorun (map inc v))))

7:22 sexpbot: ⟹ "Elapsed time: 266.448622 msecs" nil

7:22 fliebel: &(let [a (java.util.concurrent.atomic.AtomicIntegerArray. (int-array (range 1e6)))] (time (dotimes [idx (alength v)] (.incrementAndGet a idx))))

7:22 sexpbot: java.lang.Exception: Unable to resolve symbol: v in this context

7:23 fliebel: &(let [a (java.util.concurrent.atomic.AtomicIntegerArray. (int-array (range 1e6)))] (time (dotimes [idx (.length a)] (.incrementAndGet a idx))))

7:23 sexpbot: Execution Timed Out!

7:23 mduerksen: ^^

7:24 fliebel: Uhm, right… on my coputer, that is at least twice as fast as the map thing.

7:36 ,(let [a (java.util.concurrent.atomic.AtomicIntegerArray. (int-array (range 1e6)))] (time (dotimes [idx (.length a)] (.incrementAndGet a idx))))

7:36 clojurebot: "Elapsed time: 108.397 msecs"

7:37 fliebel: botsnack

7:58 dedeibel: If I see the difference between alter and commute correctly, for example a simple transaction that just adds an entry to a set, which does not care about it's order and without any conditions depending on the set itself, should rather use commute for the operation, since it will not cause the transaction to be restarted in case of a concurrent change. Right?

8:05 raek: commute should be used when it doesn't matter whether anyone else has changed (altered or commuted) the ref during the transaction. this often implies that this ref is not affected by any conditions, i.e. it should be changed the same way no mattter what

8:10 dedeibel: so: yes.

8:10 dedeibel: I guess would like to add that as a comment on the clojuredocs page :)

8:11 Can I kind of use your formulation for that? Should I cite you?

8:12 raek: it would be better two quote rich hickey, I think

8:12 dedeibel: what did he say?

8:12 raek: he has explained this in some videos

8:13 ,(doc commute)

8:13 clojurebot: "([ref fun & args]); Must be called in a transaction. Sets the in-transaction-value of ref to: (apply fun in-transaction-value-of-ref args) and returns the in-transaction-value of ref. At the commit ...

8:14 dedeibel: Well, I think the docs are pretty sharp. They explain what it does. But sometimes a few more, maybe inaccurate, words help for the understanding.

8:14 raek: http://clojure.org/refs

8:15 I'm looking for a more elegant formulation

8:16 the part about conditions in what I said can be slightly misleading if one of the branches causes an exception to be thrown

8:16 dedeibel: Now that I know what it is for, I think this one on the refs page is pretty good.

8:16 raek: so in my reasoning there, aborted transaction "didn't count"

8:17 dedeibel: yes

8:18 altered ... "using a successful transaction" ... might be better

8:19 edoloughlin: Anyone know how to disable the warnings about functions from core being replaced when useing ?

8:19 ...using clojureQl.

8:20 raek: edoloughlin: (:refer-clojure :exclude (foo bar))

8:20 edoloughlin: Thanks

8:26 raek: when using commute in transaction A, a concurrent transaction B that change the ref and finishes before A do will not cause A to restart

8:27 is this is correct, #clojure?

8:27 the semantics of the STM operations can be a little tricky

8:31 ah, now I understand how it's implemented. the docstring for commute is pretty clear.

8:31 the function is applied twice

8:31 first it changes the in-transaction-value at the place of call

8:32 at the write point of the transaction, the in-transaction-value is discarded, and the function is applied to the current value of the ref and the result is stored back.

8:35 LauJensen: raek: You should really start writing manuals

8:37 raek: :-)

9:11 fliebel: I have a CQL question, although it might be just a general SQL question as well. Imagine the classic bank account in a tutorial, where someone checks his balance, and does a transfer. Meanwhile someone has retrieved money from the account, and the transfer fails horribly! Refs solve this nicely with transactions and all, but how is this solved in SQL and CQL?

9:33 OlegYch|h: fliebel: with transactions?

9:41 Dranik: hi all!

9:42 fliebel: Dranik: Hi

9:42 Dranik: do futures use a thread pool or they create as many threads as they are called?

9:43 fliebel: OlegYch|h: Right. I just read they're not in MySam, but they exist. Is there CQL syntax for them?

9:43 Dranik: I think they create threads, but I'll have to check that.

9:44 Dranik: fliebel, could you please have a look? Bcs I haven't found an answer in google

9:46 raek: Dranik: yes, and yes. They use the same thread pool as send-off, which will create new threads when there are none available. when a task is done, its thread will return to the threadpool and be deallocated if it is not used within 1 minute.

9:47 Dranik: raek, wow, thanks!

9:47 raek, btw, where did you found the answer?

9:48 raek: http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html#newCachedThreadPool()

9:48 Dranik: ohkaaaay.......

9:48 raek: I think I asked here some time ago... :-)

9:48 Dranik: raek, thanks :-)

9:48 raek: (the link was not the answer, just the docs for the kind of thread pool clojure uses)

9:50 fliebel: raek: Does that mean that launching 1000 futures will create 1000 threads, unless the first future has finished before the last one is created?

9:51 raek: fliebel: yes.

9:52 Dranik: is is possible to create a limited-size thread pool?

9:52 I'm developing a small multithreaded application for file searching (just for learning clojure)

9:52 raek: Dranik: yes: http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool(int)

9:53 Dranik: so what mechanism to choose? I guess -- futures?

9:53 raek: you can submit clojure functions to it using the methods in http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html

9:54 the name of 'future' in clojure is a bit confusing

9:54 Dranik: raek, thats java. is anything in pure clojure?

9:54 raek: a Future object is a "handle" for an asynchrounus computation

9:54 Dranik: yep. is any way to limit their thread pool size?

9:55 raek: Dranik: re pure clojure, no: http://raek.se/java.util.concurrent.txt

9:55 Dranik: thanks

9:56 raek: the java stuff is not broken, so you are expected to use it directly

9:56 similarly to the situation of the string operations

9:56 Dranik: a Future object is something that the threadpool creates

9:57 it's the ticket you get when you submit the job

9:58 the 'future' function in clojure does multiple things: creates an anonymous function, submits it to the 'send-off' pool, returns the Future object it got from it

9:58 Dranik: raek, so how one should use the Executors and futures together?

9:59 fliebel: Are there other areas in Java where 'good stuff' lives? java.util.concurrent is one of them, but I suppose there is more in Java 'done right'. java.lang.String and java.io come to mind(while there is clojure.java.io…)

9:59 raek: Dranik: note that whenerever it says "Callable" or "Runnable", you can pass a clojure function of zero arguments

10:00 Dranik: raek, any clojure function or you mean "future"?

10:00 raek: fliebel: yeah, that's pretty much the "good parts" I have used

10:00 Dranik: regarding which of my utterances?

10:00 fliebel: Dranik: Any function, with 0 arguments.

10:00 Dranik: ... you can pass a clojure function of zero arguments

10:01 raek: (def pool (Executors/newFixedThreadPool 4))

10:01 fliebel: Dranik: IFn extends from Callable and Runnable, IIRC.

10:02 raek: (def jobs (for [i (range 10)] #(println "hello " i)))

10:02 Dranik: fliebel, aha!

10:02 fliebel: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IFn.java#L17

10:02 raek: (def futures (seq (.ivokeAll pool jobs)))

10:02 (map #(.get %) futures)

10:03 Dranik: raek, interesting...

10:03 raek: if you add a delay to each "job function", you should be able to see that it executes 4 at a time

10:03 Dranik: raek, thanks, that was helpful!

10:04 raek: (def jobs (for [i (range 10)] #(do (Thread/sleep 1000) (println "hello " i))))

10:04 fliebel: I wonder what DOODL, LOL and the like are for?

10:04 raek: today is my begin-to-blog day. after I'm done setting up stuff, I will write a short post about this

10:05 fliebel: I think that's interfaces for enhanced primitive support

10:05 like, "long invoke(double, object, object, double)" or something

10:06 fliebel: raek: Horrifying… But about the blog, what are you using?

10:06 raek: just wordpress

10:06 fliebel: :(

10:06 raek: fliebel: any suggestions for something else?

10:07 I just want something that is easy to maintain... .-)

10:08 fliebel: I guess WP is the dead-simple got-to do-all solution, but that doesn't mean I like it. Be sure to check out OStatus for Wordpress though ;)

10:10 raek: fliebel: will do

10:10 Dranik: I use futures for fairly simple and fast funtion (just to test). The application works ok, but after the main functions is finished, it hangs

10:11 * fliebel wonders how many people would be interested in a simple Clojure 'thing'

10:11 Dranik: is guess it's because there are some threads not killed which were started by futures

10:11 how to kill them?

10:11 raek: I guess I could roll my own bloggin system using clojure and ring, etc. but then I have one more project that I will never finish... :-)

10:11 fliebel: Dranik: Since it uses the agent thread pool, look at that.. what was it...

10:12 shutdown-agents

10:13 Dranik: fliebel, thanks, that helped!

10:14 fliebel: raek: My main problem is that I'm to cheap to buy a server that can do servlets, they tend to be a lot more expensive than shared PHP hosting.

10:18 nlogax: raek: but nothing is ever finished, right? can still be fun and useful :D

10:20 raek: of course... :-) progress is not measured by number of finished projects, but number of started

10:24 Dranik: when I run a single-threaded application clojure creates 4 threads... why?

10:24 I don't use any concurrency their

10:24 *there

10:24 raek: probably the thread pool used by 'send'

10:24 fliebel: Dranik: How do you measure? Java creates a dozen threads before I have done anything :S

10:24 Dranik: no way, I never use send there

10:24 fliebel, why?

10:24 raek: I think it is created anyway

10:25 Dranik: ok...

10:25 fliebel: 16 currently, but I don't knwo why.

10:25 and now 17, without me doing anything…

10:26 raek: Dranik: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Agent.java#L48

10:27 Dranik: thanks

10:27 btw, I've just finished single-threaded and multithreaded find-file app. On average, the multighreaded works twice faster!

10:28 raek: I find it really interesting that the sources for Atom and Agent are not longer than they are

10:28 Dranik: I've used futures for pattern matching will the main thread was searching for the rest of the dirs

10:30 thank you all! bye!

10:32 fliebel: What would be the nicest way to generate XML(with namespaces) in Clojure?

10:34 Enlive does not do namespaces, clojure.xml does no rendering, any other options?

10:35 mrBliss: fliebel: clojure.contrib.prxml

10:36 fliebel: mrBliss: No namespaces.

10:48 shortlord: how can I "reload" used namespaces when I'm in a REPL?

10:48 fliebel: shortlord: (use :reload-all 'ns)

10:49 shortlord: fliebel: ah, thx a lot :)

11:04 fliebel: hrm, this is still the most sensible thing I found so far… http://ws.apache.org/xmlrpc/xmlrpc2/apidocs/org/apache/xmlrpc/XmlWriter.html There must be a better way.

11:11 robonobo: Is there a way I can find out why an agent failed?

11:12 mefesto: robonobo: (agent-error a)

11:13 robonobo: mefesto: thanks

11:19 raek: robonobo: since 1.2, you can also handle errors in a more convenient way: https://github.com/clojure/clojure/blob/1.2.x/changes.txt#L168

11:20 fliebel: Huh? Why is there an XMLHandler in clojure.lang?

11:27 LauJensen: Why was the HTTP Agent lib deprecated in contrib?

11:30 david`: (= nil ())

11:30 mrBliss: false

11:30 raek: ,(= (seq nil) (seq ()))

11:30 clojurebot: true

11:31 LauJensen: ,(= nil (seq ()))

11:31 clojurebot: true

11:32 david`: is (= nil ()) one of the differences between common lisp and scheme?

11:33 in other words, is clojure a scheme branch of lisp?

11:33 ,(= nil ())

11:33 clojurebot: false

11:34 david`: or wait, it's a common lisp branch

11:34 in common lisp () == NIL

11:35 fliebel: david`: Clojure is a lisp 1 and an empty seq is not false or nil. I don't htink it's a branch of either scheme or common lisp.

11:39 david`: fliebel: I see, thanks

11:41 i guess branch was the wrong word. from wikipedia: It is usually referred to as the Lisp-1 vs. Lisp-2 debate. Lisp-1 refers to Scheme's model and Lisp-2 refers to Common Lisp's model.

11:42 fliebel: Still no decent SAX parser/serializer pair. xerces looked nice, until I noticed its last release was 10 years ago…

11:43 WarrenForeign: I'm trying to replace some java code that uses spring constructor injection using annotations with a clojure defrecord

11:43 Annotating the constructor parameters is working fine

11:44 Is there a way to annotate the constructor itself?

11:44 @Autowired

11:46 LauJensen: WarrenForeign: https://groups.google.com/group/clojure/browse_thread/thread/d2128e1505c0c117

11:47 WarrenForeign: Thanks!

11:49 Rich says there fields, methods and types

11:49 I know constructor and method parameters are working too

11:50 What about the constructor itself?

11:59 Licenser: is there any secret trick to make sessions work in ring?

12:01 yes there is

12:02 * raek remembered a git article and managed to find it again: http://tomayko.com/writings/the-thing-about-git

12:07 robonobo: raek: nice find

12:10 I didn't know about the git add --patch thing. Very cool.

12:25 gfrlog: ,(-> partial partial partial partial partial)

12:25 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$partial

12:28 peregrine81: I have a record. I am trying to modify the record using (update-in record [:key] function)

12:29 I keep getting the error java.lang.IllegalArgumentException: Key must be integer (NO_SOURCE_FILE:0)

12:29 gfrlog: ,(doc update-in)

12:29 clojurebot: "([m [k & ks] f & args]); 'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a function that will take the old value and any supplied args and return the new...

12:31 gfrlog: ,(update-in ["a" "b" "c" "d"] [:not-an-int] identity)

12:31 clojurebot: java.lang.IllegalArgumentException: Key must be integer

12:31 gfrlog: peregrine81: So is it possible part of your record is a vector when you're expecting a map?

12:32 peregrine81: my record contains only booleans

12:32 no vectors

12:32 gfrlog: can you give an example expression that produces the error?

12:33 peregrine81: lemme get a pastie

12:33 shortlord: would you rather use (epxr1 (expr2 (expr3 (expr4 coll)))) or (-> coll expr4 expr3 expr2 expr1) or ((comp expr1 expr2 expr3 expr4) coll) in most cases?

12:33 gfrlog: shortlord: I think the arrow is the cool one

12:34 the first one is definitely the worst

12:34 arrow is also more flexible -- can be used with functions of more than one argument

12:35 shortlord: gfrlog: ok, thx, I'll use the arrow then

12:35 peregrine81: gfrlog: http://pastie.org/1490331

12:35 this code get a different error

12:36 sigh :)

12:37 gfrlog: one thing that's usually helpful to me in this kind of situation is to hack away at the sample code until you get to the simplest piece of code that still produces the error

12:37 peregrine81: yea I'm working on that one

12:39 gfrlog: peregrine81: on a hopefully unrelated note, can't your "[(get x 0) (get x 1)]" expression be simplified to just "x"?

12:41 peregrine81: gfrlog: yes, yes it can :)

12:41 gfrlog: I love it when I find out I can delete half my code and it still does the same thing

12:42 peregrine81: now the error is comming from my (update-in (make-board) [1 4] [] #( %))

12:42 gfrlog: what's the reason for the empty vector there?

12:42 peregrine81: well I just want to update the entire record

12:43 so I don't need to get the propery

12:43 oops

12:43 dug

12:43 duh*

12:44 gfrlog: the constantly function would probably work well for you

12:44 in case you were about to write something like (fn [_] x)

12:45 (doc assoc-in)

12:45 clojurebot: "([m [k & ks] v]); Associates a value in a nested associative structure, where ks is a sequence of keys and v is the new value and returns a new nested structure. If any levels do not exist, hash-maps will be created."

12:45 gfrlog: for that matter, it looks like assoc-in is simpler than update-in when you're ignoring the old value

12:45 peregrine81: really?

12:46 that works on records also?

12:46 gfrlog: probably

12:46 I think records are just optimized maps

12:48 peregrine81: ok

12:49 well no more cryptic issues, assoc-in/update-in are both not doing what I expect

12:49 gfrlog: you've got a 2D vector and you want to change one of the values, is that a fair summary?

12:50 oh wait

12:50 mefesto: peregrine81: is this part of yesterday's thing?

12:50 gfrlog: not quite a 2D vector

12:50 peregrine81: nope. I've got a 2d hash map. I want to change the value associated with key, which is a percept. I want to update one of the properties in the record

12:50 mefesto: Yes :)

12:51 gfrlog: so there are two basic ways to do a grid, and my next hasty thought is that you're mixing them up

12:51 mefesto: peregrine81: ok the board is immutable as well so you either need to generate a whole new board on each change or make each "cell" a ref/atom

12:51 peregrine81: mefesto: doesn't update-in return a new board everytime

12:51 i mean return a new map/record

12:51 mefesto: peregrine81: yeah, are you storing the current state of the board as a ref somewhere?

12:52 peregrine81: mefesto: nope. I'm just passing around new versions of the board

12:52 mefesto: at least thats the idea

12:52 mefesto: peregrine81: ok can you pastie an example?

12:53 peregrine81: if i remember correctly it should look something like: (assoc-in board [[1 1] :field-name] value)

12:53 peregrine81: mefesto: http://pastie.org/1490331

12:53 that should have everything

12:54 gfrlog: peregrine81: so the keys of your map are coordinate pairs, right?

12:54 peregrine81: gfrlog: yep

12:54 gfrlog: so why not just use assoc?

12:54 assoc-in and update-in are only for nested structures. I don't think yours is nested. Not the board at least

12:54 peregrine81: gfrlog: okay

12:55 mefesto: the board is a map of records

12:55 so maps in a map

12:55 the first key is the coordinate, the next is the field of a record at that coordinate

12:55 gfrlog: okay

12:55 so yes, assoc-in should work for that

12:55 mefesto: (assoc-in board [[1 2] :stench] true)

12:55 gfrlog: right

12:56 ,(assoc-in {[1 2] {:stench true}} [[1 2] :stench] false)

12:56 clojurebot: {[1 2] {:stench false}}

12:56 peregrine81: wow

12:59 I now understand update-in

12:59 thank you both so much again

12:59 mefesto: np

13:00 gfrlog: ,(println "no prob")

13:00 clojurebot: no prob

13:00 peregrine81: still getting my mind around the whole functional/immutable thing

13:00 doing my class assignments in clojure is a good way to force myself :)

13:08 __name__: hi

13:08 is there a builtin infinite seq that just counts?

13:08 (0 1 2 3…)

13:09 LauJensen: __name__: (range)

13:10 fliebel: __name__: Coming from Python?

13:10 __name__: yes

13:11 Scriptor: should be --name-- :)

13:11 __name__: huh?

13:11 Scriptor: just joking

13:12 Bronsa: in lisp

13:12 thw convention

13:12 *the

13:13 pdk: (iterate inc 0)

13:13 ,(take 10 (iterate inc 0))

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

13:13 Bronsa: ,(take 10 (range))

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

13:13 pdk: OR THAT

13:14 raek: ,(range 10)

13:14 clojurebot: (0 1 2 3 4 5 6 7 8 9)

13:14 Bronsa: lol

13:15 __name__: now i just need to make a string from a list of characters

13:15 raek: ,(seq "hello")

13:15 clojurebot: (\h \e \l \l \o)

13:16 raek: ,(apply str (seq hello))

13:16 clojurebot: java.lang.Exception: Unable to resolve symbol: hello in this context

13:16 raek: ,(apply str (seq "hello"))

13:16 clojurebot: "hello"

13:17 jamiltron: Are your chars being packed in a list of escaped characters?

13:18 LauJensen: pdk: No need to promote (interate inc 0) when I had just shown him (range)

13:19 jamiltron: if you have a list of escaped chars (i.e. '(\h \e \l \l \o)) you can string it together with

13:20 ,(apply str '(\h \e \l \l \o))

13:20 Bronsa: 19:16:14 < raek> ,(apply str (seq "hello"))

13:20 clojurebot: "hello"

13:25 shortlord: in the case that I'd like to dispatch a multimethod on the passed value istelf, it is better to just build one big normal method and use 'case' inside that method than to use the identity function as a dispatch function, right?

13:25 clojurebot: functions are maps

13:25 __name__: can clojure do partial application?

13:27 LauJensen: ,((partial + 1 2) 3)

13:27 clojurebot: 6

13:28 LauJensen: ,(#(+ 1 2 %1) 3)

13:28 clojurebot: 6

13:30 devn: ,(#(+ 1 2 %1 %2 %3) 1 2 3)

13:30 clojurebot: 9

13:30 __name__: ,(#(= %1 %2) 1 2)

13:30 clojurebot: false

13:30 __name__: ,(#(= %1 %2) 1 1)

13:30 clojurebot: true

13:31 devn: what is the highest you can go with %1, %2, etc.? Isn't there a limit of like 20 or something?

13:31 __name__: thanks LauJensen

13:31 LauJensen: devn: 42? :)

13:31 devn: :) -- I guess we could give it a try...

13:32 __name__: ,(#(+ %42 1) 1 2 3 4 5 6 7 8 9 10 11 12 13 15 15 16 17 18 19 20 21 1 2 3 4 5 6 7 8 9 10 11 12 13 15 15 16 17 18 19 20 21)

13:32 clojurebot: java.lang.Exception: Can't specify more than 20 params

13:32 __name__: here we go

13:32 devn: there it is :)

13:32 LauJensen: How cheap :)

13:33 __name__: i want my money back :(

13:33 devn: I was actually typing out %1 through %21

13:33 You're smarter than me.

13:33 LauJensen: devn: You can do it automatically with a keyboard macro

13:33 devn: Heh, of course you can!

13:33 * devn just added (global-set-key (kbd "<C-tab>") 'bury-buffer) to his emacs

13:33 devn: nice to cycle buffers with

13:34 LauJensen: C-tab? painful combo

13:34 devn: not for me -- i have my caps lock as control

13:34 LauJensen: Yea me too - Which puts them right next to each other

13:35 devn: i move my hand and use my index + pointer, or middle + ring finger

13:35 i kind of like its placement, personally

13:36 LauJensen: k

13:37 devn: actually now that im using it i find it is nice to hold my thumb down on Control and then just tap TAB as necessary

13:37 YMMV

13:38 LauJensen: MMDV

13:41 devn: :D

13:41 LauJensen: it's not really all that useful anyway

13:42 it would be nice if I could limit it to files which live under the current project

13:42 i dont care to cycle to my loaddefs or *Messages*, etc.

13:42 LauJensen: devn: 'psycho' was actually working on a emacs mode for that called scopes. Dunno if he finished it

13:57 fliebel: Hi devn! Just curious if there is any news abut your "secret" Utterson successor. I keep running into Clojure bloggers who are using Wordpress… I am secretly planning a conspiracy against Wordpress now. (I'm stukc at finding a decent SAX parser)

14:07 Derander: LauJensen: that's an interesting idea

14:22 mefesto: (assoc-in {} [:session :history] [1 2 3])

14:22 doh, wrong window :-\

14:24 Raynes: mefesto: Did you get my mail?

14:24 mefesto: Raynes: no but was it about tryclojure update?

14:25 Raynes: /msg sexpbot mail

14:25 mefesto: when i got back home i updated my repo and it worked

14:25 Raynes: Yeah, I forgot to remove some references to clj-sandbox when I removed the dep.

14:25 mefesto: Raynes: i've been playing with the code since and thinking about tackling the interactive tutorial

14:25 fliebel: Raynes: What happened to clj-sandbox?

14:26 Raynes: mefesto: You'd be my hero.

14:26 fliebel: Nothing. I'm just using clojail now. Nobody really maintains clj-sandbox anymore.

14:27 fliebel: Raynes: Ah, I was confused. Clojail is what you made?

14:27 Raynes: Yes.

14:27 It's I and amalloy's project.

14:30 fliebel: Sad that IRC is not XML based, otherwise you'd undoubtedly be able to point me at a great way to parse and generate namespaced XML. After second thought. I'm happy that IRC is not XML based. I wonder why RSS is XML based… :(

14:31 Raynes: XMPP is XML based.

14:32 fliebel: true

14:35 I'm thinking it is a good idea to write an XML DSL, like Hiccup, on to of Xercus.

14:37 :namespaced/xml is going to be less of a pain that way :)

14:37 wolverian: ooh, clojail. that will be useful.

14:52 chouser: counted-sorted-sets (from clojure.data.finger-tree) support inserting items only in sorted order, but you can then pull items off of either end

14:54 via first/rest on the left and peek/pop on the right

14:54 that is, ISeq and IPersistentStack

14:55 This is the wrong forum for this, isn't it.

14:56 fliebel: chouser: It sounds interesting though :)

14:56 chouser: email would probably be better

14:57 LauJensen: chouser: How's performance coming along?

14:57 chouser: I think ISeq should perhaps not inherit Sequential

14:58 Licenser: *shakes his fist at enlive*

14:58 * fliebel loves Enlive, but nods in agreement.

14:59 Licenser: it is cool but it has this horrible tendencie to just die in the middle of something without telling you what went wrong

14:59 fliebel: chouser: What is wrong with sequential?

14:59 Licenser: NullPointerException?

15:00 Licenser: No clue it just dies :P

15:00 chouser: fliebel: counted-sorted-set belongs in the "set" equality partition, not the sequential or map partition

15:00 Licenser: the html page shows half filled and then just ends

15:01 chouser: fliebel: but if it implements ISeq and ISeq inherits Sequential, then if you call equals on a vector, it will be willing to consider itself equal to a counted-sorted-set

15:03 fliebel: chouser: It sounds pretty natural that a seq(uence) is sequential. *browsing source code*

15:05 chouser: yeah, it does, doesn't it.

15:06 fliebel: chouser: So maybe your question should be if first/rest should be on ISeq or if ISeq is the correct protocol for a non-sequential collection.

15:07 Licenser: hmm can enlive snipents be used recursively?

15:08 fliebel: Licenser: I think so… I'd try removing transformations until it starts working again.

15:09 Licenser: I know what transformation breaks it, sadly

15:09 I've a defsnippet X that calls X within a clone-for

15:10 calling X with the input clone for gives it also works

15:11 fliebel: Did you try stupid things like calling Y instead, (declare X) beforehand, do #'X or...

15:12 Licenser: not a bad idea

15:13 ugly solution: copying the defmacro calling it Y then calling Y from X works fine :P

15:13 fliebel: Welll.

15:14 Licenser: but only for 1 recursion deepth, calling X from Y again does not work

15:14 I think I should make a bug case here ^^

15:15 but calling Y from Y works o.O

15:15 fliebel: Licenser: paste?

15:15 Licenser: sure

15:17 http://pastebin.com/QbeFQg7d

15:17 it is odd

15:18 fliebel: (= list1 list2)?

15:18 Licenser: the code is exactly the same yes

15:18 fliebel: Licenser: You realize there is a snippet as wel as an argument called list?

15:18 Licenser: I just coppied list to list2 then replaced the call to list in L17 to list2 and it started working

15:19 ew

15:20 http://pastebin.com/up7vbeGD <-fixed

15:20 fliebel: So, why not kill list2 altogether?

15:21 Licenser: because it stops working then -.-

15:22 waaaait

15:22 you are a genius fliebel

15:22 :)

15:23 * Licenser hands out cookies

15:24 fliebel: Licenser: Lets put it this way: I've dealt with the same problem before, and before… AND before. So I'm not sure if I'm a genius, or a someone who takes a while to learn from his own mistakes.

15:24 Licenser: ^^

15:24 Somelauw: Is clojure 1.1 outdated?

15:24 fliebel: Somelauw: Yes

15:25 shortlord: should the arguments in a function definition always be put into the next line or is it ok to keep them on the same line of the function name, if no doc string is used?

15:25 Somelauw: Is there a way to make sure I always have the newest version of clojure installed?

15:25 fliebel: Somelauw: How did you install it?

15:25 Somelauw: under ubuntu

15:25 I probably used aptitude.

15:26 hiredman: the clojure runtime is a jar, "installing it" system wide is just weird

15:26 your build tool will grab the right version for your project

15:26 raek: Somelauw: it's very common (if not the norm) to use leiningen or cake to fetch the correct clojure version on a per-project basis

15:30 Somelauw: Then I will install leiningen

15:32 raek: ~lein

15:32 clojurebot: lein is http://github.com/technomancy/leiningen

15:33 fliebel: shortlord: I do that all the time. Only with a doc it becomes ugly.

15:33 ~cake

15:33 clojurebot: cake is http://wondermark.com/030/

15:33 fliebel: huh?

15:34 raek: haha

15:34 Somelauw: But what is wrong with installing clojure system wide. I mean python and gcc are installed system wide as well?

15:35 raek: when you need a server running, you often use something like python's virtualenv to freeze the python and package versions anyway

15:35 fliebel: Somelauw: Python invented virtualenv to solve that problem.

15:35 raek: Somelauw: if you want a global installation, irclj can do that

15:36 fliebel: Cake also has a global project ;)

15:36 raek: *ljr

15:36 *cljr

15:37 (irclj is the IRC lib that sexpbot uses; I'm too used to type that name)

15:37 Raynes: cake can do pretty much anything that cljr can do now and more.

15:37 fliebel: How can I tell Clojurebot that Cake is ninjudd's

15:37 Raynes: Even the searching clojars stuff.

15:37 fliebel: ?

15:37 cake search?

15:37 Raynes: fliebel: You can't. Apparently hiredman has it blocked or something for whatever reason.

15:37 raek: ~cake is https://github.com/ninjudd/cake

15:37 Raynes: Not surprising.

15:37 clojurebot: Ik begrijp

15:37 Somelauw: Are cake, lein and cljr very similar?

15:38 raek: I have got the impression that for most basic task, they are 100% interchangeable

15:38 Raynes: fliebel: I added search functional and stuff based on David Liebke's code not so long ago.

15:38 raek: That doesn't really apply to cljr.

15:38 cljr is built on leiningen for entirely different purposes.

15:38 raek: oh, yeah. that's true.

15:38 Somelauw: Is lein like make?

15:39 raek: (my utterance was re. cake and lein)

15:39 Raynes: cake is more like make than lein.

15:39 In that cake is dependency-based.

15:39 fliebel: In name at least...

15:40 raek: but yeah, both allow you to do perform build-related tasks, dependency management and launching a repl

15:40 when you start to make your own tasks, that's when they start to be different

15:41 Raynes wrote an introductionary blog post about these things

15:41 Somelauw: link?

15:41 clojurebot: your link is dead

15:41 raek: http://blog.raynes.me/?p=48

15:42 Raynes: raek: And the vast majority of an entire chapter of my book is dedicated to teaching cake, so that'll be useful.

15:42 david`: Raynes: which book?

15:42 Somelauw: thanks

15:42 raek: some history: http://blog.fogus.me/2010/11/30/take-6-justin-balthrop/

15:42 Somelauw: The link is dead (temporarily?)

15:43 raek: strange... works for me

15:43 Raynes: Works for me as well.

15:43 jamiltron: Rayne's blog? Its working for me.

15:43 Raynes: david`: http://blog.raynes.me/?p=94

15:43 Somelauw: It's working again.

16:20 edoloughlin: Anyone know how to diagnose a 'java.lang.RuntimeException: java.lang.NullPointerException' in a namespace declaration? https://gist.github.com/792443

16:22 tonyl: I don't know about this much, but have you tried it with 1 require instead of 2

16:23 peregrine81: is there a good way in clojure/java to print a table in the console?

16:24 edoloughlin: tonyl: I don't think the problem is actually on that line as I've only made one change since it last worked. My issue is that there's no stacktrace to diagnose the root cause.

16:27 dnolen: edoloughlin: the exception is coming from user.clj, are you using that file to do some global config stuff?

16:28 pdk: (doc spit)

16:28 clojurebot: "([f content & options]); Opposite of slurp. Opens f with writer, writes content, then closes f. Options passed to clojure.java.io/writer."

16:28 pdk: (doc slurp)

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

16:31 edoloughlin: dnolen: No. It's just db access.

17:02 peregrine81: I feel like this should be easy, combine list of lists into single list? ((1 2) (1 2)) => (1 2 1 2)

17:04 chouser: (apply concat stuff)

17:04 __name__: (apply concat)

17:04 *(apply concat …)

17:05 peregrine81: thanks chouser! love your book btw :)

17:05 chouser: peregrine81: thanks!

17:52 emma: Hi everyone. I'm new to the whole IRC, so I'm not sure what the etiquette is.

17:52 I have a question I've seen asked about in varying degrees on the Google group

17:52 About the overhead in lazy-seqs.

17:53 arohner: emma: just ask. maybe someone will know

17:53 emma: we're mostly a friendly bunch :-)

17:53 emma: thanks! :)

17:54 I'm checking out the Project Euler stuff and am trying to write a sieve for prime numbers

17:54 and I'd like to just discard each previous computation - maybe make this more like a generator?

17:54 but I'm not sure how to do it without mutable state

17:55 It's definitely blowing the stack at large numbers

17:55 arohner: can you paste the code? use gist or pastie or one of those

17:56 emma: Here is my integer stream: (def integers (letfn [(k [n] (lazy-seq (cons n (k (inc n)))))] (k 1)))

17:57 arohner: ah, you're holding on to the head

17:58 integers has a reference to the head of the list. The GC can only collect items in the list that have no references

17:58 emma: my primes function looks the same

17:59 so would it be better to just pass along the rest of the list?

17:59 arohner: yes

17:59 emma: sweet

17:59 thanks!

18:38 jli: hurray clojure. I finally wrote the silly little program for automatically trying to renew my library borrows. I never got around to it because Haskell, OCaml, Common Lisp, ... didn't seem to have great HTTP client libraries, but HtmlUnit worked well for me

19:03 zakwilson: Using Ring, I want to get a list of existing sessions from the repl. Is this possible?

19:21 shortlord: do you know any SLOC count tool that recognizes clojure code?

19:26 tonyl: what about just counting lines

19:26 wc -l core.clj

19:27 u can use grep to strip comments

19:29 * tonyl needs to recharge. out.

20:27 phenom_: hey folks, for some reason technomancy's starter kit isn't loading up for me

20:28 i removed my .emacs and .emacs.d file and folder, created a new .emacs.d directory and moved the starter-kit in there

20:30 dnolen: logos.minikanren gets copy-term, soft cuts, committed choice and project. The full power of Prolog in Clojure? unsure, but next up, pattern matching ...

21:14 interesting, logos.minikanren now solves zebra nearly as fast as swi-prolog.

22:22 mreynolds: Can someone point me to how 'doc' works with multi-methods? I'm using a library where it's rather important to know all the options and I'd like to add proper docs, but am not sure how to best provide the extra info

22:37 pdk: mreynolds

22:37 iirc you can add them to the defmulti form

22:37 since you're always writing (defmulti blah (fn [args] ...))

22:37 you can stick the docstring in the fn probably

22:38 ohh wait

22:38 failing that try putting the docstring after the name in defmulti

22:40 mreynolds: I'll give that a shot. I was hoping for a way to put them on the defmethod and have doc intelligently display them, but I haven't gotten that to work yet.

22:40 Thanks

22:42 pdk: i'd be surprised if it did it per method

22:53 brehaut: can macros have multiple arities

22:54 chouser: brehaut: yes

22:54 brehaut: chouser: cheers :)

23:39 mefesto: ping raynes

Logging service provided by n01se.net