In -> and ->>, don't modify the arguments

This commit is contained in:
Kodi Arfer 2018-03-19 17:40:10 -04:00
parent a48f009f1e
commit ad59fd7ff6
4 changed files with 32 additions and 12 deletions

View File

@ -25,6 +25,7 @@ New Features
Bug Fixes Bug Fixes
------------------------------ ------------------------------
* Fix `(return)` so it works correctly to exit a Python 2 generator * Fix `(return)` so it works correctly to exit a Python 2 generator
* Fixed a case where `->` and `->>` duplicated an argument
Misc. Improvements Misc. Improvements
---------------------------- ----------------------------

View File

@ -142,17 +142,16 @@ in order of the given pairs."
(_for 'for/a* args body)) (_for 'for/a* args body))
(defmacro -> [head &rest rest] (defmacro -> [head &rest args]
"Thread `head` first through the `rest` of the forms. "Thread `head` first through the `rest` of the forms.
The result of the first threaded form is inserted into the first position of 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." the second form, the second result is inserted into the third form, and so on."
(setv ret head) (setv ret head)
(for* [node rest] (for* [node args]
(if (not (isinstance node HyExpression)) (setv ret (if (isinstance node HyExpression)
(setv node `(~node))) `(~(first node) ~ret ~@(rest node))
(.insert node 1 ret) `(~node ~ret))))
(setv ret node))
ret) ret)
@ -168,17 +167,16 @@ the second form, the second result is inserted into the third form, and so on."
~@(map build-form expressions) ~@(map build-form expressions)
~f)) ~f))
(defmacro ->> [head &rest rest] (defmacro ->> [head &rest args]
"Thread `head` last through the `rest` of the forms. "Thread `head` last through the `rest` of the forms.
The result of the first threaded form is inserted into the last position of 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." the second form, the second result is inserted into the third form, and so on."
(setv ret head) (setv ret head)
(for* [node rest] (for* [node args]
(if (not (isinstance node HyExpression)) (setv ret (if (isinstance node HyExpression)
(setv node `(~node))) `(~@node ~ret)
(.append node ret) `(~node ~ret))))
(setv ret node))
ret) ret)

View File

@ -742,6 +742,18 @@
(assert (= (.join ", " (* 10 ["foo"])) (assert (= (.join ", " (* 10 ["foo"]))
(->> ["foo"] (* 10) (.join ", "))))) (->> ["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 [] (defn test-threading-two []
"NATIVE: test threading macro" "NATIVE: test threading macro"

View File

@ -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))