SlideShare ist ein Scribd-Unternehmen logo
1 von 90
Main sponsor




(map Clojure everyday-tasks)
        Jacek Laskowski
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
Why should I care
   about Clojure?
         (map Clojure everyday-tasks)
Clojure for real-world, day-to-day programming
List comprehension

(for [x (range 2)
      y (range 2)]
  [x y])
List comprehension

(for [x (range 2)
      y (range 2)]
  [x y])
user=> ([0 0] [0 1] [1 0] [1 1])
List comprehension
function

(for [x (range 2)
      y (range 2)]
  [x y])
user=> ([0 0] [0 1] [1 0] [1 1])
Persistent data
         structures
• list ()
• vector []
• map {}
• set #{}
• They can nest freely
• They’re persistent (a.k.a. immutable)
(for [n #{"jacek" "agatka"
          "iwetka" "patryk"
          "maksym"}]
  [n (count n)])
Lists in Clojure
1st item


(fn arg1 arg2 ...)
                 3rd item
      2nd item
Function calls in
       Clojure
function name


   (fn arg1 arg2 ...)
                function param
      function param
Reason #1
Functional programming
        language
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
Function definition
  (fn [args]
    (body)

  (defn function-name [args]
   (body))

  #(body)
Function call


(function-name arg1 arg2 ...)
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
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
                                                                function


Examples: addVat, convertCurrency
http://cyrille.martraire.com/2011/03/thinking-functional-programming-with-map-and-fold-in-your-everyday-java/
reduce function

(reduce f ‘( 1 2 3 4 ))            Accumulate
                                over a sequence
                                       and
‘( f ( f ( f 1 2 ) 3 ) 4 )   return the accumulator
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
(def ^:dynamic *b* 5)

(defn printb []
 *b*)

(binding [*b* 10]
 (printb))
(def ^:dynamic *b* 5)

(defn printb []
 *b*)

(binding [*b* 10]
 (printb))
user=> 10
explicit about mutation

(def ^:dynamic *b* 5)

(defn printb []
 *b*)

(binding [*b* 10]
 (printb))
user=> 10
(def a (ref 0))
(def b (ref 0))

(alter a inc) ;; java.lang.IllegalStateException:
              ;; No transaction running
(dosync
  (alter a inc)
  (alter b inc))
(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
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
(def c (agent 0))

(send c inc)
(def c (agent 0))

(send c inc)
user=> 1
explicit about mutation

 (def c (agent 0))

 (send c inc)
  user=> 1
(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)
(def atm (atom 0))

(swap! atm inc)
(def atm (atom 0))

(swap! atm inc)
user=> 1
explicit about mutation

(def atm (atom 0))

(swap! atm inc)
user=> 1
Reason #2
Concurrency abstractions
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
Clojure REPL
(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)
(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"))))
Reason #3
Dynamic programming
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)
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
user=> (def ptrn #"[0-9]+")
#'user/ptrn
user=> (class ptrn)
java.util.regex.Pattern
user=> (re-seq ptrn "abc 123 a 2 2 1")
("123" "2" "2" "1")
Java interop

• (.instanceMember instance args*)
• (.instanceMember Classname args*)
• (Classname/staticMethod args*)
• Classname/staticField
Java interop macros

• (.. instance-expr member+)
• (doto instance-expr
     (instanceMethodName-symbol args*)*)
• (Classname. args*)
Reason #4
Easy Java interop
clojure.main


• Run scripts from the command line
• java -jar clojure.jar your-script.clj args*
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
:gen-class sample
    (ns helloworld   Classname


 
:gen-class sample
    (ns helloworld
      (:gen-class))   Execute AOT
 
:gen-class sample
    (ns helloworld
      (:gen-class))
 
    (defn -main [& args]   the main function
:gen-class sample
    (ns helloworld
      (:gen-class))
 
    (defn -main [& args]
      (println "Hello world!"))   the main’s body
:gen-class sample
    (ns helloworld
      (:gen-class))
 
    (defn -main [& args]
      (println "Hello world!"))
AOT in Practice

• lein new [project-name]
• Add :main to project.clj
• lein uberjar
• java -jar [project-name-ver-standalone.jar]
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/
$ mvn archetype:generate 
  -DarchetypeArtifactId=maven-archetype-webapp 
  -DgroupId=com.mycompany.app 
  -DartifactId=my-webapp-demo
$ mvn archetype:generate 
  -DarchetypeArtifactId=maven-archetype-webapp 
  -DgroupId=com.mycompany.app 
  -DartifactId=my-webapp-demo
$ lein new my-webapp-demo-clj
$ 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))
$ 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))
(defproject my-webapp-demo-clj "1.0.0-SNAPSHOT"
  :description "FIXME: write description"
  :dependencies [[org.clojure/clojure "1.3.0"]]
  :aot :all)
(defproject my-webapp-demo-clj "1.0.0-SNAPSHOT"
  :description "FIXME: write description"
  :dependencies [[org.clojure/clojure "1.3.0"]]
  :aot :all)
$ lein install
(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>
<html>
<body>
<h2>Hello World!</h2>
</body>
<p>
 <%= new my_webapp_demo_clj.core().hello("Jacek") %>
</p>
</html>
<html>
<body>
<h2>Hello World!</h2>
</body>
<p>
 <%= new my_webapp_demo_clj.core().hello("Jacek") %>
</p>
</html>
$ mvn package
<html>
<body>
<h2>Hello World!</h2>
</body>
<p>
 <%= new my_webapp_demo_clj.core().hello("Jacek") %>
</p>
</html>
$ mvn package
Reason #5
Easy Java interop both
         ways
Leiningen
lein - a project automation tool
Starting a project

• lein new [project-name]
 • Edit project.clj (mainly deps)
 • Also plugin configuration, e.g. :main for
    run (soon explained)
Custom project setup
   defproject in project.clj customized
Dependencies


• lein deps
• lein search [library]
clojars
Maven repository for Clojure projects
         http://clojars.org/
Ongoing development
• lein repl
• lein eclipse
• lein midje (“formerly” lein test)
• lein run
• lein jar
• Some require custom setup...
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)
lein test [ns]
Runs project tests, optionally only from a ns
src/hi/core.clj
(ns hi.core)

(defn hi
 ([] "Hi!")
 ([name] (str "Hi " name "!")))
lein test
$ lein test
Copying 1 file to /Users/jacek/sandbox/hi/lib

Testing hi.test.core

FAIL in (replace-me) (core.clj:6)
No tests have been written.
expected: false
 actual: false

Ran 1 tests containing 1 assertions.
1 failures, 0 errors.
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!")))
lein test
$ lein test

Testing hi.test.core

Ran 1 tests containing 2 assertions.
0 failures, 0 errors.
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)
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
TDD with Midje #0

