Refactoring to Macros with Clojure

Dmitry Buzdin
Dmitry BuzdinSoftware Architect à Dmitry Buzdin
Refactoring to Macros
with Clojure
Dimitry Solovyov
@dimituri
Let's talk about
FUNCTIONAL PROGRAMMING
Refactoring to Macros with Clojure
liftIO	
  $	
  atomicModifyIORef	
  sc	
  $	
  n	
  -­‐>	
  (n	
  +	
  1,	
  ())
d	
  <-­‐	
  f	
  v	
  >>:	
  onInner
liftIO	
  $	
  ds	
  `addDisposable`	
  d
Refactoring to Macros with Clojure
Refactoring to Macros with Clojure
Refactoring to Macros with Clojure
>>:
Let's talk about
LISP
LISP in 3 minutes
via @bodiltv
object.method(a, b);
object.method( a b)
Refactoring to Macros with Clojure
Clojure





It's a Lisp
Compiled
Dynamic types
Type hints
Macros
Clojure







It's a Lisp
Compiled
Dynamic types
Type hints
Macros
Optional static types
Optional Prolog
http://clojure.org/java_interop
HttpServer	
  server	
  =	
  HttpServer.create(address,	
  0);
server.createContext(path,	
  handler);
server.setExecutor(null);
server.start();
HttpServer	
  server	
  =	
  HttpServer.create(address,	
  0);
server.createContext(path,	
  handler);
server.setExecutor(null);
server.start();
(doto	
  (HttpServer/create	
  address	
  0)
	
  	
  (.createContext	
  path	
  handler)
	
  	
  (.setExecutor	
  nil)
	
  	
  (.start))
macro |ˈmakrəәʊ|
noun ( pl. macros )
1 (also macro instruction) Computing a single instruction
that expands automatically into a set of instructions
to perform a particular task.
(let*	
  [G__360	
  (HttpServer/create	
  address	
  0)]
	
  	
  (.createContext	
  G__360	
  path	
  handler)
	
  	
  (.setExecutor	
  G__360	
  nil)
	
  	
  (.start	
  G__360)
	
  	
  G__360)
(doto	
  (HttpServer/create	
  address	
  0)
	
  	
  (.createContext	
  path	
  handler)
	
  	
  (.setExecutor	
  nil)
	
  	
  (.start))
