Slide 1

Slide 1 text

'GETTING' CLOJURE '(PARENTHESES ARE JUST HUGS FOR YOUR CODE) Created by / Jason Lewis Gary Trakhman

Slide 2

Slide 2 text

Javascript f u n c t i o n ( ) { r e t u r n 5 ; } FUNCTIONS

Slide 3

Slide 3 text

Put some parens around it, kill the braces ( f u n c t i o n ( ) r e t u r n 5 ; )

Slide 4

Slide 4 text

Change 'function' to 'fn', makes args into a vector ( f n [ ] r e t u r n 5 ; )

Slide 5

Slide 5 text

Kill the 'return', last thing's always returned. Welcome to Clojure. ( f n [ ] 5 )

Slide 6

Slide 6 text

Move the left parenthesis over a bit more... Done. s o m e F u n c t i o n ( a r g 1 , a r g 2 , a r g 3 ) ; ( s o m e F u n c t i o n a r g 1 a r g 2 a r g 3 ) CALLING STUFF

Slide 7

Slide 7 text

THIS ISN'T AN ACCIDENT Javascript is 'Lisp in C's Clothing' Says Crockford: http://www.crockford.com/javascript/javascript.html

Slide 8

Slide 8 text

PUT ANOTHER WAY... Q: Why do you think we've gotten so much mileage out of javascript? A: Lisp is very powerful, and it will never die

Slide 9

Slide 9 text

