#clojure log - Dec 10 2008

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

5:31 Lau_of_DK: Morning all

7:01 AWizzArd: When I do (load-file "/path/myfile.clj"), what could then be the reason for getting a EOF exception in the last line of that file?

7:01 I think this is not very exceptional that the file ends where.. well.. it ends.

7:02 mibu: AWizzArd: maybe the file was so interesting and the reader just wanted to protest that it's over. ;-)

7:03 AWizzArd: yup, right, that was it

7:03 mibu: AWizzArd: but seriously, who raised the exception, the reader or the load?

7:04 AWizzArd: Well, there was an unbalanced paren that caused it.

7:04 So probably the reader.

7:05 mibu: you solved the problem too quickly. that's not fun :-)

7:45 rhickey: try this next time you get an exception: (map bean (.getStackTrace *e))

7:48 AWizzArd: ah oki, thanks

7:48 Lau_of_DK: What is *e ? I dont recall seeing star syntax in Clojure

7:48 AWizzArd: last exception

7:48 just a normal variable

7:49 and the star syntax still makes sense for global/dynamic vars, created with (def *var*)

7:51 is the (.. syntax for doing things like frame.getContentPane().add(yellowLabel, BorderLayout.CENTER); ?

7:58 (doto frame (.add (.getContentPane) yellow BorderLayout/CENTER)) ...) looks a bit strange?

7:59 mibu: I have a theoretical question about special forms: why isn't let simulated with macros and fn? is it just a matter of practicality?

8:00 blackdog: looks to me like it is, core.clj line 24

8:01 AWizzArd: yes, let is implemented as a macro

8:01 mibu: oh, in the docs it appears as a special form

8:02 AWizzArd: Well yeah, it uses some magic

8:02 it expands into (fn* let ...)

8:02 mibu: no wait. it's not really a macro. it still uses a special form (let*)

8:03 AWizzArd: right, and let* is the real special form.. but let itself is a macro

8:03 rhickey: mibu: from a binding perspective, let can be defined in terms of fn, from a practical perspective, it never is, or, if it is, there is a special case of determining which fns don't need to be realized as proper objects. It is much simpler for them to be different

8:04 AWizzArd: In Common Lisp LET is also introduced as a special operator.

8:04 Some years ago I had an interesting discussion with Don Geddis about this issue.

8:04 mibu: rhickey: so it's only a practical matter, there isn't a theoretical limit, right?

8:04 AWizzArd: yeah, I was wondering why it's that way in CL too.

8:05 AWizzArd: In principle let and let* don't need to be special forms.

8:05 mibu: rhickey: same thing goes with loop? it could have been macro'd with fn and let, no?

8:07 rhickey: I personally see let defined via fn as taking it reduction one step too far, since in implementation you reintroduce the distinction, it's the difference between a minimal calculus and a language

8:08 AWizzArd: yes

8:08 rhickey: I think real languages and their use have cost models that matter. In Clojure, when you say fn you get an object, an overhead I wouldn't want to incur for let/loop

8:08 So I want them to be different and not to care about or rely on an implementation detail to optimize the non-realized cases

8:09 Others might prefer a minimal calculus, Scheme being a good example

8:09 mibu: hey, I wasn't complaining. just curious about theoretical limits. I'm all for practical compromises.

8:10 rhickey: Scheme maximizes what you can do with lambda

8:10 duck1123: for most people, it doesn't affect anything if it's a special form, a fn, or a macro. It works, that's all that matters

8:12 AWizzArd: How can I do frame.getContentPane().add(yellowLabel, BorderLayout.CENTER); inside a (doto frame ...)?

8:12 mibu: rhickey: on the subject of special forms, what's your take about exceptions in clojure, are they interop necessities or a legitimate flow control idiom? (I'm asking because they appear in the docs in the special forms section and not in the java interop section, where other necessary special forms are. )

8:12 rhickey: I don't think exceptions should be used for flow control in general

8:14 mibu: rhickey: I meant as a legitimate language construct in a functional programming language, not a botched up loop or switch

8:14 rhickey: mibu: not exceptions, maybe continuations

8:15 mibu: rhickey: aren't they the same as far as being side-effects?

8:18 rhickey: I'm thinking more about hierarchical exceptions where some intervening code can intercept your non-local transfer by catching its super class

8:19 mibu: rhickey: isn't that like interrupt handlers?

8:25 AWizzArd: I think (. frame (getContentPane) (.add panel BorderLayout/CENTER)) is equivalent to frame.getContentPane().add(panel, BorderLayout/CENTER);

8:26 But how can one do this with (.add ..) in the front, or (.getContentPane ..) instead of (. frame ...)?

8:26 And how can one do this in a (doto frame ...)?

8:32 rhickey: AWizzArd: (.add (.getContentPane frame) panel BorderLayout/CENTER)

8:32 AWizzArd: hmm yes, I tried this first, but got some strange exception

8:33 rhickey: btw, in your example under "Hosted on the JVM" you say (doto frame ...) and all these java functions don't start with a dot, as in (.add ...), but it simply is (add ...)

8:33 Lau_of_DK: (.. frame (getContentPane) (add BorderLayout/CENTER)) <-- Isnt that it AWizzArd ?

8:34 AWizzArd: when I do begin with (.add ...) it complains: No matching method found: add for class javax.swing.JPanel

8:34 Lau_of_DK: I will try the .. syntax. But I still don't know if this is supported inside a (doto frame ...)

8:35 Lau_of_DK: I can do it with one dot: (. frame (getContentPane) (add panel BorderLayout/CENTER)), and this also works.

8:36 Here I don't have to use dots for calling getContentPane and add.

8:36 Lau_of_DK: k

8:36 AWizzArd: But the example under http://clojure.org/jvm_hosted maybe came from an earlier version of Clojure. There one did not have to use the dots inside a doto.

8:43 Lau_of_DK: Yes that was a recent change

8:44 AWizzArd: currently the dot syntax is not fully consistent i think

8:44 Lau_of_DK: AWizzArd: I dont know what you arrived at, but it can be done like this (doto frame getContentPane (.add panel BorderLayout/CENTER)) I think

8:45 I think its consitent in code, but not in docs

8:46 rhickey: doto is about doing a set of actions to the same object, that's not what is happening here

8:46 AWizzArd: I mean: (. frame (getContentPane) (add panel BorderLayout/CENTER)) vs (.add (.getContentPane frame) ...) in the first version there is a dot, a space and then the object follows. Now function calls don't need to be prefixed by a dot.

8:47 rhickey: (. frame (getContentPane) (add panel BorderLayout/CENTER)) is not right, you need (..

8:48 AWizzArd: well, this currently works for me, without ..

8:48 or was this recently changed? I have a clojure.jar from early December

8:49 duck1123: AWizzArd: it was some time last month I think

8:50 svn rev 1111

8:50 clojurebot: svn rev 1111; enhanced doto now supports functions as well as methods !! Note - breaking change - you must now use .method instead of just method: (def frame (doto (new JFrame) (add panel) pack show)) becomes: (def frame (doto (new JFrame) (.add panel) .pack .show))

8:53 lisppaste8: AWizzArd pasted "dot syntax" at http://paste.lisp.org/display/71905

8:53 AWizzArd: That works for me

8:55 duck1123: what happens if you put a dot in front of add?

8:55 other than that, it looks good to me.

8:56 AWizzArd: it still works

8:56 that is what I mean with consistency

8:57 rhickey: AWizzArd: it doesn't work, it is wrong as I said, you have to use ..

8:58 if you use . and supply extra args they are ignored

8:58 AWizzArd: Well, here I see that it works in the sense that the window appears.

8:58 rhickey: user=> (. "foo" (length) (print 42))

8:58 3

8:58 AWizzArd: As soon I begin with .. it does not work anymore: No matching method found: add for class javax.swing.JPanel

8:59 lisppaste8: rhickey annotated #71905 with "dot options" at http://paste.lisp.org/display/71905#1

9:00 AWizzArd: I will try -> now

9:01 No, strangely it works only when I have what I pasted above.

9:01 rhickey: AWizzArd: your code is broken in other ways too,

9:01 AWizzArd: swing wise you mean?

9:01 rhickey: read the Java docs and make sure that's what you are doing - you are trying to add a layout to a panel

9:02 if you are confused by the syntax, do only one step at a time

9:02 AWizzArd: I will update my clojure.jar and see if that brings any changes.

9:02 rhickey: AWizzArd: you just have bugs

9:03 panel (new BoxLayout (new JPanel) BoxLayout/X_AXIS) is wrong

9:04 in that panel is the layout itself

9:05 AWizzArd: Okay I see. Well, I just started looking into Swing and just play with it.

9:05 blackdog: AWizzArd, have a look at miglayout to simplify your life

9:05 well your code anyway :)

9:06 AWizzArd: Is there a way to do guis under Java with something corresponding to what is html to the webbrowser?

9:06 blackdog: AWizzArd, will be soon

9:06 http://weblogs.java.net/blog/alex2d/archive/2008/12/jwebpane_projec.html

9:06 can't wait for that

9:07 AWizzArd: Well, in that case one could simply let the designer do the gui. He knows it 100x better anywa.

9:07 +y

9:08 blackdog: is that only for FX applications? Or can it be used without WebKit, inside stand-alone Clojure apps?

9:08 blackdog: it will be standalone i think, general use that is

9:09 it embeds webkit

9:09 can't use without

9:09 AWizzArd: blackdog: btw, do you know if it is possible to write JavaFX applications exclusively by using Clojure? Or will one have to write JavaFX Script at some point to make it possible?

9:09 blackdog: ah, well i think someone needs to do a comparable api

9:09 mainly javafx uses the scengraph stuff

9:10 so that is open for anyone to get into

9:10 duck1123: JavaFX looked cool, but it looks like you need to jump through a few hoops to get it working with linux

9:10 blackdog: so a similar api in clojure would probably be very easy

9:12 AWizzArd: duck1123: that doesn't matter too much, because in 1-4 months it will work under Linux. 2010 it will seem as if it never were different.

9:12 Clojure does not run on mobile phones yet. But noone will care about it anymore in 1-2 years.

9:12 (because then it most likely will)

9:12 blackdog: duck1123, http://silveiraneto.net/2008/12/06/javafx-sdk-10-on-linux/