• :repositories
  ["stuart" "http://stuartsierra.com/maven2"]
• :dev-dependencies
  [com.stuartsierra/lazytest "1.2.3"]
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.db

FAIL at (core.clj:10)
  Expected: 2
   Actual: 3

FAIL at (core.clj:10)
  Expected: 2
   Actual: 3

FAILURE: 1 fact was not confirmed. (But 1 was.)

Done.

======================================
At #<Date Tue Feb 21 13:08:11 CET 2012>

Reloading librarian-clojure.test.core
All claimed facts (2) have been confirmed.

Done.
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
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
Reason #6
Familiar-looking project
          tools
Ring
Clojure HTTP server applications
https://github.com/mmcgrana/ring
Compojure
  A concise web framework for Clojure
https://github.com/weavejester/compojure
Ring up

jacek:~/oss/librarian-clojure
$ lein ring server


:ring {:handler librarian-clojure.core/app}
Reason #7
Web application libraries
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/
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 multimethod
'say-class' for dispatch value: class clojure.lang.PersistentVector
(NO_SOURCE_FILE:0)

user=> (defmethod say-class (class []) [_] "A vector")
user=> (say-class [])
"A vector"
Reason #8
Multi-level dispatch
Are you still uncertain?

 There’s more, but...
time flies by so fast :(

Weitere ähnliche Inhalte

Was ist angesagt?

The Ring programming language version 1.6 book - Part 15 of 189
The Ring programming language version 1.6 book - Part 15 of 189The Ring programming language version 1.6 book - Part 15 of 189
The Ring programming language version 1.6 book - Part 15 of 189Mahmoud Samir Fayed
 
From Java to Parellel Clojure - Clojure South 2019
From Java to Parellel Clojure - Clojure South 2019From Java to Parellel Clojure - Clojure South 2019
From Java to Parellel Clojure - Clojure South 2019Leonardo Borges
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)Pavlo Baron
 
