#clojure log - Aug 29 2009

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

6:49 tomoj: is the person that built eugene around?

6:50 huh, I can't find it on github now

6:51 fsm: If anyone is interested, performance is up 30-35% in code running on leopard vs snow leopard

6:57 tomoj: wow

6:57 why?

7:02 fsm: I don't have a leopard install to test for the reason, but i was running java 1.6 on both

7:03 possible causes are better scheduling causing better cache usage, maybe the jvm has been tweaked for speed, maybe running in 64 bit affects it, ...

8:32 gerryxiao: hello

8:34 how to use java someclass.class.getResource method in clojure?

8:36 someclass should be main class of my application, but clojure not recognize it

8:40 i have to compile it to get that class, but complier complained can't find that class

8:43 Chousuke: someclass.class gets you the Class object of SomeClass, rright?

8:43 is getResource a static method of Class?

8:44 gerryxiao: yes

8:44 Chousuke: then you want Class/getResource

8:45 gerryxiao: oops not static method

8:47 (.getResource (class someclass) args)

8:48 Chousuke: just (.getResource SomeClass args)

8:48 if ti can't find the class, check your classpath

8:48 gerryxiao: nope, in java, is Someclass.class.getResouces(..)

8:49 not SomeClass.getResource(..)

8:51 Chousuke: yeah, but in Clojure SomeClass.class is just SomeClass

8:51 ,(.getCanonicalName String)

8:51 clojurebot: "java.lang.String"

8:52 gerryxiao: and this someclass is main class of my application, my main clojure file is cgogame.clj, so it should be cgogame class, but it not work

8:52 ok, i try (.getResouce Class args)

8:53 Chousuke: you have the (ns ...) and :gen-class declaractions in place?

8:54 damnedlag. impossible to type :

8:54 gerryxiao: Chousuke, this class isnot compiled yet

8:54 Chousuke: it needs to be.

8:55 you won't have a class until it's compiled.

8:55 gerryxiao: but compiler complained can't init it

8:55 Chousuke: are you sure you need a class though?

8:55 maybe just a proxy would do

8:56 gerryxiao: proxy what, my main class?

8:56 Chousuke: why do you need to generate a class in the first place?

8:57 gerryxiao: maybe i don't understand java correctly

8:57 Chousuke: well, in java you would of course make a class, but that's not always the case with clojure.

8:57 gerryxiao: in java, when i make one class named test, then i can use this class name in class def, is it right?

8:58 Chousuke: Does that matter? are you coding in Java or in Clojure?

8:59 gerryxiao: i need call java lib, this method seems need it

8:59 Chousuke: I have to say I don't have a good grasp of Java myself.

8:59 yeah, you can call java libs. But do you need your own class for it?

9:00 if all the library wants is an instance of some class implementing some interface, proxy will work just fine.

9:00 gerryxiao: i'm programming one go game by clojure now, want to learn clojure

9:01 GUI of this game need much java swing stuff

9:01 Chousuke: ah, yeah-

9:02 proxy works kjust fine for implementing swing GUI thingies

9:02 no need for genclassing

9:02 (doc proxy)

9:02 clojurebot: "([class-and-interfaces args & fs]); class-and-interfaces - a vector of class names args - a (possibly empty) vector of arguments to the superclass constructor. f => (name [params*] body) or (name ([params*] body) ([params+] body) ...) Expands to code which creates a instance of a proxy class that implements the named class/interface(s) by calling the supplied fns. A single class, if provided, must be first. If not provid

9:02 Chousuke: hmm.

9:02 maybe you should read it from the website.

9:04 gerryxiao: i knew it, and have wrote > 500 lines go game code, but sometimes get confused with java

9:05 swing need much proxy code to work

9:06 Chousuke: yeah.

9:06 though macros and functions in Clojure make it much more pleasant than writing it in Java

9:07 But I can't really help now.I don't know what you want to accomplish :/

9:08 gerryxiao: clojure code is concise,if i worte it in java. i need at least two times codes

9:09 zakwilson: Has anybody come up with a Clojure wrapper library to make swing hurt less?

9:12 gerryxiao: how to reduce compiled class files?

9:13 Chousuke: reduce? hmm.

9:13 I don't think you need worry about them.