9:13 duck1123: right. I'm not saying it will be a major problem. I'm just saying it annoyed me when I went to check it out after it was mentioned the other day

9:13 AWizzArd: Yes, same here *seufz*

9:14 duck1123: blackdog: ok, that one is easier. The one I saw involved mounting the mac package

9:21 AWizzArd: rhickey: does http://clojure.org/jvm_hosted need an update? (as there are no dots before the method calls)

9:23 rhickey: AWizzArd: the docs correspond to the release

9:24 AWizzArd: and the api to the svn?

9:38 cemerick: does proxy creation still use reflection in svn head?

9:43 rhickey: cemerick: no

9:43 (macroexpand '(proxy [Object] []))

9:43 duck1123: Is it possible to use clojure to gen-class a completely plain class. (without all the dynamic stuff that allows you to change the code without recompiling)

9:44 I know it's like having a swiss army knife and throwing it all out for the little plastic toothpick, but some might have a use for it

9:45 rhickey: duck1123: what advantage would that have over Java, once you had to add all the goop to specify types, access specifiers etc? Java with parens

9:45 cemerick: I can't say I knew what (proxy [Object] []) expanded into before, but that's very good to know.

9:45 I think we might move our codebase to some svn head shortly

9:46 duck1123: IDK, I'm still fighting Tomcat, and I'm just rying to reduce this down to the most basic level to figure out what's going on

9:46 AWizzArd: duck1123: but in Jetty you made it work, right?

9:46 rhickey: cemerick: it called construct-proxy, which was and still is reflective

9:46 duck1123: oh yeah, It works in Jetty no problem

9:46 rhickey: duck1123: clojure classes work fine in tomcat

9:47 AWizzArd: duck1123: but you also had to do something special to make it work in Jetty?

9:47 rhickey: where is clojure.jar in you tomcat setup

9:47 ?

9:47 AWizzArd: I know at least that Clojure-classes+Jetty+Rife can't be combined easily. Chouser and I tried it for some time, but there were other hurdles.

9:48 duck1123: It's in webapps/{projectname}/WEB-INF/lib

9:48 rhickey: rife is a completely different thing, runtime bytecode modification

9:48 duck1123: and you've tried a simple hello world servlet?

9:49 duck1123: That's what I'm using. It just spit's out a basic html hello world page using strings

9:49 AWizzArd: rhickey: Rifes author said that the bytecode transformation happens transparently. So that should not be the problem.

9:50 duck1123: http://paste.lisp.org/display/71768#2

9:52 I found a test suite that tests servlets, but I have a feeling that since Jetty works, it's going to say it's fine

9:53 Chouser-away: AWizzArd: Rife may yet be a (relatively) simple classloader thing, that's just an area I don't know much about.

9:54 AWizzArd: same here

9:55 duck1123: I'm tempted to do like Webjure does and cheat by writing Java code to define the servlet, but I really don't see any reason why this shouldn't work

9:56 rhickey: duck1123: what's your xml like?

9:57 lisppaste8: duck1123 annotated #71768 with "Web.xml that goes with this" at http://paste.lisp.org/display/71768#3

9:59 duck1123: I have a java version (Servlet2) that works fine when I change the servlet-class, but as it is I only get 404

10:17 AWizzArd: When I have a Java method foo which takes an array of strings as argument, can I then simply pass in Clojures vectors?

10:18 (foo ["a" "b" "c"]) vs. String[] bar = {"a", "b", "c"}; obj.foo(bar);

10:21 Chousuke: AWizzArd: (.foo obj (to-array vec-of-args)) or something should work.

10:23 or into-array if you need to specify the type

10:26 AWizzArd: Is there a gui builder that works nicely together with Clojure code?

10:27 Swing is by far too complex, with it's containers inside containers, that all need to be handled specifically, depending on if their layouts come from awt or swing.

10:47 rhickey: duck1123: your servlet (with only different names) works fine for me on Tomcat 6.0.18

10:47 RSchulz: The Groovy folks have a DSL for building Swing GUIs. There might be some ideas there for a Clojure counterpart.

10:57 duck1123: hmm... perhaps I need to get the latest version. I'm using Tomcat 5.5 (only one in Debian apt)

10:59 rhickey: I took out load-on-startup - it created an error on startup, but didn't prevent from working

10:59 how are you trying to invoke the servlet?

11:02 duck1123: http://localhost:8180/mycyclopedia/

11:02 where 8180 is the port it was running on

11:03 jkantz: I've been trying out http://www.zentus.com/sqlitejdbc/ from within clojure

11:03 but I'm running into a problem where putting a statement in a closure closes it

11:03 rhickey: duck1123: do you see the app in tomcat manager?

11:03 lisppaste8: jkantz pasted "sqlite3 inserts" at http://paste.lisp.org/display/71914

11:04 cemerick: AWizzArd: Our general approach right now is to use netbeans' matisse to design UI's, and have everything but the top level of event handling, etc., be handled by clojure fns we call into from the UI.

11:05 duck1123: rhickey: yeah, it was showing up there just fine

11:05 AWizzArd: cemerick: okay, so I will checkout netbeans in a few days

11:05 cemerick: IMO, building UIs without a visual designer is a disaster waiting to happen. Every UI framework is far too complicated to hand-code.

11:06 lisppaste8: jkantz annotated #71914 with "2 throws the error" at http://paste.lisp.org/display/71914#1

11:10 RSchulz: cemerick: I think there's a subset of uses, very stylized dialogs, e.g., that are amenable to a simple description language.

11:12 cemerick: RSchulz: sure, but if you're talking about generalized UI design, that description language would inevitably degenerate into a direct wrapper around whatever widget lib you happen to use.

11:12 AWizzArd: cemerick: with html it works out pretty well

11:13 cemerick: AWizzArd: wow, really? 9.9

11:13 AWizzArd: If I could just write an xml file, similar to html or whatever, but adopted to swing, and then just call (.loadUI "/path/gui.xml") and be done, then that might be nicer ;-)

11:14 RSchulz: cemerick: Sure. I was asking a couple of days ago about a Clojure counterpart for MPW's commander, which was just a DSL for parameter-gathering dialog boxes used to invoke CLIs for the CLI-phobic.

11:14 I still think that's appropriate (and something I could use).

11:15 cemerick: It seems that HTML/XHTML/css/js is a prime example of the inherent complexity of UI programming.

11:16 RSchulz: I'm not familiar with commander, but that sounds like a very narrow scope. A perfectly reasonable place to use a data-driven UI generation approach, but I don't think that's generalizable.

11:17 RSchulz: Generalizable? Surely not. But within its bounds, a productivity win, I'd say.

11:17 cemerick: Do you do a lot of full-blown Java / Swing / etc. GUIs?

11:17 GUIs aren't my thing.

11:18 cemerick: RSchulz: It's by no means my main thing. But I've been steeped in that for the past few months.

11:18 RSchulz: What do you think of that JavaFX thing? Good?

11:19 For my work, BBIs are the thing, I believe.

11:20 cemerick: RSchulz: I poked at the "launch" site a little. I've not been impressed with javafx since it was originally "announced" as an afterthought reaction to AIR and silverlight.

11:20 RSchulz: AIR is the follow-on to Adobe Flex?

11:22 cemerick: I think they're using another name for it now, but AIR is Flex, transparently deployable as a RIA (i.e. embedded in a browser) or as a thick-client, offline app.

11:23 I'm actually hopeful about the new-style applets available in java6-update10. It includes all of the guts that javafx needs (which are actually decent, technically), as well as a lot of deployment simplifications that have always made applets nigh-useless IMO.

11:25 RSchulz: BBIs?

11:26 RSchulz: I'm pushing the term (as far as I know, of my coinage): Browser-Based Interface

11:26 Web 2.0 stuff. AJAX; what have you.

11:26 cemerick: ah. "RIA" will be a formidable competitor.

11:27 RSchulz: I'll be happy when all the distinctions are erased and the programming models are easy in every deployment mode.

11:27 But I won't be holding my breath.

11:30 AWizzArd: cemerick: have you tried NetBeans gui builder, together with Enclojure already?

11:31 cemerick: AWizzArd: Using it now, although enclojure doesn't have anything to do with it, short of providing the clojure programming niceties.

11:31 matisse generates java, period.

11:32 AWizzArd: and how to you add event listeners for button clicks? In Clojure?

11:34 cemerick: AWizzArd: No, the top layer of the UI is all Java...and really, at least in my case, there's very little actual code there. When I need to hook into the real guts of the app (to put together a visualization to be drawn in the UI, for example), then I call into clojure.

11:34 I also have a couple of controller interfaces that call back into API points I've set up in the UI so I can drive certain parts of it from the clojure side.

11:35 AWizzArd: So when you add a button, you will write a clojure function foo and call it in the java event handler?

11:36 cemerick: only if the action to be performed is complicated enough, or requires interaction with APIs implemented in clojure.

11:36 AWizzArd: Otherwise you write it in Java?

11:36 cemerick: trying to be all-clojure top to bottom at the moment is going to require a lot of work that doesn't net one any reward, IMO

11:37 sure -- matisse takes care of the vast, vast majority of the real work, so the amount of java that needs to be written for simple event handlers and such is really miniscule

11:37 AWizzArd: Can Mantisse be modified to output Clojure code?

11:38 RSchulz: SMOP

11:38 cemerick: maybe :-) Some people are fiddling with it to make it emit JRuby, so it's possible in concept, I suppose.

11:38 I don't see what one would gain from that in practical terms, though.

11:39 AWizzArd: And let's say your event handler is complex enough, so that you will want to write a Clojure function which you then want to call in that handler. Does this mean that you have to wrap your Clojure function inside a (gen-class ..) to make it callable from Java?

11:39 I thought the practical terms are that you never need to write even one line of Java code.

11:40 cemerick: AWizzArd: no, it's not that difficult -- you just do RT.var("namespace", "fn-name").invoke(blah) (assuming the clojure is already loaded)

11:40 AWizzArd: You make a button and then simply say: (add-on-click-handler my-button (fn [x y mouse-button] ...))

11:41 cemerick: sure, that's certainly doable, but not with the tools the way they're set up now. You'll have to roll your own UI design environment, or UI description language, or modify matisse or some other toolset to get there.

11:41 AWizzArd: So, there is still a long way for Enclojure to go :-)

