#clojure log - Sep 03 2009

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

0:14 technomancy: will try in 1.1-snapshot; maybe it's been fixed

0:36 hiredman: clojurebot: example?

0:37 clojurebot: api examples is http://en.wikibooks.org/wiki/Clojure_Programming/Examples/API_Examples

0:37 hiredman: clojurebot: example is Short, Self Contained, Correct (Compilable), Example http://sscce.org/

0:37 clojurebot: Huh?

0:37 hiredman: clojurebot: jerk

0:37 clojurebot: Huh?

0:38 hiredman: damn it

0:47 technomancy: still broken with latest clojure master.

0:47 looks like it only works with AOT'd functions

0:48 will see if I can narrow it down to the a small repro case

0:49 hiredman: clojurebot: foo is is Short, Self Contained, Correct (Compilable), Example http://sscce.org/

0:49 clojurebot: In Ordnung

1:02 technomancy: OK, narrowed it down to a 4-line repro case: http://p.hagelb.org/bughunt.clj.html

1:08 ah... solved my problem by moving my functions zipmap into the backquoted part of the macro

1:18 sweet; it works.

1:18 some nice syntactic sugar for defining processing apps: http://github.com/technomancy/clj-processing/blob/4e762d4c4e84e4e5b36d28655be591f4f067a05e/src/rosado/processing/applet.clj

1:19 ,processing

1:19 clojurebot: java.lang.Exception: Unable to resolve symbol: processing in this context

1:19 technomancy: ~processing

1:19 clojurebot: Excuse me?

1:20 hiredman: clojurebot: processing is http://github.com/technomancy/clj-processing/blob/4e762d4c4e84e4e5b36d28655be591f4f067a05e/src/rosado/processing/applet.clj

1:20 clojurebot: 'Sea, mhuise.

1:22 technomancy: there's a better URL; hang on

1:22 clojurebot: processing is http://github.com/rosado/clj-processing/

1:22 clojurebot: Ack. Ack.

1:23 technomancy: clojurebot: processing is a language/toolkit for visualizations. See the Clojure wrapper at http://github.com/rosado/clj-processing/

1:23 clojurebot: Ik begrijp

1:23 technomancy: g'night folks

3:54 poet: having the same problem as here: http://paste.lisp.org/display/77765 any ideas for a solution?

3:56 jdz: what the hell is swank-clojure-config?

3:57 poet: says to do that here http://riddell.us/tutorial/slime_swank/slime_swank.html

3:57 I tried setting the variable by itself and that didnt work either

3:58 hiredman: ~emacs

3:58 clojurebot: emacs is best configured for Clojure with instructions at http://technomancy.us/126

3:59 poet: nice, Ill take a look

3:59 hiredman: I don't use emacs, but that seems to be the tutorial to follow

4:09 AWizzArd: Is there a mechanism in the jvm or Clojure for autodetecting file encodings?

4:11 jdz: no, but there is a library that attempts to do it

4:12 cpdetector.jar

4:12 AWizzArd: thx

4:12 jdz: not perfectly reliable, though

4:12 subhadeep: hi everyone

4:13 i'm trying out clojure box

4:13 but in emacs swing isnt working

4:13 slime hangs

4:13 jdz: osx, right?

4:14 subhadeep: windows

4:14 xp

4:15 AWizzArd: subhadeep: go into the inferior-lisp buffer

4:15 there press a few times enter

4:15 then swing will not hang anymore in emacs

4:15 subhadeep: uh oh

4:16 AWizzArd: the first time when you want to show a swing component you need to press a few times enter in the inferior repl :-)

4:17 subhadeep: umm

4:17 doesnt help

4:17 :(

4:17 (. javax.swing.JOptionPane (showMessageDialog nil "Hello World"))

4:17 i tried this

4:17 its stuck

4:18 AWizzArd: But when you start a Clojure repl from a shell, then it works.

4:19 subhadeep: yes

4:19 infact from emacs

4:19 if i open a windows shell

4:19 and try it out it works

4:28 eevar2: encoding-detection is broken by design. just hardcode anything to utf-8 ;)

4:29 hiredman: :)

4:34 AWizzArd: eevar2: yeah, I would love to do that. Unfortunately others don't know about it

4:35 clojurebot: paste

4:35 clojurebot: lisppaste8, url

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

4:38 AWizzArd pasted "Easier way to append to a file with specific encoding?" at http://paste.lisp.org/display/86490

4:38 AWizzArd: using contribs duck-streams

4:54 liwp: subhadeep: that works fine for me once I switch to the *inferior-lisp* buffer and hit enter once

4:55 (javax.swing.JOptionPane/showMessageDialog nil "Hello World") is slightly better style IMO

5:00 subhadeep: ok liwp

5:00 lemme try

5:03 it works this time

5:03 thanks

5:03 hmm

5:03 but do i have to get to inferior-list buffer everytime i try swing?

5:03 Chousuke: shouldn't you run swing UI code in the swing thread?

5:04 subhadeep: uh oh

5:05 Chousuke: at least if you want to create or change UI elements from the repl thread

5:05 it's not very difficult, though.

5:05 subhadeep: invokelater

5:05 Chousuke: just (SwingUtilities/invokeLater #(your code here))

5:05 or you can make a macro for that and do (swing your code here) :P

5:08 http://www.j2ee.me/products/jfc/tsc/articles/threads/threads1.html for more info

5:11 subhadeep: but without inferior-lisp buffer

5:11 i couldnt get the swing code running

5:12 though

5:12 learning emacs and clojure with clojure box :)

5:12 LauJensen: subhadeep: Youre only concern in regards to a seperate swing thread, is how you get messages?

5:12 subhadeep: no

5:13 in emacs

5:13 Chousuke: I had no problem running swing code from slime.

5:13 but I used my swing macros to run it.

5:13 subhadeep: i try (. javax.swing.JOptionPane (showMessageDialog nil "Hello World"))

5:13 and it gets stuck like that

5:13 LauJensen: Chousuke: You must have noticed that certain methods fail silently ?

5:13 subhadeep: until i try the inferior-lisp buffer

5:13 Chousuke: LauJensen: hm, not really.

5:13 LauJensen: oh... I get that hassle constantly

5:14 subhadeep: http://groups.google.com/group/clojure/browse_thread/thread/6c195c35ae9a7eb8

5:14 has the issue documented

5:14 LauJensen: For instance an onAction event for a swing component, will fail 100% silently

5:14 subhadeep: but didnt get a convincing solution

5:15 Chousuke: LauJensen: I got exceptions in the *inferior-lisp* buffer

5:15 LauJensen: eh?

5:15 Chousuke: when some swing-action failed that is

5:16 LauJensen: I dont see how thats possible

5:18 Chousuke: well I don't know what it did, but the exception backtraces get printed *somewhere*

