2008-05-30
| 07:02 | cgrand | ozzilee: http://code.google.com/p/clj-stuff/wiki/TemplatingExamples#Javascript_HTML_templating_examples -- I'm not quite happy with the current version but it works for my actual needs |
| 09:19 | ozzilee | cgrand: I'm going to have to download that and take a look, looks quite cool. |
| 09:20 | ozzilee | I played with a templating system in Scheme that has some ideas I haven't seen elsewhere, you might be interested. |
| 09:20 | ozzilee | Look under "Templates": http://ozzilee.com/mettle/documentation/ |
| 09:21 | cgrand | ozzilee: thanks, I'll look at it! |
| 09:22 | ozzilee | I also wrote some url-dispatching stuff in Clojure that's something like the Scheme code, but I don't have anything up anywhere. |
| 09:23 | ozzilee | Basically it lets you do (defpage ["foo" bar] (str "bar: " bar)) |
| 09:23 | ozzilee | Which would print plaintext "bar: baz" at /foo/baz |
| 09:26 | cgrand | your templating system reminds me (because of the querying capabilities) of Genshi |
| 09:30 | ozzilee | I've never looked into Genshi, I'll take a look. Thanks! |
| 09:30 | cgrand | and I took the same road concerning url dispatch, see: |
| 09:30 | lisppaste8 | cgrand pasted "defresource" at http://paste.lisp.org/display/61461 |
| 09:31 | lisppaste8 | blackdog pasted "help with macro pls?" at http://paste.lisp.org/display/61462 |
| 09:31 | blackdog | can't get my first macro to work :/ |
| 09:32 | ozzilee | blackdog: Does the code the macro expands to work by itself? |
| 09:32 | blackdog | :/ didnt try that |
| 09:33 | ozzilee | That'd be your first stop. |
| 09:34 | blackdog | k |
| 09:34 | ozzilee | cgrand: What does :filters do? |
| 09:34 | ozzilee | Is that like middleware? |
| 09:35 | blackdog | same error, and i don't know why the string is expanded unquoted |
| 09:35 | lisppaste8 | cgrand annotated #61462 with "actionPerformed" at http://paste.lisp.org/display/61462#1 |
| 09:37 | rhickey | blackdog: does it work if you say: ~'actionPerformed |
| 09:38 | cgrand | similar to an around advice in AOP, here it allows me to set up the connection to the db |
| 09:38 | ozzilee | cgrand: Ah, ok. |
| 09:39 | ozzilee | cgrand: Do you use the jdk6 xmlwriter stuff? |
| 09:40 | blackdog | rhickey, thanks rich that works |
| 09:40 | rhickey | blackdog: great - I'll look into making that not necessary |
| 09:40 | blackdog | ok, so what i had should have workedt then? |
| 09:40 | blackdog | i'm new to macros |
| 09:41 | rhickey | it has to do with how the proxy finds the matching names |
| 09:42 | cgrand | ozzilee: I had bad experiences with xmlwriter/reader for XHTML gen -- not enough control on the output (eg you have to hack around it to get to write a preamble which will trigger standard mode in most browsers) |
| 09:43 | ozzilee | cgrand: That's fine by me, I just don't have JDK6 :-) |
| 09:56 | Chouser | cgrand: you're referring to Java's own xml read/writer, or the code in clojure-contrib? |
| 09:57 | cgrand | chouser: java's Stax |
| 10:10 | ozzilee | Chart of Clojure's performance on a naive fibonacci function over last 70 or so revisions: http://groups.google.com/group/clojure/web/Fib.pdf |
| 10:12 | ozzilee | Single pass, so accuracy is probably crap, but it's a proof-of-concept. |
| 10:14 | rsynnott | not necessarily the best benchmark, as it's not a terribly optimisable problem |
| 10:15 | ozzilee | rsynnott: Again, proof-of-concept :-) The goal is an automated test that will alert us when a revision does something bad to performance. |
| 10:16 | ozzilee | Not so much for a benchmark. I intend to have a number of different performance tests. |
| 10:16 | ozzilee | Contributions weclome... |
| 10:18 | rsynnott | sbcl does something of this sort; you could steal their one :) |
| 10:18 | cgrand | chouser: I see xml-stream-writer.clj uses StAX. I'm trying to gather memories of what bit me: I think that is what related to round tripping the DTD. |
| 10:18 | ozzilee | rsynnott: I'll look into it, thanks. |
| 10:21 | cgrand | ozzilee: interesting! Do you plan to include the benchmarks of the languages shootout? |
| 10:23 | Chouser | cgrand: |
| 10:23 | Chouser | cgrand: ok. I don't know much about xml-stream-writer.clj |
| 10:24 | Chouser | But I've been kicking around some ideas for xml representation, and thought it would be good to build on Java's libs |
| 10:24 | Chouser | so if that's not true, I wanted to take note. |
| 10:33 | cgrand | chouser: ok. To back my claims: http://stax.codehaus.org/Extensions#Extensions-Rationale |
| 10:40 | rhickey | ozzilee: what's the time for this on your benchmark machine? : |
| 10:40 | rhickey | (defn fib [n] |
| 10:40 | rhickey | (if (int/< n 2) n (int/+ (fib (int/- n 1)) (fib (int/- n 2))))) |
| 10:41 | rhickey | make sure you pass -server to Java for benchmarks of Clojure |
| 10:49 | ozzilee | 1020.345 msecs |
| 10:49 | ozzilee | for 35 |
| 10:50 | rhickey | your chart was for 30, what's the apples-to-apples? |
| 10:50 | ozzilee | 30 is 490.813 |
| 10:50 | ozzilee | Sorry, misremembered what the chart was for. |
| 10:50 | rhickey | if you run it a couple of times? |
| 10:50 | rhickey | hotspot needs to warm up |
| 10:51 | rhickey | on my machine the type-hinted version is 4x faster |
| 10:52 | rhickey | 51ms |
| 10:52 | drewr | 229, 236, 233 for me. |
| 10:53 | rhickey | drewr: vs what for the unhinted version (just drop the int/s) |
| 10:53 | ozzilee | Yeesh, yeah it gets down to 88. |
| 10:53 | ozzilee | Makes a big difference if you (defn fib ...) rather than ((fn fib ...) 30) |
| 10:54 | rhickey | yes, that's a must |
| 10:54 | jteo | bigints slow things down eh. |
| 10:55 | drewr | rhickey: 620 unhinted. |
| 10:55 | rhickey | polymorphic dispatch slows things down, and boxing |
| 10:55 | rhickey | normally you shouldn't care, but having the hinted versions gives you tuning options when it matters |
| 10:56 | rhickey | like on benchmarks :) |
| 10:59 | ozzilee | Hmm, actually it looks like I lied. |
| 10:59 | ozzilee | (defn fib [n]), then calling fib inside is the slowest. |
| 10:59 | ozzilee | (defn fib this [n]), then calling this inside is the same as (fn this [n]) |
| 11:00 | ozzilee | Those both get down to 70, (defn fib [n]) stays at 382. |
| 11:30 | drewr | java.text.ParseException: Unparseable date: "2008-04-09 17:00:07.403" |
| 11:30 | drewr | Are you kidding me? DateFormat doesn't understand a SQL Server timestamp? |
| 11:30 | drewr | No wonder people use .NET. |
| 11:32 | drewr | I'd love to write Clojure versions of these libraries and remove teh suck. |
| 11:33 | rhickey | http://www.swa.hpi.uni-potsdam.de/dls/dls08/ |
| 11:34 | drewr | Nice! |
| 11:35 | rsynnott | I'm surprised SQL server doesn't just use standard SQL dates... |
| 11:35 | drewr | rsynnott: Is that not standard? That's the same as pgsql and mysql too. |
| 11:36 | drewr | rhickey: Impressive program committee. |
| 11:36 | rhickey | yeah |
| 11:37 | rhickey | It's a very nice invite |
| 11:46 | rsynnott | mysql's one looks like '2008-05-30 17:15:04' |
| 11:48 | drewr | rsynnott: I wouldn't consider fractional seconds non-standard. Besides, there are no standards in RDBMSes. :-) |
| 11:48 | drewr | java.text.ParseException: Unparseable date: "2008-04-09 17:00:07" |
| 11:49 | drewr | java.text.ParseException: Unparseable date: "2008-04-09" |
| 11:49 | drewr | What alternate universe do they live in?? |
| 11:53 | rhickey | drewr: are you using SimpleDateFormat? |
| 11:54 | drewr | rhickey: java.text.SimpleDateFormat@7945516e |
| 11:54 | rhickey | It has a ctor that takes a pattern |
| 11:55 | drewr | OK, I used the getDateTimeInstance factory. |
| 11:55 | drewr | But without a style. |
| 11:57 | drewr | Ah, I was using DateFormat.getDateTimeInstance() which apparently created my a SimpleDateFormat with no pattern. |
| 12:12 | rhickey | http://elw.bknr.net/2008/html/home.html |
| 14:56 | jteo | dumb qns: is there an equivalent to 'progn', or is there another way of doing things? |
| 14:56 | Chouser | (do ..) ? |
| 14:58 | jteo | ah. must have missed that in the documentation. |
| 14:58 | Chouser | np |
| 16:33 | Zilatica | anyone active in this page? |
| 16:34 | rhickey | yes |
| 16:34 | jgracin | sure |
| 16:34 | Zilatica | I'm taking a gander at clojure |
| 16:34 | Zilatica | and I just downloaded the ants.clj |
| 16:34 | Zilatica | trying to run it from the java command line |
| 16:34 | Zilatica | java -cp clojure.jar clojure.lang.Script ants.clj |
| 16:35 | Zilatica | is what I run |
| 16:35 | Zilatica | and for a split second, I see what looks like a pane pop up |
| 16:35 | Zilatica | and then immediately die |
| 16:35 | Zilatica | no logged exceptions to the prompt (that I see) |
| 16:36 | Chouser | try Repl instead of Script? |
| 16:36 | Zilatica | alright, will do |
| 16:36 | Zilatica | thanks! |
| 16:36 | rhickey | yes, and then run the commands in the comment section at the bottom |
| 16:42 | Zilatica | when running in Windows, what is the proper way to load a file from a fully qualified path? I've tried D:\research\ants.clj, which reported invalid token for \r, and I've tried D:/research/ants.clj, which reported invalid token, and I've tried just using a relative path from my command line call to invoke the reple (load-file "ants.clj") |
| 16:43 | jgracin | double prefix \\r |
| 16:43 | jgracin | ? |
| 16:43 | jgracin | guessing |
| 16:43 | Zilatica | just gave me an invalid token : D: |
| 16:43 | Zilatica | oddly enough |
| 16:43 | Chouser | file:// ? |
| 16:43 | Chouser | also guessing. |
| 16:43 | Chouser | what is this "Windows" of which you speak? ;-) |
| 16:43 | Zilatica | lol |
| 16:44 | rhickey | are you putting this inside " "? |
| 16:44 | Zilatica | one of the main reasons I got tired of dealing with lisp was I have to use windows at work and couldn't find a good way to involve it in the workplace |
| 16:44 | Zilatica | checking out clojure |
| 16:44 | Zilatica | cause I can get the repl to work on windows |
| 16:44 | Zilatica | yes |
| 16:45 | rhickey | I'd expect "D:\\research\\ants.clj" to work |
| 16:45 | rhickey | also guessing |
| 16:45 | Zilatica | the full things I've tried: (load-file "D:/Development/Research/Clojure/ants.clj"), (load-file "D:\Development\Research\Clojure\ants.clj"), and (load-file "D:\\Development\\Research\\Clojure\\ants.clj") |
| 16:45 | Zilatica | sadly, none of those worked |
| 16:45 | Chouser | do you need the drive letter? If you're already on D: you could try "\\Development..." |
| 16:46 | jgracin | Zilatica: what does it report on using the "D:\\Devel..." variant? |
| 16:47 | Zilatica | user=> (load-file "D:\\Development\\Research\\Clojure\\ants.clj") |
| 16:47 | Zilatica | ")\n(load-file " |
| 16:47 | Zilatica | user=> java.lang.Exception: Invalid token: D: |
| 16:47 | Zilatica | java.lang.Exception: ReaderError:(5,1) Invalid token: D: |
| 16:47 | Zilatica | at clojure.lang.LispReader.read(LispReader.java:158) |
| 16:47 | Zilatica | at clojure.lang.Repl.main(Repl.java:68) |
| 16:47 | Zilatica | Caused by: java.lang.Exception: Invalid token: D: |
| 16:47 | Zilatica | at clojure.lang.LispReader.interpretToken(LispReader.java:224) |
| 16:47 | Zilatica | at clojure.lang.LispReader.read(LispReader.java:150) |
| 16:47 | Zilatica | ... 1 more |
| 16:47 | Zilatica | any ideas? |
| 16:48 | Zilatica | everyone hate windows? ;-) |
| 16:48 | rhickey | you may have cruft left from \\r, if you could, try restarting the repl and using the "D:\\research\\ants.clj" variant |
| 16:48 | Zilatica | as a side note, what is the command to quit the repl? |
| 16:48 | Zilatica | yes yes yes, total noob. I know. |
| 16:49 | Zilatica | tried quit, (quit), (exit), exit, sayoonara, (sayoonara) |
| 16:49 | Zilatica | and a handful of others |
| 16:49 | jgracin | try pressing CTRL-D |
| 16:49 | Zilatica | just get a ^D |
| 16:49 | Zilatica | hitting enter gets me nothing, repl still expecting input |
| 16:49 | rhickey | I think most of use do some variant of ^C on unix variants - there's no exit command, send whatever was EOF for DOS |
| 16:50 | rhickey | ^Z ? |
| 16:50 | Zilatica | ctrl z works for the repl |
| 16:50 | Zilatica | until you run it in jline |
| 16:50 | Zilatica | then no bueno |
| 16:51 | Zilatica | rhickey, you were right, the D:\\ variant worked after I quit the repl. |
| 16:52 | jgracin | (. System (exit 0)) should work. |
| 16:52 | rhickey | (. System exit 0) |
| 16:52 | Zilatica | The pane that showed up looks a bit funny though |
| 16:52 | Zilatica | just a pane with a blue square in the pane |
| 16:52 | Zilatica | not filled |
| 16:52 | Zilatica | looks like a width of 1 or 2 |
| 16:52 | Zilatica | nothing really going in it |
| 16:52 | Zilatica | oh wait, hah, more commands to run |
| 16:52 | rhickey | that's right |
| 16:52 | Zilatica | sry, I'll read on! |
| 16:53 | rhickey | np |
| 16:55 | Chouser | hm, I can't even get "java" to work on Windows, so you're way ahead of me, Zilatica. |
| 16:56 | Zilatica | you're my new best friend. |
| 16:56 | Zilatica | :-) |
| 16:56 | Zilatica | nah, I just spent so much time trying to get lisp running on my mac that I gave up |
| 16:56 | Zilatica | couldn't get the emacs repl to work after 10 hours of investigation |
| 16:57 | Zilatica | and add to that the fact that work requires windows |
| 16:57 | Zilatica | just wasn't useful |
| 16:57 | Zilatica | now I have ants filling a pane with pheremones |
| 16:57 | Zilatica | very exciting |
| 16:57 | Zilatica | and all under 2 hours of investigation. |
| 16:57 | Chouser | :-) |
| 16:58 | Chouser | Do I need to download my own JVM? Windows XP doesn't come with one? |
| 16:58 | Zilatica | yep |
| 16:58 | Zilatica | you checked out Eclipse.org? |
| 16:59 | Zilatica | that's where the action is for Java |
| 17:01 | rhickey | more perf boosts! |
| 17:01 | rhickey | static public float[] vmul(float[] x, float[] ys){ |
| 17:01 | rhickey | final float[] xs = x.clone(); |
| 17:01 | rhickey | for(int i=0;i<xs.length;i++) |
| 17:01 | rhickey | xs[i] *= ys[i]; |
| 17:01 | rhickey | return xs; |
| 17:01 | rhickey | } |
| 17:01 | rhickey | That's the Java for float/a*a |
| 17:01 | rhickey | (defn amul2 [v1 v2] |
| 17:01 | rhickey | (let [ret (float/aclone v1)] |
| 17:02 | rhickey | (doidx i (float/alength v1) |
| 17:02 | rhickey | (float/aset! ret (.get i) |
| 17:02 | rhickey | (float/* (float/aget ret (.get i)) (float/aget v2 (.get i))))) |
| 17:02 | rhickey | ret)) |
| 17:02 | rhickey | That Clojure runs at exactly the same speed |
| 17:03 | rhickey | still working on making it easier, but the net result is no need to go to Java for low-level primitive array stuff |
| 17:03 | Zilatica | congrats? |
| 17:03 | Chouser | doidx is new? |
| 17:04 | rhickey | that's part of what I;m working on - it looks like I might need something like CL's symbol-macrolet |
| 17:04 | rhickey | to get rid of the (.get i) |
| 17:05 | Chouser | symbol-macrolet provides a simple alternative to a code-walker or something? |
| 17:05 | rhickey | lets you bind a symbol to a replacement form |
| 17:06 | rhickey | but yes, trying to do the same thing with a code walker is perilous |
| 17:07 | rhickey | HotSpot is amazing - it turns all those function calls into the same code that uses primitives directly |
| 17:07 | Chouser | oh, so symbol-macrolet isn't itself just a code-walking macro? Where would such functionality be located -- the reader? |
| 17:08 | rhickey | I made several enhancements today to eliminate extra boxing to/from host calls |
| 17:08 | Chouser | ah, cool. |
| 17:08 | rhickey | Compiler, it's another form, like let |
| 17:08 | Chouser | oh, ok. |
| 17:08 | rhickey | not fun |
| 17:09 | rhickey | it interacts (shadows/is shadowed by) with let |
| 17:12 | Chouser | yikes |
| 17:13 | rhickey | the other alternative is typed lets, but a much bigger can of worms |
| 17:14 | rhickey | since Clojure still won't have primitive types or operations |
| 17:14 | rhickey | and I don't want it to turn into Java |
| 17:18 | rhickey | in a namespace, and with symbol-macrolet, it could look like: |
| 17:18 | rhickey | (defn a*a [v1 v2] |
| 17:18 | rhickey | (let [ret (aclone v1)] |
| 17:18 | rhickey | (doidx i (alength v1) |
| 17:18 | rhickey | (aset! ret i (* (aget ret i) (aget v2 i)))) |
| 17:18 | rhickey | ret)) |
| 17:20 | Chouser | it would be trivial for i to be a fn, right? (aget ret (i)) isn't too bad |
| 17:21 | rhickey | to get these optimizations, it has to be a macro, not a fn |
| 17:22 | Chouser | and couldn't aget expect a fn instead of whatever it wants now, such that you'd be down to (aget ret i) without that sacry compiler work? |
| 17:22 | Chouser | oh, ok. |
| 17:23 | rhickey | The ultimate goal: |
| 17:23 | rhickey | (defn a*a [a1 a2] |
| 17:23 | rhickey | (amap [i ret a1 a2] |
| 17:23 | rhickey | (* (aget ret i) (aget v2 i)))) |
| 17:26 | rhickey | amap would be a macro that takes care of cloning and stepping |
| 17:26 | Chouser | and then you could rewrite float/a*a and all his friends in Clojure instead of Java? |
| 17:27 | rhickey | yup, and so could you or anyone write their own similar things, with performance the same as Java |
| 17:27 | Chouser | right |
| 17:43 | Chouser | so hotspot doesn't inline functions well enough to rely on that instead of macros? |
| 17:44 | rhickey | It does, that's how this is all getting so fast - BUT, Clojure fns all take and return Object, and it doesn't eliminate the boxing |
| 17:49 | Chouser | does that mean (.get i) isn't a function call? |
| 17:50 | rhickey | It's a Java call, to a method on a type known to Clojure - those calls are all already as fast as Java and strongly typed |
| 17:50 | rhickey | Clojure calls to Java methods are the same bytecode as Java calls to Java methods |
| 17:51 | rhickey | So when I make a call to a Java function that does primitive math, Hotspot inlines it |
| 17:51 | Chouser | clojure calls to clojure functions don't require a method lookup, but do get all args boxed? |
| 17:52 | rhickey | yes, but they travel boxed all the time in Clojure, so no box/unbox except to go to the other side |
| 17:52 | Chouser | hm, ok. |
| 17:53 | rhickey | A clojure call is a call to a Java method that takes and returns Objects |
| 17:53 | rhickey | But you can't define a fn that takes or returns an int, say |
| 17:54 | Chouser | thus ... symbol-macrolet. |
| 17:54 | rhickey | the last mile... |
| 17:55 | rhickey | So, that's why there's Numbers.F.add etc |
| 17:56 | Chouser | would you be unhappy with special syntax for splicing a list, to simplify the interaction with let? |
| 17:56 | rhickey | ? |
| 17:56 | Chouser | I'm probably confusing the stages of evaluation. |
| 17:57 | Chouser | (let [i '(.get 5)] (aget ret *i)) |
| 17:59 | rhickey | yes, stages of evaluation is key |
| 18:00 | Chouser | bye |
| 18:09 | Zilatica | is there a way to get closure to compile a clj into a jar? |
| 18:09 | Zilatica | I know it runs in a VM |
| 18:10 | Zilatica | but how about compiling clj into jars, does that work? |
| 18:12 | Chouser | you can include a .clj in a jar and load and run it from there |
| 18:13 | Chouser | the clojure.jar itself includes several .clj files whose code is available at runtime. |
| 18:14 | Zilatica | ok, but if I inlcuded clojure.jar in an existing java project, could I run something in a Java class against a function defined in a clj? |
| 18:15 | Chouser | yes, though it requires a bit of setup, and then the call to the clojure function isn't just a "regular" Java call. |
| 18:15 | Zilatica | so cljs are interpreted, not compiled then? |
| 18:15 | Chouser | there are actually several options here, depending on what exactly you're trying to do. |
| 18:15 | Chouser | cljs are compiled at runtime. Or something. |
| 18:16 | Zilatica | that "Or something." scares me. ;-) |
| 18:16 | Zilatica | basically, I'm just wanting to find out its capabilities |
| 18:16 | Chouser | that's just my ignorance. rhickey knows exactly what it does. |
| 18:18 | ericthorsen | if you define a user.clj in your application, the 1st call to a clojure RT function will look for that file and execute it |
| 18:18 | ericthorsen | I use this for boot-strapping enclojure |
| 18:18 | ericthorsen | This is built in to clojure |
| 18:18 | Chouser | ericthorsen: is that in the relased version? |
| 18:19 | ericthorsen | not sure...it is definitely up in svn and has been for a while now |
| 18:19 | Chouser | svn!?! I need to get that. |
| 18:19 | ericthorsen | it's very handy |
| 18:20 | Chouser | I'm trying to patch encojure to control the repl a bit differently, so that (hopefully) jVi will work with it. But I'm in over my head. |
| 18:20 | Zilatica | Chouser, what OS you running? |
| 18:20 | Chouser | Zilatica: there are several options. You can define clojure functions in a .clj and then call them by name from Java using a clojure library call. |
| 18:21 | Chouser | Zilatica: Linux |
| 18:21 | ericthorsen | chouser: can you send me some details as to what you are up against there? We are doing quite a bit of work on enclojure and I'd like to see what happening there |
| 18:21 | Chouser | ericthorsen: absolutely! enclojure google group? |
| 18:22 | Zilatica | Chouser: I think I'm going to have to continue my investigation tonight, possibly tomorrow. About to head out of the office and into the wild. ;-) |
| 18:22 | Zilatica | thanks for the help! |
| 18:22 | Zilatica | and insight |
| 18:28 | ericthorsen | chouser: yes |