SlideShare una empresa de Scribd logo
1 de 21
Thinking in Clojure




                      Mar 29, 2013
Jumping in
   We’ll quickly go through Clojure’s data types, some
    basic functions, and basic syntax
   Then we’ll get to the good stuff!




                                                          2
Clojure’s data types
   Clojure has:
       Lists, enclosed in parentheses and separated by spaces or commas:
        (a 17 "Plenty of parentheses")
       Functions: (fn [x] (first(rest x))
       Numbers: All Java numeric types, plus ratios and exact decimals:
        5, 5.3, 5.3e30, 077, 0xFF00FF, 3/5, 5.3M
       Strings, as in Java: "She said "Hello""
       Characters: a, 5, n, newline, tab, etc.
       The booleans true and false
       nil, equivalent to Java’s null
       Symbols, which stand for themselves: :meadow, :CIS-554
       Vectors: [5 :a "hi!"]
       Maps: {:one 1, :two 2}
       Sets: #{:prolog :clojure}
                                                                            3
Some basic Clojure functions
   Syntax of a function call: (function args)
   Basic operations—sequences (seq) are lists, sets, maps, vectors:
     
        (quote arg) or 'arg, to keep arg from being evaluated
        (first seq) is the first element in the sequence (or nil)
        (rest seq) is what remains when the first element is removed (or nil)
        (cons arg seq) returns a new sequence with arg as its first element
        (= args) tests whether its args are equal
        (empty? seq), (list? seq), (seq? arg), (nil? arg) are more tests
   Basic arithmetic
        (+ args), (- args), (* args), (/ args) , (< args), etc.
   Basic logic
        (and args), (or args), (not arg), (if condition result1 result2)
   Defining values
     
         (def name value) defines the name to be the given value
        (defn name argv value) is shorthand for (def name argv value),
         where argv is a vector

                                                                                 4
Functions and special forms
   The arguments to a function are evaluated before the function is called
        Example: (* 2 (+ 3 4))
         The function * is called with the arguments 2 and 7

   A special form looks just like a function, but it gets its arguments
    unevaluated
        The special form itself decides when and whether to evaluate its arguments
        quote does not evaluate its argument
        if evaluates its first argument, then decides which of the second and third
         arguments to evaluate

   Clojure allows you to define your own special forms
        This means you can define your own control structures




                                                                                       5
A typical Clojure function
   (defn first-double-letter
        "Returns the first doubled letter in a string, or nil."
        [s]
        (if (< (count s) 2)
            nil
            (if (= (first s) (second s))
                (first s)
                (first-double-letter (rest s)) ) ) )

   user=> (first-double-letter "Pennsylvania")
    n
    user=> (first-double-letter '(1 2 3 4 3 5 5 4 6))
    5




                                                                  6
It’s easier with cond
   cond is an if … then … else if … then … else … construct:
    (cond test1 result1 test2 result2 … testN resultN)
      It requires an even number of parameters (one result for each test)

      The symbol :else may be used as the last test



   (defn first-double-letter
        "Returns the first doubled letter in a string, or nil."
        [s]
        (cond (< (count s) 2)   nil
              (= (first s) (second s)) (first s)
              :else (first-double-letter (rest s)) ) )

   user=> (first-double-letter "Pennsylvania")
    n
    user=> (first-double-letter '(1 2 3 4 3 5 5 4 6))
    5

                                                                             7
It’s all about recursion
   Some rules of doing recursion:
     1.   Handle the base cases directly (without recursion)
     2.   Recur only with a simpler case
     3.   Don’t use global variables
     4.   Don’t “look down” into the recursion—that will just confuse you

   In Clojure you are almost always working with a list or some similar sequence
         Lisp programmers say, “Do something with the head, and recur with the tail”
             Clojure’s terms for “head” and “tail” are “first” and “rest”
             This pretty much covers rules 1 and 2 above
         Clojure doesn’t have global variables
             This covers rule #3 above
         Rule 4 always holds. Think about what you are doing now, not what
          some recursive call is doing


                                                                                        8
Functional programming
   Clojure is functional—what does that mean?
       Functions are like functions in math—called with the same arguments,
        they always return the same result
            This means: No “global variables,” no dependence on external values, and no
             side effects!
       Functions are values, or first-class objects
            Functions can be passed as parameters to functions, returned as the value of
             functions, created as needed, stored in data structures, and there are
             operations on functions that produce new functions
            The “blub paradox” applies—the value added is substantial, but not obvious
             to an imperative or object-oriented programmer
       Data is immutable (like strings in Java)
            Clojure’s data structures are designed to make this efficient
         
             Immutable data greatly simplifies concurrent programming
            Because data is immutable, loops are unnecessary (use recursion instead!)

                                                                                            9
Costs and benefits
   Costs of functional programming
        It’s weird and unfamiliar
        How can you do anything without objects, mutable variables, or loops?
              (Loops are used primarily to change the values of things)
        As a manager, functional programmers are hard to find (and expensive!)
        Clojure, and Lisp dialects generally, have too many parentheses!
   Benefits of functional programs
        Easier to write correct programs
              “Yeah, right!” – “No, really! All data is local and immutable.”
        Easier to write unit tests, because function values depend only on inputs
        Much easier to write concurrent programs
        Operations on collections make code simpler and more concise
        The simpler foundation means less syntax and fewer special cases
        Some operations, such as equality testing, are really fast
   But it’s still weird!
                                                                                     10
Easier to write correct programs
   Programs are easier to write when all data is local
        When relevant values can be changed elsewhere in the program—possibly in
         many places—it’s harder to see all the connections
        Functions in a functional language get all relevant input from the parameter list

   Unit testing is easier, because there are no dependencies on functions that
    may or may not have been called previously
        There is no need for a setUp method

   Functional programming supports powerful operations on sequences
        The imperative and object-oriented programming styles have been characterized
         as “word by word” programming
             Some sequence operations, such as membership testing, are provided for you
        In a functional language, any function can be a sequence operation


                                                                                             11
The problem of state
   Nonfunctional programming language are “stateful” or “have state”
        The state of a program is given by (1) the values of all the variables throughout the
         program, and (2) the current locus of execution
        That can be a huge amount of information to keep track of!
        Object-oriented programmers try to control complexity by having objects be
         responsible for their own state, and “loosely coupled” (not very dependent on)
         other objects
   Methods often have “side effects,” that is, they modify state

   Functional languages try to avoid having state at all
        This isn’t always easy
   Purely functional languages cannot have side effects
        Since I/O is a side effect, this is an even more difficult restriction




                                                                                             12
Maintaining state, functionally
   Sometimes you just need state
        Consider an adventure game
             You need to keep track of where you are, where other objects are, what you are
              holding, which paths are blocked or open, etc.—this is your state
             You do not need to keep track of permanent, immutable data; for example, most paths
              between rooms are fixed and unchanging—this isn’t part of the state
   In a functional program, a “state” is just an immutable (and usually just one)
    data item
        The data item can be quite complex, such as a dictionary
        States are immutable, but you can always create a “new” state that is a variation
         of a given state
             With carefully designed data structures, not as much storage is required as you might
              expect
        So the functional solution to maintaining state is: Pass one state into a function,
         get a new (and different) state back!



                                                                                                      13
Clojure’s I/O compromise
   A purely functional program has no side effects
        I/O is a side effect
        Therefore: A purely functional program cannot do I/O!
   In Clojure, all functions return a value
        (print args) and (println args) return nil
   Clojure allows side effects in two well-defined places:
        (do args) evaluates all its arguments in order, but returns only the value of the last one
        When a function (fn argv args) is called, the arguments are evaluated in order, but only
         the last value is returned
   Example:
        (defn powers "Computes cube and square" []
             (def n (read))
             (println (* n n n))
             (println (* n n))
             n)


                                                                                                      14
Lists are immutable
Here is a typical list:

    my-list           A      B         C

                  w
Here is
(cons 'w my-list)

Here is (rest my-list)
Notice that my-list remains unchanged
Vectors, hash maps, sorted maps, hash sets, and sorted sets
are similarly immutable
                                                              15
Functions are just values
   user=> (cons 'w '(a b c))
    (w a b c)
   user=> (defn swap-args [f x y] (f y x))
    #'user/swap-args
   user=> (swap-args cons '(a b c) 'w)
    (w a b c)

   user=> (defn apply-n-times [f x n]
         "Apply f to x, n times: f(f(f..(n)...))"
         (if (zero? n)
             x
             (apply-n-times f (f x) (dec n)) ) )
    #'user/apply-n-times
   user=> (apply-n-times (fn [x] (* 2 x)) 1 10)
    1024

                                                    16
Collatz, the hard way
   Definition:
       collatz(1) = 1
        collatz(n) = collatz(n / 2) if n is even
        collatz(n) = collatz(3 * n + 1)

   user=> (defn collatz [n]
        (let [ do-even (fn [n] (collatz (/ n 2)))
               do-odd   (fn [n] (collatz (inc (* 3 n)))) ]
            (print n " ")
            (if (= n 1) 1
            (if (even? n) (do-even n) (do-odd n)) ) ) )
   #'user/collatz
    user=> (collatz 7)
    7 22 11 34 17 52              26   13    40    20   10   5   16   8   4   2   1   1



                                                                                          17
map, filter, and reduce
   Here are three powerful functions you will find in almost any
    functional programming language
       map – apply a function to every element of a sequence, returning a
        sequence of results
            user=> (map even? '(3 1 4 1 6))
            (false false true false true)
       filter – apply a predicate to every element of a sequence, returning a
        sequence of those that satisfy the predicate
         
             user=> (filter even? '(3 1 4 1 6))
            (4 6)
       reduce – use a function to reduce a sequence to a single value
            user=> (reduce * '(3 1 4 1 6))
            72



                                                                                 18
The real problem with state
   For decades we’ve been dealing with mutable state
   Mutable state + concurrency = nondeterminism
        We use threads and locks and semaphores and so on
              These are complicated, unsafe, and inefficient
   As Herb Sutter points out in The Free Lunch is Over, we have hit a 3 GHz barrier
        Since 2003, computers have not gotten faster
        We still want them faster
        Concurrency is the only solution
   Functional languages, with immutable state, provide a partial solution
   As Martin Odersky points out, you can hide from concurrency for a while yet…but
    not forever
   Important consequences:
        All newer languages are gaining functional and concurrent features
        Older languages, such as Java, are also trying to integrate these features
   “You can run, but you can’t hide!”


                                                                                       19
Oh, and by the way…
   Clojure has
       Infinite sequences
       Lazy sequences
       Exact decimal arithmetic
       Function composition
       Function currying
       Macros
       And lots more

   No version of Lisp has ever become mainstream
       They just get mugged in dark alleys and their ideas stolen!
                                                                      20
The End




          21

Más contenido relacionado

La actualidad más candente

La actualidad más candente (20)

Computer Programming 2
Computer Programming 2 Computer Programming 2
Computer Programming 2
 
Functional programming
Functional programmingFunctional programming
Functional programming
 
PHP- Introduction to Object Oriented PHP
PHP-  Introduction to Object Oriented PHPPHP-  Introduction to Object Oriented PHP
PHP- Introduction to Object Oriented PHP
 
Some basic FP concepts
Some basic FP conceptsSome basic FP concepts
Some basic FP concepts
 
The programming philosophy of jrql
The programming philosophy of jrqlThe programming philosophy of jrql
The programming philosophy of jrql
 
PHP - Introduction to Object Oriented Programming with PHP
PHP -  Introduction to  Object Oriented Programming with PHPPHP -  Introduction to  Object Oriented Programming with PHP
PHP - Introduction to Object Oriented Programming with PHP
 
Lambda Functions in Java 8
Lambda Functions in Java 8Lambda Functions in Java 8
Lambda Functions in Java 8
 
JavaScript OOPS Implimentation
JavaScript OOPS ImplimentationJavaScript OOPS Implimentation
JavaScript OOPS Implimentation
 
Programming picaresque
Programming picaresqueProgramming picaresque
Programming picaresque
 
C++ Programming Course
C++ Programming CourseC++ Programming Course
C++ Programming Course
 
javaopps concepts
javaopps conceptsjavaopps concepts
javaopps concepts
 
Java session4
Java session4Java session4
Java session4
 
Classes, objects and methods
Classes, objects and methodsClasses, objects and methods
Classes, objects and methods
 
Java unit 7
Java unit 7Java unit 7
Java unit 7
 
Java Programming - 04 object oriented in java
Java Programming - 04 object oriented in javaJava Programming - 04 object oriented in java
Java Programming - 04 object oriented in java
 
Polymorphism
PolymorphismPolymorphism
Polymorphism
 
Java for beginners
Java for beginnersJava for beginners
Java for beginners
 
Ocl
OclOcl
Ocl
 
Javascript basic course
Javascript basic courseJavascript basic course
Javascript basic course
 
Object oreinted php | OOPs
Object oreinted php | OOPsObject oreinted php | OOPs
Object oreinted php | OOPs
 

Destacado (12)

481 bb0091
481 bb0091481 bb0091
481 bb0091
 
Introduction to writing algorithms
Introduction to writing algorithmsIntroduction to writing algorithms
Introduction to writing algorithms
 
The best!
The best!The best!
The best!
 
Istqb ctfl syll 2011
Istqb ctfl syll 2011Istqb ctfl syll 2011
Istqb ctfl syll 2011
 
Exp int toc
Exp int tocExp int toc
Exp int toc
 
Berkeley Data Analytics Stack Genel Bakış
Berkeley Data Analytics Stack Genel Bakış Berkeley Data Analytics Stack Genel Bakış
Berkeley Data Analytics Stack Genel Bakış
 
Photoshop
PhotoshopPhotoshop
Photoshop
 
Apec women and the economy 2011 mo - australia
Apec women and the economy 2011   mo - australiaApec women and the economy 2011   mo - australia
Apec women and the economy 2011 mo - australia
 
Fischer GmbH Russisch
Fischer GmbH RussischFischer GmbH Russisch
Fischer GmbH Russisch
 
Big data
Big dataBig data
Big data
 
Colab42
Colab42Colab42
Colab42
 
Sortsearch
SortsearchSortsearch
Sortsearch
 

Similar a Clojure 1a

Thinking Functionally - John Stevenson - Codemotion Rome 2017
Thinking Functionally - John Stevenson - Codemotion Rome 2017Thinking Functionally - John Stevenson - Codemotion Rome 2017
Thinking Functionally - John Stevenson - Codemotion Rome 2017Codemotion
 
Thinking Functionally with Clojure
Thinking Functionally with ClojureThinking Functionally with Clojure
Thinking Functionally with ClojureJohn Stevenson
 
Fun with Functional Programming in Clojure
Fun with Functional Programming in ClojureFun with Functional Programming in Clojure
Fun with Functional Programming in ClojureCodemotion
 
Get Functional Programming with Clojure
Get Functional Programming with ClojureGet Functional Programming with Clojure
Get Functional Programming with ClojureJohn Stevenson
 
Get into Functional Programming with Clojure
Get into Functional Programming with ClojureGet into Functional Programming with Clojure
Get into Functional Programming with ClojureJohn Stevenson
 
Clojure and The Robot Apocalypse
Clojure and The Robot ApocalypseClojure and The Robot Apocalypse
Clojure and The Robot Apocalypseelliando dias
 
About Functional Programming
About Functional ProgrammingAbout Functional Programming
About Functional ProgrammingAapo Kyrölä
 
Introduction to Erlang Programming Language
Introduction to Erlang Programming LanguageIntroduction to Erlang Programming Language
Introduction to Erlang Programming LanguageYasas Gunarathne
 
Introduction to Clojure
Introduction to ClojureIntroduction to Clojure
Introduction to ClojureRenzo Borgatti
 
Fun with Functional Programming in Clojure - John Stevenson - Codemotion Amst...
Fun with Functional Programming in Clojure - John Stevenson - Codemotion Amst...Fun with Functional Programming in Clojure - John Stevenson - Codemotion Amst...
Fun with Functional Programming in Clojure - John Stevenson - Codemotion Amst...Codemotion
 
Erlang kickstart
Erlang kickstartErlang kickstart
Erlang kickstartRyan Brown
 
Clojure for Java developers
Clojure for Java developersClojure for Java developers
Clojure for Java developersJohn Stevenson
 
DataWeave 2.0 Language Fundamentals
DataWeave 2.0 Language FundamentalsDataWeave 2.0 Language Fundamentals
DataWeave 2.0 Language FundamentalsJoshua Erney
 
Unit I Advanced Java Programming Course
Unit I   Advanced Java Programming CourseUnit I   Advanced Java Programming Course
Unit I Advanced Java Programming Courseparveen837153
 
Functional Swift
Functional SwiftFunctional Swift
Functional SwiftGeison Goes
 

Similar a Clojure 1a (20)

Clojure
ClojureClojure
Clojure
 
Thinking Functionally - John Stevenson - Codemotion Rome 2017
Thinking Functionally - John Stevenson - Codemotion Rome 2017Thinking Functionally - John Stevenson - Codemotion Rome 2017
Thinking Functionally - John Stevenson - Codemotion Rome 2017
 
Thinking Functionally with Clojure
Thinking Functionally with ClojureThinking Functionally with Clojure
Thinking Functionally with Clojure
 
Fun with Functional Programming in Clojure
Fun with Functional Programming in ClojureFun with Functional Programming in Clojure
Fun with Functional Programming in Clojure
 
Get Functional Programming with Clojure
Get Functional Programming with ClojureGet Functional Programming with Clojure
Get Functional Programming with Clojure
 
Get into Functional Programming with Clojure
Get into Functional Programming with ClojureGet into Functional Programming with Clojure
Get into Functional Programming with Clojure
 
Clojure and The Robot Apocalypse
Clojure and The Robot ApocalypseClojure and The Robot Apocalypse
Clojure and The Robot Apocalypse
 
Seeking Clojure
Seeking ClojureSeeking Clojure
Seeking Clojure
 
About Functional Programming
About Functional ProgrammingAbout Functional Programming
About Functional Programming
 
Introduction to Erlang Programming Language
Introduction to Erlang Programming LanguageIntroduction to Erlang Programming Language
Introduction to Erlang Programming Language
 
Introduction to Clojure
Introduction to ClojureIntroduction to Clojure
Introduction to Clojure
 
Functional programming
Functional programmingFunctional programming
Functional programming
 
Functional programming
Functional programmingFunctional programming
Functional programming
 
Fun with Functional Programming in Clojure - John Stevenson - Codemotion Amst...
Fun with Functional Programming in Clojure - John Stevenson - Codemotion Amst...Fun with Functional Programming in Clojure - John Stevenson - Codemotion Amst...
Fun with Functional Programming in Clojure - John Stevenson - Codemotion Amst...
 
Erlang kickstart
Erlang kickstartErlang kickstart
Erlang kickstart
 
Clojure for Java developers
Clojure for Java developersClojure for Java developers
Clojure for Java developers
 
Oop is not Dead
Oop is not DeadOop is not Dead
Oop is not Dead
 
DataWeave 2.0 Language Fundamentals
DataWeave 2.0 Language FundamentalsDataWeave 2.0 Language Fundamentals
DataWeave 2.0 Language Fundamentals
 
Unit I Advanced Java Programming Course
Unit I   Advanced Java Programming CourseUnit I   Advanced Java Programming Course
Unit I Advanced Java Programming Course
 
Functional Swift
Functional SwiftFunctional Swift
Functional Swift
 

Más de Krishna Chaytaniah

Más de Krishna Chaytaniah (7)

Linear sorting
Linear sortingLinear sorting
Linear sorting
 
Design and analysis of computer algorithms (dave mount, 1999)
Design and analysis of computer algorithms (dave mount, 1999)Design and analysis of computer algorithms (dave mount, 1999)
Design and analysis of computer algorithms (dave mount, 1999)
 
Design and analysis of computer algorithms
Design and analysis of computer algorithmsDesign and analysis of computer algorithms
Design and analysis of computer algorithms
 
Writing algorithms
Writing algorithmsWriting algorithms
Writing algorithms
 
Node js
Node jsNode js
Node js
 
Oracle apps
Oracle appsOracle apps
Oracle apps
 
Salesforce content best_practices_rollout_webinar_deck
Salesforce content best_practices_rollout_webinar_deckSalesforce content best_practices_rollout_webinar_deck
Salesforce content best_practices_rollout_webinar_deck
 

Clojure 1a

  • 1. Thinking in Clojure Mar 29, 2013
  • 2. Jumping in  We’ll quickly go through Clojure’s data types, some basic functions, and basic syntax  Then we’ll get to the good stuff! 2
  • 3. Clojure’s data types  Clojure has:  Lists, enclosed in parentheses and separated by spaces or commas: (a 17 "Plenty of parentheses")  Functions: (fn [x] (first(rest x))  Numbers: All Java numeric types, plus ratios and exact decimals: 5, 5.3, 5.3e30, 077, 0xFF00FF, 3/5, 5.3M  Strings, as in Java: "She said "Hello""  Characters: a, 5, n, newline, tab, etc.  The booleans true and false  nil, equivalent to Java’s null  Symbols, which stand for themselves: :meadow, :CIS-554  Vectors: [5 :a "hi!"]  Maps: {:one 1, :two 2}  Sets: #{:prolog :clojure} 3
  • 4. Some basic Clojure functions  Syntax of a function call: (function args)  Basic operations—sequences (seq) are lists, sets, maps, vectors:  (quote arg) or 'arg, to keep arg from being evaluated  (first seq) is the first element in the sequence (or nil)  (rest seq) is what remains when the first element is removed (or nil)  (cons arg seq) returns a new sequence with arg as its first element  (= args) tests whether its args are equal  (empty? seq), (list? seq), (seq? arg), (nil? arg) are more tests  Basic arithmetic  (+ args), (- args), (* args), (/ args) , (< args), etc.  Basic logic  (and args), (or args), (not arg), (if condition result1 result2)  Defining values  (def name value) defines the name to be the given value  (defn name argv value) is shorthand for (def name argv value), where argv is a vector 4
  • 5. Functions and special forms  The arguments to a function are evaluated before the function is called  Example: (* 2 (+ 3 4)) The function * is called with the arguments 2 and 7  A special form looks just like a function, but it gets its arguments unevaluated  The special form itself decides when and whether to evaluate its arguments  quote does not evaluate its argument  if evaluates its first argument, then decides which of the second and third arguments to evaluate  Clojure allows you to define your own special forms  This means you can define your own control structures 5
  • 6. A typical Clojure function  (defn first-double-letter "Returns the first doubled letter in a string, or nil." [s] (if (< (count s) 2) nil (if (= (first s) (second s)) (first s) (first-double-letter (rest s)) ) ) )  user=> (first-double-letter "Pennsylvania") n user=> (first-double-letter '(1 2 3 4 3 5 5 4 6)) 5 6
  • 7. It’s easier with cond  cond is an if … then … else if … then … else … construct: (cond test1 result1 test2 result2 … testN resultN)  It requires an even number of parameters (one result for each test)  The symbol :else may be used as the last test  (defn first-double-letter "Returns the first doubled letter in a string, or nil." [s] (cond (< (count s) 2) nil (= (first s) (second s)) (first s) :else (first-double-letter (rest s)) ) )  user=> (first-double-letter "Pennsylvania") n user=> (first-double-letter '(1 2 3 4 3 5 5 4 6)) 5 7
  • 8. It’s all about recursion  Some rules of doing recursion: 1. Handle the base cases directly (without recursion) 2. Recur only with a simpler case 3. Don’t use global variables 4. Don’t “look down” into the recursion—that will just confuse you  In Clojure you are almost always working with a list or some similar sequence  Lisp programmers say, “Do something with the head, and recur with the tail”  Clojure’s terms for “head” and “tail” are “first” and “rest”  This pretty much covers rules 1 and 2 above  Clojure doesn’t have global variables  This covers rule #3 above  Rule 4 always holds. Think about what you are doing now, not what some recursive call is doing 8
  • 9. Functional programming  Clojure is functional—what does that mean?  Functions are like functions in math—called with the same arguments, they always return the same result  This means: No “global variables,” no dependence on external values, and no side effects!  Functions are values, or first-class objects  Functions can be passed as parameters to functions, returned as the value of functions, created as needed, stored in data structures, and there are operations on functions that produce new functions  The “blub paradox” applies—the value added is substantial, but not obvious to an imperative or object-oriented programmer  Data is immutable (like strings in Java)  Clojure’s data structures are designed to make this efficient  Immutable data greatly simplifies concurrent programming  Because data is immutable, loops are unnecessary (use recursion instead!) 9
  • 10. Costs and benefits  Costs of functional programming  It’s weird and unfamiliar  How can you do anything without objects, mutable variables, or loops?  (Loops are used primarily to change the values of things)  As a manager, functional programmers are hard to find (and expensive!)  Clojure, and Lisp dialects generally, have too many parentheses!  Benefits of functional programs  Easier to write correct programs  “Yeah, right!” – “No, really! All data is local and immutable.”  Easier to write unit tests, because function values depend only on inputs  Much easier to write concurrent programs  Operations on collections make code simpler and more concise  The simpler foundation means less syntax and fewer special cases  Some operations, such as equality testing, are really fast  But it’s still weird! 10
  • 11. Easier to write correct programs  Programs are easier to write when all data is local  When relevant values can be changed elsewhere in the program—possibly in many places—it’s harder to see all the connections  Functions in a functional language get all relevant input from the parameter list  Unit testing is easier, because there are no dependencies on functions that may or may not have been called previously  There is no need for a setUp method  Functional programming supports powerful operations on sequences  The imperative and object-oriented programming styles have been characterized as “word by word” programming  Some sequence operations, such as membership testing, are provided for you  In a functional language, any function can be a sequence operation 11
  • 12. The problem of state  Nonfunctional programming language are “stateful” or “have state”  The state of a program is given by (1) the values of all the variables throughout the program, and (2) the current locus of execution  That can be a huge amount of information to keep track of!  Object-oriented programmers try to control complexity by having objects be responsible for their own state, and “loosely coupled” (not very dependent on) other objects  Methods often have “side effects,” that is, they modify state  Functional languages try to avoid having state at all  This isn’t always easy  Purely functional languages cannot have side effects  Since I/O is a side effect, this is an even more difficult restriction 12
  • 13. Maintaining state, functionally  Sometimes you just need state  Consider an adventure game  You need to keep track of where you are, where other objects are, what you are holding, which paths are blocked or open, etc.—this is your state  You do not need to keep track of permanent, immutable data; for example, most paths between rooms are fixed and unchanging—this isn’t part of the state  In a functional program, a “state” is just an immutable (and usually just one) data item  The data item can be quite complex, such as a dictionary  States are immutable, but you can always create a “new” state that is a variation of a given state  With carefully designed data structures, not as much storage is required as you might expect  So the functional solution to maintaining state is: Pass one state into a function, get a new (and different) state back! 13
  • 14. Clojure’s I/O compromise  A purely functional program has no side effects  I/O is a side effect  Therefore: A purely functional program cannot do I/O!  In Clojure, all functions return a value  (print args) and (println args) return nil  Clojure allows side effects in two well-defined places:  (do args) evaluates all its arguments in order, but returns only the value of the last one  When a function (fn argv args) is called, the arguments are evaluated in order, but only the last value is returned  Example:  (defn powers "Computes cube and square" [] (def n (read)) (println (* n n n)) (println (* n n)) n) 14
  • 15. Lists are immutable Here is a typical list: my-list A B C w Here is (cons 'w my-list) Here is (rest my-list) Notice that my-list remains unchanged Vectors, hash maps, sorted maps, hash sets, and sorted sets are similarly immutable 15
  • 16. Functions are just values  user=> (cons 'w '(a b c)) (w a b c)  user=> (defn swap-args [f x y] (f y x)) #'user/swap-args  user=> (swap-args cons '(a b c) 'w) (w a b c)  user=> (defn apply-n-times [f x n] "Apply f to x, n times: f(f(f..(n)...))" (if (zero? n) x (apply-n-times f (f x) (dec n)) ) ) #'user/apply-n-times  user=> (apply-n-times (fn [x] (* 2 x)) 1 10) 1024 16
  • 17. Collatz, the hard way  Definition:  collatz(1) = 1 collatz(n) = collatz(n / 2) if n is even collatz(n) = collatz(3 * n + 1)  user=> (defn collatz [n] (let [ do-even (fn [n] (collatz (/ n 2))) do-odd (fn [n] (collatz (inc (* 3 n)))) ] (print n " ") (if (= n 1) 1 (if (even? n) (do-even n) (do-odd n)) ) ) )  #'user/collatz user=> (collatz 7) 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1 1 17
  • 18. map, filter, and reduce  Here are three powerful functions you will find in almost any functional programming language  map – apply a function to every element of a sequence, returning a sequence of results  user=> (map even? '(3 1 4 1 6))  (false false true false true)  filter – apply a predicate to every element of a sequence, returning a sequence of those that satisfy the predicate  user=> (filter even? '(3 1 4 1 6))  (4 6)  reduce – use a function to reduce a sequence to a single value  user=> (reduce * '(3 1 4 1 6))  72 18
  • 19. The real problem with state  For decades we’ve been dealing with mutable state  Mutable state + concurrency = nondeterminism  We use threads and locks and semaphores and so on  These are complicated, unsafe, and inefficient  As Herb Sutter points out in The Free Lunch is Over, we have hit a 3 GHz barrier  Since 2003, computers have not gotten faster  We still want them faster  Concurrency is the only solution  Functional languages, with immutable state, provide a partial solution  As Martin Odersky points out, you can hide from concurrency for a while yet…but not forever  Important consequences:  All newer languages are gaining functional and concurrent features  Older languages, such as Java, are also trying to integrate these features  “You can run, but you can’t hide!” 19
  • 20. Oh, and by the way…  Clojure has  Infinite sequences  Lazy sequences  Exact decimal arithmetic  Function composition  Function currying  Macros  And lots more  No version of Lisp has ever become mainstream  They just get mugged in dark alleys and their ideas stolen! 20
  • 21. The End 21