Clojure & ClojureScript?

OK, I’ve finally found some time to play around with this. I think I’ve found a simpler setup that what @mangofarmer describes above, without any 3rd party dependencies. I haven’t yet tried doing a production/compiled build though, perhaps with compiled assets this will change.

I’ve created two sibling directories; one is server and holds the Elixir project (as generated by mix phx.new server --no-brunch), the other client and holds the ClojureScript project (as generated by lein new re-frame client +cider +test +garden +re-frisk +aliases).

Then, I’ve removed the priv/static folder from inside phoenix, and replaced it with a symlink to ../../client/resources/public. This way phoenix can directly serve the compiled javascript and CSS.

I’ve tweaked the LiveReloading logic of Phoenix to stop it from reloading the page on JS and CSS changes, since that is handled by Figwheel now. Just comment out the relevant pattern in config/dev.exs, under the :live_reload key.

Then, tweak the main Phoenix app.html.eex layout to point to the compiled js file and init the re-frame app:

<div id="app"></div>
<script src="<%= static_path(@conn, "/js/compiled/app.js") %>"></script>
<script>client.core.init();</script>

That’s all! Accessing the normal "http://localhost:4000" Phoenix endpoint, the phoenix template is rendered, Figwheel connects to its web socket, Phoenix connects to its own, everything works as expected.

I’ve also successfully connected to the standard /socket websocket, by using the cljsjs wrapper of the phoenix javascript library.

More as I discover…

7 Likes

In my opinion the only sense to use clojure script if you use clojure in backend and you can reuse code.
There is also nice communication clojsure <-> clojure script without json.
In other case I would prefer to use some static typed language on top of JS like:



static typing … rules :slight_smile:

2 Likes

There’s nothing exceptional about Clojure’s macros. Much like most other non-schemes they’re pretty basic and not very robust. Scheme as a dialect/family is much more focused on reasonable macros. I’d argue that Elixir has better macros than (most?) Lisps. defmacro in both Clojure and CL, for example, is pretty shallow and easy to misuse, in contrast to the constructs you’ll find in Racket, for example.

Both Clojure and CL macros aren’t hygienic and force you to use gensym to work with them, making them pretty crap in comparison to Racket/Elixir. All in all macros in Lisps are why people think macros are such footguns.

On the general topic of this thread, though: Clojure is super similar to Elixir when it comes to collections and it’s a great language to work with when it comes to data manipulation. I think it’s a great fit for Elixir when it comes to style as well, as it generally feels like a lispy Elixir in that it focuses a lot on data for most things.

Edit:

I wanna stress that the footgun-ness of Clojure/CL macros have nothing to do with their power either, they’re simply not made with hygiene in mind. They’re not more powerful than other macro constructs and they don’t accomplish more.

I have evaluated Reason for my use case, but in practice it’s just too now (a few weeks back it was undergoing a major syntax change, for example). Also it didn’t bring a coherent standard library. Perhaps after a few months it will be worth another look.

I didn’t look too closely to PureScript or Elm mainly for personal preference.

So far, working with ClojureScript has been nice. I have to go in extremely small steps in the beginning, since the syntax is unfamiliar and some errors give wild messages, but the dev cycle is so short that this is quite enjoyable.

4 Likes

I’ve not used Clojure but I have used CL and it’s macro’s, well I’m not sure what you are talking about shallow?! o.O

Actually I very much prefer non-hygienic macro’s by default, it is pretty simple to build a hygenic macro on top, but it is not always easy to build a non-hygenic version on hygenic ones (depending on the exposed API). I do not consider hygenic macro’s as superior in any form (gensym is second nature to me, you’ll even see me doing such patterns in Elixir macro’s even though it is not required there…).

Except they can escape their scope, which can be very useful in very limited situations. ^.^;

1 Like

CL macros are shallow in that they are exactly what it says on the tin: List transformers. No more, no less, which makes it so that you can inherently support macros less well. If you were pragmatic about it you’d transform a syntax object that can hold more information instead.

Just transforming lists sounds good on paper but it doesn’t make for a very robust macro system and it’s the source of a lot of skepticism when it comes to macros in general. In short: It’s CL’s fault for having a pretty shit macro system that doesn’t lend itself to robust macros. It’s like one step away from someone’s badly implemented macro facility using eval manually.

1 Like

That is basically what it is. ^.^

But that power does let it perform a lot more than could be done otherwise, including even building a hygienic macro system inside of it. :slight_smile:

2 Likes

I’ve been going round in similar circles…

I’ve been through Ember.js, a couple of years of React, some Elm. But I’m in love with clojurescript and re-frame. I’ve done a few production projects now, over maybe 2 years, and re-frame’s productivity is miles ahead of anything else I’ve used.

But I haven’t enjoyed server-side Clojure as much, I’ve given it a few goes but I much prefer Elixir and some of the opinions in Phoenix. Not sure I’ll be able to justify Exlir AND clojurescript in production code though :slight_smile:

I don’t like JS or node, so it’s a shame there aren’t more mainstream server + client tools. I find myself daydreaming about view re-use, server/client data subscriptions over websockets, less wasted time building and consuming an API for internal use only. The clojure on BEAM project has caught my eye!

3 Likes