Upgrade to Pro — share decks privately, control downloads, hide ads and more …

'Getting' Clojure

'Getting' Clojure

'(parentheses are just hugs for your code)

Jason Lewis

July 19, 2013
Tweet

More Decks by Jason Lewis

Other Decks in Programming

Transcript

  1. Javascript f u n c t i o n (

    ) { r e t u r n 5 ; } FUNCTIONS
  2. Put some parens around it, kill the braces ( f

    u n c t i o n ( ) r e t u r n 5 ; )
  3. 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
  4. THIS ISN'T AN ACCIDENT Javascript is 'Lisp in C's Clothing'

    Says Crockford: http://www.crockford.com/javascript/javascript.html
  5. 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
  6. 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
  7. 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
  8. 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?
  9. 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.
  10. 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
  11. 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 ) ] ) )
  12. ; ; 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.
  13. ( 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.
  14. 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
  15. 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?
  16. 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
  17. 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 ) ;
  18. 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 " )
  19. 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.
  20. 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
  21. 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 )
  22. CALL TO ACTION 1. Learn Clojure 2. Build cool things

    3. Screencasts! (You ruby guys really know how to make good screencasts)
  23. 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
  24. THANKS FOR COMING! WE ARE: Gary Trakhman Software Engineer at

    @gtrakGT Revelytix, Inc. Jason Lewis CTO at @canweriotnow An Estuary, LLC