#clojure log - Oct 30 2008

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

0:00 Chouser: sure. I'm off to bed. Have a pleasant evening.

0:01 _sohail_: you too

1:17 scgilardi: I'd like to get a list of files in a directory in classpath. I know a classpath-relative path but not an absolute path. It occurred to me to use findResource, but (.findResource (clojure.lang.RT/baseLoader) "clojure/contrib/sql/sql.clj") returns nil at the same time as (.getResourceAsStream (clojure.lang.RT/baseLoader) "clojure/contrib/sql/sql.clj") returns a stream. That confuses me.

5:45 AWizzArd: Moinsen

5:49 asbjxrn: Something changed in the macro code recently?

5:54 I used to have a macro (defmacro foo [& funcs] `(bar ~(fn [] ~@funcs)))

5:54 That now throws an exception: "Can't embed unreadable object in code: "

5:55 H4ns: asbjxrn: does not look right to my (untrained) eye anyway

5:55 the first ~ unquotes the whole (fn...) form, so the additional unquote is invalid and the error message makes sense.

5:56 asbjxrn: True that.

6:00 It did end up doing what I wanted it to do, though. Haven't managed in the new svn release.

6:01 H4ns: what do you want that to do?

6:05 asbjxrn: Well, "bar" puts that func into a hash, later in a rendering function I pull that function out again (after binding some variables like mouse position), and evaluate it.

6:06 H4ns: why do you unquote the (fn...) form?

6:06 asbjxrn: The trick is that if I call (foo (line 0 0 mouseX mouseY)), mouseX and mouseY is not valid outside the rendering function.

6:06 Good question. I wrote this quite a while ago.. :)

6:07 That's my only defense :-/

6:07 jdz: asbjxrn: are you sure you veed macros at all?

6:07 need even

6:07 asbjxrn: Yes, otherwise mouseX and mouseY will be evaluated when I call foo.

6:08 jdz: well, that's because you are using macros...

6:08 asbjxrn: i'm pretty sure that what you do can easily be done using functions...

6:09 asbjxrn: I'm pretty sure it can't :)

6:09 jdz: you just stuff appropriate functions in your map and then call them, passing all necessary parameters

6:10 the less context-dependent your functions are the happier you will become in the future. trust me.

6:11 asbjxrn: Imagine (on-mouse-click (background 0) (stroke 200 100 100) (line 0 0 mouseX mouseY))

6:11 jdz: imagine (on-mouse-click [mX mY] (background 0) (stroke 200 100 100) (line 0 0 mX mY))

6:12 H4ns: or (on-mouse-click (background 0) (stroke 200 100 100) (line 0 0 (:mouseX *context*) (:mouseY *context*))

6:13 i fully agree that capturing random names in macros is generally bad style.

6:13 jdz: H4ns: i'd still prefer my approach :)

6:14 H4ns: jdz: less extensible, requires knowledge of the function signature at the call site.

6:14 jdz: what if there is a mouseZ available? change all the callers? not nice.

6:14 jdz: not really

6:14 imagine (on-mouse-click [mX :mouseX mY :mouseY] (background 0) (stroke 200 100 100) (line 0 0 mX mY))

6:15 asbjxrn: H4ns: How do you stop (:mouseX *context*) from being called when you call (on-mouse-click)?

6:15 H4ns: jdz: different, but repetetive

6:15 asbjxrn: #(...)

6:15 jdz: i consider magic *context* ugly. but that may be just me.

6:15 H4ns: jdz: it is not magic, it is just context.

6:15 asbjxrn: My on-mouse-click is a macro that puts the commands in place.

6:16 jdz: asbjxrn: i'm trying to convince you that on-mouse-click does not have to be a macro

6:16 H4ns: asbjxrn: well. remove the first tilde and don't listen to us.

6:16 asbjxrn: Think scripting language.

6:16 (def panel 100 100 (background 0))

6:16 H4ns: asbjxrn: first rule of using macros: don't

6:17 asbjxrn: (draw-fun (line-width 10) (ellipse 0 0 mouseX mouseY))

6:19 jdz: Two problems: in draw-fun I want to be able to combine functions.

6:20 jdz: I have many variables, mouse positions, key pressed, size of window etc.

6:20 H4ns: asbjxrn: what prevents you from creating an anonymous function with #()?

6:20 asbjxrn: To require the function to accept all the variables is messy.

6:20 H4ns: asbjxrn: yes - that is why i would propose using _one_ instead of multiple special variables, and name the special variable according to the convention

6:21 asbjxrn: that way, you'll just script your gui in clojure rather than inventing something new, with funny capturing semantics

6:23 asbjxrn: Not quite as clean, though...

6:23 jdz: i claim that making functions depend only on their parameters is a good thing.

6:24 H4ns: jdz: it is generally a good thing, which does not automatically make passing context in special variables a bad thing. one just needs a good reason to do so.

6:24 jdz: that's what makes them parallelization-friendly

6:24 H4ns: jdz: convenience can be such a good reason.

6:24 asbjxrn: i'm not sure if i want to discuss "clean"

6:24 oh, well, yes, i am sure. i do not want to discuss "clean"

6:25 asbjxrn: :-)

6:25 jdz: yeah, i'd consider my proposed approach much cleaner than asbjxrn's :

6:26 asbjxrn: Sure, from a theoretical point of view.

6:27 jdz: asbjxrn: nope, on the most practical point of view.

6:27 which is code maintenance

6:28 asbjxrn: I wrote this inspired by processing.

6:28 I wanted something similar for the user point of view.

6:28 Which means the user first sets up a window with (setup 100 100)

6:29 then uses macros like (draw (background 0) (line 10 10 100 100) (whatever))

6:29 and (on-mouse-move (line pmousex pmouseY mouseX mouseY))

6:30 And things immediately gets updated in the window.

6:30 jdz: there are only two things that change when mouse is moved. and making those things explicit is a good thing.

6:31 or even more -- the code that responds to mouse move event only wants two things from the event, and depends only on those two.

6:31 so only those two should appear in the code

6:31 if code depends on more, well, then make those explicit, too.

6:32 i think CLX does it this way

6:33 H4ns: jdz: if i understand things right, asbjxrn wants to create something that is easy to use for beginners, failing to recognize that beginners will eventually become experts and then recognize that with the apparent simplicity comes bad design.

6:33 jdz: asbjxrn: so you either set your goal to be as close to Processing API as possible, or make it distinct enough so people don't come up with wrong expectations.

6:34 H4ns: this is not the first time when our understanding is very similar. have i seen you on #lisp maybe? :)

6:34 H4ns: jdz: not entirely impossible :)

6:35 jdz: yay, double negatives.

6:35 asbjxrn: H4ns: there are limitations of course. You can't override the pre-defined variables. And yes, simplicity is the goal here.

6:36 jdz: asbjxrn: the point is thas this simplicity is superficial, and it comes at a cost.

6:36 H4ns: think php

6:36 jdz: and it breaks down when users become advanced enough

6:37 and you lose flexibility

6:45 asbjxrn: H4ns: Just using anonymous function worked

6:47 Can't remember why I ended up with that extra ~ back when

6:50 Actually, that was only in my setup macro which requires extra stuff (size of window mostly) . my draw/mouse/keyboard stuff just uses anonymous functions.

6:56 Chousuke: http://wordwarvi.sourceforge.net/ :D

7:00 (maybe someone needs to make an emacs version)

8:24 Lau_of_DK: Afternoon guys

8:25 Ive noticed that JEditorPane reads Html just about as well as I read Russian - What are my alternatives?

8:26 duck1123: alternatives for reading HTML?

8:26 Lau_of_DK: For rendering it in a Swing app

8:27 duck1123: ahh, I've never much used Swing, so I'm no help

8:28 jdz: there is something that can render html

8:28 i'm sure i saw an exapmle of it in the mailing list or somewhere related to documentation lookup

8:28 with code!

8:29 H4ns: javax.swing.text.HTMLEditorKit should do

8:30 Lau_of_DK: I'll try to look into it

8:30 asbjxrn: H4ns: You just beat me to it.

8:30 Lau_of_DK: Thanks guy

8:30 s

8:31 asbjxrn: A google found this somewhat old, but maybe interesting lead:

8:31 http://today.java.net/pub/a/today/2004/05/24/html-pt1.html#The_Swing_HTMLEditorKit

8:32 Couple of links in the comments as well.

8:33 cemerick: Lau_of_DK: you can hook in a native browser component to render HTML in a swing app. JDIC is the name of the corresponding, project, I think.

8:35 duck1123: so using a component like JLabel doesn't work very well

9:55 Lau_of_DK: asbjxrn, cemerick : Thanks! :)

10:02 gnuvince: http://lispy.wordpress.com/2008/10/25/lisp50-notes-part-vi-the-future-of-lisp/

10:02 That posts almost makes a savior out of Rich :)

10:09 abrooks: gnuvince: BTW, nice blog post. Is there an email address where you'd like me to send feedback? (Note, this channel is logged and indexed by Google so anti-spamify accordingly...)

10:10 gnuvince: "nice blog post" == your post from last night.

10:11 AWizzArd: Lau_of_DK: is Jambi enough to bring Qt closer to Clojure?

10:12 gnuvince: abrooks: vfoley@gmail.com

10:12 duck1123: I really hope that talk makes it onto blip.tv

10:13 AWizzArd: duck1123: what talk?

10:13 gnuvince: abrooks: I'm interested in all types of comments. I'm not a native English speaker, so notes on the language are fine, notes about the Clojure style are fine, etc. Chouser already suggested that I look into line-seq, which is really nice.

10:13 duck1123: the lisp50 talk

10:13 gnuvince: AWizzArd: the Lisp50 talk.

10:13 duck1123: everythink I've heard about it says it was great

10:15 Chousuke: it sucks though that in most of the recorded talks it's impossible to hear the questions asked :/

10:15 abrooks: gnuvince: Thanks. I'll get back to you later tonight (GMT-5).

10:15 tomhickey did a nice job of transcribing the questions for the Boston Lisper's talk.

10:16 gnuvince: abrooks: thanks a lot.

10:22 Chouser: gnuvince: your English was perfect.

10:23 gnuvince: native language is French?

10:23 gnuvince: Yes.

10:24 Chouser: have you considered blogging about Clojure in French? I imagine there are plenty of non-English speakers who might be interested in Clojure but have far fewer resources at hand.

10:28 leafw: does line-seq close the reader and thus releases the file handler when done?

10:28 i.e. when all lines have been read.

10:29 and does it cache lines already read? I guess it does--would be nice to have a version that doesn't.

10:30 Chouser: if you don't hang onto the head of the seq, I don't think it'll keep the lines in memory.

10:31 line-seq does not close the file, you have to open and close it yourself.

10:32 gnuvince: Chouser: I do want to make a blog post to present Clojure in French. I don't think I'll do the tutorial in French though, most good French programmers speak English.

10:32 Chouser: rhickey has mentioned before that there's a general issue of cleaning up after seqs over stateful objects (like open files) -- right now it's all manual and therefore error-prone

10:32 gnuvince: ok

10:33 gnuvince: But a high level introduction to the language is definitely in my plans.

10:37 Lau_of_DK: AWizzArd, http://paste.lisp.org/display/66213 <-- This combined with Jambi brings Qt a whole lot closer, but there is still considerable ground to cover

10:38 AWizzArd: Does it look like a few days-weeks of work? Or more in the area of 5+ months?

10:39 Lau_of_DK: I cant really say. So far it looks like open roads ahead, with some Qt exploration involved. But 'the unexpected' might pop its head up more than a few times. But I'll let you know once I make some head-way

10:40 wwmorgan_: what's wrong with Jambi?

10:40 Chouser: Isn't Jambi just another Java lib? Can't you just use it?

10:41 Lau_of_DK: Chouser, there's no 'just' about it from where Im standing

10:42 Anyway, Im away for a few minz/hours, if you have the time, please lisp-paste an example of a Qt GUI app, designed in 'designer' running from Clojure, I'd be ever so happy :)

10:42 kib2: gnuvince: I would be glad to read your tuts, even in French !

10:44 gnuvince: kib2: you speak French?

10:44 kib2: I'am French, and I'm currently learning Clojure

10:44 gnuvince: Cool

10:45 New Now Know How...

10:45 Have you ever been in #programmeur?

10:45 kib2: never...worth a look ?

10:46 I've started something to write a Clojure tutorial (a Qt app, but in Python sorry :)) : http://www.flickr.com/photos/kib2/2984219379/sizes/l/

10:54 leafw: question about namespaces

10:54 if I was to add or overwrite a function in an existing namespace,

10:55 what would one do: (in-ns 'inspector) ... then define whatever function, which would be then under inspector namespace?

10:55 gnuvince: It's not a bad place, some knowledgeable people, mostly C and C++ programmers, I'm the only one with any interest in functional languages. It's about 2/3 Quebecers, 1/3 European with the occasional guy from Morocco

10:55 leafw: that didn't work.

10:56 scottj: I'm trying to use the sql contrib with MS SQL Server. I downloaded sqljdbc.jar and put that in the classpath, now I' defining my db variable and I set :classname to "com.microsoft.sqlserver.jdbc.SQLServerDriver" and :subprotocol to "sqlserver" but what should :subname be? and where do I put the server name, user name, password, and database name?

10:57 Chouser: leafw: in what way did it not work?

10:58 leafw: java.lang.Exception: Unable to resolve symbol: binding in this context (NO_SOURCE_FILE:1) at clojure.lang.Compiler.analyze(Compiler.java:3814)

10:58 and so on.

10:58 I guess my interpreter messed it up. Never mind

10:58 will have to come up with a better strategy to catch clojure's output for print into a REPL

10:58 I am currnelyt using (binding *out* <any entered text here> )

10:59 wwmorgan_: leafw: in general, prefer the ns macro to explicit in-ns, use, etc

10:59 in your case, the ns macro would have done the clojure/refer for you

11:00 Chouser: but the inspector namespace should already have names like "binding" in it.

11:01 duck1123: scottj: I know for mysql, I had to set :subname to "//localhost/dbname"

11:01 Chouser: scottj: I don't know what you mean by "db variable". My one experiment with db work in clojure, I used java.sql.DriverManager/getConnection

11:02 duck1123: and then just add in :user and :password, anything it doesn't recognize gets added as query params

11:02 leafw: wwmorgan_: so you'd use (ns 'inspector) instead

11:02 wwmorgan_: chouser: hmm. Perhaps he was doing (in-ns 'inspector) instead of (in-ns 'clojure.inspector), or he hadn't loaded inspector.clj

11:02 Chouser: wwmorgan_: oh! both excellent points.

11:03 wwmorgan_: leafw: (ns clojure.inspector (:use (clojure inspector))) works for me

11:06 leafw: thanks.

11:37 brainus: Hello there. Why wouldn't {:['a' 'b'] 2} work? I am trying to use a small vector a key.

11:38 Chouser: 'a' doesn't make sense. you can use either a string "a" or a character \a

11:39 gnuvince: brainus: {["a" "b"] 2}

11:39 Chouser: oh, and :[] doesn't make sense. a vector is a fine key [\a \b]

11:40 brainus: ah, excellent. thanks.

11:40 djpowell: If I wanted to create map keys that have metadata, then I can't use keywords, but would functions like this be reasonable: (defn #^{:doc "A persons first name"} field-first-name [o] (o field-first-name)) - it would then work as both (field-first-name obj) and (obj field-first-name) like keywords do

11:41 I guess a macro would make it easier to create such fn keywords

11:42 Chouser: djpowell: interesting idea!

11:43 I'd never thought of it. I guess you're right -- it would work.

11:43 the map would print kinda ugly.

11:43 djpowell: yeah, that is true

11:43 duck1123: then you just have to make a macro to make it easier to create those

11:45 djpowell: i hadn't thought about them not printing nicely though, that would suck

11:50 Chouser: you could add a new print-method to handle fns that prints just their name if they have some kind of metadata flag. :-)

11:51 This is all to put a bit of documentation on a map key?

11:51 Chousuke: can't you put the documentation on the map itself?

11:53 lisppaste8: Chouser pasted "QtJambi with UI via designer, for Lau_of_DK" at http://paste.lisp.org/display/69450

11:54 Lau_of_DK: Chouser, will you please stop by DK so I can give you a kiss ?

11:56 Chouser: it could clearly use a couple helper functions, but I don't see any huge multi-week issue lurking there.

12:05 djpowell: hmm, actually, regarding the fns as keywords idea, you can get the same functionality just by using symbols, and it prints nice too

12:07 (def #^{:doc "A persons last name"} field-last-name) ; (def m1 {'field-last-name "Dave"}) ; (m1 'field-last-name)

12:10 I hadn't realised that invoking a symbol calls get on its argument

12:11 Chouser: djpowell: yeah, just like keyword. Looks funny to me, though.

12:12 Chousuke: you can also do (def field-last-name 'field-last-name) and then (field-last-name m1) :P

12:14 Chouser: Chousuke: oh, that's wild.

12:14 Chousuke: kind of circular. a var whose value is the symbol that names the var.

12:17 drewr: djpowell: You don't need semicolons. :-)

12:18 djpowell: ha, i know

12:18 Chousuke: a bit like my earlier example, a function whose definition calls get on a map with the function as the key

12:19 Chousuke: well, a symbol appears to be such a function. :)

12:20 Chouser: plus this lets you redef field-last-name later, to completely screw with access to your map

12:20 Chousuke: heh

12:25 doing the (def foo 'foo) makes foo basically a keyword without the :. it evals to itself.

12:26 djpowell: yeah, but it is mutable, which isn't really desirable

12:31 Chousuke: Hm, well, t's basically an accessor function for the map. Most functions are redefinable -- whoever does so for anything important is in no position to complain, though.

12:33 Chouser: the lookup will go through an extra step of indirection (the var) compared to using a literal symbol or keyword.

12:50 djpowell: i was thinking that the var would be in the map, but it will resolved to the symbol at the point of assoc-ing, and get-ing

13:20 kib2: I've made a Pastebin for Clojure : http://clojurepastebin.appspot.com/

13:33 djpowell: Hmm, is it possible to create a macro that expands to something like: (def #^{:doc x} y 123) or equivalent?

13:35 I'm thinking that I might be getting into trouble with #^ being reader syntax, but I can't use with-meta, because def requires an actual literal symbol as it's first argument

13:41 I can't see how to generate '(def #^{:doc "test"} x 4)' with a macro because I can't quote #^, and '(def (with-meta (symbol "x") {:doc "test"}) 4)' isn't valid syntax for def

13:55 wwmorgan_: djpowell: check out the source of def.clj in clojure-contrib to see how they do it

13:59 djpowell: ah, thanks

14:17 AWizzArd: Was there something experimental that allows me to have something like a callback function that is called after an agent has finished?

14:20 Chouser: AWizzArd: there's (agent state validate-fn)

14:20 AWizzArd: oki, let me check if that is what I had in mind

14:20 Chouser: but that's not supposted to have side-effects

14:24 AWizzArd: What could happen if it had site-effects?

14:25 Chouser: AWizzArd: dunno, but it's a mis-use of the feature.

14:25 oh, you might actually want add-watch

14:26 AWizzArd: ah yes, that was it

14:37 Right now there is nothing like (list-all-watchers-of agent) yes?

14:42 Chouser: looks like watchers is private and I don't see an accessor

14:42 of course you could have a convention of tossing each watcher into the metadata somewhere or something.

14:43 AWizzArd: right

14:43 Chouser: btw, what is the watcher supposed to do? Why do I add a watcher and a callback? Wouldn't the callback be enough?

14:44 The callback functions has 3 parameters of which one is the watcher which could in principle be called from within the callback

14:45 Chouser: AWizzArd: hm, not sure. I've never used add-watch.

14:47 AWizzArd: perhaps it's so you can re-use the same callback function for multiple watchers?

14:47 AWizzArd: that could be possible.. but still the question stays what those two guys will be doing

14:48 Chouser: the callback is a fn, the watcher appears to be just any old value you want.

14:48 AWizzArd: The role of the watcher is not so clear to me right now.

14:48 Hmm yes, the watcher could be any 1st class object it seems

14:48 Chouser: It's used as an id, a handle for use when you remove for example

14:48 gnuvince: Chouser: I've updated my blog post draft with the comments you made. Using line-seq made the program more succinct and easier to explain.

14:49 Chouser: gnuvince: ok, great.

14:51 gnuvince: I'll wait to hear from abrooks tonight before I post.

14:52 cemerick: rhickey: did you have any reaction of note to my suggestion w.r.t. user.clj? http://groups.google.com/group/clojure/browse_thread/thread/6951a19912adfb8a

14:54 rhickey: cemerick: NB is being overly pedantic there, and many have complained. The idea behind user.clj is to be pretty easy, getting involved in nested classpath could negate that. These just first thoughts, I haven't decided anything yet

14:59 cemerick: rhickey: Yeah, I agree on both points. I was thinking that perhaps a .clojure file in the home directory would be a good possibility (which would also break the illusion that user.clj is a good place to put startup initialization code, etc)

15:14 AWizzArd: Btw, the callback function that you add with (add-watcher agent watcher callback) does not need to have three parameters. As this runs in the same thread as the function we sent to the agent it means that *agent* is bound already correctly.

15:37 http://clojure.org/data_structures#toc81 says that ArrayMaps will maintain keys in order. But when associng/conjing more data to it might make it become a hash-map.

15:38 So, what is the 'maintains key order' part then?

15:38 Would not any map that stays unchanged keep its order?

15:41 Chouser: compare (hash-map :a 1 :b 2 :c 3) and (array-map :a 1 :b 2 :c 3)

15:41 array-map guarantees that a seq over it will get keys in the order you gave when you constructed it. Not so with hash-map.

15:43 AWizzArd: Tree Maps for example stay sorted even when I assoc new stuff onto it.. that's why I was wondering

15:45 Chouser: yes, but that's in sorted order not necessarily original order. compare (sorted-map :c 1 :b 2 :a 3) and (array-map :c 1 :b 2 :a 3)

15:46 AWizzArd: Sure, I understand the difference. I just thought that array maps will keep the order even when you assoc new elements later

15:51 Chousuke: maybe clojure is trying to save you from doing stupidly inefficient things with the map :/

15:52 drewr: Hm, cast doesn't do what I thought.

15:52 Chouser: cast does hardly anything.

15:53 drewr: I'm getting an interface back from a factory, but I need the concrete class.

15:53 Chouser: you can't have an instance of an interface.

15:54 you can use (class ...) on it to see what it really is.

15:54 drewr: I'm getting a com.sun.org.apache.xerces.internal.dom.ElementImpl, but I need to cast it to a org.w3c.dom.Element.

15:56 At least I think so.

15:56 Chousuke: is Element the interface? or what.

15:56 Chouser: Have you tried just using it?

15:57 drewr: I'm trying to .appendChild on a DocumentImpl and it says the node can't be inserted there.

15:57 From what I can determine, HIERARCHY_REQUEST_ERR occurs when the node isn't the right type.

15:57 Yes, Element is the interface.

15:57 Here's the code I'm trying to clj-ize: http://www.rgagnon.com/javadetails/java-0511.html

15:59 Not wholesale, just trying to mimic the xml creation for a different purpose.

16:02 Chouser: drewr: don't you need an Element instead of a Document?

16:02 AWizzArd: And btw, why xml? ;-)

16:03 You can store your data trees directly as s-expressions

16:03 Chousuke: drewr: can you show the code you have now?

16:04 lisppaste8: drewr pasted "xml generation" at http://paste.lisp.org/display/69465

16:05 drewr: AWizzArd: True, but I'm not sure I'll be able to use the reader to read it back.

16:06 Chouser: drewr: that worked for me

16:06 drewr: Hm.

16:06 Ah, I get that error when I try to append another.

16:07 AWizzArd: drewr: the Clojure reader has no side effects... unlike CLs reader it does not intern stuff that it reads

16:08 drewr: Chouser: And then xml is #=(com.sun.org.apache.xerces.internal.dom.DocumentImpl. "[#document: null]")

16:08 Why null?

16:09 Chouser: drewr: you can only have one element in a document

16:09 that element (the "document element") can have any number of children

16:09 drewr: Ah, good call.

16:09 Chouser: so trying to add a second element to the document is failing for you

16:10 (.getDocumentElement xml) shows the one element you added

16:10 not sure what the "null" is about -- that's the Java object's toString method producing it.

16:11 ReplRat: Is there a JSON reader and printer?

16:11 drewr: ReplRat: I've played with the json-lib, and it's OK.

16:12 ReplRat: drewr: where is it? i didn't see it on Google.

16:12 drewr: But it didn't serialize java.sql.Timestamps correctly.

16:12 http://json-lib.sourceforge.net/usage.html

16:13 ReplRat: ah. I keep forgetting to look for Java libs instead of Clojure libs.

16:13 drewr: I should be able to attach a custom processor to the JsonConfig, but I lost interest by that point.

16:17 abrooks: I'm trying to transform a list of lists of three items ((1 2 3)(4 5 6)(7 8 9)...) into three lists ((1 4 7 ...)(2 5 8 ...)(3 6 9 ...)).

16:17 I need a chart visually showing some of the seq transform functions.

16:18 My brain gets stuck trying to remember them all.

16:18 drewr: That's a great idea.

16:18 abrooks: Ah... Hm. I could do this with lazy-cat.

16:19 Chouser: apply map list

16:19 (apply map list foo)

16:20 abrooks: I tried thinking through this with (apply map list foo) but it didn't work in my head. Maybe my brain is broken.

16:20 * abrooks tries again

16:21 gnuvince: Chouser: crazy trick!

16:21 abrooks: It works but I still am not thinking about it right.

16:21 gnuvince: I tried to find how to do exactly this last weekend.

16:21 abrooks: Chouser: Thanks. :)

16:21 gnuvince: I was toying with (apply #(map list %&) xss)

16:22 Didn't work<

16:22 Chouser: abrooks: I'm beginning to think a flowchart or something like it might work as well as the grid we were trying to build.

16:22 for many of these tricky problems, there are actually not many tools that will work.

16:23 AWizzArd: If you can wait from time to time for cgrand you can get often extremly nice solutions :-)

16:23 Chouser: for example, trying to talk through multiple lists in parallel -- pretty much just "map" I think. "for" won't do it (it nests instead). most of the other seq functions only take one seq.

16:23 AWizzArd: heh, exactly.

16:25 so with map, you now have the right numbers, but they're args not a list. I've tried to use "identity" in such circumstances, but of course identity only wants one arg. "list" or "vector" do what you want.

16:25 and finally you need apply if you're given a list of lists so that map can get at them.

16:30 abrooks: Chouser: A flow chart! Nice.

16:31 Chouser: A seq transform expert system! :-D

16:31 Chouser: right

16:32 "is your input a single seq, or multiple" "is your input seq made up only of seqs" ...

16:32 but since an actual expert system of flow chart would get bogged down in ridiculous details and corner cases, I'm thinking perhaps a blog post.

16:33 abrooks: Does your data structure have a spinal chord? -> Chordates...

16:33 gnuvince: SPINAL TAP!

16:33 abrooks: er.. cord.

16:33 gnuvince: Heh!

16:35 Chouser: You bring up another point that I had sort of been thinking of which is sort of a catch-phrase list. parallel-lists -> [maps], folding -> [partition, for], nesting -> [for], etc..

16:36 I guess that's sort of what we were trying to do in the spreadsheet but this notion was allowing for looser defined categories.

16:37 Chouser: I'm sympathetic with the idea that the spreadsheets categories might be too narrow.

16:38 abrooks: I think the fundamental taxonomy of the operations is too subtle to be useful. Going with a small handfull of generalities probably starts you in the proper direction.

16:42 AWizzArd: Do we have the enclojure developer here?

16:50 Chouser: that whole team is apparently swamped until after the election.

17:04 Pupeno: Hello.

17:04 Is there any particular moment when setting swank-clojure-extra-classpaths has an effect?

17:11 AWizzArd: Does (seq col) create a fresh list of all items in col? Or does it use some internal tricks on the java side to produce something that for me as a user looks like a list? I ask because seq returns extremly fast, and it seems to be not lazy.

17:12 Chouser: seq never copies any underlying collection. Usually it creates a new object that acts as a view on some other object.

17:13 AWizzArd: Okay, so this is what I meant by "trick"

17:16 Chouser: a notable exception is PersistentList, which itself implements ISeq. So calling seq on a list just returns the very same list.

17:17 AWizzArd: yes

17:18 Chousuke: vectors don't seem to implement ISeq :/

17:18 is there a reason for that?

17:20 Chouser: Yeah, it wouldn't be natural. But you can call seq on a vector and get a APersistentVector$Seq

17:23 gnuvince_: What's the significance of the $?

17:23 kotarak: Nested class

17:24 Chouser: In Java source code that looks like APersistentVector.Seq, but APersistentVector is a class not a package so the internal name uses a $ instead of a dot

17:25 you see it in some exceptions, in .class file name, and in Clojure.

17:26 ReplRat: Is there a Clojure wiki that anyone can edit?

17:26 Lau_of_DK: How do I test i a symbol has previously been declared?

17:27 Chouser: ReplRat: wiki link on clojure.org

17:27 wwmorgan_: Lau_of_DK: (resolve 'foo)

17:27 Lau_of_DK: wwmorgan_, thanks

18:05 Chousuke: hmm

18:07 kotarak: sosososo

18:08 Chousuke: I'm trying to figure out a neat way to implement a version of partition that keeps the remainder, but my best (working) attempt so far uses reverse which isn't optimal :/

18:09 ReplRat: would it be possible (or desirable) to implement a condition/restart system like CL's in closure? I'd like, for example, to say what happens when a undefined symbol is evaluated.

18:09 Chousuke: hm, I should be more careful too... 41884 java 176.7% 36:43.44 20 555 207 77M 37M 87M 259M

18:19 gnuvince_: Chousuke: something like this?

18:19 user=> (my-partition 4 (range 10))

18:19 ((0 1 2 3) (4 5 6 7) (8 9))

18:21 Chousuke: gnuvince_: yeah

18:21 gnuvince_: here's the code

18:21 <mini-flood>

18:21 (defn my-partition [n xs]

18:21 (when (seq xs)

18:21 (lazy-cons (take n xs)

18:21 (my-partition n (drop n xs)))))

18:21 </mini-flood>

18:22 Chousuke: I'm pretty sure I tried that :/

18:22 I wonder what I did wrong

18:22 gnuvince_: Don't beat yourself too much, it was probably a little detail you forgot.

18:23 That happens to me all the time.

18:28 AWizzArd: well, humans suck at programming

18:28 Chousuke: ah, I know what I did

18:28 AWizzArd: It's time we let our computers do that for us :-)

18:28 Chousuke: I forgot the (when (seq coll) ...

18:29 gnuvince_: Chousuke: ah :)

18:30 AWizzArd: you saw the movie "Eagle Eye", haven't you?

18:30 AWizzArd: hmm, maybe

18:30 I usually forget movies fast after I saw them

18:31 gnuvince_: AWizzArd: it's in theaters now, it's about an AI that goes rogue

18:31 (how original...)

18:36 AWizzArd: Maybe we all are AIs that go rogue from time to time. I personally plan to use Clojure extensively for AI programming.

18:37 I should try to make a bot which can outperform wwmorgan_ who also seems to be some kind of bot. You ask a question about what a function is called, and the moment you press enter you can already see his answer.

18:37 gnuvince_: AWizzArd: are you very busy at the moment?

18:37 AWizzArd: not very

18:38 gnuvince_: Would you mind reading a draft of a blog post I made on Clojure? It's the first part of a small tutorial, and I want to get input from the people here to make sure it's OK.

18:38 AWizzArd: sure

18:39 kib2: gnuvince : sure :)

18:39 gnuvince_: http://fornost.homeip.net:81/vince/clojure-comics1.html

18:39 Here it is

18:39 you can send comments at vfoley@gmail.com

18:39 cemerick: enclojure users: I just posted to the enclojure google group a rough patch to enclojure's head that adds support for multiple remote REPLs. If you are so brave as to try it, I welcome feedback/suggestions, mostly because I'm groping through the dark on a number of fronts in that context.

18:52 AWizzArd: hmm, apropos variables... when we have (def x 1), how much sense does it make to call x a variable?

18:53 wwmorgan_: sounds fine to me

18:54 AWizzArd: yes, to me also, because I am used to it

18:55 although beginners could ask what exactly is variable in it

18:55 maybe a beginner would suggest to call it a constant

18:56 wwmorgan_: I wouldn't call it a constant

18:57 AWizzArd: (def pi 3.1....) "The variable pi is used ...."

18:59 Well, we need a name for the things that follow after def and variable sounds nice

19:02 kib2: gnuvince : ping

19:04 gnuvince_: pong

19:06 kib2: http://kib2.alwaysdata.net/tempo/gnuvince.html

19:06 more readable

19:07 AWizzArd: kib2: now only put it all into a frame with a width of 800px

19:07 so that people with widescreen displays also can read it :-)

19:08 gnuvince_: kib2: I'll be posting it on Wordpress

19:09 kib2: AWizzArd: my tool does not do that for the moment, I don't want to modify it by hand :)

19:10 gnuvince : I'm going to sleep now, I'll read it in bed and give you a feedback tomorrow, ok ?

19:10 gnuvince_: kib2: sure thing.

19:10 kib2: See you

19:10 Lau_of_DK: AWizzArd, its not fully tested, but it seems that as of now, using the Qt-designer (and its standard widgets only, text-boxes, inputboxes, calendars all thats) you can design a form and run it from clojure, incl. hooking up slots/events.

19:12 AWizzArd: Lau_of_DK: this is good news... I am looking forward to hear what you will find out in the coming weeks about it. Perhaps it really is fully functional already. This would make especially you and a bunch of other people happy. And if not you might have very concrete info what exactly is not working as you wish.

19:16 Lau_of_DK: AWizzArd, hang on 3 minz, I'll show you something

19:17 AWizzArd: Lau_of_DK: one thing that would be very nice is a step-by-step tutorial that explains how to make a webstart application that you can simply click on a website and get a minimal Qt app that shows "Hello World".

19:19 This would tell how to publish code that you wrote in Clojure so that other people can use it, it would explain how to make a minimal webstart application, and it would also give an example on how to do Qt with Clojure.

19:23 Lau_of_DK: Thats not too far out in the future

19:23 Have you worked with their designer yet ?

19:24 AWizzArd: I have no idea what the designer is

19:24 Lau_of_DK: Ok, with this new stuff that Chouser cooked up, we can load ui's designed in the 'designer' directly in Clojure

19:25 AWizzArd: Lau_of_DK: you could download something like http://camstudio.org/ and put a little video on youtube

19:26 Lau_of_DK: In 1 minute, I'll show you how to build a webbrowser using the designer

19:26 It also has tools for text-boxes with code-highlighting, calendars, video-renderers and so on

19:27 http://www.bestinclass.dk/download/designer.mpeg <-- I appologize for the resolution, go fullscreen

19:31 AWizzArd: Thanks. The designer looks clean and professional.

19:32 Now it would be interesting to make a .jar file that a user simply needs to doubleclick

19:32 Lau_of_DK: Its good stuff - So now once I clear up a little import problem, you can design a gorgeous crossplatform GUI in seconds, with powerful functionality, and drive it directly from clojure

19:32 Thats not a problem

19:33 The problem right now is just getting the full functionality of Qt into Clojure

19:33 AWizzArd: You can make a tutorial video, with spoken language available on youtube. This could explain it all step by step to total newbies. Some of them might be driven to Clojure by that.

19:34 If it looks easy and colorful people will enjoy it. And hundreds of your watchers will send around their own programmed webbrowser to their friends :-)

19:35 "Yeah, I made it. Ima progamer expert in Qt-Closhure"

19:35 Lau_of_DK: How about you handle the PR, and I'll put in some more work on the functionality :)

19:36 Chousuke: heh

19:36 AWizzArd: yeah, let's think about it

20:18 Lau_of_DK: AWizzArd, this is what you want right? http://dist.trolltech.com/developer/download/webstart/

20:18 AWizzArd: yes

20:19 I tried that before

20:19 Lau_of_DK: k

20:19 AWizzArd: now only for your 100% Clojure example, a simple hello world

20:19 Lau_of_DK: k

20:38 sohail: Lau_of_DK, that mpeg.. that's not showing any clojure things is it?

20:46 Lau_of_DK: No, its showing the GUI of the designer. With the designer you design a nice form/window/dialog, and that window can be driven from Clojure

20:49 sohail: Lau_of_DK, I see

20:49 does qt jambi let you use anonymous classes for slots and stuff?

20:49 Lau_of_DK: yes, with a litle modding made possible by jamii, it actually does

20:49 With this much code, you can load a seriously complex GUI

20:49 (let

20:49 [ ui (QUiLoader/load (QFile. "code-ui.ui"))]

20:49 (.show ui)

20:49 (.connect (.triggered (.findChild ui Object "action_Exit")) ui "close()")

20:49 (QApplication/setStyle (QStyleFactory/create "Oxygen"))

20:49 (QApplication/exec)))

20:50 And it will render with Oxygen widgets, which are really pretty :)

20:50 http://paste.lisp.org/display/66041

20:50 With this, you can use the slots anonymously

20:51 sohail: that's cool

20:51 Lau_of_DK: yea its extremely cool

20:52 sohail: I wrote a qt binding for CL that was better but not very portable it seemed :-)

20:52 Lau_of_DK: Oh :) Feel free to paste it

20:52 sohail: well better when you used slots anyway... :-)

20:55 lisppaste8: sohail pasted "qtcl for Lau_of_DK" at http://paste.lisp.org/display/69479

20:56 sohail: Lau_of_DK, I much prefer you doing it for clojure though ;-)

20:56 Lau_of_DK: Dont worry I will, just looking for inspiration

20:57 I'll have to read through it tomorrow though, we're coming up on 02:00 AM here, which means time for bed - Have a good one all

21:34 gnuvince_: What's this binding audit thing?

21:36 Chouser: audit?

21:37 gnuvince_: http://richhickey.backpackit.com/pub/1597914

21:39 Chouser: oh, that. He wants to change doseq, if-let, and such that do bindings to use vectors.

21:39 gnuvince_: (doseq [e coll] body)?

21:39 Chouser: exactly.

21:40 gnuvince_: ok

21:40 What about condp and fcase that I keep hearing about?

21:40 Chouser: so that requires digging through boot.clj to make sure that every single one is covered.

21:41 I don't think those bind any locals.

21:59 fbru02: hey all ! :) I have a newby question ! :)

21:59 can i shoot them ?

22:01 gnuvince_: fbru02: shoot away, if somebody has the answer, they will answer.

22:05 fbru02: ok :) I programmed in python ruby c# and haskell but many of this problems I think it have to do much with lisp notation than with clojure in general but Im learnig clojure .... 1) (defn functioname [ parameter1 & parameter2] ) what does the & stnad for ? and 2) (let x (into #{} x)) #{} stands for creating a set ?

22:07 gnuvince_: 1) the & indicates a rest parameter

22:07 Since you know Python, here's something equivalent:

22:07 (defn foo [a & b] [a b]) == def foo(a, *b): return [a, b]

22:07 fbru02: cool

22:08 gnuvince_: 2) yes, #{} is the literal syntax for set.

22:09 danlarkin: gnuvince: actually (defn foo [a & b] [a b]) and def foo(a, *b): return [a, b] aren't exactly the same

22:09 they're very similar.. it's the same idea, but they are different

22:09 in the python one *b will be all arguments passed to foo

22:10 not just "the rest" like in clojure

22:10 gnuvince_: danlarkin: no, it'll be just the rest

22:10 >>> def foo(a, *b): return [a, b]

22:10 >>> foo(1,2,3,4)

22:10 [1, (2, 3, 4)]

22:12 danlarkin: gnuvince_: oops... that's embarassing, I guess you're right.

22:12 gnuvince_: ;-)

22:15 fbru02_: sorry

22:15 gnuvince_: uy... is that Uruguay?

22:15 fbru02_: yes !

22:16 nice country but we don't have many lispers here :(

22:20 thanx both one more thing and #(operator % (var1) var2) is syntax sugar for making a lambda function?

22:22 Chouser: yep: (fn [x] (operator % (var1) var2))

22:22 note you can't use #() instead of a function like: (fn [x] {:foo x})

22:24 fbru02_: uh , I thouhgt that you didnt have to use put fn[x]

22:25 ah sorry now I get it : (fn[x] (op % (var1)var2)) == (fn #{op % (var1) var2)) right?

22:27 Chouser: no, (fn [x] (op x)) == #(op %)

22:27 also no #{} and #() and #"" all mean different things

22:29 fbru02_: ah yes we discussed #{} before it was for making a set, what #"" means ?

22:30 Chouser: #"" is a regular expression literal

22:31 these are explained at http://clojure.org/reader

22:31 fbru02_: ok thanks man, I'm goint to hit the bed now I think

22:32 Chouser: 11:30 there?

22:32 fbru02_: 1230 because we are on summertime

22:32 Chouser: ok. sleep well!

22:32 fbru02_: ok thanks mate , later ! :)

22:40 abrooks: gnuvince: I am wrapping up looking at your blog post. I started a while ago but got derailed when a friend called. :-/

23:30 wwmorgan: lisppaste8: url

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

23:33 wwmorgan pasted "Good library to do this?" at http://paste.lisp.org/display/69484

23:36 bradbev_: I'd like to use zip_filter & xml from the contrib package, but keep getting Could not locate Clojure resource on classpath: clojure/contrib/zip_filter/zip_filter.clj. I've manually loaded zip_filter & clojure.xml.

23:37 wwmorgan: bradbev_: try starting clojure with clojure-contrib in your classpath

23:37 bradbev_: ah, OK...

23:40 Chouser: wwmorgan: sorry, I've got nuthin' Don't want to roll your own TCP protocol? :-)

23:41 wwmorgan: I don't want to have to worry about _anything_

23:51 abrooks: Heh. I hadn't seen this: http://www.lisp50.org/schedule/schedule/mccarthy_files/doing-it-wrong.jpg

23:52 bradbev_: thanks wwmorgan that works.

23:57 wwmorgan: bradbev_: check out the ns macro for a very clean way to handle almost all of your dependencies

23:58 bradbev_: wwmorgan: I saw that, but didn't click on to needing the classpath correct. I thought just loading the files from slime would get be the right stuff. Do the JAR files contain compiled Clojure code?

Logging service provided by n01se.net