5:18 and I just tested. (javax.swing.SwingUtilities/invokeLater #(. javax.swing.JOptionPane (showMessageDialog nil "Hello World"))) works perfectly from the slime repl

5:20 subhadeep: it didnt work for me though

5:20 until as i said inferior-lisp came to the rescue

5:20 Chousuke: hm :/

5:20 something's wrong with your java then.

5:21 subhadeep: umm i dont think so

5:21 its either winblows

5:21 or emacs config

5:21 Chousuke: might be. I'm on OS X.

5:21 liwp: It seems to me that you have to hit enter once in the *inferior-lisp* buffer and after that subsequent Swing calls work fine. That is, after hitting enter in the lisp buffer I can now bring up the dialog as many times as I want without any problems. So if you have a really long running Emacs process and slime session it's not a big deal.

5:21 clojurebot: "if you never learnt Lisp, then you never learned to program" -- some rant on some blog somewhere

5:21 subhadeep: many other faced the same problem without any viable solution as ma google says

5:21 yes liwp

5:22 after inferior-lisp

5:22 swing works fine in slime

5:22 Chousuke: weird.

5:22 LauJensen: Chousuke: I'm on LInux and I have the same behaviour as subhadeep

5:22 liwp: I've seen the issue on OS X as well (at home). I'm at work on Windows at the moment.

5:22 subhadeep: thanks for the help liwp and AWizzArd

5:22 told ya :)

5:23 Chousuke: hm

5:23 well, it might be your emacs config then

5:23 LauJensen: Its flawless

5:23 Chousuke: mine is quite customised :P

5:23 subhadeep: :)

5:24 i will try out in solaris once i get back home

5:24 i started with clojure yesterday night when i was reading this debate on scala vs clojure

5:24 as to who will hold the jvm fort

5:25 thought of learning LISP for a long time so finally i gave it a try

5:25 :)

5:25 liwp: blah, I'm getting really tired of the whole scala vs. clojure thing.

5:25 Chousuke: I never got comfortable with common lisp

5:25 but Clojure is great.

5:26 subhadeep: yes JRuby too ;)

5:26 LauJensen: liwp: funny, it doesnt bother me one bit

5:26 liwp: Chousuke: yeah me neither. I read through Practical CL but I didn't do anything else with CL after that. I also did some scheme, but that didn't stick either.

5:27 LauJensen: I just don't get it why there's suddenly this big need to compare the two. The only thing they have in common is that they run on the JVM

5:27 Chousuke: I wonder why Clojure is being compared to scala so much

5:27 Where's Groovy?

5:27 liwp: Chousuke: exactly

5:28 LauJensen: liwp: Havent you noticed that language wars have been going on since masm and tasm? :)

5:28 liwp: LauJensen: sure :)

5:28 subhadeep: scala has some big follwoing among the web2.0 darlings like twitter

5:28 AWizzArd: How can I get a MapEntry from a map?

5:28 Chousuke: what kind of a map?

5:29 hmm

5:29 LauJensen: ,(map class {:foo 1 :bar 2})

5:29 clojurebot: (clojure.lang.MapEntry clojure.lang.MapEntry)

5:29 AWizzArd: ,(map identity {:a 1, :b 2, :c 3})

5:29 clojurebot: ([:a 1] [:b 2] [:c 3])

5:29 Chousuke: oh, heh.

5:29 AWizzArd: these things that print like vectors, but those are MapEntry's

5:29 subhadeep: hmm

5:29 AWizzArd: ,(.getEntry {:a 1} 1)

5:29 clojurebot: java.lang.IllegalArgumentException: No matching method found: getEntry for class clojure.lang.PersistentArrayMap

5:30 hiredman: they are vectors

5:30 AWizzArd: ,(.getEntry {:a 1} :a)

5:30 clojurebot: java.lang.IllegalArgumentException: No matching method found: getEntry for class clojure.lang.PersistentArrayMap

5:30 AWizzArd: ,(map (comp identity) {:a 1, :b 2, :c 3})

5:30 clojurebot: ([:a 1] [:b 2] [:c 3])

5:30 AWizzArd: ,(map (comp class identity) {:a 1, :b 2, :c 3})

5:30 clojurebot: (clojure.lang.MapEntry clojure.lang.MapEntry clojure.lang.MapEntry)

5:30 AWizzArd: no

5:30 they are not vectors

5:30 hiredman: ,(ancestors clojure.lang.MapEntry)

5:30 clojurebot: #{java.lang.Iterable java.util.concurrent.Callable clojure.lang.IFn clojure.lang.IPersistentVector java.util.Collection java.util.Map$Entry java.lang.Runnable clojure.lang.Seqable clojure.lang.AMapEntry clojure.lang.Streamable java.util.RandomAccess java.util.List clojure.lang.Indexed clojure.lang.IMeta java.lang.Object clojure.lang.Counted clojure.lang.Associative clojure.lang.APersistentVector clojure.lang.IObj clojure.

5:30 AWizzArd: just print like them

5:30 hiredman: ^-

5:30 They Are Vectors

5:30 subhadeep: (+ 1 2 3)

5:30 clojurebot: *suffusion of yellow*

5:30 subhadeep: :)

5:30 hiredman: ~scala

5:30 clojurebot: Scala often gets in the way when trying to write neat code -- seen in #scala

5:31 AWizzArd: hiredman: ah okay, in the oop sense

5:31 hiredman: how can I get such an entry when I have a key?

5:31 there is a function for that, I just don't remember it :-)

5:31 Chousuke: I guess Clojure gets compared to scala because scala also advertises itself as a functional language. at least AFAIK

5:31 hiredman: ~def java.util.Map

5:32 eevar2: and because they both run on the JVM

5:32 subhadeep: ~ruby

5:32 clojurebot: Chunky bacon!

5:32 subhadeep: hehe

5:32 hiredman: oh

5:32 AWizzArd: ah :)

5:32 hiredman: ~jdoc java.util.Map

5:32 Chousuke: I haven't studied Scala in depth because every snippet of scala code I have seen roused an irresistible urge to flee.

5:32 subhadeep: ~jruby

5:32 clojurebot: No entiendo

5:33 subhadeep: wokay

5:33 LauJensen: I saw a thread recently which had the topic of "how to convert language x people to clojure" - I dont understand this mentality. I will not convert and I will not make an attempt at discussion, simply because Clojure is superior and I dont want to share the power.

5:33 subhadeep: wholly new syntax for me

5:33 coming from java/c++/ruby world

5:33 but its fun

5:34 Chousuke: there isn't much to learn anyway

5:34 subhadeep: umm

5:34 why ?

5:34 hiredman: ~literal [3] scala

5:34 clojurebot: <reply>{((x: Any, y: Any) => (f: Function2[Any, Any, Any]) => f(x, y))(1, 2)((x: Any, y: Any) => x)}

5:34 Chousuke: If you mean clojure syntax, there's (), [], {}, and the reader macros (which are optional)

5:34 and some special forms.

5:35 subhadeep: yes :)

5:35 Chousuke: hiredman: I still can't figure out wth that is supposed to be.

5:36 subhadeep: parentheses everywhere

5:36 hiredman: it's cons as λ

5:36 subhadeep: ~scala

5:36 clojurebot: {((x: Any, y: Any) => (f: Function2[Any, Any, Any]) => f(x, y))(1, 2)((x: Any, y: Any) => x)}

5:36 Chousuke: aha.

5:36 hiredman: it returns 1

5:36 (x: Any, y: Any) => x is like car

5:37 (took me a while mucking around with scalabot)

