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

Clojure for Rubyists

Colin Jones
December 03, 2013

Clojure for Rubyists

A lightning talk given at ChicagoRuby, December 3, 2013

Colin Jones

December 03, 2013
Tweet

More Decks by Colin Jones

Other Decks in Programming

Transcript

  1. Lisp ( v e r b a r g u

    m e n t - 1 a r g u m e n t - 2 a r g u m e n t - 3 ) ( v e r b ) ( ( m a k e - v e r b 2 3 ) ( c o m p u t e - s o m e t h i n g 1 ) )
  2. Lisp Order of operations: womp womp ( x | |

    y & & z ) = = ( x o r y a n d z ) # = > ? ? ?
  3. Lisp Order of operations: womp womp ( x | |

    ( y & & z ) ) = = ( ( x o r y ) a n d z ) # = > ? ? ?
  4. Macros: safer metaprogramming code as data (not strings): no parser

    required! macroexpansion is at compile time (not runtime) eval still exists. but please don't use it.
  5. Macros: real ultimate power nice APIs over the top of

    functions runtime performance improvements custom control flow constructs new language features
  6. Functional Programming ( 0 . . . 1 0 )

    . m a p { | x | x * x } # = > [ 0 , 1 , 4 , 9 , 1 6 , 2 5 , 3 6 , 4 9 , 6 4 , 8 1 ] ( m a p ( f n [ x ] ( * x x ) ) ( r a n g e 1 0 ) ) ; = > ( 0 1 4 9 1 6 2 5 3 6 4 9 6 4 8 1 )
  7. Functional Programming d e f s q u a r

    e ( x ) x * x e n d ( 0 . . . 1 0 ) . m a p ( & m e t h o d ( : s q u a r e ) ) # = > [ 0 , 1 , 4 , 9 , 1 6 , 2 5 , 3 6 , 4 9 , 6 4 , 8 1 ] ( d e f n s q u a r e [ x ] ( * x x ) ) ( m a p s q u a r e ( r a n g e 1 0 ) ) ; = > ( 0 1 4 9 1 6 2 5 3 6 4 9 6 4 8 1 )
  8. Functional Programming ( d e f n m a k

    e - a d d e r [ n ] ( f n [ & a d d e n d s ] ( a p p l y + n a d d e n d s ) ) ) ( d e f p l u s - 1 0 ( m a k e - a d d e r 1 0 ) ) ( p l u s - 1 0 1 2 3 ) ; = > 1 6 ( ( j u x t i d e n t i t y s q u a r e ) 5 ) ; = > [ 5 2 5 ]
  9. Immutability by default x = [ : a , :

    b , : c , : d , : e ] y = d o _ s o m e t h i n g ( x ) x = = [ : a , : b , : c , : d , : e ] # = > ? ? ? ( d e f x [ : a : b : c : d : e ] ) ( d e f y ( d o - s o m e t h i n g x ) ) ( = [ : a : b : c : d : e ] x ) ; = > t r u e
  10. Persistent Data Structures ' ( 1 2 3 4 )

    [ 1 2 3 4 ] { : a 1 : b 2 : c 3 } # { : a : c : b } Because copy-on-write is often too expensive
  11. Controlled mutation Atoms: atomic Refs: coordinated and atomic (STM) Agents:

    asynchronous Vars: thread-local (dynamic bindings)
  12. Calling into Java from Clojure ( . l e n

    g t h " o h a i t h e r e " ) ; = > 1 0 ( S y s t e m / g e t P r o p e r t y " o s . n a m e " ) ; = > " M a c O S X " ( d e f n n u l l - o u t p u t - s t r e a m [ ] ( p r o x y [ j a v a . i o . O u t p u t S t r e a m ] [ ] ( w r i t e [ & a r g s ] ) ) ) ( . w r i t e ( n u l l - o u t p u t - s t r e a m ) ( . g e t B y t e s " o h a i t h e r e " ) )
  13. Calling into Clojure from Java i m p o r

    t c l o j u r e . l a n g . R T ; i m p o r t c l o j u r e . l a n g . S y m b o l ; p u b l i c c l a s s R e p l y M a i n { p u b l i c s t a t i c v o i d m a i n ( S t r i n g . . . a r g s ) { S y m b o l n s = S y m b o l . i n t e r n ( " r e p l y . m a i n " ) ; R T . v a r ( " c l o j u r e . c o r e " , " r e q u i r e " ) . i n v o k e ( n s ) ; R T . v a r ( " r e p l y . m a i n " , " - m a i n " ) . a p p l y T o ( R T . s e q ( a r g s ) ) ; } }
  14. What do objects give us? namespacing functions encapsulation data containers

    state change polymorphism inheritance We can still do all of these in Clojure, but they're decoupled
  15. Internal dependencies Where does your code come from? r e

    q u i r e ' p e r s i s t e n c e / t i m e _ w i n d o w s ' c l a s s T i m e W i n d o w s C o n t r o l l e r < A p p l i c a t i o n C o n t r o l l e r # 1 r e s p o n d _ t o : j s o n # 2 d e f i n d e x r a n g e _ s t a r t = p a r a m s [ : r a n g e _ s t a r t ] # 3 r a n g e _ e n d = p a r a m s [ : r a n g e _ e n d ] P e r s i s t e n c e : : T i m e W i n d o w s . e n s u r e _ c o v e r s ( r a n g e _ e n d . t o _ i ) # i n t h e r e q u i r e r e s p o n d _ w i t h T i m e W i n d o w . i n _ r a n g e ( r a n g e _ s t a r t , r a n g e _ e n d ) # 4 , 5 e n d d e f c u r r e n t r e s p o n d _ w i t h T i m e W i n d o w . f o r _ d a t e ( D a t e . t o d a y ) # 6 , 7 e n d e n d
  16. Internal dependencies Explicit over implicit ( n s d o

    p p l e r . d a s h b o a r d . d a s h b o a r d - c o n t r o l l e r ( : r e q u i r e [ c o m p o j u r e . c o r e : r e f e r : a l l ] [ d o p p l e r . t o p i c . t o p i c : r e f e r [ f i n d - a l l - t o p i c s ] ] [ j o o d o . v i e w s : r e f e r [ r e n d e r - t e m p l a t e ] ] ) ) ( d e f n - d o - d a s h b o a r d [ ] ( r e n d e r - t e m p l a t e " d a s h b o a r d / d a s h b o a r d " : t o p i c s ( f i n d - a l l - t o p i c s ) ) ) ( d e f r o u t e s d a s h b o a r d - c o n t r o l l e r ( G E T " / " [ ] ( d o - d a s h b o a r d ) ) ) The language enforces this structure.
  17. Community core.async: Go-style CSP (Communicating Sequential Processes) core.logic: logic programming

    core.match: pattern matching core.matrix: array programming core.typed: gradual typing cascalog: datalog-like query language for Hadoop riemann: network monitoring system overtone: collaborative programmable music incanter: R-like statistics / graphics environment