9:13 clojure produces one class for each function, so you end up with a lot, but they're all fairly small.

9:29 gerryxiao: does clojure support inline functions?

9:33 Chousuke: yeah

9:33 though in most cases you should just let hotspot do the inlining.

9:34 gerryxiao: you meant i dont' need care it ?

9:35 Chousuke: well, in most cases you won't

9:35 gerryxiao: nice

9:36 Chousuke: if you're writing performance-critical code you might have to use macros or definline instead of functions, but don't bother until it's necessary.

9:36 gerryxiao: ok

9:45 ok, i have figure out the first question, i don't need that method to make it work, there is another method which don't need Class object.

9:45 thx

9:47 i need twist java instead of clojure to make game work ,that's a bit annoying.

9:57 here is one snapshot of my clojure go game :http://imagebin.ca/view/bCB5BU.html,though it's still under alpha

9:58 http://imagebin.ca/view/bCB5BU.html

10:02 tomoj: nice

10:02 what java library are you using?

10:08 gerryxiao: does structmap support serialization?

10:08 tomoj: no :(

10:16 Chousuke: Somehow that doesn't look like a beginner opening pattern.

10:17 I think this because I probably would not play like that, and I'm just 7k :P

10:22 ankou: hi, how do I use multimethods with structs? The class of every struct is PersisentStructMap, so I suppose I can't use class as dispatchfunction. Is there a way to create own types or is there a better dispatchfunction or something like that?

10:23 Chousuke: you can use the type function

10:23 (doc type)

10:23 clojurebot: "([x]); Returns the :type metadata of x, or its Class if none"

10:23 Chousuke: or you can just use a key in the structmaps as the dispatch

10:24 ankou: how can I add a :type to the metadata of every instance of a struct?

10:25 Chousuke: you'll need a factory function.

10:25 hmm

10:26 I wonder if instances of structmap could inherit metadata from the struct object.

10:26 would make using :type for them rather convenient.

10:26 cark: not everyone likes the "type as metadata" thing

10:27 Chousuke: right.

10:27 cark: i'd rather have an normal slot for this

10:27 Chousuke: mit might make more sense to dispatch on some other key.

10:27 or even multiple keys

10:28 don't be constrained by types :)

10:28 cark: i think it's good practice to have either metadata or additional slot for the type, but leave it to the programmer to go either way

10:29 Chousuke: and if you use metadata for the type, then ordinary maps can't be used :/

10:31 ankou: mhm yeah, it would probably make more sense to dispatch on keys.

10:44 what is the license of clojure and clojure.contrib anyway? Since I need to distribute those in order to use them I suppose I should ask for the restrictions first. I saw that at least parts of the clojure.contrib library are published under the terms of CPL, can I use them from a GPL program? or a proprietary program?

10:45 Chousuke: both are EPL

10:45 cark: ankou : my understanding is that yes you can

10:46 gerryxiao: tomoj: mainly swing

10:46 Chousuke: if there is anything in contrib that claims to be CPL, that's a bug

10:46 gerryxiao: i'm 4d in cgoban

10:46 sometimes 5d

10:46 ankou: yes I meant EPL, german wikipedia redirects from EPL to CPL, what's the difference between these licenses?

10:46 Chousuke: EPL is the newer licence.

10:47 CPL should redirect to EPL :/

10:48 but my understanding is that you can write GPL clojure programs just fine.

10:48 ankou: But still GPL incompatible, right? I find this GPL compatibilitystuff hard to understand. Is it possible to distribute a gpl program which uses a library, that is not gpl-compatible?

10:49 Chousuke: if the GPL required the libraries your program uses to be GPL, then GPL programs on windows would be impossible :/

10:50 ankou: at least the other way around holds true

10:50 Chousuke: yeah, if you link to GPL libraries then your program is a derivative work.

10:51 but Clojure is not a derivative work of your GPL code

10:53 ankou: I suppose that makes sense.

10:56 Chousuke: hmm

10:57 "Based upon the position of the Free Software Foundation, you may not combine EPL and GPL code in any scenario where linking exists between code made available under those licenses."

10:57 that's rather weird

10:58 complicated by the java notion of linking which happens at runtime :P

11:03 cark: ankou : do you absolutely need gpl ?

11:04 mybe epl might suit you just as well ?

11:04 *maybe

11:04 ankou: well I think it would be a major problem in general if it is impossible to write GPL code with Clojure?

11:16 Chousuke: you can write GPL code on windows because GPL seems to have a system library exception.

11:17 Chousuke: hm

11:17 wonder if that'd apply to clojure

11:18 woop

11:18 ankou: at least not in terms of GPLv2, which explicitly excludes everything that is distributed with the GPL application

11:18 Chousuke: so hm

11:19 could you get around by simply not distributing clojure.jar?

11:19 ankou: There is also another thing "If you want your program to link against a library not covered by the system library exception, you need to provide permission to do that. " however I don't really understand what they mean. http://www.fsf.org/licensing/licenses/gpl-faq.html#GPLIncompatibleLibs

11:22 It seams that it is possible to change the GPL to have special exceptions but I suppose that wouldn't the usage of any GPL libraries, since I can't put the exception in their license.

11:24 rhickey: ankou: the GPL is not compatible with the EPL, that's the fault of the GPL

11:27 ankou: rhickey: I don't think it is important whose fault this is. It is a fact that there is lots of GPL software and GPL librarys out there and that GPL is standard on linux systems and not beeing able to use them really is a major problem.

11:28 rhickey: ankou: I can't fix gpl

11:30 Chousuke: Is there a reason clojure is gpl-incompatible though? I know EPL is friendlier for commercial users, but that doesn't rule out dual-licencing for example.

11:32 And Clojure being a programming language I think excluding any licence is counterproductive.

11:32 rhickey: Chousuke: dual licensing means people can create derivative works that are GPL, i.e. that I and others can't use as freely as what they originated from. That's not my idea of a reciprocal license.

11:34 Chousuke: this just prevent people from using any GPL java libraries with Clojure. I don't know if that really will be a problem, but it'd be better if the problem didn't exist in the first place.

11:34 prevents*

11:34 cark: a co-routine implementation would require a code-walking macro wouldn't it ?

11:34 rhickey: the problem is with the GPL libraries, complaints should go to them

11:35 it is GPL that's preventing

11:35 EPL has not restrictions on the things with which it can be combined

11:36 Chousuke: hmm. I suppose.

11:36 ankou: rhickey: The incompatibility already existed when you chose the license, so it was your decision to make clojure GPL-incompatible and not the decision of the FSF

11:36 rhickey: ankou: that's silly

11:36 cark: the fsf is annoying with its non-free free software

11:36 rhickey: GPL is incompatible with the world, not the world with GPL

11:37 cark: though they served a purpose, they are such zealots ... *roll-eyes*

11:37 rhickey: If you choose to use GPL software that's what happens to you, buyer beware

11:38 I chose a license that provides no restrictions on what it can be combined with, others chose licenses with restrictions on what they can be combined with. If you can't combine things, it's not my fault

11:39 use libraries with better licenses

11:39 ankou: rhickey: that's childish.

11:39 rhickey: ankou: yes, any child could figure it out

11:40 as adults, we make choices and have to live with them, choosing GPL means a lot of restrictions

11:41 in any case, Clojure is not going to become GPL or LGPL

11:41 I can't use that in my work, period

11:43 ankou: rhickey: there are lots of other gpl-compatible licenses

11:45 rhickey: ankou: the GPL is not compatible with any other reciprocal license, AFAIK

11:45 why should the GPL be the only reciprocal license in the world?

11:47 If you really want to use a GPL library with Clojure, ask them to change it to LGPL, which drops the combining poison

11:47 Raynes: If it's a library, it should probably be LGPL in the first place.

11:47 rhickey: right,

11:48 angerman: hmm.. GPL+exception(you must license all your deriv work under EPL)

11:48 I wonder if that's legal :]

11:54 tomoj: I hate this licensing crap :(

12:01 rhickey: there would be no licensing issues if GPL didn't want to impose things on combined work. Every other license can be combined with every other, only impacting truly derived (not merely combined) work

12:05 cark: wasn't the original question about using clojure from a gpl program anyways ? i don't see how this would be restricted

12:07 ankou: <Chousuke> "Based upon the position of the Free Software Foundation, you may not combine EPL and GPL code in any scenario where linking exists between code made available under those licenses."

12:07 which is a quote from the EPL FAQ

12:09 cark: oh i see

12:20 jkantz_: are there any efforts under way to port CLOS to clojure or to make something CLOS-like for clojure?

12:23 tomoj: jkantz_: what's wrong with clojure's multimethods?

12:27 pluijzer: I think there brilliant

12:28 rhickey: jkantz: yes, I forget where it lives though

12:28 jkantz_: ok, nothing wrong with multimethods, just curious

12:29 wanted to look at it

12:29 s/it/code/

12:29 tomoj: what would be the point of a CLOS-like thing for clojure?

12:29 pluijzer: is there an other language that uses Clojure style multimethods?

12:29 tomoj: I mean, would it just attach metadata and generate appropriate dispatch functions for you implicitly?

12:31 rhickey: http://code.google.com/p/explorersguild/wiki/XGModelAndGF

12:33 jkantz_: thanks

12:36 arbscht: pluijzer: fwiw, I've implemented simple prototypes of clojure-like multimethods in javascript and python

12:42 rhickey: fn-tuple needs a better name: http://groups.google.com/group/clojure-dev/browse_frm/thread/155c8b9893d673bc

12:43 I've got a version that produces vectors

12:43 pluijzer: arbscht: any source of info about the python one?

12:46 maacl: Has anyone used the CouchDB clojure view server that comes with Clutch (http://github.com/tashafa/clutch) ?

12:46 rhickey: Haskell has binary &&&, called fanout or both, not really good names here

12:48 ((comp a b c) x) => (a (b (c x)), ((??? a b c) x) => [(a x) (b x) (c x)]

12:49 juxt?

12:49 for juxtapose

12:49 compose/juxtapose

12:49 comp/juxt

12:50 * rhickey babbles on...

13:04 Chousuke: rhickey: that's a lot like Sean Devlin's fn-tuple idea.

13:05 rhickey: it is exactly that idea

13:05 I pointed to the discussion

13:06 I just worked it up for inclusion, now just need a name

13:06 Chousuke: ah, right. it had scrolled of my screen :)

13:07 juxt is a bit weird though. hm.

13:08 I guess combine is a bit too generic.

13:11 rhickey: conjf ?

13:11 conjfn

13:12 adjoin

13:12 allfn

13:13 abut

13:15 alrex021: do Agents in Clojure provide any guaranty that the action in the transaction 'will' happen?

13:15 rhickey: nothing other than appose is as correct as juxt[apose]

13:16 appose?

13:17 alrex021: the actions are not themselves transactional, just held until the transaction completes

13:23 ankou: are there any finished projects written in Clojure?

13:25 danlarkin: ankou: no program is ever finished :)

13:25 arbscht: ankou: there are many live projects in production using clojure, if that's any consolation :)

13:26 ankou: lets say non-beta-release

13:26 rhickey: http://www.flightcaster.com/

13:29 alrex021: are there any good examples of projects that make good use of Clojure's transactional API? (preferably OSS)

13:31 flightcaster doesn't seem to utilize the Clojure's transactional API as they deligate the concurrency concerns to hadoop, cascade...

13:34 so I heard on a recent podcast :)

13:34 arbscht: compojure the web framework uses it to manage in-memory session state

13:37 alrex021: gr8, I'll have a look at compojure. I'm watching Rich's concurrency screencast and talks about the Ant concurrency example...is it available somewhere for download?

13:41 ole3: hello, is there a precompiled version of clojure?

13:42 alrex021: ok, I found the ant app on the clojure google-group files

13:44 rhickey: juxt/conjf/adjoin/abut/allfn/appose - anyone?

13:45 arbscht: alrex021: that might be out of date. see here instead http://github.com/weavejester/compojure/

13:49 ole3: ah, ok found the jar, sorry for the spam

13:53 arbscht: rhickey: 'gib'?

13:54 rhickey: arbscht: meaning what?

13:56 arbscht: I see (gib a b c) as collecting a b and c in a 'gib' (notched structure), so when invoked with x, x is exposed to all the edges of the structure

13:57 [(a x) (b x) (c x)] would be the "cut of the gib" of x, I guess

13:59 rhickey: arbscht: I didn't get that at all from gib

13:59 anyways, it's up as juxt for now, final name TBD

14:00 arbscht: too obscure then :)