T3chFest 2016 - The polyglot programmer
T3chFest 2016 - The polyglot programmerT3chFest 2016 - The polyglot programmer
T3chFest 2016 - The polyglot programmerDavid Muñoz Díaz
 
The Ring programming language version 1.6 book - Part 36 of 189
The Ring programming language version 1.6 book - Part 36 of 189The Ring programming language version 1.6 book - Part 36 of 189
The Ring programming language version 1.6 book - Part 36 of 189Mahmoud Samir Fayed
 
The Ring programming language version 1.7 book - Part 16 of 196
The Ring programming language version 1.7 book - Part 16 of 196The Ring programming language version 1.7 book - Part 16 of 196
The Ring programming language version 1.7 book - Part 16 of 196Mahmoud Samir Fayed
 
Clojure 1.1 And Beyond
Clojure 1.1 And BeyondClojure 1.1 And Beyond
Clojure 1.1 And BeyondMike Fogus
 
ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015Michiel Borkent
 
Clojure for Java developers - Stockholm
Clojure for Java developers - StockholmClojure for Java developers - Stockholm
Clojure for Java developers - StockholmJan Kronquist
 
Java 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardMario Fusco
 
Programmation fonctionnelle en JavaScript
Programmation fonctionnelle en JavaScriptProgrammation fonctionnelle en JavaScript
Programmation fonctionnelle en JavaScriptLoïc Knuchel
 
ES6 - Next Generation Javascript
ES6 - Next Generation JavascriptES6 - Next Generation Javascript
ES6 - Next Generation JavascriptRamesh Nair
 
G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門Tsuyoshi Yamamoto
 
Jggug 2010 330 Grails 1.3 観察
Jggug 2010 330 Grails 1.3 観察Jggug 2010 330 Grails 1.3 観察
Jggug 2010 330 Grails 1.3 観察Tsuyoshi Yamamoto
 
The Ring programming language version 1.8 book - Part 86 of 202
The Ring programming language version 1.8 book - Part 86 of 202The Ring programming language version 1.8 book - Part 86 of 202
The Ring programming language version 1.8 book - Part 86 of 202Mahmoud Samir Fayed
 
GUL UC3M - Introduction to functional programming
GUL UC3M - Introduction to functional programmingGUL UC3M - Introduction to functional programming
GUL UC3M - Introduction to functional programmingDavid Muñoz Díaz
 
ES2015 (ES6) Overview
ES2015 (ES6) OverviewES2015 (ES6) Overview
ES2015 (ES6) Overviewhesher
 

Was ist angesagt? (20)

Scala coated JVM
Scala coated JVMScala coated JVM
Scala coated JVM
 
The Ring programming language version 1.6 book - Part 15 of 189
The Ring programming language version 1.6 book - Part 15 of 189The Ring programming language version 1.6 book - Part 15 of 189
The Ring programming language version 1.6 book - Part 15 of 189
 
From Java to Parellel Clojure - Clojure South 2019
From Java to Parellel Clojure - Clojure South 2019From Java to Parellel Clojure - Clojure South 2019
From Java to Parellel Clojure - Clojure South 2019
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)
 
Sneaking inside Kotlin features
Sneaking inside Kotlin featuresSneaking inside Kotlin features
Sneaking inside Kotlin features
 
T3chFest 2016 - The polyglot programmer
T3chFest 2016 - The polyglot programmerT3chFest 2016 - The polyglot programmer
T3chFest 2016 - The polyglot programmer
 
The Ring programming language version 1.6 book - Part 36 of 189
The Ring programming language version 1.6 book - Part 36 of 189The Ring programming language version 1.6 book - Part 36 of 189
The Ring programming language version 1.6 book - Part 36 of 189
 
The Ring programming language version 1.7 book - Part 16 of 196
The Ring programming language version 1.7 book - Part 16 of 196The Ring programming language version 1.7 book - Part 16 of 196
The Ring programming language version 1.7 book - Part 16 of 196
 
Clojure 1.1 And Beyond
Clojure 1.1 And BeyondClojure 1.1 And Beyond
Clojure 1.1 And Beyond
 
ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015
 
Clojure for Java developers - Stockholm
Clojure for Java developers - StockholmClojure for Java developers - Stockholm
Clojure for Java developers - Stockholm
 
