Refactoring to Macros with Clojure

3,272 views
3,156 views

Published on

Published in: Technology, Education
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,272
On SlideShare
0
From Embeds
0
Number of Embeds
2,431
Actions
Shares
0
Downloads
14
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Refactoring to Macros with Clojure

  1. 1. Refactoring to Macroswith ClojureDimitry Solovyov@dimituri
  2. 2. Lets talk aboutFUNCTIONAL PROGRAMMING
  3. 3. liftIO  $  atomicModifyIORef  sc  $  n  -­‐>  (n  +  1,  ())d  <-­‐  f  v  >>:  onInnerliftIO  $  ds  `addDisposable`  d
  4. 4. >>:
  5. 5. Lets talk aboutLISP
  6. 6. LISP in 3 minutesvia @bodiltv
  7. 7. object.method(a, b);
  8. 8. object.method( a b)
  9. 9. ClojureIts a LispCompiledDynamic typesType hintsMacros
  10. 10. ClojureIts a LispCompiledDynamic typesType hintsMacrosOptional static typesOptional Prolog
  11. 11. http://clojure.org/java_interop
  12. 12. HttpServer  server  =  HttpServer.create(address,  0);server.createContext(path,  handler);server.setExecutor(null);server.start();
  13. 13. 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))
  14. 14. macro |ˈmakrəәʊ|noun ( pl. macros )1 (also macro instruction) Computing a single instructionthat expands automatically into a set of instructionsto perform a particular task.
  15. 15. (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))
  16. 16. 根性
  17. 17. .println(Encoding.encodeBase64(Encoding.decodeUrl(Encoding.decodeBas
  18. 18. String  url  =  Encoding.decodeBase64(b);String  decodedUrl  =  Encoding.decodeUrl(url);String  encodedUrl  =  Encoding.encodeBase64(decodedUrl);System.out.println(encodedUrl);
  19. 19. 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)
  20. 20. -­‐>(-­‐>  stuff    (foo  ,,,  a)    (bar  ,,,  b  c  d)    (baz  ,,,  e  f))
  21. 21. -­‐>>-­‐>(-­‐>  stuff    (foo  ,,,  a)    (bar  ,,,  b  c  d)    (baz  ,,,  e  f))(-­‐>>  stuff    (foo  a  ,,,)    (bar  b  c  d  ,,,)    (baz  e  f  ,,,))
  22. 22. -­‐<>-­‐>>-­‐>(-­‐>  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))
  23. 23. “Swiss Arrows”-­‐<>> -­‐?<> -­‐!> -­‐!>>-­‐!<> <<-­‐ -­‐< -­‐<:p-­‐<< -­‐<<:p -­‐<>< -­‐<><:phttps://github.com/rplevy/swiss-arrows
  24. 24. -­‐<<:p
  25. 25. -­‐<<:p
  26. 26. Q: How do I get the result from achain of computatoins that may fail?
  27. 27. PhoneNumber  number  =  phoneMap.get(person);if  (number  !=  null)  {        Carrier  carrier  =  carrierMap.get(number);        if  (carrier  !=  null)  {                return  addressMap.get(address);        }}return  null;
  28. 28. WHAT YOURE LOOKING FORIS AN OPTION MONAD
  29. 29. 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))
  30. 30. Clojure vectors implementjava.lang.Comparablejava.util.RandomAccess
  31. 31. All Clojure functions implementjava.util.Comparatorjava.lang.Runnablejava.util.concurrent.Callable
  32. 32. 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);        }});
  33. 33. 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));
  34. 34. 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));
  35. 35. 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));
  36. 36. (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"niluser=>  (time  (dotimes  [i  1000000]  (len-­‐hinted  (str  i))))"Elapsed  time:  113.317  msecs"nil
  37. 37. Polyglot projectswith 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
  38. 38. http://www.ldn.lvWorkshop: ClojureSaturday, May 18, 201310:00 amCitadeles iela 12, Rigahttp://riga.techhub.com/
  39. 39. (kthx-­‐bye))))))
  40. 40. (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)))
  41. 41. (ns  foo.core    (:gen-­‐class))  (defn  -­‐main    "I  dont  do  a  whole  lot  ...  yet."    [&  args]    (println  "Im  a  little  pony"))foo$  lein  runIm  a  little  pony
  42. 42. (defn  make-­‐example  []    (proxy  [Object]  []        (toString  []  "Im  a  little  pony")))user=>  (.toString  (make-­‐some-­‐example))"Im  a  little  pony"
  43. 43. 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))))
  44. 44. (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));

×