14:23 gko: What's the equivalent of CL return in Clojure?

14:30 Chousuke: what does return do?

14:33 ole3: 'return' returns from a block

14:33 Chousuke: ah. then there's no way to do that in clojure that I know of.

14:34 using return would mean you have side-effects somewhere.

14:34 not very clojurey I suppose :P

14:34 ole3: yes

14:35 :)

14:37 Chousuke: funny, though. Before I learned clojure I don't think I would have asked what a function called "return" does :P

14:38 ole3: return is not a function :)

14:39 return is a macro, witch it expands to return-from witch is a special form

14:39 nevermind

14:40 Chousuke: okay. operator, then :P

14:40 ole3: Are there many former cl'ers here?

14:44 arbscht: there are some. I still use CL

14:52 kylesmith: I've used cl

15:04 luis: ole3: former... pff. :)

15:40 maacl: How does one write a function that takes a literal value (string) and returns a function that operates on this literal value?

15:41 hiredman: eh?

15:46 maacl: If I pass "hello" to the function the returned function must contain the literal value of "hello" not a var.

15:47 angerman: how would I determine the substrposition of a re-match?

15:49 hiredman: maacl: contain?

15:49 closed over locals are not vars

15:50 rhickey: ,((fn [x] x) "hello")

15:50 clojurebot: "hello"

