Slide 1

Slide 1 text

Clojure for Rubyists Colin Jones / 8th Light @trptcolin

Slide 2

Slide 2 text

Big picture A Lisp for functional programming on the JVM

Slide 3

Slide 3 text

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 ) )

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

Clojure order of operations table

Slide 7

Slide 7 text

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.

Slide 8

Slide 8 text

Macros: real ultimate power nice APIs over the top of functions runtime performance improvements custom control flow constructs new language features

Slide 9

Slide 9 text

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 )

Slide 10

Slide 10 text

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 )

Slide 11

Slide 11 text

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 ]

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

Controlled mutation Atoms: atomic Refs: coordinated and atomic (STM) Agents: asynchronous Vars: thread-local (dynamic bindings)

Slide 15

Slide 15 text

JVM GC JIT memory model tools (profiling, web servers, etc.) libraries

Slide 16

Slide 16 text

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 " ) )

Slide 17

Slide 17 text

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 ) ) ; } }

Slide 18

Slide 18 text

BONUS TIME!

Slide 19

Slide 19 text

What do objects give us? namespacing functions encapsulation data containers state change polymorphism inheritance

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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.

Slide 23

Slide 23 text

External Dependencies Leiningen "for automating Clojure projects without setting your hair on fire."

Slide 24

Slide 24 text

Unbiased opinions

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

Community Friendly Helpful Awesome

Slide 27

Slide 27 text

Oh, and one more thing... a production-ready variant on the JavaScript runtime (ClojureScript)

Slide 28

Slide 28 text

Thanks! Colin Jones / 8th Light @trptcolin