Java 8 Workshop
Java 8 WorkshopJava 8 Workshop
Java 8 Workshop
 
Java 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forward
 
Programmation fonctionnelle en JavaScript
Programmation fonctionnelle en JavaScriptProgrammation fonctionnelle en JavaScript
Programmation fonctionnelle en JavaScript
 
ES6 - Next Generation Javascript
ES6 - Next Generation JavascriptES6 - Next Generation Javascript
ES6 - Next Generation Javascript
 
G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門
 
Jggug 2010 330 Grails 1.3 観察
Jggug 2010 330 Grails 1.3 観察Jggug 2010 330 Grails 1.3 観察
Jggug 2010 330 Grails 1.3 観察
 
The Ring programming language version 1.8 book - Part 86 of 202
The Ring programming language version 1.8 book - Part 86 of 202The Ring programming language version 1.8 book - Part 86 of 202
The Ring programming language version 1.8 book - Part 86 of 202
 
GUL UC3M - Introduction to functional programming
GUL UC3M - Introduction to functional programmingGUL UC3M - Introduction to functional programming
GUL UC3M - Introduction to functional programming
 
ES2015 (ES6) Overview
ES2015 (ES6) OverviewES2015 (ES6) Overview
ES2015 (ES6) Overview
 

Andere mochten auch

Introduction to clojure
Introduction to clojureIntroduction to clojure
Introduction to clojureAbbas Raza
 
A little exercise with clojure macro
A little exercise with clojure macroA little exercise with clojure macro
A little exercise with clojure macroZehua Liu
 
Clojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVMClojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVMsunng87
 
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013Leonardo Borges
 
不自然なcar/ナチュラルにconsして
不自然なcar/ナチュラルにconsして不自然なcar/ナチュラルにconsして
不自然なcar/ナチュラルにconsしてmitsutaka mimura
 
Macros in Clojure
Macros in ClojureMacros in Clojure
Macros in Clojuresohta
 
入門ClojureScript
入門ClojureScript入門ClojureScript
入門ClojureScriptsohta
 
Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012Leonardo Borges
 
Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...
Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...
Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...AboutYouGmbH
 
Clojureシンタックスハイライター開発から考えるこれからのlispに必要なもの
Clojureシンタックスハイライター開発から考えるこれからのlispに必要なものClojureシンタックスハイライター開発から考えるこれからのlispに必要なもの
Clojureシンタックスハイライター開発から考えるこれからのlispに必要なものsohta
 
Winning the Erlang Edit•Build•Test Cycle
Winning the Erlang Edit•Build•Test CycleWinning the Erlang Edit•Build•Test Cycle
Winning the Erlang Edit•Build•Test CycleRusty Klophaus
 
Messaging With Erlang And Jabber
Messaging With  Erlang And  JabberMessaging With  Erlang And  Jabber
Messaging With Erlang And Jabberl xf
 

Andere mochten auch (20)

Clojure: a LISP for the JVM
Clojure: a LISP for the JVMClojure: a LISP for the JVM
Clojure: a LISP for the JVM
 
Introduction to clojure
Introduction to clojureIntroduction to clojure
Introduction to clojure
 
DSL in Clojure
DSL in ClojureDSL in Clojure
DSL in Clojure
 
A little exercise with clojure macro
A little exercise with clojure macroA little exercise with clojure macro
A little exercise with clojure macro
 
Clojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVMClojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVM
 
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013
 
A Dive Into Clojure
A Dive Into ClojureA Dive Into Clojure
A Dive Into Clojure
 
不自然なcar/ナチュラルにconsして
不自然なcar/ナチュラルにconsして不自然なcar/ナチュラルにconsして
不自然なcar/ナチュラルにconsして
 
Writing Macros
Writing MacrosWriting Macros
Writing Macros
 
Patterns
PatternsPatterns
Patterns
 
Macros in Clojure
Macros in ClojureMacros in Clojure
Macros in Clojure
 
入門ClojureScript
入門ClojureScript入門ClojureScript
入門ClojureScript
 
Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012
 
Clojure的魅力
Clojure的魅力Clojure的魅力
Clojure的魅力
 
Clojure概览
Clojure概览Clojure概览
Clojure概览
 
Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...
Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...
Stefan Richter - Writing simple, readable and robust code: Examples in Java, ...
 