15:51 hiredman: rhickey: he seems to be big on the word literal, os I assume he somehow wants the returned function contain "hello", which doesn't make sense, but that is what he sounds like he wants

15:51 maacl: ah

15:54 I am using Clutch which is a library for using CouchDB. It contains a view server for CouchDB which takes a view function. This function cannot contain a external reference. Sorry if I mess up the terms

15:56 cupertinochad: What is the customary way to calculate an average time for an expression to be evaluated over a number of runs? Is there a standard function for this or a commonly used idiom? (time expr) gives me the time for one run, but those results are misleading.

16:02 maacl: hiredman: I am sorry if the question doesn't make any sense

16:15 rhickey: maacl: do you have a link to the api you are trying to satisfy, or any code?

16:16 maacl: rhickey: sure http://github.com/tashafa/clutch/tree/master

16:16 rhickey: clojure string literals get interned in compiled code just like Java's

16:17 hiredman: are you sure clutch takes a function?

16:18 seems like it would take a datastructure that looks like the datastructure defining a function

16:18 and transform it to javascript somehow

16:19 maacl: hiredman: yes I believe so, if you see the link above - it is not transformed to javascript - clojure is use as the view-server

16:20 I am messing around with load-string to see if I can make it do what I want to

16:21 hiredman: :(

16:21 rhickey: maacl: what did you try that didn't work, and how?

16:23 hiredman: yeah, with-clj-view-server doesn't take functions

16:24 it takes a list '(fn [x] x)

16:25 which it serializes as a string

16:26 maacl: I tried this http://paste.lisp.org/+1UJJ

16:27 hiredman: definitely not going to work

16:27 maacl: I sort of figured that out

16:28 hiredman: :P

16:29 bacause what apears to be a function pased to with-clj-view-server is turned back into a string, then actually evaluated somewhere outside of that lexical scope

16:29 you might need to write your own macro

16:29 maacl: hiredman: indeed, that is why I was looking for a way to get a literal value in there

16:30 hiredman: ,(let [x 1] `(1 2 3 ~x))

16:30 clojurebot: (1 2 3 1)

16:32 pluijzer: I'm very new to clojure so pardon the simple question but do I need the java library to spawn threads?

16:32 hiredman: the java library?

16:33 pluijzer: yes?

16:33 hiredman: what do you mean by "the java library"

16:34 pluijzer: do I need methods from Java?

16:34 hiredman: nope

16:34 maacl: hiredman: ah

16:34 hiredman: simplest is to just use future

16:35 maacl: I think you are going to have to construct your own version of the with-clj-view-server macro

16:35 ,(doc future)

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

16:36 pluijzer: hiredman: thank you!

16:36 hiredman: there are also agents

16:37 you can also do something like (.start (Thread. #(prn :foo)))

16:38 pluijzer: thank you I'll try that]

16:45 Chouser: rhickey: new's "this" apprears to be unhinted

16:47 rhickey: Chouser: completely - no-reflective self calls are todo, also more than a hint is required, all the code is compiled before this's class exists and thus there is no reflective type info for the compiler

16:47 non-reflective

16:48 so all use of this will require special handling in the compiler

16:48 hiredman: *head explodes*

16:49 Chouser: ah. hm. I was able to work around it by hinting the interface that provids the interface I'm calling

16:50 rhickey: that will work for everything other than self-calls to methods added in reify

16:50 Chouser: It's not called 'reify' on github yet -- dunno if it's not ready or just an oversight.

16:50 rhickey: but in the end shouldn't be necessary

16:50 * Chouser is reading the discussion of the 'reify' name to see if he'll dislike it any less in the end...

16:51 rhickey: suggestions for something-other-than-new still welcome, there's no code yet using reify

16:52 also, you missed juxt discussion before

16:52 Chouser: saw it mentioned on the group

16:52 * Chouser wonders if he should admit to checking the group via iphone while mowing...

16:53 rhickey: :)

16:58 Chouser: you're set against re-using "new"? Right now, that's *the* primitive for creating new instance of Java objects.

16:59 rhickey: Chouser: other than fn

16:59 Chouser: hm, and 'fn' I suppose

16:59 but if fn is defined in terms of newnew, we get that back

16:59 hm, and every object literal.

17:00 rhickey: new is the way you create an object given its class name, reify both creates code and makes an instance

17:01 plus reify has all the closing over stuff

17:01 Chouser: I also like how it read. Here I'm making a new Indexed Sequable IPersistentVector.

17:01 how it reads.

17:02 I guess it emphasises the instance creation perhaps at the expense of the closing-over, class-defining behavior.

17:06 rhickey: all discussions of new would have to be bifurcated right away on that

17:06 Chouser: and docs. Ok, I can see your point.

17:07 implementing Indexed is insufficient for destructuring.

17:08 rhickey: due to?

17:08 Chouser: I have to implement IPersistentVector in order to get a nth method with a not-found arg.

17:10 rhickey: oh, that should be fixed to be the same, using Indexed first, as in RT.nth(Object coll, int n)

17:11 I thought I did that

17:11 ah, is that way in master

17:11 Chouser: oh!

17:15 git cherry-pick 7ba336f5

17:15 rhickey: Chouser: do I need to do that?

17:16 Chouser: or I can push it, thought that might complicate merges later.

17:16 though

17:16 I'm ok running a weird version of clojure for my finger tree stuff for now.

17:18 rhickey: ok

17:34 cemerick: wow, I'm glad I missed the licensing debate last november

17:36 * rhickey wished he had :(

17:40 cemerick: rhickey: you must do a great deal of mediation. I have zero patience for such discussions.

17:40 ...especially when I get some fool coming around saying we should open source product. :x

17:43 ole3: ,(doc reify)

17:43 clojurebot: Excuse me?

18:26 technomancy: ~(find-doc "absolute value")

18:26 clojurebot: Pardon?

18:26 technomancy: ,(find-doc "absolute value")

18:26 clojurebot: nil

18:27 technomancy: what do you call that in Java-land?

18:31 kylesmith: ,(Math/abs -1)

18:31 clojurebot: 1

18:34 technomancy: thakns

19:29 krumholt_: how can i use one of my .clj files in another .clj file?

19:33 arbscht: krumholt_: if the directory containing foo.clj is in your classpath, you can (:require foo) in another namespace

19:33 krumholt_: arbscht, ok i allready have it thanks i was looking for (refer ..)

19:59 ambient: anyone know how I can autocomplete java libraries and methods in emacs with clojure-mode, slime, etc? and perhaps view some documentation

20:29 kylesmith: Is anyone attending this conference? http://www.lanl.gov/conferences/lacss/2009/agenda/workshops.shtml

21:00 Chouser: anyone know if any videos from ilc2009 are available yet?

21:01 rhickey: Chouser: not as far as I know

21:08 Chouser: I should have started with reify. more fun than a pile of functions on vectors.

21:14 also seems plausible that one could use some macros to produce collections of primitives without a whole lot more code.

Logging service provided by n01se.net