5:37 Chousuke: right.

5:38 I can't remember the lisp definitions of cons either though.

5:38 and I can't read that well enough to see what it is.

5:39 hiredman: ,(((fn [a b] (fn [f] (f a b))) 1 2) (fn [a b] a))

5:39 clojurebot: 1

5:40 liwp: hiredman: so there's a lambda which takes x and y as args and returns another lambda. The second lambda takes f as an arg and applies f to x and y. And finally we pass in (1, 2) to the first lambda and then the ((x, y) => x) lambda to the second lambda. Something like that?

5:40 hiredman: sure

5:40 liwp: yeah, that seems more familiar :)

5:40 Chousuke: ah, right.

5:41 liwp: to be fair to scala, the clojure version is a mess as well if you don't know clojure

5:41 Chousuke: there's less noise though.

5:41 liwp: agreed

5:41 less syntax => less noise ;)

5:42 Chousuke: that doesn't always hold though.

5:42 clojure has more syntax than common lisp, but I think it has less noise :)

5:42 sgtarr: what do you guys think about Scala?

5:42 Chousuke: mostly because of [] and {}

5:43 I also think the literal vector and map syntax also makes writing more expressive macros easier.

5:43 since you have two more syntax elements to work with.

5:43 or actually three since #{} is a literal set :P

5:44 but I haven't seen that in macros.

5:45 liwp: Chousuke: that is true, [] and {} do help. Also fewer parens in bindings and cond etc. help as well

5:48 sgtarr: I've looked at a little scala code in the past, mostly Lift and actors examples. Nothing wrong with it an it's a big step up from Java. I just think that Haskell and OCaml (even F#) are more interesting as strongly typed functional languages. Also, my understanding is that people are writing more OOP like code than FP like code in it, but I might be wrong.

5:49 So to me, at least for the time being, it's not very interesting

5:49 Chousuke: one thing that [] allows nicely is user code inside macros. you can have your macro syntax centered around vectors, and evaluate lists normally as user code. I think one of the html libraries does just this.

5:50 liwp: Chousuke: do you have an example handy?

5:52 sgtarr: liwp: seems like it is useful as a stepping stone for people not willing to dive into FP in every scenario, but rather work on it

5:52 Chousuke: I guess something like [:html [:body (generate-list "foo" "bar" "zonk")]] where generate-lists produces [:ul [:li "foo"] [:li "bar"] [:li "zonk"]] would be possible

5:52 if you had only lists available, it would be slightly more cumbersome to accomplish this.

5:52 though I suppose you could use quasiquote :)

5:54 LauJensen: What a fantastic idea to let ISPs decide the Whois format themselves. "COUNTRY:\tSE" "country: uk" "Country:\tUS" etc... :)

5:55 eevar2: i'm also shooting for haskell as my non-lisp FP language. moere new & interesting concepts than scala, and as it's just for playing around anyway..

5:56 hiredman: ~haskell

5:56 clojurebot: Yo dawg, I heard you like Haskell, so I put a lazy thunk inside a lazy thunk so you don't have to compute while you compute.

5:58 Chousuke: that should say: you don't have to compute while you don't compute

6:00 LauJensen: so fix it

6:00 :)

6:01 Chousuke: nah, I'm lazy as well.

6:08 liwp: Chousuke: oh, that's what you meant with macro syntax. I thought you might mean that it would be easier to implement (rather than call) the macro if the call used vectors for somethings and lists for others. It sounded like a real pain to me if you would have to check the types of args in the macro definition. It all makes sense now

6:11 Chousuke: it's also possible to have the macro expect just seqs of course.

6:12 ,(letfn [[foo [x] x]] (letfn [(bar [x] x)] [(foo 2) (bar 3)])

6:12 clojurebot: EOF while reading

6:12 Chousuke: ,(letfn [[foo [x] x]] (letfn [(bar [x] x)] [(foo 2) (bar 3)]))

6:12 clojurebot: [2 3]

6:13 Chousuke: hmm

6:30 djpowell: has rich mentioned anything about what his rdfm project is for? Is it for working with rdf, or is it designed as a way to serialize clojure datastores to a persistent store?

6:30 LauJensen: ~rdfm

6:30 clojurebot: Titim gan éirí ort.

6:30 LauJensen: djpowell: Sorry, no idea

6:52 djpowell: rhickey: what is the purpose of the rdfm project you've been working on? To work with RDF? To be a general purpose way to store clojure datastructures?

7:20 ambient: btw is there any natural language processing library for clojure in existance?

7:20 i guess it would have to work through java interop...

7:22 or perhaps i should make a dent in my budget and finally buy peter norvig's book, iirc it has some stuff about that stuff

7:25 triyo: I am trying to call clojure/xml.parse with InputStream and my own Parser, like so (parse (.openStream *url*) myparser) but it throws IllegalArgumentException saying parse method not found. If I pass a string as path to file instead of InputStream it works 100%. my *url* is a java.net.URL and it has of course the getOpenStream which returns InputStream.

7:26 *getOpenStream = openStream

7:28 liwp: triyo: what happens if you do (parse (.openStream *url*))?

7:28 btw. the function is clojure.xml/parse not clojure/xml.parse

7:29 triyo: liwp: works fine...so is that a bug in the binding part of the clojure/xml.parse function or am I missing something?

7:30 liwp: based on the exception message is sounds like you're trying to call parse as a method on the InputStream

7:30 so (parse (.openStream *url*)) works but (parse (.openStream *url*) myparser) does not work?

7:31 triyo: thanks about ...xml/parse

7:32 liwp: triyo: I just meant that the function is parse and it's in the clojure.xml namespace, so if you're calling (clojure/xml.parse ...) you're doing it wrong

7:32 did that help then?

7:32 or is it still broken?

7:32 triyo: and yes, parse (.openStream *url*)) works but (parse (.openStream *url*) myparser) does not

7:33 liwp: hmm

7:33 ,(doc clojure.xml/parse)

7:33 clojurebot: "([s] [s startparse]); Parses and loads the source s, which can be a File, InputStream or String naming a URI. Returns a tree of the xml/element struct-map, which has the keys :tag, :attrs, and :content. and accessor fns tag, attrs, and content. Other parsers can be supplied by passing startparse, a fn taking a source and a ContentHandler and returning a parser"

7:33 liwp: so what's myparse then?

7:33 Fossi: why in hell is a regex a special datatype?

7:34 triyo: the way I see it, I call clojure.xml/parse with 2 parameters, 1st: InputStream and 2nd: the parsers to use

7:35 liwp: triyo: well based on the doc string the second arg is a fn that returns a parser

7:35 triyo: (parse "/path/to/local/file" myparser) works

7:36 liwp: so it would seem that myparser is fine

7:36 sorry, I don't have any more ideas - I'm going for lunch now

7:36 Fossi: ok, they are a reader macro. that's a little more sane

7:37 triyo: I have (:use clojure.xml) :)

7:38 then call parse function

7:42 clojure.xml/parse says arg list options are as follows: ([s] [s startparse]) ... I am using the second of the two and the doc string says that 's' can be a string, File or InputStream

8:04 AWizzArd: ~seen kotarak

