2008-10-03
| 00:35 | johnwayner | Hopefully this is a FAQ: I've gotten the src and 'mvn install'd it. But when trying to start up the repl, it just hangs. No input is being read and no output printed on the screen. Java is 1.5.0. Platform is Windows 2003 server. TIA |
| 00:36 | arohner | how are you starting the repl? |
| 00:36 | johnwayner | java -cp target/clojure-lang-1.0-SNAPSHOT.jar clojure.lang.Repl |
| 00:37 | arohner | I've always used ant |
| 00:37 | arohner | though I would assume they both work |
| 00:38 | johnwayner | I didn't get any errors. And the jar is definitely there. |
| 00:38 | johnwayner | Strangely, I tried just throwing some debug println's in the Repl main(), and they aren't showing up either. |
| 00:38 | johnwayner | I may have other java issues, I suppose. |
| 00:39 | arohner | what terminal are you using? |
| 00:39 | johnwayner | I've tried the standard "Command Prompt" and M-x shell in emacs |
| 00:39 | johnwayner | ...which should be the same really |
| 00:41 | johnwayner | I'll play around some more. I am using a pre-boxed java set up that my company has put together. I'll try just using a stand JVM installation. |
| 00:44 | johnwayner | Hmmm... musta been something there. It's working on a 1.6 JRE I had lying around. |
| 00:44 | johnwayner | Thanks. |
| 01:16 | arohner | johnwayner: good |
| 02:23 | rk98x03 | Morning gents, can somebody please stimulate my sense of (map (fn [])) ? :) I have a list of titles, and each title has subsequent subtitles. I need to map them out into an array, so that |
| 02:23 | rk98x03 | title1-sub1-sub2-sub3 |
| 02:23 | rk98x03 | maps to "title1: sub1" "title1:sub2" "title1:sub3" |
| 02:23 | rk98x03 | and so forth |
| 02:27 | Lau_of_DK | ok, simplified, if I want an infinite sequence of the word "hi", how do I make it? |
| 02:28 | Lau_of_DK | So that (take 1 seq) = "Hi", take 2 = "Hi" "Hi" |
| 02:31 | Lau_of_DK | k got it |
| 02:31 | Lau_of_DK | thanks for listning |
| 03:06 | avida | Lau_of_DK: (take 3 (iterate #(str % " " "hi") "hi")) |
| 03:06 | avida | hrm, that only creates strings |
| 03:07 | avida | this will return sequences: (take 3 (iterate #(conj % "hi") (list "hi"))) |
| 03:18 | Lau_of_DK | avida , thanks, you can also (replicate 1000 "hi") |
| 03:18 | Lau_of_DK | There are a few options |
| 03:19 | avida | ha, i totally misunderstood how take worked, thanks |
| 03:21 | avida | you can use (cycle (list "hi")) too |
| 03:24 | Lau_of_DK | oh that was a good one :) |
| 03:24 | Lau_of_DK | my first was (for [x (range 1000)] "hi") |
| 03:39 | jdz | Lau_of_DK: it looks like 1000 is infinity for you... |
| 03:40 | Lau_of_DK | hehe, its about 995 hits more than I expect to get at the most |
| 03:40 | Lau_of_DK | Anyway, I'm having some trouble outputting the object[][] type to Java, how would I do that? |
| 03:41 | Lau_of_DK | ex (to-array [(to-array [1 2]) (to-array[1 2]) ...]) would to be an array within an array, but it still fires a ctor argument error |
| 03:49 | jdz | Lau_of_DK: how about (to-array [[1 2][1 2]]) ? i admit i have started looking at clojur only yesterday |
| 04:30 | Lau_of_DK | same result im afraid |
| 04:35 | jdz | the form i mentioned works without errors for me... |
| 04:35 | Lau_of_DK | I see that Chouser has posted something like a bug-report on the issue |
| 04:35 | Lau_of_DK | http://paste.lisp.org/display/61639/xml |
| 04:36 | Lau_of_DK | remove the /xml from the url |
| 05:14 | achim_p | Lau_of_DK: question still open? try to-array-2d |
| 05:14 | achim_p | reason is: to-array constructs an array of objects, without conveying information about the types inside. so an array of arrays looks like a 1D array of objects to java. see also (doc into-array) |
| 05:44 | Lau_of_DK | achim_p, still open, but thanks that was a good suggestion, I didnt find that procedure documented on the website, but I'll give it a go |
| 05:53 | Lau_of_DK | achim_p, you got a sec? |
| 05:55 | Lau_of_DK | I actually think it working now, it constructs like it should, but the JTable Im populating just hangs afterwards |
| 05:56 | Lau_of_DK | Im getting some ArrayIndexOutofBounds, which is weird since I never assign a size |
| 06:00 | achim_p | mmh, hard to say. are the inner arrays all equal-sized? maybe a jtable doesn't like ragged 'matrices'. i don't know much about jtables, though |
| 06:03 | lisppaste8 | Lau_of_DK pasted "2d array w. bad dimensions" at http://paste.lisp.org/display/67849 |
| 06:03 | Lau_of_DK | achim_p, this routine digs into an xml structure thats like <problem> <title> bla </title> <solution> blub </solution> </problem> |
| 06:03 | Lau_of_DK | And its supposed to return "title" "solution" |
| 06:03 | Lau_of_DK | 2d |
| 06:04 | jdz | Lau_of_DK: the code layout sucks to be honest. |
| 06:04 | Lau_of_DK | the layout? |
| 06:05 | H4ns | rather offensive usage of white space :) |
| 06:05 | jdz | Lau_of_DK: and you are still putting arbitrary constants in your code when you have been given a solution that does not involve doing so... |
| 06:05 | Lau_of_DK | okay, when you girls are done prettying up, could you look at the actual code? |
| 06:05 | H4ns | *g* |
| 06:05 | jdz | Lau_of_DK: the problem is we can't see the code... |
| 06:06 | H4ns | but really, get an editor that does the identation right so that it is easier to just read it. |
| 06:06 | H4ns | as, say, an act of politeness. |
| 06:07 | Lau_of_DK | noted |
| 06:07 | achim_p | Lau_of_DK: what does (map (fn [x] (get-problem x)) titles) return? |
| 06:08 | Lau_of_DK | the function (get problem) is also pasted, its supposed to return a 1d array like ["title" "solution"] |
| 06:08 | Lau_of_DK | Which then should be wrapped in another array |
| 06:08 | Lau_of_DK | so its like [["title1" "sol1"] ["title2" "sol2"]] |
| 06:09 | H4ns | did you try it? does it do so? |
| 06:09 | achim_p | yes, i can see what it should do, but does it actually? ;) |
| 06:09 | Lau_of_DK | Positively maybe |
| 06:09 | achim_p | please try the map call in isolation, and print the result |
| 06:09 | Lau_of_DK | user=> (get-problem "Bad Cable") |
| 06:09 | Lau_of_DK | (["Bad Cable" "Try with another cable"] ["Bad Cable" "Try wifi"] ["Bad Cable" "I |
| 06:09 | Lau_of_DK | nform hotel of broken cable in room."]) |
| 06:11 | H4ns | just as it would be easier to read: (fn [x] (foo x)) is equivalent to just foo, no? |
| 06:12 | Lau_of_DK | yea, im using map to cycle all the xml hits |
| 06:14 | H4ns | so, what does (xml-> w-xml :problem :title text) actually return? |
| 06:14 | H4ns | isnt that a sequence of sequences? |
| 06:14 | Lau_of_DK | The return the text from all xml nodes in /problem/title/ |
| 06:15 | Lau_of_DK | user=> (xml-> xml :problem :title text) |
| 06:15 | Lau_of_DK | ("--- INFO ---" "3.rd MAC" "Bad Cable" |
| 06:15 | Lau_of_DK | ... |
| 06:16 | H4ns | looks proper. i'd freely insert some print statements at this point :) |
| 06:17 | Lau_of_DK | huh? |
| 06:17 | achim_p | and you made sure that get-problem returns a 2-tuple for each of these? |
| 06:18 | Lau_of_DK | No im not 100% sure - how can I be + |
| 06:19 | achim_p | i think you'll have to make sure. i think either the first row of the matrix or the maximum of row sizes serves as an implicit size declaration for jtable. |
| 06:20 | achim_p | (that's wild guessing) |
| 06:20 | H4ns | Lau_of_DK: it does not look as if there is a way for get-problem to return anything but an array of seqs |
| 06:20 | H4ns | no, a seq of arrays really |
| 06:20 | H4ns | Lau_of_DK: print statements as in "make the program print what it is doing to trace the problem" |
| 06:21 | H4ns | Lau_of_DK: with common lisp, i'd trace get-problem, but clojure does not have trace on the repl yet, or does it? |
| 06:22 | Lau_of_DK | no it doesnt |
| 06:22 | Lau_of_DK | Ok, I'll have to hit this again on monday, thanks for the input guys |
| 06:22 | H4ns | Lau_of_DK: one last thought: |
| 06:23 | Lau_of_DK | shoot |
| 06:23 | H4ns | Lau_of_DK: what happens if get-problem returns nil? |
| 06:23 | H4ns | could solutions be nil at any time? |
| 06:23 | Lau_of_DK | I suppose I get an array of nils |
| 06:23 | H4ns | ah, no. :) |
| 06:24 | H4ns | well, without the input data set, proper formatting and some more clojure experience it is just guesswork. :) |
| 08:21 | prunedtree | how small can a deployable and standalone "hello world" in closure ? (including all the JVM machinery) |
| 08:34 | H4ns | depends on much time you want to invest stripping down the jre |
| 08:35 | H4ns | clojure itself is below 500k, but the jre as distributed uses around 54 mb on-disk |
| 08:35 | prunedtree | ok |
| 08:36 | prunedtree | I'm extremely unfamiliar with Java (the platform) |
| 08:37 | prunedtree | how does it perform as a desktop deployement ? Is it common to deploy application along with their own java runtime ? |
| 08:37 | H4ns | yes. shrink-wrapped applications come with their own jre. |
| 08:38 | prunedtree | Is there any issue distributing commercial apps this way ? (regarding sun's licencing on the jre for instance) |
| 08:39 | H4ns | any issue, well. there is a license agreement, but you can distribute the jre at no cost if you follow sun's guidelines. |
| 08:40 | prunedtree | ok, so it's viable for commerical desktop applications |
| 08:41 | H4ns | certainly |
| 08:41 | rhickey | prunedtree: sure, look at IntelliJ for instance |
| 08:41 | prunedtree | with all the web madness, some language seem to think it's 'all okay' not to be distributable because they run on servers anyway |
| 08:42 | prunedtree | as I said, I'm scarily ignorant about Java (the platform/the language) |
| 08:42 | prunedtree | I know how sun's JVM internals works very well, but that's because I know the roots of it (not java) |
| 08:43 | rhickey | prunedtree: there's Java Web Start too |
| 08:43 | prunedtree | how fast does the JVM boot these days ? haven't tried for years |
| 08:43 | prunedtree | rhickey : oh great, you are on IRC :) |
| 08:43 | prunedtree | the web is very scarce on implementation details of closure |
| 08:44 | rhickey | well, there is the source |
| 08:44 | prunedtree | I've tried to read everything I could find on clojure. I've watched the 'clojure for lisp programmers' screencast. looked very good |
| 08:45 | prunedtree | I don't come from a Lisp background, but from smalltalk. so Java always looked like a regression to me. but the way clojure does polymorphism looks nice |
| 08:46 | prunedtree | I have no idea how to setup a Java environnement and so on... I wonder how many clojure newbies have no idea how to do Java at all |
| 08:46 | rhickey | H4ns: great! it's been fun watching you dive in |
| 08:47 | H4ns | prunedtree: i have used java a little, but only a little. it is a relatively friendly environment to work in, and most stuff is usually described from a professional or enterprise perspective. |
| 08:48 | prunedtree | that's great. actually, I've always been tempted to use the JVM given the great compiler/GC/threading technology |
| 08:48 | prunedtree | but in my memories it could take dozens of seconds to boot... and I'd really like my applications to boot under 2 seconds |
| 08:49 | H4ns | rhickey: i want member, at least. find would be nice, too, but given that the standard library is rather minimal, (first (member ..)) would do |
| 08:50 | prunedtree | I've looked into what can be done with JNI, and I've seen that there have been many many changes over the years |
| 08:50 | prunedtree | It used to be ungodly slow |
| 08:50 | H4ns | prunedtree: all the java programmers i know avoid the jni at all cost. |
| 08:50 | rhickey | H4ns: you've seen: http://groups.google.com/group/clojure/msg/ff8777fc5f5d0157 ? |
| 08:51 | prunedtree | H4ns : my idea is quite simple. I have a single JNI method to implement |
| 08:51 | prunedtree | with { return getBufferAddress(...)() } in the body |
| 08:51 | H4ns | rhickey: yes, that is what i am referring to. |
| 08:52 | prunedtree | (ie, a native call on a bytebuffer) |
| 08:52 | prunedtree | plus a hack to get the base address of nio direct buffers |
| 08:52 | prunedtree | with that, you can do anything |
| 08:52 | rhickey | It's been an experiment of mine to see how long people can go without them - the answer is, pretty long! |
| 08:53 | rhickey | A nice thing about not having them is it discourages slow code, people use the associative structures more rather than using lists when inappropriate |
| 08:54 | rhickey | but I understand their utility for small things |
| 08:54 | prunedtree | re JNI. the thing is, I want to write very high performance apps, and clojure will not be fast enough |
| 08:54 | prunedtree | it's not because of clojure. even java isn't fast enough... and C isn't either |
| 08:55 | prunedtree | I have absolutely no issue writing compilers that produce machine code myself, and clojure should be up to the task |
| 08:56 | blackdog | rhickey: did you see charlie nutter's post about Xbootclasspath speeding up jruby boottime significantly? i'm not sure if it would make a difference for clojur or not |
| 08:57 | drewr | blackdog: I've been using it in my clojure run script and it only gives me about 0.1s improvement. |
| 08:57 | blackdog | ok, there it is :) |
| 08:57 | prunedtree | how long is your boot time overall ? |
| 08:57 | drewr | About 1.4s. :-( |
| 08:57 | blackdog | jruby probably has a lot more overhead in base classes than clojure |
| 08:58 | prunedtree | 1.4 sec... well that's much better than it used to be. still huge but I (my users) could live with that I think |
| 08:58 | H4ns | rhickey: find/member are the cl programmer's set membership operations, and it is often useful to consider a vector or list to be a set. if clojure has other techniques for achiving that, what are they? |
| 08:58 | rhickey | H4ns: use sets |
| 09:00 | drewr | prunedtree: Yeah, it's not ideal, but I don't use Clojure for fast, shell-style things. If I'm doing reports from a db, however, I don't care about adding another second on a multi-second process. |
| 09:00 | rhickey | that was my point before, without sets in the language, you use lists/vectors and it doesn't scale, with sets in the language, you should use them |
| 09:00 | prunedtree | might be okay for shell things if you keep an instance open I guess |
| 09:00 | drewr | I also use -Xverify:none, which saves another 0.1s. |
| 09:01 | prunedtree | then simply pipe some shell arguments to the running instance, which will spawn a worker thread for it |
| 09:01 | prunedtree | there might be some way to achieve that using xargs/netcat... or simply write a trivial C app that does it |
| 09:02 | rhickey | blackdog: with AOT compilation of Clojure we could precompile boot.clj. That + Xbootclasspath would probably make a difference |
| 09:02 | H4ns | rhickey: so please do not include member or find in the standard library. i'll actually print the pdf today and read it on my flight home, so i'll know how i determine set membership on the weekend :) |
| 09:02 | prunedtree | rhickey : btw, I was surprised by one element of the syntax while viewing your presentation |
| 09:02 | blackdog | rhickey: ok, nice |
| 09:05 | prunedtree | why are maps {:keyA x, :keyB y } but destructuring them {x :keyA, y :keyB} ? |
| 09:05 | prunedtree | this seems very confusing |
| 09:08 | rhickey | prunedtree: you are using x and y there for 2 different purposes, in the first case they are the values, in the second the let-bound names |
| 09:08 | drewr | prunedtree: They aren't. He just happened to used keywords as values in the destructuring slide. |
| 09:08 | drewr | (I'm assuming you're talking about the recent talk.) |
| 09:08 | rhickey | in destructuring, you are really making a mapping from a let-bound name to a key |
| 09:09 | prunedtree | rhickey : bound to values, right ? |
| 09:09 | rhickey | yes |
| 09:09 | prunedtree | so they should be to the same place as values (imho) |
| 09:10 | prunedtree | it looks as if you're bouding names to keys with :a being the value (inverse mapping) |
| 09:10 | prunedtree | to my untrained eyes |
| 09:10 | rhickey | I disagree, when you say let [x 42] the value comes second, here, the value isn't supplied directly, rather its key is, also second |
| 09:11 | prunedtree | binds x to the index of the vector that has value 42 ? |
| 09:11 | prunedtree | weird |
| 09:11 | rhickey | no, I'm comparing to normal let |
| 09:12 | prunedtree | ah, (x 42) in lisp... |
| 09:12 | rhickey | let [name value] |
| 09:12 | prunedtree | yeah, must be my lack of familiarity with Lisp speaking. but the lack of symetry is disturbing |
| 09:12 | rhickey | (let [ {name value-key} value-map] |
| 09:12 | prunedtree | If it's idiomatic I'll get used to it hopefully |
| 09:13 | prunedtree | where value-map could be a former binding, right ? |
| 09:13 | rhickey | I don't disagree that one could see it differently, but this is how it is, and, as I said, this way is necessary in order to support :as and :or |
| 09:14 | prunedtree | okay |
| 09:15 | drewr | prunedtree: I see what you mean now. I haven't destructured maps very much. |
| 09:15 | rhickey | :and :or :keys etc are very powerful |
| 09:17 | prunedtree | also there's a weird difference between ident and :ident.. aren't both symbols ? what is the rationale behind that ? |
| 09:17 | prunedtree | (especially when uou have strange forms like :or / :as .. which are obviously not keys) |
| 09:17 | rhickey | no, keywords are not symbols in Clojure |
| 09:18 | rhickey | (symbol? :key) -> false |
| 09:19 | prunedtree | so the difference is in the resolution ? |
| 09:20 | rhickey | they are read as different types of objects |
| 09:20 | prunedtree | why aren't :or/:as keywords ? old lisp convention ? |
| 09:21 | rhickey | they are keywords, not in the 'reserved words' sense |
| 09:22 | rhickey | a keyword is just a datatype with the useful property that it always evaluates to itself |
| 09:22 | prunedtree | whereas symbols are resolved ? |
| 09:25 | rhickey | prunedtree: yes, see: http://clojure.org/reader and http://clojure.org/evaluation |
| 09:26 | prunedtree | yeah, I've read that. I guess the sourcecode provides the most information |
| 09:26 | rhickey | that's in those docs, no need to read the source to Clojure in order to use it |
| 09:27 | prunedtree | well the docs seem very barebones. I've read it and it feels more than a teaser than real documentation. no offsence meant :) |
| 09:29 | rhickey | http://clojure.org/evaluation : "Strings, numbers, characters, nil and keywords evaluate to themselves." |
| 09:31 | prunedtree | ah yes, keywords aren't symbols. I'm not used to that denomination, sorry |
| 09:37 | jdz | Clojure: what would it [Lisp] be like if you had been given a second chance. |
| 10:13 | drewr | So I fired up a JVM with the requisite jswat flags, and I'm running the jswat application. |
| 10:13 | drewr | And I've attached to the socket. |
| 10:13 | drewr | How do I get an exception in the REPL to appear in jswat? |
| 10:17 | leafw | uncatched exceptions will appear in the plugged debugger |
| 10:18 | drewr | I just ran: |
| 10:18 | drewr | user=> (throw (Exception. "foo")) |
| 10:18 | drewr | java.lang.Exception: foo (NO_SOURCE_FILE:0) |
| 10:18 | drewr | But jswat doesn't seem to care. |
| 10:18 | leafw | because the reader is catching it. I don't know how one can stop the reader from doing so. |
| 10:19 | rhickey | drewr: usually there is some break-on-exception setting |
| 10:19 | drewr | leafw: Ah, that makes sense. |
| 10:20 | drewr | rhickey: Looking... |
| 10:21 | rhickey | because there are so many exceptions-as-flow-control uses, they make you say which ones to break on |
| 10:21 | prunedtree | in java or in clojure ? |
| 10:21 | rhickey | no exceptions as flow control in Clojure |
| 10:22 | rhickey | except in the transaction system |
| 10:22 | drewr | There's a Breakpoints window, with "Uncaught exceptions" checked. Perhaps leafw is right that since the REPL is catching the exception to show it to me, the debugger doesn't know about it. |
| 10:24 | drewr | That seems counterintuitive though, since the point of the attached debugger is to monitor a running JVM. |
| 10:24 | leafw | drewr: jswat is just a wrapper for jdb |
| 10:24 | leafw | drewr: jdb only shows uncatched exceptions |
| 10:26 | rhickey | new breakpoint|breakpoint type|exception pick exception type etc |
| 10:27 | drewr | rhickey: Yeah, just trying that... |
| 10:27 | leafw | ha, so it can be configured :) |
| 10:27 | drewr | ...and getting somewhere now. |
| 10:29 | drewr | I think it would be worth adding a sentence in the "Getting Started" section that says something to the effect of, "Make sure you set up a breakpoint for something other than the default uncaught exceptions rule..." |
| 10:31 | prunedtree | what is the prefered environnement for clojure under win32 ? eclipse ? |
| 10:31 | Chouser | drewr: you could add details here: http://en.wikibooks.org/wiki/Clojure_Programming#Getting_Started |
| 10:31 | drewr | prunedtree: For me? Emacs. |
| 10:32 | H4ns | prunedtree: emacs-23 and slime work for me. |
| 10:32 | Chouser | prunedtree: gvim and a command prompt, just like everywhere else. :-) |
| 10:35 | prunedtree | on windows, sure.... |
| 10:35 | prunedtree | I guess that would be somewhat doable, but why not use the candy |
| 10:36 | prunedtree | aren't there good Java IDEs with decent integration of clojure ? |
| 10:36 | baetis-fly | i thought someone was working on a netbeans plugin, but i agree, emacs + slime. |
| 10:36 | dudleyf | prunedtree: enclojure is a plugin for Netbeans |
| 10:36 | H4ns | there is enclojure which integrates into netbeans, but that seemingly does not run on windows. |
| 10:37 | prunedtree | ohh |
| 10:37 | Chouser | candy rots teeth. Or maybe I'm already too old-fashioned. I understand gvim and command prompts, so I use them. |
| 10:37 | prunedtree | so emacs it is on windows then... ironic :) |
| 10:37 | Chouser | H4ns: oh, I'm sure that must be a temporary failure. I'm pretty sure enclojure is meant to work on Windows. |
| 10:37 | cemerick | enclojure certainly is supposed to run on windows; I don't have any experience, but I've seen reports of success on the google group |
| 10:38 | prunedtree | I'll give it a try then |
| 10:38 | H4ns | oops - i am alone, then. |
| 10:39 | H4ns | so i stand corrected. enclojure does not work for me on vista/x64 right now but i'll try the next version. |
| 10:39 | drewr | Hm, this doesn't seem very productive. I have to reattach the session after every exception. |
| 10:39 | rhickey | cemerick: I haven't heard you chime in on the potential maps as java.util.Maps change - iirc you were one of the few to stand up for keeping them Collections |
| 10:39 | prunedtree | it looks like it's made for OSX not windows |
| 10:39 | prunedtree | quoting the site: At the moment enclojure has only been tested on Mac OSX. If you are testing on Windows/Linux, please post any issues you find in the enclojure group. |
| 10:40 | cemerick | rhickey: I've been very distracted by other stuff... |
| 10:40 | prunedtree | well, can't be much worse than emacs in windows |
| 10:41 | rhickey | cemerick: short story is I'm thinking about making the change |
| 10:42 | Chouser | relevent thread: http://groups.google.com/group/clojure/browse_thread/thread/e83e3de776fd8143/26c4a2995fbc959c |
| 10:42 | Chouser | ^ cemerick |
| 10:42 | cemerick | Chouser: thx, reading now |
| 10:46 | cemerick | wwmorgan: do you have any opinion on this maps as j.u.Map change? |
| 10:49 | wwmorgan | it's easy enough to go from a j.u.Map to an IPersistentMap, because you can use (into {} m) |
| 10:50 | cemerick | wwmorgan: I think the general concern is pushing clojure maps out into java libs that require j.u.Maps; or, implementing java interfaces that require a j.u.Map |
| 10:54 | wwmorgan | cemerick: I see. Up to now you would need a function like this http://paste.lisp.org/display/67857 |
| 10:54 | abrooks | This shows how little Java background I have. Can't a class implement multiple interfaces? Why can't Clojure maps implement both j.u.Map and yadda.yadda.collection ? |
| 10:55 | cemerick | abrooks: j.u.Map and j.u.Collection have a conflict (with the remove method returning different types -- void in one and an Object in another, I think) |
| 10:55 | abrooks | Ah! Okay. Now I see. |
| 10:55 | wwmorgan | abrooks: I think the main concern is how you handle mutability |
| 10:57 | cemerick | That's a good point. Making cmaps implement j.u.Map gets you one step closer to java compatibility, but given that so many java libs assume that Maps are mutable, would we simply be setting ourselves up to fail further down the call stack? |
| 10:57 | wwmorgan | it would be pretty disastrous if users started .put-ing their clojure maps because they can |
| 10:58 | wwmorgan | instead of using assoc, I mean |
| 10:59 | rhickey | cemerick: there's a well defined subset of read-only methods, all of the others are optional |
| 11:00 | cemerick | rhickey: Sure. It's unfortunate that there isn't a separate MutableMap interface; however, the optionality of those methods is entirely defined by API contract and nothing else. There's a *lot* of java code out there that simply assumes mutability of Maps. |
| 11:01 | cemerick | I'd suggest that that's not the case for j.u.Collection, which was long just a stand-in before Iterable was available. |
| 11:02 | rhickey | cemerick: then a common use case might be just calling a java.util.XXXMap ctor passing a Clojure map, which you can't do right now |
| 11:03 | cemerick | rhickey: calling that ctor from clojure, you mean? |
| 11:04 | rhickey | cemerick: from Java, for interop |
| 11:05 | rhickey | cemerick: I agree about optional being a lame contract, but doesn't reduce the utility of read-only |
| 11:07 | cemerick | rhickey: no, the utility isn't diminished at all -- I'm just trying to think of the gestalt of java Map usage I've seen/written. Assuming mutability is pretty common. I might be wrong about that, of course. |
| 11:08 | prunedtree | maybe you could have in/out args for java interop |
| 11:08 | cemerick | I think this is a choice between six of one and a half-dozen of another. There's pitfalls on either side. |
| 11:08 | wwmorgan | If clojure maps implement java.util.Map, then getting a mutable map is as easy as calling the HashMap constructor and passing in a clojure map. Although it might be confusing for new users |
| 11:08 | prunedtree | let java mutable your structure and give you the mutated one back as if the changes where atomic |
| 11:09 | rhickey | cemerick: enough people are asking for Clojure maps as Maps, indicating the read-only limitation of that is not prohibitive |
| 11:10 | cemerick | rhickey: True -- at least for the current Clojure-using population. |
| 11:11 | cemerick | rhickey: is Stuart right in assuming/hoping that seq on a map would continue to emit key-value pairs after this change? |
| 11:12 | rhickey | absolutely |
| 11:16 | dudleyf | Immutability is such a stand-out feature of Clojure that most users are not going to be too surprised by a read-only limitation on Clojure Maps |
| 11:17 | cemerick | dudleyf: I think the surprise will be more in the neighborhood of passing clojure maps to libraries or returning clojure maps from gen-class impl functions where the recipient assumes mutability |
| 11:18 | cemerick | I guess I'm essentially neutral on the change. I certainly see some upside, but losing the single base for all clojure collections is unfortunate, IMO. |
| 11:18 | dudleyf | cemerick: Sure, but I found it much more surprising that clojure maps weren't Maps |
| 11:19 | dudleyf | Maybe we should just start a JSR to make the Collection and Map interfaces compatible |
| 11:19 | dudleyf | ;-) |
| 11:19 | Chouser | can't we just submit a patch to fix j.u.Collections remove method? |
| 11:20 | cemerick | dudleyf: for sure, it falls outside of one's expectations. I think there's solid reasons behind Rich's choice there, though. The rising tide of Java<-->Clojure intermingling seems to be nudging the needle, tho. |
| 11:21 | dudleyf | cemerick: Yeah, it makes sense once you understand the reasoning behind it |
| 11:21 | cemerick | Ach, Map doesn't extend Iterable (or, Iterable<Entry<K,V>>, I suppose)! That's really unfortunate. I was hoping that I could fall back to expecting that all clojure collections were Iterable. |
| 11:24 | rhickey | cemerick: Clojure maps will still be Iterable |
| 11:24 | cemerick | rhickey: actually, could you make clojure maps Iterable? That would be helpful. |
| 11:24 | rhickey | and IFn and all of their other goodness |
| 11:26 | cemerick | rhickey: OK, I'm +0 on it as a whole. ;-) |
| 11:27 | rhickey | +0 - that gives me all the points I need! :) |
| 11:28 | cemerick | I always knew you were a low maintenance benevolent dictator. |
| 11:28 | cemerick | The mutability issue may be more important than our particular circle appreciates, though. I wouldn't be super surprised if the common idiom becomes (HashMap. clojure-map) in a year's time. |
| 11:29 | Chouser | rhickey: did you see my new patch for clojurescript? I don't need any response except that you're aware of it or not. |
| 11:29 | rhickey | Chouser: sorry, saw your message, yes, haven't looked at the patch |
| 11:29 | dudleyf | cemerick: But isn't that the idea? |
| 11:30 | Chouser | rhickey: ok, thanks. |
| 11:31 | cemerick | dudleyf: I wouldn't think so; if that's expected to be the norm, then a simple helper function to remap a map to a j.u.HashMap is a simpler, easier choice. |
| 11:32 | rhickey | cemerick: are you suggesting a copy-free mapper class that implemented mutability? |
| 11:34 | cemerick | rhickey: I thought a patch for such an approach was put forth over the summer -- perhaps in the same discussion around making vectors implement j.u.List? |
| 11:34 | Chouser | I think prunedtree suggested that -- could be a little thing wrapping a ref and a persistent map |
| 11:36 | cemerick | hrm, I think I missed that, but that approach sounds very pleasant. There are many Java methods that take a map, fiddle with it, and return void. |
| 11:39 | Chouser | would that be better than just copying a PersistentMap into a j.u.Map, passing it in, and creating a new PersistentMap afterward? |
| 11:41 | cemerick | Chouser: I'd think so, especially in those cases where you need to capture changes being made to a j.u.Map in a method without a return value. |
| 11:42 | cemerick | But that's sort of orthogonal to what I've understood the demand to be: that is, that clojure maps should directly implement j.u.Map. |
| 11:46 | Chouser | orthogonal, yes. |
| 11:47 | Chouser | but while we're still talking about it, rhickey is nearly done implementing it. Next words from him will be "IPersistentMap now implements j.u.Map" |
| 11:47 | cemerick | I mean, that approach would be generally more useful IMO, but then I can't really give voice to the view that implementing j.u.Map is really important. |
| 11:47 | cemerick | heh, yeah, that's a safe bet. |
| 12:09 | prunedtree | wow. expected it to be kinda slow, but not that much (microbenchmarking :s) |
| 12:42 | prunedtree | is naive fibonnaci an isolated case or are function calls really expensive in clojure ? |
| 12:43 | Chouser | a clojure function call should cost the same as a java function call |
| 12:44 | cemerick | prunedtree: you can paste your microbenchmark if you like. I'll bet a type hint will bring the clojure into parity with Java. |
| 12:44 | prunedtree | (defn fib [n] |
| 12:44 | prunedtree | (if (< n 2) |
| 12:44 | prunedtree | n |
| 12:44 | prunedtree | (+ (fib (- n 1)) |
| 12:44 | prunedtree | (fib (- n 2))))) |
| 12:44 | prunedtree | note, I tested on two other very very dynamic systems that do not need any type hint to produce ridiculously superior performance |
| 12:45 | prunedtree | in fact, even an interpreter performs faster... |
| 12:45 | prunedtree | maybe it's the JVM I have which sucks ? |
| 12:46 | prunedtree | Java: 1.6.0_07; Java HotSpot(TM) Client VM 10.0-b23 |
| 12:48 | cemerick | prunedtree: you'll likely be happier with (defn fib [#^Integer n] ... |
| 12:49 | cemerick | fwiw, you'd be better off using loop/recur, which won't blow stack |
| 12:53 | prunedtree | as I said, I tested on other systems that do not have types |
| 12:53 | prunedtree | and I have the same difference (an order of magnitude) if a feed a ratio as input (to avoid fixnum arith) |
| 12:53 | ozzilee | prunedtree: What kind of times are you seeing? |
| 12:54 | prunedtree | (fib 36) takes 17 sec |
| 12:54 | blackdog | does that include jvm starup time? |
| 12:54 | Chouser | (fib 36) is 1.8 seconds here. |
| 12:55 | walters | prunedtree: what hardware architecture? |
| 12:55 | Chouser | user=> (time (fib 36)) |
| 12:55 | Chouser | "Elapsed time: 1814.196797 msecs" |
| 12:55 | ozzilee | (fib 25) is 11.8 seconds on a 700mhz PPC :-) |
| 12:56 | prunedtree | core2duo ulw |
| 12:56 | prunedtree | 1 ghz |
| 12:56 | Chouser | prunedtree: that's faster than my machine. there must being something "wrong" with your environment. |
| 12:56 | walters | prunedtree: oh, client VM...hm. you might use -server |
| 12:57 | walters | i think in the latest openjdk beta there is no -client and -server anymore which will be nice |
| 12:57 | cemerick | client/server shouldn't impact things that much... |
| 12:57 | dudleyf | unless it does include jvm startup time |
| 12:57 | prunedtree | and i'm getting under 5 sec in interpreted smalltalk |
| 12:58 | Chouser | yeah, even without -server I'm at about the same speed |
| 12:58 | prunedtree | <dudleyf> unless it does include jvm startup time << doesn't, it's inside a program |
| 12:59 | dudleyf | Then client/server won't make much of a difference until you run the same benchmark 10,000 times or so |
| 12:59 | prunedtree | <Chouser> "Elapsed time: 1814.196797 msecs" |
| 12:59 | prunedtree | what is your hardware ? that's closer to what i'd expect to see... |
| 13:00 | Chouser | prunedtree: core 2 duo, 800 MHz |
| 13:00 | prunedtree | and anything specific jvm-wise ? |
| 13:03 | Chouser | java version "1.6.0_06" Java HotSpot(TM) Server VM (build 10.0-b22, mixed mode) |
| 13:03 | prunedtree | maybe the client VM is at fault |
| 13:03 | prunedtree | how do you get the server thing ? j2ee ? |
| 13:04 | lisppaste8 | abrooks pasted "lazy fib performance" at http://paste.lisp.org/display/67863 |
| 13:04 | Chouser | I doubt that's the issue, but I guess maybe ... I just have a pretty stock ubuntu install. Not sure how I got server instead of client. |
| 13:04 | abrooks | Lazy fib 36 (i.e. 35) takes 0.242755 msecs |
| 13:05 | abrooks | prunedtree's fib on the same system takes 2549.496222 msecs |
| 13:05 | abrooks | That's crazy. |
| 13:05 | abrooks | 1000X slowdown. |
| 13:06 | abrooks | I think prunedtree has spotted a real performance issue. |
| 13:06 | Chouser | With OpenJDK Server VM (build 1.6.0_0-b11, mixed mode), I'm still getting (fib 36) in 1.5 seconds |
| 13:07 | Chouser | abrooks: your algorithm is different -- you're caching values instead of recomputing. |
| 13:07 | abrooks | Chouser: I know. |
| 13:07 | Chouser | I assume prunedtree is using an algorithm that is intentionally beating on function calls. |
| 13:07 | prunedtree | yes |
| 13:07 | dudleyf | prunedtree: just pass -server to the java command |
| 13:08 | prunedtree | doesn't work. I have j2se |
| 13:08 | Chouser | But for some reason his is taking 10x longer than mine. I think that's an environment issue, somehow. |
| 13:08 | prunedtree | maybe there's something wrong with the client VM |
| 13:10 | dudleyf | prunedtree: I think you're right |
| 13:10 | prunedtree | humm 2 mb... good that sun has good proxies here... |
| 13:11 | prunedtree | 100 mb, not 2 |
| 13:11 | dudleyf | user=> (time (fib 36)) |
| 13:11 | dudleyf | "Elapsed time: 13347.682 msecs" |
| 13:11 | dudleyf | with -client |
| 13:11 | cemerick | prunedtree: I just tried your function on -client and -server, no timing difference. |
| 13:11 | prunedtree | client still doesn't use the c2 compiler ? urgh... thought they fixed that years ago |
| 13:12 | prunedtree | I hope the server performance is more reproducible than the client one ;) |
| 13:12 | dudleyf | user=> (time (fib 36)) |
| 13:12 | dudleyf | "Elapsed time: 2936.406 msecs" |
| 13:12 | dudleyf | with -server |
| 13:12 | prunedtree | that creates a huge incentive to bundle the VM with any app you distribute |
| 13:12 | danlarkin | (time (fib 36)) |
| 13:12 | danlarkin | "Elapsed time: 8332.648 msecs" |
| 13:13 | danlarkin | that's with prunedtree's fib function |
| 13:13 | prunedtree | wouldn't want my clients using the client version and getting horrible performance |
| 13:14 | walters | prunedtree: ah...i think both VMs are shipped with the J2SDK or whatever it's called, they created a -client because they thought it would make a large startup time impact as I understand it |
| 13:15 | dudleyf | It does cut down startup time significantly, but I've never seen that kind of performance gap on simple benchmarks |
| 13:15 | leafw | walters: :if that's the reason, makes no sense anymore: here a jdk takes one or 2 seconds to launch (T60 laptop) |
| 13:15 | walters | leafw: in a cold cache? |
| 13:16 | leafw | walters: in cold, it may take 5 or 6 secs |
| 13:16 | leafw | granted. |
| 13:16 | leafw | with -server flag, we are talking. |
| 13:19 | prunedtree | bah |
| 13:19 | prunedtree | the sun website sucks |
| 13:20 | prunedtree | I have no idea how to get the server VM.... |
| 13:20 | Chouser | prunedtree: what happens when you use -server -- error? no change? |
| 13:21 | prunedtree | error |
| 13:21 | prunedtree | tells me I don't have the right dll |
| 13:21 | prunedtree | (ie I don't have the server VM) |
| 13:23 | dudleyf | prunedtree: http://tinyurl.com/5ptq6n |
| 13:24 | dudleyf | From there you should be able to pick your platform and download the jdk |
| 13:24 | dudleyf | Or wait, are you on a Mac? |
| 13:24 | prunedtree | windows |
| 13:25 | prunedtree | and I tried the jre 1.6u7 |
| 13:25 | dudleyf | Then you should be able to download it from there ^^^ |
| 13:25 | prunedtree | and also the jdk |
| 13:25 | dudleyf | You want the jdk |
| 13:26 | prunedtree | and they don't give me the server thing :/ |
| 13:26 | prunedtree | maybe I should remove the jre and put the jdk ? |
| 13:26 | dudleyf | Maybe |
| 13:27 | dudleyf | I haven't installed a JRE without the JDK in a long time |
| 13:28 | prunedtree | uninstalling both. the jdk you linked to was the one I had btw |
| 13:29 | achim_p | Chouser: just read your post to the list regarding shell calls. since that's on my todo list anyway, i could as well do it as a seperate library |
| 13:29 | achim_p | for now my needs are simple, sth like ruby's/python's popen* would do (in conjunction with expect), but i'm not settled on it. you don't seem to like it - care to elaborate on where you see the shortcomings? |
| 13:30 | walters | Chouser: btw if you do take influence from something, python's subprocess is very good and the only one i've used that isn't broken or very limited |
| 13:31 | abrooks | walters: Subprocess is better than the others but is still horribly awkward. Launching programs sucks in Python. |
| 13:31 | walters | the hard part about implementing it is you can't do it on top of the JDK ProcessBuilder class since it won't let you do prefork functions |
| 13:31 | walters | abrooks: it sucks everywhere as far as i know |
| 13:31 | walters | it's like remoting |
| 13:32 | walters | they'll just never be as nice as local library call |
| 13:33 | abrooks | I have a Python library partially constructed that allows for much better process control. |
| 13:33 | abrooks | print pl("ls", "/dev")("grep", "-i", "tty")().stdout |
| 13:34 | abrooks | There's also IFS parsing available if you don't want each argument as a separate string. |
| 13:35 | walters | yeah, i have a shell (http://hotwire-shell.org) which implements a trivial language specifically for this, but i don't think it necessarily makes sense in the core subprocess invocation library |
| 13:37 | Chouser | walters: that looks nifty |
| 13:37 | abrooks | I don't know if belongs in the core library but I want something better as part of the distribution. Your project looks very interesting. |
| 13:40 | Chouser | I guess my objections to python's popen* revolve around the combinatorially named functions and that the mechanisms for when you want to capture none of the output, just stdout, or stdout and stderr each feel rather different. |
| 13:40 | Chouser | I don't think I've ever used subprocess. |
| 13:40 | walters | yeah, popen* is broken |
| 13:40 | Chouser | so as long as we don't do that, I'm golden. ;-) |
| 13:41 | prunedtree | reinstalled everything, rebooted.... and still no server |
| 13:41 | Chouser | I find it unlikely that implementing something akin to abrooks' api would be that much harder. |
| 13:41 | Chouser | prunedtree: :-( |
| 13:42 | Chouser | hm, looking at my Windows VM, I see I also have the Client VM |
| 13:44 | abrooks | Can't you just switch the VM with the -client/-server flags or is that only with the VM provided with the Sun JDK? |
| 13:45 | Chouser | So on my 800MHz laptop, in a VMPlayer running XP, using the Sun Java Client VM, (fib 36) takes 7.6 seconds. |
| 13:46 | prunedtree | how come it's so much faster than me ? |
| 13:46 | Chouser | abrooks: apparently the VM package for windows understands the switch, but doesn't include the actual server VM. |
| 13:46 | Chouser | Error: no `server' JVM at `C:\opt\java\bin\server\jvm.dll'. |
| 13:46 | prunedtree | <abrooks> Can't you just switch the VM with the -client/-server flags or is that only with the VM provided with the Sun JDK? << I installed the jdk... which installs the jre |
| 13:47 | Chouser | I think I have only the JRE |
| 13:47 | abrooks | Okay. I'm only half paying attention. Sorry. |
| 13:49 | prunedtree | man I sure hope there's a way to avoid all this mess when I deliver application, or that platform is simply not usable (how do they manage to have something immature after more than a decade ? it takes some serious skills....) |
| 13:49 | prunedtree | you think it's legal to build the VM from the source and distribute it in a commercial package ? |
| 13:49 | prunedtree | without all the sun clutter |
| 13:50 | walters | the icedtea project has removed all proprietary plugs, but it's targeting Free operating systems and not Windows, but i doubt it would be hard to get it to build for Windows |
| 13:51 | achim_p | how about |
| 13:51 | achim_p | (popen "ls" ...) -> [in out err] |
| 13:51 | walters | i believe the goal is to get upstream openjdk to this point as well, but they are more concerned about complete compatibility |
| 13:51 | achim_p | (with-popen ["ssh" ...] in out err |
| 13:51 | achim_p | (expect in "^[uU]sername: " (fn [match] ...) |
| 13:51 | achim_p | ... )) |
| 13:51 | walters | e.g. icedtea just doesn't implement SNMP |
| 13:52 | cemerick | prunedtree: there's a *lot* of people using Java very successfully in a lot of different scenarios. It's certainly not unusable. |
| 13:52 | abrooks | achim_p: I like the context manager ("with") style much better -- much more lispy. |
| 13:52 | abrooks | You'd want both, I'd suppose. |
| 13:53 | achim_p | abrooks: yes, both |
| 13:54 | prunedtree | I'm one very unlucky people |
| 13:54 | prunedtree | the only positive side is that I am an incredible beta-tester ^^; |
| 13:59 | Chouser | wouldn't the with- version be equiv to (let [[in out err] (popen "ssh" ...)] (expect in...)) |
| 14:01 | abrooks | Chouser: Often context managers will automatically close/dealloc/cleanup the managed item on exit of the block. |
| 14:01 | Chouser | abrooks: ah, good point. |
| 14:09 | achim_p | perhaps a third version would be nice, one that slurps out+err and returns a string |
| 14:12 | achim_p | and timeouts for expect - has anybody come up with a simple way to perform blocking calls with a timeout? |
| 14:13 | lisppaste8 | achim_p pasted "with-timeout" at http://paste.lisp.org/display/67868 |
| 14:13 | walters | achim_p: you can call Thread.interrupt() on the blocking thread, not sure how that appears in clojure |
| 14:17 | achim_p | walters: thanks, i'll have to look into java threading. right now i'm abusing agents for that |
| 14:20 | prunedtree | 4.5 seconds |
| 14:20 | prunedtree | i'm still very far from 1.5 sec... |
| 14:20 | prunedtree | still much better than the client VM |
| 14:22 | prunedtree | Chouser : you use a 64 bit system ? |
| 14:27 | Lau_of_DK | Has anybody here got a clojure example of a successful initialization of a JTable using the object[][] object[] constructor? |
| 14:27 | Chouser | prunedtree: 32 bit |
| 14:28 | Chouser | Lau_of_DK: I saw you were poking at that. I dug out my example, and found I bailed on that constructor. ...so no, I do not. |
| 14:28 | prunedtree | c2duo ? |
| 14:28 | Chouser | prunedtree: core 2 duo, 800MHz |
| 14:28 | prunedtree | are you sure you tested the same function ? no integer hint or such |
| 14:29 | Chouser | no integer hint (which wouldn't help anyway since these are not calls to java methods) |
| 14:29 | Lau_of_DK | Chouser the all-seeing - Okay. Its a little weird, I managed to get it initialized, so it was accepted as an object[][] (the data), but when rendering it fails and throws some outofbounds errors.... |
| 14:30 | prunedtree | so how come we have different performance results ? |
| 14:30 | prunedtree | I have a 1ghz c2duo |
| 14:31 | Chouser | prunedtree: that's an excellent question, and I'm afraid I don't really know. |
| 14:31 | Chouser | Maybe there's some Java forum where they would know such things? I knowledge of Java is pretty shallow. |
| 14:32 | prunedtree | I'd say that it's speedstep messing up your measurements (giving you something that's not realtime) |
| 14:33 | prunedtree | can you try something that takes a dozen seconds to check it's true real time ? |
| 14:33 | prunedtree | and not time scaled on some virtual high frequency clock |
| 14:33 | prunedtree | fib 40 should do (if that doesn't take too long) |
| 14:34 | Chouser | (fib 37) in my VMPlayer, Windows XP, etc. just took 13 seconds, counting manually |
| 14:36 | prunedtree | other than -server, what parameters do you use ? |
| 14:37 | Chouser | no -server in my Windows install. C:\>java -cp h:\build\clojure\clojure.jar clojure.lang.Repl |
| 14:38 | Chouser | then I pasted your fib fn at the prompt, and ran (time (fib 36)) |
| 14:38 | prunedtree | "Elapsed time: 6308.444789 msecs" |
| 14:38 | prunedtree | 24157817 |
| 14:38 | Chouser | I can see one of CPU meter peg at 50% for 7 or 8 seconds. |
| 14:38 | prunedtree | for fib 37 |
| 14:39 | Chouser | oh! that's better, isn't it? |
| 14:39 | prunedtree | didn't feel like realtime |
| 14:39 | prunedtree | ah, it is |
| 14:40 | prunedtree | the VM takes a few seconds too boot, too |
| 14:40 | prunedtree | 4 sec to boot |
| 14:40 | Chouser | but still, in linux (no vmplayer) with -server, (fib 37) takes 2.8 seconds (not counting java boot) |
| 14:42 | prunedtree | Exception in thread "main" java.lang.NoClassDefFoundError: clojure/lang/Repl |
| 14:42 | prunedtree | Caused by: java.lang.ClassNotFoundException: clojure.lang.Repl |
| 14:42 | prunedtree | strange, I can't do what you did |
| 14:43 | prunedtree | ah no, wrong path |
| 14:44 | prunedtree | Chouser : and it's not a 64-bit linux ? |
| 14:44 | prunedtree | I guess you must have some hidden VM parameters, as you didn't have to add -server |
| 14:45 | prunedtree | (which gives me the client version here...) (or maybe -server is the default on linux... discrimination !) |
| 14:46 | prunedtree | I have consistent timings ... |
| 14:46 | prunedtree | user=> (time (fib 36)) |
| 14:46 | prunedtree | "Elapsed time: 3704.085855 msecs" |
| 14:46 | prunedtree | 14930352 |
| 14:57 | Chouser | On linux (32 bit) without -server I get 2836 msecs and with -server I get 2818 |
| 14:58 | Chouser | ah, but -client gives me 13403 msecs |
| 14:59 | Chouser | so it does appear to be client vs. server setting -- you got -server to work on Windows now? |
| 14:59 | prunedtree | yes |
| 14:59 | prunedtree | otherwise I get 18 sec |
| 14:59 | prunedtree | it looks like the speeddown for client is consistent |
| 14:59 | prunedtree | I wonder if it's not a timing error from windows/linux |
| 15:00 | prunedtree | (well, I do measure 4 seconds of real time myself) |
| 15:00 | prunedtree | you are sure that the numbers you get are accurate on linux ? |
| 15:01 | Chouser | I'm not including java boot time |
| 15:02 | rhickey | even with -server you may need to run it a bunch of times to get the server to optimize it |
| 15:03 | achim_p | whoa, shockingly slow on a power pc (1ghz). 40 secs for (fib 36) |
| 15:03 | dudleyf | rhickey: But is it expected for -client to run the simple fib 8-9x slower than -server? |
| 15:04 | Chouser | (fib 38) in linux with -server is definitely taking no more than 5 realtime seconds. |
| 15:04 | rhickey | this kind of benchmarking is a huge time-suck |
| 15:04 | dudleyf | No kidding ;-) |
| 15:04 | Chouser | prunedtree: at least you're beating your smalltalk numbers now |
| 15:04 | prunedtree | no I'm not :) |
| 15:05 | prunedtree | but it's closer to something acceptable |
| 15:05 | Chouser | hmph. |
| 15:05 | danlarkin | which version of fib are you all using now? |
| 15:06 | prunedtree | 4.5 sec on my system is the time for /interpreted/ smalltalk |
| 15:07 | prunedtree | <rhickey> even with -server you may need to run it a bunch of times to get the server to optimize it << actually it doesn't make any difference to me |
| 15:07 | prunedtree | OSR works well |
| 15:07 | Chouser | danlarkin: http://clojure-log.n01se.net/date/2008-10-03.html#12:44a |
| 15:08 | danlarkin | Chouser: thanks |
| 15:08 | Chouser | note that's not a good fib implementation, but it's a pretty punishing way to test function call speed. |
| 15:09 | rhickey | except all of your numbers are not bound at all by function call speed, but by arithmetic boxing! |
| 15:10 | danlarkin | Chouser: haha agreed, but I want to try it with -server and -client on my machine |
| 15:10 | rhickey | this test is dominated by boxing |
| 15:10 | prunedtree | yeah, I think so |
| 15:11 | prunedtree | I wonder if the linux VM has some different internal compiler tweaks |
| 15:11 | ozzilee | achim_p: What PPC? G4? |
| 15:13 | achim_p | ozzilee: yes, inside an aging powerbook |
| 15:14 | danlarkin | so I get about 8.1 seconds with -client, 5.3 seconds with -server, -client being the default on my Leopard macbook pro |
| 15:15 | prunedtree | I get ~5x difference between client/server. but I'd like to have Chouser's numbers ;p |
| 15:18 | prunedtree | anyway, that's decent enough. as long as you are within 10-5x of the C time I'd say it's acceptable for most stuff |
| 15:19 | danlarkin | I don't see any speed improvement by hinting n to an Integer |
| 15:19 | danlarkin | unless I'm doing it wrong, which is totally possible |
| 15:19 | danlarkin | (defn fib [#^Integer n] ... |
| 15:21 | ozzilee | ozzilee: My 700mhz G3 is still cranking away... 8 minutes so far... |
| 15:23 | prunedtree | let's try a much more interressing benchmark... |
| 15:23 | dudleyf | danlarkin: That only affects Java method calls where Clojure might otherwise need to use reflection |
| 15:23 | dudleyf | If I'm not mistaken |
| 15:23 | ozzilee | achim_p: I meant to reply to you :-) |
| 15:24 | Chouser | dudleyf: right |
| 15:25 | lisppaste8 | rhickey pasted "hinted fib" at http://paste.lisp.org/display/67873 |
| 15:25 | prunedtree | humm. how do I get an interval ? call java ? code it myself ? |
| 15:26 | rhickey | dudleyf: no, hinting can impact arithmetic too. The main problem here is that the recursive calls take and return Objects, but inside the fn we can optimize a bit, see paste |
| 15:27 | prunedtree | well, to make it interressing I tested (fib 301/10) also |
| 15:28 | prunedtree | other polymorphic systems would still win by a huge margin. hard to tell if it's the way you do polymorphism or number unboxing |
| 15:29 | prunedtree | anyways, ints are so common in code that it's likely to impact everything. hopefully the next generation of VMs will unbox stuff. it's actually trivial compared to more exotic stuff they do with locks and so on |
| 15:29 | danlarkin | hinted fib clocks in at 1.2 seconds with -server, 3.5 with -client... down from 5.3 and 8.1 respectively |
| 15:29 | rhickey | all Lisp and Smalltalk system that have tagged numbers will beat all JVM langs that box on this benchmark, until the JVM supports tagged numbers or optimizes the escape analysis across calls |
| 15:30 | achim_p | ozzilee: wow, 8 minutes :) i wonder why (un)boxing is so much more expensive on the jvm for ppc. |
| 15:31 | rhickey | danlarkin: not too shabby |
| 15:31 | ozzilee | achim_p: Oh it's still going. 15 minutes or so now. |
| 15:32 | Chouser | cljs performs poorly for this test. |
| 15:32 | abrooks | Chouser: heh. Really? </ironic> |
| 15:33 | Chouser | (fib 30) costs 4 seconds in Rhino |
| 15:38 | abrooks | Chouser: That's really impressive, actually. I assume that's the hinted fib? |
| 15:38 | achim_p | alright, enough of this for me - signore fibonnaci would likely turn around in his grave if he knew what the kids were doing with his sequence nowadays ;) |
| 15:38 | abrooks | Oh, it's also fib 30. |
| 15:40 | Chouser | no, hinting doesn't work in cljs yet. |
| 15:53 | ozzilee | achim_p: 39.31 minutes. I win. |
| 15:54 | danlarkin | ouch |
| 17:24 | lisppaste8 | prunedtree pasted "stack overflow without recursion" at http://paste.lisp.org/display/67882 |
| 17:25 | prunedtree | wrote a bytearray implementation because immutability sucks to do sieves |
| 17:25 | prunedtree | stack overflow at 10k iterations is a problem for something that should iterate over 10 million elements... |
| 18:37 | Chouser | prunedtree: http://paste.lisp.org/display/67882 is pretty interesting. |
| 19:08 | Chouser | (dorun (for [i (range 10000) j nil] nil)) --> java.lang.StackOverflowError |
| 19:24 | Chouser | It's all lazy-cat's fault. |
| 19:56 | Chouser | got it. |
| 20:01 | Chouser | prunedtree: I think this patch to boot.clj fixes the problem you found: http://clojure.googlegroups.com/attach/1a9afd4aed95c26c/for-overflow.patch |
| 20:25 | Pupeno | Hello. |
| 20:25 | Chouser | Pupeno: hi |
| 20:25 | Pupeno | How does this thing of adding a dot at the end of a name work? like JFrame. |
| 20:26 | Pupeno | I mean, what is it supposed to do? I couldn't get anything but errors. |
| 20:26 | Chouser | (Foo. x y) is the same as (new Foo x y) |
| 20:26 | Chouser | which is like "new Foo(x, y)" in Java |
| 20:26 | Pupeno | oh, ok. |
| 20:27 | Pupeno | Thanks. |
| 20:27 | Chouser | np |
| 20:35 | Pupeno | Can you ship a Clojure program in a jar? |
| 20:44 | Chouser | yep |
| 20:45 | Pupeno | Nice. Thank you. |
| 20:45 | Chouser | Many of the clojure lib functions will find .clj files in the classpath, including in .jars |
| 20:46 | danlarkin | so is the (Foo. x y) a reader special-case? It has to be, right? Because Foo. is not in the namespace so it can't be called like a normal function or macro |
| 20:48 | rhickey | danlarkin: It's actually special macroexpansion: (macroexpand '(Foo. x y)) -> (new Foo x y) |
| 20:49 | Chouser | danlarkin: it's not in the reader, technically, since "Foo." is a valid symbol and is read that way. The docs say Foo. turns into "new Foo" at "macro expansion time" |
| 20:49 | achim_p | hi! it's probably really easy, but it won't cross my mind right now: how to obtain a lazy seq of ((1) (1 2) (1 2 3) ...) from (1 2 3 4) in one pass? i'd like to produce a lazy seq of "growing" reads, given a reader ("h" "he" "hey") |
| 20:51 | danlarkin | rhickey: Okay, so macroexpand-1 knows how to deal with the (Foo. x y) form, but how does clojure know to try to macroexpand it? For instance, (Foo x y) won't be passed to macroexpand.. or will it? |
| 20:53 | Chouser | achim_p: (map (fn [a b] (take a s)) (iterate inc 1) s) |
| 20:54 | Chouser | That's one way -- I'm sure there's something better. |
| 20:54 | rhickey | danlarkin: in looking to see if a form is a macro form, the compiler looks for leading or trailing dots, which are reserved for this purpose, then knows it gets special expansion, otherwise looks to see if was a defmacro var etc |
| 20:55 | Chouser | rhickey: you saw the stack overflow in "for"/ |
| 20:55 | Chouser | ? |
| 20:56 | achim_p | Chouser: thanks! that's quadratic-time though, but it should do for now |
| 20:57 | rhickey | Chouser: yes, thanks for chasing that. Your fix works ok for that case, but I think there may be a deeper problem |
| 20:57 | Chouser | rhickey: ok. |
| 20:58 | danlarkin | rhickey: excellent, thank you for the explaination |
| 20:58 | Chouser | achim_p: what? it's a lazy seq of lazy seqs -- each level of seq produces the next item in constant time |
| 20:59 | danlarkin | sorry if I'm asking a bunch of arcane annoying questions of y'all, but it helps me learn a lot about the language |
| 21:00 | Chouser | danlarkin: tell you what, nothing helps learn arcane and annoying details of a language like writing a new back end -- know anything about JavaScript? |
| 21:00 | Chouser | :-) |
| 21:00 | danlarkin | Chouser: oh jeez, more than I'd like to |
| 21:01 | Chouser | hm... looked at clojure-contrib/clojurescript at all? |
| 21:01 | achim_p | Chouser: of course you're right, i misread. i should get some sleep :) thanks again! |
| 21:01 | Chouser | achim_p: np |
| 21:01 | danlarkin | Chouser: I'm scared of it! |
| 21:02 | Chouser | yeah, me too :-( well, just so long as you know it's there... |
| 21:03 | danlarkin | TBH I haven't looked at it. Saw it was there but moved on |
| 21:03 | danlarkin | although now I'm looking |
| 21:04 | rhickey | achim_p: no, you are right, the takes, when consumed grow with N |
| 21:04 | achim_p | Chouser: erm, but take takes longer for growing a, doesn't it? |
| 21:05 | achim_p | ah, ok |
| 21:05 | lisppaste8 | rhickey pasted "taking" at http://paste.lisp.org/display/67889 |
| 21:05 | rhickey | try that |
| 21:05 | Chouser | ah, I see. |
| 21:07 | Chouser | if you touch each item produced, though, aren't they the same? |
| 21:08 | Chouser | "taking" is a win if you're doing something sparse on each vector, like using nth. |
| 21:08 | rhickey | no, because each take starts at the beginning, while each step of mine just adds one item to the vector |
| 21:09 | achim_p | rhickey: perfect, thank you! |
| 22:18 | danlarkin | ((fn [a b c d] b) 1 2 3 4) => 2 |
| 22:18 | danlarkin | ((fn [a b c d :as lst] b) 1 2 3 4) => java.lang.Exception: Unsupported binding form: :as (NO_SOURCE_FILE:57) |
| 22:18 | danlarkin | :-( |
| 22:19 | danlarkin | ohhh |
| 22:19 | danlarkin | wait! |
| 22:20 | danlarkin | no.. still don't get it |
| 22:22 | danlarkin | oh.. must I do it like this, ((fn [[a b c d :as lst]] b) [1 2 3 4])? |
| 22:23 | rhickey | danlarkin: yes |
| 22:25 | danlarkin | I see -- so it's not quite like "def fun(*args)" if you're familiar with Python. I was assuming it worked that way, but come to think of it I shouldn't have, based on the let example of destructuring |
| 22:26 | lisppaste8 | baetis-fly pasted "Faster nsieve vs. prunedtree" at http://paste.lisp.org/display/67899 |
| 22:43 | lisppaste8 | danlarkin pasted "metadata" at http://paste.lisp.org/display/67900 |
| 22:45 | danlarkin | so my question about that is why does one way of defining a function get an :arglists key in its metadata, but the other way doesn't |
| 22:47 | Chouser | danlarkin: the :arglists metadata is added by the defn macro itself |
| 22:47 | Chouser | boot.clj, line 207 |
| 22:47 | danlarkin | d'oh! |
| 22:47 | danlarkin | good reason |