Amos, Great work!
I would like to see how we can integrate it with rails. Can we use shin in our asset pipeline now? If so, how? Luke On 3 December 2014 at 15:48, Amos Wenger <[email protected]> wrote: > I don't have a (publishable) example readily available (but might work on > one in the future), but I'll try to answer what I think your question is. > > First off — I'm not talking about implementing part of your server-side > logic in ClojureScript. If you want something like this you're better off > writing your whole server app in Clojure, there's enough good libraries > around to do that :) > > Second — I'm not talking about some Rails magic like UJS either. I haven't > used that ever, and am not planning to > > So "cljs & rails integration" is really a fancy way of saying "the Rails > asset pipeline knows how to compile clojurescript code and serve it" — the > Rails asset pipeline really being Sprockets. > > There are two predominant models when it comes to compiling assets in dev: > > - Have a 'watcher' process that recompiles source files whenever they're > changed ('lein cljsbuild auto', 'coffee-script --watch', 'sass --watch', > etc.) > - Have an 'asset pipeline' integrated in your HTTP server, that compiles > assets on-demand, when they're requested. > > When developing a Rails app, it's most convenient to just have the server > running and let the asset pipeline take care of everything. Sure, maybe > you're wasting a few ms waiting for a file to compile while reloading the > page, but you also get to see compile errors in your browser instead of in > a tmux pane / terminal tab somewhere far away — there's no notification to > distract you everything you save a file and the compilation succeeds, you > only get info when something goes wrong, and barring that, you can stay in > the comfortable "text editor / browser" loop. > > To integrate a transpiler (like the ClojureScript/CoffeeScript/Sass/LESS > compilers) into an asset pipeline like I just described, you need to have > control over the compiler's cache & the ability to get output for > individual files. > > In the case of cljs mainline, that would mean having a ruby gem, loaded > into the Rails asset pipeline, that starts up a JVM, loads the > ClojureScript compiler into it, and then knows enough about its internals > to ask for recompilation when a specific file is being requested by the > pipeline, and then instead of writing them to disk somewhere, return their > content so that the pipeline may serve it. > > I'm not saying it's impossible, btw, it's very possible - as Thomas Heller > demonstrated with shadow-build. But this: > https://github.com/thheller/shadow-build/blob/master/src/clj/shadow/cljs/build.clj > — doesn't look like the kind of code I want to maintain in a simple plug-in > for an asset pipeline. > > There's a good reason the ClojureScript compiler API is "complicated", > though — it's really powerful. And evaluates macro in a *real* Clojure > environment, unlike Shin (which uses V8 + cljs.core). And I'm still not > sure how it handles caching/incremental build, because honestly, at this > point I'm scared to look. > > Hopefully Shin can expose a simpler API so it can be integrated in > pipelines all around - whether they are Ruby-based (in which case they can > just use the gem), or not (in which case a disk-based cache is probably the > way to go: the big advantage being that shin boots up *fast* so there's > little penalty to that approach). > > TL;DR - asset pipelines benefit from simple interfaces & lighter > command-line tool, and that's what I'm aiming for with shin. > > On Wednesday, December 3, 2014 4:13:56 PM UTC+1, Yehonathan Sharvit wrote: > > Could you please share an example of an integration of cljs and rails? > > > > > > On Wednesday, 3 December 2014 00:50:57 UTC+2, Thomas Heller wrote: > > > Hey, > > > > > > good luck with your efforts. > > > > > > It seems to be that is was motivated by alot of frustration due to > lein-cljsbuild and Google Closure. Most of the issues mentioned in "S-exps > in your browser" are actually addressed in shadow-build [1], part of the > reason I wrote it due to some frustrations I had myself. > > > > > > Seems like you moved on but maybe you are interested ... > > > > > > Cheers, > > > /thomas > > > > > > [1] https://github.com/thheller/shadow-build > > > > > > On Tuesday, December 2, 2014 10:01:27 PM UTC+1, Amos Wenger wrote: > > > > There's definitely a business case behind this, otherwise I wouldn't > be able to justify the time put behind it :) > > > > > > > > Obviously, one use-case is to be able to use ClojureScript in Rails > projects seamlessly, without having to 1) use an external "watcher" tool > that runs parallel to the asset pipeline or 2) use something integrated to > the asset pipeline but which spins up a fresh compiler instance every time > (3-4s penalty right there) > > > > > > > > But even when using ClojureScript in standalone projects, say, only > static HTML files + heavy JS client-side logic, it pays off to have a > smaller, quick to boot up compiler be it launched fresh each time and using > a file cache, or living in the background, integrated to a tool like > "guard" (and believe me - an MRI instance is *much* cheaper memory-wise > than a JVM instance with the whole Clojure machinery loaded). > > > > > > > > So it's a lot of small things, really. Small annoyances. I'm trying > really hard not to criticize mainline cljs too much, because it's an > achievement in itself and it'll remain forever the first-class cljs > compiler everybody uses — there's all the goodies in there. > > > > > > > > I guess I just wanted something I could know inside-out. I've > started seriously getting into Clojure only about 2 months ago, so it's > been a great learning experience as well! Plus, it's not my first time > writing a transpiler... but Clojure is much nicer to implement. > > > > > > > > By the way, since the original message went through on the mailing > list, I managed to get reagent-shin to work completely (as far as I can > tell) including input components, etc. The last hurdle was a typo in > PersistentArrayMap.-equiv (one damn parenthesis...). > > > > > > > > I reckon shin is a strange beast "it's experimental!" but "it > compiles 90% of the cljs code out there without modifications!", "don't use > it for anything serious!" but "contributions welcome!", not to mention that > it's written in Ruby - but Ruby is just a tool like any other, that has a > very friendly ecosystem, and whose VMs boot up fast. That's all I asked. > > > > > > > > Since cljs.core has grown to a healthy 2.2K and ~200 defs, I'm now > trying. Macro expansion is the costliest part of the workflow so far, each > taking 10 to 12ms (because every expansion is a module that has to be > translated from AST to JST, generated into JS, loaded into V8, passed its > input, serialize its output, then parse its output back from the Ruby > side). However I have a few ideas on how to make it all faster. And when > I'm out of ideas, caching will help a lot, like mainline does. > > > > > > > > On Tuesday, December 2, 2014 6:16:04 PM UTC+1, Jamie Orchard-Hays > wrote: > > > > > Amos, I'm curious about your motivation for this. Fun? Curiosity? > Business need? I'm using Om/CLJS in a Ruby on Rails app, so this caught my > eye. > > > > > > > > > > > > > > > On Dec 2, 2014, at 8:35 AM, Amos Wenger <[email protected]> > wrote: > > > > > > > > > > > shin (新) is an early-stage but relatively complete > implementation of a ClojureScript-to-JavaScript compiler, written in Ruby, > and that does not rely on Google Closure's libraries or compiler: > https://github.com/memoways/shin > > > > > > > > > > > > The README contains probably more than you ever want to know > about Shin, but I am of course happy to answer any of your questions :) > > > > > > > > > > > > The main differences are: > > > > > > > > > > > > - It's not based on any previous Clojure compiler - no use of > the analyzer, etc. > > > > > > - It generates AMD modules rather than Google Closure modules > > > > > > - Data structures are implemented on top of Matt Bierner's > HAMT+ for the time being (but that may change) > > > > > > - Macros are expanded in JavaScript, using V8 (driven from Ruby) > > > > > > - Uses `escodegen` to generate JavaScript > > > > > > > > > > > > What sorely missing? At this time: metadata support, type > annotations, transducers, a cache for the compiler so recompiles are > faster, and actually passing source location information from the AST to > escodegen. > > > > > > > > > > > > But otherwise, functions, defprotocol/deftype, macros, base > collections (list, cons, hash-set, hash-map) > > > > > > > > > > > > Right now the most involved piece of ClojureScript code (except > for ~30% of cljs.core and 100% of clojure.string) is probably Reagent, > which I am almost done making work with Shin: > https://github.com/memoways/reagent-shin — I wanted to wait till it was > complete to make the announcement, but I figured I could probably use some > help along the way :) > > > > > > > > > > > > Why should anyone care about this ? > > > > > > > > > > > > - Alternative implementations of a language are just plain > healthy, even if you don't use them. > > > > > > - Polyglot programming is awesome (Clojure/Ruby/JS all in one!) > > > > > > - 330 specs and growing: > https://github.com/memoways/shin/tree/master/spec (maybe we can get a > runnable specification of ClojureScript at some point?) > > > > > > > > > > > > Oh, and hopefully obvious disclaimer: don't use it for anything > serious! It still breaks often, it's not even a month old, handle with care. > > > > > > > > > > > > That said, helping hands are more than welcome, in particular in > these areas: > > > > > > > > > > > > - Identifying differences in behavior with the mainline CLJS > implementation > > > > > > - Writing more specs & porting more of cljs.core > > > > > > - Profiling & making the compiler faster (probably more for > Ruby folks!) > > > > > > - Figuring out a JS-friendly way to distribute libraries > (bower? component?) — eventually have libraries that compile both on > mainline and shin? > > > > > > > > > > > > Love, > > > > > > — Amos > > > > > > > > > > > > P.S: I'm not sure how the whole licensing thing works, since > ClojureScript is EPL+CA and Shin is just MIT-licensed. There's a note in > the README, let me know if there's anything else I need to do! > > > > > > > > > > > > -- > > > > > > Note that posts from new members are moderated - please be > patient with your first post. > > > > > > --- > > > > > > You received this message because you are subscribed to the > Google Groups "ClojureScript" group. > > > > > > To unsubscribe from this group and stop receiving emails from > it, send an email to [email protected]. > > > > > > To post to this group, send email to > [email protected]. > > > > > > Visit this group at http://groups.google.com/group/clojurescript > . > > -- > Note that posts from new members are moderated - please be patient with > your first post. > --- > You received this message because you are subscribed to the Google Groups > "ClojureScript" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To post to this group, send email to [email protected]. > Visit this group at http://groups.google.com/group/clojurescript. > -- Note that posts from new members are moderated - please be patient with your first post. --- You received this message because you are subscribed to the Google Groups "ClojureScript" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/clojurescript.
