Skip to content

Instantly share code, notes, and snippets.

@mattdenner
Last active December 18, 2015 17:09
Show Gist options
  • Select an option

  • Save mattdenner/5816745 to your computer and use it in GitHub Desktop.

Select an option

Save mattdenner/5816745 to your computer and use it in GitHub Desktop.

Revisions

  1. mattdenner revised this gist Jun 19, 2013. 2 changed files with 10 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion attempt1.clj
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,6 @@
    ; My first attempt would have been my typical approach: wrap the function being used in the map.
    ; My first attempt would have been my typical approach: wrap the function being used in the map. What I dislike, even though
    ; this is my current natural (read "first thing I try normally") is that 'reporter' looks more complicated than I'd like, plus
    ; 'report-progress' knows about the idea of "progress".
    (defn reporter
    [report-every f]
    (fn [val cnt]
    7 changes: 7 additions & 0 deletions attempt2.clj
    Original file line number Diff line number Diff line change
    @@ -12,6 +12,13 @@
    [aseq reporter]
    (map-indexed (fn [& args] (apply reporter args) (last args)) aseq))

    ; Here 'report-progress' knows only about mapping, really, and so this function doesn't have to exist:
    ; (doall (map identity (reporting-seq (range 10) (progress-reporter 2))))
    ;
    ; Which then leads to:
    ; (doall (map identity (reporting-seq (range 10) (fn [cnt val] (println "Processing:" val)))))
    ;
    ; Which has nothing to do with progress!
    (defn report-progress
    [report-every aseq]
    (map identity (reporting-seq aseq (progress-reporter report-every))))
  2. mattdenner created this gist Jun 19, 2013.
    16 changes: 16 additions & 0 deletions attempt1.clj
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,16 @@
    ; My first attempt would have been my typical approach: wrap the function being used in the map.
    (defn reporter
    [report-every f]
    (fn [val cnt]
    (let [rv (f val)]
    (and (zero? (mod cnt report-every)) (println "Done" cnt))
    val)
    ))

    (defn report-progress
    [report-every aseq]
    (map (reporter report-every identity)
    aseq
    (iterate inc 1)))

    (doall (report-progress 2 (range 10)))
    19 changes: 19 additions & 0 deletions attempt2.clj
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,19 @@
    ; Then I read the popular answer (http://stackoverflow.com/a/2023356/207031) which talks about wrapping the *data*. At the
    ; moment this is my favourite, and it's taught me a lot, because it cleanly separates so much of the behaviour.
    (defn progress-reporter
    "Returns a function that reports the count every 'report-every' times"
    [report-every]
    (fn [cnt _]
    (and (zero? (mod cnt report-every)) (println "Done" cnt))))

    (defn reporting-seq
    "Wraps a sequence so that the 'reporter' function is called with the index and value for reporting, but maintains map
    behaviour of the inner sequence"
    [aseq reporter]
    (map-indexed (fn [& args] (apply reporter args) (last args)) aseq))

    (defn report-progress
    [report-every aseq]
    (map identity (reporting-seq aseq (progress-reporter report-every))))

    (doall (report-progress 2 (range 10)))
    15 changes: 15 additions & 0 deletions original.clj
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,15 @@
    ; Here's the original code:
    (defn report
    [report-every val cnt]
    (if (= 0 (mod cnt report-every))
    (println "Done" cnt))
    val)

    (defn report-progress
    [report-every aseq]
    (map (fn [val cnt]
    (report report-every val cnt))
    aseq
    (iterate inc 1)))

    (doall (report-progress 2 (range 10)))