All Things Open 2014 - Day 2
Thursday, October 23rd, 2014
Stuart Halloway
Founder/President of Cognitect
Back Dev
Clojure: Simple By Design
Report
Share
Report
Share
1 of 85
Download to read offline
More Related Content
Clojure: Simple By Design
1. Simple by Design:
Clojure
@stuarthalloway
stu@cognitect.com
Copyright Cognitect, Inc.
This presentation is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.
See http://creativecommons.org/licenses/by-nc-sa/3.0/us/
17. Function Definition
define a fn fn name
docstring
(defn greet!
"Returns a friendly greeting"!
[your-name]!
(str "Hello, " your-name))
arguments
fn body
18. …Still Just Data
symbol symbol
string
(defn greet!
"Returns a friendly greeting"!
[your-name]!
(str "Hello, " your-name))
vector
list
19. Complexities Avoided
lots of syntax to learn
ordering dependencies
operator precedence
code over data bias
tedious metaprogramming
31. If you have more things
than names, your design
is broken.
32. Clojure’s Simplicity
Me 182
nachos
184
reference
value
pure
function
succession function new value
33. Values and References
(defprotocol Nachos!
(yum [_] "eat some nachos"))!
!
(defrecord Person [name lbs]!
Nachos!
(yum [person]!
(update-in person [:lbs] + 2)))!
!
(def me (atom (->Person "Stu" 182)))!
!
(def me-before @me)!
!
(swap! me yum)!
!
(def me-after @me)
34. Values and References
(defprotocol Nachos!
(yum [_] "eat some nachos"))!
!
(defrecord Person [name lbs]!
Nachos!
(yum [person]!
functional
(update-in person [:lbs] + 2)))!
!
(def me (atom (->Person "Stu" 182)))!
!
(def me-before @me)!
!
(swap! me yum)!
!
(def me-after @me)
35. Values and References
(defprotocol Nachos!
(yum [_] "eat some nachos"))!
!
(defrecord Person [name lbs]!
Nachos!
(yum [person]!
(update-in person [:lbs] + 2)))!
!
(def me (atom (->Person "Stu" 182)))!
!
(def me-before @me)!
!
(swap! me yum)!
!
(def me-after @me)
update
semantics
36. Values and References
(defprotocol Nachos!
(yum [_] "eat some nachos"))!
!
(defrecord Person [name lbs]!
Nachos!
(yum [person]!
(update-in person [:lbs] + 2)))!
!
(def me (atom (->Person "Stu" 182)))!
!
(def me-before @me)!
!
(swap! me yum)!
!
(def me-after @me)
multiple
point-in-time
values
37. Complexities Avoided
incidental complexity temporal reasoning
single-threading
locking
defensive copying
setter methods
String vs. StringBuilder vs. StringBuffer
note (again!) that these are all combinatorial
42. // From Apache Commons Lang, http://commons.apache.org/lang/!
public static int indexOfAny(String str, char[] searchChars) {!
if (isEmpty(str) || ArrayUtils.isEmpty(searchChars)) {!
return -1;!
}!
for (int i = 0; i < str.length(); i++) {!
char ch = str.charAt(i);!
for (int j = 0; j < searchChars.length; j++) {!
if (searchChars[j] == ch) {!
return i;!
}!
}!
}!
return -1;!
}
indexOfAny Impl
43. public static int indexOfAny(String str, char[] searchChars) {!
when (searchChars)!
for (int i = 0; i < str.length(); i++) {!
char ch = str.charAt(i);!
for (int j = 0; j < searchChars.length; j++) {!
if (searchChars[j] == ch) {!
return i;!
}!
}!
}!
}!
}
- Corner Cases
44. indexOfAny(str, searchChars) {!
when (searchChars)!
for (i = 0; i < str.length(); i++) {!
ch = str.charAt(i);!
for (j = 0; j < searchChars.length; j++) {!
if (searchChars[j] == ch) {!
return i;!
}!
}!
}!
}!
}
- Type Decls
45. indexOfAny(str, searchChars) {!
when (searchChars)!
for (i = 0; i < str.length(); i++) {!
ch = str.charAt(i); !
when searchChars(ch) i;!
}!
}!
}
+ When Clause
46. indexOfAny(str, searchChars) {!
when (searchChars)!
for ([i, ch] in indexed(str)) {!
when searchChars(ch) i;!
}!
}!
}
+ Comprehension
49. imperative functional
searches strings searches any sequence
matches characters matches any predicate
returns first match returns lazy seq of all
matches
56. PICOS Everywhere
collections
directories
files
XML
JSON
result sets
web requests
web responses
sessions
configuration
metrics
logs
57. Consuming JSON
What actors are in more than one movie
currently topping the box office charts?
http://developer.rottentomatoes.com/docs/
read/json/v10/Box_Office_Movies
58. Consuming JSON
find the JSON input!
download it!
parse json!
walk the movies!
accumulating cast!
extract actor name!
get frequencies!
sort by highest frequency
http://developer.rottentomatoes.com/docs/
read/json/v10/Box_Office_Movies
61. PICOs for Big Data
(defn my-data-2 []
(->>
(pig/load-tsv "input.tsv")
(pig/map (fn [[a b c]]
{:sum (+ (Integer/valueOf a) (Integer/valueOf b))
:name c}))
(pig/filter (fn [{:keys [sum]}]
(< sum 5)))))
!
=> (pig/dump (my-data-2))
[{:sum 3, :name "foo"}]
https://github.com/Netflix/PigPen
62. Me 182
nachos
184
reference
value
pure
function
new value
succession
function
63. Me t-1
transact
t-2
connection
db value
pure
function
new db value
ACID
64. ACID data of record
persistent data structures: “scm for business data”
distributed, componentized, read scalable & elastic
information and logic as PICOs in any peer process
65. Connect and Query
Connection conn = !
connect("datomic:ddb://us-east-1/mb/mbrainz");!
!
!
Database db = conn.db();!
!
!
Set results = q(..., db);!
!
!
Set crossDbResults = q(..., db1, db2);!
!
!
Entity e = db.entity(42);
66. Connect and Query
Connection conn = !
connect("datomic:ddb://us-east-1/mb/mbrainz");!
!
!
Database db = conn.db();!
!
!
Set results = q(..., db);!
!
!
Set crossDbResults = q(..., db1, db2);!
!
!
Entity e = db.entity(42);
database is a lazily
realized value, available
to all peers equally