根性
.println(Encoding.encodeBase64(Encoding.decodeUrl(Encoding.decodeBas
String	
  url	
  =	
  Encoding.decodeBase64(b);
String	
  decodedUrl	
  =	
  Encoding.decodeUrl(url);
String	
  encodedUrl	
  =	
  Encoding.encodeBase64(decodedUrl);
System.out.println(encodedUrl);
String	
  url	
  =	
  Encoding.decodeBase64(b);
String	
  decodedUrl	
  =	
  Encoding.decodeUrl(url);
String	
  encodedUrl	
  =	
  Encoding.encodeBase64(decodedUrl);
System.out.println(encodedUrl);
(-­‐>	
  b
	
  	
  Encoding/decodeBase64
	
  	
  Encoding/decodeUrl
	
  	
  Encoding/encodeBase64
	
  	
  println)
-­‐>
(-­‐>	
  stuff
	
  	
  (foo	
  ,,,	
  a)
	
  	
  (bar	
  ,,,	
  b	
  c	
  d)
	
  	
  (baz	
  ,,,	
  e	
  f))
-­‐>>-­‐>
(-­‐>	
  stuff
	
  	
  (foo	
  ,,,	
  a)
	
  	
  (bar	
  ,,,	
  b	
  c	
  d)
	
  	
  (baz	
  ,,,	
  e	
  f))
(-­‐>>	
  stuff
	
  	
  (foo	
  a	
  ,,,)
	
  	
  (bar	
  b	
  c	
  d	
  ,,,)
	
  	
  (baz	
  e	
  f	
  ,,,))
-­‐<>-­‐>>-­‐>
(-­‐>	
  stuff
	
  	
  (foo	
  ,,,	
  a)
	
  	
  (bar	
  ,,,	
  b	
  c	
  d)
	
  	
  (baz	
  ,,,	
  e	
  f))
(-­‐>>	
  stuff
	
  	
  (foo	
  a	
  ,,,)
	
  	
  (bar	
  b	
  c	
  d	
  ,,,)
	
  	
  (baz	
  e	
  f	
  ,,,))
(-­‐<>	
  stuff
	
  	
  (foo	
  a	
  <>)
	
  	
  (bar	
  b	
  c	
  <>	
  d)
	
  	
  (baz	
  <>	
  e	
  f))
“Swiss Arrows”
-­‐<>> -­‐?<> -­‐!> -­‐!>>
-­‐!<> <<-­‐ -­‐< -­‐<:p
-­‐<< -­‐<<:p -­‐<>< -­‐<><:p
https://github.com/rplevy/swiss-arrows
-­‐<<:p
-­‐<<:p
Q: How do I get the result from a
chain of computatoins that may fail?
PhoneNumber	
  number	
  =	
  phoneMap.get(person);
if	
  (number	
  !=	
  null)	
  {
	
  	
  	
  	
  Carrier	
  carrier	
  =	
  carrierMap.get(number);
	
  	
  	
  	
  if	
  (carrier	
  !=	
  null)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  return	
  addressMap.get(address);
	
  	
  	
  	
  }
}
return	
  null;
WHAT YOU'RE LOOKING FOR
IS AN OPTION MONAD
Refactoring to Macros with Clojure
PhoneNumber	
  number	
  =	
  phoneMap.get(person);
if	
  (number	
  !=	
  null)	
  {
	
  	
  	
  	
  Carrier	
  carrier	
  =	
  carrierMap.get(number);
	
  	
  	
  	
  if	
  (carrier	
  !=	
  null)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  return	
  addressMap.get(address);
	
  	
  	
  	
  }
}
return	
  null;
(some-­‐>>
	
  	
  (.get	
  phoneMap	
  person)
	
  	
  (.get	
  carrierMap)
	
  	
  (.get	
  addressMap))
Clojure vectors implement
java.lang.Comparable
java.util.RandomAccess
All Clojure functions implement
java.util.Comparator
java.lang.Runnable
java.util.concurrent.Callable
List<Integer>	
  numbers	
  =	
  Arrays.asList(1,	
  3,	
  4,	
  8,	
  2);
Collections.sort(numbers,	
  new	
  Comparator<Integer>()	
  {
	
  	
  	
  	
  @Override
	
  	
  	
  	
  public	
  int	
  compare(Integer	
  o1,	
  Integer	
  o2)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  return	
  o2.compareTo(o1);
	
  	
  	
  	
  }
});
List<Integer>	
  numbers	
  =	
  Arrays.asList(1,	
  3,	
  4,	
  8,	
  2);
Collections.sort(numbers,	
  new	
  Comparator<Integer>()	
  {
	
  	
  	
  	
  @Override
	
  	
  	
  	
  public	
  int	
  compare(Integer	
  o1,	
  Integer	
  o2)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  return	
  o2.compareTo(o1);
	
  	
  	
  	
  }
});
List<Integer>	
  numbers	
  =	
  Arrays.asList(1,	
  3,	
  4,	
  8,	
  2);
Collections.sort(numbers,	
  (o1,	
  o2)	
  -­‐>	
  o2.compareTo(o1));
List<Integer>	
  numbers	
  =	
  Arrays.asList(1,	
  3,	
  4,	
  8,	
  2);
Collections.sort(numbers,	
  new	
  Comparator<Integer>()	
  {
	
  	
  	
  	
  @Override
	
  	
  	
  	
  public	
  int	
  compare(Integer	
  o1,	
  Integer	
  o2)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  return	
  o2.compareTo(o1);
	
  	
  	
  	
  }
});
(doto	
  (ArrayList.	
  [1	
  3	
  4	
  8	
  2])
	
  	
  (Collections/sort	
  (fn	
  [o1	
  o2]	
  (.compareTo	
  o2	
  o1))))
List<Integer>	
  numbers	
  =	
  Arrays.asList(1,	
  3,	
  4,	
  8,	
  2);
Collections.sort(numbers,	
  (o1,	
  o2)	
  -­‐>	
  o2.compareTo(o1));
List<Integer>	
  numbers	
  =	
  Arrays.asList(1,	
  3,	
  4,	
  8,	
  2);
