Clojure in the Wild Web 7 Reflections Ignacio Thayer, - - PowerPoint PPT Presentation

clojure in the wild web
SMART_READER_LITE
LIVE PREVIEW

Clojure in the Wild Web 7 Reflections Ignacio Thayer, - - PowerPoint PPT Presentation

Clojure in the Wild Web 7 Reflections Ignacio Thayer, ReadyForZero.com Summer 2010: The Beginning 2 person team Validation is key No communication overhead "No conventions required" 1: Frameworks: easy things are


slide-1
SLIDE 1

Clojure in the Wild Web

Ignacio Thayer, ReadyForZero.com 7 Reflections

slide-2
SLIDE 2
  • 2 person team
  • Validation is key
  • No communication overhead

○ "No conventions required"

Summer 2010: The Beginning

slide-3
SLIDE 3
  • ... And some complicated things are too
  • Up and running
  • Relatively simple at the start
  • Their advantages run out
  • Strong in areas that Clojure is currently weak

1: Frameworks: easy things are easy

slide-4
SLIDE 4
  • Django
  • jQuery Soup
  • Common bug patterns emerged

Early 2011: The Launch

slide-5
SLIDE 5

Non-existent key

  • Javascript "undefined"
  • Python's "has no attribute"
  • Clojure's missing key in map

2: "The Most Common Bug"

slide-6
SLIDE 6

(defconstrainedfn create-client "Creates Billpay client ..." [user params] [(-> params :first-name string?) (-> params :last-name string?) (-> params :dob date-string?) (-> params :address1 string?) (-> params :address2 ((optional string?))) => valid-response?] ;; do-stuff)

Contracts

2: "The Most Common Bug"

slide-7
SLIDE 7

# (def x {:y {:z 1}}]) # (-> x :y :z) 1 # (-> x :y :q) nil # (-!> x :y :q) ;; "(-!> (-!> x :y) :q) is nil!"

Checked threading

2: "The Most Common Bug"

slide-8
SLIDE 8

Began using Clojure

  • Initially for analysis
  • REPL sold it

3 months after launch

slide-9
SLIDE 9

In general

  • Build code up
  • Real data

What's different?

3: The Clojure REPL is a delight

slide-10
SLIDE 10

# (map :date_joined users) [2012-01-02 2012-01-03 ...] # (filter after-xmas? (map :date_joined users)) [2012-12-26 ...] # (count (filter after-xmas? (map :date_joined users)) 1291

Composable syntax

3: The Clojure REPL is a delight

slide-11
SLIDE 11

Concatenative Programming

Threading (->)

# (-> user (assoc :logins (get-logins user)) (assoc :balance (get-balance user))) {:id 1 :email "..." :logins [1 3 5] :balance 123.0} 3: The Clojure REPL is a delight

slide-12
SLIDE 12

Concatenative Programming

Thrush (->>)

# (->> users count) 1000 # (->> users (take 5) (map println)) ... # (->> users (map :date_joined) (take 5) (map println)) .... # (->> users (map :date_joined) (filter after-xmas?)) 3: The Clojure REPL is a delight

slide-13
SLIDE 13

Thinking ahead

  • Next Milestones
  • Hiring

Series A

slide-14
SLIDE 14
  • Noir
  • Korma
  • Postgres
  • Mongo (analytics only)
  • Backbone.js

Webapp in Clojure

slide-15
SLIDE 15
  • Succinct nor verbose is comprehensible
  • Use the expressiveness of the language to

promote comprehension

  • Keep namespaces clean

4: Code as Communication

slide-16
SLIDE 16

(defendpoint mobile1 [:post "/login"] (out-example examples/login) (in {:email string? :password string?}) (out {:success not-nil?}) (return {:as creds} ....))

DSLs: Web endpoints

4: Code as Communication

slide-17
SLIDE 17

(defnotification :successful-payment (email {:subject "Your payment has arrived" :template "rfz_plus_successful_payment"}) (web {:text "Your payment of {{amt}} to {{dest}}..."}) (mobile-push {:text "Payment to {{dest}} delivered." :location "rfz://tabs/payments"}) (limit 1 :by :id :ever))

DSL: User Notifications

4: Code as Communication

slide-18
SLIDE 18

Why should there be privileged syntax?

# (defn+ mult [x] (* x 3)) # (if+ (even? x) (/ 2 x) (-> x (* 3) (+ 1)) # (let+ [x 3] (println x))

Same level as the language

4: Code as Communication

slide-19
SLIDE 19
  • Code should look like the code around it
  • Be humble, agree to them as a team, and

enforce them (☃ x)

5: Humility and convention

slide-20
SLIDE 20
  • Think in pipelines with ->
  • Prefer maps to tuples or vectors
  • Keep them flat
  • Use built-in functions

6: Maps

slide-21
SLIDE 21

7: Skip the trickiest code

Concurrency

  • pmap
  • pvalues

(let [[l b] (pvalues (get-logins) (get-balance))] (-> user (assoc :logins l) (assoc :balance b)

slide-22
SLIDE 22
  • Tricky made simple
  • Convention and culture
  • Expressiveness

nacho@readyforzero.com

Clojure is great for non-trivial apps