#clojure log - Nov 23 2008

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

0:59 albino: Does the plus sign in the docs for aset represent varargs?

1:01 hiredman: (doc aset)

1:01 clojurebot: Sets the value at the index/indices. Works on Java arrays of reference types. Returns val.

1:03 hiredman: it must

1:09 gnuvince_: albino: it's like with regexes; ? is when there's none or one, * when there's none or many and + when there's at least one.

1:12 albino: user=> (aset a 0 1 10)

1:12 java.lang.IllegalArgumentException: Argument is not an array (NO_SOURCE_FILE:0)

1:12 I can't get it to work with more than one index

1:15 Chouser: I think the multiple indexes is for multi-dimentional arrays.

1:15 (aset a 1 2 10) is like a[1][2] = 10

1:20 albino: ahhh

1:20 we need that in the docs

1:22 I thought it was a[1] = 10; a[2] = 10;

1:23 Chouser: yeah, that's a reasonable guess. And it does appear the actual behavior isn't even hinted at in the docs.

1:24 that I can find, anyway.

1:26 notallama: how can i tell how a sorted set will be sorted?

1:26 is there any way to give it a comparator?

2:45 albino: Do I need to import things from clojure.core? I figured it would all be imported by default.

2:50 danlei: From (doc ns) If :refer-clojure is not used, a default (refer 'clojure) is used.

4:06 Lau_of_DK: Top of the morning gents! =)

4:06 kotarak: Hi Lau!

4:20 hiredman: clojurebot: Lau_of_DK is <reply>Top of the morning #who!

4:20 clojurebot: You don't have to tell me twice.

4:20 hiredman: clojurebot: Lau_of_DK?

4:20 clojurebot: Top of the morning hiredman!

4:21 Lau_of_DK: :)

4:35 tWip: webjure now supports regex patterns on the path... and binding groups

4:40 Lau_of_DK: webjure != compojure ?

4:40 @ tWip

4:40 tWip: no, they are two different projects

4:40 I don't know about compojure

4:40 Lau_of_DK: You mean, "Yes, they are two different projects"

4:41 What makes webjure special ?

4:41 tWip: I think webjure came first

4:41 Lau_of_DK: oh :)

4:43 tWip: compojure seems to have more of a community

4:44 Lau_of_DK: Why the fork then. Wouldnt you get more done by merging the two projects?

4:44 tWip: I don't think they forked

4:51 and no, I think exploring different ways to make a web framework for Clojure is useful

4:51 maybe one de-facto will emerge in time, but it's good to have choice

4:53 Lau_of_DK: tWip: alright

6:19 So - Anyone doing anything interesting in Clojure?

6:20 kotarak: Not in, but for actually. Working on VimClojure improvement. Hmmm.. So interesting maybe depends on the point of view. ;)

6:20 Lau_of_DK: Yes - Im not really into the revival of discarded editors though, but others might find it interesting, so thanks for sharing =)

6:21 Did you check out Chousers online Repl, kota ?

6:21 kotarak: The Browser Repl?

6:21 Lau_of_DK: yea

6:22 kotarak: I had a look, but cannot claim, that I understood everything. I'm not that deep in javascript and browser stuff.

6:22 Lau_of_DK: He wrote part of it in C, I think you can find the whole thing in contrib

6:23 blackdog_away: i wonder why chouser doesn't use an applet with clojure

6:24 Lau_of_DK: Hmm...

6:24 Thats actually a very good question.

6:24 blackdog, did you ever find a way to wrap JQuery nicely in Clojure?

6:25 blackdog_away: i suppose his method is likely to woork 100% with no requierment for jdk installation

6:25 yes, clojurescript works

6:25 i did a one line test, but it can be done

6:25 Lau_of_DK: Chousers own words were that it was not ready for production yet

6:26 blackdog_away: i think its a technology in search of an application

6:27 Lau_of_DK: As it is, JQuery is so simple to write out in plain javascript, that I'd prefer to have the thing operational beore using it

6:27 But maybe thats just me

6:27 blackdog_away: agreed, it needs the killer app

6:28 as js is a tad entrenched to beat up on

6:29 Lau_of_DK: How do you mean blackdog_away ?

6:30 blackdog_away: well there are too many plus points with js for clojurescript to really be an option

6:30 unless there was a killer app

6:30 another negative is it needs compiled

6:33 Lau_of_DK: I agree with the first part. But I dont see how the compilation is any different from anything else that goes out of Clojure

6:33 @ Big Black Dawg

6:33 blackdog_away: well, compared to js on the client it's a problem

6:33 Lau_of_DK: So you mean, that it takes away from the performance we would normally free from the server?

6:35 blackdog_: no, simply an extra compilation step is not so good for the client i think

6:36 if you're used to working with gwt etc or java web frameworks it's a no brainer,

6:36 but for your average web designer type, they don't want another step

6:37 well i suppose you can argue that flash etc all require extra steps too

6:37 i guess that's why i don't like any of them :)

6:38 Lau_of_DK: Weird attitude :)

6:38 I mean, I agree that we should plan ahead with resources in mind. But this step that youre worrying about is not likely to cause any problems, anywhere?

6:38 Or am I being short sighted now?

6:39 blackdog_: well, for example, i was using haxe a lot last year, and it's excellent, great for the web,

6:39 but really with the advances in js and great debugging

6:39 it's hard to beat straight js/dom

6:40 that's really all I'm sayin

6:40 the point of haxe being it's an extra compilation step too

6:40 and it just becomes old

6:40 Lau_of_DK: k

6:40 You want the comet?

6:41 blackdog_: ?

6:41 Lau_of_DK: Comet? You work with Comet now right?

6:41 blackdog_: i wrote a wrapper for the jetty comet chat server in clojure

6:42 Lau_of_DK: k

6:42 blackdog_: but that's all, i need to know more about

6:42 it

6:43 Lau_of_DK: btw, BlackDingDawg - Do you know how to set up a standard apache2 server to handle the static pages, and then have it proxy all dynamic pages to a jetty or something like that?

6:44 blackdog_: not really i use nginx these days to do exactly the same thing

6:45 but it won't take yo long to goog for mod_proxy

6:45 Lau_of_DK: Im sure it wont, but I have zero experience, so if you knew how, I'd prefer to hear it from you

6:47 blackdog_: can't remember of the top of my head

6:59 Fib: Is there any significant difference between ((fn a [seq] (foo seq)) seq) and (fn b [& args] (apply foo args))? Would there ever be a limit on the number of args to a function?

7:01 jaan: uuu. snowstorm. lights are blinking. i'll better go offline..

7:02 timothypratley: b is easier to call?

7:02 opps that doesn't answer your question /hides

7:05 Fib: hehe

7:11 It's true (apply b seq) and (b z y x) are very easy while (a `(~z ~y ~x)) is a bit uglier

7:11 But if you want to chain serveral operations on a sequence then calling apply each time would be awkward...

7:11 kotarak: I hope that his is a joke: (a (list x y z))

7:11 s/his/this/

7:12 Fib: Ah I see

7:12 Sorry, I am a complete newbie :)

7:12 kotarak: no problem. I was scared by the quotation usage. :)

7:13 Fib: it depends on what you want to do. eg. map gets a collection. (map transform-element some-seq)

7:14 (apply map transform-element some-coll) seems odd.

7:15 Fib: Yeah, that's what I was thinking

7:15 kotarak: (it has an application though: (apply map transform-pair [first-coll second-coll])

7:15 Fib: I was defining a function "average" and wondering if that should take varargs or a sequence

7:17 kotarak: Probably a seq. Rationale: (defn average "Returns the average of the elements of coll." [coll] (/ (reduce + coll) (count coll)))

7:19 Equally well not a seq: Rationale: + and friends also take variable numbers of arguments...

7:19 Hmmm... Don't know. Personal preference maybe�

7:20 Fib: :)

7:20 I'm still trying to understand the (apply map transform-pair [col1 col2]) example you gave though

7:21 Is that any different from (map transform-pair [col1 col2])?

7:21 kotarak: (map (fn [x] (transform x)) xs) vs. (map (fn [x y] (transform x y)) xs ys)

7:21 mehrheit: Fib: it's the same as (map transform-pair coll1 coll2)

7:21 Fib: ah ok

7:22 kotarak: Fib: it was bad example from my side. Since map actually accepts multiple arguments.

7:23 timothypratley: Good question really, I'd be interested in when to use a vs b. At a guess I'd imagine b is good for cases where you generally only have a few arguments, whereas a is good when you want to use larger sequences eg (range 100)?

7:23 average is a tricky example

7:24 I would say it is more likely you want to use it for large sets

7:24 so a is more convenient

7:24 kotarak: timothypratley: I think it depends on whether you want to work in the collection as an argument or whether the collections the arguments.

7:25 Geez, I'm confused today. Sorry. I don't even understand what I'm trying to say myself...

7:25 timothypratley: hahahaa, I agree I'm just trying to figure out how to tell the difference :)

7:25 kotarak: reduce expects a collection which it transforms into something else.

7:26 + adds two or more numbers.

7:27 Ok. I'm confused. Sorry.

7:27 timothypratley: yes... one could quite easily define + as opperating on a collection of 1 or more elements

7:27 and vice versa

7:28 kotarak: I'm looking for a good example.

7:28 timothypratley: I think the rational would be that usually people use + with only 1 or two args

7:28 kotarak: Say struct: (struct foo :a :b :c) creates a new foo map with the given values.

7:28 Now you get [:a :b :c] from somewhere else.

7:29 Then you use apply: (apply struct foo the-vector)

7:30 Providing the values always in a collections, doesn't make sense, because the number is well-defined.

7:31 Something like that maybe? Would go along your argument about the "usual" call.

7:33 tWip: should an empty list be a seq?

7:33 (seq? ()) => false

7:33 timothypratley: Sounds reasonable :) Average is tricky because well you do want to take the average of 2 numbers sometimes... othertimes maybe you want to average a large set of data, its hard to say which is more likely... wouldn't it be great if both forms were supported??? but surely that is impossible (and confusing).

7:34 kotarak: tWip: I think the empty list is Collection not a Seq.

7:35 tWip: yes, but what is the reasoning behind that?

7:36 Chousuke: tWip: it's an empty list, so as a sequence, it's "nothing". I guess that's why it's not automatically a seq

7:36 you can do (seq ()) and get nil

7:36 kotarak: tWip: a collection is something specific, while a seq is an abstract view on a specific collection

7:38 tWip: easy to work around, I still feel it should be a seq

7:39 danlei: how to do this? (in a non-ugly way) have not looked at multimethods so far

7:39 (defn avg ([s] (/ (reduce + s) (count s))) ([x & args] (/ (+ x (reduce + args)) (inc (count args)))))

7:42 kotarak: (defn avg [x & args] (/ (reduce + x args) (inc (count args))))

7:42 ups

7:42 sorry. Forget it. Misread your function.

7:43 danlei: in cl, i'd specialize on list in the first case (first method of a generic function), a number in the second case. i guess, that could be done with multimethods. i'll have a look at them later.

7:44 Chousuke: tWip: you just need to remember (seq coll) whenever you work with sequences :)

7:46 Fib: Isn't it because () doesn't support (first) and (rest) and thus doesn't match the abstract interface of a sequence?

7:48 tWip: ok, I changed my usage to coll? and calling seq... it's no big deal, just seemed weird at first

7:53 timothypratley: danlei: that seems to work great :) thanks. why do you call it ugly?

