Skip to content

Commit

Permalink
Merge pull request hylang#1538 from Kodiologist/tail-thread-fix
Browse files Browse the repository at this point in the history
In ->>, don't modify the arguments
  • Loading branch information
Kodiologist authored Mar 23, 2018
2 parents a48f009 + e7b21cc commit f57463c
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 12 deletions.
1 change: 1 addition & 0 deletions NEWS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ New Features
Bug Fixes
------------------------------
* Fix `(return)` so it works correctly to exit a Python 2 generator
* Fixed a case where `->` and `->>` duplicated an argument

Misc. Improvements
----------------------------
Expand Down
22 changes: 10 additions & 12 deletions hy/core/macros.hy
Original file line number Diff line number Diff line change
Expand Up @@ -142,17 +142,16 @@ in order of the given pairs."
(_for 'for/a* args body))


(defmacro -> [head &rest rest]
(defmacro -> [head &rest args]
"Thread `head` first through the `rest` of the forms.
The result of the first threaded form is inserted into the first position of
the second form, the second result is inserted into the third form, and so on."
(setv ret head)
(for* [node rest]
(if (not (isinstance node HyExpression))
(setv node `(~node)))
(.insert node 1 ret)
(setv ret node))
(for* [node args]
(setv ret (if (isinstance node HyExpression)
`(~(first node) ~ret ~@(rest node))
`(~node ~ret))))
ret)


Expand All @@ -168,17 +167,16 @@ the second form, the second result is inserted into the third form, and so on."
~@(map build-form expressions)
~f))

(defmacro ->> [head &rest rest]
(defmacro ->> [head &rest args]
"Thread `head` last through the `rest` of the forms.
The result of the first threaded form is inserted into the last position of
the second form, the second result is inserted into the third form, and so on."
(setv ret head)
(for* [node rest]
(if (not (isinstance node HyExpression))
(setv node `(~node)))
(.append node ret)
(setv ret node))
(for* [node args]
(setv ret (if (isinstance node HyExpression)
`(~@node ~ret)
`(~node ~ret))))
ret)


Expand Down
12 changes: 12 additions & 0 deletions tests/native_tests/language.hy
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,18 @@
(assert (= (.join ", " (* 10 ["foo"]))
(->> ["foo"] (* 10) (.join ", ")))))

(defn test-threading-in-macro []
; https://github.com/hylang/hy/issues/1537
; The macros need to be defined in another file or else the bug
; isn't visible in cb72a8c155ac4ef8e16afc63ffa80c1d5abb68a7
(require tests.resources.macros)

(tests.resources.macros.thread-set-ab)
(assert (= ab 2))

(tests.resources.macros.threadtail-set-cd)
(assert (= cd 5)))


(defn test-threading-two []
"NATIVE: test threading macro"
Expand Down
9 changes: 9 additions & 0 deletions tests/resources/macros.hy
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
(defmacro thread-set-ab []
(defn f [&rest args] (.join "" (+ (, "a") args)))
(setv variable (HySymbol (-> "b" (f))))
`(setv ~variable 2))

(defmacro threadtail-set-cd []
(defn f [&rest args] (.join "" (+ (, "c") args)))
(setv variable (HySymbol (->> "d" (f))))
`(setv ~variable 5))

0 comments on commit f57463c

Please sign in to comment.