#clojure log - Sep 24 2008

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

0:48 arohner: can you create a macro that takes a variable number of arguments?

0:48 I'm trying to use the same syntax as defn, but it's not quite working out

0:49 lisppaste8: arohner pasted "macro" at http://paste.lisp.org/display/67353

1:07 arohner: nm, got it working

10:47 Chouser: anyone want to help me churn out another few hundred lines of tedious JavaScript?

10:47 tomhickey: Chouser: how tedious?

10:48 Chouser: I'm walking through clojure/lang/*.java and translating to JS.

10:50 Not all of it will have to be done: nothing from Compiler.java, for example.

10:50 tomhickey: Chouser: i would need to take some time to review what you've done so far, but i'm interested in getting involved with the clojurescript work

10:50 Chouser: clj.js is the file I'm populating now. I think nearly everything else is done.

10:51 blackdog: is that up to date on contrib Chouser ?

10:51 Chouser: I already did the fun part, writing Clojure code that translates ClojureScript to JavaScript.

10:52 blackdog: yep, close enough. I'm working on PersistentHashMap now, and none of that is checked in.

10:53 blackdog: i'll have a look too, it would be nice for me to be able to do all my stuff in clojure, basically servlets right now, but adding a clojure client would be cool

10:54 Chouser: I'm not sure how big this "runtime" piece will be in the end -- that is, how much JS you'll have to load into your page for ClojureScript to work.

10:55 I also don't know how fast we may be able to make it.

10:55 either of those could make using it a "deal breaker" in a lot of cases, I'm afraid. We'll just have to see how it goes.

10:57 blackdog, tomhickey: thanks for even considering helping. :-)

10:58 I'm also completely open to critique of my approach. Anything you can think of to make the JS smaller, faster, or easier to write would be great.

10:59 For now I'm mainly working on getting something working correctly, and trying to mimic the layout of the .java closely enough that patches there can be pretty easily ported over to the Js.

10:59 blackdog: i think an important thing if possible is how well the integration with standard js libs is, well like jquery for example

11:00 not just doing a clojure port, but making sure those popular frameworks can be dealt with

11:00 dojo, ext etc

11:00 and also debugging, but i guess that is really tricky

11:00 Chouser: one of the benefits of JS over Java is that it's already dynamic. This allows more seamless integration between the two.

11:01 For example, if you make a cljs function named foo in a namespace my.ns, you can call it from JavaScript just by saying: my.ns.foo( a, b, c )

11:02 interop the other way looks just like in clojure: (.getElementsByTagName document "script")

11:02 blackdog: ok, and calling into a js namespace is ?

11:04 ok so call into jquery would be (.css JQuery "div" "bakground-color" "#0") for example

11:05 so the top level global is the object

11:05 Chouser: hm, good question. We may need a bit more tweaking there -- I think we'd want it to be (JQuery/css ...) and I don't think that works right now.

11:06 blackdog: i'm not sure if that's a static or not

11:06 i think in practive JQuery("#id") actually adds to the object itself

11:07 Chouser: It looks like your example works as-is. We should have to ability to make other forms work as needed.

11:07 blackdog: but the good thing is it's all so dynamic it can be dealt with

11:08 Chouser: Right, and rhickey supports this effort, so if we need to get patches into Clojure, that's definitely an option.

11:09 blackdog: i have to say i think this is a very important effort, i was drawn to the haxe programmign language originally because it supports multiple "platform" options

11:09 js is one of those

11:09 but it's server side story is weak

11:09 this is coming from the other direction

11:09 Chouser: yep, I found exactly the same thing with haxe.

11:10 It would be interesting to add a Flash target to clojure as well.

11:11 blackdog: if you used haxe, i tried to implement a jquery lib on top of it, hxServlet

11:11 oops wrong lib, hxScriptlet

11:12 so i can see the benefits of targetting js

11:12 esp with these massive speed increases

11:12 baetis-fly: hi folks. new to closure here, hope this isn't too silly: is there something similar to common lisps subst that i can do on a seq or should i just write my own. and if i find myself writing my own does that mean i'm doing something fundamentally flawed :)

11:13 subst in common lisp replaces the nth value with something else.

11:13 Chouser: baetis-fly: clojure vectors support that directly.

11:13 baetis-fly: do you specifically want something that works on any kind of seq?

11:14 blackdog: yeah, the JS speed increases we're seeing make something like this less ... ridiculous. :-)

11:14 baetis-fly: Chouser: well, i was kind of under the impression that i should try to make everything work ok seq, but i guess using a vector would solve all my problems.

11:14 blackdog: :) did you see squirrelfish are posting 2 * v8 now too

11:14 it's already in their trunnk apparently

11:14 amazing

11:15 baetis-fly: Chouser: i'll just try to get my function to work on a vector as a starting point and maybe revisit it with seq later. Many thanks.

11:17 Chouser: blackdog: no, I hadn't seen that. Well, I don't care whether squirrelfish, V8, or tracemonkey wins, as long as they keep egging each other on.

11:18 blackdog: yep all to the common good

11:19 Chouser: baetis-fly: PersistentVector's internal design is specifically made to make setting a particular index fast. You could write something that works on any given lazy seq, but there's no way it could be as efficient.

