A chronicle of my attempt to create a real time web app using pure clojure at every layer of the stack, from the client to the styles to the web server
6. Clojure Scramble
• A multiplayer game for practicing clojure
• Transform given clojure collection into a new
one in as many different ways as you can
using list of permitted values
7. Clojure Scramble
• A multiplayer game for practicing clojure
• Transform given clojure collection into a new
one in as many different ways as you can
using list of permitted values
• Compete against other clojurians for high score
8. Clojure Scramble
• A multiplayer game for practicing clojure
• Transform given clojure collection into a new
one in as many different ways as you can
using list of permitted values
• Compete against other clojurians for high score
• A work in progress - will launch at
www.clojurescramble.com soon
10. Clojure For
Web Server
HTML
Css
Javascript
Web Sockets
Data Transfer
Deployment
11. Clojure For
Web Server • Noir - github.com/noir-clojure/noir
HTML
Css
Javascript
Web Sockets
Data Transfer
Deployment
12. Clojure For
Web Server • Noir - github.com/noir-clojure/noir
HTML • Hiccup - github.com/weavejester/hiccup
Css
Javascript
Web Sockets
Data Transfer
Deployment
13. Clojure For
Web Server • Noir - github.com/noir-clojure/noir
HTML • Hiccup - github.com/weavejester/hiccup
Css • Cssgen- github.com/paraseba/cssgen
Javascript
Web Sockets
Data Transfer
Deployment
14. Clojure For
Web Server • Noir - github.com/noir-clojure/noir
HTML • Hiccup - github.com/weavejester/hiccup
Css • Cssgen- github.com/paraseba/cssgen
Javascript • Clojurescript - github.com/clojure/clojurescript
Web Sockets
Data Transfer
Deployment
15. Clojure For
Web Server • Noir - github.com/noir-clojure/noir
HTML • Hiccup - github.com/weavejester/hiccup
Css • Cssgen- github.com/paraseba/cssgen
Javascript • Clojurescript - github.com/clojure/clojurescript
Web Sockets • Web Sockets - aleph, lamina, noir-async
Data Transfer
Deployment
16. Clojure For
Web Server • Noir - github.com/noir-clojure/noir
HTML • Hiccup - github.com/weavejester/hiccup
Css • Cssgen- github.com/paraseba/cssgen
Javascript • Clojurescript - github.com/clojure/clojurescript
Web Sockets • Web Sockets - aleph, lamina, noir-async
Data Transfer • Data Transfer - strings/reader. outgoing only!
Deployment
17. Clojure For
Web Server • Noir - github.com/noir-clojure/noir
HTML • Hiccup - github.com/weavejester/hiccup
Css • Cssgen- github.com/paraseba/cssgen
Javascript • Clojurescript - github.com/clojure/clojurescript
Web Sockets • Web Sockets - aleph, lamina, noir-async
Data Transfer • Data Transfer - strings/reader. outgoing only!
Deployment • Leinengen - superjar. upstart/monit. nginx proxy
20. Benefits of pure clojure
• No context switching
• Share server and client code
21. Benefits of pure clojure
• No context switching
• Share server and client code
• Enabled higher level abstractions
22. Benefits of pure clojure
• No context switching
• Share server and client code
• Enabled higher level abstractions
• Avoid web language pitfalls
23. Benefits of pure clojure
• No context switching
• Share server and client code
• Enabled higher level abstractions
• Avoid web language pitfalls
• Everything maps easily to lisp
25. Clojure MVC
• Namespaces make relationships explicit - good
for architectural discipline. Control very directly who
can see who.
26. Clojure MVC
• Namespaces make relationships explicit - good
for architectural discipline. Control very directly who
can see who.
• Quarantine state - lots of state inevitable in web
programming. Can still be minimized compared to
imperative programming. I’ve used atoms for everything
so far. Simple updates. Other approaches?
27. Clojure MVC
• Namespaces make relationships explicit - good
for architectural discipline. Control very directly who
can see who.
• Quarantine state - lots of state inevitable in web
programming. Can still be minimized compared to
imperative programming. I’ve used atoms for everything
so far. Simple updates. Other approaches?
• Async events through lamina channels -
decoupled interactions
28. Clojure MVC
• Namespaces make relationships explicit - good
for architectural discipline. Control very directly who
can see who.
• Quarantine state - lots of state inevitable in web
programming. Can still be minimized compared to
imperative programming. I’ve used atoms for everything
so far. Simple updates. Other approaches?
• Async events through lamina channels -
decoupled interactions
• I ended up with a thick ‘manager’ tier - async
creates responsibilities that don’t fall neatly into mvc
30. Noir
• Lightweight - gives you what you need. Server start
(server.clj), routes (defpage), and basic http stuff
(sessions, cookies, etc.). Mostly stays out of your way
31. Noir
• Lightweight - gives you what you need. Server start
(server.clj), routes (defpage), and basic http stuff
(sessions, cookies, etc.). Mostly stays out of your way
• Unopinionated - you must determine and enforce
your own architecture. Doesn’t try to save you from
yourself.
35. Hiccup
• Expressive syntax
• Composable in interesting ways
• Crate - hiccup in clojurescript - github.com/ibdknox/
crate
36. Hiccup
• Expressive syntax
• Composable in interesting ways
• Crate - hiccup in clojurescript - github.com/ibdknox/
crate
• Death to xml! - xml is ugly and poorly implemented
lisp. The designers will be fine.
39. cssgen
• Specify nested rules in clojure
• Mixins for functional css
40. cssgen
• Specify nested rules in clojure
• Mixins for functional css
• Has a long way to go - less/sass/compass/etc. and
some asset build tool like sprockets much better option at
this point
41. cssgen
• Specify nested rules in clojure
• Mixins for functional css
• Has a long way to go - less/sass/compass/etc. and
some asset build tool like sprockets much better option at
this point
• Clojure needs a serious tool like clojurescript for
css
42. cssgen
• Specify nested rules in clojure
• Mixins for functional css
• Has a long way to go - less/sass/compass/etc. and
some asset build tool like sprockets much better option at
this point
• Clojure needs a serious tool like clojurescript for
css
• Don’t underestimate front end organization! -
clojure can and should take css to new heights
44. Clojurescript
• Namespaces are a huge improvement over js/
coffeescript - makes client side development feel a lot
less like wandering through a dark Malaysian jungle
45. Clojurescript
• Namespaces are a huge improvement over js/
coffeescript - makes client side development feel a lot
less like wandering through a dark Malaysian jungle
• You don’t need much state! - clojurescript can often
function as a straight pipeline from server to ui. Don’t
hold onto data unless you need it!
46. Clojurescript
• Namespaces are a huge improvement over js/
coffeescript - makes client side development feel a lot
less like wandering through a dark Malaysian jungle
• You don’t need much state! - clojurescript can often
function as a straight pipeline from server to ui. Don’t
hold onto data unless you need it!
• Feels like clojure! But native js interop can be
tricky - javascript is a mutable paradigm. Leads to
verbosity.
47. Clojurescript
• Namespaces are a huge improvement over js/
coffeescript - makes client side development feel a lot
less like wandering through a dark Malaysian jungle
• You don’t need much state! - clojurescript can often
function as a straight pipeline from server to ui. Don’t
hold onto data unless you need it!
• Feels like clojure! But native js interop can be
tricky - javascript is a mutable paradigm. Leads to
verbosity.
• Check out Chris Granger libs - (ibdnox - noir/light
table dude). jayq, crate, fetch. best cljs tutorial: chris-
granger.com/2012/02/20/overtone-and-clojurescript/
48. Clojurescript
• Namespaces are a huge improvement over js/
coffeescript - makes client side development feel a lot
less like wandering through a dark Malaysian jungle
• You don’t need much state! - clojurescript can often
function as a straight pipeline from server to ui. Don’t
hold onto data unless you need it!
• Feels like clojure! But native js interop can be
tricky - javascript is a mutable paradigm. Leads to
verbosity.
• Check out Chris Granger libs - (ibdnox - noir/light
table dude). jayq, crate, fetch. best cljs tutorial: chris-
granger.com/2012/02/20/overtone-and-clojurescript/
56. Data transfer
• Server to client. Clojure over the wire! - send
clojure forms as strings and read them straight into
context with clojurescript reader.
57. Data transfer
• Server to client. Clojure over the wire! - send
clojure forms as strings and read them straight into
context with clojurescript reader.
• Client to server. Use intermediary. - eval-ing
client supplied strings = fail. Could use some sort of
whitelist or safe eval? I used json -- encode and parse it on
at both ends. Good json parser: github.com/dakrone/
cheshire
59. Deployment
• lein uberjar gotchas - specify :main and :keep-non-
project-classes true in project.clj. specify (:gen-class) and
require all views in server.clj
60. Deployment
• lein uberjar gotchas - specify :main and :keep-non-
project-classes true in project.clj. specify (:gen-class) and
require all views in server.clj
• nginx, upstart, monit - I haven’t deployed yet, but
based on preliminary research, this lightweight stack
should get the job done.
61. Deployment
• lein uberjar gotchas - specify :main and :keep-non-
project-classes true in project.clj. specify (:gen-class) and
require all views in server.clj
• nginx, upstart, monit - I haven’t deployed yet, but
based on preliminary research, this lightweight stack
should get the job done.
• Continuous deploys? - git hooks? uberjar + scp +
upstart?
62. Deployment
• lein uberjar gotchas - specify :main and :keep-non-
project-classes true in project.clj. specify (:gen-class) and
require all views in server.clj
• nginx, upstart, monit - I haven’t deployed yet, but
based on preliminary research, this lightweight stack
should get the job done.
• Continuous deploys? - git hooks? uberjar + scp +
upstart?
• Environment config? - dev/staging/prod
64. Drawbacks of pure clojure
• Rough setup process
• Cryptic stack traces - especially cljs
• Lack of polished utilities - sass/compass, asset
pipeline
• Minor issues - overall, clojure is awesome for web dev!
67. Next steps
• DB integration
• Test suite - unit/integration tests
68. Next steps
• DB integration
• Test suite - unit/integration tests
• Advanced clojure - amazing what can be elegantly
accomplished with 1/100th of the standard lib. I still
don’t fully understand macros, state mechanisms,
clojure concurrency, and a lot of functional constructs,
but I’ve caught a glimpse of their power.
69. Next steps
• DB integration
• Test suite - unit/integration tests
• Advanced clojure - amazing what can be elegantly
accomplished with 1/100th of the standard lib. I still
don’t fully understand macros, state mechanisms,
clojure concurrency, and a lot of functional constructs,
but I’ve caught a glimpse of their power.
• Thanks for listening!