Collections.sort(numbers,	
  new	
  Comparator<Integer>()	
  {
	
  	
  	
  	
  @Override
	
  	
  	
  	
  public	
  int	
  compare(Integer	
  o1,	
  Integer	
  o2)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  return	
  o2.compareTo(o1);
	
  	
  	
  	
  }
});
(doto	
  (ArrayList.	
  [1	
  3	
  4	
  8	
  2])
	
  	
  (Collections/sort	
  (fn	
  [o1	
  o2]	
  (.compareTo	
  o2	
  o1))))
(sort	
  #(compare	
  %2	
  %1)	
  [1	
  3	
  4	
  8	
  2])
List<Integer>	
  numbers	
  =	
  Arrays.asList(1,	
  3,	
  4,	
  8,	
  2);
Collections.sort(numbers,	
  (o1,	
  o2)	
  -­‐>	
  o2.compareTo(o1));
Refactoring to Macros with Clojure
(defn	
  len-­‐reflected	
  [s]
	
  	
  (.length	
  s))
(defn	
  len-­‐hinted	
  ^String	
  [^String	
  s]
	
  	
  (.length	
  s))
user=>	
  (time	
  (dotimes	
  [i	
  1000000]	
  (len-­‐reflected	
  (str	
  i))))
"Elapsed	
  time:	
  3204.913	
  msecs"
nil
user=>	
  (time	
  (dotimes	
  [i	
  1000000]	
  (len-­‐hinted	
  (str	
  i))))
"Elapsed	
  time:	
  113.317	
  msecs"
nil
Polyglot projects
with Leiningen
(defproject	
  clojure-­‐java	
  "1.0.0-­‐SNAPSHOT"
	
  	
  :description	
  "Example	
  Clojure+Java	
  project."
	
  	
  :min-­‐lein-­‐version	
  "2.0.0"
	
  	
  :source-­‐paths	
  ["src/clojure"]
	
  	
  :java-­‐source-­‐paths	
  ["src/java"]
	
  	
  :javac-­‐options	
  ["-­‐target"	
  "1.5"	
  "-­‐source"	
  "1.5"])