11:41 cemerick: purging Java isn't big on my to-do list. I'll live if my time in Java is cut to 10% or something.

11:42 I don't think the enclojure guys have said anything about tackling UI design.

11:42 AWizzArd: It's maybe okay for people who actually know Java...

11:42 Otherwise going down to 0% should be the goal.

11:43 cemerick: clojure runs on the jvm, so short of very isolated research purposes, it'll be tough to not touch java sometimes.

11:57 Chousuke: AWizzArd: you can't avoid java, but a lot of it can be hidden with functions and macros and some proxying :)

11:57 AWizzArd: Why do you think that Java can't be avoided?

11:57 Maybe for doing some low level (assembler-like) optimizations Java could come in handy.

11:57 Chousuke: because that's not what clojure is trying to do.

11:58 AWizzArd: Chousuke: do you have some typical things in mind where one would have to write .java code for a project that could not be written in .clj?

12:00 Chousuke: hm, not really.

12:00 AWizzArd: It would mean that there exists methods in Java that can't be called from within Clojure. Or that one wants to work in a Java project that makes use of annotations which can't be generated in Clojure at the moment.

12:01 achim_p: hi all!

12:01 AWizzArd: I understand that cemerick knows Java and does not feel much pain to write it from time to time. He just wants to do it less often, so for him the Mantisse+Java+Clojure combination works.

12:01 I however come from Common Lisp, and I didn't do it to write more Java than I did in the past (0% that is *g*).

12:02 Chousuke: hm

12:02 achim_p: has it always been the case that you weren't allowed to await an agent from within an agent action?

12:02 lisppaste8: achim_p pasted "awaiting awaiting awaiting" at http://paste.lisp.org/display/71922

12:02 Chousuke: it's pretty hard to avoid using java if you use libraries designed to be used from java. clojure has a disadvantage.

12:02 cemerick: AWizzArd: I think an all-clojure UI framework would be very, very warmly welcomed, including by me. Such a beast just doesn't exist (yet?).

12:03 Chouser: achim_p: I think it's always been that way, yes.

12:03 AWizzArd: I just don't know swing very well. If I did I could write a wrapper in Clojure that reads xml or s-expression files and could generate UIs from that. It would not be a declerative language so to speak.

12:03 cemerick: Chousuke: clojure's java interop is what makes it practical, IMO

12:03 Chousuke: cemerick: yeah.

12:04 AWizzArd: cemerick: yes, I guess in 3-5 years such a thing could exist, if Clojure can attract some 10k programmers.

12:04 Chouser: achim_p: the problem is that sends from inside an agent are held until the agent is complete. await doesn't make sense.

