
Bringing functional to the frontend – Clojure and ClojureScript for the web - aria
http://blog.getprismatic.com/blog/2013/1/14/bringing-functional-to-the-frontend-clojure-clojurescript-for-the-web
======
tikhonj
If you're interested in a functional approach to UI code, check out functional
reactive programming (FRP). It's a declarative way to specify UI logic which
abstracts away much of the inherent messiness of using mutable state and
callbacks.

I've played around with FRP in Haskell, and have found it much nicer than the
more standard approaches to implementing UI logic. Before using FRP, my main
UI experience was with Java Swing and web development, and FRP is definitely a
step up. I've found it easier to write the code in the first place and then
_much_ easier to add new features and logic.

I've only used FRP with native UIs, but I think it would be very natural for
web development as well. It's certainly a shift in philosophy and mindset, but
one that I think is well worth overcoming.

Unfortunately, I do not know of a good tutorial for using FRP. I'm sure there
are some out there, but I basically picked it up by reading academic papers
which are not to everyone's taste. That said, I actually found some of the
papers were clearer than the blog posts and SO questions I found online!

I'm probably going to write a basic FRP tutorial in Haskell some time soon,
probably built around some very simple application (maybe John Conway's Game
of Life). It really is a fun subject. Is anybody interested in something like
that?

~~~
piranha
I recently finally understood FRP and I'm working on my own library on top of
Flapjax and Enfocus (ClojureScript) to make things simpler than doing
everything by hand.

However, I can't find examples of systems of moderate (or big) size - nothing
to get inspiration from, all examples I've seen are quite small and do too
much by hand. They often select elements (like button to track click on) from
whole document by id (and in big app this is pretty useless except for some
top-level elements), or interwind templates with bindings to events and
interaction between them is structured so that it feels like almost using
globals. Directly changing top-level data from some inner template.

Anyway, I've got some ideas - display is easy though, what's hard is nicely
structuring forms and buttons IMO - but it takes time to carve them out in
code. I would love to read something on topic of structuring applications,
which are more than a single input and a single list.

------
pelle
We use ClojureScript (and Clojure) at <http://economi.co> and I'm really
enjoying it.

Maybe one of the most difficult things coming into it is trying to relate it
to something like BackBone.

However generally speaking in Clojure the culture is more about libraries than
frameworks.

C2 <http://keminglabs.com/c2/> which on the outset looks just like a
ClojureScript version of d3 is actually a great library to use instead of a
traditional front end framework.

Check the example implementation of the class TodoMVC list here:
<https://github.com/lynaghk/todoFRP/tree/master/todo/c2>

