How about this, @alexmiller? What are the chances of getting this change into core? ;)
From c18ca3c055b8267fed84e40cb3dcd9513c263599 Mon Sep 17 00:00:00 2001
From: Thomas Spellman <thos37@gmail.com>
Date: Sun, 12 Jan 2020 11:07:42 -0800
Subject: [PATCH] thread lambdas
---
src/clj/clojure/core.clj | 14 +++++++++-----
test/clojure/test_clojure/macros.clj | 12 ++++++++++++
2 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index 8e98e072..27d22558 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -1671,43 +1671,47 @@
but is easier to write, read, and understand."
{:added "1.0"}
([x form] `(. ~x ~form))
([x form & more] `(.. (. ~x ~form) ~@more)))
(defmacro ->
"Threads the expr through the forms. Inserts x as the
- second item in the first form, making a list of it if it is not a
+ second item in the first form, making a list of it if it is a lambda or not a
list already. If there are more forms, inserts the first form as the
second item in second form, etc."
{:added "1.0"}
[x & forms]
(loop [x x, forms forms]
(if forms
(let [form (first forms)
threaded (if (seq? form)
- (with-meta `(~(first form) ~x ~@(next form)) (meta form))
+ (if (#{'fn 'fn*} (first form))
+ (list form x)
+ (with-meta `(~(first form) ~x ~@(next form)) (meta form)))
(list form x))]
(recur threaded (next forms)))
x)))
(defmacro ->>
"Threads the expr through the forms. Inserts x as the
- last item in the first form, making a list of it if it is not a
+ last item in the first form, making a list of it if it is a lambda or not a
list already. If there are more forms, inserts the first form as the
last item in second form, etc."
{:added "1.1"}
[x & forms]
(loop [x x, forms forms]
(if forms
(let [form (first forms)
threaded (if (seq? form)
- (with-meta `(~(first form) ~@(next form) ~x) (meta form))
- (list form x))]
+ (if (#{'fn 'fn*} (first form))
+ (list form x)
+ (with-meta `(~(first form) ~@(next form) ~x) (meta form)))
+ (list form x))]
(recur threaded (next forms)))
x)))
(def map)
(defn ^:private check-valid-options
"Throws an exception if the given option map contains keys not listed
as valid, else returns nil."
diff --git a/test/clojure/test_clojure/macros.clj b/test/clojure/test_clojure/macros.clj
index ce17bb38..5ebd2dd5 100644
--- a/test/clojure/test_clojure/macros.clj
+++ b/test/clojure/test_clojure/macros.clj
@@ -106,8 +106,20 @@
(is (nil? (loop []
(as-> 0 x
(when-not (zero? x)
(recur))))))
(is (nil? (loop [x nil] (some-> x recur))))
(is (nil? (loop [x nil] (some->> x recur))))
(is (= 0 (loop [x 0] (cond-> x false recur))))
(is (= 0 (loop [x 0] (cond->> x false recur)))))
+
+(deftest ->lambda-test
+ (is (= 'a (-> 'a ((fn [x] x)))))
+ (is (= 'a (-> 'a (fn [x] x))))
+ (is (= 'a (-> 'a #(identity %))))
+ (is (= 'a (-> 'a (#(identity %))))))
+
+(deftest ->>lambda-test
+ (is (= 'a (->> 'a ((fn [x] x)))))
+ (is (= 'a (->> 'a (fn [x] x))))
+ (is (= 'a (->> 'a #(identity %))))
+ (is (= 'a (->> 'a (#(identity %))))))
\ No newline at end of file
--
2.21.0 (Apple Git-122.2)
it works!
(-> :hmm (fn [x] x))
=> :hmm
and tests pass!
test:
[INFO] Executed tasks
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:18 min
[INFO] Finished at: 2020-01-12T10:58:31-08:00
[INFO] ------------------------------------------------------------------------