12:04 cemerick: AWizzArd: *shrug* Swing is essentially the only option in Java land w.r.t. UIs (short of SWT, which I'll rudely ignore :-) )

12:05 There may very well be a declarative swing layout library out there already that you could wrap with clojure...?

12:05 Chousuke: AWizzArd: Did you look at QtJambi? there were some examples some time ago that used a QT GUI builder and resource files and no java (though the API obviously isn't very clojurey either)

12:05 Chouser: Lots of people seem to be playing with Clojure and Qt/Jambi

12:05 ...which has a nice graphical GUI editor, if you're into that sort of thing.

12:05 AWizzArd: cemerick: what about this: you make a gui with Mantisse, put it into a single .class file and load that from Clojure. There you make an instance of it which should show the gui. Then you get all objects that need event handlers and add them in Clojure.

12:06 Chousuke: that could work.

12:06 duck1123: rhickey: I installed Tomcat6, deployed my app and it ran without a hitch

12:06 achim_p: Chouser: oh, i didn't realize they were. thanks for the pointer!

12:06 walters: cemerick: i use GTK+ through bindings I wrote, works great

12:06 (and Clutter)

12:07 AWizzArd: Chouser: but what does the qt gui builder produce? Will it allow me to click together my gui and then do the rest in Clojure? Such as onClick or onKeyPress handlers, etc?

12:07 Chouser: AWizzArd: yes

12:07 cemerick: AWizzArd: certainly doable. There's a lot of manual bookkeeping there, but if avoiding Java is your priority, then it just might work.

12:07 Chouser: the qt gui builder produces .xml

12:07 AWizzArd: And why isn't that possible with NetBeans+Mantisse+Swing?

12:07 I see

12:07 Chousuke: AWizzArd: why wouldn

12:07 wouldn't it be?

12:07 cemerick: the same degree of bookkeeping would be necessary with Qt, I presume

12:07 Chouser: in clojure you can load the .xml, and then hook up wantever signal/slots you want.

12:07 Chousuke: I don

12:07 gaH

12:08 AWizzArd: So the qt gui builder basically does what I asked for. It produces something comparable to .html files.

12:08 Chouser: duck1123: wow, just like that?

12:08 cemerick: walters: that's interesting. Can't say I'd want to learn yet another widget toolkit, though. :-)

12:08 AWizzArd: While the Mantisse builder produces .java code.

12:08 Chousuke: code generation ;(

12:08 duck1123: Chouser: just like that... Obviously there's something wrong with 5.5 + clojure

12:08 RSchulz: Not to harp on spelling / typos, but it's "Matisse," right?

12:08 walters: cemerick: http://live.gnome.org/GObjectIntrospection/ if you're interested

12:09 cemerick: RSchulz: yes

12:09 walters: cemerick: (more specifically http://live.gnome.org/JGIR )

12:09 cemerick: walters: ah, it's JNA-based?

12:09 duck1123: Now I just need to figure out how to get a repl working with this so I can hack at some live code

12:09 walters: right now yeah

12:10 though i am about on the edge of writing something more lowlevel and efficient

12:10 cemerick: walters: I was going to say, JNA uses reflection for fn invocation, which would be troublesome depending on how much you're pushing through the keyhole.

12:10 walters: right

12:11 the way it does structs and unions is also really bad (implementation wise)

12:14 cemerick: AWizzArd: a couple of declarative swing libraries you might be able to wrap: http://www.swixml.org/ http://jacekfurmankiewicz.blogspot.com/2008/06/java-swingbuilder-finally-01-beta.html

12:18 AWizzArd: you could also take a look at JWebPane, which might be just the ticket based on the 2.5 blog posts I've read about it ;-)

12:32 RSchulz: clojurebot: todo?

12:32 clojurebot: todo is http://richhickey.backpackit.com/pub/1597914

12:34 RSchulz: Is there a technical reason why special forms don't have doc strings?

12:37 Chouser: RSchulz: where would they be stored?

12:38 RSchulz: I don't know. Where are other doc strings stored?

12:38 Chouser: in the metadata of the var

12:38 but special forms don't have vars

12:38 RSchulz: It seems plausible that whatever Java constructs embody the run-time definition of special forms could be the locus of a doc string, right?

12:40 Surely doc could have special-case code for speical forms that looked in some place other than the (non-existent) Var for special form document strings.

12:46 rhickey: RSchulz: there are only a handful of special forms - they have long descriptions that really need to be read before using Clojure

12:46 RSchulz: OK. But something synoptic still seems useful for a (doc) result?

12:54 cemerick: rhickey: I'm curious: why doesn't RT.toArray produce results for IPersistentCollections? It seems like the class-is-array block can be directly used for IPC's as well.

12:56 rhickey: cemerick: it used to be that Collection covered all IPCs

12:56 now all but maps

13:05 abrooks: In a flourish of ignorance -- what sorts of things would break if we defined vars for builtins to hold their docstring?

13:05 Ala: (def #^{:doc "More fn* than you can imagine"} fn* "fn* is builtin")

13:06 rhickey: what is the purpose of these docstrings? are people forgetting how fn/let/do work?

13:07 RSchulz: No offense, but you're pretty deep inside Clojure to understand a beginner's mindset...

13:07 abrooks: rhickey: If you can tell a new user (doc foo) will tell you about foo, they're going to be surprised when that thing that they saw in the example (and perhaps even read about once before) doesn't have a doc string.

13:08 RSchulz: Well, to be fair, it refers you to the Web documentation.

13:08 rhickey: But I do remember learning CL, and I never wanted doc strings for defun or let, always looked in documentation, vs quickie arg lookup for other things

13:13 abrooks: rhickey: You're a long time lisper -- beginners don't remember which forms are special and which are not. The (a) beauty of lisp is that the both appear the same.

13:13 zakwilson: When I first started with Clojure, the fact that some arguments that would be lists in most lisps are vectors bit me several times.

13:14 And "Don't know how to create ISeq from Symbol" didn't help.

13:14 abrooks: rhickey: I recognize special formsm when I see them but I could not rattle off a list off the top of my head.

13:15 RSchulz: Oh, right. It does send you to the web docs.

13:15 RSchulz: Not so useful if you're at a REPL and offline without the web docs, though.

13:16 Also, that link will be broken when the website changes and someone's still running an older version of Clojure.

13:18 RSchulz: My guess is that clojure.org will be the Clojure Web site as long as Clojure is alive.

13:19 alphazero: Hi all! Does anyone know what is the baseline target jre for clojure? (1.1, 1.3, etc.)?

13:20 Chousuke: 1.5

13:20 cemerick: rhickey: I asked, because I have a couple of IPC implementations, and I always forget to wrap them in seq in order to use them with sort, etc.

13:20 whidden: Is there an equivalent function in clojure of CL's 'find-all-symbols ?

13:22 alphazero: Chousuke: thanks! then it would be nice if a shutdownHook was added to repl.java.

13:22 rhickey: cemerick: but you don't want to implement Collection?

13:25 cemerick: rhickey: They implement Iterable, but that's as far as I want to go. Java-land API users simply don't get the notion of implementing only the read portions of Collection (despite the interface's contract).

13:28 Chousuke: alphazero: the repl is a clojure function. do you need to have the shutdown hook in the java code? maybe you could add it from clojure :/

13:29 abrooks: whidden: all-ns will show you all namespaces. ns-map (and in varying slices: ns-aliases, ns-imports, ns-interns, ns-publics and ns-refers) will show you what's in a given namespace.

13:30 whidden: abrooks: thanks...just what i needed!

13:30 alphazero: chousuke: hah! am a Java old timer but very (very) new to lisp and clojure. (rhickey: didn't see you here earlier. Great stuff! Thanks for clojure.)

13:32 .. could give you the patch for java if you want. (I didn't like how it just dies after ctl-c so added a goodbye msg to mine, but wasn't sure if rhickey wanted to be backwards compatible with pre 1.3 jvms.)

13:37 Chousuke: alphazero: You want something like this? (.addShutdownHook (Runtime/getRuntime) (Thread. (fn [] (println "Goodbye World!"))))

13:38 lisppaste8: alphazero pasted "shutdown hook for Repl.java" at http://paste.lisp.org/display/71931

13:39 Chousuke: oh, I should've used #(println "Goodbye world") ;P

13:40 RSchulz: Chousuke: Since Clojure functions imlement Callable and Runnable, couldn't you skip the (Thread ...) part?

13:40 alphazero: Chousuke: yep, thanks for the clojure version.

13:40 ? what's the diff? I pasted yours and it worked.

13:41 RSchulz: The #(...) notation is just more concise, in situations where it's applicable.

13:42 alphazero: RSchulz: thanks.

13:43 RSchulz: Perhaps (doc ...) deserves to be a multimethod? Then 3rd-party add-ons could extend it in interesting ways. And the overhead of multimethod dispatch wouldn't be a problem in that case.

13:46 alphazero: Chousuke: tried (.addShutdownHook (Runtime/getRuntime) (Thread. (#(println "Goodbye World!")))) and it immediately executes.

13:47 .. and it doesn't actually run on shutdown. can someone explain why please?

13:47 Chousuke: alphazero: you have an extra pair of parentheses

13:48 #(println "foo") returns a function (#(println foo)) runs a function :)

13:48 alphazero: Chousuke: Aha! the mysteries of lisp. you are right.

13:48 Chousuke: RSchulz: .addShutdownHook wants a Thread

13:49 RSchulz: That's rude of it.

13:49 It should be satisfied with a Runnable...

13:50 Chousuke: alphazero: anyway, #(foo bar) is just a more concise way of saying (fn [] (foo bar)) :)

13:51 alphazero: Chousuke: thanks. Yep, RSchulz mentioned that earlier.

13:51 Chousuke: of course if you want a function with more than one expression you'll need to use fn. or #(do (foo) (bar)) :P

13:52 alphazero: a more general question: do you guys think clojure is a good platform for scripting bytecode engineering? (Specifically, can it do something like aspects without the pain of asm, etc.?)

13:53 Chousuke: you could implement aspect-oriented programming constructs in clojure I suppose.

13:55 alphazero: I ask, since multimethods seem to be an excellent way to write crosscut specs and coupled with ad-hoc taxonomies ...

13:55 Chousuke: I'm not that familiar with aspect oriented programming, so I can't really say anything about that.

13:56 duck1123: when using gen-class, the -init fn is essentially the constructor right? (with the exception that it must return a vector)

13:56 Chousuke: but for example, you could redefine defn to work in a way that wraps every defined function in a way that checks (from a global data structure, for instance) if there are any things to run before or after its execution.

13:58 alphazero: Chousuke: in a nutshell: you define pre- and -post ops for a signature pattern and apply it across class hierarchies. e.g.: you say whenever a method return void with params Foo, Object[] is called, first pass the args throw this -pre method and then after the actual method is done call this -post method. Its a very powerful mechanism.

13:59 through

13:59 cemerick: rhickey: thinking about it a little more, to-array really should accept any IPC, in order for third-party IPC implementations to be peers to standard data structures.

13:59 (IMO, of course ;-) )

14:02 Chousuke: alphazero: I think that should be doable, but would require a fair amount of trickery

14:03 alphazero: Chousuke: well, I was thinking wrapper functions would do it, but then, not sure how that would help with (existing) java classes. So question is: does the clojure import mechanism allow you to customize its classloader?

14:04 Chouser: duck1123: I think that's right, though I believe -init gets run before the object is created.

14:04 alphazero: because then you could script that

14:05 Chousuke: alphazero: you'll have to read the code and see how clojure imports stuff. I don't know :/

14:06 alphazero: Chousuke: will do, thanks. I have to step out for lunch but if anyone has an idea and posts it it is appreciated and I will read the logs. bye for now.

14:10 duck1123: every time I try to use an init, I get: Duplicate field name&signature in class file

14:12 you know what, this class has a method named init... that's probably causing a problem

14:18 ok, If I'm implementing an overloaded fn, do I have to provide implementations for both of them, or can I specify which one I'm doing?

14:27 Lau_of_DK: Good evening gents

14:27 duck1123: hello Lau_of_DK

14:28 Lau_of_DK: duck1123: Hows your projects coming along?

14:29 duck1123: actually, I upgraded to Tomcat 6, and like a miracle, it worked

14:30 Lau_of_DK: Wuhuu! :)

14:30 What did?

14:30 duck1123: gen-classing a servlet and dropping it into tomcat

14:31 Lau_of_DK: Oh, from pure clojure?

14:31 duck1123: now I'm trying to get a repl put in there so I can modify the code

14:31 Lau_of_DK: Duck I dont know which country youre in, but Tomcat is very hot in Denmark atm

14:31 duck1123: yeah. My code was right, it's just something funky with Tomcat 5.5

14:31 Lau_of_DK: I'll remember that

14:32 duck1123: I'm in Michigan, USA

14:32 Lau_of_DK: JBoss server selling like hot bread there? :)

14:33 duck1123: I really wouldn't know.

14:36 Chouser: duck1123: there is a (still undocumented, I think) feature that lets you add arg types to your function name.

14:37 duck1123: like (defn -foo-Integer-String ...) for an implementation of foo that takes 2 args of those types.

14:37 duck1123: but I've never tried to use it, so that's about all I know.

14:39 duck1123: Chouser: thanks. What if it doesn't take any args? -init-Void?

14:40 Chouser: good guess. dunno. :-)

14:41 try -init-void

14:41 Lau_of_DK: Hey Chouser

14:41 Chouser: Lau_of_DK: hey!

14:42 RSchulz: tomhickey, rhickey: Thanks a million for fixing up the API page. The underline thing is still happening for (ns ...) (only)

14:45 acieroid: is there a way to download the videos of clojure.blip.tv ?

14:47 danlarkin_: toward the bottom you can subscribe

14:48 Lau_of_DK: acieroid: Or change the type of video to .mov, then as I recall you get enough in the adresse line to pass it to wget

14:48 Thats how I usually do it

14:49 acieroid: and how do I change it to .mov ?

14:49 Lau_of_DK: Hang on let me look

14:50 In the top right corner, choose Episode Archive

14:50 Then select the video you want to download

14:50 Then when it starts playing, you have a dropdown box right below where you can choose .mov

14:51 acieroid: yeah ok

14:51 thanks

14:52 Lau_of_DK: But looking at it now, I forgot how I modified the adress to become downloadable, but you can probably work it out

14:52 :)

14:55 acieroid: hum

14:56 I just found the flv in the firefox's cache

14:57 Yeah, great, if I change the .flv to .mov, it works

14:57 thanks

14:58 rhickey: acieroid: there's a Download Playing link at the bottom when playing from the episode directly

14:59 hiredman: rhickey: what are the odds of (show ...) or something like it showing up in clojure.core?

15:00 rhickey: hiredman: good, although it will likely be an enhanced inspect

15:00 gnuvince: rhickey: Do you have any upcoming speaking engagements?

15:01 hiredman: excellent

15:01 rhickey: gnuvince: QCon London and ILC Cambridge in March

15:01 gnuvince: Thank you.

15:07 mchurch: I have a design question re: Clojure.

15:08 I'm starting to use it, and I like it, but why is it set up so that two primitives can be print/read equal and yet nonequal?

15:08 e.g. (symbol "nil") is something that prints as nil but is not actually equal to nil

15:10 Chousuke: that's because it's not nil, it's a symbol that looks like nil when printed :)

15:10 rhickey: mchurch: there is print-dup, with more verity along with more verbosity.

15:11 mchurch: What's print-dup?

15:11 rhickey: nil is special, not read as a symbol as in CL due to its unification with Java null

15:11 mchurch: Clojure's great, but I really dislike the idea of ambiguous read/print syntax.

15:12 Ah, this makes sense.

15:12 rhickey: well, printing the symbol nil and expecting to get a symbol when read is asking for trouble.

15:12 Lau_of_DK: mchurch: Does that really make much of a difference in the bigger picture of concurrency and functional programming?

15:12 rhickey: print-dup is a printing mode like print-readably, set with *print-dup*

15:12 mchurch: Yes. This is one of those pathological use cases that is unlikely to occur.

15:13 rhickey: print-readably has rough read/print equivalence, by data structure category, butif you look at CL, they just ended up with unreadble printed representations of so many things

15:14 print-dup does track the specific types, so sorted sets come back sorted. print-readably is readable but bot type equivalent, but still useful for repl

15:15 not type equivalent

15:15 mchurch: I'm writing some glue code for IPC between SBCL and Clojure, so I'm dealing with the question of how to unify the concepts of Nil/false in the "between language"

15:16 rhickey: mchurch: nil should be ok for IPC, as it is used similarly by Clojure, just isn't a symbol

15:16 false is a different thing, not in CL

15:17 mchurch: Yeah. The "ambiguity" I was worried about is not an issue for me right now. I just wanted to know why it was done that way, because a lot of things that seem "wrong" turn out to make sense.

15:18 Chousuke: how does print-dup work? there's no docstring

15:18 rhickey: right now print-dup is used only by serialization during AOT compilation, will get doc'ed soon

15:19 but it is used to serialize all constants, and they are read back with read, so print/read is important to me

15:19 mchurch: rhickey: Shall I assume you're Rich Hickey, the inventor of Clojure?

15:19 rhickey: Clojure just has a much richer type space than prior Lisps, so I ended up needing another level of 'readable'

15:20 mchurch: yes

15:20 mchurch: Your talk at the JVM conference was great; I watched it on video last night.

15:20 rhickey: thanks, it was quite rushed, but fun

15:20 Chousuke: the java side certainly complicates things for read/print

15:21 Lau_of_DK: mchurch: Is that on blib?

15:22 mchurch: http://news.ycombinator.com/item?id=392442

15:22 lisppaste8: rhickey pasted "print-dup in action" at http://paste.lisp.org/display/71933

15:23 Lau_of_DK: Thanks alot

15:23 mchurch: That's cool.

15:24 Mind if I ask (while I'm here) about the difference between let vs. bindings?

15:24 rhickey: those things read back precisely, but not as nice for the repl

15:25 mchurch: err, binding, sorry (I'm a 4-day-old newb to Clojure)

15:25 rhickey: let is for lexical locals, binding is for thread-specific dynamic binding of global vars

15:25 mchurch: you know CL?

15:26 mchurch: CL: 3 months old.

15:26 Plus some exposure to Scheme in college.

15:26 rhickey: ok, well CL does both kinds of binding in let, Clojure breaks them apart

15:26 binding ~~ Scheme fluid-let

15:27 let is the primary construct, binding is pretty special-purpose

15:27 mchurch: This makes sense.

15:28 So binding is used for constructs like (let ((*read-eval* nil)) ... ).

15:28 rhickey: mchurch: right, dynamic vars

15:28 mchurch: Although that's a bad example, since (I believe) Clojure's reader is side-effect free.

15:29 rhickey: binding *out*, *print-dup* etc

15:29 Clojure jobs! - http://groups.google.com/group/clojure/msg/9bcd9c42346206fa

15:30 danlarkin_: *drools*

15:30 abrooks: Awesome.

15:32 Lau_of_DK: rhickey: Can we expect some improvements on the performance characteristics of the STM that Mr. Click touched upon in his presentation? I ask, because he gave the impression that this was something that had been around for 15 years with little or no improvement

15:32 argh

15:33 * duck1123 wants a job doing clojure

15:34 Lau_of_DK: duck1123: start your own business? :)

15:35 danlarkin_: duck1123: wanna go into business together? I'm not moving to Michigan though...

15:35 * zakwilson has started some projects in Clojure that might turn in to products.

15:36 RSchulz: zakwilson: Elaborate, please!

15:36 * duck1123 is too broke to risk not getting paid

15:36 duck1123: I did, however, put Clojure on my resume on dice

15:37 Lau_of_DK: duck1123: You only need 1 good contract to carry yourself for 2� - 3 months :)

15:37 zakwilson: When I'm not writing software, I'm a lighting designer for a band.

15:37 Stage lighting controlers use profiles to determine how to control specific types of lights. All of them use different file formats.

15:38 * duck1123 produces microfilm, and writes the software to produce the layout files

15:38 zakwilson: There is no central place to get such profiles, and people like me often end up making half-complete profiles on the fly while setting up for a show because there's no profile for a specific light/controller combination.

15:38 cemerick: is there something along the lines of doseq that also binds the current index of the item in seq being enumerated? Something more concise than using (interleave seq (iterate inc )), preferably...

15:39 mchurch: rhickey: Thank you for taking the time to reply to me about Clojure. I'm really glad Clojure exists; it's a cool language.

15:39 zakwilson: I'm thinking profit could be made from a profile format that can be converted to most controllers on the fly.

15:40 Chouser: cemerick: clojure.contrib.seq-utils/indexed

15:40 zakwilson: Either by charging for access or by running ads on a website.

15:41 Chouser: cemerick: (doseq [[i foo] (indexed foos)] ...)

15:41 Lau_of_DK: Does anybody know if we can expect some improvements on the performance

15:41 characteristics of the STM that Mr. Click touched upon in his

15:41 presentation? I ask, because he gave the impression that this was

15:41 something that had been around for 15 years with little or no

15:41 improvement

15:41 :)

15:41 cemerick: Chouser: thanks much

15:42 blackdog: Lau_of_DK, i think his impression after doing the clojure tsp that is was going in the right direction

15:42 if you readthe blog entry

15:42 zakwilson: I'm also contemplating writing lighting control software, as I think everything currently on the market has obvious flaws. Professional lighting controllers are very expensive, and a sucessful product has a great deal of potential for profit.

15:42 Lau_of_DK: blackdog: Thats just not very concrete

15:43 RSchulz: I wonder how easily STM-based systems (such as Clojure) would re-target to hardware TM?

15:44 Lau_of_DK: Mr. Schulz, you certainly do

15:45 RSchulz: Eh? I do what?

15:46 Lau_of_DK: You wonder...

15:46 RSchulz: Yes... That's why I asked about it...

15:47 Lau_of_DK: I know. I was just confirming that fact. I cant be helpful 100% of the time you know

15:47 hoeck: zakwilson: cool

15:48 zakwilson: I'm actually stuck on something related to the first project, if anybody has some advice on reverse-engineering a file format.

15:57 AWizzArd: RSchulz: do you have your test for find-factors still available? I mean, do you remember for which number it produced a wrong result?

15:57 RSchulz: I think I can dig it up in my terminal back-scroll (it's set to 5,000 lines, and I have many tabs open, for different purposes).

15:57 Just a sec...

15:57 AWizzArd: thanks :-)

15:57 5k is not bad *g*

15:58 holmak: recur only goes back to fn's and loops, right? Not lets or anything strange?

15:58 RSchulz: If not, it'll be in the channel logs. Could someone remind me of the URL of those logs?

15:59 AWizzArd: holmak: yes

15:59 but also to defn's (which are fn's under the hood)

15:59 RSchulz: AWizzArd: Here it is: 43587438757

16:00 AWizzArd: thanks

16:00 RSchulz: factor 43587438757

16:00 43587438757: 21517 2025721

16:00 The various "find-factor" functions only gave the first factor.

16:00 AWizzArd: yes

16:01 lisppaste8: holmak pasted "recur problem" at http://paste.lisp.org/display/71936

16:02 holmak: I'm having a strange problem...

16:02 I'm getting an error that recur should be getting one arg, not two.

16:03 hiredman: uh

16:03 I don't think recur will work there

16:03 in a lazy-cons

16:03 holmak: That could be it, but I'm not getting a "not in tail position" error

16:03 hiredman: well

16:04 it is not in the tail position (I think) but that is not the problem

16:04 it is not being called in the context of that function

16:04 holmak: Ah

16:04 hiredman: because lazy-cons is, well, lazy

16:05 you should be ok calling chop again there

16:05 hoeck: holmak: lazy-cons is a macro, the recur gets wrapped in a function with one arg

16:06 holmak: I was wondering where the fn was coming from. Serves me right for trying to feed macros strange things...

16:07 hoeck: holmak: to me, your chop function looks like clojure.core/partition

16:08 holmak: I was trying to find a good standard library function to do what I wanted, but couldn't -- I'll take a look at partition.

16:09 Aha, wonderful. partition is what I wanted.

16:09 hoeck: yeah, did that too until I discovered partition :)

16:10 holmak: It can be hard to find the right standard function for things.

16:10 There's really a lot of things a person might want to do to a sequence.

16:12 Anyway, thanks for the help.

16:13 hoeck: takes some time to learn them, I often take a look at clojure.org sequences docs

16:29 lisppaste8: holmak pasted "partition by different sizes" at http://paste.lisp.org/display/71941

16:30 holmak: So ^^^ was my final solution, since I had to partition according by different sizes.

16:33 s/partition according by/partition by/

16:52 Lau_of_DK: holmak: Looks good :)

16:53 holmak: Thanks :D I don't know if it would be generally useful, but I happened to need it.

16:53 Lau_of_DK: In my experience helpers like that always come in handy sooner or later, so I tug them all away in my utility lib :)

