
ClojureScript 101 - swannodette
http://swannodette.github.io/2013/11/07/clojurescript-101/
======
swannodette
If there's something in the tutorial that trips anyone up or doesn't make
sense please let me know and I will amend.

I'm pretty excited about the latest release of ClojureScript that makes all
this possible. With respect to speed of incremental compiles, code size,
performance of generated code, and debugging we're finally in a good place
(with of course many improvements planned in the near future).

None of this would have been possible without the tireless work of 62
contributors over the past two years,
[http://github.com/clojure/clojurescript/](http://github.com/clojure/clojurescript/).
A big thank you to all!

Happy hacking!

~~~
benmathes
Couldn't really get started (with the latest clean install of leiningen from
homebrew).

    
    
      $ lein cljsbuild auto async-tutl
      ...
      java.lang.Exception: Unknown build identifier: async-tutl
    

Did the name of the tutorial change?

edit: ell instead of 1. I guess that's why I use a heavily-serifed font for my
coding. I even re-read the command several times looking for a simple typo to
catch exactly this problem.

~~~
chongli
You have a typo there. The proper command is:

$ lein cljsbuild auto async-tut1

Note the _one_ instead of the _ell_.

------
michaelsbradley
Is there a maintained web page or cheat sheet somewhere that lists the
functions and macros unique to ClojureScript?

The API Overview[1] page for Clojure itself is great, and many of those
facilities are 1-to-1 in cljs. For individual libs, like core.async, it's easy
enough to go look in the cljs namespaces (i.e. the source code) to see what's
available.

But it seems there are at least several important facilities unique to
ClojureScript and it would be great if they were spelled out somewhere readily
accessible and linked to from the main README[2]. Digging through the source
is a bit more challenging given that there's more to wade through than for
individual libs.

