#clojure log - Feb 08 2009

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

0:13 replaca: I *do* miss reader macros - used them all the time in CL.

0:14 But I'll happily prefer good syntax for data structures (and good integration too) in exchange

0:15 Plus, there's no real reason you *couldn't* write your own variant of the reader

0:15 and plug it in (at least at the repl and folks could call it directly other places)

0:25 karmazilla: OT: a JDBC connection is closed and returns to its connection pool. The pool sees that the physical connection is too old and closes it (in the same thread). This physical close causes an SQLException. Should this exception bubble up to user code?

1:45 * ayrnieu patches a test into a running server and uncovers a bug.

1:48 durka42: darn bugs trying to hide

1:49 ayrnieu: when I can easily add a (println x) to the dodgy routine, they're easier to find :-)

1:53 offby1: it's the 21st century and we're still debugging with printfs :-|

1:54 ayrnieu: I just added a (send last-recv #(do % cl)) ; happy?

1:54 * hiredman has (try ... (catch Exception e (println e))) everywhere

1:55 * durka42 thinks that should be a macro

1:56 hiredman: (just-bloody-do-it ...)

1:56 durka42: (defmacro cry-about-it [& body] `(try ~@body (catch Exception e (clojure.contrib.stacktrace/print-stack-trace e))))

2:05 ayrnieu: I attached a debugging println to a server, but printed the wrong thing; server stops responding; I look at agent-errors, see the problem, clear the error, redefine the handler, restart the server -- and the effect is as if it had been a little laggy

2:05 gregh: you know the saying, "when in doubt, print more out"

3:01 rfgpfeiffer: is there a difference between :when and :while in for expressions?

3:02 ayrnieu: Yes.

3:04 ,(take 2 (for [x (range 100) :while (> x 50)] [x]))

3:04 clojurebot: nil

3:04 ayrnieu: ,(take 2 (for [x (range 100) :when (> x 50)] [x]))

3:04 clojurebot: ([51] [52])

3:05 ayrnieu: http://github.com/ayrnieu/clj-actors/blob/1c062dc5dcde01e4774793840e5f149f7d5dbc37/examples/chat_server.clj -- rough.

3:06 presently it ignores clients until they send something, as the initial .isAcceptable() SelectionKey differs from subsequent .isReadable() SelectionKeys, which are consistent.

3:06 rfgpfeiffer: ,(for [a [1 2 3 1] b [:foo :bar] :while (< a 3)] [b a])

3:06 clojurebot: ([:foo 1] [:bar 1] [:foo 2] [:bar 2] [:foo 1] [:bar 1])

3:06 ayrnieu: so on connect I've no idea who I'm talking to :-/

3:06 rfgpfeiffer: shouldn't the sequence stop after [:bar 2]

3:07 ayrnieu: the test stops before [:foo 3], and then stops before [:bar 3]

3:09 rfgpfeiffer: so the while only stops the sequence next to it

3:09 ayrnieu: where do you get that from?

3:12 rfgpfeiffer: ,(for [b [:foo :bar] a [1 2 3 1] :while (< a 3)] [b a])

3:12 clojurebot: ([:foo 1] [:foo 2] [:bar 1] [:bar 2])

3:13 ayrnieu: that isn't about :while's nearness to a, but about the way that for traverses space

3:13 ,(doc for)

3:13 clojurebot: "([seq-exprs expr]); List comprehension. Takes a vector of one or more binding-form/collection-expr pairs, each followed by an optional filtering :when/:while expression (:when test or :while test), and yields a lazy sequence of evaluations of expr. Collections are iterated in a nested fashion, rightmost fastest, and nested coll-exprs can refer to bindings created in prior binding-forms. (take 100 (for [x (range 100000000

3:13 ayrnieu: >> Collections are iterated in a nested fashion, rightmost fastest,

3:14 so it says [:foo 1] [:foo 2] [:foo -- oh, stop here.

3:14 rfgpfeiffer: doesn't that mean the same?

3:14 ayrnieu: doesn't what mean the same?

3:16 rfgpfeiffer: while does not stop the rightmost first

3:16 ,(for [a [1 2 3 1] :while (< a 3) b [:foo]] [b a])

3:16 clojurebot: ([:foo 1] [:foo 2])

3:17 ayrnieu: ,(for [a [1 2 3 1] :while (< a 3) b [:foo :bar]] [b a])

3:17 clojurebot: ([:foo 1] [:bar 1] [:foo 2] [:bar 2])

3:17 ayrnieu: rightmost fastest.

3:18 rfgpfeiffer: i see

3:18 anyway, a :break condition that stops everything would be handy

3:18 ayrnieu: if you're looking at list comprehension because you said "how do I loop in this thing?!" and 'for' seemed right, please look elsewhere.

3:20 hiredman: for is a. lazy b. not a loop, so :break does not make sense

3:20 rfgpfeiffer: I have this prolog solver and the solutions for a query are a lazy list

3:21 :break would be the cut operator

3:21 i can use take-while instead

3:22 ayrnieu: please use that instead.

5:04 Lau_of_DK: Good morning gents

5:23 niff: where can i discuss complexity theorya nd computational models?

5:24 kotarak: niff: concerning Clojure? Here or on the google groups list.

5:25 Lau_of_DK: niff: #Haskell ? :)

5:26 niff: i mean in general

5:26 CS-theory

5:28 leafw: niff: you can discuss anything you want, but if nobody answers, they may have put you on ignore.

5:28 such is everyone's freedom.

5:30 niff: one thing I dont understand is, all computational models can simulate each other. but can it be proven that there is no more powerful model?

5:31 quantum computing for example. 1 might not be realizable; 2. doesnt solve problems turing machines cant?;

5:33 Lau_of_DK: technically it doesnt solve problems other turning machines cant, but practically it will

5:34 kotarak: There is a difference between "can solve" and "can solve realistically".

5:34 Lau_of_DK: Thats what Im saying

5:35 turbo24prg: is there an equivalent to sorted-map-by for a sorted-set?

5:37 kotarak: turbo24prg: It's an open issue.

5:37 Lau_of_DK: turbo24prg: You mean something like

5:37 user> (sorted-set :c :b :a)

5:37 #{:a :b :c}

5:37 user> (sort [:c :b :a])

5:37 (:a :b :c)


5:37 ?

5:37 kotarak: turbo24prg: http://groups.google.com/group/clojure/browse_frm/thread/9d280b6229aef384/157d50d4caeae354?lnk=gst&q=sorted-set-by#157d50d4caeae354

5:41 turbo24prg: ah, ic

5:42 well, it doesn't work for lists and maps but seems to work for vectors

5:42 Lau_of_DK: As far as I understood, lists are to be avoided

5:42 turbo24prg: erm, storing these things in a sorted-set

5:42 hiredman: eh?

5:42 what doesn't work for lists?

5:43 turbo24prg: i tried to store lists and maps and sets in a sorted-set

5:43 an exception is thrown that they aren't convertable to comparable

5:43 hiredman: define doesn't work

5:43 ah

5:43 kotarak: turbo24prg: this probably works only with sorted-set-by with a custom comparator.

5:43 turbo24prg: yep, that's why i asked for it

5:44 but it seems to work for vectors

5:44 hiredman: ,(sorted-set '(2 3) '(4 3))

5:44 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to java.lang.Comparable

5:44 kotarak: Vectors maybe compare by comparing there elements lexicographically.

5:44 hiredman: interesting

5:45 turbo24prg: ,(sorted-set ["a"] ["c"] ["b"])

5:45 clojurebot: #{["a"] ["b"] ["c"]}

5:45 kotarak: ,(sorted-set ['(1)] ['(2)])

5:45 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to java.lang.Comparable

5:46 turbo24prg: still, i like clojure a lot

5:46 hiredman: must be a performance consideration

5:46 hmmm

5:46 turbo24prg: interesting to see how the api evolves

5:46 hiredman: but you have to walk thought the whole thing anyway

5:49 flup: so is compleity thoery more concerned with practically computable functions thtan theoretically ones?

5:55 kotarak: flup: I think as the name says: complexity theory talks about theory. Compare assembler and Clojure. Both get you to your target, but Clojure maybe a bit less code.

5:56 flup: then complexity theory talks about worst case complexity. Talk a SAT solver: the problem is np-hard AFAIK, but is use with great success in verification of electronic circuits, because the worst case almost never happens in reality.

6:09 flup: progs.imagesearch.algorithms.rbm can i then do (:require (progs.imagesearch.algorithms [algorithms :as alg])) and alg/rbm/run?

6:11 no doesnt work

6:11 how do import every file ina dir?

6:59 zakwilson: Something makes me think that agents and watchers would be a great way to implement something like Ken Tilton's Cells dataflow library.

7:05 forest: how is 'clojure' supposed to be pronounced

7:05 is it like 'closure'

7:06 zakwilson: That's how I pronounce it. I'm not sure if there's a FAQ on that anywhere.

7:10 leafw: instead of clo/Z/ure I say clo/SH/ure, but I bet everybody does it differently.

7:11 flup: closure si what hickey says in the videos

7:14 forest: ye, indeed, clo/Z/ure he says, actually i am listening to an audio lectore on it in background

7:52 punya: hi everyone

7:52 i'm new to clojure

7:52 does anyone have any tips on using clojure with slime and qt jambi?

7:53 i'm running this on windows vista and though everything seems to evaluate just fine, i don't see any GUI output

8:00 klirr: post your code...

8:00 i use java-swing + contrib-miglayout for GUIs

8:02 punya: http://paste.lisp.org/display/75055

8:02 klirr: my main reason for using jambi is that it has nice webkit bindings

8:03 klirr: i should mention that this code works (i.e. displays a window) when i run it from the command line using clojure.lang.Script

8:05 klirr: when doesnt it work then?

8:05 punya: klirr: from slime

8:05 klirr: from the repl in slime?

8:05 punya: klirr: yes

8:05 klirr: hmm i just use clojure +emacsmode for clojure

8:06 where do i download qt jambi?

8:07 punya: klirr: http://www.qtsoftware.com/downloads/opensource/appdev it's a pretty big download, and possibly not worth the pain if you're just curious

8:08 klirr: (you have to pick one of the two qt for java links)

8:08 klirr: ok

8:20 punya: okay, well thanks for taking a look!

8:20 and good night

8:32 wlr: zakwilson: re Cells: not a new thought. search for posts, esp by Stuart Sierra, on clojure's google group.

9:04 slaney: /clear

9:04 heh

10:15 te: 'LO

10:15 err, 'lo

10:26 zakwilson: wlr: It also looks like there's a Cells library by Kre?imir ?ojat. I'm interested in building a library to make working with Swing nicer, and I think a Cells-style dataflow extension is required.

10:32 te: whoa.

10:32 im having a mild epiphany with regard to lisp, clojure, etc.

10:35 ]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\===========================''''''''''=\

10:35 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]

10:35 whoa.

10:35 slaney: cat?

10:36 te: spaced out really bad haha

10:36 im in deep thought trying to visualize the way the data moves in lisp

10:36 slaney: nice

10:48 te: Is there a diagram anywhere that shows a function and a diagram side by side?

10:54 wlr: zakwilson: intiguing are comments from rhickey suggesting a rethinking of the whole cells-like paradigm based on a more concurrent/parallel pov. when i try, my meager apportionment of gray cells quickly goes tilt.

10:56 zakwilson: wlr: It seems like things would be quite parallel if a cell was an agent and the inputs were any of the IRef types.

11:01 wlr: zakwilson: does "being consistent" have any meaning without some notion of a logical or actual point in time at which they are consistent?

11:01 te: holy shit

11:01 i think i just got it

11:01 sorry guys -- having some eipiphanies

11:01 epiphanies

11:05 zakwilson: wlr: I can see how that would be a problem for some applications - values of cells made using agents could become out of date in a concurrent application. Maybe updates need to happen in a transaction... but that doesn't really match the simple agent/watcher model I had in mind.

11:09 wlr: zakwilson: surely i've got to clarify my thinking on the matter. anyway, good luck with your library.

11:25 niff: isnt this correct: (let [s (svm.)]

11:25 (load_model s data)

11:25 s)) ?

11:26 ah

11:26 .

11:27 dreish: I wish I'd gone with Carbon Emacs instead of Aquamacs.

11:28 durka42: why?

11:28 dreish: I've wasted so much time over the last few months just trying to find that little vertical-bar cursor.

11:28 * durka42 hasn't tried the former

11:28 niff: why doesnt i get an error when usign a method that doesnt exist?

11:28 durka42: what happens instead?

11:28 dreish: niff: Are you talking about load_model above?

11:29 If that's supposed to be a method invocation rather than a function call, it should be (.load_model s data)

11:30 te: durka42: could you show me an example of passing a sequence of functions to a function?

11:31 Chouser: ,(map #(% 1 2) [+ - * /])

11:31 clojurebot: (3 -1 2 1/2)

11:31 te: Chouser: was that at me?

11:32 ,(map #(% 1 2) [ - + / *])

11:32 clojurebot: (-1 3 1/2 2)

11:32 niff: dreish: changed that

11:32 stimuli: hi

11:32 te: hello

11:32 durka42: hello again

11:32 Chouser: te: yep, that was a sequence of functions (seq [+ - * /]) being passed to a function 'map'

11:33 stimuli: that errorkit thing looks pretty cool

11:33 If someone had asked me if you could have lisp style conditions in clojure I would have said "it can't be done on the jvm"

11:33 so natually someone did it

11:33 Chousuke: how does it perform though? :/

11:33 stimuli: no idea

11:34 not as fast as exceptions I'd suppose

11:34 Chousuke: I guess that's not always an issue though

11:34 dreish: Clojure is Turing-complete.

11:34 stimuli: but if you need it ...

11:34 TeX is turing complete :)

11:34 Chousuke: dreish: and macros make it possible to hide the awkwardness of pretty much anything :)

11:34 dreish: Of course, a Turing machine would probably take trillions of years to do conditions.

11:35 Chouser: I have't profiled it yet (want to get it correct first) but with-handler, handle, continue and raise should all be very fast, possibly faster than Java exceptions.

11:36 stimuli: I assume you're just wrapping up the handlers in some data structure and passing them down the call chain

11:36 Chouser: sorry, continue-with, not continue.

11:37 using continue, bind-continue, or just returning a value from a handle should be competitive with Java exceptions, but may be slower.

11:37 kefka: I know that killing threads in Clojure/Java is deprecated. What's the proper way to free a thread that you don't want any more?

11:37 dreish: Poll a variable. :(

11:37 durka42: it seems to me that a condition system like this will get deeply ingrained in an application's logic, so if someone were worried about performance (which isn't always the case) profiling data would be good, because extracting it might take a substantial rewrite

11:37 Chousuke: kefka: poll Thread/isInterrupted I think

11:38 kefka: and then from outside run .interrupt on it.

11:38 stimuli: kefka you have to have a protocol between threads

11:38 google "java thread interrupt"

11:38 there are lots of ways to do it wrong

11:38 durka42: ~thread

11:38 clojurebot: No entiendo

11:38 durka42: ~destroy

11:38 clojurebot: No entiendo

11:38 Chousuke: Clojurebot just uses stop :p

11:38 stimuli: but basically waht chousuke said

11:38 durka42: he has a factoid on it, but i forget what it's called

11:39 kefka: So I poll Thread/isInterrupted, then if it's not, use .interrupt

11:39 te: Is it possible that I'm simply not smart enough to learn clojure?

11:39 kefka: And interrupting frees the resources?

11:39 Chousuke: kefka: .interrupt on a thread makes isInterrupted return true; nothing more.

11:39 kefka: te: It's possible, but unlikely. If you're smart enough to learn Java, you're smart enough to learn Clojure

11:40 Chousuke: kefka: except if it's waiting, in which case it'll throw an InterruptedException in the thread

11:40 te: kefka: I didn't come from Jabba

11:40 kefka: Easy on the insults

11:40 Chouser: te: what's your background?

11:40 te: Ruby, C++

11:40 Chousuke: ruby is closer than C++

11:41 Chouser: I think Clojure is *much* simpler than C++

11:41 kefka: te: No insult.

11:41 te: yeah i was just reading that in paul graham's book

11:41 niff: http://www.textpresso.org/clustering-software/javadoc/libsvm/SVM.html

11:41 thats what im trying to use

11:41 forest: lisp is generally hard for people

11:41 te: he showed the example of def blah { |i| i+=1 }

11:41 kefka: te: I know nothing about you. There are some people who are not smart enough to learn Clojure, but I highly doubt you're one of them, if you're here.

11:41 stimuli: yeah ..... C++ is hard to learn and hard to use .... Lisps are hard to learn and easy to use

11:41 Chousuke: forest: I think it's functional programming that people have a hard time adjusting to

11:41 forest: it is needed to think differentky

11:41 Chousuke: it's just that much difficult.

11:41 te: kefka: thanks -- im just trying to marinade myself in it long enough to get it

11:41 Chousuke: er,

11:41 different* P

11:41 not difficult :P

11:41 stimuli: te : don't be in a rush and have fun

11:42 te: good advice

11:42 forest: yes, add FP to lisp and things get even more difficult

11:42 Chousuke: forest: er, no.

11:42 inherently, lisp is not difficult.

11:42 nor is FP

11:42 durka42: niff: those are all static methods, you will want to call (SVM/svm_load_model "etc")

11:42 Chousuke: but they're different from waht people are used to

11:42 forest: sure, if you are not accustomed to java/c/pascal

11:43 lisppaste8: klirr pasted "libsvm donka donka" at http://paste.lisp.org/display/75064

11:43 Chouser: doing anything with a function besides calling it is one step more difficult, like pointers vs. named variables in C

11:43 Chousuke: It'll just take some time to rewire your brain so that it's not dependent on mutability and imperative tools.

11:43 durka42: are you getting errors on that import? i would think the jvm is case sensitive there

11:43 Chouser: and even the less functional lisps do a lot more of that than C++ or Java do.

11:43 te: stimuli: i think i just need to build my confidence, the language seems daunting at first -- i think i just need to get my hands on something i can toy with

11:43 maybe compjure is a good idea

11:44 Chousuke: if you get past that, functional programming is *easier*

11:44 Chouser: te: I highly recommend doing the Project Euler problems from the beginning.

11:44 offby1: Chouser: I did the easiest ones first :)

11:44 and then pooped out after 40 or so.

11:44 (And didn't do them in Clojure, either)

11:45 stimuli: I think "compojure" is a great name .... I predict its outrageous success on name alone

11:45 te: yeah definitely

11:45 forest: would be interesting to see clojure solution to this http://www.topcoder.com/stat?c=problem_statement&pm=10268&rd=13696&rm=&cr=9946038

11:45 dreish: The SICP lectures were helpful for me in learning functional programming.

11:45 Chousuke: what I like most about functional programming is that I can write one function, ensure it does what it does, and then forget entirely how it's implemented, since it doesn't matter :)

11:45 te: dreish: ive been watching those

11:45 but that guy with the lack of hair and excess sweat

11:45 makes me cringe

11:46 forest: Chousuke: it is also true for imperative langs

11:46 niff: ah i see

11:46 Chousuke: forest: no it's not. with FP, all that matters is whether your function returns the values it's supposed to; with imperative programming, what matters is what the function DOES.

11:46 dreish: And I also solved my hard-to-find Aquamacs cursor problem: M-x customize-group <enter> cursor <enter>; change color to something with better contrast against my background.

11:46 Chouser: offby1: yeah, I've not gotten past about 50

11:46 durka42: forest: behind a login :( want to paste it or something?

11:47 now i'm curious

11:47 Chouser: but that's plenty to get a decent level of comfort on a new language.

11:47 offby1: and I cheat, too: I mostly use a particular math library which, I suspect, was written specifically to do Project Euler. Many of my programs are like three lines long

11:47 cheating is underrated

11:47 Chousuke: forest: it's about side-effects: functional languages avoid them, while they're everywhere in a imperative language.

11:47 Chouser: If I ever learn Haskell I'll probably do those same problems again.

11:47 niff: Chousuke: yeah me too, mostly i like sideeffectfree very composotional programs you get so you can isolate effects and errors easily and much easier prove the program works

11:48 then if you want to go "all" the way like haskell or not is another less important question

11:48 forest: Chousuke you can still add Unit tests)

11:48 Chousuke: forest: in a function in an imperative language, even something simple as an assignment may make a crucial difference between whether your code returns the correct value or not.

11:49 if it's multithreaded for example.

11:49 it's not perfectly isolated.

11:49 forest: durka42: i am sorry without a login it is not possible, i thought it was generally available, (Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited) sorry for confusion

11:50 durka42: no worries

11:51 Chousuke: niff: I don't think provability matters

11:51 niff: but the ability to make pure functions efficiently does.

11:52 pure functions are much easier to reason about and use than something that might have external dependencies.

11:52 you can have pure functions in C too of course, but they're cumbersome to write and very likely inefficient as well :/

11:56 forest: multithreading is an issue, but with a good architecture you may have pretty much isolated units of code almost always in single threaded environment

11:57 Chousuke: forest: functional programs have that architecture by default though :)

11:57 especially if it's enforced, like in haskell :P

11:59 forest: ok, let me change a problem given a matrix 10x10 compute its permanent, http://en.wikipedia.org/wiki/Permanent

11:59 would be nice to see clean implementation

12:01 durka42: i don't even understand that formula :\

12:02 Ariens: you must read the symetric group definition 2

12:02 forest: it is like determinant, but you never substract

12:04 Chousuke: I don't even remember how to calculate the determinant :P

12:04 Ariens: lol

12:05 forest: never mind :)

12:05 Ariens: forest: why don't you use the recursive solution for determiants?

12:05 durka42: so you could calculate it like the determine but without doing that checkerboard sign thing?

12:06 Chousuke: I can't figure out what that small sigma notation is supposed to mean, either

12:06 durka42: it's the symmetric group

12:06 there's a formula without sigma on http://en.wikipedia.org/wiki/Computation_of_the_permanent_of_a_matrix

12:07 forest: sigma - it is just a permutation if {1, 2, ..., n}, and iteration is over all of them (n!)

12:07 if=of

12:08 Ariens: yes, recursive solution is intended

12:08 durka42: ouch, O(n*n!)

12:09 * Chousuke finds it much easier to think of matrices as bunch of vectors rather than the independent cells :/

12:09 forest: let matrix be 6x6 - it is fast

12:11 Ariens: forest: use a recursive solution with and hash with 2 element lists as keys and make a function reject to create a new hash based on some criteria

12:11 forest: so even here in very simple example you need to update many cell of an array (vector) - and you have to get penalty of persistent collections even if you don't need previous version

12:11 Ariens: an*

12:13 forest: it seems to me that doing computations in clojure is pain

12:13 gnuvince_: how so?

12:14 forest: you have to pay big penalty for persistent collections

12:15 Ariens: have you tried type hints?

12:15 forest: i believe there is no chance adding plain mutable collections and arrays that are local to a function

12:15 what are type hints

12:16 dreish: What do you mean no chance? You can have Java arrays in Clojure.

12:17 Ariens: forest: you can tell clojure an argument is of a particular type

12:17 it improves performances for intensive numeric jobs

12:17 dreish: You can use java.util.HashMap if you're dead certain you want it.

12:18 forest: i need to investigate into it...

12:18 dreish: doto is a nice syntax for working with Java collections.

12:18 Ariens: since Big number arithmetic is replaced by native arithmetic

12:19 forest: the author of the language is so much talks about how persistent is absolutly good that i supposed there is the only way to go)

12:20 dreish: I tend to agree, but nobody's forcing you to refrain from using what Java offers.

12:21 Ariens: we need a matrix library in clojure

12:21 :p

12:21 dreish: I think your code is going to end up being harder to reason about in 99% of cases, and that it's better to write it the idiomatic way first and get it working, then see whether and where you need major efficiency gains, and whether there's any way to get them.

12:23 durka42: all right how do i check if i calculated the permanent correctly :p

12:23 forest: we can always write a hard part in low level language like java

12:24 Ariens: durka42: you print it?

12:24 durka42: no, i mean i need to check my answer

12:24 i imagine i could do it with matlab or mathematica

12:24 Ariens: formaly?

12:24 ll*

12:25 forest: i guess it is no easy way

12:25 Ariens: you need a formal proof that you code is correct?

12:26 durka42: not at all

12:26 i want a reference implementation so i can spot-check my calculation

12:27 Lau_of_DK: Good evening gentlemen

12:27 danlarkin: Hi Lau

12:28 durka42: hi lau

12:28 Lau_of_DK: danlarkin: so... any news? :)

12:28 "Bio Hansard" ? :)

12:29 danlarkin: haha

12:29 nope no news yet

12:29 Lau_of_DK: k

12:36 StartsWithK: lisppaste8: help

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

12:37 niff: how do is et a make-array from clojure?

12:37 ohw ait i use arrays interface

12:37 lisppaste8: StartsWithK pasted "Tree paths" at http://paste.lisp.org/display/75066

12:38 StartsWithK: Chouser: i tried to finish that tree paths function, this is the shortes solutions i could find, any ideas how to make it shorter?

12:45 stimuli: here is one for you guys : does anyone know a O(n * ln(n)) algorithm to partition a directed graph into mutually recursive subgraphs ?

12:45 te: how do i do this in compojure: (routes/ANY "/*" [(html (bold ("Hello world!")))]))

12:45 stimuli: I have a simple polynomial time algorithm

12:45 niff: how do you dow ith your user-file? put it ina namespace?

12:45 but then it is not asscessable by defualt right?

12:46 Ariens: why? I made a simple one...but there is java colt if you want a high performanc ehigh quality one

12:46 zakwilson: forest: I wrote image processing code in Clojure and got decent performance (with a bit of optimization help from Rich), so it's certainly possible to write fast computational code.

12:47 Lau_of_DK: te, something like (ANY "*" (layout "foo" [:h1 "Hello"]))

12:47 forest: stimuli: define the problem better what is mutually recursive

12:47 Lau_of_DK: In the definition of your servlet

12:47 forest: zakwilson: and what about memory consumption, is it higher that it would be in plain java

12:48 zakwilson: Since I never wrote a Java version, I couldn't tell you for certain, but my guess would be no.

12:49 It was destructively modifying a Java BufferedImage, but computing the pixel values was a pure Clojure function.

12:49 te: Lau_of_DK: hmm how can i make say a sidebar, and then pass that as a function to the servlet Lau_of_DK

12:49 or whoever

12:50 forest: i just was watching presentation with famous ant colony example - it ate >140M, too big

12:51 stimuli: your question does not make any sense to me

12:51 stimuli: forest : mutually reachable ... that is if a can reach b and b can reach a

12:52 forest : think of functions that can call each other

12:53 te: Lau_of_DK: that threw an error

12:53 Lau_of_DK: te: I dont know how you make a sidebar specifically, but you pass it as you would anyother function, replacing (layout ...)

12:53 forest: maybe it is vertexes ? that are reachable one from another ?

12:53 niff: is there a way to slurp line by line from clojure?

12:53 te: ,layout

12:53 clojurebot: java.lang.Exception: Unable to resolve symbol: layout in this context

12:53 leafw: ,(doc line-seq)

12:53 clojurebot: "([rdr]); Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader."

12:54 forest: stimuli: maybe it is vertexes ? that are reachable one from another ? subgraphs and functions are still not connected for me

12:54 leafw: niff: so yes, as per above. Use in combination with: (with-open [...] ... )

12:54 Lau_of_DK: te, scrap layout, use (html (doctype :html5) [:html [:head [:title "Hello"] ] [:body "Hi there"]]) If that doesnt work Im blank, my experience with compojure is 15 minutes of reading

12:54 stimuli: forrest : yes

12:55 leafw: niff, see an example here: http://github.com/acardona/xmms2-clj/blob/89ae9d125af9968fefcf7c31505c23000a29c0f4/xmms2.clj#L34

12:55 stimuli: uh .. say function one calls function two .. then draw and arrow from one to two

12:55 so now your function dependencies are a graph

12:55 durka42: is there a remove-nth?

12:55 kotarak_: durka42: dissoc fot vectors?

12:55 stimuli: I want to find all the mutually recursive clusters

12:56 durka42: ,(dissoc [1 2 3 4 5 6] 2)

12:56 clojurebot: java.lang.ClassCastException: clojure.lang.LazilyPersistentVector cannot be cast to clojure.lang.IPersistentMap

12:56 forest: stimuli: it is http://en.wikipedia.org/wiki/Strongly_connected_component

12:57 durka42: ,(concat (take 2 [1 2 3 4 5 6]) (drop 3 [1 2 3 4 5 6]))

12:57 stimuli: yeah

12:57 forest: which can be solved in O(E+V)

12:57 durka42: uh

12:57 clojurebot: botsnack

12:57 oh dear

12:57 stimuli: but I need to find all components that intersect

12:57 forest: they form a tree

12:58 where a vertex of this reachability tree - is strongly connected component

12:58 niff: hwta is \r ?

12:59 forest: and the strongly component consists of vertexes each pair from which is mutually reachable or how you call them mutully recursive

12:59 durka42: niff: carriage return

12:59 stimuli: right .. I was sort of doing tarjan ... I was hoping for something wehre I didn't have to walk a tree from each node

12:59 durka42: niff: windows encodes line breaks as \r\n. unix as \n

12:59 forest: http://en.wikipedia.org/wiki/Kosaraju%27s_algorithm - it linear on number of edges

13:00 you just can not do better

13:05 stimuli: forest : thanks ... that link gave me a solution

13:07 te: ,paste

13:07 ,paste

13:07 forest: stop paste )

13:07 te: how do i get the pastie

13:08 durka42: ~paste

13:08 oh yeah, clojurebot died

13:08 te: d'oh

13:08 durka42: lisppaste8: url

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

13:09 te pasted "compojure" at http://paste.lisp.org/display/75067

13:09 te: how do i make that sort of thing workj?

13:09 work?*

13:10 lisppaste8: durka42 pasted "permanent" at http://paste.lisp.org/display/75068

13:11 Lau_of_DK: Can somebody dig up that link from the logs, that technomancy pasted last night? The file was called concourse.tar.gz, but I lost the full path to it

13:11 durka42: forest: there you are

13:11 Lau_of_DK: te: If somebody finds that link, it'll answer all your compojure related questions

13:12 If you have some time, you might want to hold out for danlarkin's project: Clabango Django Jango, it should be quite interesting

13:12 danlarkin: oh jeez

13:13 te: Lau_of_DK: http://paste.lisp.org/display/73997

13:13 Lau_of_DK: nope

13:13 forest: durka42: unable to resolve symbol remove-nth

13:13 te: errr this? http://paste.lisp.org/display/75030

13:13 durka42: Lau_of_DK: this one? http://p.hagelb.org/concourse.tar.gz

13:13 forest: whoops, rename that without function to remove-nth

13:14 Lau_of_DK: te: http://p.hagelb.org/concourse.tar.gz

13:14 oh.. yes durka durka

13:14 thats the one

13:15 durka42: that google custom search doesn't seem to index so well

13:15 te: Lau_of_DK: durka42: sweet!

13:15 thanks

13:16 Lau_of_DK: no probs

13:16 te: this is what ive been looking for all along

13:17 Lau_of_DK: Friends like Durka durka and I ?

13:18 danlarkin: how best to express a function that takes a collection of functions and applies (rest coll) to (first coll) successively down the coll

13:19 Lau_of_DK: cascade-fn ?

13:21 forest: durka42: nice, but less much readable that imperative implementation

13:21 i suppose it was also much harder to implement

13:23 durka42: eh, it was just fiddling

13:23 that impementation is also how i think of the formula

13:24 you expand across a row/column, multiplying each element by the permanent of the matrix created by removing the row and column containing said element

13:24 forest: also i guess it will be also pretty hard to add memoization, for computing perm for matrixes say 20x20

13:24 like in perl)

13:25 durka42: there is clojure.core/memoize

13:26 i wonder if it would speed things up, since you'd have to do deep compares every time

13:27 forest: sure current implementation will never stop for for 20x20

13:28 durka42: never?

13:28 forest: aha, a disaster will happen earlier that will break the machine

13:30 best way to do memoization is having a key as integer with corresponding bits set for used columns

13:30 so it is very fast - 2^n *n

13:30 Chousuke: 2^n*n is fast? :/

13:31 forest: it is all relative, if compared to n! - yes )

13:32 if i remember correctly computing permanent is NP-hard, so you can not do much better, for n=20 it is fast enough

13:32 durka42: but will you ever be computing the same permanent?

13:35 forest: suppose you used columns 1 4 5 in first three rows having current product X, after that you need to sum all permutations of matrix without first three rows and columns 1 4 5 and multiply by X

13:36 so you need perm of that new matrix - and it depends only on number of first rows and which columns we already usd

13:38 durka42: sorry, i don't really get it

13:40 forest: if T[i] - matrix A without row and column i, that perm A = A[1][1]*(perm T[1]) + A[1][2]*(perm T[2]) + .... +A[1][n]*(perm T[n])

13:40 *without row 1

13:41 durka42: yeah

13:41 gnuvince_: ,(* 33 237)

13:41 durka42: the bot has left us :(

13:42 forest: but you only use (perm T[i]) once for each i

13:42 forest: if Q[a][b] is matrix A without rows 1, 2 and cols a b that perm A = Sum_over_all_pairs(a, b) A[1][a]*A[2][b] * perm(Q[a][b])

13:43 durka42: oh, i might see what you mean

13:43 although trying to visualize it is making my head hurt

13:43 Raynes: Run fo'est run!

13:43 forest: then triples and so on

13:43 durka42: i should be able to do this since i took linear algebra...

13:44 clojure.core/memoize doesn't help at all

13:44 forest: you'd better think of it as if you never knew linear algebra

13:44 durka42: why?

13:44 forest: it is elementary thing

13:45 you just take A[1][a]*A[2][b] out of parenthes for all products that have a in row 1 and b in row 2

13:47 blbrown: (defmacro async-call [display & body] ...in this code, what is the purpose of the '*&'

13:48 stimuli: blb : it binds body to a stream of the remaining arguments

13:48 ayrnieu: async-call receives one argument, bound to display, and then N arguments in a list, bound to body

13:48 stimuli: ayr : is it a list or a stream ?

13:49 durka42: it's just a list

13:49 stimuli: ok

13:49 kotarak_: blbrown: (async-call the-display) => body is nil, (async-call the-display some) => (some), (async-call the-display some thing) => (some thing) ...

13:49 forest: it is easy to find out - just run Repl under debugger

13:49 stimuli: of course, by stream I meant seq

13:49 ayrnieu: clojure.lang.ArraySeq , looks like.

13:49 lisppaste8: klirr pasted "dss" at http://paste.lisp.org/display/75071

13:50 ayrnieu: forest - or you can just ((fn [& rst] (class rst)) 1)

13:50 niff: why isnt memoization working there? ^^

13:51 ayrnieu: niff, it works fine there.

13:51 forest: ayrnieu: ye it is slightely more handy

13:51 durka42: my guess is the internal calls to fib don't call the memoized version

13:52 stimuli: when I'm coding I'm almost never aware if I'm using a col or a seq ... I'm sure sooner or later that will cause a bug

13:52 niff: ayrnieu: yes it works but it isnt speeded up

13:52 durka42: so how do i make them?

13:52 memoization ony works for recursion right?

13:53 or does the jvm store the function calls then so it is not for recursion but rather for caching?

13:53 ayrnieu: niff - (let [f-aux (memoize fib)] (defn f [n] (binding [fib f-aux] (f-aux n)))

13:53 niff - subsequent (f 34)s return immediately, as you'd expect. The memoization works, it's just what durka said.

13:54 lisppaste8: durka42 annotated #75071 with "striking difference" at http://paste.lisp.org/display/75071#1

13:55 durka42: forest: FWIW, matlab is still churning on my 10x10 matrix

13:55 clojure: FasterThanMatlab!

13:55 unless the matlab permanent function i found just has a bug

13:55 niff: i see

13:55 durka42: how can anything be churning ona 10*10 matrix?

13:56 10K you mean?

13:57 forest: n! grows rather fast

13:57 durka42: clojure did the 10x10 matrix in 53 seconds

13:58 Ariens: is the result correct?

13:59 ayrnieu: (defn matrix-multiy [& _] 0)

14:01 niff: anyone used libsvm? i have a weird error : unknown text in model file , could eb windows usign \r\n and not just \n. anyone know?

14:01 durka42: ayrnieu: i'm not sure about that approximation :)

14:01 niff: is matlab generalyl slow? allt he matlab toolbox stuff is it written in matlabs language or in C?

14:02 Chousuke: niff: matlab is not slow

14:02 it would be stupid if it were...

14:02 durka42: well, it is sometimes

14:03 Chousuke: well, I guess.

14:03 durka42: i've certainly heard of people writing things in matlab because it's good at math, and then porting to C

14:03 forest: in any language they could implement it for small sizes up to 15-20 to be lightening fast

14:03 Chousuke: durka42: I guess matlab's own language is not that fast

14:03 blbrown: ayrnieu, in your macro example earlier. I guess it doesn't make any sense to do this. (defmacro m [a b & body something-else] ...

14:03 forest: permanent is rarely used function I suppose

14:03 blbrown: ayrnieu, eg something-else wouldn't work

14:03 Chousuke: it's just "glue" for the libraries that are fast

14:04 ayrnieu: blbrown, what macro example?

14:04 Chouser: blbrown: that's right

14:04 ,(fn [a & b c])

14:04 durka42: blbrown: clojure doesn't allow that

14:04 java.lang.Exception: Unexpected parameter

14:04 Chouser: but you can destructure in the 'rest' position

14:05 blbrown: durka42, so define the arguments 'required' before the & body ...stream (I am not explaining that right am I ?)

14:05 Chouser: (,(let [[a & [b c]] [1 2 3]] [a b c])

14:05 blbrown: Chouser, oh man are you confusing me

14:05 Chouser: :-)

14:05 clojurebot too, apparently.

14:05 ,(let [[a & [b c]] [1 2 3]] [a b c])

14:05 ayrnieu: clojurebot died earlier.

14:05 durka42: Chouser: what is the point of using the rest position, then?

14:05 i gave clojurebot a ClassCastException and he died

14:05 i seem to be good at that

14:05 blbrown: hehe

14:06 he needs my new

14:06 (when-try) macro

14:06 durka42: blbrown: define the required parameter first, yes, and then you can have a & before the last parameter to gobble the rest into a seq

14:06 Chouser: durka42: it's optional

14:06 durka42: parameters*

14:06 blbrown: durka42, good explanation

14:06 durka42: i mean, if you're going to use [a & [b c]] why not just do [a b c]

14:07 Chouser: ((fn [a b] {:a a, :b b}) 1 2) ==> {:a 1, :b 2}

14:07 ((fn [a b] {:a a, :b b}) 1) ==> Exception

14:07 ((fn [a & [b]] {:a a, :b b}) 1) ==> {:a 1, :b nil}

14:08 gnuvince_: Isn't it the inverse order?

14:08 {a :a, b :b}?

14:08 Chouser: sorry, now I'm confusing you

14:08 the map there isn't destructuring, just returning results

14:08 durka42: ah, i see

14:09 ayrnieu: gnuvince, it's {key value key value}

14:09 durka42: that seems like a klunky way to have optional parameters, but it works

14:09 what the hell is wrong with matlab

14:09 Chouser: durka42: yeah, I wouldn't recommend it.

14:10 ((fn f ([a] (f a nil)) ([a b] {:a a, :b b})) 1)

14:10 durka42: right

14:10 Chouser: they're all kinda clunky when packed onto one line

14:15 niff: what is the advantage of matlab over something like java matrix lib like colt? all the toolboxes?

14:15 but if you want to use it in an application...?

14:15 leafw: niff: matlab has a debugger and docs built in

14:15 niff: like clojure :)

14:16 skogs: (defmacro mm [arg] (let [[p q] arg]`(and (isa? 'x ~p) (isa? y ~q))))

14:16 durka42: what are x and y? and why not take [p q] instead of [arg]?

14:17 skogs: my q is would y same as lexical y into which it expands

14:19 durka42: in the future remind me not to set matlab on a 15 minute calculation and not print out the answer

14:19 skogs: can i write a macro that expands to use a lexical symbol

14:20 gnuvince_: Does C-c C-c work for anyone in SLIME to stop a Clojure operation?

14:21 skogs: any macro experts in house?

14:23 ayrnieu: assume that they're here and ask a question that they may answer.

14:24 skogs: ayrnieu: did u see the macro i just posted

14:24 ayrnieu: (defmacro inc-it [] `(dosync (commute ~'it inc))) , (let [it (ref 0)] (inc-it) (inc-it) (inc-it) @it)

14:25 durka42: 3

14:25 ayrnieu: skogs - `y expands to *ns*/y -- look at ['a 'b `a `b] at the repl

14:25 durka42: ~'it prevents quasiquote from trying to resolve it

14:26 skogs: oh! so i need a quasiquote

14:26 durka42: sorry, quasiquote is the backquote

14:27 ayrnieu: you've already found quasiquote: `

14:27 durka42: `

14:27 i screwed something up so i can't type ` except in vim, need to fix that

14:28 skogs: so *ns*/x is different from lexical x?

14:28 ayrnieu: it depends on the namespace.

14:29 skogs: well, in the same namespace

14:29 as macro expands to *ns*/x and thats not same as x

14:29 ayrnieu: try: (let [it 0] (eval `(+ it 1)))

14:29 AWizzArd: if you have in ,,user" (def x 10) and then do (let [x 15] (print user/x)), then it will print 10

14:30 gnuvince_: If I have a 2D vector ([[0 1] [2 3] [4 5]]) and that I want to conj something onto one of the inner vectors, how should I do that?

14:30 skogs: so *ns*/x resolves to global variable

14:30 AWizzArd: skogs: indeed

14:31 ayrnieu: 'namespace variables', you could say.

14:31 if you (def x 10) x is also in the lexical scope of the subsequent forms

14:31 skogs: r they same as dynamically scoped variables

14:31 ayrnieu: no.

14:32 durka42: so the clojure program is correct, and fourteen times faster than the matlab program

14:32 ayrnieu: OK, nevermind.

14:32 (def x 10) (defn f [] (+ x 10)) (binding [x 20] (f))

14:33 AWizzArd: gnuvince_: you traverse your datastructure

14:33 gnuvince_: basically you write your own version of filter

14:33 It is a design pattern in functional programming languages to implement map/reduce/filter from time to time.

14:33 gnuvince_: AWizzArd: nothing built in?

14:34 AWizzArd: well, in principle you could also work with these zippers I guess

14:34 skogs: ayrnieu: got it, thx

14:34 durka42: (concat (take (dec n) matrix) (conj (nth matrix n) 12) (drop (inc n) matrix))

14:35 AWizzArd: gnuvince_: and you could do it also with built-in functions, but it might not always be very clean

14:35 ayrnieu: gnuvince - write a matrix-oriented update-in

14:35 Chousuke: ayrnieu: matrix-oriented? :/

14:35 ayrnieu: Yes.

14:36 Chousuke: if your matrix is a vector of vectors, you can just use the regular update-in

14:36 for non-vectors I suppose you'd need something else.

14:37 gnuvince_: ayrnieu: ah, this works well enough: (update-in [[0 1] [2 3] [4 5]] [1] conj :a)

14:37 ayrnieu: oh, I tried it wrong.

14:56 durka42: ,(prn "I'm alive!")

14:56 clojurebot: "I'm alive!"

14:56 durka42: yay

14:56 hiredman: do you know what happened?

14:56 hiredman: machine went offline

14:56 durka42: oh

14:56 so it just happened to coincide with my buggy code

14:57 hiredman: maybe your buggy code killed the machine :P

14:58 durka42: it was just a ClassCastException!

15:03 blbrown: am I wrong or should the macro (time) display 'secs' as opposed to msecs

15:04 Chousuke: blbrown: no, it shows msecs

15:04 hiredman: last I checked (months ago) it was msecs

15:04 Chousuke: ,(time (+ 1 1))

15:04 clojurebot: 2

15:04 "Elapsed time: 0.152 msecs"

15:04 blbrown: ,(time (+ (range 100))

15:04 clojurebot: Eval-in-box threw an exception:EOF while reading

15:05 Chousuke: forgot apply :)

15:05 hiredman: you need an apply there

15:05 durka42: ,(time (Thread/sleep 1000))

15:05 clojurebot: "Elapsed time: 1001.088 msecs"

15:05 blbrown: hmm

15:08 ayrnieu: ,(java.util.Date. (long (* 1000 1234567890))) ;; THIS WEEK

15:08 clojurebot: #<Date Fri Feb 13 15:31:30 PST 2009>

15:08 blbrown: ,(time (Thread/sleep 10000))

15:08 clojurebot: Execution Timed Out

15:08 blbrown: ,(time (Thread/sleep 3000))

15:08 clojurebot: "Elapsed time: 3001.374 msecs"

15:11 forest: ,(.. System getRuntime (exec "sudo reboot"))

15:11 clojurebot: java.lang.NoSuchFieldException: getRuntime

15:11 blbrown: ooooooo

15:11 forest: )

15:11 blbrown: denie

15:11 d

15:12 hiredman: well

15:12 you have to use System/getRuntime

15:12 ,(System/getRuntime)

15:12 clojurebot: java.lang.NoSuchFieldException: getRuntime

15:12 Chousuke: ,(System/runtime)

15:12 clojurebot: java.lang.NoSuchFieldException: runtime

15:12 hiredman: er

15:12 Chousuke: hmm

15:12 blbrown: it is blocked I bet

15:12 * Chousuke forgets :(

15:12 hiredman: nah

15:13 Chousuke: it is, but that's not the right exception

15:13 ,(.getRuntime System/Runtime)

15:13 hiredman: ,(System/Runtime)

15:13 clojurebot: java.lang.Exception: No such namespace: System

15:13 java.lang.NoSuchFieldException: Runtime

15:13 hiredman: ,(.getRuntime (System/Runtime))

15:13 clojurebot: java.lang.NoSuchFieldException: Runtime

15:13 blbrown: ,(let [r (. Runtime getRuntime)])

15:13 forest: ,(.. Runtime getRuntime (exec "sudo reboot"))

15:13 clojurebot: nil

15:13 java.security.AccessControlException: access denied (java.io.FilePermission <<ALL FILES>> execute)

15:13 ayrnieu: ,(.. Runtime getRuntime availableProcessors)

15:13 clojurebot: 1

15:13 ayrnieu: ,(-> Runtime (.getRuntime) (.availableProcessors))

15:13 clojurebot: java.lang.IllegalArgumentException: No matching field found: getRuntime for class java.lang.Class

15:13 blbrown: ,(.. Runtime getRuntime totalMemory)

15:14 hiredman: ,(Runtime/getRuntime)

15:14 clojurebot: #<Runtime java.lang.Runtime@1401d28>

15:14 hiredman: ,(.exec (Runtime/getRuntime) "sudo reboot")

15:14 clojurebot: java.security.AccessControlException: access denied (java.io.FilePermission <<ALL FILES>> execute)

15:14 hiredman: there we go

15:14 blbrown: ,(.. Runtime getRuntime freeMemory)

15:14 ,(. Runtime getRuntime freeMemory)

15:14 hiredman: hmm

15:14 clojurebot: ping?

15:14 clojurebot: PONG!

15:15 blbrown: doesn't like me

15:15 hiredman: nah

15:15 blbrown: ,(. Runtime getRuntime maxMemory)

15:15 Chouser: ~roulette

15:15 clojurebot: click

15:15 hiredman: it doesn't like your spaces

15:15 blbrown: ,(. Runtime getRuntime maxMemory)

15:15 Chousuke: ,(.. Runtime getRuntime gc)

15:15 clojurebot: java.lang.Exception: Unable to resolve symbol: maxMemory in this context

15:15 nil

15:15 blbrown: ,(.. Runtime getRuntime maxMemory)

15:15 clojurebot: 66387968

15:15 blbrown: ,(.. Runtime getRuntime totalMemory)

15:15 clojurebot: 5177344

15:15 blbrown: ,(.. Runtime getRuntime freeMemory)

15:15 clojurebot: 2472128

15:16 blbrown: 64 MB default jvm memory, you might increase that

15:16 hiredman: *shrug*

15:16 blbrown: hiredman, are you running the bot

15:17 hiredman: I used to run it with a lot less

15:17 yessir

15:17 blbrown: nice

15:17 hiredman, you run it off a virtual host or your own home box or somethig

15:17 ayrnieu: ,(-> (.. Runtime getRuntime maxMemory) (/ 1024) (/ 1024))

15:17 clojurebot: 1013/16

15:17 blbrown: (. System getProperty "os.name")

15:17 ,(. System getProperty "os.name")

15:17 clojurebot: java.security.AccessControlException: access denied (java.util.PropertyPermission os.name read)

15:18 Chousuke: ,(/ (.. Runtime getRuntime maxMemory) 1024 1024)

15:18 clojurebot: 1013/16

15:18 forest: ,(. System exit 0)

15:18 clojurebot: java.security.AccessControlException: access denied (java.lang.RuntimePermission exitVM.0)

15:18 blbrown: hiredman, OK, I will stop messing with the bot

15:18 durka42: well, they do have the same ip address

15:18 blbrown: forest, you are evil, hehe

15:18 forest: just security tests ...

15:18 Chousuke: forest: if you succeed in breaking it you have succeeded in breaking the java sandbox model.

15:19 it has a few weaknesses though

15:19 blbrown: I bet a runtime error could choke it

15:19 Chousuke: you can spawn new threads for example.

15:23 ayrnieu: but if you want to have fun breaking it, please get the clojurebot source and do it without pulling a durka42 :-)

15:24 blbrown: clojurebot, source

15:24 durka42: clojurebot: where are you?

15:24 clojurebot: http://github.com/hiredman/clojurebot/tree/master

15:24 durka42: what did i do the first time? i think i OOMed him

15:24 blbrown: 'source' is less verbose

15:24 hehe

15:24 durka42: clojurebot: source is http://github.com/hiredman/clojurebot/tree/master

15:24 clojurebot: In Ordnung

15:28 AWizzArd: clojurebot: max people

15:28 clojurebot: max people is 145

15:28 AWizzArd: wow

15:31 niff: clojurebot: commit suicide

15:31 clojurebot: Huh?

15:31 niff: clojurebot: do a forward loop

15:31 clojurebot: Titim gan �ir� ort.

15:34 ayrnieu: hum.

15:34 ,(java.util.Date. (long (* 1000 1234567890))) ;; <-- 12345678900000 is too large for a Java long. So what's happening, here?

15:34 clojurebot: #<Date Fri Feb 13 15:31:30 PST 2009>

15:35 durka42: ,(class (long (* 1000 1234567890)))

15:35 clojurebot: java.lang.Long

15:35 durka42: ,(long (* 1000 1234567890))

15:35 clojurebot: 1234567890000

15:35 durka42: ,(java.lang.Long/MAX_VALUE)

15:35 clojurebot: 9223372036854775807

15:35 durka42: not too large

15:36 forest: not to long

15:36 *not too long

15:36 ayrnieu: long x = 1234567890000; fails with fixn.java:3: integer number too large: 1234567890000

15:37 forest: long x = 1234567890000L;

15:37 to big for int ok for long

15:37 *too

15:37 ayrnieu: ok, sorry.

15:37 durka42: ayrnieu: that's why you use clojure :)

16:01 blbrown: http://paste.lisp.org/display/75073 I know it doesn't look pretty, but I was trying to use' ref in this way, but my values aren't being set. Anyone see something

16:03 and really all I want to access a hashmap of objects from any function (globally). I guess in java, it would be. Class.field = new HashMap();

16:03 Chousuke: blbrown: yeah, it always returns a new ref

16:04 you need to (def *mymap* (ref {}))

16:04 make a global definition

16:04 blbrown: hmm

16:05 Chousuke I thought calling 'findgrep-widg-state' would do that

16:05 Chousuke: it defines a new ref, which is then promptly discarded

16:05 your set operation works; you just throw away the ref immediately afterwards :)

16:06 blbrown: dope

16:06 Chousuke: also, it's usually not useful to have have nil values in a map like that.

16:06 since trying to get a key that does not exist returns nil

16:07 blbrown: Chousuke, so it should just be nil

16:08 Chousuke: so what you want is (def *widget-state* (ref {})); then get-state would be @*widget-state* and set would be (dosync (commute *widget-state* assoc fkey widg))

16:08 you can also pass around the ref manually, but the global style is fine too

16:09 as long as it's really *state*, not just trying to emulate mutability becuase you don't want to think of a functional approach :)

16:10 in that case it seems like it's correct to use a ref though.

16:13 djpowell: the other day I mentioned that I was considering dealing a lazy-seq out to multiple seqs after wrapping the input seq in a seque, so that one thread doesn't lag behind of the others leading to unpredictable memory usage

16:14 just wondering if there are any liveness issues with using a seque like that

16:31 Chouser: djpowell: you mean having multiple thread pulling from the same seque-generated seq?

16:35 djpowell: yeah

16:36 well, from separate seqs dealt out from a seque

16:37 so if one thread raecs ahead, it will block putting new items in the seque

16:42 if the fastest thread gets too far ahead of the slowest thread, then the fastest thread will block, because when it tries to pull a new element into the seque's queue it will block cause it has filled the seque's buffer, the other threads will carry on running.

16:42 that sounds ok.

16:44 er i think. i'm confused

16:49 no, that won't work will it. the blocking will only affect the producer

16:53 perhaps i want something like: http://java.sun.com/javase/6/docs/api/java/util/concurrent/LinkedBlockingDeque.html

16:57 Chouser: no seque's block both sides.

16:57 but I'm not sure having multiple consumers will work

16:58 if you call 'rest' on a seque before the producing thread is ready, you'll block.

16:58 if the seque's internal queue is full, it won't call 'rest' on the producing seq until there's room.

17:00 djpowell: btw - in case I didn't explain, the consumers read from seqs that were dealed out from the seque via: http://paste.lisp.org/display/74970

17:02 Chouser: ah, so your consumer threads will skip appropriate amounts of the seque to get full coverage without the same item going to more than one thread

17:02 yeah, that should work.

17:03 but it might be easier to use a LBQ directly

17:03 djpowell: i'll have to have a read of Java Concurrency In Practice - that book is good

17:04 The number of classes in java.util.concurrent is a bit overwhelming without it

17:04 Chouser: because then your consuming threads wouldn't have to be coordinated like that -- when each is done processing an item, it could just grab the next one from the LBQ without having to partition so specifically

17:06 djpowell: yeah

17:07 not sure what the difference between LinkedBlockingQueue and LinkedBlockingDeque is yet

17:08 forest: do you know what is the difference between queue and deque

17:08 stimuli: is paste.lisp.org down ?

17:08 I'm getting proxy errors

17:08 forest: me too

17:08 stimuli: rats

17:08 I was about to post something

17:08 djpowell: forest: no - i'll take a look

17:09 hiredman: jcip mentions deques as useful when each consumer has a queue of input, and if it finishes, it can steal work off the back of another consumers queue

17:09 forest: stimuli: there is a lot of such services, we use http://rafb.net

17:09 hiredman: there is also gists

17:09 gist

17:09 stimuli: forest: thanks

17:12 djpowell: the consumer is based in java, so I think using LBQ directly makes sense

17:21 0

17:21 oops - the perils of using emacs for irc and a repl

17:24 Raynes: People actually use Emacs for IRC?

17:24 :|

17:24 gnuvince_: Yes.

17:24 Hun: of course

17:24 djpowell: M-x erc is ok

17:24 Hun: what else?

17:25 forest: xchat

17:25 Hun: M-x irc is nicer

17:25 gnuvince_: It actually has advantages over other clients.

17:25 ayrnieu: Raynes - I used to live in rcirc.

17:25 forest: i doubt it )

17:25 ayrnieu: One big advantage is that you can edit what you say, and see all of it over multiple lines.

17:26 also, it's a good example of the benefits of lisp. You can hack on your IRC client while you use it, fix bugs, add features.

17:26 forest: not convincing at all )

17:27 ayrnieu: read Cat's Paws and Catapults, then :-)

17:27 djpowell: i use emacs for mail a bit too - on my laptop - it is the only imap client that i've seen that works like webmail

17:27 forest: xchat has perl and python integration

17:28 Raynes: I use XChat simply because I can't find a better client that I like. The only thing I /don't/ like about XChat is that for some reason it crashes on me if I click thinks too fast.

17:28 hiredman: of course, the one true irc setup is screen+irssi

17:28 Raynes: hiredman: On windows Irssi is shit.

17:29 In my opinion,

17:29 hiredman: Raynes: screen

17:29 ssh -> unix

17:29 Raynes: What is screen?

17:29 hiredman: who runs windows anyway?

17:29 :P

17:29 Screen is a full-screen window manager that multiplexes a physical terminal

17:29 between several processes (typically interactive shells).

17:30 Raynes: hiredman: I do. Because I don't have another option. I'd explain, but Lau_Of_DK might crack his whip for offtopic chat.

17:30 forest: there is no user friendly alternative to xchat is far as i know

17:30 AWizzArd: While I am on Windows I use putty to connect to my box in which a screen runs irrsi.

17:30 ayrnieu: forest, http://github.com/ayrnieu/clj-actors/blob/1c062dc5dcde01e4774793840e5f149f7d5dbc37/examples/chat_server.clj starts a simple chat server and then drops into a repl. So you can add features to the server, fix bugs, add tracing, perform tricks (bypass the broadcast and send a message to only one person, or give one person extra commands), etc.

17:30 Hun: depends on the value of user. and friendly.

17:30 Raynes: forest: mIRC is userfriendly. But it's a horrible client.

17:31 hiredman: so is xchat

17:31 AWizzArd: Raynes: you could use Putty to connect to your Linux box

17:31 Raynes: I don't have a linux box.

17:31 forest: Raynes: right now i am in mIRC, what is wrong with it

17:31 AWizzArd: then mirc is probably your best bet :-)

17:32 forest: for windows - mIRC is the best option )

17:32 Raynes: I don't get how anyone can recommend mIRC :|

17:32 ayrnieu: forest - so there's 'classical' development of edit->compile->run->crash->, and there's the 'dynamic' development cycle of edit->run->crash->, and there's a development style that few environments really provide: edit->run->(edit->edit->)

17:33 forest: ayrnieu: right, but fixing an IRC client happens one or zero times in life

17:33 gnuvince_: IRCing from Emacs: auto-completion of more than just nicks, flyspell support, searching, extensibility with Elisp (possibly to give interactions with interpreters), etc.

17:33 ayrnieu: forest - you're thinking like a user. Pretend that you also program.

17:34 forest: my brain just refuses to extend this philosophy to IRC client

17:35 emacs just does not have enough space needed to draw every tab

17:36 Hun: why would you do that? sounds like a truly horrible idea

17:36 gnuvince_: tabs?

17:36 forest: for each channel

17:36 Hun: don't try to summon the great old ones (that's M-x fhtagn for you)

17:37 gnuvince_: Emacs people don't use tabs.

17:37 forest: what do they use having 10 open irc channels

17:37 gnuvince_: plain old buffers

17:37 Hun: i use events

17:37 gnuvince_: Emacs users use buffers

17:37 ayrnieu: rcirc notes activity in the modeline.

17:37 Hun: everytime someone says something, the channel gets added to the active list

17:38 i can switch to and from that with a single keystroke


17:38 forest: because emacs does not have anything more to offer, it is good for text editing, but as i think something more is needed for IRC

17:39 Hun: what is irc /besides/ multiplayer text editing?

17:39 Raynes: Hun: It is everything mankind has accomplished since coming into existence.

17:39 ayrnieu: forest, now you're talking about what an Emacs IRC client could possibly offer. Why don't you TIAS?

17:39 forest: scripting, user coloring)

17:40 Hun: is done by emacs. perfectly fine

17:40 gnuvince_: forest: like I said earlier, it offers auto-completion, it offers spell checking, it offers backward search, etc.

17:40 ayrnieu: yeah, Emacs buffers are much better than "/lastlog ... aw, crap, I'll just grep the logs."

17:40 forest: ayrnieu: what's TIAS

17:40 Hun: ayrnieu: try M-x occur :)

17:41 ayrnieu: try it and see

17:43 blbrown: (apply (fn [x y] (str x " " y)) ["1" "2" "3"]) I want to do a join in clojure, I am assuming this is wrong

17:43 hiredman: uh

17:43 ayrnieu: ,(apply str (interpose " " ["1" "2" "3"]))

17:43 clojurebot: "1 2 3"

17:44 hiredman: your fn there takes two args

17:44 forest: i don't use auto-completion and i feel fine about misspelling, i search in logs and it happens once a year, etc, so for me emacs just offeres lack of tabs and colors

17:44 hiredman: and you applied it to a seq of three args

17:44 *boom*

17:44 yay clojure!

17:44 Hun: forest: it has those. though tabs are still a bad idea

17:44 blbrown: hiredman: I programmed in broken imperative languages most my life, bad habits are hard to break

17:45 ayrnieu: for newlines: (apply str (interleave ["1" "2" "3"] (repeat \n)))

17:45 ...

17:45 for newlines: (apply str (interleave ["1" "2" "3"] (repeat \newline)))

17:46 oh, clojurebot did respond. Darned log.

18:13 danlarkin: I did not get enough sleep this weekend, I am having trouble reasoning about what I need this function to do :)

18:15 forest: ,(.danlarkin sleep (* 1000 (* 8 (* 60 60))))

18:15 clojurebot: java.lang.Exception: Unable to resolve symbol: sleep in this context

18:15 forest: ,(. danlarkin sleep (* 1000 (* 8 (* 60 60))))

18:15 clojurebot: java.lang.Exception: Unable to resolve symbol: danlarkin in this context

18:15 forest: no wonder, you just can't sleep

18:17 danlarkin: Mmmmm 8 hours would be nice

18:18 kotarak: ,(.sleep danlarkin (* 1000 8 60 60))

18:18 clojurebot: java.lang.Exception: Unable to resolve symbol: danlarkin in this context

18:19 kotarak: Yeah. Doesn't work.

18:19 c|p: hello all

18:19 back from my trip

18:20 to those of you who were discussing with me about books, my parents surprised me with a common lisp book

18:20 good enough for my purposes

18:22 ayrnieu: which book?

18:25 c|p: "lisp" by patrick henry winston, 3rd edition

18:26 its a bit old

18:26 but i wanted a book more for exploring functional programming than anything else

18:26 so its just fine

18:27 Hun: c|p: that one is cool. especially the later xps chapters

18:29 c|p: yeah, im on chapter 16 or so

18:29 i slept a bit moer than i intended :)

18:37 blbrown: another newb question coming

18:38 how do you append a value to a sequence

18:38 durka42: conj

18:38 well

18:38 conj appends to the end of vectors, prepends to the beginning of lists

18:39 blbrown: conjoine

18:40 ayrnieu: ,(concat "h" "i")

18:40 clojurebot: (\h \i)

18:41 forest: so you have to be aware all the time what you are working with, is it a vector or a list

18:41 not very nice

18:43 ayrnieu: no, that doesn't follow.

18:43 kotarak: forest: you should be aware anyway, since lists and vectors have different performance characteristics...

18:44 forest: kotarak: appending an element, taking first and rest are almost the same

18:44 durka42: true, but one of the points of generic seq functions is so you can swap out lists for vectors if you discover that they would be faster

18:44 i agree with forest that it seems inconsistent

18:46 forest: i believe that language author said in a presentation that it is transparent to change datatype - he was lying a little

18:47 durka42: i mean, if you are using conj and pop to implement a stack

18:47 then you can switch data types transparently

18:47 because both of those switch

18:47 if you are using first and pop it will need tweaking

18:50 forest: using conj and first seem to me very common operations

18:50 as they come from older lisps

18:50 lisppaste8: jjkk pasted "slow prime-summing" at http://paste.lisp.org/display/75083

18:50 ayrnieu: cons and first, rather.

18:51 beepbeepimajeep: http://paste.lisp.org/display/75083

18:51 why is it taking so long?

18:52 forest: how big is maxi

18:54 ayrnieu: clj defines those functions pretty quickly.

18:54 beepbeepimajeep: maxi is sqrt of the nbr to be tested

18:55 Chouser: that's a slow algorithm for finding primes. You could probably improve the run speed a bit with primitive number types, but it might not be sufficient improvement.

18:55 forest: ok, how big is the nbr to be tested )

18:55 beepbeepimajeep: from 0 to 2000000

18:55 each nbr

18:56 (prime? 2000000) is instant

18:56 durka42: well, it is basically the same algorithm as in the wiki, except for the even number part

18:56 unless i misread i

18:56 t

18:57 * Chouser checks the wiki

18:57 Chouser: hm, indeed

18:57 forest: one good improvement would be checking to all numbers up to sqrt(p) but only already found primes <= sqrt(p)

18:57 Chouser: how long is "so long"?

18:57 forest: to all = not all

18:59 hiredman: clojurebot: Sieve?

18:59 clojurebot: Pardon?

19:00 hiredman: clojurebot: Seive?

19:00 clojurebot: Gabh mo leithsc�al?

19:00 forest: http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes

19:02 Chouser: your prime? is testing at least twice as many numbers as the wiki version, since it's counting up by 2 instead of 1

19:02 hiredman: clojurebot: google genuine seive

19:02 clojurebot: First, out of 1190 results is:

19:02 WikiAnswers - Name of the tissue that cotains seive tubes

19:02 http://wiki.answers.com/Q/Name_of_the_tissue_that_cotains_seive_tubes

19:02 hiredman: gah

19:03 useless

19:03 forest: Chouser: doesn't it make it test twice LESS numbers

19:04 gnuvince_: ,(let [x [1 2 3], f (fn [y] (identical? x y))] (f x))

19:04 clojurebot: true

19:06 Chouser: forest: I messed up my English. With wiki version uses (+ i 2) instead of (inc n)

19:07 forest: anyway it will find divisor 2 immediately

19:07 for even numbers

19:08 i don't think it influences much on runtime

19:08 durka42: the wiki vewrsion doesn't say anything about how long it takes

19:09 forest: it must be pretty long

19:10 sieve of eratosthenes is fast

19:24 Hun: depends on the range of numbers you use it on

19:25 and on your test. using it naively on bignums is /slow/

19:25 forest: where do bignums come from ? 2 000 000 fits in int fine

19:26 Chousuke: it's by default a boxed integer

19:26 which is still a lot slower than primitive math

19:26 forest: but still it is not bignum

19:27 Chousuke: I'm assuming Hun meant boxed integers

19:27 forest: by bignums, you have a vivid imagination)

19:30 * Chousuke is just good at divining

19:30 Chousuke: Though even my crystal ball sometimes fails :/

19:34 xoox: How do I find out where in my clojure code an exception is being raised? Trying to do (.printStackTrace *e) in slime returns nil. The exception is "Wrong number of args passed to: LazilyPersistentVector". The backtrace provided by slime is unhelpful.

19:37 ayrnieu: ,([])

19:37 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: PersistentVector

19:37 ayrnieu: ,([] 1 2)

19:37 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: PersistentVector

19:37 ayrnieu: ,([] 1)

19:37 clojurebot: java.lang.IndexOutOfBoundsException

19:37 hiredman: ,(vec 1 2 3)

19:37 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$vec

19:38 xoox: I understand but how do I find out where it is occuring?

19:38 Is there no backtrace for clojure code?

19:39 ayrnieu: there's the backtrace that you've already found unhelpful, if that's the same that (.printStackTrace *e) would give you

19:39 you can find clj-backtrace on github, which tries to give better backtraces

19:40 xoox: ayrnieu: Are the backtraces supposed to reference clojure code?

19:42 ayrnieu: at clojure.core$inc__3264.invoke(core.clj:685)

19:43 and as this error rises from (send ag inc), you can also see clojure.lang.Agent$Action.doRun(Agent.java:69)

19:43 ,(doto (agent nil) (send inc) (await) (-> agent-errors first (.printStackTrace)))

19:43 clojurebot: java.lang.RuntimeException: Agent has errors

19:43 ayrnieu: ,(doto (agent nil) (send inc) (await) (-> agent-errors first (.printStackTrace)))

19:43 clojurebot: Agent has errors

19:43 ayrnieu: there's a nasty race condition in that code.

19:44 durka42: shouldn't the await prevent it

19:44 xoox: Is anyone working on instrumentation of clojure code for the purposes of debugging?

19:44 ayrnieu: durka42 - await is what's throwing the exception

19:44 durka42: oh

19:45 forest: xoox: why, http://clojure.org/getting_started#toc5

19:47 xoox: forest: Does that provide anything like the slime debugger?

19:47 skogs: why does condp throws an exception instead of returning nil on no matches

19:48 ayrnieu: skogs - it's useful.

19:49 te: Hello all

19:49 does someone have the concourse.tar.gz link

19:49 it should be within the last 12 hours

19:49 maybe some one has it in their buffer?

19:49 skogs: it could be, but seems odd compared to cond and other control structures

19:49 ayrnieu: Lau_of_DK> te: http://p.hagelb.org/concourse.tar.gz

19:49 forest: xoox: not sure

19:49 te: thanks

19:50 forest: there are some pictures http://bc.tech.coop/blog/081023.html

19:50 xoox: (xml1-> foo-dom zf/descendants :table

19:50 #(when (re-find #"sortable_table_id_0" (attr % :id))

19:50 (node %)))

19:51 sorry, wrong buffer

19:51 te: Is it useful to think of clojure as "divide and conquer"? Sort of a: build this module, build that module, pass both modules to this module, which completes the calculation?

19:51 forest: an example why i don't like emacs as IRC client

19:52 c|p: emacs has an irc client?

19:52 well, not all surprising

19:52 emacs has everything

19:52 durka42: heck emacs has a web browser

19:52 te: c|p: it's pretty neat tbh

19:52 c|p: heh

19:52 te: im new to emacs

19:52 Chousuke: no, it's not emacs as an irc client!

19:52 te: but i think the split windows and such is really cool

19:52 c|p: makes me think of like

19:52 forest: it was quite a discussion a little earlier

19:52 c|p: "what os do you use?"

19:52 "emacs"

19:52 Chousuke: that's like saying "java as an irc client"

19:52 te: its kind of like screen + ncurses environment

19:52 drewr: I'm using ERC Version 5.2 with GNU Emacs 22.3.2 (i386-apple-darwin9.5.0, Mac Carbon) of 2008-11-29.

19:53 te: does Java have curses libraries?

19:53 I would assume so...

19:53 ayrnieu: te - yes.

19:53 c|p: there is one that i know of

19:53 forest: is it unix only ?

19:53 te: i googled and got my answer

19:53 ayrnieu: it's a curses library. It's curses only.

19:53 te: ncurses?

19:55 ayrnieu: http://www.nongnu.org/jcurzez/doc.html also supports windows

19:55 durka42: console gui widgets library

19:56 forest: tested on win9X ))

19:56 i would not call it windows support

19:57 * ayrnieu shrugs.

20:12 te: I hope I'm not offending the author if he's in here

20:12 but I am not really enjoying "Programming Clojure" thus far

20:12 it's a beta, so things may well change

20:12 forest: is it a book ?

20:12 te: but i think it is kind of a harsh introduction

20:12 yes

20:12 pragprog.com

20:14 Technomancy isn't here is he?

20:14 d'oh

20:14 I need his .emacs configuration -- I don't remember how to do this

20:32 Exception in thread "main" java.lang.NoClassDefFoundError: jline/ConsoleRunner

20:32 grrrrr

20:33 nevermind found it -- absollute path i think will fix the config

20:33 absolute*

20:34 ls

20:38 xoox: (xml1-> (xml-zip (xml/parse url startparse-tagsoup) zf/descendants :img))

20:38 Why do I get OutOfMemory? ^

20:41 skogs: on an IllegalArgumentException, how do i identify where its coming from

20:41 mofmog: So I can get an apache server

20:42 should i ask for tomcat or jetty? I know people prefer jetty w/ clojure but tomcat seems likeless hassle

20:42 skogs: there r multiple functions that throw this exception, but i only want to catch my high level one

20:50 hiredman: skogs: all functions throw that Exception if you pass them the incorrecct number of args

20:51 skogs: tough luck i guess

20:57 what's the recommended way of writing tests in clojure

20:58 i'd like to keep the tests near the code itself

20:58 durka42: (doc test)

20:58 clojurebot: test [v] finds fn at key :test in var metadata and calls it, presuming failure will throw exception; arglists ([v])

20:59 durka42: you can put a test in the metadata of a function

20:59 at the key :test

21:00 skogs: how do i execute the test then/

21:01 stimuli: hi

21:02 durka42: (defn #^{:test #(= 2 (plus 1 1))} plus [a b] (+ a b))

21:02 (test #'plus)

21:03 hmm, that test is wrong, it has to throw an exception if not satisfied

21:03 skogs: cool, thats a good test then

21:04 btw why cant u just call (test plus)

21:05 durka42: wrap the test in an assert to fix it, #(assert (= 2 (plus 1 1)))

21:05 because you need the var

21:05 ^plus is nil

21:05 ^#'plus has the :test key

21:05 symbols don't have metadata, vars do

21:06 skogs: oh

21:06 durka42: (defmacro test-fn [f] `(test #'~f))

21:07 skogs: thats neat

21:08 i heard about test-is

21:08 any comments on its utility?

21:08 stimuli: it works as well as any other unit test framework

21:08 durka42: not from me, haven't used it

21:08 probably works better than straight clojure.core/test as described above

21:09 Chouser: xoox: parens in the wrong place?

21:09 xoox: (xml1-> (xml-zip (xml/parse url startparse-tagsoup)) zf/descendants :img)

21:15 skogs: durka42: thanks for ur help

21:17 defn: so what is performance really compared to say, perl, ruby?

21:17 ive read all sorts of dissenting opinion

21:18 ayrnieu: you read people who said that their Clojure program ran slower than their similar Ruby program?

21:18 defn: no definitely not

21:18 im just curious if there it is faster by a factor of N, etc.

21:19 Chouser: Clojure and JVM startup time hurt pretty bad.

21:19 ayrnieu: which knocks you out of using clojure for trivial things. Oh well :-/

21:19 defn: so compared to say, C++? what does that comparison look like?

21:19 durka42: could use nail

21:19 nailgun*

21:20 Chouser: once running, the JVM is dramatically faster than the runtime engines of perl, python, and ruby.

21:20 defn: Chouser: i assumed as much i supposed

21:21 Chouser: any particular library functionality may be faster in one language than another. I've heard complaints about Java's large number speed compared to python, though I've not run any tests myself.

21:24 ayrnieu: depends on how trivial. On my computer, clojure startup costs perhaps a second. Interactively at the shell prompt, that's usually not a deal breaker.

21:24 defn: what is a deref? eg @form => (deref form)

21:25 why would that be useful?

21:25 durka42: get the value out of a ref/atom/agent

21:25 ayrnieu: defn - you'll use it with STM and concurrency.

21:26 defn: hm, durka42 what are those?

21:26 durka42: what ayrnieu said

21:26 i recommend reading the relevant sections on clojure.org for starters

21:26 defn: yeah im reading it right now

21:27 its weird that the second link after getting started is "The Reader", which makes reference to many obscure ideas that I've never been introduced to before

21:27 ayrnieu: Programming Clojure also helps, and reading clojure.org more carefully a second time helps, and so does slamming into walls doing things that are very simple in anticipation and in retrospect, but not while they aren't working :-(

21:27 defn: haha true

21:28 ayrnieu: I bought programming clojure, but it's not finished yet and it seems kind of well, disjointed

21:28 blbrown: Chouser they say a lot of that startup performance hit is because of the loading of the core Java libraries, in terms of the quantity and since all the boostrap libraries are archived files. Wonder if someone would fork the jdk to resolve this issue

21:28 defn: not very linear anyway

21:29 Chouser: defn: what languages have you used previously?

21:29 defn: Ruby, C++

21:29 I know there are many similarities to Ruby, or at least, more than C++

21:29 I guess I just am getting hung up on the idea of functional programming

21:30 Chouser: yes, clojure and ruby are both dynamic and have some high-order functions.

21:30 C++ is neither. :-)

21:30 defn: what i dont understand is the order in which things are mixed together

21:31 Chouser: when Clojure is evaluating a line of code?

21:31 defn: yes

21:31 blbrown: defn if you want, you can keep a lot of the imperative style programming as you do in Ruby/C++. even though it is not advised. The syntax is going to be different E.g parens but you can code almost line for line like you would in ruby.

21:31 defn: i need a flow chart to show me what is happening behind the scenes

21:31 blbrown: defn actually, you can code line for line like you would in java, just different syntax

21:31 defn: because i feel like there is some magic happening im unaware of

21:31 Chouser: defn: with the exception of macros, clojure expressions are evaluated from the inside out, args left to right, just like in Ruby.

21:32 defn: i think the parens that span multiple lines and encompass other things are making my head spin a bit

21:32 i might be making this too hard

21:33 durka42: it's just that pretty much anything can be nested inside anything else

21:34 defn: how do i pass a function as an argument? lets say I want to make some module that filters a list of integers and outputs integers with a remainder of 0

21:34 and then i have a list that keeps on making random numbers

21:34 err a fn that makes random numbers

21:35 how could i tell my filter to start outputting the results of the data ive generated

21:35 (after this ill leave you alone for a bit, but this would be helpful if you could explain nit)

21:35 blbrown: you might ask one question at a time, maybe a little easier for others to help

21:36 defn: yeah im sorry, just anxious

21:36 Chouser: anytime you use a functions name that's not at the head of a list, you'll get its value

21:36 ,(prn +)

21:36 clojurebot: #<core$_PLUS___3183 clojure.core$_PLUS___3183@1afd9cc>

21:36 ayrnieu: ,(filter #(-> % (rem 3) zero?) (take 100 (repeatedly #(rand-int 10))))

21:36 clojurebot: (9 9 9 0 0 0 3 6 9 0 6 0 0 0 6 9 0 3 6 3 3 0 0 6 0 9 9 9 9 9 6 0 3 3 0 9 0 3 9 0 0 9)

21:36 Chouser: there 'prn' is at the head of a list, so it gets called with + as a parameter.

21:39 defn: could you explain what you mean by that?

21:39 Chouser: who, me?

21:39 defn: yes, please

21:39 Chouser: prn is function and + is a function

21:40 defn: how is prn at the head of a list, it seems like its off on its own

21:40 err d'oh

21:40 im sorry i see

21:40 Chouser: :-) no problem. Code is data can be a little surprising at first.

21:40 defn: im just trying to understand the effect of it on the 2nd line you posted

21:41 oh god, im terrible, that was ayrnieu

21:41 * defn needs sleep

21:41 durka42: read it inside-out, starting at rand-int

21:41 Chouser: yeah, ayrnieu's using a couple convenience macros there that may obscure a bit what's really going on.

21:41 he solved your whole problem in a single line.

21:41 defn: yeah the -> threw me

21:42 blbrown: defn, do you understand the prefix notation?

21:42 ayrnieu: ,(filter (fn [n] (zero? (rem n 3))) (take 100 (repeatedly (fn [] (rand-int 20)))))

21:42 clojurebot: (6 15 15 9 3 15 12 12 15 18 9 12 18 18 18 9 12 15 15 6 3 0 15 6 15 6 9 18 18 9)

21:42 defn: blbrown: yes i believe so

21:44 so repeatedly takes a function rand-int 10, and returns an infinite sequence of calls to it

21:44 take 100 limits it

21:44 ayrnieu: right.

21:45 defn: then you define an anonymous function with an argument n that checks if its zero, if yes, it gets the remainder of n and 3

21:45 durka42: it checks whether the remainder of n/3 is zero

21:45 ayrnieu: no. What argument does zero? have?

21:45 defn: zero has (rem n 3) as an arg

21:46 ayrnieu: zero?'s just a function, so (rem n 3) must be evaluated before zero? can see if it's equal to zero.

21:46 ,(rem 6 3)

21:46 clojurebot: 0

21:46 ayrnieu: ,(rem 7 3)

21:46 clojurebot: 1

21:46 defn: so for every element in the sequence we check to see if the remainder of n and 3 is 0, if zero? is true

21:47 then we output it

21:47 ayrnieu: well, filter returns a lazy list of numbers divisible by three, drawn from the first hundred elements of an infinite sequence :_)

21:47 defn: haha

21:48 ayrnieu: ,(let [cnt (ref 0)] (filter #(-> % (rem 3) zero?) (take 100 (repeatedly #(do (dosync (alter cnt inc)) (rand-int 20))))))

21:48 clojurebot: (15 18 6 6 9 9 18 3 3 15 6 12 12 18 15 3 6 6 3 12 18 0 0 3 12 15 12 12 9 18 15 0 6 18 9 12 15)

21:49 defn: okay let me think here

21:49 :)

21:49 ayrnieu: ,(let [cnt (ref 0) lst (filter #(-> % (rem 3) zero?) (take 100 (repeatedly #(do (dosync (alter cnt inc)) (rand-int 20)))))] [@cnt lst])

21:49 clojurebot: [2 (0 6 0 9 0 18 12 12 9 15 0 3 3 0 9 3 0 12 15 18 18 12 0 9 3 12 0 12 15 18 9 9)]

21:49 ayrnieu: ... that doesn't seem right :-/

21:49 defn: oof that is tough

21:49 durka42: erm... that didn't work so well did it

21:49 defn: is that the concurrent version?

21:50 ayrnieu: that sets cnt to (ref 0), to keep a count of the times that the function given to repeatedly is called.

21:50 defn: you use cnt (ref 0) to keep track of state

21:51 ayrnieu: ,(let [cnt (agent 0) lst (filter #(-> % (rem 3) zero?) (take 100 (repeatedly #(do (send cnt inc) (rand-int 20)))))] (await cnt) [@cnt lst])

21:51 clojurebot: [1 (9 0 18 18 6 0 15 12 0 0 9 6 12 6 0 12 6 12 18 15 18 6 0 6 15 9 0 15 9 3 9 18 18 6 0 15 18 6 6)]

21:51 defn: ayrnieu: what is that -> stuff?

21:51 it looks familiar, from squeak maybe? limbo?

21:51 ayrnieu: (-> x expr1 expr2 expr3) becomes (expr3 (expr2 (expr1 x)))

21:52 durka42: ayrnieu: throw a doall around the list

21:52 defn: ahhh

21:52 ayrnieu: durka - I want to see how many times it's really called, though, not force 100 calls

21:52 defn - likewise, (-> x expr1 (expr2 y)) becomes (expr2 (expr1 x) y)

21:53 defn: this is awesome.. i feel a lot better just having someone hold my hand for a minute -- with 0 lisp experience im always very unsure of what im doing with clojure

21:53 ayrnieu: ...

21:54 ,(let [cnt (agent 0) lst (filter #(-> % (rem 3) zero?) (take 100 (repeatedly #(do (send cnt inc) (rand-int 20)))))] (doall lst) (await cnt) [@cnt lst])

21:54 clojurebot: [100 (9 6 18 3 12 3 12 0 9 0 3 9 12 3 0 0 9 12 9 9 12 0 6 3 6 18 0 15 9 6 12 6 15 0 3 9 9 6 18 15 0 3 12)]

21:54 ayrnieu: ,(let [cnt (agent 0) lst (filter #(-> % (rem 3) zero?) (take 100 (repeatedly #(do (send cnt inc) (rand-int 20)))))] (await cnt) [lst @cnt])

21:54 clojurebot: [(6 6 12 15 18 6 6 9 6 9 12 18 15 3 18 15 9 12 0 18 0 12 15 9 9 18 3 0 3 9 9 12 3 9 15 3 0 9 12 12 18 6 18 6) 1]

21:54 blbrown: show off

21:55 ayrnieu: hey, I was confused.

21:56 durka42: ayrnieu: i think the transactions are being run after stuff is printed

21:56 lisppaste8: durka42 pasted "untitled" at http://paste.lisp.org/display/75093

21:57 defn: how does #() work in these cases?

21:57 Chouser: right, filter etc. are lazy, and aren't forced until printed.

21:57 ayrnieu: #(...) becose (fn [] ...); #(... % ...) becomes (fn [x] ... x ...), and so on.

21:58 s/becose/becomes/.

21:58 Chouser: ayrnieu: almost. #(foo) becomes (fn [] (foo))

21:58 not the inner parens on the output form

21:58 *note

21:58 defn: oh, so #(foo) is just short-hand for an anonymous definition

21:59 durka42: ya

21:59 c|p: #() is sugar for lambda etc

21:59 defn: ah okay

21:59 ayrnieu: ,(#(do %2) 1 2)

21:59 clojurebot: 2

21:59 ayrnieu: ,(#(do %3 %2) 1 2)

21:59 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--1062$fn

22:28 blbrown: Can I not do this to set a value defined by 'ref' (defn set-directory-open [path] (dosync (commute (set! *directory-open-state* path))))

22:28 where *dir....open* is a string

22:29 Chouser: no, you can't.

22:29 try 'ref-set'?

22:29 (doc ref-set)

22:29 clojurebot: Must be called in a transaction. Sets the value of ref. Returns val.; arglists ([ref val])

22:29 blbrown: dope

22:30 Chouser, would I need the 'commute' then?

22:31 ayrnieu: (dosync (commute *directory-open-state* #(do % path)))

22:31 (dosync (commute *d-o-s* ref-set path))

22:31 blbrown: hehe, don't like my long name

22:31 durka42: isn't ref-set inside commute redundant?

22:32 ayrnieu: oh, you can just (dosync (ref-set *d-o-s* path))

22:32 it needn't be.

22:32 actually, if it weren't, it would be useful for (send ag ref-set new-value)

22:32 blbrown: and for my own edification, we use 'ref' and sometimes 'agent' for setting 'global' values

22:33 durka42: ayrnieu: that doesn't make sense, an agent is not a ref

22:33 ayrnieu: durka - it doesn't make sense because commute is redundant, do you see?

22:33 durka42: i suppose so

22:33 (send ag #(do new-value))

22:33 ayrnieu: #(do % new-value)

22:34 c|p: is there a method that returns the classpath?

22:34 ayrnieu: #(do %2) new-value

22:34 durka42: yes, that

22:34 c|p: wait

22:34 yes there is

22:34 lol

22:34 durka42: (System/getProperty "java.class.path")

22:34 ,(System/getProperty "java.class.path")

22:34 clojurebot: java.security.AccessControlException: access denied (java.util.PropertyPermission java.class.path read)

22:34 c|p: ye

22:35 ayrnieu: blbrown, ref access provides STM. Atom access provides dumb spinlocking. Agents... are interesting.

22:37 blbrown: ayrnieu, do you think there is any future for adding a distributed actor model kind of like erlang?

22:37 ayrnieu: blbrown - http://github.com/ayrnieu/clj-actors/tree/master , but that doesn't address distribution.

22:40 blbrown - I think distribution is possible.

22:42 danlarkin: there's so much cool work happening in clojure, it's hard to keep up with it all :)

22:45 blbrown: danlarkin, is this you? http://twitter.com/danlarkin

22:45 danlarkin: one and the same

22:46 although that is not me in the picture

22:46 I just think it's hilarious

22:47 blbrown: this is me in the picture. http://twitter.com/berlinbrown if you follow, ignore the stories of drunken debauchery

22:49 danlarkin: heh, will do

22:51 Chouser: This is not me, and has nothing to do with me: http://twitter.com/chouser

22:51 blbrown: my function names are ridiculously long

22:53 danlarkin: oh Chouser you should petition twitter to give you @chouser, I'd follow you!

22:54 gnuvince_: Has anyone ever noticed that as your program becomes more correct, it becomes slower also?

22:55 danlarkin: gnuvince_: yeah what the hell right?

22:56 gnuvince_: danlarkin: yeah :) When I dumped all the actions of a Starcraft replay into one vector, analyzing 1000 replays tooks 3 minutes 40 seconds. Now that I separate actions by player, it takes move than five minutes.

22:56 *took

22:57 blbrown: gnuvince, what in the world are you doing...woooa

22:57 gnuvince_: blbrown: http://github.com/gnuvince/clj-starcraft/tree/master

22:58 danlarkin: oh, do you live in hungary, gnuvince_?

22:59 oh, nevermind, I see what it is

22:59 blbrown: this is my clojure tool, but will probably be used by the company first. Maybe I can release it later to the public. http://img17.imageshack.us/img17/3748/screenshotoctanetextvierk1.png

22:59 gnuvince_: danlarkin: Canada. I'm using the lib of someone else to unpack the replays.

23:02 danlarkin: gnuvince_: yes, my mistake

23:02 gnuvince_: danlarkin: no problem.

23:03 blbrown: gnuvince, what can you do with them after they are unpacked

23:03 gnuvince_: Anyway, I'm trying to trim down the processing time of a single replay as much as I can (without compromising correctness), because some guys have collections of thousands of replays.

23:04 blbrown: Once they're unpacked, it's a binary format that I decode and it gives you a complete history of what happened during a game. Every action is recorded with a time stamp and a player id.

23:04 So it's possible to know how many actions per minutes a player was doing (good players keep in the 300 apm range), what units were produced, etc.

23:16 hiredman: when I visit my parents in korea I watch the pro starcraft players on tv

23:16 crazy

23:19 * durka42 was not aware it's a spectator sport

23:19 gnuvince_: durka42: it is.

23:19 Very popular in South Korea.

23:19 hiredman: they have their own tv channel fror starcraft and counter-strike

23:19 gnuvince_: There are English commentaries of the pro games

23:19 http://www.youtube.com/profile?gl=CA&hl=en&user=VioleTAK&view=videos

23:19 hiredman: they wear jumpsuits

23:19 gnuvince_: hiredman: they used to :)

23:19 hiredman: (the contestants)

23:19 gnuvince_: They've now reverted to sports jackets.

23:20 durka42: hey, if you can manage to get paid for it... :p

23:20 gnuvince_: http://www.mymym.com/gfx/bisu_skt1.jpg

23:20 They look more like this.

23:20 Anyway, I'm a pretty big fan of the korean pro scene.

23:21 blbrown: is starcraft mostly a mix of strategy or 'physical speed'. When I play, I am too slow to do anything

23:21 hiredman: I bought my copy of sc in korea many years ago

23:21 blbrown: talking about starcraft, I wonder if I can play it on wine

23:21 hiredman: blbrown: I am pretty sure it is one of the main use cases

23:22 ayrnieu: blbrown, I played SC on wine on a P133 -- obviously a long time ago.

23:22 gnuvince_: blbrown: speed plays a big part, because players need to attend to many tasks at once, but it is not impossible for slower players to dominate faster players if their game sense is more finely honed.

23:23 hiredman: I think someone was porting SC to C# on mono

23:23 blbrown: interesting. I bought the boxed version a couple of months ago, I might install it right now

23:23 gnuvince_: blbrown: http://www.youtube.com/watch?v=PPP8aSi1PeM

23:24 This is a first person video from a pro gamer

23:24 You'll see he's *very* fast

23:25 c|p: is there a sort-of #' equivalent for java functions

23:25 ayrnieu: ,(map #(.getName %) (.getMethods String))

23:25 clojurebot: ("hashCode" "compareTo" "compareTo" "indexOf" "indexOf" "indexOf" "indexOf" "equals" "toString" "length" "isEmpty" "charAt" "codePointAt" "codePointBefore" "codePointCount" "offsetByCodePoints" "getChars" "getBytes" "getBytes" "getBytes" "getBytes" "contentEquals" "contentEquals" "equalsIgnoreCase" "compareToIgnoreCase" "regionMatches" "regionMatches" "startsWith" "startsWith" "endsWith" "lastIndexOf" "lastIndexOf" "lastI

23:25 hiredman: c|p: there are no functions in java, just methods :P

23:26 c|p: well, i hope what i meant was implied :)

23:26 ayrnieu: ,(let [f #(System/getProperties)] (f))

23:26 clojurebot: java.security.AccessControlException: access denied (java.util.PropertyPermission * read,write)

23:26 gnuvince_: c|p: memfn maybe?

23:26 durka42: (doc memfn)

23:26 clojurebot: Expands into code that creates a fn that expects to be passed an object and any args and calls the named instance method on the object passing the args. Use when you want to treat a Java method as a first-class fn.; arglists ([name & args])

23:26 gnuvince_: ,((memfn .valueOf) 3)

23:26 clojurebot: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Malformed member expression, expecting (.member target ...)

23:26 gnuvince_: ,((memfn toString) 3)

23:26 clojurebot: "3"

23:26 c|p: i see

23:27 that will work

23:27 gnuvince_: ,(macroexpand-1 '(memfn toString))

23:27 clojurebot: (clojure.core/fn [target__4019__auto__] (. target__4019__auto__ (toString)))

23:35 blbrown: hiredman, this is awesome, I am about to install now

23:35 hiredman: hmmm

23:36 blbrown: my appreciation for linux just went up

23:36 hiredman: actually I just tried and wine died

23:37 blbrown: hiredman, I am on Ubuntu , put in the CD and then navigated to the dos devices in Wine and launched setup.exe

23:38 * hiredman will try again

Logging service provided by n01se.net