http://leiningen.org
http://www.ldn.lv
Workshop: Clojure
Saturday, May 18, 2013
10:00 am
Citadeles iela 12, Riga
http://riga.techhub.com/
(kthx-­‐bye))))))
(defmacro	
  doto
	
  	
  [x	
  &	
  forms]
	
  	
  (let	
  [gx	
  (gensym)]
	
  	
  	
  	
  `(let	
  [~gx	
  ~x]
	
  	
  	
  	
  	
  	
  	
  ~@(map	
  (fn	
  [f]
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  (if	
  (seq?	
  f)
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  `(~(first	
  f)	
  ~gx	
  ~@(next	
  f))
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  `(~f	
  ~gx)))
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  forms)
	
  	
  	
  	
  	
  	
  	
  ~gx)))
(ns	
  foo.core
	
  	
  (:gen-­‐class))
	
  
(defn	
  -­‐main
	
  	
  "I	
  don't	
  do	
  a	
  whole	
  lot	
  ...	
  yet."
	
  	
  [&	
  args]
	
  	
  (println	
  "I'm	
  a	
  little	
  pony"))
foo$	
  lein	
  run
I'm	
  a	
  little	
  pony
(defn	
  make-­‐example	
  []
	
  	
  (proxy	
  [Object]	
  []
	
  	
  	
  	
  (toString	
  []	
  "I'm	
  a	
  little	
  pony")))
user=>	
  (.toString	
  (make-­‐some-­‐example))
"I'm	
  a	
  little	
  pony"
class	
  Example	
  {
	
  	
  	
  	
  void	
  someMethod(String	
  x)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  someMethod(x,	
  null)
	
  	
  	
  	
  }
	
  
	
  	
  	
  	
  void	
  someMethod(String	
  x,	
  String	
  y)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  doSomethingWith(x,	
  y);
	
  	
  	
  	
  }
}
(proxy	
  [Example]	
  []
	
  	
  (toString
	
  	
  	
  	
  ([x]	
  	
  	
  (proxy-­‐super	
  someMethod	
  x))
	
  	
  	
  	
  ([x	
  y]	
  (do-­‐other-­‐stuff	
  this	
  x	
  y))))
(let	
  [^LoadingCache	
  cache	
  (doto	
  CacheBuilder/newBuilder
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  (.maximumSize	
  1000)
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  (.build	
  (reify	
  CacheLoader
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  (load	
  ^Graph	
  [^Key	
  key]	
  (create-­‐expensive-­‐graph	
  key)))))])
LoadingCache<Key,	
  Graph>	
  cache	
  =	
  CacheBuilder.newBuilder()
	
  	
  	
  	
  	
  	
  	
  	
  .maximumSize(1000)
	
  	
  	
  	
  	
  	
  	
  	
  .build(new	
  CacheLoader<Key,	
  Graph>()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  public	
  Graph	
  load(Key	
  key)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  return	
  createExpensiveGraph(key);
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  });
LoadingCache<Key,	
  Graph>	
  cache	
  =	
  CacheBuilder.newBuilder()
	
  	
  	
  	
  	
  	
  	
  	
  .maximumSize(1000)
	
  	
  	
  	
  	
  	
  	
  	
  .build((key)	
  -­‐>	
  createExpensiveGraph(key));
1 sur 51

Contenu connexe

Tendances(18)

Mozilla とブラウザゲームMozilla とブラウザゲーム
Mozilla とブラウザゲーム
Noritada Shimizu2.6K vues
Tuga it 2016 - What's New In C# 6Tuga it 2016 - What's New In C# 6
Tuga it 2016 - What's New In C# 6
Paulo Morgado849 vues
Python postgre sql   a wonderful weddingPython postgre sql   a wonderful wedding
Python postgre sql a wonderful wedding
Stéphane Wirtel1.9K vues
What's New In C# 7What's New In C# 7
What's New In C# 7
Paulo Morgado1K vues
Collection Core ConceptCollection Core Concept
Collection Core Concept
Rays Technologies13 vues
HammurabiHammurabi
Hammurabi
Mario Fusco3.3K vues
Comparing JVM languagesComparing JVM languages
Comparing JVM languages
Jose Manuel Ortega Candel2.2K vues
Python Performance 101Python Performance 101
Python Performance 101
Ankur Gupta3.2K vues
Template Haskell とかTemplate Haskell とか
Template Haskell とか
Hiromi Ishii2.1K vues
Haskell in the Real WorldHaskell in the Real World
Haskell in the Real World
osfameron1.3K vues
2014-11-01 01 Денис Нелюбин. О сортах кофе2014-11-01 01 Денис Нелюбин. О сортах кофе
2014-11-01 01 Денис Нелюбин. О сортах кофе
Омские ИТ-субботники273 vues
EcmaScript 6 EcmaScript 6
EcmaScript 6
Manoj Kumar1.7K vues

Similaire à Refactoring to Macros with Clojure

GroovyGroovy
GroovyZen Urban
1.1K vues35 diapositives
Cpp tutorialCpp tutorial
Cpp tutorialVikas Sharma
260 vues23 diapositives
Hw09   Hadoop + ClojureHw09   Hadoop + Clojure
Hw09 Hadoop + ClojureCloudera, Inc.
1.3K vues21 diapositives

Similaire à Refactoring to Macros with Clojure(20)

GroovyGroovy
Groovy
Zen Urban1.1K vues
Pune Clojure Course OutlinePune Clojure Course Outline
Pune Clojure Course Outline
Baishampayan Ghose686 vues
Introduction to GroovyIntroduction to Groovy
Introduction to Groovy
André Faria Gomes751 vues
Cpp tutorialCpp tutorial
Cpp tutorial
Vikas Sharma260 vues
Hw09   Hadoop + ClojureHw09   Hadoop + Clojure
Hw09 Hadoop + Clojure
Cloudera, Inc.1.3K vues
Hadoop + ClojureHadoop + Clojure
Hadoop + Clojure
elliando dias1.6K vues
Spark workshopSpark workshop
Spark workshop
Wojciech Pituła1.1K vues
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
Stuart Roebuck1.1K vues
Introduction to Scalding and MonoidsIntroduction to Scalding and Monoids
Introduction to Scalding and Monoids
Hugo Gävert7.6K vues
mobl presentation @ IHomermobl presentation @ IHomer
mobl presentation @ IHomer
zefhemel526 vues
Spark_Documentation_Template1Spark_Documentation_Template1
Spark_Documentation_Template1
Nagavarunkumar Kolla189 vues
Modern technologies in data science Modern technologies in data science
Modern technologies in data science
Chucheng Hsieh3K vues
CppTutorial.pptCppTutorial.ppt
CppTutorial.ppt
HODZoology33 vues
T3chFest 2016 - The polyglot programmerT3chFest 2016 - The polyglot programmer
T3chFest 2016 - The polyglot programmer
David Muñoz Díaz760 vues
A Shiny Example-- RA Shiny Example-- R
A Shiny Example-- R
Dr. Volkan OBAN469 vues
Scala in Places APIScala in Places API
Scala in Places API
Łukasz Bałamut629 vues

Plus de Dmitry Buzdin(20)

How Payment Cards Really Work?How Payment Cards Really Work?
How Payment Cards Really Work?
Dmitry Buzdin1.1K vues
How to grow your own Microservice?How to grow your own Microservice?
How to grow your own Microservice?
Dmitry Buzdin685 vues
JOOQ and FlywayJOOQ and Flyway
JOOQ and Flyway
Dmitry Buzdin2.1K vues
Developing Useful APIsDeveloping Useful APIs
Developing Useful APIs
Dmitry Buzdin1K vues
Whats New in Java 8Whats New in Java 8
Whats New in Java 8
Dmitry Buzdin826 vues
Dart WorkshopDart Workshop
Dart Workshop
Dmitry Buzdin8.2K vues
Continuous Delivery Continuous Delivery
Continuous Delivery
Dmitry Buzdin2.7K vues
Introduction to DevOpsIntroduction to DevOps
Introduction to DevOps
Dmitry Buzdin3.1K vues
Thread Dump AnalysisThread Dump Analysis
Thread Dump Analysis
Dmitry Buzdin8.3K vues
Pragmatic Java Test AutomationPragmatic Java Test Automation
Pragmatic Java Test Automation
Dmitry Buzdin7K vues
Mlocjs buzdinMlocjs buzdin
Mlocjs buzdin
Dmitry Buzdin3.4K vues
Web polyglot programmingWeb polyglot programming
Web polyglot programming
Dmitry Buzdin1.5K vues
Code Structural AnalysisCode Structural Analysis
Code Structural Analysis
Dmitry Buzdin2K vues
Google GuavaGoogle Guava
Google Guava
Dmitry Buzdin1.3K vues
Jug Intro 20Jug Intro 20
Jug Intro 20
Dmitry Buzdin712 vues
Jug intro 18Jug intro 18
Jug intro 18
Dmitry Buzdin444 vues

Dernier(20)

ChatGPT and AI for Web DevelopersChatGPT and AI for Web Developers
ChatGPT and AI for Web Developers
Maximiliano Firtman161 vues
Liqid: Composable CXL PreviewLiqid: Composable CXL Preview
Liqid: Composable CXL Preview
CXL Forum120 vues
Green Leaf Consulting: Capabilities DeckGreen Leaf Consulting: Capabilities Deck
Green Leaf Consulting: Capabilities Deck
GreenLeafConsulting177 vues
The Research Portal of Catalonia: Growing more (information) & more (services)The Research Portal of Catalonia: Growing more (information) & more (services)
The Research Portal of Catalonia: Growing more (information) & more (services)
CSUC - Consorci de Serveis Universitaris de Catalunya59 vues
ThroughputThroughput
Throughput
Moisés Armani Ramírez31 vues

Refactoring to Macros with Clojure

  • 1. Refactoring to Macros with Clojure Dimitry Solovyov @dimituri
  • 4. liftIO  $  atomicModifyIORef  sc  $  n  -­‐>  (n  +  1,  ()) d  <-­‐  f  v  >>:  onInner liftIO  $  ds  `addDisposable`  d
  • 8. >>:
  • 10. LISP in 3 minutes via @bodiltv
  • 15. Clojure        It's a Lisp Compiled Dynamic types Type hints Macros Optional static types Optional Prolog
  • 17. HttpServer  server  =  HttpServer.create(address,  0); server.createContext(path,  handler); server.setExecutor(null); server.start();
  • 18. HttpServer  server  =  HttpServer.create(address,  0); server.createContext(path,  handler); server.setExecutor(null); server.start(); (doto  (HttpServer/create  address  0)    (.createContext  path  handler)    (.setExecutor  nil)    (.start))
  • 19. macro |ˈmakrəәʊ| noun ( pl. macros ) 1 (also macro instruction) Computing a single instruction that expands automatically into a set of instructions to perform a particular task.
  • 20. (let*  [G__360  (HttpServer/create  address  0)]    (.createContext  G__360  path  handler)    (.setExecutor  G__360  nil)    (.start  G__360)    G__360) (doto  (HttpServer/create  address  0)    (.createContext  path  handler)    (.setExecutor  nil)    (.start))
  • 23. String  url  =  Encoding.decodeBase64(b); String  decodedUrl  =  Encoding.decodeUrl(url); String  encodedUrl  =  Encoding.encodeBase64(decodedUrl); System.out.println(encodedUrl);
  • 24. String  url  =  Encoding.decodeBase64(b); String  decodedUrl  =  Encoding.decodeUrl(url); String  encodedUrl  =  Encoding.encodeBase64(decodedUrl); System.out.println(encodedUrl); (-­‐>  b    Encoding/decodeBase64    Encoding/decodeUrl    Encoding/encodeBase64    println)
  • 25. -­‐> (-­‐>  stuff    (foo  ,,,  a)    (bar  ,,,  b  c  d)    (baz  ,,,  e  f))
  • 26. -­‐>>-­‐> (-­‐>  stuff    (foo  ,,,  a)    (bar  ,,,  b  c  d)    (baz  ,,,  e  f)) (-­‐>>  stuff    (foo  a  ,,,)    (bar  b  c  d  ,,,)    (baz  e  f  ,,,))
  • 27. -­‐<>-­‐>>-­‐> (-­‐>  stuff    (foo  ,,,  a)    (bar  ,,,  b  c  d)    (baz  ,,,  e  f)) (-­‐>>  stuff    (foo  a  ,,,)    (bar  b  c  d  ,,,)    (baz  e  f  ,,,)) (-­‐<>  stuff    (foo  a  <>)    (bar  b  c  <>  d)    (baz  <>  e  f))
  • 28. “Swiss Arrows” -­‐<>> -­‐?<> -­‐!> -­‐!>> -­‐!<> <<-­‐ -­‐< -­‐<:p -­‐<< -­‐<<:p -­‐<>< -­‐<><:p https://github.com/rplevy/swiss-arrows
  • 31. Q: How do I get the result from a chain of computatoins that may fail?
  • 32. PhoneNumber  number  =  phoneMap.get(person); if  (number  !=  null)  {        Carrier  carrier  =  carrierMap.get(number);        if  (carrier  !=  null)  {                return  addressMap.get(address);        } } return  null;
  • 33. WHAT YOU'RE LOOKING FOR IS AN OPTION MONAD
  • 35. PhoneNumber  number  =  phoneMap.get(person); if  (number  !=  null)  {        Carrier  carrier  =  carrierMap.get(number);        if  (carrier  !=  null)  {                return  addressMap.get(address);        } } return  null; (some-­‐>>    (.get  phoneMap  person)    (.get  carrierMap)    (.get  addressMap))
  • 37. All Clojure functions implement java.util.Comparator java.lang.Runnable java.util.concurrent.Callable
  • 38. List<Integer>  numbers  =  Arrays.asList(1,  3,  4,  8,  2); Collections.sort(numbers,  new  Comparator<Integer>()  {        @Override        public  int  compare(Integer  o1,  Integer  o2)  {                return  o2.compareTo(o1);        } });
  • 39. List<Integer>  numbers  =  Arrays.asList(1,  3,  4,  8,  2); Collections.sort(numbers,  new  Comparator<Integer>()  {        @Override        public  int  compare(Integer  o1,  Integer  o2)  {                return  o2.compareTo(o1);        } }); List<Integer>  numbers  =  Arrays.asList(1,  3,  4,  8,  2); Collections.sort(numbers,  (o1,  o2)  -­‐>  o2.compareTo(o1));
  • 40. List<Integer>  numbers  =  Arrays.asList(1,  3,  4,  8,  2); Collections.sort(numbers,  new  Comparator<Integer>()  {        @Override        public  int  compare(Integer  o1,  Integer  o2)  {                return  o2.compareTo(o1);        } }); (doto  (ArrayList.  [1  3  4  8  2])    (Collections/sort  (fn  [o1  o2]  (.compareTo  o2  o1)))) List<Integer>  numbers  =  Arrays.asList(1,  3,  4,  8,  2); Collections.sort(numbers,  (o1,  o2)  -­‐>  o2.compareTo(o1));
  • 41. List<Integer>  numbers  =  Arrays.asList(1,  3,  4,  8,  2); Collections.sort(numbers,  new  Comparator<Integer>()  {        @Override        public  int  compare(Integer  o1,  Integer  o2)  {                return  o2.compareTo(o1);        } }); (doto  (ArrayList.  [1  3  4  8  2])    (Collections/sort  (fn  [o1  o2]  (.compareTo  o2  o1)))) (sort  #(compare  %2  %1)  [1  3  4  8  2]) List<Integer>  numbers  =  Arrays.asList(1,  3,  4,  8,  2); Collections.sort(numbers,  (o1,  o2)  -­‐>  o2.compareTo(o1));
  • 43. (defn  len-­‐reflected  [s]    (.length  s)) (defn  len-­‐hinted  ^String  [^String  s]    (.length  s)) user=>  (time  (dotimes  [i  1000000]  (len-­‐reflected  (str  i)))) "Elapsed  time:  3204.913  msecs" nil user=>  (time  (dotimes  [i  1000000]  (len-­‐hinted  (str  i)))) "Elapsed  time:  113.317  msecs" nil
  • 44. Polyglot projects with Leiningen (defproject  clojure-­‐java  "1.0.0-­‐SNAPSHOT"    :description  "Example  Clojure+Java  project."    :min-­‐lein-­‐version  "2.0.0"    :source-­‐paths  ["src/clojure"]    :java-­‐source-­‐paths  ["src/java"]    :javac-­‐options  ["-­‐target"  "1.5"  "-­‐source"  "1.5"]) http://leiningen.org
  • 45. http://www.ldn.lv Workshop: Clojure Saturday, May 18, 2013 10:00 am Citadeles iela 12, Riga http://riga.techhub.com/
  • 47. (defmacro  doto    [x  &  forms]    (let  [gx  (gensym)]        `(let  [~gx  ~x]              ~@(map  (fn  [f]                                (if  (seq?  f)                                    `(~(first  f)  ~gx  ~@(next  f))                                    `(~f  ~gx)))                            forms)              ~gx)))
  • 48. (ns  foo.core    (:gen-­‐class))   (defn  -­‐main    "I  don't  do  a  whole  lot  ...  yet."    [&  args]    (println  "I'm  a  little  pony")) foo$  lein  run I'm  a  little  pony
  • 49. (defn  make-­‐example  []    (proxy  [Object]  []        (toString  []  "I'm  a  little  pony"))) user=>  (.toString  (make-­‐some-­‐example)) "I'm  a  little  pony"
  • 50. class  Example  {        void  someMethod(String  x)  {                someMethod(x,  null)        }          void  someMethod(String  x,  String  y)  {                doSomethingWith(x,  y);        } } (proxy  [Example]  []    (toString        ([x]      (proxy-­‐super  someMethod  x))        ([x  y]  (do-­‐other-­‐stuff  this  x  y))))
  • 51. (let  [^LoadingCache  cache  (doto  CacheBuilder/newBuilder                            (.maximumSize  1000)                            (.build  (reify  CacheLoader                                                (load  ^Graph  [^Key  key]  (create-­‐expensive-­‐graph  key)))))]) LoadingCache<Key,  Graph>  cache  =  CacheBuilder.newBuilder()                .maximumSize(1000)                .build(new  CacheLoader<Key,  Graph>()  {                              public  Graph  load(Key  key)  {                                      return  createExpensiveGraph(key);                              }                      }); LoadingCache<Key,  Graph>  cache  =  CacheBuilder.newBuilder()                .maximumSize(1000)                .build((key)  -­‐>  createExpensiveGraph(key));