bryan maass

bcm@bryans-MBP.gateway

Clojure Intro. + CLJS Fiddle

Bryan Maass

Twitter @escherize
Telegram @escherize
Website escherize.com
Clojurians Slack escherize

Clojure intro

"It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures."

—Alan Perlis

Basic Data Types

Some basic Atomic Data Types that we work with in Clojure:

12345675432           ;; Integers

1.234                 ;; Doubles (as in java)

1.234M                ;; BigDecimals (as in java)

22/7                  ;; ratios

"Greetings syd-clj"   ;; strings (as in java)

:apple :jelly         ;; keywords

lemon, having-fun?    ;; symbols

\a \b \newline \space ;; characters

nil                   ;; Null

true, false           ;; booleans

#"a*b"                ;; regex patterns

Collection Data Types

It's extremely simple to create hash-tables, lists, and vectors:

'(1 2 3 4)  ;; List

[1 2 3 4]   ;; Vector

#{:a :b :c} ;; Set

{:a 1 :b 2} ;; Hash-map (often called Map)

Syntax

That is the syntax.

Data structures are the code.

To call a function, put it at the beginning of a list.

(range 5)
;;=> (0 1 2 3 4 5)

(map dec [1 2 3])
;;=> (0 1 2)

Not a text-based syntax

Syntax is based on the data structures

Things that require special syntax are all just lists with the operand at the front

Everything is an Expression

Homoiconic

Again, Clojure programs are made up of the same primitives as the data.

Here we define a function called square that takes x as argument and returns x^2.

(defn square [x]
  (* x x))

(square 3)
;; => 9

Macros (aka Compiler Extension)

Clojure allows us to access the code as a datastructure, before it has run. This is possible in string-based languages but way harder, and not often leveraged.

(defmacro infix
  "Use this macro when you pine for the notation of your childhood."
  [infixed]
  (list (second infixed)
        (first infixed)
        (last infixed)))

(infix (1 + 1))
;; => 2

Applied to HTML

With Clojure, we can learn the core functionality once, and reapply it everywhere.

Let's take a look at what this philosophy means for HTML:

Some languages have string munging which you may think is awesome.

(defn hello [s]
  (str "Hello, " s "!" ))

(hello "syd-clj")
;;=> "Hello, syd-clj!"

(defn h2 [s]
  "<h2>" s "</h2>")

(h2 "Wow!")
;;=> "<h2>Wow!</h2>"

Wow!!!

Just kidding! Hiccup:

N.B.: This is just Clojure, we can use any Clojure functions here. No tempting lang necessary. (though there are some for mustache, etc.)

http://hiccup.space/

(def small [:h2#some-id.some-class "Hello!"])

(html small)
;;=> "<h2 id='some-id' class='some-class'>Hello!</h2>"

Hiccup 2:

(defn my-blog [title author posts]
  [:html
   [:head
    [:title title]]
   [:body
    [:h1 title]
    [:h2 "By: " author]
    (for [post posts]
      [:article
       [:h3 (:title post)]
       [:p (:content post)]])]])

(html
 (my-blog "Hello Sydney"
          "Me"
          [{:title "Hi"    :content "there"}
           {:title "Hello" :content "over there"}]))

;;~> blog page html stuff

CLJS Fiddle

How can we enable people to dip into the glory of hiccup, and build font-end apps with it?

React

Facebook front end library to handle drawing updates to the screen using a virtual dom and diffing algorithm. A key technology for react is JSX which is also a pre-processor for turning JSX into valid js.

var NewComponent = React.createClass({
    render: function() {
        return (
                <div>
                {/* Hello world */}
                <div className="awesome" style={{border: '1px solid red'}}>
                <label htmlFor="name">Enter your name: </label>
                <input type="text" id="name" />
                </div>
                <p>Enter your HTML here</p>
                </div>
        );
    }
});

Reagent

Reagent leverages the same React toolchain. But instead of writing views in JSX, we get to use immutable data structures.

Live Reload

"I've spent a lot of time over the years desperately trying to think of a "thing" to change the world. I now know why the search was fruitless – things don't change the world. People change the world by using things. The focus must be on the "using", not the "thing"."

  • Bret Victor
  • Once you try it you can't go back.
  • Worth the pain of setup
  • Immutable programming makes it possible

Figwheel

  • The original way to setup live reload
  • difficult to understand, ymmv.

Boot in CLJS

Still, getting setup is not Easy Enough

Errors along this path can cause fewer people to find the glorious joy of Clojure.

CLJS-in-CLJS

Clojurescript can compile itself.

So now the dream is possible.

CLJS Fiddle

ClojureScript project, idea brought up to me by @gadfly361 (the maintainer of reagent-cookbook).

Lots of help from community!

Parinfer to help newcomers with Lisp editing.

http://cljsfiddle.com/ - Demo!

Created by bryan maass.