From 834b0019a715f6351d53963f743361651cd60912 Mon Sep 17 00:00:00 2001 From: Matthew Wampler-Doty Date: Mon, 21 Apr 2014 12:35:56 -0700 Subject: [PATCH] Fixing `doto` to be API compatible with Clojure's `doto` --- docs/language/api.rst | 22 ++++++++++------------ hy/core/macros.hy | 17 +++++++++-------- tests/native_tests/core.hy | 6 +++++- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/docs/language/api.rst b/docs/language/api.rst index f5b1ac5..53b89a5 100644 --- a/docs/language/api.rst +++ b/docs/language/api.rst @@ -563,23 +563,21 @@ del doto ---- -`doto` macro is used to make repetitive calls to an object easy. Following -example demonstrates this. +`doto` macro is used to make a sequence of method calls for an object easy. + +.. code-block:: clj + + => (doto [] (.append 1) (.append 2) .reverse) + [2 1] .. code-block:: clj => (setv collection []) - => (doto collection (.append 1) (.append 2)) + => (.append collection 1) + => (.append collection 2) + => (.reverse collection) => collection - [1 2] - -.. code-block:: clj - - => (setv collection []) - => (.append 1 collection) - => (.append 2 collection) - => collection - [1 2] + [2 1] eval ---- diff --git a/hy/core/macros.hy b/hy/core/macros.hy index 548a81b..29db215 100644 --- a/hy/core/macros.hy +++ b/hy/core/macros.hy @@ -128,14 +128,15 @@ (defmacro doto [form &rest expressions] - (setv expressions (iter expressions)) - (defn build-form [form expression] - `(~(first expression) ~form ~@(rest expression))) - (setv result `()) - (for* [expression expressions] - (.append result (build-form form expression))) - `(do ~@result)) - + "Performs a sequence of potentially mutating actions on an initial object, returning the resulting object after the sequence is performed" + (setv f (gensym)) + (defn build-form [expression] + (if (isinstance expression HyExpression) + `(~(first expression) ~f ~@(rest expression)) + `(~expression ~f))) + `(let [[~f ~form]] + ~@(map build-form expressions) + ~f)) (defmacro ->> [head &rest rest] ;; TODO: fix the docstring by someone who understands this diff --git a/tests/native_tests/core.hy b/tests/native_tests/core.hy index fec1316..c1ef191 100644 --- a/tests/native_tests/core.hy +++ b/tests/native_tests/core.hy @@ -483,5 +483,9 @@ "NATIVE: testing doto macro" (setv collection []) (doto collection (.append 1) (.append 2) (.append 3)) - (assert-equal collection [1 2 3])) + (assert-equal collection [1 2 3]) + (setv res (doto (set) (.add 2) (.add 1))) + (assert-equal res (set [1 2])) + (setv res (doto [] (.append 1) (.append 2) .reverse)) + (assert-equal res [2 1]))