7:54 danlei: because it is so ugly, that only a mother could love it =)

7:54 timothypratley: hahahah

7:54 danlei: but yes, it works

7:54 *chuckles

7:58 Lau_of_DK: danlei: I must say, you havent convinced me that a mother could actually love it :(

7:59 danlei: well, maybe a very benevolent one ;)

8:00 you know how to do it with multimethods? still hadn't the time to check them out

8:00 Lau_of_DK: oh youre right.. or maybe a blind one, who used to code a little Python way back when :)

8:00 danlei: =)

8:10 timothypratley: danlei: well if you think yours is ugly... wait till you get a load of this:

8:10 (defn avg [s & nots]

8:10 (if (seq? s)

8:10 (apply avg s)

8:10 (/ (reduce + s nots) (inc (count nots))))

8:10 then...

8:10 danlei: it's alive!

8:11 timothypratley: (defnaa avg [s] .....) => above

8:11 bottleneck: anyone know of a guide to a simple webserver

8:11 Lau_of_DK: bottleneck: To write one, or to use one?

8:11 bottleneck: write

8:11 MarkVolkmann: What is the function that expands a list so that each value can be used as a separated argument to a function?

8:12 bottleneck: jsut want to do a simple one to see hown they work

8:12 Lau_of_DK: bottleneck: I think I have a guide for a Jetty/clojure server in about 100 lines or so, want me to dig it up ?

8:12 bottleneck: yes please, would be awesome

8:12 tWip: added basic json support to webjure

8:12 blackdog_: bottleneck, http://robert.zubek.net/blog/2008/04/26/clojure-web-server/

8:13 Lau_of_DK: bottleneck: thats the one that blackdog_ posted

8:14 danlei: MarkVolkmann: you mean apply?

8:14 Lau_of_DK: tWip: I think somewhere along the way I got JQuery and Json mixed up. What does JSon specifically enable me to do ? I know its serilization, but when will I need it ?

8:14 blackdog_: your browser reads json natively

8:14 tWip: most likely when you call your servlets from javascript code using AJAX

8:14 blackdog_: it's a subset of javascript

8:15 jquery is a nice library that helps you select then appy actions to dom elements

8:15 tWip: and much much more

8:15 jquery has some very nice UI plugins

8:15 Lau_of_DK: JQuery is my weapon of choice, when I want to move formatting operations and such, away from the server and onto the client, as I see it

8:15 blackdog_: still a bit limited in the UI package

8:16 Lau_of_DK: Am I to take it, that JSon is the format in which I pass my data to JQuery ?

8:16 blackdog_: no official grid yet

8:16 yes

8:16 Lau_of_DK: k, thanks

8:16 blackdog_: there's a $.getJSON method

8:18 Lau_of_DK: It confused me a bit blackdog_ when you were explaining your servlet approach to me. You said "This way, I dont need Jetty", and then you sent me an example using Jetty =)

8:18 blackdog_: i don't need to, but i do, could be any server, jetty is very convenient

8:18 the point is the client is not tied to a jsp/asp or php

8:19 why tie yourself to a server framework when you can tempalte on the client?

8:20 Lau_of_DK: To get cool t-shirts from Microsoft?

8:21 bottleneck: Lau_of_DK: thanks!

8:24 Lau_of_DK: no probs

8:42 MarkVolkmann: Suppose foo is the list (1 2 3) and I want to pass the items in it as individual arguments to a function. What expands a list like that? (my-function (??? my-list))

8:43 rhickey: MarkVolkmann: (apply + foo)

8:43 danlei: (apply my-function my-list)

8:43 MarkVolkmann: Thanks!

8:44 danlei: wtf

8:44 why does cond return nil?

8:45 rhickey: danlei: tradition, a la one-branch if

8:45 danlei: hm

8:46 what should i use instead? nested ifs?

8:47 Chousuke: what kind of code?

8:47 rhickey: danlei: for what purpose? cond only returns nil if no condition matches

8:47 danlei: the cond kind of code

8:47 wait a sec

8:48 (cond [true 1]) -> nil

8:48 i'm used to cl: (cond (t 1)) 1

8:49 not a problem, just /very/ surprising to me

8:50 or do i miss something?

8:50 Chousuke: cond doesn't take a vector.

8:50 (cond true 1) -> 1

8:51 danlei: oh my

8:51 now, that's embarassing =)

8:51 thank you

8:56 MarkVolkmann: To get the metadata for a function, say str, I enter (meta #'str). What do the # and single-quote do in this context?

8:58 Chousuke: that returns var named by str

8:58 rhickey: MarkVolkmann: #' is a reader macro. When read, #'x reads as the form (var x)

9:00 MarkVolkmann: Thanks! I need to go read more about vars.

9:06 danlei: ok, now that i know about cond ... ;) how would i dispatch on type, i.e. if something is/are a number/numbers, or a collection?

9:06 i tried like this:

9:06 lisppaste8: danlei pasted "avg" at http://paste.lisp.org/display/70915

9:06 danlei: works. is that the way to do it?

9:07 (first multimethod so far)

9:08 ... at least, it's not as ugly, as the other one ;)

9:10 fanda: hello!

9:10 question about fn?

9:10 Lau_of_DK: Hey fanda

9:10 shoot

9:10 fanda: (def x 5) => #'user/x

9:10 (var x) => #'user/x

9:10 (fn? (var x)) => true

9:10 true or false?

9:11 duck1123: should be

9:11 fanda: why is var a function?

9:13 rhickey: fanda: why are all vars functions?

9:13 var is a special form

9:14 vars are functions because it is useful for them to be so - they all implement the IFn interface in terms of a call to their value, which must in turn be a fn

9:14 Lau_of_DK: Guys, simple question (I hope)