11:19 blackdog: http://webkit.org/blog/214/introducing-squirrelfish-extreme/

11:21 Chouser: I hope writing the persistent collections in JS is the right choice. I made a brief attempt at writing them in Clojure, but it didn't look like it was going to work very well.

11:22 But if that could be made to work, cranking out a new target (Flash, C#, Java source code, etc.) would be smaller task.

11:22 blackdog: well it fits more clojure's model right now, which may help the port

11:23 Chouser: hm, scratch Java source from that list -- Java's already got the collections. ;-)

11:23 blackdog: like haxe has a common set of haxe libs which are #if according to platform

11:23 and makes a port easier

11:26 probably the base ds need to be native for performance though, maybe get better optimisation

11:27 it was interesting that your closure test was a lot slower than the prototype test

11:27 Chouser: yes, I was surprised at how different.

11:27 blackdog: and it seems that webkit is using the same optimisation technique as v8 too, creating background classes

11:28 Chouser: Now that I'm further into the project, I'm much less worried about the lack of protection.

11:29 People just aren't going to use this code from JS -- they'll use cljs, and that won't expose the dangerous parts in any natural way

11:30 baetis-fly: http://paste.lisp.org/display/67372

11:31 is that remotely correct for a shuffle in clojure? I realize it doesn't return the vector (getting there :)

11:32 Chouser: baetis-fly: (doc rand-int)

11:34 I think there have been discussions of other shuffle algorithms on the google group, but for this algorithm your implementation's not bad I think.

11:35 baetis-fly: yeah, it was just an excercise. i don't actually need to shuffle anything.

11:35 lisppaste8: ozzilee pasted "Java Shuffle" at http://paste.lisp.org/display/67373

11:35 ozzilee: There's another way :-)

11:37 baetis-fly: ozzilee: bah, that's cheating ;)

11:37 blackdog: ozzilee, that was my approach too :)

11:38 * ozzilee likes cheating

11:38 Chouser: baetis-fly: you might use (doseq n (range (count v)) ...) instead of loop/recur

11:39 hm, scratch that -- you'd have to use reduce or something to pass along your incrementally modified vector.

11:39 baetis-fly: the java version is faster :(

11:39 as in ozzilee's version.

11:40 Chouser: baetis-fly: http://groups.google.com/group/clojure/browse_thread/thread/180842eb58c58370

11:41 baetis-fly: Chouser: oh great. thanks for that. Note to self: search the google group.

11:56 Chouser: rhickey: good morning!

12:02 rhickey: hey - broadcasting live from the JVM languages summit!

12:02 blackdog: oh nice

12:02 where?

12:04 rhickey: Sun Santa Clara

12:04 blackdog: nah, the live feed :)

12:04 don't see it

12:04 on the summit page

12:04 rhickey: this is it

12:05 blackdog: you!

12:05 ok

12:05 gotcha

12:11 fyuryu: it seems the summit will be recorded by InfoQ

13:09 Chouser: clj.js is already up past 1200 lines, and it's got a ways to go. :-/

13:12 shoover: Chouser: Yeah, that may be a bummer, but keep your eye on the prize... once it's done you're writing Clojure!

13:13 Chouser: heh, yeah.

13:13 Hopefully this will all compress down to some sane size.

