2008-09-11
| 07:47 | StartsWithK | i was just reading results of latest poll |
| 07:47 | StartsWithK | one of the thing metioned was cpan like repository |
| 07:47 | StartsWithK | that sounds like realy good idea |
| 07:47 | StartsWithK | so, to share how i started to build my own app |
| 07:48 | StartsWithK | first i was using ant, but that didn't work that great, no dependancies to extrenal jar.. i had to download them all to lib/ and sync them manualy |
| 07:49 | StartsWithK | then i moved for short time to buildr (ruby make like system for java, part of apache incubator) |
| 07:49 | StartsWithK | it supports maven repositories, so that worked great |
| 07:49 | StartsWithK | but you have to install ruby/jruby and buildr, and that could be a pain for most users |
| 07:50 | StartsWithK | so now i am at ant+ivy, ivy is dependancy tracker (part of apache) |
| 07:51 | StartsWithK | why i like it is, it just resolves dependanicies, it supports its own repository format, maven repositories, or general urlresolvers |
| 07:51 | StartsWithK | also, there is no need to install ivy manualy, it can be done from ant build |
| 07:52 | StartsWithK | only thing missing at the moment is maven/ivy repository with clojure and clojure-contrib, then you wouldn't need to distribute clojure.jar with your own lib |
| 07:54 | cemerick | Yeah, we use ant+ivy as well. Although, we only use our own internal repo, and we'll always distribute a "full stack", with all dependencies included. |
| 08:00 | StartsWithK | i think ivy would be a good choice |
| 08:01 | StartsWithK | maven looks to much java orientated, and that didn't fit that well for genclass and similar thing for me |
| 10:32 | achim_p | hi! is there an easy way of turning a java.util.Enumeration object into a (lazy) seq? |
| 10:33 | rhickey_ | achim_p: enumeration-seq |
| 10:34 | rhickey_ | (find-doc "Enumeration") finds it |
| 10:36 | achim_p | oh, embarrassing ;-) thanks for the pointer! |
| 10:36 | leafw | rhickey_: I really like the 'new' way of calling static methods and fields. You have finally captured what they really are: unbound functions within a namespace. Calling them like other clojure namespaces, with '/', is just brilliant. |
| 10:37 | leafw | it's easier to explain to a novice that a static method is by using clojure, than by using java itself. |
| 10:37 | leafw | s/that/what/ |
| 10:38 | rhickey_ | leafw: just need to get everyone to transition to the new style... |
| 10:38 | leafw | I will update my wikis. |
| 10:47 | leafw | it's done/ |
| 10:56 | Chouser | rhickey_: were you serious about gen'ing JS just like AOT JVM bytecode? Or would macroexpand still be a useful approach. |
| 10:57 | rhickey_ | AOT Java/JavaScript _source_ |
| 10:57 | Chouser | oh, Java source? |
| 10:58 | rhickey_ | Right, like I used to do. But that is less compelling than JS |
| 10:59 | blackdog_ | that sounds really good to me, finally client and server code in one decent language :) |
| 10:59 | Chouser | naw, there are lots of people who want AOT Java. They'd probably be content with Java source. |
| 10:59 | rhickey_ | as I said before, AOT Java for what purpose? For startup speed, I have ideas that won't require AOT |
| 11:00 | Chouser | anyway, my real question is how you'd recommend doing the macroexpand of interior expressions, assuming macroexpand is a useful approach. |
| 11:01 | rhickey_ | the idea is cal Compiler.analyze as done now - that does all of the heavy lifting. Then just to emitJS per expression type |
| 11:01 | rhickey_ | just do |
| 11:02 | blackdog_ | and if Chouser has finished the clojure persistent structures by then we're good to go ;) |
| 11:05 | Chouser | my goal (dream?) is to get boot.clj auto-gen'ing to JS. |
| 11:06 | Chouser | That will require some stubs/wrappers for a few Java classes. StringBuffer, for example. |
| 11:09 | Chouser | Compiler/analyze is private |
| 11:13 | rhickey_ | Chouser: so are all of the expression classes, this will require some cooperation from Clojure :) |
| 11:30 | Chouser | doesn't analyze do too much? like looking up vars? |
| 11:31 | rhickey_ | Chouser: I don't know how you compile without resolving names |
| 11:33 | Chouser | I was imagining a literal translation from symbols, and then allowing the JS to do resolving. |
| 11:34 | rhickey_ | what a var becomes in the generated output is still open |
| 11:35 | Chouser | (Compiler/analyze Compiler$C/STATEMENT '(def map "test")) |
| 11:36 | Chouser | that throws an exception. Hm, maybe I just need to make sure I'm in the 'clojure namespace like it expects. |
| 12:05 | Chouser | It's also doing static method resolution. I was assuming I'd want host syntax to access JS classes and methods. |
| 15:19 | Chouser | would it be inappropriate for me to put half-baked non-functional peices of clojurescript into the clojure-contrib repo? |
| 15:19 | Chouser | or even pieces? |
| 15:23 | rhickey_ | Chouser: sure, go ahead - have to start somewhere! |
| 15:26 | Chouser | well, I just didn't know if clojure-contrib was the right place to dump it. |
| 15:27 | Chouser | Don't want to scare the newbies. ;-) |
| 15:27 | rhickey_ | People pick and choose from contrib right? Not one bundle? |
| 15:28 | Chouser | I dunno about other, but I "svn up" the whole thing, and use (ns (:require ...)) to pick out what I want to use. |
| 15:28 | Chouser | s/other/other people/ |
| 15:29 | rhickey_ | Ok, well, just put work-in-progess comments in there. I don't think we need another project |
| 15:31 | Chouser | ok |
| 15:35 | cemerick | fwiw, we bundle all of clojure.contrib into our jars. I suppose it's only a matter of time before we need to establish exactly what we use and what we don't. |
| 15:36 | cemerick | it certainly seems silly to have separate projects at this point |
| 15:36 | rhickey_ | cemerick: trusting souls :) |
| 15:37 | cemerick | rhickey_: I've been standing on the shoulders of giants forever; I'd be fiddling with microcode if I didn't trust others implicitly. :-) |
| 15:38 | Chouser | I'll put it in src/clojurescript, so if you're bundling src/clojure/contrib you're already set to skip this stuff. |
| 15:39 | Chouser | or maybe I'll put it in clojurescript right at the top level (instead of in src) |
| 15:42 | cemerick | wow, defvar and friends put the docstring *last* |
| 15:42 | StartsWithK_ | maybe you could create your own branch? |
| 15:47 | rhickey_ | no branches please |
| 15:50 | abrooks | Branching in Subversion is just as convenient as maintaining another family on the side. I recommend against it. |
| 15:51 | abrooks | rhickey_: I've been thinking of writing up a plan to use Mercurial (or git) for Clojure. Is that a waste of time or something that would be helpful. |
| 15:51 | rhickey_ | abrooks: for me to use mercurial? |
| 15:51 | abrooks | Well, yes, you would be part of that. :) |
| 15:53 | rhickey_ | I don't think so. there's nothing wrong with the SVN at present, and those that want to see it via git can |
| 15:53 | abrooks | We get the most benefit when the main repo (rather than just a mirror) is Mercurial. |
| 15:53 | rhickey_ | how so? |
| 15:54 | abrooks | Right now we have a single, linear history. If people are tracking changes on the side, rebasing and other activities are a lot more annoying. Particularly if some of their changes are accepted upstream and some aren't. |
| 15:54 | abrooks | Part of the writup would be a rationale of why it would be beneficial. |
| 15:55 | Chouser | abrooks: you'll be fighting a relative derth of IDE integration, compared to svn. |
| 15:56 | abrooks | When I say Mercurial, I also mean git. I think either would be fine (having used both) though I think Mercurial is sufficiently easier for Clojure's usage. |
| 15:56 | rhickey_ | abrooks: feel free to write it up, but I am strongly inclined to stick with large hosts like SF or Google code, and I care about IDE support |
| 15:56 | abrooks | Chouser: tortiose-hg is out there. |
| 15:56 | abrooks | I'll be most inclined to spend the time if I think the chances are good. |
| 15:57 | StartsWithK_ | netbeans also has mercurial support now |
| 15:57 | abrooks | IDE/GUI tools -- noted. That's not something I generally care about but I think the state of the world is good. I'll have to check in detail. |
| 16:02 | cemerick | Are any super-automagic yet reliable ways to have a svn repo mirror a git repo? If clojure goes to git/hg (and yes, I know rhickey_'s not super-interested, but still), I'll need to put together something to keep me in the sane (for me) world of svn. |
| 16:07 | abrooks | Providing a flat svn mirror of git/hg is not a problem -- you just lose some information that Subversion has no way of storing. |
| 16:07 | abrooks | Tailor works quite well from what I hear: http://progetti.arstecnica.it/tailor |
| 16:07 | abrooks | You just want to keep the svn changes flowing out from git or flowing into git. Bi-directional sync gets nasty. |
| 16:31 | Chouser | bi-directional sync with git when the canonical repo is svn is not a problem. |
| 16:35 | abrooks | True but I think that's an odd way to do things. Can you properly publish a git-svn repo? I've not tried. |
| 16:35 | arohner | it's pretty straight forward as long as your git history isn't too complicated |
| 16:35 | abrooks | Well, you're still missing out on all the merge history from the canonical svn repo, anyways. |
| 16:35 | arohner | when using git-svn, bidirectional works well both ways. just treat git like svn |
| 16:35 | arohner | :-) |
| 16:36 | arohner | the svn merge history is represented in git too, IIRC |
| 16:37 | abrooks | arohner: But manual merges done on the Subversion side of things aren't shown with merge history (at least for Subversion 1.4). They're just ugly checkins. |
| 16:39 | arohner | huh. I either haven't run into that, or haven't noticed |
| 16:39 | arohner | I do know that complicated merges on the git side before going into svn are messy |
| 19:55 | Chouser | clojurescript macros get expanded by the JVM |
| 19:55 | ozzilee | So, today I notice that the half-assed site I put up ages ago is the number one google result for "scheme clojure". Apparently the scheme people aren't too interested in clojure :-) |
| 19:56 | rhickey | Chouser: is that a question? (just arrived) |
| 19:57 | Chouser | macros can call any functions defined so far, which means all functions must be defined in the JVM, doesn't it? |
| 19:57 | Chouser | but of course some functions are going to refer to JavaScript objects, so those function will fail to compile on the JVM |
| 20:01 | rhickey | no, the only functions that run at compile time are the ones needed to _expand_ the macro, not the ones it expands into. The former are likely to already exist in Clojure |
| 20:02 | rhickey | parenscript works the same way - macros are written in and run in CL, but expand into JS |
| 20:04 | Chouser | I'm trying to process boot.clj, but of course it defines functions and then defines macros that use them. |
| 20:04 | rhickey | process boot.clj how? |
| 20:05 | Chouser | running each top-level form through Compiler/analyze and then translating the results into JavaScript. |
| 20:07 | Chouser | for now I'm eval'ing each in a 'tmp namespace as well as translating to JavaScript. That should work for all of boot.clj. |
| 20:08 | Chouser | I guess for user-provided forms I'll rely on the user deciding which will be for the JVM and which will be run through formtojs. |
| 20:09 | rhickey | I'm not sure what your objective is. I;d shoot for having a fully-loaded Clojure 'compile' a file to JS on demand. It's not at all like the bootstrap of Clojure. I wouldn't expect to have compilation capabilities at all in JS |
| 20:09 | rhickey | that compile could ignore macros |
| 20:11 | rhickey | all you need are emitJS functions for all of the expr types (ok, not all, but that's the essence) If we want to end up with a shareable boot.clj there will need to be more wrapping of Java, so everything goes through RT or something |
| 20:11 | Chouser | Here's the kind of expression I'd expect to translate to JS: (let [[a b] foo] (.getElementById document "x")) |
| 20:11 | rhickey | no problem |
| 20:13 | rhickey | a simple flag could keep the compiler from trying to resolve types - all calls look reflective and instance |
| 20:13 | Chouser | ah, ok, that's one set of problems. That's a flag that doesn't exist, I assume? |
| 20:14 | rhickey | yeah, you're not going to be able to glom on a JS compiler without some support :) |
| 20:14 | rhickey | unless you write a full compiler, which would be a lot of work... |
| 20:14 | Chouser | oh, clearly. I've already got a giant patch on Compiler.java |
| 20:15 | Chouser | For now all I've had to do is make a bunch of classes public, final fields public, and added some final accessors. |
| 20:15 | rhickey | are you adding emitJS methods to the Exprs? |
| 20:16 | Chouser | no, I've got a multimethod named tojs |
| 20:16 | rhickey | that's fine |
| 20:17 | Chouser | Actually, I've got it working through boot.clj up to the first recur. |
| 20:17 | rhickey | does JS have the comma operator? |
| 20:17 | Chouser | yes |
| 20:18 | Chouser | I haven't needed it yet. I guess that would be a alternate way to do BodyExpr |
| 20:18 | rhickey | right, that's good. dropping that from C was a huge mistake for Java/C#, makes using them as compilation targets much harder |
| 20:18 | rhickey | It seem the way to do BodyExpr, no? |
| 20:19 | Chouser | it would have been easier: return e1,e2,e3; But I just did: e1;e2;return e3; |
| 20:19 | rhickey | You realize by doing this you are going to completely understand Clojure... |
| 20:20 | Chouser | except for the Magical STM part :-) |
| 20:20 | rhickey | Chouser: what if it's in an expression position? |
| 20:20 | rhickey | you can't say return |
| 20:21 | Chouser | yeah, I may need to change BodyExpr. so far it's only been used as the body of what has ended up a JS function. |
| 20:21 | Chouser | but recur's tricky. |
| 20:21 | rhickey | you need to pay attention to the context stuff, it deals with the expr/statement dichotomy |
| 20:21 | rhickey | esp. important when generating source |
| 20:22 | Chouser | My only thought so far is to put a function in a while loop, and have the function return an array of args to be supplied to the next function call. |
| 20:24 | rhickey | no, you emit a function that has the while loop in it, preceded by locals, and it just sets the locals each iteration |
| 20:24 | rhickey | at least JS has closures |
| 20:25 | rhickey | or resets the args |
| 20:26 | Chouser | but the args are set in parallel -- the inits for the next iteration all refer to the old values. |
| 20:27 | rhickey | use temps |
| 20:27 | Chouser | ok |
| 20:29 | Chouser | yeah, I'm using JS closures for let blocks |
| 20:29 | rhickey | just have to be careful about JS broken block scope |
| 20:30 | rhickey | Clojure uses stack as temp area for recur |
| 20:31 | Chouser | careful about JS broken block scope when choosing temp names? |
| 20:32 | rhickey | and local names |
| 20:32 | rhickey | let names |
| 20:38 | Chouser | ah, bother. I can't use a JS function for let blocks, because recur needs to pop right past them. |
| 20:39 | rhickey | what's wrong with block + locals for let? |
| 20:48 | Chouser | JS doesn't give me a new scope for a block, but locals in a let need to be able to shadow any outer scope |
| 20:49 | rhickey | shadowing is a compilation detail, just rename |
| 20:49 | rhickey | that's what I was talking about before |
| 20:49 | lisppaste8 | jamii pasted "cells" at http://paste.lisp.org/display/66688 |
| 20:50 | lisppaste8 | jamii pasted "cells java" at http://paste.lisp.org/display/66689 |
| 20:52 | Chouser | oh, you mean keep track of any names that will be shadowed, store the old values in temps, and restore them after leaving the let? |
| 20:53 | rhickey | if the clojure source says x, the JS could say fred (or more likely x1), a nested x would be x2, etc |
| 20:54 | rhickey | so the nested refs target different js locals |
| 20:55 | Chouser | oh, I see. |
| 20:55 | Chouser | You can probably guess at this point that I've never written a compiler. |
| 20:56 | rhickey | you don't need to track anything, the compiler already 'unique-izes' locals |
| 20:56 | Chouser | ok, great. |
| 20:56 | rhickey | just give each LocalBinding a unique name |
| 21:09 | Chouser | oh, ignore the name field in LocalBinding and make up my own for each? |
| 21:11 | rhickey | Chouser: you might want to base it on name for debugging purposes |
| 21:11 | rhickey | but yes, make each unique |
| 21:13 | Chouser | I'll need to store that mapping somewhere -- I guess I may need to pass that along as context as I process the tree. |