9:14 (defmacro onClick [obj & body] `(. ~obj addMouseListener (proxy [MouseListener] [] (~'mouseClicked [evt#] ~@body))))

9:15 Why does this not work in a JPanel which implements addMouseListener?

9:15 s/in/on

9:15 fanda: thanks rhickey! that makes sense. just double checking tests for Clojure predicates

9:17 rhickey: fanda: Imagine you had some global fn foo, if you passed foo to (hang-onto-this foo), you would be passing the current value of foo. If you later fixed foo, hang-onto-this wouldn't see the change. If instead you passed (hang-onto-this #'foo) then it would. In either case it could 'call' what it was passed

9:18 Lau_of_DK: I'm on a mission - no one should ask a macro question by posting only the source of the macro - please post an invocation and actual and/or expected expansions

9:19 and please paste

9:19 Lau_of_DK: Alright Rich Norris, I'll get right on it

9:22 rhickey: Chuck Norris doesn't say please

9:22 Chouser: I was thinking the other day of a "macro help request" form with separate sections for each.

9:23 rhickey: Chouser: great idea!

9:23 duck1123: is there an easy way to add metadata to a file? It's looking like we might need a way to store things about files (ie. filename, author, license) as clojure data

9:23 Lau_of_DK: Chouser: does Rich actually sponsor you ? :)

9:23 rhickey: duck1123: files are not first-class constructs in Clojure, but namespace metadata has been requested

9:24 lisppaste8: Lau_of_DK pasted "mouseListener" at http://paste.lisp.org/display/70916

9:25 mmcgrana: Hey Rich, very sorry about the clj-doc license issue, I'm working on it right now.

9:25 rhickey: mmcgrana: np

9:25 duck1123: that was why I bring it up

9:26 rhickey: mmcgrana: I'm sorry I didn't get to look at it sooner - very neat

9:26 duck1123: what if clj-doc indexes non-clojure core code, it'd have a different license

9:27 mmcgrana: rhickey: thanks

9:27 hopefully I'll have it set up on a proper server at a permanent URL for 1.0

9:28 duck1123: perhaps if i do the license notice per-function, like under the source code.

9:29 rhickey: Lau_of_DK: please try macroexpand-1 on your macro before pasting

9:29 Lau_of_DK: rhickey: macroexpand-1 is basically what you see in the bottom of the paste

9:29 duck1123: mmcgrana: have you thought any about using iframes? As much as I hate them, they make it easy to see code and function list seperately

9:30 rhickey: i.e. paste real code you have tried, rather than having others try for the first time

9:30 lisppaste8: Lau_of_DK annotated #70916 with "macroexpand-1" at http://paste.lisp.org/display/70916#1

9:30 rhickey: user=> (macroexpand-1 '(onclick panel (javax.swing.JOptionPane/showMessageDialog nil "Clicked")))

9:30 (onclick panel (javax.swing.JOptionPane/showMessageDialog nil "Clicked"))

9:31 Lau_of_DK: rhickey: Ive tried this code, and variations on it for quite some time

9:31 Your error is just because C is lowercase in on_C_lick

9:31 It was just meant as an example to understand what I was aiming for

9:32 mmcgrana: I was thinking something like this http://skitch.com/mmcgrana/hqgn/clj-doc-clojure-library-documentation.

9:33 Any ideas on how to disambiguate the text: i.e. what software its referring to exactly, which files, etc.

9:33 phil: Hey all. How do I create a new var without interning it?

9:34 Chouser: (doc with-local-vars)

9:34 clojurebot: varbinding=> symbol init-expr Executes the exprs in a context in which the symbols are bound to vars with per-thread bindings to the init-exprs. The symbols refer to the var objects themselves, and must be accessed with var-get and var-set

9:34 phil: Great, cheers.

9:35 rhickey: Lau_of_DK: and I wasted my time trying to get it to work, it's simple courtesy to make a decent try yourself first and paste only code you have run

9:36 Lau_of_DK: rhickey: Im sorry about the typo, but like I said, I've tried this code several times in several variations.

9:37 rhickey: mmcgrana: looks fine. I think you could 'attach' the notice to the corresponding code by putting it in the same box

9:38 mmcgrana: ok good idea

9:38 rhickey: mmcgrana: but in this case, the notice applies to the doc as well

9:39 mmcgrana: so what you have is fine

9:41 danlei: ok, another cl/clojure question: in cl, if a symbol is read, it gets interned in the package you're in. then it may e.g. be bound to a special (symbol-value slot). i have read that clojure differs here, and symbols don't get interned, but vars do, and that symbols are only names, or somehting. could someone just quickly name the main differences between symbols/vars in cl and clojure and the consequences?

9:42 phil: danlei: Symbols are interned in a namespace which is a mapping from those symbols to vars. Vars in turn are bound to other values.

9:42 danlei: so symbols /are/ interned, when they're read, like in cl?

9:42 but don't have a value-slot, but are ... "names"(?) for vars?

9:48 rhickey: phil: not quite, symbols are not interned in namespaces inherently

9:48 danlei: rhickey: does it boil down to "symbols are just names"?

9:48 rhickey: (identical? (symbol "foo") (symbol "foo"))

9:48 false

9:49 symbols are just names, but with faster equality than strings

9:49 danlei: ah, ok

9:50 rhickey: because symbols' names are interned strings

9:50 but the symbols themselves aren't interned, so they can support metadata

9:51 vars are much more like CL's symbols, but still not identical

9:52 danlei: if i do (resolve 'x), for example

9:52 rhickey: vars are (normally) interned in a namespace, are named by a symbol in that namespace, have root value bindings and can be thread-locally bound

9:52 danlei: i get a var back, if it's def'ed

9:53 rhickey: danlei: right, and that resolution happens at compile time, not read time - the reader reads symbols

9:54 danlei: rhickey: ok. i think it's clearer now

9:54 rhickey: but symbols can name other things, like classes, too

9:54 user=> (resolve 'String)

9:54 java.lang.String

9:55 danlei: ok

9:56 and i can't resolve that symbol, because resolve works on vars, and the argument to resolve would be the symbol which names it, right?

9:56 (which names the var)

10:02 ah, ok. i actually /can/ resolve it, since returns the var /or/ class.

10:09 mmcgrana: new docs w/ license notice are uploaded: http://clj-doc.s3.amazonaws.com/tmp/doc-1116/index.html

10:09 MarkVolkmann: I recently ran across function definitions like this. (defn- -foo ...) I understand that defines a non-public function. Is the fact that the name of the function starts with a dash a convention for private functions or a requirement?

10:10 kotarak: -foo is a method for the class defined by the namespace.

10:10 defn- says it's private.

10:10 as a clojure function, I mean.

10:11 MarkVolkmann: It looks like I don't have to start the number of the function with a dash though. It must be a convention to do so.

10:12 kotarak: ?? "number of the function"?

10:15 Lau_of_DK: kotarak: I think he means "name of the function"

10:15 We just have to hope Rich doesnt catch him makings typos like that, you know how he gets :)

10:16 kotarak: Oh. If I remember correctly, for the new AOT gen-class one has to start the method names with a dash. For private function this is not necessary.

10:17 rhickey: mmcgrana: sorry, I missed the lack of copyright notice - text should start with: Copyright (c) Rich Hickey. All rights reserved.

10:17 MarkVolkmann: Right, I meant name, not number.

10:18 mmcgrana: ok np

10:18 rhickey: MarkVolkmann: right -name is the name to which an AOT generated class method will be bound

10:19 MarkVolkmann: If I change the default namespace using (ns my-ns), is there an easier way to pop back to the previous default namespace than something like (ns user)?

10:20 Lau_of_DK: rhickey: Are you the one who updates ants.clj when something new happend to Clojure?

10:20 rhickey: MarkVolkmann: you should only use ns for namespace definition, use in-ns to change namespaces, and no, there isn't 'back' function for namespaces

10:20 Lau_of_DK: yes

10:21 Lau_of_DK: rhickey: I didnt really understand the latest change where (send-off *agent* self) becomes (send-off *agent* #'self). Can you explain that for me?

10:22 MarkVolkmann: I tried defining a private function with a name that didn't start with a dash and it worked as expected. I couldn't use the function from another namespace. That's why it seems to me that starting the function name with a dash is just a convention.

10:22 kotarak: MarkVolkmann: a name with a dash has nothing to do with private functions.

10:22 rhickey: MarkVolkmann: name starting with dash is completely unrelated to defn- and private

10:23 kotarak: defn- defines a private function.

10:23 defn -foo defines the method foo for some class

10:23 (.foo x) translates to the function -foo

10:24 MarkVolkmann: Is (defn -foo) a way to add a method to an existing Java class?

10:24 How does it know which class I want to add to?

10:25 kotarak: MarkVolkmann: no monkey patching here, you have to derive (ns my.fancy.Class (:gen-class :extends this.other.Class) (defn -methodToOverride ....))

10:25 rhickey: MarkVolkmann: With AOT compilation, each namespace becomes a class. You can declare with a :gen-class clause in ns the superclass and interfaces that class extends/implements

10:26 then define the overidden or declared methods by defn-ing -methodName functions

10:26 mmcgrana: rhickey: like this? http://skitch.com/mmcgrana/hqe8/clj-doc-clojure-library-documentation

10:26 rhickey: as kotarak said, no monkeypatching

10:27 mmcgrana: great, thanks

10:29 MarkVolkmann: It's tough to tell from the documentation why I should prefer (in-ns my-ns) over (ns my-ns) when I just want to change the default namespace. The both say they create it if it doesn't exist.

10:30 mmcgrana: rhickey: np, thanks for your help

10:30 danlei: MarkVolkmann: i think, ns is more to create a namespace, e.g. at the top of your file, while in-ns is more for changing the current ns, creating it being just a convenience

10:31 rhickey: danlei: right, I think the point is it's not clear

10:31 I'm thinking of renaming ns to defnamespace

10:32 danlei: maybe defns? but that would probably be to close to defn

10:32 MarkVolkmann: I'd suggest defns to keep it similar in length to other functions and using "ns" like other functions.

10:32 rhickey: danlei: we've discussed defns before, looks like plural defn

10:33 I'd be fine with it, but that's the objection

10:33 kotarak: Oh please. Not the defns/defnamespace whatever disscusion. rhickey, please use simply defnamespace it's clear and one doesn't type it too often...

10:33 mmcgrana: is it bad style to use ns multiple times for the same namespace? For example, if the ns is defined over several files and there are java imports for each of the different files?

10:34 rhickey: kotarak: right, the other advantage is it is long, so less likely a target for use in repl

10:34 MarkVolkmann: Maybe def-ns.

10:34 danlei: well, i think, whatever it'll be named like, a "def" in front of it would be a good idea

10:34 rhickey: mmcgrana: yes, that's bad, use ns once in the file named for the namespace and in-ns in the others

10:35 mmcgrana: because you don't actually get per-file imports anyway

10:35 mmcgrana: ok

10:35 rhickey: import imports into namespace

10:35 mmcgrana: right, i just meant to declare the import close to where they are used, so that its easier to know when I need to add/remove imports.

10:36 but all the imports should just actually be declared at the one spot (ns is used for a namespace?

10:37 rhickey: mmcgrana: yes, so it documents the sources of names in the namespace, else one file will presume it can use a name another introduces in an import

10:38 danlei: btw. is there a way to un- use/refer a package?

10:38 aehm

10:38 namespace ;)

10:39 mmcgrana: ok

10:39 Lau_of_DK: rhickey: Did you catch my last question?

10:39 rhickey: use/refer isn't a link, it pulls current vars in. There is ns-unmap

10:39 Lau_of_DK: you can ignore the #', it doesn't matter anymore

10:40 Lau_of_DK: k, thx

10:40 danlei: rhickey: yes, i meant something like ns-unap for everything i refer'ed from another ns

10:40 *unmap

10:40 rhickey: danlei: not yet

10:40 danlei: rhickey: ok, thanks

10:44 Lau_of_DK: user> tst

10:44 [{:b 4, :a 1} {:b 5, :a 2} {:b 6, :a 3}]

10:45 If I want to grab the entry where b = 5. How do I do that idiomatically? (word?)

10:45 bottleneck: i have 2 maps with {word: count} pairs, i want to merge them. some words occur in both and then i want to do word: count1 / (count1 + count2)

10:46 rhickey: (doc merge-with)

10:46 clojurebot: Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping(s) from the latter (left-to-right) will be combined with the mapping in the result by calling (f val-in-result val-in-latter).

10:46 bottleneck: so 4 / (4+0) or 7 / (7+12)

10:47 rhickey: hmmm, clojurebot should do the arglists as well

10:48 bottleneck: merge-with takes a function that will be used to combine entries

10:48 bottleneck: ah nice

10:48 how do i force float-division?

10:49 rhickey: bottleneck: use floats

10:49 or cast with (float ...)

10:49 or (double ...)

10:50 Lau_of_DK: Anybody got a take on that?

10:50 bottleneck: (defn assoc-inc [m k v]

10:50 (if (contains? m k)

10:50 (assoc m k (+ v (get m k)))

10:50 (assoc m k v)))

10:50 rhickey: Lau_of_DK: filter

10:51 bottleneck: is there a built-in way fo doing that?

10:51 (assoc-inc {1 2 3 4} 1 3) -> {1 5 3 4}

10:51 Lau_of_DK: thanks rhickey

10:52 rhickey: (assoc m k (+ (m k 0) v))

10:52 gets rid of the if

10:54 more generally, you'd want assoc-with a la merge-with

10:54 bottleneck: i dont get it

10:54 rhickey: bottleneck: (m k 0) == (get m k 0), that extra arg at end is default return if not found

10:56 bottleneck: ok

10:57 danlei: is there a way (without use of regexes) to get the namespace of a symbol out of the return value of resolve? like: (symbol-ns (resolve 'sym)) -> my-ns

10:58 mmcgrana: its in the metadata

10:58 (:ns ^#'filter)

10:59 danlei: ah, ok

10:59 mmcgrana: thanks

10:59 mmcgrana: or: (:ns (meta (resolve 'filter)))

10:59 np

11:02 notallama: this is weird. i made a prime number function, and it gets up to 46337 and then says "java.lang.RuntimeException: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long (NO_SOURCE_FILE:0)"

11:03 < and > don't work with longs?

11:03 or =?

11:05 bottleneck: rhickey: can i merge-with with default?

11:05 (merge-with #(/ (float %1) (+ %1 %2)) {"you" 10 "are" 5 "sick" 1} {"you" 2 "no" 12})

11:05 {"no" 12, "are" 5, "sick" 1, "you" 0.8333333}

11:06 i want then for sick to be 1 / (1+0) -> 1

11:06 which it ebcome sby luck

11:06 wait

11:06 "are" should be 1 instead if 5 in the emrged map

11:30 danlei: ok, first try for unrefer. not really tested, but seems to work:

11:30 lisppaste8: danlei pasted "unrefer" at http://paste.lisp.org/display/70917

11:32 danlei: maybe i should take the ns as an argument too, but then, its more for interactive use

11:56 AWizzArd: How can one compile .clj files? Something like (compile-file ...)

11:59 bottleneck: if i want to map over a hash-map, is (for [x Map]...) the onyl way, ic ant use map?

11:59 Chousuke: (map fn (vals yourmap))

12:00 rhickey: bottleneck: you can use map, the mapping function will be passed map entries, which you can destructure with [k v] or use (key e) (val e)

12:00 AWizzArd: (map #(println %) {:a 10 :b 20})

12:01 rhickey: AWizzArd: map with side effects is not a good example

12:01 AWizzArd: it just produces a very strange result for me

12:01 Chousuke: works for me, in the repl

12:01 AWizzArd: it produces ([:b 20]\nnil [:a 10]\n nil) where \n is a newline

12:02 Chousuke: AWizzArd: that's just the repl not being quite synchronised

12:02 rhickey: map is a function, it returns a sequence of the return values, which for println are nil

12:02 AWizzArd: I am using the newest clojure.jar and also just checked out a fresh swank-cloujre

12:02 Chousuke: the return value is (nil nil) but it prints the vectors too

12:02 rhickey: if you care about the returns fine, if you just want side effects use doseq

12:02 AWizzArd: rhickey: sure.. but it should produce a different result

12:03 Chousuke: AWizzArd: it produces the correct result

12:03 AWizzArd: it just prints weird.

12:03 AWizzArd: if you want to foce it to print correctly, you need to use doall

12:03 AWizzArd: I will post a screenshot, one sec

12:03 Chousuke: force*

12:04 rhickey: it doesn't print weird, you've mapped a function with side effects, it returns a lazy seq and those effects are delayed

12:04 AWizzArd: we know what you are seeing

12:05 Chousuke: AWizzArd: whenever you use a 'map with side-effects, you must remember to use 'doall or 'dorun. otherwise the results may be not what you want

12:05 lisppaste8: danlei annotated #70917 with "takes ns as argument, too" at http://paste.lisp.org/display/70917#1

12:05 rhickey: map is lazy, so the values aren't produced until needed, they are needed to print the result in the repl, thus the interleave of print result val, side-effect, print result, side-effect

12:06 AWizzArd: so this problem is maybe in emacs, displaying it in a wrong color?

12:07 rhickey: bottleneck: (map (fn [[k v]] [v k]) {:a 1 :b 2 :c 3})

12:07 ([2 :b] [3 :c] [1 :a])

12:08 AWizzArd: How can one compile .clj files? Something like (compile-file ...)

12:08 rhickey: user=> (map val {:a 1 :b 2 :c 3}) ;same as vals

12:08 (2 3 1)

12:08 AWizzArd: you can compile namespaces with (compile 'my.ns.lib)

12:09 the class files will be put in *compile-path*, and both the source root and *compile-path* must be in the classpath

12:09 AWizzArd: oki thx

12:11 danlei: does anybody see anything suspicious in unrefer? if not, i'll add it to my toolbox

12:15 rhickey: danlei: a few things, first, you are getting map entries which you should treat as such - first and frest are suspect, use key/val etc. Second, you should do find-ns once in a let

12:17 danlei: rhickey: ok, thanks. i understand the key/val issue, but why should i do find-ns in a let, if it's called only once?

12:19 rhickey: danlei: it's not called only once, but every step of the filter

12:19 danlei: rhickey: ah, stupid me. sure

12:20 notallama: i posted about my prime number sieve problem. i found the issue, but it turns out that sorted-set doesn't make a nice priority queue due to lack of custom comparator. any ideas for a way around this?

12:25 lisppaste8: danlei annotated #70917 with "destupidized version" at http://paste.lisp.org/display/70917#2

12:25 bottleneck pasted "merge-maps problem" at http://paste.lisp.org/display/70919

12:25 bottleneck: ^^ why does it return {}, i suppose im not handling let correctly

12:27 (defstruct word :ham :spam)

12:28 rhickey: bottleneck: how about a doc string? - would help us know what the function is trying to do

12:29 danlei: you need to lift find-ns, not ns-map/mappings, which only happens once

12:30 danlei: rhickey: wtf ... i think i need some sleep. thanks

12:33 lisppaste8: bottleneck annotated #70919 with "example" at http://paste.lisp.org/display/70919#1

12:33 AWizzArd: http://clojure.googlegroups.com/web/http-client.clj makes use of gen-and-load-class. I think this exists no longer. Is genclass the new replacement?

12:34 gen-class

12:34 rhickey: bottleneck: did you look at merge-with?

12:34 lisppaste8: bottle annotated #70919 with "asa" at http://paste.lisp.org/display/70919#2

12:34 bottleneck: merge-with: yes but i didnt get how to handle the caes where one isnt in the other

12:36 lisppaste8: bottle annotated #70919 with "dsdsd" at http://paste.lisp.org/display/70919#3

12:36 rhickey: bottleneck: you have to remember that the data structures are immutable, and that map/assoc etc return new values that you have to keep track of, they don't work by side effects

12:37 lisppaste8: danlei annotated #70917 with "schwere geburt" at http://paste.lisp.org/display/70917#3

12:37 danlei: i think i'll get some coffee ... start feeling stupid :) thanks for the tips

12:38 bottleneck: so reduce instead of map

12:41 hiredman: AWizzArd: it uses gen and load for ssl stuff

12:42 I would recommend grabbing xlightweb and driving that with clojure

12:42 AWizzArd: oh oki, never heard of that before. Let me see...

12:43 Btw, is there a java tool that allows me to operate firefox? I would like to do some automatic testing of a website, and it would cool to have something as close to a real browser as it can get.

12:43 hiredman: someone else here recommended it to me

12:44 AWizzArd: With running JavaScript and such

12:47 lisppaste8: asasa annotated #70919 with "dsfd" at http://paste.lisp.org/display/70919#4

12:47 bottleneck: rhickey ^^

12:55 Chouser: ah, shoot. paste.lisp.org actually does do a little something with its captcha.

12:57 Aisling: 9

12:58 dthomas: Chouser: Thanks for printStackTrace last night, BTW. Didn't really solve my most hated problem, which is stack traces when working in SLIME being light on details, but it got me past the exception I was working on at the time.

13:00 danlei: omg ... another creation, only a mother could love. any ideas why my donut is so ugly?

13:00 lisppaste8: danlei pasted "ugly donut" at http://paste.lisp.org/display/70920

13:02 dthomas: Side SLIME/swank-clojure question: is slime-eval-defun supposed to eval in the NS appropriate NS for that point in the buffer? If my REPL is in "user" but the buffer starts with (ns some.package), eval-defun fails because (I'm guessing) it tries the defun in "user" (the REPL's NS).

13:04 Chousuke: dthomas: I think that's intended behaviour.

13:05 there is only one instance of clojure after all.

13:05 dthomas: Yeah, I seem to recall it worked this way when using SLIME with, say, SBCL.

13:05 Does slime-eval-defun (C-M-x) eval in the correct Clojure namespace for others?

13:06 Actually, I just realized that if I change the slime-repl's namespace to my.namespace first, it doesn't help: it still can't find some of the Java classes I've imported.

13:07 Chousuke: the repl namespace should be the same as in your other buffers, as long as you've evaled the ns setup expressions :/

13:07 Lau_of_DK: Good evening gents!

13:08 danlei: here is the page, i transcribed it from, no idea why mine looks so ugly: http://www.zetcode.com/tutorials/javagamestutorial/basics/

13:09 Chousuke: dthomas: at least for me, evaling import statements in a buffer also makes them available in the repl.

13:10 dthomas: Chousuke: I can eval the whole buffer, (ns) form included, and it works fine. I can see the NS in the REPL, just as it should be.

13:11 Chousuke: But trying to evaluate with slime-eval-defun then fails to find classes that are imported in that NS, which makes me think it's evaluating in a different namespace than the one in the (ns) form at the top of the buffer.

13:11 * dthomas looks at swank-clojure some.

13:12 bottleneck: http://paste.lisp.org/display/70919#4

13:12 noone can help

13:13 iff reduceing over a map cant i use when?

13:13 i have to use if-else

13:13 if i have a cond

13:13 ?

13:13 Lau_of_DK: rhickey: I was wondering about the STM. As I recall you once made the argument, that locking gives terrible performance. What the difference between user locks, and the STM locks, dont they drag down performance as well ?

13:15 bottleneck: yes now it works

13:17 so this ia annoying

13:17 rhickey: Lau_of_DK: I never said locking gives poor performance, I may have said coarse-grained locks do

13:17 bottleneck: then i have to filter out afterwards

13:17 Lau_of_DK: rhickey: right, that might actually have been it

13:27 danlei: i'm googling for a java lib that lets me display notes, nothing fancy, i only just one system which i can put notes on. any tips?

13:28 *only need

13:29 (by notes, i mean musical notation)

13:30 Lau_of_DK: http://www.softsynth.com/links/java_music.html

13:31 danlei: Lau_of_DK: thanks, already plowing through ;)

13:34 Lau_of_DK: they all look kinda overkill to me ...

13:35 lisppaste8: Lau_of_DK pasted "Refs vs. Agents!" at http://paste.lisp.org/display/70921

13:36 Lau_of_DK: Could somebody please lend a hand with this. I think I might be misunderstand send-off. Youre supposed to identify a single pixel in the swarm my its id, so (get-pixel 1) returns the first with :id 1.

13:36 So my idea was, that the agents state, would simply be this id.

13:36 But something is not working, since they get corrupted after the first cycle

13:37 Chouser: every action you send to the agent needs to return their new state

13:37 if you don't want the state to change, you need to return the old state

13:37 dthomas: OK, nevermind my SLIME problems, it seems that CVS SLIME within the past couple weeks must have fixed my problem.

13:38 Lau_of_DK: Which I believe the last 'a' in (behave) accomplishes, right Chouser?

13:40 danlei: ah, abc4j looks interesting

13:41 Chouser: Lau_of_DK: oh, sorry, didn't notice the paste. Did you try to list the errors the agent has?

13:42 Lau_of_DK: The error is "Agent has errors NO SOURCE"

13:42 Can I get more than that?

13:44 Got it working Chouser

13:45 I couldnt get a more precise error, but I could strip the body, and rebuild it bit by bit

13:45 the @ can be a bit confusing when nested

13:57 powr-toc: hey

13:57 Lau_of_DK: yo

13:57 powr-toc: Is there a reason why (+) returns 0 but (*) returns 1?

13:57 notallama: they return the identity.

13:58 kotarak: because 0 is the neutral element for +, and 1 for *

13:58 powr-toc: ahh, makes sense

14:00 thearthur: can i get a functions name?

14:00 if somone passes a fun can i print its name?

14:01 kotarak: thearthur: functions don't have names.

14:01 (fn [] :xxx)

14:01 No name.

14:02 thearthur: some of them do

14:02 if they where defined with defn no?

14:02 kotarak: No. There are names refering to functions. But the functions itself doesn't have a name.

14:05 powr-toc: Where is the doc function defined?

14:06 kotarak: powr-toc: in clojure.core namespace

14:06 powr-toc: src/clj/clojure/core.clj

14:06 powr-toc: I have it in boot.clj

14:06 kotarak: Ok. That's all possible for pre rev1094 version.

14:07 With revision 1094, the file was renamed.

14:09 powr-toc: ahh

14:09 Is there any idea on how long until 1.0 is expected?

14:13 Lau_of_DK: Is there anyway of testing the effectiveness of the STM in a given program of mine? Can the Javaprofilers help et?

14:13 etc?

14:24 AWizzArd: How can one load/make use of downloaded .jar files?

14:25 lisppaste8: bottleneck pasted "bayesian spamfilter" at http://paste.lisp.org/display/70929

14:26 kotarak: AWizzArd: download .jar; export CLASSPATH=$CLASSPATH:file.jar; have fun :)

14:26 bottleneck: ^^ 4 functions to make a spamfilter, nice! however im sure i can make it more elegant, merge-maps should be a lot shorter and clearer

14:27 danlei: AWizzArd: you can check your classpath from the repl with: (System/getProperty "java.class.path")

14:27 AWizzArd: ah gut

14:27 danlei: keine ursache

14:31 bottleneck: ja bitte und guten tag

14:32 no opinions ony my spamfilter?

14:33 AWizzArd: I can add anything to the environment variable CLASSPATH under Windows Vista, this (System/getProperty "java.class.path") always returns "clojure.jar". That does not sound right, right?

14:35 danlei: AWizzArd: for me it's: "/home/danlei/build/clojure/trunk/target/clojure-lang-1.0-SNAPSHOT.jar:/home/danlei..."

14:36 Lau_of_DK: Can somebody tell me how this is done in these terrible AOT times: http://rpdillon.googlepages.com/creatingexecutablejarswithclojure

14:36 danlei: AWizzArd: i've heard, that the classpath environ variable is not used, when a classpath is given via -cp, but i'm not sure about it. try adding it with (add-classpath "file:///C:/path/to/file.jar")

14:37 AWizzArd: if you're running slime, add the path to swank-clojure-extra-classpaths

14:41 lisppaste8: kotarak pasted "rescue for Lau" at http://paste.lisp.org/display/70930

14:42 Lau_of_DK: uuuuh

14:42 Thanks alot Mr. Kota - You saved the day

14:42 kotarak: Lau_of_DK: np :)

14:48 Lau_of_DK: but Mr. Kota..

14:48 This effectively means, that I must rename ALL my functions to my namespace :|

14:50 kotarak: ?? Do you mean the new -form?

14:50 Lau_of_DK: oh...

14:50 I started with (ns 'lbj.core.Langdon)

14:51 kotarak: without ': (ns lbj.core.Langdon)

14:51 Lau_of_DK: so I figured everything must be (defn lbj.core.Langdon-func)

14:51 yea

14:51 mistake

14:51 kotarak: No. In this namespace simply (defn -foo ..) (defn -bar ...)

14:51 Lau_of_DK: k

14:51 kotarak: The Classname is not needed anymore.

14:56 Lau_of_DK: So basically, every single variable, function, constant, whatever, in every single problem I write, must be prefixed with -, for the reader to understand that its in the same ns ?

14:56 kotarak: No.

14:57 -foo in namespace foo.bar.Baz is the method foo of class foo.bar.Baz as in (.foo (new foo.bar.Baz))

14:58 bottleneck: 1. is there some database stuff shipping with Clojure or what is the easiest way to set up and use a database? 2. is there a lib that lets me start mp3s ?

15:01 Lau_of_DK: kotarak: thats basically the same thing

15:02 everything in that namespace must be prefixed with -

15:02 kotarak: If everything is a method then yes. "Normal" functions, don't have to be prefixed.

15:02 albino: bottleneck: use JDBC and do the java thing as far as databases are concerned

15:03 kotarak: (ns foo.bar.Baz (:gen-class ...)) (defn bar [x] (+ x 2)) (defn -foo [a-number] (bar a-number))

15:03 Lau_of_DK: kotarak: Explain the difference between method and function please

15:04 kotarak: A method is part of the class as in (.methodName clase-instance). A function is a "normal" Clojure function.

15:04 s/clase/class/

15:04 Lau_of_DK: k

15:07 notallama: are methods java mathods? like, if i compile with a fn called -bar, can i go into java, import it, and say "foo.bar()"?

15:08 kotarak: notallama: you have to declare a class with :gen-class. There you can specify, that your class has a method bar and then you can basically do that. Yes.

15:11 notallama: awesome. i'm going to have to figure out how this works.

15:11 kotarak: (doc require)

15:11 clojurebot: Loads libs, skipping any that are already loaded. Each argument is either a libspec that identifies a lib, a prefix list that identifies multiple libs whose names share a common prefix, or a flag that modifies how all the identified libs are loaded. Use :require in the ns macro in preference to calling this directly. Libs A 'lib' is a named set of resources in classpath whose contents define a library of

15:12 kotarak: upsala.

15:12 notallama: you might be interested in [doc gen-class] with (). (Don't what clojurebot does. It's a bit long...)

15:15 lisppaste8: Chouser pasted "my test macro" at http://paste.lisp.org/display/70931

15:16 Chouser: clojurebot: macro help is http://clojure-log.n01se.net/macro.html

15:16 clojurebot: Ack. Ack.

15:16 Chouser: clojurebot: macro help?

15:16 clojurebot: macro help is http://clojure-log.n01se.net/macro.html

15:18 kotarak: Chouser: *thumbs up*

15:19 rhickey: Chouser: awesome!

15:20 Chouser: cheap hack, actually, but anyway...

15:20 you have to fill out the captcha *after* you submit the form -- an extra step.

15:21 kotarak: Chouser: the right way: poka-yoke

15:23 Chouser: :-)

15:29 bottleneck: 1. is there some database stuff shipping with Clojure or what is the easiest way to set up and use a database? 2. is there a lib that lets me start mp3s ?

15:30 Chouser: 1. Java comes with JDBC. There is also clojure.contrib.sql

15:30 2. I think Java comes with audio playback libs.

15:35 bottleneck: jdbc? i want something that abstracts away all the annoying sql syntax

15:35 like: insert stuff table row col

15:35 and not allt hat extra shite

15:37 Chouser: bottleneck: ah, yes, that would be nice. The idea has come up, but I'm not aware of any implementation.

15:39 kotarak: There is schemeql, but I don't know, whether it's easy to port and whether it is worth the trouble..

15:42 Chouser: I'd love to see something like (select my-col from my-table where id-col = ~id) -> [{:my-col "foo1"} {:my-col "foo2"}]

15:42 bottleneck: hmm link?i might cuz it looks like im going with clojure

15:42 Chouser: but I haven't thought it through much.

15:42 kotarak: Chouser: schemeql is something in this way.

15:43 But I never used it and don't know it state.

15:48 Chouser: SchemeQL link: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=

15:52 looks about right to me

15:58 jgracin: I never found any sources of SchemeQL

15:58 source code, I mean

15:59 Lau_of_DK: Chouser: how do I test the effeciency of the STM in any program of mine?

16:02 Chouser: effeciency? If you mean overall performance, I suppose you would create something that puts your program under realistic or extreme load, and measure how it performs.

16:06 Lau_of_DK: I mean, how many transaction had to be retried, average re-try rate. That type of thing.

16:10 Chouser: oh! There's no "standard" way yet, as far as I know.

16:10 Perhaps you could add a logging call to the dosync macro and collect stats that way.

16:12 bottleneck: why does both succeeding imports and failing ones return nil?

16:13 powr-toc: Lau_of_DK: There's a nice low ceremony java ORM for JDBC, called ActiveObjects... It's OO, so it's not the functional wrapper you're looking for, and I have no idea how it'd translate into clojure; but it might be worth a look as a last resort


16:13 dthomas: bottleneck: What is a failing import?

16:14 bottleneck: When I try to (import) something that doesn't exist I get a ClassNotFoundException.

16:15 bottleneck: (import '(java.jdbc))

16:15 nil

16:15 (import '(java.jdbcsdcscc))

16:15 nil

16:16 dthomas: bottleneck: Ah, OK.

16:16 cooldude127: bottleneck: you can't just import a whole package in clojure i think

16:17 dthomas: I suspect you don't need to import a package when you use a fully-qualified name.

16:17 cooldude127: correct

16:19 dthomas: I wonder if Java even offers a way to introspect a "namespace" (or "package" or whatever they'd like to call java.sql).

16:19 bottleneck: so hiw do i do?

16:20 dthomas: I guess that's java.lang.Package. I see Package/getPackage itself returns null instead of raising an exception when given a bogus package name.

16:21 bottleneck: What are you trying to accomplish? If you want to use things in java.sql by their fully qualified name you can just use them. E.g. java.sql.DriverManager.

16:22 AWizzArd: When I do (System/getProperty "java.class.path") I get back "c:/Users/ath/clojure/clojure.jar" under Windows Vista. Now I say (add-classpath "file:///Users/ath/clojure/libs/xLightweb/xlightweb-2.2.1-jar-with-dependencies.jar") and it returns nil. But when I check the classpath again via (System/getProperty "java.class.path") nothing has changed. Is that normal? Doesn't this get updated?

16:25 dthomas: AWizzArd: I observe the same behavior here. My guess is that java.class.path is set at JVM bootstrap time and from then on it's just the ClassLoader using that path.

16:26 Er, that is, I'm betting the ClassLoader reads that property when it's constructed, and further modifications to it are ignored.

16:26 I note that when I (add-classpath) something, I can't (import) it but I can refer to classes from that JAR.

16:26 AWizzArd: how do you refer to them?

16:28 dthomas: AWizzArd: Fully qualified name. Like I just loaded a JAR and then tried just "org.w3c.util.URLUtils" in the REPL

16:32 Lau_of_DK: So Im reading through the ClojureGroup, and suddenly there are entire posts in French... w00t?

16:33 kotarak: Yeah, instead of discussing in english whether the language matters, they do it in french, excluding external opinions.

16:34 Lau_of_DK: Cant we add a filter for french? My mind has one built in :)

16:53 danlei: is there a way to make the prompt show only the last part of the ns? foo.bar.baaz.quux> -> quux>

16:53 s/./-/g

16:55 AWizzArd: danlei: you would have to supply your own repl

16:55 the p part prints the full ns thing (default)

16:55 your print would not

16:56 danlei: AWizzArd: ok, thanks, AWizzArd

16:56 arohner: If you look at Repl.java, the prompt is hard coded

16:56 it would be pretty simple to replace that with a var that points at a fun

16:56 danlei: yes, that shouldn't be hard. just wanted to know, if there's a standard way to tweak it

16:59 AWizzArd: in Common Lisp you "program" your own Lisp interpreter by saying: (loop (print (eval (read))))

17:00 that will not give any output prompt.. but into this structure you could put your own prompt

17:00 arohner: the musings on the google group about rewriting the repl in clojure look interesting

17:01 danlei: i should start reading the group more regularly

17:01 Lau_of_DK: I second that

17:01 AWizzArd: you can simply build your own repl on top of the existing one

17:01 in this meta repl you can do whatever you want

17:02 danlei: i understand

17:12 flaskan: dthomas:ok, im new to databases, how do i create database? is their one coming with java or i have to download postgresql or mysql separately and install?

17:12 Chouser: So far I've written a Clojure REPL in Clojure for the browser and for Swing. Someone else wrote one in Clojure for Qt.

17:13 dthomas: flaskan: AFAIK J2SE JDK doesn't come with any databases, so you'll probably need to have a database and then the JDBC driver for it.

17:13 kotarak: I use a Clojure Repl for Gorilla. But heavily modified in many ugly ways to sync with Vim.

17:16 Chousuke: flaskan: if you want an easy way to make a simple database, you could try sqlite

17:17 it doesn't require any complex server setups so it should be good for experimentation :)

17:17 tWip: I think JDK6 comes with derby

17:19 http://java.sun.com/developer/technicalArticles/J2SE/Desktop/javase6/beta2.html

17:19 dthomas: flaskan: I second Chousuke's recommendation pretty much. I just compiled http://www.xerial.org/trac/Xerial/wiki/SQLiteJDBC the other day.

17:19 tWip: under database... but don't use it for production :)

17:20 dthomas: I'm actually kind of scared by the number of pure Java SQL databases available with a quick web search.

17:22 Never really looked at Derby, looks kind of nice. It seems to support foreign keys, which I sometimes miss in SQLite. Also supports multiple connections to the DB from within the same JVM, which I was having problems with in conjunction with the above SQLite JDBC driver.

17:22 tWip: yeah, I think bundling derby pretty much solved the testing of jdbc apps

17:23 no need for sqlite

17:52 flaskan: Chousuke: how do i connect it to my program?

17:57 Chousuke: flaskan: that shouldn't be too difficult with JDBC. I'm sure you'll find examples if you do some googling.

17:58 flaskan: tWip: how do i access derby from clojure? is the database itself there too so i dont need to install anything?

17:58 i cant even understand how do they made java so complicated.

17:58 blackdog_: flaskan, have a look in contrib.sql

17:58 in tests there is an example

18:07 flaskan: i see

18:07 i have contrib in C:/clojure_20080916/clojure-contrib

18:07 but i never got how to install it so i cant use it

18:08 arohner: flaskan: source or jar?

18:27 flaskan: source

18:33 where is that link to setup slime?

18:33 http://github.com/jochu/swank-clojure/tree/master/swank-clojure.el

18:33 is that enough?

18:37 hiredman: clojurebot: (* 34 23)

18:37 clojurebot: I don't understand.

18:37 hiredman: damn you

18:37 (* 34 23)

18:37 clojurebot: 782

18:41 danlei: (+ 1 2)

18:41 clojurebot: 3

18:41 danlei: (prn 'hello)

18:41 nice

18:42 flaskan: (pr "clojurebot is a donkey")

18:43 (eval '(+ 1 2))

18:43 arohner: is there a way to make swank pretty print a macroexpand?

18:43 danlei: clojurebot: clojurebot?

18:43 clojurebot: clojurebot is self referential

18:44 hiredman: just math right now

18:46 and only simply stuff, no nested expr

18:47 danlei: is there a function that: (?? [a b c d]) -> [b c d a] -> [c d a b]

18:47 "rotates"

18:48 flaskan: (+ 3 4)

18:48 clojurebot: 7

18:48 Chouser: clojure.contrib.lazy-seqs/rotations

18:48 flaskan: (- clojurebot life)

18:49 danlei: Chouser: great thanks

18:49 flaskan: chouser: cool

18:49 i want to setup SLIME for windows, can someone post a link?

18:49 Chouser: (apply + 1 2 3)

18:49 flaskan: i think remember seeing one

18:49 Chouser: (+ 1 2 3)

18:49 clojurebot: 6

18:49 flaskan: or how do i do it?

18:50 danlei: flaskan: i remember some podcast, but maybe that was for os x

18:50 flaskan: but slime is just a bunch of el-files right?

18:50 so i need to what, run it with clojure as inferior-lisp?

18:51 danlei: well, you'd need swank-clorure and stuff, it's described on the wiki

19:00 hm, i think i'm a little confused ... what does (require 'foo.bar) (refer 'foo-bar) become in ns?

19:00 dthomas: I'm a bit surprised that 0 is apparently true. Is this right?

19:01 rhickey: danlei: use

19:02 dthomas: 0 is not nothing (nil), nor false

19:02 flaskan: rhickey: on homepage, Slow/no innovation post standardization, slow as in slow execution speed? sbcl is superfast...

19:02 powr-toc: does anyone know in which java files the built-ins are defined (e.g. if, let etc...)

19:02 rhickey: flaskan: slow innovation, not execution :)

19:03 flaskan: ah yes i read like a donkey

19:03 rhickey: powr-toc: clojure.lang.Compiler

19:03 danlei: rhickey: ok, (:use (foo.bar) (baz.quux)) seems to work. is that correct (the parens)

19:04 powr-toc: rhickey: thanks... was looking in there, but somehow skipped past them.

19:05 danlei: nice, works

19:07 dthomas: rhickey: OK, I guess I see where that's documented both in the section on the reader and the "Differences with Lisps" page. Thanks.

19:08 rhickey: dthomas: 0 is true in Common Lisp too

19:09 dthomas: rhickey: Huh, so I just tested. That's kind of embarassing that I didn't know that.

19:09 (And now immortalized in IRC logs.)

19:11 Too bad in this case, since I wanted to do (or (compare a b) (compare c d)).

19:16 flaskan: clojure-lang-1.0-SNAPSHOT.jar

19:16 what is that?

19:18 path tot e clojure.jar?

19:18 why snapshot?

19:20 i got wokring a bit, both clojure and slime in the menu

19:20 but i cant run inferior lisp

19:22 notallama: point it to your clojure.jar. (whatever yours is called)

19:22 flaskan: in did

19:22 i did

19:22 arohner_: flaskan: what do you mean "can't run?" what happens when you do M-x inferior-lisp?

19:22 flaskan: no such filem or directory, lisp

19:23 (setq swank-clojure-jar-path "C:/clojure_20080916/clojure.jar")

19:23 arohner_: if you are trying to run slime, you should use M-x slime rather than M-x inferior-lisp

19:24 powr-toc: Is there a reason why the special-forms like if, let etc... don't have meta-data associated with them? I'm thinking doc strings etc...

19:25 as a newbie, it occaisionally seems frustrating to do (doc new) and get an error

19:26 arohner_: powr-toc: SVN clojure supports (doc <special form>)

19:26 powr-toc: ahh cool

19:26 I'll upgrade

19:26 arohner_: it only tells you to go read clojure.org though

19:26 flaskan: ok i got it running wioth M-x slime but it doenst sem to fucntion poerfectly. for some reason I cant do C-c C-e(its grey in the menu)

19:26 powr-toc: lol

19:27 arohner_: flaskan: you have a repl?

19:27 flaskan: why are the keybindings for clojure-mode no in the menu? why are the keybindings for slime grey, ie not working?

19:28 arohner_: flaskan: did you install clojure-mode?

19:28 go to a .clj file and type M-x clojure-mode

19:28 notallama: flaskan: have you looked at http://riddell.us/clojure/ ? that helped me get it working.

19:29 arohner_: or http://en.wikibooks.org/wiki/Clojure_Programming#Emacs_.2F_Slime_Integration

19:29 flaskan: aroherr: yes repl

19:29 ^^ im doing that

19:30 i have clojure and slimem in the emacs-menu, the clojure-repl is running with M-x slime

19:30 but the keybindings are not working

19:30 danlei: ok, something must be wrong. is this correct use: (ns ... (:use (foo.bar) (baaz.quux)) ... ?

19:31 flaskan: in normal clojure-mode i can do C-c C-e to eval last s-expr, now i ahveto choose with the mouse in the clojrue-menu. the binding is in the slime-menu but it is grey, ie not activ eor something

19:31 using windows btw

19:32 arohner_: try C-x C-e

19:34 danlei: i don't get it; (require 'foo.bar) (refer 'foo-bar) works perfectly fine ...

19:34 notallama: i have that same issue on my windows box. i'm thinking it's because i screwed up the setup. i'll try fixing it afte i' done my homework, and let you know how it goes if you don't get it working by then.

19:36 flaskan: user=> java.lang.Exception: No such namespace: swank

19:36 the repl starts but i get that ^^

19:36 arohner_: flaskan: I've seen that when the clojure and swank versions don't match up. If you have a pre-AOT clojure, you'll need a pre-AOT swank, and vice versa

19:37 you are using the downloaded clojure.jar?

19:37 flaskan: ahead of time compilatioN?

19:37 arohner_: flaskan: yes

19:37 flaskan: dont know i have the september 16 version

19:37 arohner_: and you git clone'd swank?

19:39 flaskan: yes

19:39 both swank and clojure-mode i git-cloned

19:39 arohner_: run this:

19:39 git reset --hard 73625153203649bb9bac1a32774e1100a60c6f5c

19:39 inside your swank-clojure directory

19:39 then restart emacs

19:40 that will point your swank to an older version which should work with the sept clojure

19:42 flaskan: user=> java.lang.Exception: No such var: swank/start-server

19:42 etc

19:42 still the same problem

19:42 arohner_: hrm. That's the exact version I'm using on an older clojure version

19:43 danlei: ok, one more time. can someone give me a sample invocation of "use"? neither (use 'foo.bar), (use 'foo-bar) (use '(foo.bar)) (use '(foo-bar)), nor 20 other possible combinations i tried seem to do the trick. can't be that hard

19:44 arohner_: danlei: (use 'clojure.contrib.test-is)

19:44 if that doesn't work, it probably means the library you want is not in the classpath

19:45 flaskan: anyway f*** slime. couldnt someone put up a guid eon how to do java classpath stuff on windows, how to make it work with clojure?

19:45 danlei: well, it works, if i do (require 'foo.bar) (refer 'foo-bar)

19:45 but not with (use 'foo.bar)

19:45 arohner_: danlei: how does it not work?

19:45 Chousuke: aren't you supposed to use the ns macro instead of those anyway?

19:45 danlei: namespace foo.bar not found

19:46 well, i wanted, but that won't work either

19:46 i'm sure it's just a small glitch, but i don't get what's wrong

19:46 Chouser: danlei: it may be your file structure

19:47 danlei: ok

19:47 look:

19:47 arohner_: flaskan: use -cp when starting java

19:47 Chouser: danlei: what's the full name of your namespace?

19:47 arohner_: java -cp /path/to/clojure-contrib.jar clojure.lang.Repl

19:48 danlei: dhl-utils

19:48 Chousuke: that's missing clojure.jar though :p

19:48 arohner_: oops, need a clojure.jar in there

19:48 danlei: they live in .../clojure/dhl/utils.clj

19:48 and ... is in the classpath

19:48 arohner_: java -cp path/to/clojure.jar:/path/to/clojure-contrib.jar clojure.lang.Repl

19:48 danlei: sorry .../clojure/ is in the claspath

19:48 Chousuke: danlei: that's misnamed then, isn't it?

19:48 Chouser: ok, with that file structure your namespace should be clojure.dhl.utils

19:49 ok, then dhl.utils

19:49 rhickey: flaskan: maybe you want to try this: http://groups.google.com/group/clojure/msg/5f4d2779717e6b26

19:49 danlei: even if .../clojure/ is in the classpath?

19:49 yes, ok

19:49 cooldude127: is anybody else reasonably familiar with On Lisp's non-determinism macros? (choose, fail)

19:49 danlei: i just double-checked it's definitely in the classpath, and i spelled everything correct

19:50 if i do (require 'dhl.utils) (refer 'dhl-utils) everything works as expected

19:50 Chouser: so with your

19:50 no

19:50 danlei: then: use 'dhl.utils ->

19:50 namespace dhl.utils not found

19:51 Chouser: if (refer 'dhl-utils) works, then your namespace is named dhl-utils when it should be dhl.utils

19:51 danlei: aha

19:51 just a sec, i'll check



19:52 sorry guys :)

19:53 danlei: Chouser: Thou art a saint. Thank thee!

19:53 i almost went mad

19:53 Chouser: danlei: np. subtle one there. :-)

19:53 danlei: oh boy

19:55 powr-toc: cooldude127: vaguely... they implement failure driven search right?

19:55 bradbev: does anybody know where the best place to post patches for clojure/swank?

19:56 powr-toc: like prolog style backtracking etc...

19:57 arohner_: bradbev: fork it off github, and then commit to your fork

19:58 bradbev: arohner_: true. I guess that's easier than posting patches to the main tree then?

19:59 arohner_: are you asking about clojure proper, or swank-clojure, or both?

19:59 bradbev: swank-clojure

20:01 arohner_: ok, yeah. what I said above. the process is different for clojure proper and for a second I thought you were asking about htat

20:02 cooldude127: powr-toc: exactly

20:03 i'm trying to port those to clojure

20:03 it's only going somewhat well

20:03 bradbev: arohner_: thanks

20:03 arohner_: np

20:05 cooldude127: powr-toc: it works, but the problem with it is that if you reach a solution before you've tried them all, the possibilities are still left around, they don't get removed

20:06 it makes me sad

20:07 flaskan: rhickey: thanks for the link, seems awesome

20:07 really very good initiative

20:07 Chouser: cooldude127: doesn't 'on lisp' include macros for making continuations out of closures?

20:09 cooldude127: yeah it does, i need to look at them, still haven't wrapped my head around how that can work

20:10 Chouser: does anyone think there's a niche for very small standalone text editor + clojure repl written in pure clojure? It'd be very small and require essentially no installation, but it's getting to be a crouded space with slime, clojurebox, enclojure, gorilla, jedit plugin, eclipse plugin, etc.

20:11 danlei: Chouser: if it would be a one-click installer, everything included that one needs to get a repl, without classpaths and all that stuff, there would surely be a niche

20:12 i mean ... about 8-10 /long/ discussions just about such stuff in the last few days

20:13 Chouser: danlei: yeah, I think it could be a single .jar which, if I understand correctly, could be double-clicked in Windows and MacOS. Launching in any Linux would be a one-liner at worst.

20:13 danlei: Chouser: i'm sure that peope would use it

20:13 +l

20:13 flaskan: a

20:13 MarkVolkmann: Darn! I asked this question this morning and I already forgot the answer! ...

20:14 lisppaste8: flaskan pasted "bayesian spamfilter" at http://paste.lisp.org/display/70940

20:14 MarkVolkmann: I have a list and I want to use the values and arguments to a function. What expands a list in place so the items in it can be treated as individual arguments?

20:14 Chouser: MarkVolkmann: apply

20:14 flaskan: does anyone know how to make the merge-and-compute... function smaller?

20:14 MarkVolkmann: Thanks!

20:15 flaskan: Chouser: id be interested in the code but not really using it

20:15 Chouser: flaskan: heh, ok.

20:17 cooldude127: Chouser: might be nice for those new to the language or those unattached to their editor

20:17 but for me, emacs is it

20:18 MarkVolkmann: Why doesn't this print all the arguments on separate lines?

20:18 (defn prn-all [& args] (apply prn args))

20:18 danlei: that's what i thought, too. imagine being a total newbie, never used emacs or stuff. then you've got to get java, clojure, contrib(?), set classpaths up, install slime, make that work with swank-clojure, ... it's quite something a starter has got to get working

20:19 MarkVolkmann: When I run (prn-all 1 2 3), all the values are output on the same line, but prn is supposed to include a newline after each call.

20:19 arohner_: MarkVolkmann: because you call prn once with [args]

20:19 danlei: (and emacs alone may be fairly intimidating to some)

20:19 flaskan: anyone using clojure-box? it works perfectly, i just dont get which .emacs file it uses. i want to take away the toolbar, how?

20:19 MarkVolkmann: How can I make my prn-all function call it once for each argument?

20:19 arohner_: try (defn prn-all [& args] (doseq [x args] (prn x))

20:20 cooldude127: well here does, now i'm giving clojure continuations

20:20 MarkVolkmann: I'm confused why apply didn't do that. Isn't it supposed to call the function prn once for each item in the args list?

20:20 danlei: flaskan: you're talking about the emacs toolbar?

20:21 arohner_: flaskan: i don't know where the .emacs file is, but you can get rid of the toolbar by eval'ing (if (fboundp 'tool-bar-mode) (tool-bar-mode -1))

20:21 cooldude127: MarkVolkmann: you're thinking of map

20:21 arohner_: prn by itself takes any number of arguments, prints them, and then prints one newline

20:22 try (prn 1 2 3)

20:22 cooldude127: apply basically the list you pass as the last argument and makes each element an argument

20:22 arohner_: apply calls the function you supply, once

20:22 MarkVolkmann: Ah, okay. I guess I need to use doseq to call a function once for each item in a sequence.

20:23 arohner_: right

20:26 cooldude127: wow the doc macro makes me super happy

20:31 flaskan: when using clojure-box, is it then possible to do sql stuff without installing anything else?

20:32 danlei: any musicians here?

20:32 flaskan: im trying to write a genetic programming music program in clojure

20:32 but no i suck at music unfortuenwately

20:32 danlei: hm

20:33 cooldude127: Chouser: you seem to know what's going on when it comes to idiomatic clojure. so when it comes to these continuation and non-determinism macros, we have some global state. is this a situation for refs or vars?

20:33 danlei: how would you model generation of scales/arpeggios and stuff

20:33 i did it like this:

20:33 keep chromatic scale in a vector

20:33 and the scales, for example are the number of half-steps (relative to each oher)

20:33 then, i map those over the chromatic scale from the tonic

20:34 so that i can create scales/arpeggios and that stuff without having a large database of such stuff

20:36 at least it works, kinda :)

20:38 cooldude127: you gotta love clojure's approach to mutable state until it makes your life a pain in the ass

20:38 lisppaste8: Chouser annotated #70940 with "shorter merge-and-compute... for flaskan" at http://paste.lisp.org/display/70940#1

20:41 Chouser: cooldude127: vars are fine if all the mutation is going to happen within a single thread -- changes will be invisible to other threads and thrown away when the thread completes.

20:41 cooldude127: chances are you want a ref

20:43 cooldude127: Chouser: ok, well now i have new challenges, as i'm not sure how to implement these continuation macros with refs

20:44 Chouser: cooldude127: you're sure the state mutates, right? Sorry, it's been ages since I looked at 'on lisp'

20:44 cooldude127: well, the paths variable gets stuff added to it whenever you do a choose

20:45 i'm not really sure about the continuation variable, looks like all it does is get rebound

20:45 but the way it does is weird, he uses it as the name of the first argument to functions

20:45 Chouser: sorry, gotta go -- back in a few...

20:45 cooldude127: NOOOOO

20:45 k

20:52 bradbev: what's the best way to see if an argument is a function? I feel like I want (function? x) or (callable? x)

20:52 fn?

20:52 doh

20:53 cooldude127: yay

20:53 lol

20:54 Chouser: bradbev: note that (fn? {}) -> true

20:54 cooldude127: yeah anything that can be called like a function gets to return true

20:54 bradbev: yeah, same for vectors etc

20:55 cooldude127: and keywords even

20:58 powr-toc: Is that why vectors etc... implement java.lang.Runnable?

20:58 cooldude127: probably

20:58 powr-toc: Is it just a side effect of them being functions?

20:58 cooldude127: everything in clojure implements everything even remotely possible

20:58 bradbev: coming from CL, I am starting to like how easy it is to call functions is a Lisp-1

20:58 in a Lisp-1

20:58 cooldude127: yeah it's so nice and clean

20:59 Chouser: cooldude127: ok, so he's capturing *cont* all over the place

20:59 danlei: i often name my vars as functions ...

20:59 cooldude127: yes

20:59 Chouser: i'm not sure how to translate the lambda captures to refs

21:00 danlei: took me almost 10 minutes to find a bug (let [seq ...

21:00 cooldude127: do i even need refs for it?

21:00 Chouser: danlei: yeah, don't do that.

21:00 cooldude127: danlei: that's the only problem

21:00 powr-toc: cooldude127: I guess it makes sense, just wondering what it means to run a vector...

21:00 danlei: Chouser: yes, i know. it's just habits

21:01 Chouser: tempting names for locals that should be avoided: seq, list, vector, vec, fn

21:01 str

21:01 powr-toc: it takes an int, and returns the value at that index

21:02 cooldude127: powr-toc: all functions are runnable

21:02 Chouser: powr-toc: ([:a :b :c] 1) -> :b

21:02 MarkVolkmann: question about function documentation syntax ... look at (doc concat) as an example ...

21:02 cooldude127: powr-toc: they just do their thing

21:02 danlei: those things bite me quite often, a few hours ago, cond confused me to death, because of the removed parens =)

21:02 cooldude127: lol

21:02 MarkVolkmann: It says ([] [x] [x y] [x y & zs]).

21:02 cooldude127: MarkVolkmann: those are the 4 possible signatures

21:02 MarkVolkmann: Why not just & x.

21:02 cooldude127: optimization

21:02 MarkVolkmann: Doesn't that encompass all the possibilities?

21:03 So the common cases are handled more efficiently?

21:03 cooldude127: yes

21:03 MarkVolkmann: That seems to be an implementation detail and not really part of the documentation of the function.

21:03 cooldude127: and it might use reduce to turn the multiple one into a bunch of calls to the two-arg variety

21:03 MarkVolkmann: could be true

21:04 are the docs autogenerated?

21:04 powr-toc: Chouser: yeah, I understand that... but Vectors are a function of their indexes... java.lang.Runnable#run() takes no params (though they could be instantiated via a constructor)... so I guess it's just a function of being a function...

21:04 cooldude127: i had not considered that

21:05 is rhickey here?

21:05 Chouser: powr-toc: ah, good point. yeah, IFn implements Runnable, but in any case where a function can't be run with zero args, that fact's not useful.

21:05 powr-toc: So I guess there's no use in it

21:05 cooldude127: apparently not

21:06 we could just try (.run [1 2 3])

21:06 could we not?

21:06 Chouser: cooldude127: the arg list doc is generated from the actual function signatures in most cases

21:06 cooldude127: yeah that's what i thought

21:06 powr-toc: Chouser: still... it's all elegant, right through to the java... I like it :-)

21:07 cooldude127: yeah (.run [1 2 3]) throws an exception

21:07 i don't think vectors specifically implement run by choice

21:07 it appears to delegate to function behavior

21:07 Chouser: cooldude127: I don't think you need a ref

21:07 cooldude127: Chouser: i was starting to think so

21:08 i still think i do for choose

21:08 but not for continuations

21:08 Chouser: oh, ok.

21:08 cooldude127: still not sure what the hell i'm doing

21:08 lol

21:08 Chouser: :-)

21:08 well, good luck with it anyway.

21:08 cooldude127: thanks

21:09 it was so much easier in arc lol, of course graham would make it easy in his own language

21:09 rhickey: fns implement Runnable, but not all IFns do

21:09 cooldude127: rhickey: why do vectors?

21:09 * Chouser spoke without checking the source. Oops.

21:09 MarkVolkmann: Yes, documentation of the arguments a function takes IS autogenerated. That explains why (doc concat) outputs what it does. It picks up on the optimizations.

21:10 rhickey: cooldude127: because their abstract superclass does

21:11 cooldude127: rhickey: sounds right

21:11 the exception calling run() on it throws indicates that

21:11 Chouser: IFn extends Runnable

21:13 flaskan: Chouser: cool, learned some new tricks from that

21:13 Chouser: flaskan: great!

21:13 flaskan: I did that without actually understanding your algorithm or having a complete test case, so there may be other reductions available.

21:13 powr-toc: Looks like it should throw an IllegalArg...Exception due to the arity

21:14 cooldude127: powr-toc: run() should? cuz it does :)

21:14 flaskan: If you only have 1 core, is STM useful then? like i cant hvae more execeutionsppeed right? but i can still have better concurreny

21:15 powr-toc: cooldude127: hehe... was reading the code, not running it :-)

21:15 cooldude127: words cannot express how happy i am having ERC for IRC right next to a clojure slime buffer

21:15 emacs FTW

21:15 julian_morrison: flaskan: threads still contend on a preemptive multitasking OS, even on one core

21:16 danlei: god, making music is hard

21:16 * danlei gets a smoke.

21:17 julian_morrison: question for anybody who knows Clojure concurrency well: how would you code reactive behavior?

21:17 both STM and agents seem to be purely applicative - the best I've come up with is spin-and-poll

21:18 Chouser: julian_morrison: you want a thread to block until some kind of signal?

21:19 rhickey: you can add watchers to agents

21:19 julian_morrison: Chouser: I'm thinking something like a comms protocol that has states and reacts to inputs, errors, etc

21:20 rhickey: you can?

21:20 * julian_morrison goes digging in the API

21:20 rhickey: julian_morrison: add-watch/remove-watch

21:21 cooldude127: woah

21:21 didn't know that was there lol

21:21 rhickey: but for what you are describing, agents are the same as actors, just not switch statements

21:21 the functions you run can implement a state machine with the state

21:21 julian_morrison: ah, that must be new, it hasn't made it to the web site

21:22 cooldude127: how up-to-date is the web site?

21:22 Chouser: might refs one day support watchers as well?

21:22 danlei: cooldude127: it's still experimental

21:22 julian_morrison: rhickey: I've been thinking about the agent, actor thing. People keep saying they're similar but they look like duals to me.

21:23 rhickey: julian_morrison: agents are an open protocol and actors are closed

21:23 an actor is waiting for a fixed set of inputs

21:23 an new function for an agent can be defined and sent at any time

21:24 julian_morrison: one moves data to code, the other moves code to data

21:24 actors are implicits stateful, even if the state is in tail call parameters

21:25 rhickey: both are stateful

21:25 julian_morrison: and actors can give security gurantees - agents obviously can't

21:25 rhickey: that's right, Clojure doesn't protect against internal malice, but few systems really do or can

21:26 cooldude127: rhickey: that kind of protection is usually restrictive

21:26 julian_morrison: agents are stateful in a strange way. the only state is the reference. they're the most purely FP concurrent system i've ever seen

21:26 rhickey: actors bifurcate the control model into messages and functions, agents use a single control model

21:26 julian_morrison: actors can give strong guarantees, cf the "object capability model"

21:27 rhickey: its the standard dynamic/control tradeoff - Clojure favors dynamic models

21:27 cooldude127: dynamic = yummy :)

21:27 julian_morrison: also, actors don't make assumptions that everyone can see all the RAM

21:28 rhickey: but have the serious limitation of requiring messages to read, which introduces the possibility for deadlock or the necessity of timeouts

21:29 a->b tell me something, while b->a tell me something, a waits for b, b for a, deadlock

21:29 so actors impose the overhead of a distributed model even in the local case

21:29 I decided against that

21:30 but yes, agents are a shared memory system

21:30 julian_morrison: I think you could work around that deadlock but it would involve a very strong asynchrony assumption and an effort to never block

21:30 powr-toc: rhickey: are there any good papers on pros/cons of actors which influenced your decision?

21:30 rhickey: powr-toc: just read about Erlang

21:31 julian_morrison: timeouts are the norm with actors

21:31 powr-toc: rhickey: hehe, that'd all be pro actor literature then ;-)

21:31 cooldude127: erlang is all actor-ed up

21:31 rhickey: powr-toc: not at all, there ar epapers about deadlocks, lost messages, etc

21:32 powr-toc: cool... I'll have to go and dig em out..

21:32 rhickey: Erlang is a great way to do comm apps, but comm apps are hard

21:32 all apps shouldn't be that hard

21:32 powr-toc: true

21:33 julian_morrison: what apps nowadays aren't comm apps

21:34 even my desktop widgets are often comm apps

21:34 rhickey: parts of apps are comm, but not simple object interactions

21:35 julian_morrison: no, that's true, apps are usually comm on their outside

21:35 rhickey: the vast majority of an app shouldn't work that way, IMO

21:35 julian_morrison: although big apps often are comm on their inside

21:35 powr-toc: rhickey: Have you any plans to better support distributed apps in clojure?

21:35 rhickey: incredibly cumbersome

21:35 powr-toc: there will be support for message queues, probably on top of JMS

21:36 powr-toc: cool

21:36 rhickey: julian_morrison: inside, many things are solved by queues

21:37 julian_morrison: rhickey: are there FP queues in Clojure? I know there are non-FP ones in Java

21:38 rhickey: julian_morrison: I don't think queues should be FP - I like j.u.concurrent for workflow

21:39 julian_morrison: rhickey: aside, a request: pretty please, could we have the API doc in PDF?

21:39 rhickey: there is a PersistentQueue in the Clojure lib but not exposed in the API yet

21:39 julian_morrison: no FP in queues? Interesting. Why?

21:40 rhickey: julian_morrison: because you need to pace work, i.e. block

21:41 julian_morrison: http://clojure.googlegroups.com/web/manual.pdf

21:42 julian_morrison: rhickey: thanks :-D

21:43 hmm. I wonder if "functional reactive programming", Haskell style, applies

21:47 that is, describing blocking semantics as a function of lazily streaming input

21:56 rhickey: julian_morrison: I don't know enough about FRP, but the little I've read about seemed inordinately complex

21:57 why simulate time when you have real time?

21:57 blackdog_: are there any examples (apart from rhickey's lisppast) on the new gen-class stuff

21:57 powr-toc: rhickey: one thing erlang supports is safe hot code-swapping, as fn's are def'd is there a safe way to update a function definition in a running system?

21:58 blackdog_: do i need to use import or use to get at it from clojure

21:58 hiredman: I do it all the time with clojurebot, just dump updated functions into the repl

21:58 rhickey: blackdog_: you can just use :gen-class in your ns declaration

21:59 powr-toc: hiredman: yeah, but what would happen if that function was running at the moment you updated?

22:00 rhickey: powr-toc: it doesn't mutate running code, just swaps the fn in the var

22:00 blackdog_: ok, and if i want to generate a new instance in clojure is that (my.ns.) ?

22:01 rhickey: next call sees new code

22:01 julian_morrison: powr-toc: the Erlang way is that you can have two versions, and when the old version tail calls with a package name prefixed, the call goes to the new version and the old version gets unloaded

22:01 rhickey: julian_morrison: yes, Erlang is more sophisticated in this area

22:02 julian_morrison: rhickey: blame the JVM not yet supporting tail calls ;-)

22:02 powr-toc: julian_morrison: yeah, OTP's quite nice in that regard

22:02 rhickey: not the tail calls, the multiversion update

22:03 julian_morrison: as to the simulated time thing earlier, I think that's a Haskellism.

22:03 rhickey: plus it is module granularity, Clojure's is per var

22:03 powr-toc: rhickey: true

22:03 julian_morrison: rhickey: if you had tail calls, you could do it the Erlang way, just tail calling the var

22:05 blackdog_: ah hang on, is the ns version specifically for AOT? I see a gen-class function now too, which is really what I want in this case i think

22:06 Chouser: blackdog_: I don't think you're meant to call gen-class directly.

22:06 rhickey: julian_morrison: a long running agent often works that way, sending the same action to itself, will see updated code

22:07 blackdog_: ah, ok, how do i get hold of a new instance of my class then - feeling dense

22:08 rhickey: julian_morrison: but most Clojure code isn't wait/do/loop as in Erlang. Agents are idle, new actions use new code

22:09 hiredman: clojurebot: new Class(x) is (Class. x)

22:09 clojurebot: You don't have to tell me twice.

22:09 hiredman: hmmm

22:09 clojurebot: new is <reply>new Class(x) is (Class. x)

22:09 clojurebot: You don't have to tell me twice.

22:09 rhickey: julian_morrison: I've read Haskell School of Expression, Hudak's book on FRP

22:10 As someone who's worked on professional broadcast multimedia systems, I found it pretty irrelevant

22:10 julian_morrison: fair enough

22:11 rhickey: time is the hole in the functional model, as functions don't have time, but real programs do

22:11 julian_morrison: Haskell is often trying to push the envelope of "just how far can we get with one hand tied behind our backs" anyhow

22:12 rhickey: agents and refs model time

22:12 julian_morrison: actors model physics and were designed from it ;-)

22:12 rhickey: I think Haskell is absolutely right to push that agenda and see where it goes, I've learned a lot from it

22:13 julian_morrison: I quite disagree about actors - Armstrong is always saying that's the way the world works but it simply isn't

22:13 julian_morrison: rhickey: how so?

22:13 rhickey: we can observe things without their cooperation - not everything is messaging

22:13 julian_morrison: rhickey: you observe something by bouncing a particle off it. particle interactions are local.

22:14 rhickey: I don't bounce a particle off it - a particle bounced off it and hit me

22:14 julian_morrison: even quantum stuff is local if you use the Everett model

22:14 rhickey: no cooperation

22:15 julian_morrison: doesn't matter, same difference. the particle's interaction with you is also local

22:15 rhickey: I think there's all kinds of intention in the actor model not present in physics, but am no physicist

22:16 skrit: are refs the idiomatic way to do something like paul graham's accumulator generator?

22:16 (defn acc-gen [n] (let [x (ref n)] (fn [y] (dosync (alter x + y)))))

22:16 rhickey: skrit: pgs accumulator generator is a real waste of time

22:17 skrit: even as an exercise?

22:18 rhickey: If I try to bounce a message off an actor that it doesn't understand, it controls what happens

22:19 skrit: yeah, think of something cool you'd like your computer to do and make it do that, much better exercise

22:19 julian_morrison: rhickey: true

22:19 skrit: yeah, just coming from a lisp background rather than java, starting off in what I know

22:20 rhickey: skrit: unfortunately some of those exercises don't encourage good habits

22:21 skrit: so you won't recommend things like project euler, etc

22:21 Chouser: skrit: oh, I like project euler

22:21 rhickey: skrit: no, project euler is neat, and lot of Clojure people are doing that

22:22 accumulator generator is silly

22:22 Chouser: it doesn't dictate how you solve the problem -- functional solutoins are generally very natural.

22:22 skrit: oh, I agree

22:23 Chouser: I mean functional solutions for PE problems. :-)

22:23 julian_morrison: g'night all

22:37 notallama: yeah. i'm doing pe right now. it's the first time i have tried it. i looked at it before, but when i only knew java, the programming part was rather unpleasant.

22:40 Chouser: notallama: and now?

22:40 blackdog_: Chouser, you have any full example of gen-class usage

22:41 i understand the definition just don't know how to instance one

22:42 notallama: clojure is quite fun to program in. i end up wanting to implement several solutions.

22:47 scheme is nice to program in too. and i thought it would be painful, but i also kinda like c. (not for project euler type stuff, though. i like the repl too much there)

22:48 Chouser: blackdog_: no, I haven't worked one up yet.

22:48 blackdog_: all I've got are rhickey's example and a simple AOT class with just 'main'.

22:49 notallama: i end up using gdb as a repl in c, but it's not really the same.

22:49 blackdog_: yea, i have that

22:49 and understand it, but i don't know how to use it :)

22:49 do i import or use? neither is working for me

22:51 Chouser: blackdog_: I don't know if you can instantiate the class without AOT.

22:51 as in, without compiling it first.

22:51 blackdog_: yea, so use compile first

22:52 ok, I'll give that a shot, i guess i was thinking it was a bit like gen-and-load

22:57 Chouser: yeah, I just confirmed --

22:57 'require' doesn't create a class from a namespace

22:57 blackdog_: ok

22:57 Chouser: that is, not one named for the namespace

22:58 you have to do a separate compile first, though you can then immediately start using it.

22:58 blackdog_: okdok, thanks

23:04 arohner_: Chouser: to clarify, that means that require will load source or .class, but will not compile source?

23:14 Chouser: It looks like 'require' loads and of course compiles in-memory and evaluates the lib, but does not save it to disk and does not appear to create a class named for the namespace.

23:15 arohner_: that sounds like rhickey's standard orthogonal-ness

23:15 Chouser: or, right, if it finds a .class file that's newer, loads and evals that.

23:32 timothypratley: Exception in thread "main" java.lang.NullPointerException (server.clj:0)

23:32 what might be hiding the line number?

23:32 hmmm I'll try to make an example

23:45 notallama: so i was showering, and those accumulator generators crossed my mind. wouldn't that just be a special case of iterate? (not the same thing, but you'd use it for the same thing)

23:48 hiredman: some thing like http://paste.lisp.org/display/70873

23:49 (Except diffferent of course)

23:50 (f n) -> g, (g e) -> h, (h :nan) = n+e

23:52 hah

23:53 user=> ((partial (partial (partial + 1) 2) 3))

23:53 6

23:57 notallama: ah. i was thinking it was a function that returned a counter. i see what it's supposed to be now, though.

23:57 hiredman: c is a counter

23:58 which is the different part, the same part is returning a function whose result is the current state of the calculation

Logging service provided by n01se.net