It's uses normal Clojure data structures within atoms as the data model
([https://github.com/lynaghk/todoFRP/blob/master/todo/c2/src/c...](https://github.com/lynaghk/todoFRP/blob/master/todo/c2/src/cljs/todo/core.cljs#L9))
and uses C2 to automatically update the UI
([https://github.com/lynaghk/todoFRP/blob/master/todo/c2/src/c...](https://github.com/lynaghk/todoFRP/blob/master/todo/c2/src/cljs/todo/list.cljs)).
Very elegant.

I'm just starting to explore this area myself, but have already found it
useful for a few smaller parts of our site.

~~~
bradfordcross
Don't worry about how anything compares to frameworks, because they don't
matter anymore.

We think traditional frontend frameworks - whether of the rails/django variety
or the backbone variety, are generally rubbish in a nearly infinite number of
ways. It's a style of programming based on wrapping weak mutation oriented
idioms behind monolithic APIs and design patterns. We think default functional
style and fine grained composability is the future, and mutation + oo design
patterns + frameworks is the past.

~~~
squidsoup
It may be the future for very skilled developers that have already
familiarised themselves with frameworks and design patterns and are capable of
moving past them. The majority of software developers benefit enormously from
the conventions encouraged in a framework like Rails. If Clojure is going to
be adopted widely (if that is a goal of the project at all), the community
needs to work on better communicating best practices to make up for the lack
of framework 'guidance'.

~~~
andrewvc
Eh, even the least charitable would have to admit that frameworks enforce
style. On a large project, this matters hugely. I don't care how good your
devs are they DO have different opinions re: style.

~~~
djacobs
I disagree -- frameworks enforce structure (especially of callbacks), not code
style.

Unity of code style is something you can solve with standards, style guides,
pairing with new developers, and following conventions from surrounding code.

Clojure is nice because the community, while having different opinions about
how often you should use X technique vs Y, generally has core sensibilities
about what makes for good, simple code that composes well and doesn't tangle
concerns. (This is largely due to the influence of Rich Hickey.) This (and not
"perfectly uniform code style") makes for an effective large team.

------
puredanger
If you're interested in learning more about Clojure and ClojureScript, check
out the upcoming Clojure/West conference in Portland, OR March 18-20th
(<http://clojurewest.org/schedule>), including a keynote from Rich Hickey,
creator of Clojure. There is also a 1 day training class the day before on
ClojureScript if you want the deep dive (<http://clojurewest.org/training>).
Register here: <http://regonline.com/clojurewest2013>

~~~
bradfordcross
Highly recommended! Alex's events are always great - long on technical and
short on BS!

------
mark_l_watson
Great article. I have spent a fair amount of time playing with ClojureScript,
read "ClojureScript: Up and Running" and a lot of tutorial material on the
web, and used it a bit in a customer project.

That said, ClojureScript has not really _clicked_ for me yet, but this article
and the pointer to dommy is getting me closer to adopting ClojureScript.

I use Clojure + Compojure (and still Noir) + Hiccup for just about all of my
web app development. Love Hiccup. Having (mostly) Hiccup on the client side
with dommy looks very cool.

~~~
aria
I'd be curious to hear what you're not liking about it.

~~~
mark_l_watson
It is not that I don't like it, I just tend to be a little slow in adopting
new stuff into my set of _almost_ _always_ _used_ _tools_.

------
saosebastiao
So guys, I hate to bring this up in an unrelated topic, but when are you going
to open-source Graph? It has been 4 months since you said "soon" and I'm
squirming in anticipation.

------
vemv
On server-side templating - did you consider a selector-based approach like
cgrand's Enlive?

As I see it, it brings the best of both worlds (the comprehensibility of
"logicful" templating, the maintainability of strictly separating presentation
and data transformations)

~~~
aria
No, but I think enlive is great.

To me and the team, most of our functions are making Clojure data structures
and thinking of templating as converting data to dom elements or HTML strings
seems the most compatible with that way of thinking. But both are definitely
valid.

------
Rauchg
"The above is valid Clojure code, not another language whose syntax you have
to learn or separate compiler to use."

Even though this is a fair point, the comparison between the Jade solution and
the Clojure one is invalid. Jade was conceived as a whitespace-significant
language. Its biggest benefit over plain HTML (or HTML-based template engines
like Moustache) is the usage of indentation to determine hierarchies.

The comparison would be more valid with something like <http://domo-js.com>,
which is solving the exact same problem: using a single language (JS) for
markup production – and even replacing CSS.

~~~
aria
That's a fair point. Really, I think we're making the argument that we prefer
data approach to templates (i.e., language-native data structures (maps,
arrays, strings)) represent html structure.

You can certainly take that approach in JS. domo-js isn't quite that, it would
look more like:

["html" ["head" ["title" {class: "class1"} "Welcome to Domo"]]]

As we say in the post, you can totally pull all this off in JS, but I think if
you're going to be manipulating nested data structures, it's better to have
immutable data structures built in and the suite of functions that can
manipulate them. Clojure makes building template structures really easy:
persistent data structures, map/seq argument destructuring, keywords, sets,
etc.

------
weareconvo
I really love Clojure, but it still feels a bit heavy-weight for anything but
numerical computation. However, I'd ignore that if the performance gains were
significant. What are the performance advantages of ClojureScript server-side
templating compared to client-side Javascript templating? The vogue style
these days seems to be a one-page app where the clicks take barely any time,
because the jQuery/Zeppo/Underscore selectors are all cached.

~~~
aria
While you can use ClojureScript (CLJS) server-side running on say node.js, the
largest benefit is as a replacement for client-side JS (ClojureScript converts
to JS at compile-time).

You can actually use all the libraries you mentioned (jQuery, underscore) from
ClojureScript. What CLJS really brings to the table are a set of abstractions
and data structures that make it easier to write strong reusable functional
code. In fact, alot of underscore comes built into CLJS and I think much of
what jQuery buys you can be handled as a good CLJS library (but more on that
soon!)

~~~
weareconvo
The idea of decomposing jQuery into small libraries Clojure-style is very
appealing. The advantage would be building the specific Javascript file needed
by the client at request time, and caching intelligently to prevent doing this
too much. The extra benefit would be, you could break out the pieces of jQuery
devoted to patching cross-browser issues, and only include the ones you really
cared about.

Very cool!

~~~
aria
Yeah absolutely. One of the better CLJS features is getting the Google Closure
modules and explicit dependencies.

We'll probably add dom selectors and/or manipulation and wheter it's the same
library as dommy (github.com/prismatic/dommy) or a different one will depend
on if the selectors borrow the same abstractions and syntax as templating.

------
r0man
I'm using my ported version of Hiccup [1] to ClojureScript for a while now and
share most of my templates between Clojure on the server, and ClojureScript on
the client side with good sucess. It can sometimes get a little bit hairy to
share code between the 2 platforms, but I hope something like Common Lisp's
feature expressions [2] will make it into Clojure and ClojureScript soon. When
this arrives, life will be a lot better ...

Just for fun, I benchmarked my Hiccup port against the other candidates.

Compilation Mode: Whitespace {:crate 7.076333333333333, :jquery
1.4643333333333333, :dommy 2.1186666666666665, :hiccup-str 1.985, :hiccup-node
2.3476666666666666}

Running Hiccup and Dommy in advanced mode get's the time towards unoptimized
jQuery.

Compilation Mode: Advanced (Crate and jQuery don't run in advanced mode)
{:dommy 1.3436666666666666, :hiccup-str 1.0293333333333334, :hiccup-node
1.3506666666666665}

One thing to note: The original Prismatic tests were building jQuery Nodes and
appended them to an UL element. Building strings and appending those to the
node speeds the whole thing up a little bit further [3]. In the above
benchmark :hiccup-node uses DOM nodes to append to the root, :hiccup-str uses
Javascript strings.

I can only agree. Using a Hiccup like template system in Clojure is very nice.

[1] <https://github.com/r0man/hiccup/tree/clojurescript> [2]
<http://dev.clojure.org/display/design/Feature+Expressions> [3]
<https://github.com/r0man/dommy/tree/hiccup>

------
aria
Author here. Happy to answer any questions or comments.

~~~
mingpan
I've been using Clojure for a while now. Do you have any particular
recommendations for resources for getting started with ClojureScript? I tried
a while back and got really confused.

~~~
pchristensen
I haven't used it but here's a 10-part mega tutorial on modern Clojurescript:
<https://github.com/magomimmo/modern-cljs/>

------
t_hozumi
I agree that using data as templete is great. This is a typical example of
"The value of value"(Rich Hickey's speech).

And I think client side have a bit different requirement compared to server
side. At client side, I often need to manipulate specific element instead of
root element which crate and dommy return. So I forked crate in order to get a
collection of created elements as a hashmap. <https://github.com/hozumi/crate-
bind> This is useful. I will create dommy version of this.

------
dustingetz
the dom is a mutable data structure and the native (fast) dom apis expose
mutable interfaces. so dynamic sites (you know, single page html5 apps doing
all sorts of client-side dom manipulation) are either going to be slow, or are
going to have an imperative core, which is where you need functional
programming the most ;(

maybe HTML6 will have native functional dom manipulation and we can rewrite
all our favorite javascript libraries to expose functional interfaces. one can
dream.

~~~
vemv
I'm afraid you're confusing data structures (such as vectors, sets and maps)
with the document model object.

Not even in JS the DOM and objects are the same - some properties of the DOM
have 'magical behavior' attached.

ClojureScript does not provide any functional interface to the DOM - that
would involve a Haskell-like model of programming (monads etc), which Clojure
programmers rarely do in practice.

~~~
dustingetz
i don't think i'm confusing anything. Clojure programmers love their
persistent data structures, and in a browser environment, the most important
data structure - the document model object - is not persistent and cannot be
made persistent in a performant manner because it is a native api.

there is ongoing research into dom manipulaton in clojurescript - Conrad
Barski presented one approach[1] at Conj 2012 where the dom is mirrored in
clojurescript data structures, and then 'synced' with the dom - so that way
the imperative ickyness is tucked away in the sync method - it remains to be
seen if that can be made fast enough until we get a native persistent
interface to the dom.

[1] <https://github.com/drcode/webfui>

~~~
vemv
Characterizing side-effects as a series of supposedly functional
transformations doesn't sound quite alright to me.

That said I'm curious about such an approach.

~~~
dustingetz
Modeling side effects as transformations on data is what functional
programmers do all day. I'm not talking about monads - simple things like
inserting keys into a map and manipulating collections does not rely on side
effects in functional languages.

------
ilaksh
Another option for functional on the front end (and back end) is LiveScript.
<http://livescript.net/> Many people may not have heard of LiveScript.

I prefer LiveScript for a number of reasons, starting with the fact that I
just don't like brackets and parentheses enough to want to use them
everywhere.

------
alisnic
My biggest problem with ClojureScript is that is very hard to reason about
code written in it if you are a beginner.

~~~
aria
It's definitely a complicated language to learn since you have to learn the
complexity of

(1) Clojure core itself and readjust to functional programming (2) Understand
how ClojureScript is translated into JS in order to do interop which will
absolutely be necessary for any real project (3) Understand Clojure on the JVM
in order to understand/write macros

------
martinced
Semi-related question but...

One of the thing that I love when developing under Emacs is that I can get
real-time validation of my XML (eg XHTML) based on, say Relax NG. This even
works nicely with multiple-major-mode (eg I can get realtime validation of the
XML part, yet see JavaScript as JavaScript inside the same source file).

Now my question: with all these templating libraries like Jade, aren't you
losing feature like real-time validation?

And when such a templating library comes out, it means every editor out there
as to be modified so that it supports it?

Or is there some kind of a schema that can be used to perform real-time
validation + auto-completion?

My point is: I definitely see the point as replacing Jade by Clojure because
you can then manipulate your templates as data, which is gorgeous. But I don't
see the point of using Jade in the first place...

~~~
aria
The nice thing about dommy (github.com/prismatic/dommy) is that emacs doesn't
need to be changed at all to use it. It's just clojure and all the
highlighting and the emacs major mode work.

Also out of the box, you get a repl to live test and evaluate template
functions and data structure. It would only take a few lines of emacs lisp to
take a string from the repl and pipe it through XHTML validation.

~~~
ibdknox
In terms of performance, wouldn't it be far faster to use strings and turn
those into document fragments or setting innerHTML? I've been looking at ways
to make crate much faster and it seems that would be the fastest solution by
far.

~~~
zcam
That's the approach Hiccups took, it goes as far as generating most of the
html at compile time as well. I didn't run benchmarks but I would guess it is
faster than crate in some situations (huge fragments, older browsers etc).

Another plus is nodejs compatibilty (if you care about that, but I guess you
might :)).

<https://github.com/teropa/hiccups>

