Your SlideShare is downloading. ×
0
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

(map Clojure everyday-tasks)

1,468

Published on

Presentation on Clojure from the 33rd degree conference in Krakow, Poland, in March 2012.

Presentation on Clojure from the 33rd degree conference in Krakow, Poland, in March 2012.

Published in: Technology, News & Politics
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,468
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
54
Comments
0
Likes
4
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Transcript

    • 1. Main sponsor(map Clojure everyday-tasks) Jacek Laskowski
    • 2. About me• Functional apprentice to Clojure• Founder and co-leader of Warszawa JUG• Conference organizer of Javarsovia, Confitura, warsjawa• Member of NetBeans DreamTeam• Blogger of http://JacekLaskowski.pl• Blogger of http://blog.japila.pl• @jaceklaskowski• Member of Apache Software Foundation• IBMer
    • 3. Why should I care about Clojure? (map Clojure everyday-tasks)Clojure for real-world, day-to-day programming
    • 4. List comprehension(for [x (range 2) y (range 2)] [x y])
    • 5. List comprehension(for [x (range 2) y (range 2)] [x y])user=> ([0 0] [0 1] [1 0] [1 1])
    • 6. List comprehensionfunction(for [x (range 2) y (range 2)] [x y])user=> ([0 0] [0 1] [1 0] [1 1])
    • 7. Persistent data structures• list ()• vector []• map {}• set #{}• They can nest freely• They’re persistent (a.k.a. immutable)
    • 8. (for [n #{"jacek" "agatka" "iwetka" "patryk" "maksym"}] [n (count n)])
    • 9. Lists in Clojure1st item(fn arg1 arg2 ...) 3rd item 2nd item
    • 10. Function calls in Clojurefunction name (fn arg1 arg2 ...) function param function param
    • 11. Reason #1Functional programming language
    • 12. Functional language• Functions are first-class citizens• They’re like other values• They can be • passed to a function • returned from a function• HOF = higher-order function
    • 13. Function definition (fn [args] (body) (defn function-name [args] (body)) #(body)
    • 14. Function call(function-name arg1 arg2 ...)
    • 15. Fundamental functions• map - apply a function to a sequence • returns a sequence• reduce - accumulation over a sequence • returns an accumulator• filter - filters items satisfying a predicate • return a sequence
    • 16. map function Apply a function (map f ‘(1 2 3)) to a sequence and return a sequence in which every item is ‘((f 1) (f 2) (f 3)) transformed by the functionExamples: addVat, convertCurrencyhttp://cyrille.martraire.com/2011/03/thinking-functional-programming-with-map-and-fold-in-your-everyday-java/
    • 17. reduce function(reduce f ‘( 1 2 3 4 )) Accumulate over a sequence and‘( f ( f ( f 1 2 ) 3 ) 4 ) return the accumulator
    • 18. Mutation• Persistent references to a mutable state • Var - dynamically rebound on a per- thread basis (thread isolation) • Ref - transactional via Clojure STM • Agent - independent, asynchronous change of individual location • Atom - synchronous, independent state
    • 19. (def ^:dynamic *b* 5)(defn printb [] *b*)(binding [*b* 10] (printb))
    • 20. (def ^:dynamic *b* 5)(defn printb [] *b*)(binding [*b* 10] (printb))user=> 10
    • 21. explicit about mutation(def ^:dynamic *b* 5)(defn printb [] *b*)(binding [*b* 10] (printb))user=> 10
    • 22. (def a (ref 0))(def b (ref 0))(alter a inc) ;; java.lang.IllegalStateException: ;; No transaction running(dosync (alter a inc) (alter b inc))
    • 23. (def a (ref 0))(def b (ref 0))(alter a inc) ;; java.lang.IllegalStateException: ;; No transaction running(dosync (alter a inc) (alter b inc))user=> 1
    • 24. explicit about mutation (def a (ref 0)) (def b (ref 0)) (alter a inc) ;; java.lang.IllegalStateException: ;; No transaction running (dosync (alter a inc) (alter b inc)) user=> 1
    • 25. (def c (agent 0))(send c inc)
    • 26. (def c (agent 0))(send c inc)user=> 1
    • 27. explicit about mutation (def c (agent 0)) (send c inc) user=> 1
    • 28. (def c (agent 0))(defn f-agt [v] (Thread/sleep (* v 1000)) (println (Thread/currentThread)) (inc v))(send c f-agt);; (agent-errors c);; (restart-agent c 0)
    • 29. (def atm (atom 0))(swap! atm inc)
    • 30. (def atm (atom 0))(swap! atm inc)user=> 1
    • 31. explicit about mutation(def atm (atom 0))(swap! atm inc)user=> 1
    • 32. Reason #2Concurrency abstractions
    • 33. Namespace, Symbols and Vars• Symbol is a name bound to a Var• (def v ...)• Vars can be changed on a per-thread basis• Namespace is a map of symbols to Vars• Namespace is similar to a fully-qualified class name in Java
    • 34. Clojure REPL
    • 35. (defn handle-numbers [handler] (fn []   (doseq [x (iterate inc 0)]      (println (handler x)      (Thread/sleep 1000)))))(defn sample-handler [x] x)(def th (Thread. (handle-numbers sample-handler)))(.start th)(defn sample-handler [x] (- x))(.stop th)(defn sample-handler [x] x)(def th (Thread. (handle-numbers #sample-handler)))(.start th)
    • 36. (import [javax.swing JFrame] [java.awt.event ActionListener])(def f (JFrame. "A window"))(.setSize f 300 100)(.setVisible f true)(import [javax.swing JButton])(def b (JButton. "Press me!"))(.add f b)(.pack f)(.addActionListener b (proxy [ActionListener] [] (actionPerformed [evt] (println "I’ve been pressed"))))
    • 37. Reason #3Dynamic programming
    • 38. Values in Clojure• Strings are just instances of java.lang.String user=> (.charAt “abc” 0)• Numbers, characters, nil, true, false, and keywords evaluate to themselves user=> (Character/isLetter c)
    • 39. Regular expressions• #"pattern" - java.util.regex.Pattern• (re-seq re s) lazy seq of matches of re in s• (re-find m) the next regex match• (re-matches re s) returns the match• (re-matcher re s) gives j.u.regex.Matcher• (re-groups m) returns the groups
    • 40. user=> (def ptrn #"[0-9]+")#user/ptrnuser=> (class ptrn)java.util.regex.Patternuser=> (re-seq ptrn "abc 123 a 2 2 1")("123" "2" "2" "1")
    • 41. Java interop• (.instanceMember instance args*)• (.instanceMember Classname args*)• (Classname/staticMethod args*)• Classname/staticField
    • 42. Java interop macros• (.. instance-expr member+)• (doto instance-expr (instanceMethodName-symbol args*)*)• (Classname. args*)
    • 43. Reason #4Easy Java interop
    • 44. clojure.main• Run scripts from the command line• java -jar clojure.jar your-script.clj args*
    • 45. AOT compilation• Clojure compiles all code you load on-the- fly into JVM bytecode• Ahead-of-time (AOT) = before on-the-fly at runtime• Target of (compile) is namespace• Each file, fn, and gen-class give new .class
    • 46. :gen-class sample (ns helloworld Classname 
    • 47. :gen-class sample (ns helloworld   (:gen-class)) Execute AOT 
    • 48. :gen-class sample (ns helloworld   (:gen-class))  (defn -main [& args] the main function
    • 49. :gen-class sample (ns helloworld   (:gen-class))  (defn -main [& args]   (println "Hello world!")) the main’s body
    • 50. :gen-class sample (ns helloworld   (:gen-class))  (defn -main [& args]   (println "Hello world!"))
    • 51. AOT in Practice• lein new [project-name]• Add :main to project.clj• lein uberjar• java -jar [project-name-ver-standalone.jar]
    • 52. Java EE web apps with Clojure(Maven and Leiningen are there, too!) http://blog.japila.pl/2012/03/java-ee-web-apps-with-clojure-maven-and-leiningen-are-there-too/
    • 53. $ mvn archetype:generate -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=com.mycompany.app -DartifactId=my-webapp-demo
    • 54. $ mvn archetype:generate -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=com.mycompany.app -DartifactId=my-webapp-demo$ lein new my-webapp-demo-clj
    • 55. $ mvn archetype:generate -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=com.mycompany.app -DartifactId=my-webapp-demo$ lein new my-webapp-demo-clj(ns my-webapp-demo-clj.core  (:gen-class   :methods [[hello [String] String]]))(defn -hello  [this s]  (str "Hello, " s))
    • 56. $ mvn archetype:generate -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=com.mycompany.app -DartifactId=my-webapp-demo$ lein new my-webapp-demo-clj public String hello(String)(ns my-webapp-demo-clj.core  (:gen-class   :methods [[hello [String] String]]))(defn -hello  [this s]  (str "Hello, " s))
    • 57. (defproject my-webapp-demo-clj "1.0.0-SNAPSHOT"  :description "FIXME: write description"  :dependencies [[org.clojure/clojure "1.3.0"]]  :aot :all)
    • 58. (defproject my-webapp-demo-clj "1.0.0-SNAPSHOT"  :description "FIXME: write description"  :dependencies [[org.clojure/clojure "1.3.0"]]  :aot :all)$ lein install
    • 59. (defproject my-webapp-demo-clj "1.0.0-SNAPSHOT"  :description "FIXME: write description"  :dependencies [[org.clojure/clojure "1.3.0"]]  :aot :all)$ lein install<dependency>  <groupId>my-webapp-demo-clj</groupId>  <artifactId>my-webapp-demo-clj</artifactId>  <version>1.0.0-SNAPSHOT</version></dependency>
    • 60. <html><body><h2>Hello World!</h2></body><p> <%= new my_webapp_demo_clj.core().hello("Jacek") %></p></html>
    • 61. <html><body><h2>Hello World!</h2></body><p> <%= new my_webapp_demo_clj.core().hello("Jacek") %></p></html>$ mvn package
    • 62. <html><body><h2>Hello World!</h2></body><p> <%= new my_webapp_demo_clj.core().hello("Jacek") %></p></html>$ mvn package
    • 63. Reason #5Easy Java interop both ways
    • 64. Leiningenlein - a project automation tool
    • 65. Starting a project• lein new [project-name] • Edit project.clj (mainly deps) • Also plugin configuration, e.g. :main for run (soon explained)
    • 66. Custom project setup defproject in project.clj customized
    • 67. Dependencies• lein deps• lein search [library]
    • 68. clojarsMaven repository for Clojure projects http://clojars.org/
    • 69. Ongoing development• lein repl• lein eclipse• lein midje (“formerly” lein test)• lein run• lein jar• Some require custom setup...
    • 70. Unit testing• clojure.test namespace• the is macro (is (= 5 (+ 2 2)) "Crazy arithmetic")• the are macro• the deftest macro (deftest addition (is (= 4 (+ 2 2))) (is (= 7 (+ 3 4))))• (run-tests & namespaces)
    • 71. lein test [ns]Runs project tests, optionally only from a ns
    • 72. src/hi/core.clj(ns hi.core)(defn hi ([] "Hi!") ([name] (str "Hi " name "!")))
    • 73. lein test$ lein testCopying 1 file to /Users/jacek/sandbox/hi/libTesting hi.test.coreFAIL in (replace-me) (core.clj:6)No tests have been written.expected: false actual: falseRan 1 tests containing 1 assertions.1 failures, 0 errors.
    • 74. test/hi/test/core.clj(ns hi.test.core (:use [hi.core]) (:use [clojure.test]))(deftest hi-simple-test (is (= (hi) "Hi!")) (is (= (hi "Clojure") "Hi Clojure!")))
    • 75. lein test$ lein testTesting hi.test.coreRan 1 tests containing 2 assertions.0 failures, 0 errors.
    • 76. Modern unit testing• Midje - a TDD library for Clojure that supports top-down (mockish) TDD• https://github.com/marick/Midje• midje.sweet namespace• fact macro• (fact "one plus one is two" (+ 1 1) => 2)
    • 77. Midje and Leiningen• lein plugin install lein-midje 1.0.8• :dev-dependencies [[lein-midje "1.0.8"] [midje "1.3.1"]]• lein midje• lein midje --lazytest
    • 78. TDD with Midje #0• :repositories ["stuart" "http://stuartsierra.com/maven2"]• :dev-dependencies [com.stuartsierra/lazytest "1.2.3"]
    • 79. TDD with Midje #1$ lein midje --lazytest======================================At #<Date Tue Feb 21 13:07:52 CET 2012>Reloading librarian-clojure.run, librarian-clojure.repl, librarian-clojure.test.core, librarian-clojure.core,librarian-clojure.books, librarian-clojure.dbFAIL at (core.clj:10) Expected: 2 Actual: 3FAIL at (core.clj:10) Expected: 2 Actual: 3FAILURE: 1 fact was not confirmed. (But 1 was.)Done.======================================At #<Date Tue Feb 21 13:08:11 CET 2012>Reloading librarian-clojure.test.coreAll claimed facts (2) have been confirmed.Done.
    • 80. TDD with Midje #2• (fact "doubles odd numbers"   (my-func 3) => 6)• (fact "triples even numbers"   (my-func 4) => 12)• A solution? http://www.lispplusplus.com/2012/02/tdd-in-midje-in-nutshell.html
    • 81. TDD with Midje #3• Which solution do you prefer?• (defn my-func [n]   (if (odd? n)     (* 2 n)     (* 3 n))• (defn my-func [n]   (let [multiplier (if (odd? n) 2 3)]     (* multiplier n))• Monitor lein terminal
    • 82. Reason #6Familiar-looking project tools
    • 83. RingClojure HTTP server applicationshttps://github.com/mmcgrana/ring
    • 84. Compojure A concise web framework for Clojurehttps://github.com/weavejester/compojure
    • 85. Ring upjacek:~/oss/librarian-clojure$ lein ring server:ring {:handler librarian-clojure.core/app}
    • 86. Reason #7Web application libraries
    • 87. Multimethods• Runtime dynamic dispatch• (defmulti say-count count) (defmethod say-count 0 [_] "Zero") (defmethod say-count 1 [_] "One") (defmethod say-count :default [_] "A Bunch")• (say-count [1 2 3]) http://blog.fogus.me/2011/10/14/why-clojure-doesnt-need-invokedynamic-but-it-might-be-nice/
    • 88. user=> (defmulti say-class class)user=> (defmethod say-class (class {}) [_] "A map")user=> (say-class {})"A map"user=> (say-class [])java.lang.IllegalArgumentException: No method in multimethodsay-class for dispatch value: class clojure.lang.PersistentVector(NO_SOURCE_FILE:0)user=> (defmethod say-class (class []) [_] "A vector")user=> (say-class [])"A vector"
    • 89. Reason #8Multi-level dispatch
    • 90. Are you still uncertain? There’s more, but...time flies by so fast :(

    ×