Clojureシンタックスハイライター開発から考えるこれからのlispに必要なもの
Clojureシンタックスハイライター開発から考えるこれからのlispに必要なものClojureシンタックスハイライター開発から考えるこれからのlispに必要なもの
Clojureシンタックスハイライター開発から考えるこれからのlispに必要なもの
 
Winning the Erlang Edit•Build•Test Cycle
Winning the Erlang Edit•Build•Test CycleWinning the Erlang Edit•Build•Test Cycle
Winning the Erlang Edit•Build•Test Cycle
 
Messaging With Erlang And Jabber
Messaging With  Erlang And  JabberMessaging With  Erlang And  Jabber
Messaging With Erlang And Jabber
 
Elixir talk
Elixir talkElixir talk
Elixir talk
 

Ähnlich wie (map Clojure everyday-tasks)

Clojure - A new Lisp
Clojure - A new LispClojure - A new Lisp
Clojure - A new Lispelliando dias
 
Clojure Intro
Clojure IntroClojure Intro
Clojure Introthnetos
 
Exploring Clojurescript
Exploring ClojurescriptExploring Clojurescript
Exploring ClojurescriptLuke Donnet
 
Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)Phil Calçado
 
Clojure made-simple - John Stevenson
Clojure made-simple - John StevensonClojure made-simple - John Stevenson
Clojure made-simple - John StevensonJAX London
 
Clojure and Modularity
Clojure and ModularityClojure and Modularity
Clojure and Modularityelliando dias
 
Php 5.4: New Language Features You Will Find Useful
Php 5.4: New Language Features You Will Find UsefulPhp 5.4: New Language Features You Will Find Useful
Php 5.4: New Language Features You Will Find UsefulDavid Engel
 
Getting started with Clojure
Getting started with ClojureGetting started with Clojure
Getting started with ClojureJohn Stevenson
 
Clojure made simple - Lightning talk
Clojure made simple - Lightning talkClojure made simple - Lightning talk
Clojure made simple - Lightning talkJohn Stevenson
 
ClojureScript for the web
ClojureScript for the webClojureScript for the web
ClojureScript for the webMichiel Borkent
 
Functional programming with clojure
Functional programming with clojureFunctional programming with clojure
Functional programming with clojureLucy Fang
 
Predictably
PredictablyPredictably
Predictablyztellman
 
Clojure concurrency overview
Clojure concurrency overviewClojure concurrency overview
Clojure concurrency overviewSergey Stupin
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing UpDavid Padbury
 
Funkcija, objekt, python
Funkcija, objekt, pythonFunkcija, objekt, python
Funkcija, objekt, pythonRobert Lujo
 

Ähnlich wie (map Clojure everyday-tasks) (20)

Pune Clojure Course Outline
Pune Clojure Course OutlinePune Clojure Course Outline
Pune Clojure Course Outline
 
Clojure - A new Lisp
Clojure - A new LispClojure - A new Lisp
Clojure - A new Lisp
 
Clojure Intro
Clojure IntroClojure Intro
Clojure Intro
 
Clojure And Swing
Clojure And SwingClojure And Swing
Clojure And Swing
 
Exploring Clojurescript
Exploring ClojurescriptExploring Clojurescript
Exploring Clojurescript
 
Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)
 
Clojure made-simple - John Stevenson
Clojure made-simple - John StevensonClojure made-simple - John Stevenson
Clojure made-simple - John Stevenson
 
Clojure and Modularity
Clojure and ModularityClojure and Modularity
Clojure and Modularity
 
Php 5.4: New Language Features You Will Find Useful
Php 5.4: New Language Features You Will Find UsefulPhp 5.4: New Language Features You Will Find Useful
Php 5.4: New Language Features You Will Find Useful
 
Getting started with Clojure
Getting started with ClojureGetting started with Clojure
Getting started with Clojure
 
Clojure made simple - Lightning talk
Clojure made simple - Lightning talkClojure made simple - Lightning talk
Clojure made simple - Lightning talk
 
Clojure intro
Clojure introClojure intro
Clojure intro
 
ClojureScript for the web
ClojureScript for the webClojureScript for the web
ClojureScript for the web
 
DevOps with Fabric
DevOps with FabricDevOps with Fabric
DevOps with Fabric
 
Functional programming with clojure
Functional programming with clojureFunctional programming with clojure
Functional programming with clojure
 