16:53 s/tug/tuck

17:27 aperotte: hi, does anyone know how to print the stack trace?

17:27 blackdog: (.printStackTrace e) or some such

17:27 rhickey: *e

17:27 aperotte: thanks!

17:30 blackdog: well that's shorter :P you can tell who the master is

17:31 aperotte: blackdog: I think he meant *e instead of just e ... at least that's what worked for me

17:31 rhickey: right

17:31 blackdog: yep

17:34 aperotte: Am I right in thinking that the only way to expose protected members is through gen-class and AOT compilation?

17:34 rhickey: aperotte: yes

17:34 aperotte: rhickey: ok, thanks

17:48 rafting: How can I call Clojure-code from Java?

17:49 Chouser: Wide-open REPL type thing, or calling into a specific interface?

17:49 rhickey: rafting: Var someFn = RT.var("some.ns","some-fn"); someFn.invoke(someargs);

17:52 rafting: and the cloure-code shuld be compild to .class or i can call .clj-files?

17:54 rhickey: rafting: either, just put it in the classpath, you can require it by:

17:55 Var require = RT.var("clojure.core","require"); require.invoke(Symbol.intern("my.ns"));

17:55 etc

17:59 clojurebot: svn rev 1150; releaxed namespace requirement for derives in private hierarchy, patch from J. McConnell

18:01 rafting: how do i do repeatedly for a function with arguments?

18:01 aperotte: I don't know if this is my problem or a bug but here's what happened. I am extending an abstract class with :gen-class. There is one method that must be implemented and it shouldn't take any arguments. However, I get a clojure.lang.AFn.throwArity unless I define the method with [& args] instead of [].

18:02 hiredman: rafting: wrap it? #()

18:02 aperotte: explicit "this" argument

18:02 aperotte: ohhh

18:02 blackdog: rafting, apply?

18:03 aperotte: hiredman: thanks

18:03 hiredman: (doc repeatedly)

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

18:04 rafting: hiredman: yes i wrap it but i dont want to :)

18:04 hiredman: rafting: what?

18:05 then write a macro to wrap it for you

18:05 RSchulz: hiredman: Have considered a variant of clojurebot that would allow evaluation of Clojure forms? It would be risky if not restricted (say, no load calls) and would probably have to self-limit the amount of computation and I/O fron any given form evaluated, but it could be great to have for helping an experimenting here.

18:06 hiredman: RSchulz: I think chouser suggested I look at java's sandboxing capabilities

18:07 (+ 1 5)

18:07 clojurebot: *suffusion of yellow*

18:07 RSchulz: I doubt it would be trivial to do well, but it could be interesting and useful.

18:07 (shhh!)

18:07 I see it's selective about what it tries to eval.

18:08 hiredman: yes

18:08 RSchulz: A bot with discretion...

18:08 cemerick: You should be able to sandbox clojure without a hitch, especially now that namespaces and fn's clearly correspond to classes now.

18:09 hiredman: oh, this looks familar

18:09 I must have googled "java sandboxing" before

