Guest User

Untitled

a guest
Aug 29th, 2018
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (ns com.seanshubin.clojure.tryme.concurrency)
  2.  
  3. ;This sample demonstrates the benefits of pure functional code.
  4. ;In the method sortRecursiveParallel I can compute different parts of the sorting concurrently ;I can do this because I have no side effects, which gives me referential transparency, which means it does not matter ;which order I call my functions in.  So I can place the instructions for each computation in a separate future without ;having to think about synchronization or locks ; ;A function is pure if ;  it's inputs are explicit in the parameter list ;  it's outputs are explicit in the return value, not side effects ; ;A function is not pure if ;  reads the system clock ;  reads or writes an environment variable ;  reads or writes global variable ;  reads or writes a file
  5.  
  6. (defn sortRecursive [unsorted]
  7.   (if (empty? unsorted) []
  8.     (let
  9.       [target (first unsorted)
  10.        less (filter (fn [x] (< x target)) unsorted)
  11.        greaterEqual (filter (fn [x] (>= x target)) unsorted)]
  12.       (concat
  13.         (sortRecursive less)
  14.         [target]
  15.         (sortRecursive (rest greaterEqual))))))
  16.  
  17. (defn sortRecursiveParallel [unsorted]
  18.   (if (empty? unsorted) []
  19.     (let
  20.       [target (first unsorted)
  21.        less (filter (fn [x] (< x target)) unsorted)
  22.        greaterEqual (filter (fn [x] (>= x target)) unsorted)
  23.        sortedLess (future (sortRecursive less))
  24.        sortedGreaterEqual (future (sortRecursive (rest greaterEqual)))]
  25.       (concat
  26.         (sortRecursive (deref sortedLess))
  27.         [target]
  28.         (sortRecursive (deref sortedGreaterEqual))))))
  29.  
  30. (defn runSorts [unsorted]
  31.   (let
  32.     [sorted (sortRecursive unsorted)
  33.      sortedParallel (sortRecursiveParallel unsorted)]
  34.     [(str "unsorted              = " unsorted)
  35.      (str "sortRecursive         = " (vec sorted)) ;convert to a vector so that we can realize the lazy sequence
  36.      (str "sortRecursiveParallel = " (vec sortedParallel))]))
  37.  
  38. ;code above is pure functional (inputs and outputs are explicit, no side effects) ; ;I like to clearly separate my pure functional code from other code ; ;code below is not pure functional (hidden inputs and outputs, side effects) ;  (not done here) constructing a random without a seed talks to an external device (the system clock) ;  random.shuffle mutates state (any time you get a random number you also update the seed) ;  println talks to an external device (standard output)
  39.  
  40. (defn shuffleUsingRandom [coll random] ;clojure does not have a built in shuffle that allows you to specify a random
  41.   (let [arrayList (java.util.ArrayList. coll)]
  42.     (java.util.Collections/shuffle arrayList random) ;side effect, the current seed for random changed
  43.     (clojure.lang.RT/vector (.toArray arrayList))))
  44.  
  45. (let [seed 12345
  46.       random (new java.util.Random seed)
  47.       numbers (range 1 21)
  48.       shuffled (shuffleUsingRandom numbers random) ;side effect, shuffleUsingRandom is not pure
  49.       results (runSorts shuffled)]
  50.     (dorun (map println results))) ;using a first class function, but not pure functional because there is a side effect
  51.  
  52. (shutdown-agents) ;clojure does not automatically shut down its futures when they are finished
  53.  
  54. ;unsorted              = [13 6 20 17 15 9 3 4 7 8 11 19 18 10 5 14 1 16 2 12]
  55. ;sortRecursive         = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20]
  56. ;sortRecursiveParallel = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20]
Add Comment
Please, Sign In to add comment