Predictably
PredictablyPredictably
Predictably
 
Clojure concurrency overview
Clojure concurrency overviewClojure concurrency overview
Clojure concurrency overview
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
Funkcija, objekt, python
Funkcija, objekt, pythonFunkcija, objekt, python
Funkcija, objekt, python
 
Clojure+ClojureScript Webapps
Clojure+ClojureScript WebappsClojure+ClojureScript Webapps
Clojure+ClojureScript Webapps
 

Mehr von Jacek Laskowski

 Kafka Streams VS Spark Structured Streaming - Modern Stream Processing Engin...
 Kafka Streams VS Spark Structured Streaming - Modern Stream Processing Engin... Kafka Streams VS Spark Structured Streaming - Modern Stream Processing Engin...
 Kafka Streams VS Spark Structured Streaming - Modern Stream Processing Engin...Jacek Laskowski
 
Opening slides to Warsaw Scala FortyFives on Testing tools
Opening slides to Warsaw Scala FortyFives on Testing toolsOpening slides to Warsaw Scala FortyFives on Testing tools
Opening slides to Warsaw Scala FortyFives on Testing toolsJacek Laskowski
 
#Be #social #FTW aka Your #Professional #Development with #StackOverflow #Git...
#Be #social #FTW aka Your #Professional #Development with #StackOverflow #Git...#Be #social #FTW aka Your #Professional #Development with #StackOverflow #Git...
#Be #social #FTW aka Your #Professional #Development with #StackOverflow #Git...Jacek Laskowski
 
StackOverflow, GitHub, twitter, reddit i Twój profesjonalny rozwój
StackOverflow, GitHub, twitter, reddit i Twój profesjonalny rozwójStackOverflow, GitHub, twitter, reddit i Twój profesjonalny rozwój
StackOverflow, GitHub, twitter, reddit i Twój profesjonalny rozwójJacek Laskowski
 
Introduction to Web Application Development in Clojure
Introduction to Web Application Development in ClojureIntroduction to Web Application Development in Clojure
Introduction to Web Application Development in ClojureJacek Laskowski
 
Introduction to Functional Programming in Scala
Introduction to Functional Programming in ScalaIntroduction to Functional Programming in Scala
Introduction to Functional Programming in ScalaJacek Laskowski
 
Moje pierwsze kroki w programowaniu funkcyjnym w Scali
Moje pierwsze kroki w programowaniu funkcyjnym w ScaliMoje pierwsze kroki w programowaniu funkcyjnym w Scali
Moje pierwsze kroki w programowaniu funkcyjnym w ScaliJacek Laskowski
 
Functional web development with Git(Hub), Heroku and Clojure
Functional web development with Git(Hub), Heroku and ClojureFunctional web development with Git(Hub), Heroku and Clojure
Functional web development with Git(Hub), Heroku and ClojureJacek Laskowski
 
Praktyczne wprowadzenie do OSGi i Enterprise OSGi
Praktyczne wprowadzenie do OSGi i Enterprise OSGiPraktyczne wprowadzenie do OSGi i Enterprise OSGi
Praktyczne wprowadzenie do OSGi i Enterprise OSGiJacek Laskowski
 
Developing modular applications with Java EE 6 and Enterprise OSGi + WebSpher...
Developing modular applications with Java EE 6 and Enterprise OSGi + WebSpher...Developing modular applications with Java EE 6 and Enterprise OSGi + WebSpher...
Developing modular applications with Java EE 6 and Enterprise OSGi + WebSpher...Jacek Laskowski
 
Apache Tomcat + Java EE = Apache TomEE
Apache Tomcat + Java EE = Apache TomEEApache Tomcat + Java EE = Apache TomEE
Apache Tomcat + Java EE = Apache TomEEJacek Laskowski
 

Mehr von Jacek Laskowski (11)

 Kafka Streams VS Spark Structured Streaming - Modern Stream Processing Engin...
 Kafka Streams VS Spark Structured Streaming - Modern Stream Processing Engin... Kafka Streams VS Spark Structured Streaming - Modern Stream Processing Engin...
 Kafka Streams VS Spark Structured Streaming - Modern Stream Processing Engin...
 
Opening slides to Warsaw Scala FortyFives on Testing tools
Opening slides to Warsaw Scala FortyFives on Testing toolsOpening slides to Warsaw Scala FortyFives on Testing tools
Opening slides to Warsaw Scala FortyFives on Testing tools
 