[1] [http://clojure.github.io/clojure/](http://clojure.github.io/clojure/)

[2]
[https://github.com/clojure/clojurescript/blob/master/README....](https://github.com/clojure/clojurescript/blob/master/README.md)

~~~
michaelsbradley
For example: I'm aware of 'js*', but where is it defined? Where is it
documented? Does it have any "gotchas" that are explained somewhere?

~~~
swannodette
js* should not be used - it's an implementation detail. I agree we could do a
better job documenting what's unique to ClojureScript over Clojure.

------
stewbrew
Since this is supposed to be a 101 tutorial, could you please add (maybe in a
later episode) some info on debugging and on parsing the stack trace.

When I add the text

    
    
        1+"
    

to core.clsj and have auto compile running, I get a gigantic stack trace but
none of the entries points me to the line where the error occured. I wonder
how people are supposed to handle a code base bigger than a few lines of code
and I stop following the tutorial before having written a single line of
clojurescript.

~~~
stolio
Clojure stack traces in general are pretty verbose. A few thoughts from a
fellow user (not ClojureScript specific, but remember we're doing all of this
in a Clojure project):

The top few lines of the stack trace have the most information. Entering some
blank space or clearing your terminal will make it easier to find the top.

The errors are often caught way down in Java land so you can be left trying to
map Java errors and types into your own code - I've learned to ignore 80%+ of
the trace for this reason.

There's a bit of a learning curve to figure out what _this_ can't be cast to
_that_ might mean, both for Java types and Clojure types. For example a
missing opening paren may give a (roughly) "number can't be cast to sequence"
error. A missing closing paren will generally throw an End Of File (EOF)
error.

A lot of the time you can get a line number from the top entry in the stack
trace, they'll be in parentheses and aren't labeled terribly well - but once
you find it once you'll know where it is forever.

Sometimes, in certain situations - especially with macros that call across
files (like for testing) - the stack trace might be completely unhelpful.

I'm definitely hopeful that this situation will improve in the future (and
maybe we can get an Edwin style debugger? Please?) In the meantime we can use
tools to help us at least keep our braces organized since that's half the
difficult to trace problems right there. For Emacs some swear by paredit, I'm
still working on my system but it includes electric-parens, rainbow-parens (so
helpful!) and auto-closing parens.

Also, it's not as robust as Emacs but Lighttable offers some decent
parentheses handling out of the box (I went back to Emacs after Lighttable was
making connections to outside servers that I at least didn't mean to ask it to
and didn't have time to deal with. Other than that Lighttable was great).

------
andreypopp
Recreated in pure js with ES6 generators —
[http://andreypopp.com/posts/2013-11-09-recreating-core-
async...](http://andreypopp.com/posts/2013-11-09-recreating-core-async-
tutorial-with-es6-generators.html)

~~~
swannodette
Fantastic! :)

------
minikomi
Thank you for such a straightforward train I thought/workflow post. Would love
to see something detailing how to deal with state in clojurescript. Use atoms?
Pass the world in and return it modified? Dispatch within go funcs using
symbols at the head of lists?

~~~
michaelsbradley
Jim Duey's protocol-monads[1] library is compatible with ClojureScript, and
the State monad[2] can be a great for mechanism for "passing around the
world". It's not always the best choice, but it's a good option to have in
your toolbelt:

[1] [https://github.com/jduey/protocol-
monads](https://github.com/jduey/protocol-monads)

[2] [https://github.com/jduey/protocol-
monads/blob/master/src/clj...](https://github.com/jduey/protocol-
monads/blob/master/src/clj/monads/core.clj#L280)

~~~
graue
In what circumstances is it the best choice? I get the impression that monad
libraries in dynamic languages are basically toys, or are written to show off.
If I'm wrong, I'd love to see examples of how you used them in a ClojureScript
project, why (other than novelty value) you chose them over other approaches
like atoms, and how they worked out in practice.

~~~
michaelsbradley
That's a fair question, to be sure.

However, your comments regarding monads see a bit off. I've seen the same
sentiments expressed elsewhere (i.e. by others), so I think they represent
something of a common misunderstanding.

First of all, monads are simply programming patterns which relate a set of
values to a set of of functions. For any monad X, we can say that a function
is monadic if it returns a value in the X Monad. The set of values are
precisely those such that the following three Monad Laws[1] hold:

[ Using JavaScript syntax, they can be approximated as... ]

 _Left Identity_

    
    
      mBind( mReturn(x), f ) == f(x);
      // => true
      

_Right Identity_

    
    
      mBind( mReturn(x), mReturn ) == mReturn(x);
      // => true
      

_Associativity_

    
    
      mBind( mBind( mReturn(x), f ), g ) == mBind( mReturn(x), function(x) { return mBind( f(x), g ); } );
      // => true
    

Above, x is any value in the Monad X; f and g are monadic functions for the
same monad. The definitions of mBind and mReturn will vary depending on the
monad, but the same laws (and sometimes additional properties) hold for each
group of things taken as a whole – the monadic values, monadic functions, and
the mBind and mReturn pair for those values and functions.

As you can see, there is nothing special that requires a statically typed
language. That being said, if your language is statically typed, and even more
so if its type system has advanced capabilities (e.g. Haskell's type system),
then the relationships between the monadic values and functions can be
leveraged to do a number of useful things, including catching a host of errors
at compile time (though that's true regardless of monads).

If your language is dynamically typed, then you won't get those extra
benefits, but you can still take advantage of the fact that monads can
abstract away a great deal of plumbing between various pieces of your program.

Sometimes the "monad patterns" will appear in a language under another name,
or will be used "under the hood" to implement a particular API.
Clojure/Script's `let` for example is essentially the Identity Monad; and its
`for` is very much akin to the List Monad (the same is true for list
comprehensions in other languages). The core.async library involves an
inspiring application of the State Monad pattern[2].

In my case, I'm working on an SCXML-like[3] framework which builds on Google
Polymer, core.async and protocol-monads (and core.logic at some point?). By
using the State Monad pattern (together with trampolines and core.async
channels), the algorithms of SCXML can be implemented in a manner that's not
dependent on side effects, instead flowing the "global state" between the
computational steps in a manner that is consisent and relatively easy to
reason about. To boot, by using channels to link together steps in the
"mainEventLoop", time is deliberately yielded back to the CPU, making the
framework even more concurrency friendly. The project will be open source
soon, and I can follow up with some links to source code once it goes public
on GitHub.

[1]
[http://en.wikipedia.org/wiki/Monad_(functional_programming)#...](http://en.wikipedia.org/wiki/Monad_\(functional_programming\)#Monad_laws)

[2]
[https://github.com/clojure/core.async/blob/master/src/main/c...](https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async/impl/ioc_macros.clj#L53)

[&]
[https://github.com/clojure/core.async/blob/master/src/main/c...](https://github.com/clojure/core.async/blob/master/src/main/clojure/cljs/core/async/impl/ioc_macros.clj#L46)

[3] [http://www.w3.org/TR/scxml/](http://www.w3.org/TR/scxml/)

~~~
graue
You've piqued my interest around the state monad specifically, and I just
added a long but promising-looking article on it[1] to my reading queue.
However:

> _Sometimes the "monad patterns" will appear in a language under another
> name, or will be used "under the hood" to implement a particular API.
> Clojure/Script's `let` for example is essentially the Identity Monad; and
> its `for` is very much akin to the List Monad (the same is true for list
> comprehensions in other languages)._

I knew this from reading monad tutorials. And yes, certainly there exist
useful things that happen to be monads. But I question the usefulness of
explicitly pointing that out and saying, "Here's a monad library. I'm going to
use this monad library to build X. You can use all the normal monadic
functions on X, because it's a monad", as opposed to putting the monad stuff
to the side and just building X. What would you gain from building `let` or
list comprehensions atop a monad library? Would it be worth the users you'd
confuse? The concept of monad is far too abstract to be intuitive to most
people, so there is a cognitive cost to making people think about them.

1\. [http://brandon.si/code/the-state-monad-a-tutorial-for-the-
co...](http://brandon.si/code/the-state-monad-a-tutorial-for-the-confused/)

~~~
michaelsbradley
Jim Duey's blog post on the State Monad was helpful to me[1].

I agree that one shouldn't reach for monads just because one finds them
interesting or neat, or challenging for that matter.

An analogy: consider that in many cases, `while` and `for` loops are great
when looping is what's called for. But there are many times when recursion is
more attractive still. But what to do if your language doesn't have TCO, and
blowing the callstack is a real concern? Well, then you can use
trampolines![2]

Now, trampolines are great, but you don't need to always reach for them. An
analysis should be done of the problem at hand, and "the right tool chosen for
the task", which may be a simple `while` loop. The same goes for monads. Are
there cases where the State Monad makes the most sense among other programming
patterns? Yes, I think so. Particularly, when you are trying to model a multi-
step and nested-steps computation where the steps are intertwined in such a
way that one can easily identify "global state" at work. In that case, the
State Monad is a tool that will let you thread the global state through the
steps and levels of computation without having to twist yourself into knots
doing it some other way AND without relying on unfettered mutability.

[1]
[http://www.clojure.net/2012/02/10/State/](http://www.clojure.net/2012/02/10/State/)

[2] [http://raganwald.com/2013/03/28/trampolines-in-
javascript.ht...](http://raganwald.com/2013/03/28/trampolines-in-
javascript.html)

[&] [http://clojure.github.io/clojure/clojure.core-
api.html#cloju...](http://clojure.github.io/clojure/clojure.core-
api.html#clojure.core/trampoline)

------
nico
It looks great, thanks! Here's another one I just saw:
[https://github.com/magomimmo/modern-
cljs/blob/master/doc/tut...](https://github.com/magomimmo/modern-
cljs/blob/master/doc/tutorial-01.md)

I got started with CLJS about a year ago but ran into performance issues with
the specific application I was building, hopefully things have improved now.

~~~
swannodette_
ClojureScript has had performance escape hatches for some time. It's pretty
much always possible to get the performance of hand written JS, important
otherwise our data structures would be lame. We'll likely document these
techniques in the future.

------
john2x
Great write up.

ClojureScript 102 should be how to get a REPL running ;)

~~~
jbeja
Could you please do one that explain how to actually debug in CLJS.

~~~
poppingtonic
Using `lein cljsbuild auto` should enable you to see problems in your
clojurescript code as soon as you save it, and using the browser's js console
enables you to see problems in the compiled/generated js. The stack trace
printed out in case of an exception is usually informative enough. I
experienced its helpfulness quite recently during my study of OP's example.

------
DigitalJack
Nice. I spent like an hour today looking for a leiningen clojurescript
template, so I'm happy to see Mies.

It doesn't show up when googling for "leiningen clojurescript template." I
wonder if maybe mentioning leiningen in the readme would change that.

------
sherbondy
Hey swannodette, just curious about why you ended the <input> tag in your
tutorial. Was this deliberate?

~~~
sherbondy
Hmm, I seem to have found a limitation/bug in go blocks. I didn't know about
the nifty "." syntax for calling methods on js objects, eg: (. js/console (log
"hi")).

Anyway, I thought this was great, so I tried doing it inside of a go block,
like so: (go (while true) (. js/console (log (<! clicks))))

And this yielded a compiler warning: WARNING: Use of undeclared Var async-
tut1.core/log at line 50 src/async_tut1/core.cljs

So there seems to be a problem with namespace resolution and the go macro? Or
maybe a bug with "." in particular? Works fine when I do (.log js/console (<!
clicks))

Either way, I would try to be consistent about your notation throughout the
article. Either use (.log js/console ...) or use (. js/console (log ...)).

Core.async in the browser is a ton of fun otherwise! Kudos.

~~~
omni
I think this is a typo in the article. If you remove the parenthesis right
before log, this should work. You're using the dot form to chain log onto
js/console. When you write "(log" instead of just "log", it tries to call log
as its own function, not as a method of js/console. This is why it tells you
it's never seen that variable before.

(go (while true) (. js/console log (<! clicks)))

------
krosaen
Perfect intro to core.async in a web app - just enough of an example (jsonp
within a click handler would require a nested callback).

It would be nice to update the tutorial with a final instruction on compiling
with advanced mode so people can see that the end result is a reasonable sized
js file.

------
macmac
Incorporating a browser REPL into the template would be fantastic.

