SlideShare uma empresa Scribd logo
1 de 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 :(

Mais conteúdo relacionado

Mais procurados

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
 

Mais procurados (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
 

Destaque

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
 

Destaque (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
 

Semelhante a (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
 

Semelhante a (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
 

Mais de 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
 

Mais de 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
 

Último

Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 

Último (20)

Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 

(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 :(

Notas do Editor

  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