18:09 cemerick: even easier would be to lock off particular sections of RT.

18:09 RSchulz: Do Java's sandboxing mechanism extend to resource consumption limitation?

18:09 cemerick: not sure about that, maybe

18:09 hiredman: doing anything that is really involved in java makes me want to bak things

18:09 brake

18:10 RSchulz: Or, maybe, "break?"

18:10 hiredman: gah

18:11 aperotte: If I'm extending an abstract class with :gen-class, do I have to define the abstract methods in the same file or can I define those in a different context as well?

18:12 hiredman: you can define ththe functions that corrispond to class methods latter

18:12 as long as they are in the right namespace

18:13 aperotte: and the right namespace would be the same as the :gen-class ns or whatever namespace I happen to be in?

18:13 hiredman: it defaults to the gen-class ns

18:14 but you can specify it

18:14 aperotte: oh ok, that's right

18:14 thanks

18:14 hiredman: I just worked through this yesterday

18:17 aperotte: hiredman: thanks, those things would've taken me a little while to figure out

18:22 hiredman: clojurebot: sandbox is http://calumleslie.blogspot.com/2008/06/simple-jvm-sandboxing.html

18:22 clojurebot: Ok.

18:26 hiredman: oooh

18:26 very cool

18:28 RSchulz: What an odd coincidence... I just found a transcript of #haskell and it appears they have an evaluater bot called "lambdabot"

18:28 http://tuukka.iki.fi/tmp/haskell-2008-02-24.html

18:29 gnuvince_: RSchulz: yes

18:29 lambdabot is very cool

18:30 Chousuke: hm, that sandboxing stuff is rather verbose :P

18:30 RSchulz: gnuvince_: You do Haskell?

18:30 Chousuke: but then again, it's java :p

18:30 billc: RSchulz: for people who use ERC in emacs, creating a Clojure evaluator is trivial

18:30 RSchulz: What's ERC?

18:30 billc: (= 42 42) => true

18:31 Chousuke: RSchulz: elisp irc client

18:31 gnuvince_: RSchulz: a little, I enjoy it a lot. ERC is an Emacs IRC Client.

18:31 RSchulz: Thanks.

18:31 billc: (printf "%s" *ns*) => usernil

18:31 Chousuke: heh

18:31 RSchulz: I'm feeling pretty overloaded with things to learn lately: Clojure, FP, Emacs. Whew!

18:31 billc: lisppaste8: url

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

18:33 aperotte: hiredman: do you happen to have an example of :gen-class that uses :exposes?

18:33 gnuvince_: RSchulz: tell me about it; I'm into Clojure, learning git and I'm doing my calculus classes

18:33 hiredman: getting the default applet security policy is not very verbose

18:33 aperotte: sorry, did not get that far

18:33 RSchulz: gnuvince_: Sounds like your brain is younger than mine...

18:33 lisppaste8: billc pasted "ERC Clojure code evaluator" at http://paste.lisp.org/display/71946

18:34 RSchulz: gnuvince_: (based on the calculus class thing)

18:34 hiredman: (.setSecurityManager System (SecurityManager.))

18:34 then suddenly no file or net io in my repl

18:34 dunno what else is off limits

18:35 cemerick: hiredman: well, can't get much simpler than that...

18:35 hiredman: well, clojurebot kind of needs network io

18:36 and some file io too come to think of it

18:36 Chousuke: hiredman: (System/setSecurityManager (SecurityManager.)) ;)

18:36 hiredman: whichever

18:36 Chousuke: yeah. the / form is much nicer though.

18:37 hiredman: I guess

18:37 I see this in java a lot, that simple thing there does almost exactly what I want, but getting the exactly part is going to be hell

18:40 if I do have clojurebot eval forms, is there a preference for format?

18:40 Chousuke: Though for System I guess it's semantically correct to say you're calling the method on it. but I'd rather see Math/pow than (.pow Math 1 2) ... or, hrr, (. Math PI)

18:40 hiredman: would be easiest to prefix with , or something

18:40 Chousuke: remember to set print-length :P

18:41 hiredman: heh

18:42 RSchulz: hiredman: What do you mean by format?

18:42 hiredman: ,(do stuff)

18:42 like, we don't want it to just eval every sexp in the channel, right?

18:42 RSchulz: You mean what pattern does the bot trigger on?

18:43 Chousuke: that's unlikely to conflict with any clojure code

18:43 so fine with me :)

18:43 hiredman: RSchulz: yeah

18:43 RSchulz: Leading !, perhaps.

18:43 hiredman: Chousuke: because , is whitespace

18:43 rafting: what do i pass to sort from biggest to lowest?

18:44 RSchulz: rafting: Supplying your own Comparator would certainly work.

18:44 Chousuke: hm? (sort > [2 3 4 1 5])

18:44 hiredman: wrapping in a (reverse ...) might be easier if you are getting smallest to bigggest

18:45 Chousuke: or just (sort < [2 3 4 1 5]) :p

18:45 hiredman: oh

18:45 I see what you did there

18:46 RSchulz: How did you learn that sort would take a predicate? I assumed from the wording of the doc text that it required an actual Comparator.

18:46 Chousuke: RSchulz: in clojure predicates work as comparators.

18:46 at least, I think I read that in the SVN log a while ago :)

18:47 RSchulz: OK... But Comparators have to reutnr < 0, 0 or > 0 to signify the ordering relation that exists between their arguments.

18:47 Chousuke: I guess a predicate-turned-Comparator will never return a 0 then

18:48 RSchulz: Unless whatever converts it implicitly checks for = (first?)

18:48 Chousuke: hm, right.

18:50 did clojurebot have a log lookup function for revisions?

18:50 anyway, r1088: made AFn's Comparator.compare work with predicates too, true values sorting first

18:51 hiredman: svn rev 1088

18:51 clojurebot: svn rev 1088; made AFn's Comparator.compare work with predicates too, true values sorting first

18:53 gnuvince_: RSchulz: I'm 25. Been out of school for 5 years and I've decided that I want to go back and get my bachelor's degree

18:54 RSchulz: gnuvince_: Yuh-huh. I see your 25 and raise you 25 more. (The AARP's on my ass...)

18:55 gnuvince_: RSchulz: wow

18:55 I'll repeat what I said a few weeks ago: this is a really diverse community

18:55 RSchulz: It's a large world.

18:55 Chousuke: heh

18:56 * Chousuke is an almost-24-year-old student from Finland

18:56 Chousuke: I think. last I checked I was 23. :/

18:56 I sometimes have trouble remembering my age :)

18:56 * gnuvince_ too

18:57 gnuvince_: I should just say "I'm 27" for the next 6 years

18:57 rafting: how do i sort on the first element in a list of tuples?

18:57 hiredman: hah

18:57 RSchulz: Then for you (and other non-U.S. types): AARP Associate for the Advancement of Retired Persons (though technically they're just AARP now, since no one's retired at 50...)

18:58 gnuvince_: Speaking of school, I'm gonna go and study for a bit

18:58 Catch ya later

18:59 Chousuke: rafting: (sort-by first > [[1 2] [5 1]])

18:59 hiredman: when I was 16 a girl guessed my age as 35, so I started introducing my self as being 35

19:00 Chousuke: I get the opposite :/

19:00 RSchulz: hiredman: You'll get over that some day.

19:00 rafting: user=> (sort-by first > [[1 2] [5 1]])

19:00 java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.Number

19:00 hiredman: RSchulz: oh, I am over it, it's mostly just a habit now

19:00 RSchulz: So you're 35 for ever. Nice.

19:00 Chousuke: rafting: your version of clojure is too old :)

19:01 hiredman: actually people believe it less now than they did then

19:01 Chousuke: rafting: in the meantime, (sort-by first (comparator >) ...)

19:02 RSchulz: rafting: Realisically, you should be working with the latest code from SVN. The "official" releases become out-of-date very quickly.

19:02 And sine everyone here and on the list is living on the bleeding edge, we expect everyone to bleed with us.

19:02 But seriously, Rich manages changes well, and it is, as best I can tell, a monotonic curve of improvement.

19:04 hiredman: clojurebot: latest?

19:04 clojurebot: latest is 1150

19:06 Chousuke: there have been a lot of changes since the release.

19:06 the release version is not clojure anymore!

19:07 I suppose things should calm down after an actual 1.0 release :)

19:09 ppierre: anyone use textmate and/or ant ?

19:11 whidden: what's the bot command for the log of the latest svn revision?

19:11 ppierre: clojurebot: latest?

19:11 clojurebot: latest is 1150

19:12 hiredman: svn rev 1150

19:12 clojurebot: svn rev 1150; releaxed namespace requirement for derives in private hierarchy, patch from J. McConnell

19:12 whidden: svn rev head

19:13 wishful thinking on my part

19:13 Chousuke: svn rev HEAD

