SlideShare a Scribd company logo
1 of 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 :(

More Related Content

What's hot

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
 

What's hot (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
 

Viewers also liked

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
 

Viewers also liked (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
 

Similar to (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
 

Similar to (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
 

More from 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
 

More from 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
 

Recently uploaded

Google I/O Extended 2024 Warsaw
Google I/O Extended 2024 WarsawGoogle I/O Extended 2024 Warsaw
Google I/O Extended 2024 WarsawGDSC PJATK
 
WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024Lorenzo Miniero
 
Introduction to FIDO Authentication and Passkeys.pptx
Introduction to FIDO Authentication and Passkeys.pptxIntroduction to FIDO Authentication and Passkeys.pptx
Introduction to FIDO Authentication and Passkeys.pptxFIDO Alliance
 
Vector Search @ sw2con for slideshare.pptx
Vector Search @ sw2con for slideshare.pptxVector Search @ sw2con for slideshare.pptx
Vector Search @ sw2con for slideshare.pptxjbellis
 
Design and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data ScienceDesign and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data SciencePaolo Missier
 
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdfWhere to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdfFIDO Alliance
 
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdfLinux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdfFIDO Alliance
 
How we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdfHow we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdfSrushith Repakula
 
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc
 
Collecting & Temporal Analysis of Behavioral Web Data - Tales From The Inside
Collecting & Temporal Analysis of Behavioral Web Data - Tales From The InsideCollecting & Temporal Analysis of Behavioral Web Data - Tales From The Inside
Collecting & Temporal Analysis of Behavioral Web Data - Tales From The InsideStefan Dietze
 
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Paige Cruz
 
Long journey of Ruby Standard library at RubyKaigi 2024
Long journey of Ruby Standard library at RubyKaigi 2024Long journey of Ruby Standard library at RubyKaigi 2024
Long journey of Ruby Standard library at RubyKaigi 2024Hiroshi SHIBATA
 
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on ThanabotsContinuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on ThanabotsLeah Henrickson
 
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...FIDO Alliance
 
ADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptxADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptxFIDO Alliance
 
WebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM PerformanceWebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM PerformanceSamy Fodil
 
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Skynet Technologies
 
Working together SRE & Platform Engineering
Working together SRE & Platform EngineeringWorking together SRE & Platform Engineering
Working together SRE & Platform EngineeringMarcus Vechiato
 
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...FIDO Alliance
 
Portal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russePortal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russe中 央社
 

Recently uploaded (20)

Google I/O Extended 2024 Warsaw
Google I/O Extended 2024 WarsawGoogle I/O Extended 2024 Warsaw
Google I/O Extended 2024 Warsaw
 
WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024
 
Introduction to FIDO Authentication and Passkeys.pptx
Introduction to FIDO Authentication and Passkeys.pptxIntroduction to FIDO Authentication and Passkeys.pptx
Introduction to FIDO Authentication and Passkeys.pptx
 
Vector Search @ sw2con for slideshare.pptx
Vector Search @ sw2con for slideshare.pptxVector Search @ sw2con for slideshare.pptx
Vector Search @ sw2con for slideshare.pptx
 
Design and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data ScienceDesign and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data Science
 
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdfWhere to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
 
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdfLinux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
 
How we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdfHow we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdf
 
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
 
Collecting & Temporal Analysis of Behavioral Web Data - Tales From The Inside
Collecting & Temporal Analysis of Behavioral Web Data - Tales From The InsideCollecting & Temporal Analysis of Behavioral Web Data - Tales From The Inside
Collecting & Temporal Analysis of Behavioral Web Data - Tales From The Inside
 
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
 
Long journey of Ruby Standard library at RubyKaigi 2024
Long journey of Ruby Standard library at RubyKaigi 2024Long journey of Ruby Standard library at RubyKaigi 2024
Long journey of Ruby Standard library at RubyKaigi 2024
 
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on ThanabotsContinuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
 
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
 
ADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptxADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptx
 
WebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM PerformanceWebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM Performance
 
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
 
Working together SRE & Platform Engineering
Working together SRE & Platform EngineeringWorking together SRE & Platform Engineering
Working together SRE & Platform Engineering
 
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
 
Portal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russePortal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russe
 

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

Editor's Notes

  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