#Be #social #FTW aka Your #Professional #Development with #StackOverflow #Git...
#Be #social #FTW aka Your #Professional #Development with #StackOverflow #Git...#Be #social #FTW aka Your #Professional #Development with #StackOverflow #Git...
#Be #social #FTW aka Your #Professional #Development with #StackOverflow #Git...
 
StackOverflow, GitHub, twitter, reddit i Twój profesjonalny rozwój
StackOverflow, GitHub, twitter, reddit i Twój profesjonalny rozwójStackOverflow, GitHub, twitter, reddit i Twój profesjonalny rozwój
StackOverflow, GitHub, twitter, reddit i Twój profesjonalny rozwój
 
Introduction to Web Application Development in Clojure
Introduction to Web Application Development in ClojureIntroduction to Web Application Development in Clojure
Introduction to Web Application Development in Clojure
 
Introduction to Functional Programming in Scala
Introduction to Functional Programming in ScalaIntroduction to Functional Programming in Scala
Introduction to Functional Programming in Scala
 
Moje pierwsze kroki w programowaniu funkcyjnym w Scali
Moje pierwsze kroki w programowaniu funkcyjnym w ScaliMoje pierwsze kroki w programowaniu funkcyjnym w Scali
Moje pierwsze kroki w programowaniu funkcyjnym w Scali
 
Functional web development with Git(Hub), Heroku and Clojure
Functional web development with Git(Hub), Heroku and ClojureFunctional web development with Git(Hub), Heroku and Clojure
Functional web development with Git(Hub), Heroku and Clojure
 
Praktyczne wprowadzenie do OSGi i Enterprise OSGi
Praktyczne wprowadzenie do OSGi i Enterprise OSGiPraktyczne wprowadzenie do OSGi i Enterprise OSGi
Praktyczne wprowadzenie do OSGi i Enterprise OSGi
 
Developing modular applications with Java EE 6 and Enterprise OSGi + WebSpher...
Developing modular applications with Java EE 6 and Enterprise OSGi + WebSpher...Developing modular applications with Java EE 6 and Enterprise OSGi + WebSpher...
Developing modular applications with Java EE 6 and Enterprise OSGi + WebSpher...
 
Apache Tomcat + Java EE = Apache TomEE
Apache Tomcat + Java EE = Apache TomEEApache Tomcat + Java EE = Apache TomEE
Apache Tomcat + Java EE = Apache TomEE
 

Kürzlich hochgeladen

#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 

Kürzlich hochgeladen (20)

#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 

(map Clojure everyday-tasks)

  • 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 comprehension function (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 Clojure 1st item (fn arg1 arg2 ...) 3rd item 2nd item
  • 10. Function calls in Clojure function name (fn arg1 arg2 ...) function param function param
  • 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)
  • 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 function Examples: addVat, convertCurrency http://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
  • 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
  • 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"))))
  • 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/ptrn user=> (class ptrn) java.util.regex.Pattern user=> (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*)
  • 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 #5 Easy Java interop both ways
  • 64. Leiningen lein - 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. clojars Maven 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 test Copying 1 file to /Users/jacek/sandbox/hi/lib Testing hi.test.core FAIL in (replace-me) (core.clj:6) No tests have been written. expected: false actual: false Ran 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 test Testing hi.test.core Ran 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.db FAIL at (core.clj:10) Expected: 2 Actual: 3 FAIL at (core.clj:10) Expected: 2 Actual: 3 FAILURE: 1 fact was not confirmed. (But 1 was.) Done. ====================================== At #<Date Tue Feb 21 13:08:11 CET 2012> Reloading librarian-clojure.test.core All 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
  • 83. Ring Clojure HTTP server applications https://github.com/mmcgrana/ring
  • 84. Compojure A concise web framework for Clojure https://github.com/weavejester/compojure
  • 85. Ring up jacek:~/oss/librarian-clojure $ lein ring server :ring {:handler librarian-clojure.core/app}
  • 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 multimethod 'say-class' for dispatch value: class clojure.lang.PersistentVector (NO_SOURCE_FILE:0) user=> (defmethod say-class (class []) [_] "A vector") user=> (say-class []) "A vector"
  • 90. Are you still uncertain? There’s more, but... time flies by so fast :(

Hinweis der Redaktion

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n