19:13 hm, not case-sensitive either then ;(

19:13 hiredman: maybe I should add that

19:14 aperotte: does anyone happen to have any examples of :gen-class using :exposes (I'm trying to use a library the has lots of protected members)

19:15 whidden: library with lots of protected, which library?

19:16 RSchulz: I don't know about "lots," but the Java Collections have some.

19:16 aperotte: java monkey engine (maybe lots was an exaggeration, I need to use 3 for the very basic example)

19:16 hiredman: cute

19:17 Chousuke: monkey engine? does it involve typewriters?

19:17 aperotte: hahaha

19:17 RSchulz: java.util.AbstractList has both protected fields and methods, if that matters.

19:18 Even a protected constructor.

19:18 Chousuke: Java would be more fun if you replaced Abstract with Ideal all over.

19:19 People would go "oh, there's an IdealList! I'll use that" and then be disappointed to find it's not actually implemented :(

19:19 RSchulz: Or, maybe, "Platonic."

19:21 hiredman: public platonic Friends {}

19:21 RSchulz: Hmmm... Maybe a topic for an XKCD comic.

19:22 aperotte: hahaha

19:33 rafting: is there get-with-default? liek (get {'x 5 'y 10} var if-not-found)

19:38 RSchulz: (doc get)

19:38 clojurebot: Returns the value mapped to key, not-found or nil if key not present.; arglists ([map key] [map key not-found])

19:38 RSchulz: The second for takes a third argument, the "if-not-found" value.

19:39 ...the second _form_ takes...

19:44 Chousuke: are there any vimperator users here btw? I just found it a few days ago and I'm really impressed :P

19:44 first non-mouse control scheme for a browser that is actually faster and more effective than using the mouse.

19:47 Makes me think that I might be weird. I make my Firefox act like vi, and even emacs, but I rarely actually use vim the editor for anything more complex than simple edits

19:47 at least, that's the case now that I found vimpulse which makes emacs and acceptable vim clone :P

19:48 Chouser: Chousuke: tried it, didn't like it (vimperator)

19:49 RSchulz: What is "vimperator?"

19:49 (I _am_ a Vim user)

19:50 Chousuke: a firefox extension that brings vi-style modal control to firefox.

19:54 So my firefox now looks like this: http://www.modeemi.fi/~oranenj/vimp.png

19:55 hid the tab bar becuase tab rendering is a bit buggy on OS X and I don't really need to see them anyway :P

19:57 RSchulz: I'm intrigued by the notion of making a browser like a character-mode editor. But I don't see anything out of the ordinary on that screen snapshot.

19:58 Chousuke: RSchulz: that's exactly what's out of the ordinary with it, compared to most browser screenshots :)

19:59 the little black bar at the bottom is vimperator's UI :p

19:59 RSchulz: Uh... huh...

19:59 Chouser: the vimperator key bindings got in the way of site-specific key bindings for me.

19:59 RSchulz: I still don't get it.

19:59 Chousuke: (it's white by default)

19:59 Chouser: There were work-arounds, but didn't strike me as worth the effort.

19:59 RSchulz: I'm looking at http://vimperator.org/trac/wiki/Vimperator now

19:59 Chousuke: Chouser: gmail?

20:00 Chouser: bingo

20:00 * Chousuke doesn't use gmail, so no problem.

20:00 Chouser: but also others. chalk.

20:00 Chousuke: apparently a piece of javascript in the config file can turn off vimperator for specific sites though.

20:00 RSchulz: So I could, e.g., ":g/(map.*#(/p" ??

20:01 I'm still running Firefox 2.0. I'm loathe to give up Pinball.

20:01 Chousuke: hmm.

20:02 RSchulz: They should have called it Vimperial!

20:02 Chousuke: what I like most is the quickhints stuff

20:02 Chouser: when I tried it, vimperator disabled ff3's "awesome bar", which I've grown to rely on.

20:02 hm, we're way off topic.

20:02 Chousuke: no, It's vimperator because it's in control :)

20:02 * Chouser drops it

20:04 Chousuke: anyway, I think vimperator is worth investigating at least if you're partial to how vi works. I guess it's not for everyone though.

20:05 RSchulz: I'm certainly partial towards Vim!

20:06 Chousuke: I guess I just like how quickhints and quickmarks work.

20:07 you can press "f" in vimperator and it'll number every link, and you can then either type a number to open the link, or type text to "narrow down" the selection of numbered links

20:07 if you want a tab, that's F :)

20:09 quickmarks are just a way to assign a URL (or URLs) to buttons, so if you assign www.clojure.org to c, then typing goc will get you there.

20:09 rafting: meh how do i prevent a list from becoming a lazycons? there is a lot of implicit conversion in clojure which im not so fond of.

20:09 rhickey: rafting: when does a list become a lazy cons?

20:10 rafting: that swhat i dont know :)

20:11 rhickey: so what conversions are you talking about that you don't like?

20:12 Chousuke: I would guess rafting means stuff becoming lazy at the earliest opportunity.

20:12 rafting: well my lsit becomes a lazy-cons somewhere and i cant figure out where

20:13 rhickey: nothing becomes anything else, functions take values and return different values

20:13 rafting: take makea alzycons of a list for example

