1 / 24

Feb 17, 2015

Clojure 3. Feb 17, 2015. Clojure errors. (NO_SOURCE_FILE:12) Useless--just means you’re running from the REPL shell java.lang.Exception: EOF while reading (test.clj:139) You have an unclosed parenthesis somewhere Use a good text editor!

burpee
Download Presentation

Feb 17, 2015

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Clojure 3 Feb 17, 2015

  2. Clojure errors • (NO_SOURCE_FILE:12) • Useless--just means you’re running from the REPL shell • java.lang.Exception: EOF while reading (test.clj:139) • You have an unclosed parenthesis somewhere • Use a good text editor! • In jEdit, Control-A Control-I will make the error obvious • user=> (map (fn[x] (x * x)) (take 10 (iterate inc 1))) • java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

  3. Sequences • In Clojure, almost every collection is a sequence • user=> (cons 5 [1 2 3])(5 1 2 3) ; Not [5 1 2 3] • user=> (class '(1 2 3))clojure.lang.PersistentList • user=> (class [1 2 3])clojure.lang.LazilyPersistentVector • user=> (class (cons 5 [1 2 3]))clojure.lang.Cons • user=> (class (rest (cons 5 [1 2 3])))clojure.lang.LazilyPersistentVector$ChunkedSeq • Most of the time you don’t care what kind of a sequence it is

  4. Persistence and laziness • In Functional Programming, a persistent data structure is one that is itself immutable, but can be modified to create a “new” data structure • The original and the new data structure share structure to minimize copying time and wasted storage • A lazy data structure is one where parts of it do not exist until they are accessed • This allows you to have “infinite” data structures

  5. range, take, and drop • user=> (range 10)(0 1 2 3 4 5 6 7 8 9) • user=> (range 1 10)(1 2 3 4 5 6 7 8 9) • user=> (range 0 20 3)(0 3 6 9 12 15 18) • user=> (range 10 20)(10 11 12 13 14 15 16 17 18 19) • user=> (take 4 (range 10 20))(10 11 12 13) • user=> (drop 4 (range 10 20))(14 15 16 17 18 19) • user=> (range 1 10)(1 2 3 4 5 6 7 8 9) • user=> (take 20 (range 1 10))(1 2 3 4 5 6 7 8 9) • user=> (drop 20 (range 1 10))() • user=> (take 4 "abcdefg")(\a \b \c \d) • user=> (str (take 4 "abcdefg"))"clojure.lang.LazySeq@3babc3" • user=> (apply str (take 4 "abcdefg"))"abcd"

  6. iterate • iterate takes a function f and a starting value n, and lazily produces the infinite series (n, f(n), f(f(n)), f(f(f(n))), ...) • ; Don’t try this!user=>(iterate inc 1)(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...) • ; But this is okayuser=> (take 5 (iterate inc 1))(1 2 3 4 5) • ; Don’t try this!user=> (drop 5 (iterate inc 1))(6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21...) • ; But this is okayuser=> (take 5 (drop 1000 (iterate inc 1)))(1001 1002 1003 1004 1005)

  7. Fun with iterate • user=> (take 10 (iterate (fn [x] (* 2 x)) 2))(2 4 8 16 32 64 128 256 512 1024) • (defn collatz-1 [n] (cond (= n 1) 1 (even? n) (/ n 2) (odd? n) (inc (* 3 n)) ) ) • user=> (take 5 (iterate collatz-1 7))(7 22 11 34 17) • user=> (take 25 (iterate collatz-1 7))(7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1 1 1 1 1 1 1 1 1) • user=> (nth (iterate collatz-1 7) 4)17

  8. Fibonacci numbers • user=> (defn next-pair [pair] (list (second pair) (+ (first pair) (second pair))))#'user/next-pair • user=> (next-pair '(1 1))(1 2) • user=> (next-pair '(1 2))(2 3) • user=> (take 10 (iterate next-pair '(0 1)))((0 1) (1 1) (1 2) (2 3) (3 5) (5 8) (8 13) (13 21) (21 34) (34 55)) • user=> (map second (take 10 (iterate next-pair '(0 1))))(1 1 2 3 5 8 13 21 34 55)

  9. Prime numbers • user=> (defn divides [d n] (integer? (/ n d)))#'user/divides • user=> (divides 4 24)true • user=> (divides 5 24)false • user=> (defn prime [n] (not-any? (fn [d] (divides d n)) (range 2 (dec n)))) #'user/prime • user=> (take 20 (filter prime (iterate inc 2)))(2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71) • user=> (defn composite [n] (some (fn [d] (divides d n)) (range 2 (dec n)))) #'user/composite • user=> (take 20 (filter composite (iterate inc 1)))(4 6 8 9 10 12 14 15 16 18 20 21 22 24 25 26 27 28 30 32)

  10. Tri-nums • (defn triangle [n] • (/ (* n (+ n 1)) 2)) • (def tri-nums (map triangle (iterate inc 1))) • (take 10 tri-nums) • ;=> (1 3 6 10 15 21 28 36 45 55) • ;; what Gauss found • (nth tri-nums 99) • ;=> 5050

  11. More tri-nums • (take 10 (filter even? tri-nums)) • ;=> (6 10 28 36 66 78 120 136 190 210) • (double (reduce + (take 1000 (map / tri-nums)))) • ;=> 1.998001998001998 • (take 2 (drop-while #(< % 10000) tri-nums)) • ;=> (10011 10153)

  12. let and letfn • user=> (defn hypotenuse [a b] (let [a2 (* a a) b2 (* b b)] (Math/sqrt (+ a2 b2)) ) ) #'user/hypotenuse • user=> (hypotenuse 3 4)5.0 • user=> (hypotenuse 1 1)1.4142135623730951 • user=> (defn hypotenuse [a b] (letfn [(square [n] (* n n))] (Math/sqrt (+ (square a) (square b)))))#'user/hypotenuse • user=> (hypotenuse 3 4)5.0 • user=> (hypotenuse 1 1) 1.4142135623730951

  13. Debugging with do • user=> (format "%d + %d is %d\n" 3 4 7)"3 + 4 is 7\n" • user=> (print (format "%d + %d is %d\n" 3 4 7))3 + 4 is 7nil • user=> (defn hypotenuse [a b] (letfn [(square [n] (* n n))] (do (println (format "a = %d, b = %d" a b)) (Math/sqrt (+ (square a) (square b))) ) ) ) #'user/hypotenuse • user=> (hypotenuse 3 4) a = 3, b = 4 5.0

  14. List comprehensions I • formacroUsage: (for seq-exprs body-expr)List comprehension. Takes a vector of one or more binding-form/collection-expr pairs, each followed by zero or more modifiers, and yields a lazy sequence of evaluations of expr. Collections are iterated in a nested fashion, rightmost fastest, and nested coll-exprs can refer to bindings created in prior binding-forms. Supported modifiers are::let [binding-formexpr ...], :while test, :when test. • user=> (take 12 (for [x (range 100000000) y (range 1000000) :while (< y x)] [x y])) ([1 0] [2 0] [2 1] [3 0] [3 1] [3 2] [4 0] [4 1] [4 2] [4 3] [5 0] [5 1]) • Source: http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/for

  15. List comprehensions II • user=> (map (fn[x] (* x x)) (take 10 (iterate inc 1)))(1 4 9 16 25 36 49 64 81 100) • user=> (for [x (take 10 (iterate inc 1))] (* x x))(1 4 9 16 25 36 49 64 81 100) • user=> (take 10 (for [x (iterate inc 1)] (* x x)))(1 4 9 16 25 36 49 64 81 100) • user=> (for [x (iterate inc 1) :while (< x 11)] (* x x))(1 4 9 16 25 36 49 64 81 100) • user=> (for [x (range 1 11)] (* x x))(1 4 9 16 25 36 49 64 81 100)

  16. List comprehensions III • user=> (for [x (range 1 11) :when (even? x)] (* x x)) (4 16 36 64 100) • user=> (take 10 (for [x (iterate inc 1) :when (even? x)] (* x x)))(4 16 36 64 100 144 196 256 324 400) • ; Don't do this:user=> (for [x (iterate inc 1) :when (even? x)] (* x x))(4 16 36 64 100 144 196 256 324 400 484 576 676 784 ... • user=> (for [x "abcde" y [1 2]] [x y]) ([\a 1] [\a 2] [\b 1] [\b 2] [\c 1] [\c 2] [\d 1] [\d 2] [\e 1] [\e 2]) • user=> (for [word ["the" "quick" "brown" "fox" "jumps"]] (format "Word: %s" word) )("Word: the" "Word: quick" "Word: brown" "Word: fox" "Word: jumps")

  17. Partial functions • (partial f arg1 arg2 arg3 & more)Takes a function f and fewer than the normal arguments to f, and returns a fn that takes a variable number of additional args. When called, the returned function calls f with args + additional args. • user=> (def hundred-times (partial * 100))#'user/hundred-times • user=> (hundred-times 5)500

  18. Prime, revisited • user=> (defn prime [n] (not-any? (fn [d] (divides d n)) (range 2 (dec n))))#'user/prime • user=> (defn divisible [n d] (integer? (/ n d)))#'user/divisible • user=> (divisible 24 3)true • user=> (divisible 24 5)false • user=> (defn prime [n] (not-any? (partial divisible n) (range 2 (dec n))))#'user/prime • user=> (prime 21)false • user=> (prime 19)true

  19. Member • user=> (defn member [e coll] (cond (empty? coll) false (= e (first coll)) true :else (member e (rest coll)) ) )#'user/member • user=> (member 5 (range 1 10))true • user=> (member 5 (range 10 20))false

  20. Member, revisited • user=> (some (partial = 5) (range 1 10))true • user=> (some (partial = 5) (range 10 20))nil • user=> (defn member [e coll] (some (partial = e) coll))#'user/member • user=> (member 5 (range 1 10))true • user=> (member 5 (range 10 20))nil

  21. Avoiding recursion • Java is an object-oriented language • You have a lot of classes available to you • You should not write your own Stack class! • Clojure is a very recursive language • There are a lot of built-in functions that are recursive • You should avoid recursion if Clojure will do it for you

  22. Zip • (defn zip [a b] (if (or (empty? a) (empty? b)) () (cons (list (first a) (first b)) (zip (rest a) (rest b))) ) ) • user=> (zip [1 2 3 4] [:a :b :c])((1 :a) (2 :b) (3 :c)) • user=> (zip '(1 2 3 4) '(:a :b :c))((1 :a) (2 :b) (3 :c)) • user=> (def zip4 (partial zip [1 2 3 4]))#'user/zip4 • user=> (zip4 "abcde")((1 \a) (2 \b) (3 \c) (4 \d))

  23. Best reference • http://clojure.github.com/clojure/clojure.core-api.html

  24. The End

More Related