8:04 clojurebot: kotarak was last seen quiting IRC, 5534 minutes ago

8:04 AWizzArd: ,(/ 5534 60.0)

8:04 clojurebot: 92.23333333333333

8:04 AWizzArd: ,(/ *1 24)

8:04 clojurebot: java.lang.IllegalStateException: Var clojure.core/*1 is unbound.

8:05 AWizzArd: ,(/ 92.2333333 24)

8:05 clojurebot: 3.8430555541666664

8:21 bpattiso1: BUILD FAILED

8:21 /home/bpattison/opt/fnparse/clojure-build.xml:86: Could not find clojure.lang.Compile. Make sure you have it in your classpath

8:22 ^^^ i'm getting the above from ant

8:23 any ideas? i've set the CLASSPATH to clojure .jar files but still get same error

8:24 Chouser: setting the CLASSPATH env var often has no effect since it's overridden by the command line

8:25 bpattiso1: so there's an "ant" option to set the classpath -- unfortunately i'm not that familiar with ant

8:29 Chouser: me either. you might check the .xml file to see if in mentions a setting for the classpath.

8:29 like I know the contrib .xml file has you set -Dclojure.jar=... on the ant command line.

8:30 bpattiso1: i'll try that -- thanks

8:53 Chouser: a variation of the -D option worked! thanks

8:58 Chouser: bpattiso1: great.

9:19 lisppaste8: raphinou pasted "looking for feedback on this code" at http://paste.lisp.org/display/86499

9:20 raphinou: I just pasted working code, but as I'm new to lisp like languages, I'm looking for feedback on how to improve it

9:20 if someone has too much time... ;-)

9:24 Chouser: looks fine to me, for whatever that's worth.

9:25 the use of closures seems good

9:25 you could clean up the formatting a little. *shrug*

9:25 Chousuke: raphinou: Great work not using . directly! What's with the extra spaces though?

9:26 raphinou: yes, I should take a better habit of formatting from the start....

9:27 AWizzArd: Is there somewhere a good explanation of what ensure is doing? Good in the sense that it is targeted at idiots :)

9:27 Chouser: AWizzArd: what it does, or what it's for?

9:27 AWizzArd: second

9:28 When should I use it?

9:28 Chouser: AWizzArd: you searched the google group? It's come up a couple times.

9:28 AWizzArd: I did that in the past, and at that time there were not too many entries. I can try it again now.

9:28 I just had a dosync which won't work without ensure.

9:29 Chouser: you only need ensure when the behavior of your transaction depends on the value of a ref that you do not set.

9:29 that you do not set within the transaction.

9:30 AWizzArd: When I read a value V in my transaction and depend on it, but without modifying V itself?

9:30 Chousuke: yeah.

9:30 Chouser: a ref V, yeah

9:30 AWizzArd: ok, then I will see where I had this case

9:31 It must have been at least one path

9:47 ,(+ nil)

9:47 clojurebot: nil

9:49 AWizzArd: hmm, why is it good that (+ nil) ==> nil?

9:50 Chouser: because (+ anything) is anything

9:50 ,(+ nil 5)

9:50 clojurebot: java.lang.NullPointerException

9:50 AWizzArd: It is fine that:

9:50 ,(+)

9:50 clojurebot: 0

9:50 AWizzArd: but (+ nil) I find strange

9:51 ,(+ "test")

9:51 clojurebot: java.lang.ClassCastException

9:52 Chouser: ok, a related question: why does it matter at all what (+ nil) does?

9:52 AWizzArd: Someone asked me today for a simple example that would produce a NPC. I wanted to show him, but...

9:53 Chouser: call any method on nil

9:53 AWizzArd: (.append nil)

9:53 ,(.append nil)

9:53 clojurebot: java.lang.NullPointerException

9:53 AWizzArd: ,(.append nil "world)

9:53 clojurebot: EOF while reading string

9:53 AWizzArd: ,(count nil)

9:53 clojurebot: 0

9:53 Chouser: ,(.i-just-made-this-up nil)

9:53 clojurebot: java.lang.NullPointerException

9:54 Chouser: or call nil itself

9:54 ,((identity nil))

9:54 AWizzArd: ,(nil)

9:54 clojurebot: java.lang.IllegalArgumentException: Can't call nil

9:54 java.lang.NullPointerException

9:54 AWizzArd: Now I also find it strange and incorrect that (count nil) ==> 0

9:55 Chouser: well, if the Compiler can tell it's nil it won't even compile it.

9:55 AWizzArd: In CL it makes sense, because nil is the empty list.

9:55 Chouser: I don't understand why you would want things to generate more errors than necessary.

9:56 AWizzArd: error detection

9:56 ,(count (get {:a []} :a)

9:56 clojurebot: EOF while reading

9:56 AWizzArd: ,(count (get {:a []} :a))

9:56 clojurebot: 0

9:57 AWizzArd: ,(count (get {:a []} :x))

9:57 jdz: "nothing" has exactly zero elements in it, right?

9:57 clojurebot: 0

9:57 AWizzArd: jdz: this is also true for 15

9:57 ,(count 15)

9:57 clojurebot: java.lang.UnsupportedOperationException: count not supported on this type: Integer

9:57 AWizzArd: A 15 contains no elements

9:58 Chouser: ,(map count (take 5 (iterate next [1 2 3 4])))

9:58 clojurebot: (4 3 2 1 0)

9:58 jdz: yes, nil is "nothing", so it does not make sens to do any operations on it except testing whether something is nil...

9:59 AWizzArd: right

9:59 jdz: Chouser: why next?

10:00 nil is not a sequence

10:00 so it makes sense for count not to work on it

10:00 AWizzArd: I would agree with that right now.

10:00 Chouser: ,(conj nil 5)

10:00 clojurebot: (5)

10:01 jdz: ,(map count (take 5 (iterate rest [1 2 3 4])))

10:01 clojurebot: (4 3 2 1 0)

10:01 Chouser: ,(cons :foo nil)

10:01 clojurebot: (:foo)

10:01 jdz: that conj call also is a stretch

10:02 cons, otoh, is perfectly normal

10:02 AWizzArd: ,(cons :foo (get {} :x))

10:02 clojurebot: (:foo)

10:02 AWizzArd: ,(cons :foo (get {:x (list :xyz} :x))

10:02 clojurebot: Unmatched delimiter: }

10:02 AWizzArd: ,(cons :foo (get {:x (list :xyz)} :x))

10:02 clojurebot: (:foo :xyz)

10:02 Chouser: when things have reasonable default behavior instead of erroring out, there are fewer special cases that have to be handled with extra pieces of explicit code

10:02 AWizzArd: and more holes for type errors

10:03 Fossi: pff, who writes code with type errors anyway? ;)

10:03 AWizzArd: Humas ;)

10:03 Humans

10:04 Raynes: Androids.

10:04 Chouser: If you had to explicitly handle nil in a bunch of cases, you'd have just as many holes as now.

10:05 and you'd have to handle them in all cases instead of just the cases where the current default isn't what you want.

10:05 current behavior

10:05 AWizzArd: why is

10:05 ,(+ 5 nil)

10:05 clojurebot: java.lang.NullPointerException

10:05 AWizzArd: good then?

10:05 Chouser: AWizzArd: what would be the reasonable default there?

10:06 jdz: rule of thumb: nil is treated as an empty sequence if given to functions expecting sequences.

10:06 Fossi: IllegalArgument :)

10:07 Chouser: jdz: right. and returned by a subset of functions that return sequences

10:12 triyo: Chouser: I came across this old post http://markmail.org:80/message/2e7i72y4cg36wqdx and I got it to work as you sescribed it (xml.clj was updated with your change I can see) ... I am struggling to get the parse to work with that tagsoup parser when using s as InputStream instead of string. I get a IllegalArgumentException on tagsoup's parse method.

10:13 *sescribed = describe

10:16 (parse "/path/to/my/file" startparse-tagsoup) works 100% but (parse (.openStream *url*) startparse-tagsoup) fails with IllegalArgumentException on parse method. I see TagSoup has overloaded version of parse method that allows InputStream so I can't seem to see whats causing the problem.

10:19 Chouser: hm...

10:21 that really is an old post. I had been using Clojure for about 3 weeks at that point...

10:23 triyo: hehe, like me now, :)

10:25 AWizzArd: I have many threads generate data and want to write it into a file. Is there already something like a Queued writer that will take a string to write and an index which tells in what order to write, and which will write as soon the queued write jobs allow that (because of their order)?

10:25 triyo: I am just so puzzled with this as I see org.ccil.cowan.tagsoup.Parser has a parse(InputStream) method and I know java.net.URL's openStream method returns a InputStream and thats what I pass as s param of startparse-tagsoup function

10:26 Chouser: triyo: note that tagsoup takes a org.xml.sax.InputSource

10:26 that's what you're passing in?

10:26 oh

10:27 right. URL is returning you a java.io.InputStream. Different class

10:28 triyo: note InputSource vs. InputStream

10:29 fortunately InputSource has a ctor that takes an InputStream

10:29 triyo: I ran (show parser-instance) and confirmed that parse(InputStream) exists on org.ccil.cowan.tagsoup.Parser

10:29 Chouser: (parse (org.xml.sax.InputSource. (.openStream *url*)) startparse-tagsoup)

10:31 triyo: I see InputSource and String overloads, nothing else. What version of tagsoup?

10:31 I'm looking at 1.2

10:49 inverselimit: newbie q: are there LAPACK bindings for clojure?

10:55 Chouser: inverselimit: never heard of it, but you might be able to use http://icl.cs.utk.edu/f2j/

11:20 icylisper: any way to destructure-bind like (def [a b] (values a b)) , without using let ?

11:21 Chouser: I don't think so.

11:21 stuartsierra: No, you'd need a wacky macro to do that.

11:22 icylisper: Chouser: perhaps a macro destruct (destruct [a b] (values a b))

11:22 yeah

11:22 something like cl's m-v-b

11:23 Chouser: sure, destructuring in general is used in places where one might use m-v-b in CL

11:23 but def doesn't destructure. I suppose it could, though.

11:24 stuartsierra: def is complicated enough, I think

11:24 Chouser: def isn't even a macro :-)

11:24 icylisper: Chouser: true. it would be cool if it did :)

11:45 Fossi: it isn't really obvious that binding does not have the let* property of binding in the same order

11:46 stuartsierra: this has been brought up before

11:46 Fossi: caused some headscratching here for a while

11:47 i get why, but i guess there could be a hint about it in the api docs

11:47 stuartsierra: yes

11:48 rhickey_: patch welcome for doc

11:49 stuartsierra: http://www.assembla.com/spaces/clojure/tickets/152

11:49 i'll write a patch

11:56 patch attached to #152

12:01 lisppaste8: drewr pasted "json-object-seq" at http://paste.lisp.org/display/86503

12:02 drewr: stuartsierra: think there's a place for j-o-s in c.c.json.read?

12:02 maybe just json-seq?

12:02 I'm serializing a bunch of objects to files and need to read them in lazily

12:03 stuartsierra: I can see where that would be useful.

12:03 How do you make sure the file gets closed?

12:03 drewr: ah, good question

12:03 rhickey_: stuartsierra: fyi - I'm working on Clojure data structure serialization to/from RDF stores

12:04 drewr: stuartsierra: have to wrap in a with-open by hand I guess

12:04 stuartsierra: rhickey_: Awesome! Tell me more.

12:05 rhickey_: Basically you can save #^{:foo :foo} {:a 1 :b 2 :c #{3 4 5} :d [6 7 {:g 8}]}, in a single shot, and read it back also with a single call

12:05 lisppaste8: drewr annotated #86503 "caller needs with-open" at http://paste.lisp.org/display/86503#1

12:06 rhickey_: everything gets flattened to triples, so you can query etc

12:06 does automatic creation of bnodes for "owned" nested elements, or you can have external refs via URIs

12:06 does multimap-style handling of sets as values

12:07 stuartsierra: rhickey_: Very, very interesting.

12:07 rhickey_: can store keywords as values and use as properties

12:07 stuartsierra: What do you mean by multimap-style?

12:07 rhickey_: handles all the atomic types as values

12:08 {:a #{1 2 3}} for some uri xxx will yield triples xxx :a 1, xxx :a 2, xxx :a 3, rather than an RDF collection as the value

12:08 stuartsierra: That's good.

12:09 rhickey_: there will be an rdfm/assoc* which does that set-aware association

12:09 stuartsierra: How do you map between Clojure keywords and RDF predicates?

12:10 rhickey_: basically you can spit a relatively arbitrary structure into the triple store, but later use rdfm/assoc/assoc*/dissoc/dissoc* inside RDF transaction and get both the new value and the necessary triples stored