20:14 user=> (class '(1 2 3 4 5 6 7 78))

20:14 clojure.lang.PersistentList

20:14 user=> (class (take 5 '(1 2 3 4 5 6 7 78)))

20:14 clojure.lang.LazyCons

20:14 rhickey: take returns a new thing, how could it return the same list?

20:14 rafting: sure but you get what i mean

20:15 ot youre right and im wrong but it is a bit implicit

20:15 zakwilson: take always returns a LazyCons.

20:15 take takes lazily from the original collection

20:15 Chousuke: rafting: clojure is lazy, so it'll always return you lazy things if it can.

20:15 you can force evaluation with doall and dorun

20:16 rhickey: More generally, there's no problem with functions taking one type and returning another

20:16 is there?

20:16 RSchulz: It would be a horribly restrictive language if every function's codomain were equal to its domain...

20:17 Chousuke: (class (doall (take 5 '(1 2 3 4 5 6 7 78)))) will still be lazycons though, but this time all the values have really been taken :P

20:17 rhickey: and you can create a realized result easily from a lazy one, the converse isn't true without incurring the cost of realizing first

20:18 zakwilson: You could (apply list ...) or (apply vec ...) to that and get a non-lazy list or vector.

20:18 (defn eager-take [n coll] (apply vec (take n coll)))

20:18 rhickey: vec doesn't need the apply, neither list*

20:18 (doc vec)

20:18 clojurebot: Creates a new vector containing the contents of coll.; arglists ([coll])

20:19 * zakwilson stands corrected.

20:19 rhickey: vector does

20:19 but apply vector was so common, added vec

20:19 zakwilson: In any case, if you want eager-take, it's a one-liner.

20:20 rhickey: right, and you get to choose the resulting container type, rather than it being hardwired

20:20 alos remember (into [] (take ...))

20:20 also

20:20 Chousuke: can you put them into java collections?

20:21 rhickey: Chousuke: no, because the semantics of adding are different - mutation in that case

20:22 but Java collections all take collections in their ctors, so (ArrayList. [1 2 3 4]) works

20:22 zakwilson: It also wouldn't be hard to write a multifn eager-take that dispatches on the class of the collection and returns the same type.

20:22 rhickey: zakwilson: right: (into (empty x) (map f x))

20:23 zakwilson: rhickey: that's MUCH easier than what I had in mind.

20:24 * zakwilson needs to find some more good Clojure code to read.

20:24 Chousuke: duck typing makes polymorphism easy.

20:25 rhickey: Chousuke: that's not really duck typing, as there are strong abstractions and interfaces behind it, not just name matching

20:27 Chousuke: But did you see this? http://groups.google.com/group/clojure/browse_thread/thread/913077ecdbe1d3a

20:28 mostly the part where ('+ 1 4) => 4

20:29 hiredman: yeah

20:29 weird, no?

20:30 rhickey: symbols are functions, when called on something in which they can't find themselves they return nil or the default if supplied

20:30 Chousuke: I think it should give an error on things like Integer though.

20:31 rhickey: until you want to write generic lookup code on heterogeneous sets

20:31 then you'll have to add an awkward type test and branch yourself

20:32 RSchulz: I take it it was an nth-level concern how things like #' would read to CL programmers...

20:33 rhickey: RSchulz: yeah, the symbol/var/fn thing is so different in Clojure, being a Lisp-1 with a non-interning reader

20:33 RSchulz: A friend of mine, a died-in-the-wool CL guy for a long time, told me today he'd prefer a CL job to a Scheme job and that he prefers a Lisp-2.

20:33 I can't say I get it but...

20:34 (dyed-in-the-wool, of course)

20:35 zakwilson: I know a lot of people think lisp-2 or lisp-n is the Right Thing. It's always seemed messy to me, but Scheme has never seemed as practical as CL.

20:36 rhickey: Clojure does find a middle ground, with reified vars, non-interning reader, symbols->resolving->vars, defmacro + some hygiene in `

20:36 I think it's the best of both

20:37 zakwilson: That's why I'm here.

20:37 RSchulz: rhickey: Hey, I'm cool with it. But clearly I'm making inroads, since today he bought the PDF of Stuarts book.

20:39 And my friend got a kick out of Bill Clementson's "Common Lisp is the Borg of programming languages" blog: http://bc.tech.coop/blog/040402.html

20:40 zakwilson: Clojure is already my language-of-choice for anything than needs a GUI. I still go for CL for web stuff because I'm used to using Hunchentoot.

20:42 rafting: Hmm, is it just a thing you have to live with in functional programming to pass the same arguments through several functions or is there some design trick to get around it?

20:43 RSchulz: Well, you certainly don't need any other search terms to find _that_ via Google...

20:43 rafting: clojure iis so much better than cl or scheme from what ive tried.

20:43 RSchulz: rafting: How is that different than other languages?

20:45 rafting: what?

20:46 holmak: There's a lot less explicit passing of arguments to functions when there are globals globals, as in normal imperative programming.

20:46 Chousuke: but you know globals are evil.

20:46 unless done right like clojure does.

20:46 RSchulz: holmak, rafting: I'm not sure I think that's really true. My experience in Java is that there's very little reference to global names in any given method.

20:47 holmak: Oh absolutely, but it makes you more aware of the state you are using when you have to pass everything along explicitly.

20:47 * zakwilson never used a lot of globals in languages that permit imperative programming.

20:47 Chousuke: RSchulz: except stuff "global" to the object

20:47 RSchulz: And when I think about it, virtually all such references in my code are really _constants_. Fundamental constants of an implementation.

20:47 zakwilson: So I'm not sure what you're getting at, rafting.

20:48 holmak: By globals I also mean an object's state, which you implicitly have in methods...

20:48 RSchulz: Nor I. Passing along arguments doesn't strike me as a problem or even an inconvenience.

20:48 I'd rather pass something off on someone else (some other function) than have to use it directly.

20:48 zakwilson: I've always preferred to pass state around in args rather than store it in globals. If you don't you have a couple options.

20:49 One is to pass around closures.

20:49 holmak: For the record, I like the Clojure way. But it is a change to have to pass _everything_ instead of having things sitting in an object's state.

20:49 zakwilson: Another is to use refs/agents/atoms as globals, but I think that should be avoided when practical as it tends to make for messy code.

20:50 rafting: is there a common class for +-/*?

20:50 RSchulz: If you have very commonly occurring collections of values, you can always use a map or a struct.

20:50 hiredman: closures can do a lot

20:50 rafting: i hate globals

20:50 RSchulz: rafting: Those functions are not classes, so there's no common class unifying them.

20:51 Clojure is not really object-oriented, and you're best served by not trying to think of it as such.

20:51 rhickey: holmak: if you are used to objects, try using maps, so where you would have said anObject.aMethod() you now say (a-function a-map)

20:51 zakwilson: Global objects with encapsulated state and methods that mutate it are still globals.

20:51 Chousuke: I was thinking to myself today, that all languages that want "pure OO" or that methods must be part of a class or an object are fundamentally wrong. (Except smalltalk, but that's because in smalltalk a block of code is the object... it's not a function.)

20:52 rafting: how do i passa round a closure?

20:52 hiredman: rafting: excellent, I was looking for an excuse to paste this again

20:52 clojurebot: chutes and ladders?

20:52 clojurebot: Excuse me?

20:52 hiredman: damn it

20:52 rafting: yes oc i could just use a Map and pass it around

20:52 RSchulz: A "closure" (any function) is not special. Just pass it. By name, if it's def-ed / defn-ed, or as a literal, via (fn ...) or #(....)

20:53 holmak: I'm getting along fine with using maps and such, but it was a significant change from my usual style.

20:54 hiredman: rafting: http://gist.github.com/32417 <-- at the bottom the chute function returns a function which is closed over the ref used as an in que

20:54 queue

20:54 zakwilson: I think Clojure is a significant change from most people's usual style. It's like a bastard child of Scheme and Haskell.

20:54 holmak: My usual language being Python, which has plenty of classes, mutability and even globals.

20:54 zakwilson: (and I mean that in the nicest way)

20:55 hiredman: heh

20:55 RSchulz: Uh... The term "bastard" has generally negative connotations...

20:55 hiredman: s/bastard/love-child/

20:56 RSchulz: Amazing what a euphemism can do for a thing.

20:56 holmak: Haskell's really good if you want to go crazy trying to understand monads. I'm a PhD or two short of being qualified to be a Haskell programmer.

20:56 Chousuke: born out of scheme and haskell, raised by java...

20:56 RSchulz: Oh my god! Clojure is The One!

20:56 Chousuke: (resulting in a burning passion to change Javaland forever)

20:56 hiredman: born of scheme and haskell secreted away to be raised in the kingdom of nouns

20:57 gnuvince_: "In a world where the number of cores per CPU keeps increasing, the chosen child of Scheme and Haskell seeks to save the world! Raised by his uncle Java The Hutt..."

20:57 </Don Lafontaine>

20:57 RSchulz: So it could commit regicide on the king of said realm?

20:57 rafting: hiredman: thats some actor-model stuff?

20:57 hiredman: dunno

20:57 I just did it, not sure what it is

20:57 zakwilson: I don't know about regicide, but it could be the hier to the throne.

20:58 RSchulz: Well, it's got S-Exprs, so I guess it's pretty hierarchical.

20:58 Something tells me I should go have supper...

21:00 Chousuke: Or maybe it would be more appropriate to say clojure is born out of scheme and java, and carefully raised by haskell :P

21:02 gnuvince_: Clojure does what more programs should do: standing on the shoulders of giants

21:03 Chousuke: hm, yes, that would take into account the fact that clojure is made of lisp and works on the JVM, yet brings functional programming to javaland.

21:03 rafting: (append '(1 2 3) '(4 5 6)), no function for that?

21:03 gnuvince_: In CS, progress is made by standing on the toes of everyone else

21:03 rafting: -> '(1 2 3 4 5 6)

21:04 gnuvince_: rafting: concat

21:04 * cemerick wishes if-not was in the stdlib

21:05 rhickey: cemerick: just to swap the order?

21:05 cemerick: rhickey: yeah, corollary of when-not

21:05 RSchulz: (into '(1 2 3) '(4 5 6))

21:05 rhickey: cemerick: when-not has no order

21:06 Chouser: 'concat' is lazy, 'into' is not.

21:06 rhickey: if has two branches, if-not just swaps them

21:06 RSchulz: Chouser: You beat me to it.

21:06 zakwilson: I didn't know about when-not. I have unless in my util file.

21:06 rhickey: into conjes, so will give different order too

21:07 cemerick: rhickey: I know that :-) if-not just allows one to keep the exit from a loop or recur'ed fn at the top is all.

21:07 RSchulz: rafting: One gets the feeling you've not spent much time perusing the resources at http://clojure.org/ ...

21:07 Chouser: RSchulz: but worth mention 'into' -- I still don't think of it often enough when adding to a non-empty collection.

21:07 rhickey: cemerick: that's what I'm trying to get at - the style you are trying to achieve

21:08 e.g. exit-at-top

21:09 cemerick: sometimes irc is like trying to have a conversation through a mattress

21:10 RSchulz: The colors aren't enought for you??

21:10 cemerick: is if-not in the stdlib, then? I don't see it anywhere...

21:10 everyone is so ORANGE in here!!!

21:10 :-P

21:10 RSchulz: There's (when-not), but it takes only a single body form.

21:11 mmcgrana: are there any HTML parsers for Java along the line's of Ruby's Hpricot?

21:11 Chouser: cemerick: I'm not sure, but I rhickey was telling you that exit-at-top is not a desirable style in Clojure.

21:11 was trying to tell you, that is.

21:11 mmcgrana: also when trying clojure.xml/pars I get: java.lang.IllegalArgumentException: No matching method found: parse for class com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl

21:11 cemerick: ah, I see. Hrm, I'll buck that trend.

21:12 mmcgrana: rather clojure.xml/parse

21:13 cemerick: so often, the return value from a terminating loop or fn recur is just returning an accumulator, so I like to have that short bit before whatever the bulk of the form is.

21:13 hiredman: mmcgrana: you are passing in something that does not patch the method sig of that java method

21:13 Chouser: mmcgrana: I've had some success with tagsoup and zip-filter

21:13 hiredman: I think by default it takes some kind of io stream

21:14 mmcgrana: hiredman: sounds like that could be it, i'll check.

21:15 Chouser: mmcgrana: there's also http://gnuvince.wordpress.com/2008/11/18/fetching-web-comics-with-clojure-part-2/

21:16 mmcgrana: indeed, giving it an InputStream worked, I was giving it a plain String previously.

21:16 rafting: can i in stop a function without doing C-x kill?

21:16 Chouser: rafting: probably not

21:17 rafting: Is there any plan on completely bootstrapping clojure? ie its own datatypes etc, meaning all of them, no java.lang.integer etc

21:18 hiredman: I doubt it

21:18 no real point

21:25 RSchulz: rafting: What would be the up-side of that?

21:25 None, I think.

21:25 Java inter-op, not just the mechanism, but the stock libraries, is a big plus for Clojure.

21:25 Just today someone asked me how Clojure will get main-stream buy-in. My answer: Complete Java compatibility and interoperability.

21:26 mmcgrana: Chouser: thanks for those pointers

21:27 RSchulz: If deep Java intimacy were not an issue, we'd use Haskell or Caml or OCaml or ML or some other language. But it _is_ an issue, so the "turn-your-back-on-the-Java-world" approach is a non-starter.

21:27 Chouser: RSchulz: Actually I still wouldn't, but anyway...

21:28 RSchulz: Well, I can't say I would, either, but that's 'cause I don't know any of those languages. Maybe I should have included CL, but that's _far_ from functional.

21:37 Chouser: I played with OCaml, but macros are not to be trifled with.

21:42 zakwilson: Scheme has a more functional culture (e.g. set! is discouraged), but Java interop is a big win.

21:42 Ironicly, it kept me from trying Clojure earlier. I've never liked Java and I had a tendency to dismiss anything associated with it.

21:44 Chouser: looks like beta 4 of the book is out

21:46 hiredman: "The difference between the two interfaces is that the run() method in the PrivilegedExceptionAction interface may throw an arbitrary exception. Note the unfortunate overloading between this method and the run() method of the Thread class and Runnable interface, which return void; a class cannot implement both the Runnable and PrivilegedAction interfaces.

21:46 lame

21:51 RSchulz: Chouser: beta4 of "Programming Clojure" was out yesterday. Where you been?

21:54 hiredman: You can probably resolve the conflict with delegation. Unless you really must create a class that is type-compatible with both those interfaces.

21:57 Chouser: RSchulz: oh.

21:57 RSchulz: zakwilson: Disliking Java is fine, but ignoring anything even remotely affiliated will blind you to good languages such as Scala and Clojure.

21:58 Chouser: Did you buy the PDF and / or the printed version of Stuart's book? 'Cause if you did, you should have gotten an email notification of the new beta.

21:58 Yesterday.

21:59 When I mentioned it some other denizen here said he was half way through the new chapter ("Macros")

22:00 Chouser: oh, yeah, now that you mention it, I remember that.

22:00 I just got signed up properly today.

22:01 RSchulz: Proper is good.

22:01 "Respect must be paid."

22:13 hiredman: RSchulz: yeah, I just used a proxy

22:14 but still terribly disapointing

22:22 hah!

22:22 sandboxing is sort of working

22:34 zakwilson: RSchulz: you're right. It just took me a while to see that. I don't remember what article or blog post finally got me to try Clojure, but I was impressed when I did.

22:36 danlarkin: zakwilson: I had the same opinion

22:36 and the same change of heart

23:06 blenket: is there a good fft-package in java?

23:17 Kerris7: blenket: JScience has an experimental section, you could have a look there https://jade.dev.java.net/

23:18 blenket: is there an automatic documentation tool for clojure? like .clj to html

23:20 mmcgrana: blenkey: i had started something like that a while back. see some sample docs here: http://clj-doc.s3.amazonaws.com/tmp/doc-1116/index.html code itself is here (not ready to use, though): http://github.com/mmcgrana/clj-doc/tree/master i want to come back to this over the next month.

23:20 err blenket sorry

23:21 blenket: no worries

23:51 jvoorhis: Chouser: thanks for posting your with-bg-queue example to the mailing list :)

23:56 Chouser: wow, that's going back.

23:56 it's in core now

23:56 (doc seque)

23:56 clojurebot: Creates a queued seq on another (presumably lazy) seq s. The queued seq will produce a concrete seq in the background, and can get up to n items ahead of the consumer. n-or-q can be an integer n buffer size, or an instance of java.util.concurrent BlockingQueue. Note that reading from a seque can block if the reader gets ahead of the producer.; arglists ([s] [n-or-q s])

23:58 jvoorhis: oh, perfect

Logging service provided by n01se.net