From 2adfdfc4fa1d6b1694d36dfcd51823781b82dd0a Mon Sep 17 00:00:00 2001 From: Phil Hagelberg Date: Thu, 5 Aug 2010 21:14:42 -0700 Subject: [PATCH] Initial commit. Also version 1.0. --- .gitignore | 4 ++++ README | 29 +++++++++++++++++++++++++++++ project.clj | 5 +++++ src/reducate/core.clj | 10 ++++++++++ test/reducate/test/core.clj | 28 ++++++++++++++++++++++++++++ 5 files changed, 76 insertions(+) create mode 100644 .gitignore create mode 100644 README create mode 100644 project.clj create mode 100644 src/reducate/core.clj create mode 100644 test/reducate/test/core.clj diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d9148e9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +pom.xml +*jar +lib +classes \ No newline at end of file diff --git a/README b/README new file mode 100644 index 0000000..98b6480 --- /dev/null +++ b/README @@ -0,0 +1,29 @@ +# reducate + +reducate is a new fancy shiny reduce-like macro! You'll love it! + +## Usage + +Ever get tired of function literals in your reduce? When you get tired +of them with map, you can switch to a for macro, but no such luck with +reduce ... until now! + + (def words [["delicious" "coffee"] + ["scrumptious" "scones"] + ["hungry" "hackers"]]) + + ;; the old way + (reduce (fn [acc [adj noun]] (conj acc adj)) + [] words) + ;; => ["delicious" "scrumptious" "hungry"] + + ;; but look! + (reducate [acc []] [[adj noun] words] + (conj acc adj)) + ;; => ["delicious" "scrumptious" "hungry"] + +## License + +Copyright (C) 2010 Seajure + +Distributed under the Eclipse Public License, the same as Clojure. diff --git a/project.clj b/project.clj new file mode 100644 index 0000000..a440390 --- /dev/null +++ b/project.clj @@ -0,0 +1,5 @@ +(defproject reducate "1.0.0" + :description "A shiny new reduce macro" + :dev-dependencies [[org.clojure/clojure "1.2.0-beta1"] + [org.clojure/clojure-contrib "1.2.0-beta1"] + [swank-clojure "1.3.0-SNAPSHOT"]]) diff --git a/src/reducate/core.clj b/src/reducate/core.clj new file mode 100644 index 0000000..e731aef --- /dev/null +++ b/src/reducate/core.clj @@ -0,0 +1,10 @@ +(ns reducate.core) + +(defmacro reducate + "map:for :: reduce:reducate" + ([accum bindings body] + `(reduce (fn ~[(first accum) (first bindings)] ~body) + ~(second accum) ~(second bindings))) + ([[name value] body] + `(let [[init# & more#] ~value] + (reducate [~'% init#] [~name more#] ~body)))) diff --git a/test/reducate/test/core.clj b/test/reducate/test/core.clj new file mode 100644 index 0000000..1fcff66 --- /dev/null +++ b/test/reducate/test/core.clj @@ -0,0 +1,28 @@ +(ns reducate.test.core + (:use [reducate.core] :reload) + (:use [clojure.test])) + +(def words [["delicious" "coffee"] + ["scrumptious" "scones"] + ["hungry" "hackers"]]) + +(deftest test-reducate-three-arg + (is (= 12 (reducate [acc 0] + [n [1 2 3]] + (+ acc (* n 2))))) + (is (= {:sea :jure, :zoka :coffee} + (reducate [acc {}] + [pair [[:sea :jure] [:zoka :coffee]]] + (conj acc pair)))) + (is (= " delicious scrumptious hungry" + (reducate [acc ""] + [[adj noun] words] + (str acc " " adj))))) + +;; Case 1 +;; (reducate [foo bar] (do-something foo bar)) +;; (reducate [accum 0] [foo [:bar] x [:y]] (do-something)) + +(deftest test-reducate-two-arg + (is (= 12 (reducate [n [0 1 2 3]] + (+ % (* n 2))))))