(parens
(all(the(way(down)))))

    A web app in pure clojure
Clojure For
Clojure For
   Web Server
   HTML
   Css
   Javascript
   Web Sockets
   Data Transfer
   Deployment
Clojure Scramble
Clojure Scramble
  • A multiplayer game for practicing clojure
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
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
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
Clojure For
Clojure For
   Web Server
   HTML
   Css
   Javascript
   Web Sockets
   Data Transfer
   Deployment
Clojure For
   Web Server      • Noir -   github.com/noir-clojure/noir



   HTML
   Css
   Javascript
   Web Sockets
   Data Transfer
   Deployment
Clojure For
   Web Server      • Noir -   github.com/noir-clojure/noir



   HTML            • Hiccup -      github.com/weavejester/hiccup



   Css
   Javascript
   Web Sockets
   Data Transfer
   Deployment
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
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
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
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
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
Benefits of pure clojure
Benefits of pure clojure
  • No context switching
Benefits of pure clojure
  • No context switching
  • Share server and client code
Benefits of pure clojure
  • No context switching
  • Share server and client code
  • Enabled higher level abstractions
Benefits of pure clojure
  • No context switching
  • Share server and client code
  • Enabled higher level abstractions
  • Avoid web language pitfalls
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
Clojure MVC
Clojure MVC
 • Namespaces make relationships explicit - good
    for architectural discipline. Control very directly who
    can see who.
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?
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
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
Noir
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
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.
Hiccup
Hiccup
 • Expressive syntax
Hiccup
 • Expressive syntax
 • Composable in interesting ways
Hiccup
 • Expressive syntax
 • Composable in interesting ways
 • Crate - hiccup in clojurescript - github.com/ibdknox/
    crate
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.
cssgen
cssgen
 • Specify nested rules in clojure
cssgen
 • Specify nested rules in clojure
 • Mixins for functional css
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
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
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
Clojurescript
Clojurescript
 • Namespaces are a huge improvement over js/
    coffeescript - makes client side development feel a lot
    less like wandering through a dark Malaysian jungle
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!
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.
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/
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/
Noir-async
Noir-async
 • Netty wrapper
Noir-async
 • Netty wrapper
 • Noir-async/aleph/lamina make sockets simple
Noir-async
 • Netty wrapper
 • Noir-async/aleph/lamina make sockets simple
 • Lamina event channel
Noir-async
 •   Netty wrapper

 •   Noir-async/aleph/lamina make sockets simple

 •   Lamina event channel

 •   overtone/at-at for efficient short term
     scheduling
Noir-async
 •   Netty wrapper

 •   Noir-async/aleph/lamina make sockets simple

 •   Lamina event channel

 •   overtone/at-at for efficient short term
     scheduling

 • clj-time for date/time handling
Data transfer
Data transfer
 • Server to client. Clojure over the wire! - send
    clojure forms as strings and read them straight into
    context with clojurescript reader.
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
Deployment
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
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.
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?
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
Drawbacks of pure clojure
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!
Next steps
Next steps
 • DB integration
Next steps
 • DB integration
 • Test suite - unit/integration tests
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.
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!

A web app in pure Clojure

  • 1.
    (parens (all(the(way(down))))) A web app in pure clojure
  • 2.
  • 3.
    Clojure For Web Server HTML Css Javascript Web Sockets Data Transfer Deployment
  • 4.
  • 5.
    Clojure Scramble • A multiplayer game for practicing clojure
  • 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
  • 9.
  • 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
  • 18.
  • 19.
    Benefits of pureclojure • No context switching
  • 20.
    Benefits of pureclojure • No context switching • Share server and client code
  • 21.
    Benefits of pureclojure • No context switching • Share server and client code • Enabled higher level abstractions
  • 22.
    Benefits of pureclojure • No context switching • Share server and client code • Enabled higher level abstractions • Avoid web language pitfalls
  • 23.
    Benefits of pureclojure • No context switching • Share server and client code • Enabled higher level abstractions • Avoid web language pitfalls • Everything maps easily to lisp
  • 24.
  • 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
  • 29.
  • 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.
  • 32.
  • 33.
  • 34.
    Hiccup • Expressivesyntax • Composable in interesting ways
  • 35.
    Hiccup • Expressivesyntax • Composable in interesting ways • Crate - hiccup in clojurescript - github.com/ibdknox/ crate
  • 36.
    Hiccup • Expressivesyntax • 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.
  • 37.
  • 38.
    cssgen • Specifynested rules in clojure
  • 39.
    cssgen • Specifynested rules in clojure • Mixins for functional css
  • 40.
    cssgen • Specifynested 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 • Specifynested 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 • Specifynested 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
  • 43.
  • 44.
    Clojurescript • Namespacesare a huge improvement over js/ coffeescript - makes client side development feel a lot less like wandering through a dark Malaysian jungle
  • 45.
    Clojurescript • Namespacesare 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 • Namespacesare 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 • Namespacesare 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 • Namespacesare 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/
  • 49.
  • 50.
  • 51.
    Noir-async • Nettywrapper • Noir-async/aleph/lamina make sockets simple
  • 52.
    Noir-async • Nettywrapper • Noir-async/aleph/lamina make sockets simple • Lamina event channel
  • 53.
    Noir-async • Netty wrapper • Noir-async/aleph/lamina make sockets simple • Lamina event channel • overtone/at-at for efficient short term scheduling
  • 54.
    Noir-async • Netty wrapper • Noir-async/aleph/lamina make sockets simple • Lamina event channel • overtone/at-at for efficient short term scheduling • clj-time for date/time handling
  • 55.
  • 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
  • 58.
  • 59.
    Deployment • leinuberjar gotchas - specify :main and :keep-non- project-classes true in project.clj. specify (:gen-class) and require all views in server.clj
  • 60.
    Deployment • leinuberjar 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 • leinuberjar 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 • leinuberjar 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
  • 63.
  • 64.
    Drawbacks of pureclojure • 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!
  • 65.
  • 66.
    Next steps •DB integration
  • 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!