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.

Reply via email to