12:10 lisppaste8: stuartsierra annotated #86503 "Simpler" at http://paste.lisp.org/display/86503#2

12:11 rhickey_: http://org.clojure/keywords/your-ns/your-key

12:11 drewr: stuartsierra: nice

12:11 rhickey_: you can use strings as keys too, will be presumed a valid URI

12:12 stuartsierra: rhickey_: Ok. So I could (def dctitle "http://purl.org/dcterms/title")

12:12 rhickey_: stuartsierra: yes, np, I looked at what you were doing putting URI strings into vars and look to support it

12:12 you can mix and match

12:13 stuartsierra: Cool. Having a 1-to-1 mapping between Clojure data structures and RDF would make my day/month/year, I think.

12:13 rhickey_: vectors become collections with rdf:_nnn properties

12:13 stuartsierra: ok

12:13 Lists are rdf:List, I assume.

12:13 rhickey_: metadata supported for maps

12:14 I don't do lists or sets-as-collections yet

12:14 stuartsierra: ok

12:14 rhickey_: restoring rdf:Lists is extremely piggy

12:14 stuartsierra: Sets as multiple properties makes more sense to me.

12:15 Yes, I got annoyed trying to deal with rdf:List. I thought it would be easy.

12:15 rhickey_: yes, as map members sets become multiple props, but as vector members not

12:15 stuartsierra: Ok, this makes sense.

12:15 clojurebot: this is not a bug

12:16 stuartsierra: What about literal datatypes?