Should look familiar Don't freak out DON'T FREAK OUT { : k e y 1 5 , : k e y 2 n i l } [ 1 2 3 4 " f i v e " ] [ 1 [ 2 ] # { 3 } { 4 4 } ( c o n s t a n t l y 5 ) ] = > ( r a n g e 1 0 ) ( 0 1 2 3 4 5 6 7 8 9 ) = > ( t a k e 1 1 ( r a n g e ) ) ( 0 1 2 3 4 5 6 7 8 9 1 0 ) = > ( l a s t ( r a n g e ) ) ; ; H o p e y o u d o n ' t m i n d w a i t i n g a l o n g t i m e . DATA

Slide 10

Slide 10 text

Evals to... ; ; s e m i c o l o n s a r e c o m m e n t s , c o m m a s a r e i g n o r e d , ; ; c h e c k o u t t h i s w e i r d h a s h - m a p { : a - k e y w o r d 5 , " a s t r i n g k e y " " a s t r i n g v a l u e " , [ " a " : v e c t o r " a c t i n g " : a s [ : a : c o m p o u n d ] " k e y " ] ( f n [ ] " a n o - a r g f u n c t i o n t h a t r e t u r n s t h i s m u l t i - l i n e s t r i n g , t h e f u n c t i o n i t s e l f i s t h e v a l u e " ) , + ' ( f u n c t i o n s c a n b e k e y s t o o , a n d w h e n y o u q u o t e s y m b o l s , y o u j u s t h a v e s y m b o l s , n o t w h a t t h e y r e p r e s e n t ) } { : a - k e y w o r d 5 , " a s t r i n g k e y " " a s t r i n g v a l u e " , [ " a " : v e c t o r " a c t i n g " : a s [ : a : c o m p o u n d ] " k e y " ] # < u s e r $ e v a l 3 3 1 $ f n _ _ 3 3 2 u s e r $ e v a l 3 3 1 $ f n _ _ 3 3 2 @ a 5 8 5 e f > , # < c o r e $ _ P L U S _ c l o j u r e . c o r e $ _ P L U S _ @ 2 0 a 1 2 d 8 f > ( f u n c t i o n s c a n b e k e y s t o o a n d w h e n y o u q u o t e s y m b o l s y o u j u s t h a v e s y m b o l s n o t w h a t t h e y r e p r e s e n t ) } EVERYTHING IS DATA

Slide 11

Slide 11 text

ANYTHING CAN BE A KEY, BECAUSE 1. Every object is also a 'value' 2. Values have true equality 3. Values Never Change (Immutability) 4. Without immutability, objects are just buckets in memory ...have you ever trusted a bucket with no values?

Slide 12

Slide 12 text

Q: Why is this big news? A: I can write code and rest assured that other parts of my program can't change the data that I'm working on. Q: But I thought every program is simply a short-lived http request handler that talks to a database? We just throw the program state out after every request! A: Well, that's one way to do it.

Slide 13

Slide 13 text

http://www.ibm.com/developerworks/library/wa-aj- multitier2/

Slide 14

Slide 14 text

NODE.JS... http://www.andrerodrigues.me/isel- workshop/intro.html#/24

Slide 15

Slide 15 text

NODE.JS... IS NOTHING NEW We can write our own loops Node.js assumes threaded programming is hard, and throws out the baby with the bath-water Threaded programming is hard without real 'Data' or 'Values' Composition of any sort is simpler with data

Slide 16

Slide 16 text

APPROXIMATING NODE.JS 'Agents' are asynchronous queues, sharing threadpools to do work, storing the last value returned. ( d e f n i n c - l a s t [ v a l ] ( c o n j v a l ( i n c ( l a s t v a l ) ) ) ) ; ; W e m a k e a s e q u e n c e o f 1 0 i n c - l a s t t a s k s , ; ; t h e n f o l l o w - u p w i t h a ' p r i n t l n ' t a s k ( d e f t a s k s ( c o n c a t ( r e p e a t 1 0 i n c - l a s t ) [ ( f n [ v a l ] ( p r i n t l n v a l ) v a l ) ] ) )

Slide 17

Slide 17 text

; ; s t a r t s o f f w i t h a v a l u e o f [ 0 ] ( l e t [ a ( a g e n t [ 0 ] ) ] ( d o s e q [ t t a s k s ] ( s e n d a t ) ) ) ; ; p r i n t s : [ 0 1 2 3 4 5 6 7 8 9 1 0 ] Agents are not values, they are mutable references with asynchronous semantics Clojure has other mutable references types, acting as 'containers' for values, for various use cases. Nothing prevents you from making your own.

Slide 18

Slide 18 text

( l e t [ f ( f u t u r e ( d o - a - b u n c h - o f - s t u f f ) ) ] ; ; i n a n o t h e r t h r e a d ( d o - s t u f f - i n - t h i s - t h r e a d ) ; ; r e t u r n t h e v a l u e i n f , b l o c k i n g i f i t ' s n o t f i n i s h e d ( d e r e f f ) ) MORE! Basically, Clojure promotes your ability to do whatever you want, by simplifying things to their bare essence.

Slide 19

Slide 19 text

WHAT WE REALLY WANT Tools that let us 1. Compose Systems 2. Change our minds 3. Re-use components in different contexts, processes, servers, etc.. Data/Values give us the ability to decouple things easily

Slide 20

Slide 20 text

'(code is data) BRAINSPLODE

Slide 21

Slide 21 text

Read-Eval-Print-Loop ( c l a s s ( r e a d - s t r i n g " ( + 1 2 ) " ) ) ; ; c l o j u r e . l a n g . P e r s i s t e n t L i s t ( m a p c l a s s ( r e a d - s t r i n g " ( + 1 2 ) " ) ) ; ; ( c l o j u r e . l a n g . S y m b o l j a v a . l a n g . L o n g j a v a . l a n g . L o n g ) R-E-P-L 1. Read: (read-string "(+ 1 2)") => '(+ 1 2) 2. Eval: (eval '(+ 1 2)) => 3 3. What if there's something in the middle?

Slide 22

Slide 22 text

This is only the beginning ( d e f n o n l y - e v e n ! [ v a l ] ( i f ( a n d ( i n t e g e r ? v a l ) ( o d d ? v a l ) ) ( i n c v a l ) v a l ) ) ( m a p o n l y - e v e n ! ( r e a d - s t r i n g " ( + 1 2 ) " ) ) ; ; ' ( + 2 2 ) ( e v a l ( m a p o n l y - e v e n ! ( r e a d - s t r i n g " ( + 1 2 ) " ) ) ) ; ; 4

Slide 23

Slide 23 text

Everybody likes chaining, right? How is this implemented? Is this reusable? $ ( " # p 1 " ) . c s s ( " c o l o r " , " r e d " ) . s l i d e U p ( 2 0 0 0 ) . s l i d e D o w n ( 2 0 0 0 ) ;

Slide 24

Slide 24 text

What if, as a library author, you could just not write that fluent interface code at all? ( u s e ' c l o j u r e . s t r i n g ) ; ; T h e s e a r e e q u i v a l e n t ( m a p t r i m ( s p l i t ( u p p e r - c a s e " h o l a , w o r l d " ) # " , " ) ) ; ; ( " H O L A " " W O R L D " ) ( - > " h o l a , w o r l d " u p p e r - c a s e ( s p l i t # " , " ) ( - > > ( m a p t r i m ) ) ) ; ; ( " H O L A " " W O R L D " )

Slide 25

Slide 25 text

Really useful when you're doing a lot of collection operations, filtering, etc. ( - > > ( r a n g e ) ( f i l t e r e v e n ? ) ( m a p ( p a r t i a l * 2 ) ) ( t a k e 1 0 ) ( i n t o [ ] ) ) ; ; [ 0 4 8 1 2 1 6 2 0 2 4 2 8 3 2 3 6 ] ; ; v e r s u s ( i n t o [ ] ( t a k e 1 0 ( m a p ( p a r t i a l * 2 ) ( f i l t e r e v e n ? ( r a n g e ) ) ) ) ) 1. I find the flat one easier to think about. 2. Semantically equivalent. 3. No burden on implementing code. Functions don't care about how they're used. Giving the user choices is more effective with more powerful languages. Leads to simple, composable libraries.

Slide 26

Slide 26 text

Let's look at a real one. ( d e f m a c r o l a z y - s e q " T a k e s a b o d y o f e x p r e s s i o n s t h a t r e t u r n s a n I S e q o r n i l , a n d y i e l d s a S e q a b l e o b j e c t t h a t w i l l i n v o k e t h e b o d y o n l y t h e f i r s t t i m e s e q i s c a l l e d , a n d w i l l c a c h e t h e r e s u l t a n d r e t u r n i t o n a l l s u b s e q u e n t s e q c a l l s . S e e a l s o - r e a l i z e d ? " { : a d d e d " 1 . 0 " } [ & b o d y ] ( l i s t ' n e w ' c l o j u r e . l a n g . L a z y S e q ( l i s t * ' ^ { : o n c e t r u e } f n * [ ] b o d y ) ) ) ; ; s i m p l y r e t u r n s a l i s t , a l l o c a t e s a J a v a o b j e c t ( L a z y S e q ) a n d w r a p s ; ; y o u r e x p r e s s i o n s i n a f u n c t i o n ( m a c r o e x p a n d - 1 ' ( l a z y - s e q A N Y T H I N G 1 A N Y T H I N G 2 ) ) ; ; ' ( n e w c l o j u r e . l a n g . L a z y S e q ( f n * [ ] A N Y T H I N G 1 A N Y T H I N G 2 ) ) MACROS

Slide 27

Slide 27 text

Let's create an infinite sequence representing a square-wave --__--__--__--__ No mutable variables ( d e f n s q u a r e - w a v e " t i s t h e p e r i o d f o r a h a l f - c y c l e " [ t ] ( l e t f n [ ( o s c [ c u r - v a l u e s o - f a r ] ( l e t [ s o - f a r ( m o d s o - f a r t ) n e x t - v a l ( i f ( z e r o ? s o - f a r ) ( - c u r - v a l u e ) c u r - v a l u e ) ] ( c o n s n e x t - v a l ( l a z y - s e q ( o s c n e x t - v a l ( i n c s o - f a r ) ) ) ) ) ) ] ( o s c 1 0 ) ) ) ( t a k e 1 0 ( s q u a r e - w a v e 3 ) ) ; ; ( - 1 - 1 - 1 1 1 1 - 1 - 1 - 1 1 )

Slide 28

Slide 28 text

CALL TO ACTION 1. Learn Clojure 2. Build cool things 3. Screencasts! (You ruby guys really know how to make good screencasts)

Slide 29

Slide 29 text

DEMO TIME CLOJURE ON THE WEB Now clone this: https://github.com/canweriotnow/bohjure

Slide 30

Slide 30 text

RESOURCES Clojure: http://clojure.org Fun Exercises: http://www.4clojure.com Cheatsheets: http://clojure.org/cheatsheet Building: https://github.com/technomancy/leiningen Insight: http://www.youtube.com/user/ClojureTV Community docs: http://clojuredocs.org Blogs: http://planet.clojure.in Light Table: http://www.lighttable.com this doc: http://gtrak.github.io/bohconf.clojure

Slide 31

Slide 31 text

MORE DEMO TIME

Slide 32

Slide 32 text

THANKS FOR COMING! WE ARE: Gary Trakhman Software Engineer at @gtrakGT Revelytix, Inc. Jason Lewis CTO at @canweriotnow An Estuary, LLC