13:25 baetis-fly: ok, another questions. I can call (seq (myfunc (range 10)) just fine, but if i make my func call (seq result) i get a class cast exception on Range. What's the difference?

13:26 where my func converts it's argument to a vector at the start, but wants to return it as a seq.

13:26 i can paste if it's not clear.

13:27 Chouser: baetis-fly: I think you'll have to paste. Sounds like it should work.

13:29 baetis-fly: http://paste.lisp.org/display/67381

13:31 same problem if i (seq (loop

13:35 fyuryu: baetis-fly: i think you're hiding seq

13:35 your parameter is named seq

13:35 baetis-fly: ug, of course.

13:36 fyuryu: that was it. many thanks.

13:36 fyuryu: baetis-fly: np

13:38 Chouser: fyuryu: good catch. I was stumped.

13:40 achim_p_: hey

13:40 Chouser: i just discovered your zip-filter.xml lib. very nice!

13:40 i was just about to get started on something similar when i found it. saved me a lot of time, thank you!

13:41 (half-finished rewrites of stuff i didn't know already existed - i'm rather good at these ;)

13:45 Chouser: achim_p_: glad you like it.

13:45 as far as I know, it's not gotten a whole lot of abuse yet, so I'd be interested to know how it works out for you.

14:01 achim_p_: Chouser: doing very basic stuff (for now): extracting dependency information from maven metadata (e.g. getting every dependency with runtime scope from a file like http://repo1.maven.org/maven2/maven/maven/1.1/maven-1.1.pom). so there's not much to report, but i'll let you know if i run into troubles

14:02 i like the way the query expressions seem to resemble xpath

14:03 Chouser: that was a specific goal.

14:03 I like xpath. :-)

14:04 the other main goal, though, is to allow you to drop in custom filter expressions, which isn't natural in any xpath API I've seen.

14:34 achim_p_: Chouser: yes, i've seen it's possible, but haven't used it yet. it's a nice feature

14:35 btw, speaking of reimplementing already existing things: i'm (ab)using maven repos. metadata to implement some kind of "add-classpath" replacement for jars on the net, with local caching and automatic dependency resolution.

14:35 you could start your code with e.g. "(deps/depend :maven [["org.apache.velocity" "velocity" "1.6"]])" and the specified jars plus dependencies would be downloaded into a local directory (in case they weren't in there already) and added to the cp. has this or sth similar been done? would this be useful to anybody?

14:40 PLT does vaguely similar things with planet

14:41 Chouser: I think people have discussed similar schemes in general, but I've not heard of anyone working on an implementation.

14:47 ozzilee: achim_p_: That would be killer. Even without the automatic downloading, some kind of local shared repository of jars would be great.

14:49 achim_p_: ok, i'll tinker on then ...

16:00 Chouser: gah. Anyone know of some good fast hashCode code for JS?

16:20 baetis-fly: \quit

16:43 * drewr is confused by use

16:43 Chouser: ns :use ?

16:44 drewr: No, the function use.

16:44 I would say USE, but rhickey doesn't like that. :-)

16:44 Chouser: what are you trying to do?

16:44 drewr: If I say (use 'dbauth), I get all the symbols in the dbauth namespace grandfathered into my current one.

16:45 Chouser: yes

16:45 drewr: But then if I say (require 'dbauth), it doesn't get the dbauth ns.

16:46 Sorry, if I do (use 'dbauth :require), it doesn't mimic (require 'dbauth).

16:46 Chouser: ah

16:47 what would you want it to do?

16:47 drewr: Something different than just (use 'dbauth) :-)

16:47 Chouser: Use "use" when you might otherwise do both "require" and "refer"

16:48 drewr: Hm, OK.

16:50 Chouser: If you really want to use "use" but don't want it to bring in any symbols, you could say (use '[dbauth :only []])

16:51 drewr: I was just trying to migrate to use usage.

16:51 If I still need require, I can use it too.

16:53 Chouser: I think ns is recommeneded now above both use and require. (ns my-ns (:require dbauth))

16:54 drewr: Oh.

17:49 aperotte: hello everyone

17:53 drewr: aperotte: Hi.

17:53 aperotte: hi drewr

17:53 I'm new to clojure

17:54 but very excited about it

17:54 how are you?

17:57 drewr: Doing fine, thanks.

17:57 We're all excited about Clojure!

18:02 aperotte: Since I'm relatively new to thinking about building things using functional programming and concurrency, I wanted to ask for a more well informed opinion

18:04 In general, I was curious about whether clojure would be a good choice for machine learning sorts of problems

18:05 things that you would usually write to include lots of elements, each of which change with time

18:11 fyuryu`: aperotte: that kind of problems often involve lots of number crunching

18:13 aperotte: so it's probable that you'll have to write some java

18:14 because Clojure uses boxed numbers, which are slow

18:14 aperotte: oh ok

18:14 blackdog: you can type hint numbers

18:14 and they can be very fast

18:14 fyuryu`: but if you're prototyping clojure is perfect

18:14 you can optimize better

18:15 s/better/later

18:15 blackdog: http://clojure.org/java_interop

18:15 have a look at java primitives

18:16 close to the bottom

18:16 fyuryu`: blackdog: yeah that too

18:16 aperotte: yup, I'm there

18:16 oh ok ... that's fantastic

18:17 fyuryu`: blackdog: but it's mostly for arrays, right?

18:17 blackdog: not sure haven't used it

18:18 fyuryu`: blackdog: because most of the good stuff comes via seqs

18:19 aperotte: are the java primitives mutable?

18:19 and would I need to use mutation to get decent performance?

18:20 blackdog: you can use set! if you have a thread local variable

18:20 i think

18:20 Chouser would have the definitive answer

18:20 aperotte: ok

18:20 fyuryu`: aperotte: primitives are not mutable, but you're probably asking for something else

18:21 java objects are (if they have mutable members)

18:21 aperotte: I mean if I make an array of java primitive floats, can I then assign to one of the members

18:22 fyuryu`: aperotte: yes

18:24 aperotte: thanks fyuryu` and blackdog

18:24 blackdog: yw

20:20 wmorgan: http://paste.lisp.org/display/67399 <-- I'm struggling with nested macro-quotes. Any ideas?

20:51 shoover: wmorgan: what if you replace the nested backquote with (list default x#)

20:53 wmorgan: won't work because then x# doesn't get gensym'd at all

20:56 Chouser: you can't use the x# syntax in nested backticks -- they only resolve to the same symbol within the same level of backtick

20:57 oh, you figured that out already. :-)

20:58 wmorgan: yeah, and I added an annotation with one solution that I don't really like

21:02 shoover: given the limitation, maybe you just need to make your own (let [x (gensym)] ...)

21:07 does this do what you want? http://paste.lisp.org/display/67399#2

21:08 wmorgan: shoover: that's exactly right, thanks

21:12 shoover: no problem

Logging service provided by n01se.net