12:16 rhickey_: plus I will support (rdfm/assoc a-stored-vec i new-val)

12:16 int/long/float/double/bigint/bigdec/boolean/calendar/string/keyword

12:17 will add symbols

12:17 stuartsierra: How about things that don't map directly to Clojure/Java types, like "my string"@en?

12:17 rhickey_: and (rdfm/conj a-stored-vec an-additional-val)

12:18 stuartsierra: the objective of the library is definitely leveraging RDF stores to store Clojure data, not interop with RDF data

12:18 stuartsierra: Ok, fair enough.

12:19 rhickey_: when reading back "my string"@en what would you expect to be returned?

12:20 stuartsierra: Best I could come up with is {:type :literal :value "my string" :language "en"}

12:20 rhickey_: hmm

12:21 stuartsierra: This is the problem with every RDF library; some parts don't quite match any typical language constructs.

12:21 Chouser: #^{:language "en"} "my string"

12:21 if only

12:21 rhickey_: The library uses the Sesame API, which seems pretty widely supported - AllegroGraph, Virtuoso as well as Sesame.

12:22 stuartsierra: Sesame and Jena are probably the two big ones.

12:22 The secondary layers like JRDF don't seem to add much.

12:24 rhickey_: once the data is in you can use sparql etc to query it

12:24 stuartsierra: Are you using Sesame 1.x or 2.x?

12:25 rhickey_: 2.x

12:26 stuartsierra: ok

12:36 winterstream: Hi everyone. I'm trying to instantiate a Java object whose constructor parameters are (double[], double). In Clojure's REPL, if I try (LinearObjectiveFunction. (into-array [-2.0 1.0]) -5.0), Clojure complains that no suitable constructor exists. What am I missing? The class I want to instantiate is described at http://commons.apache.org/math/api-2.0/org/apache/commons/math/optimization/linear/LinearObjectiveFunction.html

12:39 Chouser: ,(into-array [-2.0 1.0])

12:39 clojurebot: #<Double[] [Ljava.lang.Double;@1ade7f6>

12:39 Chouser: That's an array of Double not double

12:39 ,(into-array Double/TYPE [-2.0 1.0])

12:39 clojurebot: #<double[] [D@1cc903c>

12:39 Chouser: try that instead

12:40 winterstream: Ah

12:40 Chouser: thanks! It works!

12:43 drewr: wow, that's confusing

12:44 stuartsierra: Boxed primitives are an unfortunate legacy feature of the JVME.

12:44 *JVM

12:44 ole3: how to convert an java array to a string?

12:46 stuartsierra: If it's an array of chars, (String. the-array)

12:46 or bytes, (String. the-array "UTF-8")

12:49 ole3: (make-array byte 2)

12:50 oops

12:50 stuartsierra: ,(make-array Byte/TYPE 2)

12:50 clojurebot: #<byte[] [B@1ebaf3>

12:50 ole3: :) thank you

12:51 by the way, what's the difference between (new String ...) and (String. ....)

12:59 cschreiner: how can I test for a {} structure in my data?

12:59 drewr: ,(map? {:foo 1})

12:59 clojurebot: true

12:59 cschreiner: ah

12:59 it is always so easy...

13:00 drewr: well, the easy things are :-)

13:04 stuartsierra: ole3: (String. ...) is syntactic sugar for (new String ...)

13:04 Any EMACS fans know how to open a file in the *subdirectory* under point in a dired buffer?

13:08 drewr: C-x C-f then use completion?

13:09 it'll start in the current dired directory

13:09 stuartsierra: Right, that's what I'm trying to avoid. Like if I'm in a dired buffer on "/home/stuart/project" but I've expanded the subdirs to "/home/stuart/project/src/main/java/foo/bar/baz" and I want to open a file there.

13:10 drewr: if you've traversed to baz then find-file will be local to that dir

13:11 stuartsierra: Not if I've traversed to baz using dired-maybe-insert-subdir (bound to "i")

13:11 eyeris: Is there a form of assoc that simple takes a map, key, and function, with a body similar to this? (assoc m :k (f (:k m)))

13:12 drewr: stuartsierra: ah, that's different :-)

13:13 stuartsierra: My dired buffer looks like this: http://paste.lisp.org/+1UQZ

13:14 Chousuke: eyeris: update-in

13:14 eyeris: ty

13:14 Chousuke: it takes a seq of keys though :)

13:15 drewr: stuartsierra: you can't hit RET on the baz so that it's not a subdir at that point?

13:15 Chousuke: ,(update-in {:a 1 :b 2 :c {:a 3}} [:c :a] inc)

13:15 clojurebot: {:a 1, :b 2, :c {:a 4}}

13:16 stuartsierra: drewr: doesn't work if I hit RET on the subdir header line, works if I go up one parent and then hit RET

13:16 drewr: that's what I mean

13:17 i... i... i.... RET C-x C-f

13:17 at worst, ^ RET C-x C-f

13:18 stuartsierra: drewr: Yeah, just want it to be one key. Hmph. I guess I could write it.

13:25 lisppaste8: stuartsierra pasted "dired-find-file-in-subdir" at http://paste.lisp.org/display/86509

14:00 LauJensen: How do you define a 'triple' data structure?

14:05 Chouser: LauJensen: that's an RDF thing

14:06 LauJensen: http://www.w3.org/TR/rdf-concepts/#section-triples

14:06 LauJensen: Thanks a lot

14:07 eyeris: How do I control which defs are exported from my namespace?

14:07 Chouser: eyeris: all vars are public unless marked private

14:08 eyeris: you can use defn- or #^{:private true} to mark a var as private

14:09 eyeris: Okay

14:09 Thanks

14:25 Chouser: ok, that's fun. (rseq ft) returns a thing just like ft except with cons/first/rest swapped for conj/peek/pop

14:26 so you can build/consume from the other end, then call rseq again to switch back to a normal-direction finger-tree, all without losing any abilities.

14:26 that is, both seq and rseq just return another finger-tree, not a cursor type of any kind.

14:37 eyeris: I swear I will never understand the rules for the ns macro

14:37 Chouser: :-(

14:37 eyeris: If I want to :use two namespaces, what is the syntax?

14:37 Chouser: (ns foo (:use [ns1 :only []] [ns2 :only []]))

14:38 eyeris: Okay, that works.

15:14 LauJensen: What is this obession that the chinese have for accessing /fastenv on my webserver ?

15:15 eyeris: LauJensen sounds like they're probing for a FastCGI vulnerability

15:15 LauJensen: oh ok - amazing perseverance

15:15 eyeris: Just a guess.

15:15 lisppaste8: stuartsierra annotated #86509 "better dired-find-file-in-subdir" at http://paste.lisp.org/display/86509#1

15:21 stuartsierra annotated #86509 "binding it to a key in dired" at http://paste.lisp.org/display/86509#2

15:23 LauJensen: stuartsierra: ido aint doing for you ?

15:23 stuartsierra: LauJensen: what do you mean? What's ido?

15:24 LauJensen: ido-find-file, what I type back, and it auto completes to ~/home/coding/lisp/projects/clojureql/src/dk/bestinclass/backend.clj ?

15:24 s/what/where

15:25 I keeps a history of all your files, and whenever you type something, it finds the file

15:25 s/I/It

15:26 stuartsierra: ok, didn't know about that one. But no, I wanted something for opening a new file that doesn't exist yet.

15:27 LauJensen: ah ok

16:42 Is there any hope on the horizon for a quality UI toolkit for Java?

16:50 slyrus_: LauJensen: hasn't there been hope for years now?

16:51 LauJensen: nope

16:51 I got my hopes up a little bit with the entrace of QtJambi - but then that died

16:52 stuartsierra: There's probably a good commercial toolkit out there.

16:53 slyrus_: LauJensen: I didn't say a quality UI toolkit, I said _hope_ for one. that's been around for as long as I can remember.

16:53 LauJensen: slyrus_: nope, sorry

16:55 hiredman: what is the problem with swing?

16:56 LauJensen: its ugly, its laggy, its unflexible

16:57 hiredman: laggy?

16:58 LauJensen: Its does not perform well

16:58 Chousuke: hm.

16:58 I'm not sure if that's swing's fault.

16:58 or just that people misuse it. :/

16:58 LauJensen: Its swing

16:59 But Im not here to discuss swing, I was just probing for some new technological innovations

17:01 hiredman: the #java guys seem pretty happy with swing

17:01 LauJensen: They must not know better

17:01 hiredman: so what is better than swing, and why is it better?

17:01 Chousuke: LauJensen: with quick googling I can't find any resource that claims swing as particularly slow

17:02 LauJensen: hiredman: Aqua for instance, performs better, looks nicer, is more easily extended. Same goes for Windows MFC, which is just pure joy to work with in Visual Studio

17:02 I'd say the only thing thats not better is GTK

17:02 stuartsierra: I have noticed Swing apps with a lot of drawing errors, but I don't know if that's Swing's fault or the app's fault.

17:03 LauJensen: but both Aqua and MFC are single-platform products, Swing is trying to work everywhere.

17:03 hiredman: LauJensen: the visual studio comment makes it sound like a tools issue

17:03 LauJensen: stuartsierra: Doesnt change the user-perception

17:04 Chousuke: I think Swing may have an undeservedly bad reputation. :/

17:04 just like Java has :P

17:04 stuartsierra: LauJensen: agreed, but that may explain why it's harder to do GUIs well in Swing than in Aqua or MFC.

17:04 LauJensen: hiredman: its a little bit of both

17:04 hiredman: I am inclined to agree with Chousuke

17:05 LauJensen: stuartsierra: Sure, but I'm cynical enough not to care, I just want somethings thats high quality :)

17:05 I'd go as far as to say that the UI side of things, is my only dark cloud over Clojure

17:05 Rich needs to put emphasis on the eye candy! :)

17:05 duncanm: if i have a list of maps, each one like {"x" 0 "y" 1}, how do i pluck out all the "x"s?

17:06 ahh

17:06 map!

17:06 stuartsierra: yep

17:06 LauJensen: (keys m) ?

17:07 stuartsierra: (map #(get % "x") list-of-maps)

17:07 duncanm: stuartsierra: that's exactly what i'm writing now

17:07 LauJensen: duncanm: this is the simplest way to go

17:07 ,(doto (java.util.ArrayList. (into [] (mapcat concat (map keys (list {"foo" 2 "bar" 3} {"min" 4 "max" 5}))))) java.util.Collections/shuffle)

17:07 clojurebot: #<ArrayList [bar, min, foo, max]>

17:08 LauJensen: nothing will beat that for pure elegance, but you'll get random results :)

17:09 its a sad day when even my 'code jokes' dont fly...

17:10 stuartsierra: wasn't sure what you were going for there

17:11 LauJensen: its not elegant, its not simple, it randomizes the result... just tought it was funny when (map keys ..) was enough

17:11 arbscht: rest assured, my face was deeply embedded in my palm when I read that. there was an instant, though, in which I panicked about my choice of ClojureQL...

17:12 LauJensen: haha

17:13 ClojureQL rocks - I just did a very awesome combination of compojure+clojureql+googlecharts to auto-generate some very nice stats for www.bestinclass.dk

17:53 Chousuke: hm.

17:54 just now this swing talk made me take a look at my swing experiments file I wrote some time ago to learn how it works.

17:54 it has a small blue square that I can move around the screen with arrow keys. my drawing code was rather idiotic though...

17:55 (holding down an arrow key caused java to have over 100% CPU utilisation in top)

17:56 so I rewrote the code to be a bit smarter and now it uses ~7-10% :P

17:56 aack: \join #lisp

17:56 Chousuke: My dream is to write a small roguelike in Clojure at some point but first I really need to learn swing better :)

17:58 but if I ever get to the point that I have an avatar walking around the dungeons, I'm going to embed a clojure repl in the game for spellcasting :P

17:58 it'd be neat to make a game by playing it :)

17:58 hiredman: Chousuke: you should make a clojure version of ruby-warrior http://github.com/ryanb/ruby-warrior/tree/master

18:00 tomoj: swing? :(

18:00 it's really too bad java sucks at the console

18:01 my dream is to write a messaging client, but it needs to run in screen

18:01 Chousuke: yeah, I couldn't find any terminal drawing stuff :/

18:02 technomancy: Chousuke: you should try clj-processing

18:02 it's a lot of fun

18:02 tomoj: I found jcurses but my tentative judgement is that it sucks

18:02 technomancy: ~processing

18:02 clojurebot: processing is a language/toolkit for visualizations. See the Clojure wrapper at http://github.com/rosado/clj-processing/

18:02 hiredman: http://github.com/ryanb/ruby-warrior/tree/master

18:02 technomancy: incanter (the stats package) is migrating towards that

18:02 hiredman: er

18:03 http://www.pitman.co.za/projects/charva/Screenshots.html "A Java Windowing Toolkit for Text Terminals"

18:03 tomoj: haven't tried that one yet

18:04 my problem is that I'm not really interested in making it look like a shitty old console gui with windows and tabs. I just want like irssi

18:04 maybe you can manipulate charva into being more minimal..

18:04 spaceman_stu: is there a good way to implement type-specific versions of already defined fns? like count for an unsupported type

18:05 tomoj: spaceman_stu: I was just thinking about exactly that while walking home

18:05 afaik, no

18:05 spaceman_stu: bummer

18:06 tomoj: I suppose you might be able to replace count with a multimethod and have it delegate to the old count for things it doesn't know about

18:06 spaceman_stu: yeah, I was thinking about that

18:06 tomoj: but that doesn't seem like a good idea to me

18:06 technomancy: spaceman_stu: for things that are based on interfaces it's not hard to do

18:06 but I don't think count is

18:06 it's easy to proxy something like IMeta though

18:07 tomoj: oh, hmm, I hadn't thought about that

18:07 I suppose you can also act like seqs, too?

18:07 was trying to think of how to translate some python into clojure, and the python has objects that duck-type as lists

18:07 technomancy: actually, count does work on an interface

18:07 just implement clojure.lang.Counted and write a count method

18:08 tomoj: I dunno if I'm happy using a java type, though :/

18:08 Chousuke: ,(count (proxy [clojure.lang.Counted] [] (count [] 5)))

18:08 hmm

18:08 technomancy: docs say you have to guarantee constant-time counts; not sure how important that is

18:11 tomoj: is = linear in the size of the data structure?

18:13 stuartsierra: I think = checks hashes first, so it's constant if the structures are not equal, linear if they are.

18:14 But (= (iterate inc 0) (iterate inc 0)) will not terminate.

18:15 technomancy: infinity is a constant. =)

18:15 tomoj: ah, but if you have a proxy like above, it'll use the default equals() from java and = will just compare the reference, right?

18:16 but then, if you memoize a function call on that reference, you still prevent it from being garbage collected, I suppose. hrmmm

18:41 * stuartsierra posted Maven 's Not So Bad: Further Thoughts on Clojure Package Management http://bit.ly/17pPFE

19:07 * technomancy be glad if people are at least educated about maven.

19:10 somnium: can clj-haml generate the xml? (would shave off 50-100 characters at least)

19:12 tomoj: hrmm

19:12 trying to figure out how to write python's re.findall in clojure

19:12 java.util.regex.Matcher wants you to call .find and then .group to get the next match

19:14 Chousuke: re-seq?

19:14 (doc re-seq)

19:14 clojurebot: "([re s]); Returns a lazy sequence of successive matches of pattern in string, using java.util.regex.Matcher.find(), each such match processed with re-groups."

19:15 tomoj: oh

19:15 damn

19:15 missed that one, thanks :D

19:17 the source is illuminating

19:17 I was trying to do something like that but couldn't quite get it

19:22 so anonymous functions can't call themselves if the recur needs to be not in tail position?

19:22 I mean, without writing a Y combinator

19:23 Chouser: you can give a function an internal-only name

19:23 tomoj: right, yeah. but then I tried to switch it to anonymous, and couldn't because I need to recur but not in tail position

19:23 Chouser: ((fn zeros [] (lazy-seq (cons 0 (zeros)))))

19:24 that name "zeros" isn't available externally, so in that sense it's "anonymous".

19:24 hiredman: ,((fn a [x] (if (zero? x) x (a (dec x)))) 1)

19:24 clojurebot: 0

19:24 tomoj: I guess this is why the Y combinator exists

19:24 hiredman:

19:24 Chouser: I guess I'm not quite sure what you're asking. 'recur' can only be used in tail position.

19:25 tomoj: right, I guess I was asking if there was an alternative to recur that just called the current function without needing to be in tail position

19:25 hiredman: tomoj: Yes

19:25 tomoj: but that would be a silly thing to have just to avoid giving a name

19:25 hiredman: ,((fn a [x] (if (zero? x) x (a (dec x)))) 1)

19:25 clojurebot: 0

19:25 tomoj: hiredman: yeah, I meant truly anonymous

19:25 as in, unnamed

19:25 hiredman: it is anonymous

19:26 a is just the equivilant of the 'this' pointer

19:26 Chousuke: even an anonymous person has something to refer to himself. :P

19:27 tomoj: well, sure, like 'this' or 'self'

19:27 but we don't have that

19:27 hiredman: I think, in fact, at some point all functions just bound to thisfn

19:27 tomoj: #$%!@#%$%

19:27 we do

19:27 (fn a [])

19:27 Chousuke: tomoj: sure we do. (fn self [] (self))

19:27 tomoj: just like in python. :P

19:27 hiredman: if you put a symbol after a, inside the scope of the function, the function is bound to a

19:27 tomoj: right but if you change the name there, you have to go through and change the calls

19:27 not that this is a real problem

19:27 Chousuke: tomoj: just like in python :)

19:27 hiredman:

19:28 tomoj: "recur" is always the same nomatter the function name or whether you've even given it a name

19:28 Chouser: tomoj: just always use (fn thisfn [] ...) and you'll never have to rename your internal uses of thisfn.

19:28 tomoj: but yeah, this isn't actually a problem, I will just put a name there :)

19:29 Chouser: true

19:29 Chouser: tomoj: you do know that 'recur' behaves differently from a self-call in the tail position?

19:29 hiredman: fn used to bind thisfn, before it got the ability to bind any name you choose

19:29 tomoj: Chouser: yeah

19:29 Chouser: I was wondering if there was something that behaved like a self-call but didn't require giving a name

19:29 not binding thisfn is really better, I suppose

19:30 (now I realize what I was asking was whether thisfn existed)

19:31 Chouser: the problem with thisfn was when you had nests fns and wanted to call the outer one.

19:32 tomoj: I guess it's unlikely that you'd be using the name "thisfn" elsewhere

19:32 but hygiene is good

19:32 I could always write afn which binds thisfn

19:45 ,(letfn [(Y [f] ((fn [x] (f (fn [y] ((x x) y)))) (fn [x] (f (fn [y] ((x x) y)))))) (F [f] (fn [x] (if (zero? x) 1 (* x (f (dec x))))))] ((Y F) 5))

19:45 clojurebot: 120

19:45 tomoj: :D

19:49 or better,

19:49 ,(((fn [f] ((fn [x] (f (fn [y] ((x x) y)))) (fn [x] (f (fn [y] ((x x) y)))))) (fn [f] (fn [x] (if (zero? x) 1 (* x (f (dec x))))))) 5)

19:49 clojurebot: 120

19:52 somnium: is that maintainable?

19:53 tomoj: well it could be more maintainable

19:53 but clojurebot wants everything in one expr

19:53 Y never needs to change, and if you separate it out it becomes much cleaner

19:53 (but still useless)

19:54 technomancy: there's no function to translate between hyphen-case and camelCase, is there?

19:54 Chouser: hm, I think I wrote one...

20:12 nm. I found what I was thinking of but it's broken or something.

21:46 prospero_: is there a function that says whether something is IMeta?

21:46 meta? or metable or something

21:48 Chouser: I don't think so. just 'instance?'

21:48 ,(instance? clojure.lang.IMeta [])

21:48 clojurebot: true

21:48 Chouser: ,(instance? clojure.lang.IMeta "")

21:48 clojurebot: false

21:48 prospero_: ok, just wondering if there was a way less tied to the implementation

21:50 Chouser: nope, I think that's it. Interfaces aren't really implementation anyway -- they're interface. :-)

21:51 technomancy: is there a way to programmatically determine if Clojure is running interactively?

21:51 I guess you could check for some of the bindings from the repl function

21:52 it'd be great if environment developers could agree on a unified way of stating this.

21:52 will suggest it on the mailing list.

22:14 Chouser: it could even include repl provider name and version number

22:14 so that you could differentiate between :enclojure and :core if you really wanted to

23:03 tomoj: implementing IMeta means the value has metadata?

23:05 Chouser: right, it means you can call 'meta' on it.

23:41 duck1123: This is probably a FAQ I'm missing somewhere, but how do I get my test script to return false on errors?

23:56 tomoj: huh

23:57 clojure.test?

23:59 duck1123: If I run a clojure script that executes clojure.test tests, how do I get the script return a -1 on failure

23:59 tomoj: oh, hmm

23:59 well you can give a return code with System.exit

23:59 duck1123: I build with maven

23:59 and I'm trying to get the plugin to fail on error

Logging service provided by n01se.net