Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 为什么不';t默认情况下,when-let和if-let支持多个绑定?_Clojure - Fatal编程技术网

Clojure 为什么不';t默认情况下,when-let和if-let支持多个绑定?

Clojure 为什么不';t默认情况下,when-let和if-let支持多个绑定?,clojure,Clojure,为什么让默认情况下不支持多个绑定,而让默认情况下不支持多个绑定 因此: …而不是: (when-let [a ... (when-let [b ... (+ a b))) 我知道我可以编写自己的宏或使用monad(如下所述:)。因为(至少对于if let),不清楚如何处理“else”案例 至少,在我的激励下,我开始写一个宏来实现这一点。给定 (if-let* [a ... b ...] action other) 它将产生 (if-let [a ...

为什么让默认情况下不支持多个绑定,而让默认情况下不支持多个绑定

因此:

…而不是:

(when-let [a ...
  (when-let [b ...
    (+ a b)))
我知道我可以编写自己的宏或使用monad(如下所述:)。

因为(至少对于
if let
),不清楚如何处理“else”案例

至少,在我的激励下,我开始写一个宏来实现这一点。给定

(if-let* [a ...
          b ...]
  action
  other)
它将产生

(if-let [a ...]
  (if-let [b ...]
    action
    ?))
我不清楚如何继续(还有两个地方是“其他”)

您可以说,对于任何失败都应该有一个单一的替代方案,或者在let时,对于
应该没有替代方案,但是如果任何测试状态发生变化,那么事情仍然会变得一团糟

简言之,它比我预期的要复杂一点,因此我想当前的方法避免了需要对解决方案进行调用

另一种说法是:假设
if let
应该像
let
那样嵌套。更好的模型可能是
cond
,它不是一个“嵌套if”,而是一个“替代if”,因此不适合范围。。。或者,还有另一种说法:
如果
不能更好地处理这种情况。

如果您使用,那么您可能会发现有一个
mlet
函数非常有用:

如您所见,mlet遇到nil值时会短路


(第6.5.1节无)

以下是let*:

(defmacro when-let*
  "Multiple binding version of when-let"
  [bindings & body]
  (if (seq bindings)
    `(when-let [~(first bindings) ~(second bindings)]
       (when-let* ~(vec (drop 2 bindings)) ~@body))
    `(do ~@body)))
user=> (when-let* [a 1 b 2 c 3]
                (println "yeah!")
                a)
;;=>yeah!
;;=>1


user=> (when-let* [a 1 b nil c 3]
                (println "damn! b is nil")
                a)
;;=>nil
(defmacro if-let*
  "Multiple binding version of if-let"
  ([bindings then]
   `(if-let* ~bindings ~then nil))
  ([bindings then else]
   (if (seq bindings)
     `(if-let [~(first bindings) ~(second bindings)]
        (if-let* ~(vec (drop 2 bindings)) ~then ~else)
        ~else)
     then)))
用法:

(defmacro when-let*
  "Multiple binding version of when-let"
  [bindings & body]
  (if (seq bindings)
    `(when-let [~(first bindings) ~(second bindings)]
       (when-let* ~(vec (drop 2 bindings)) ~@body))
    `(do ~@body)))
user=> (when-let* [a 1 b 2 c 3]
                (println "yeah!")
                a)
;;=>yeah!
;;=>1


user=> (when-let* [a 1 b nil c 3]
                (println "damn! b is nil")
                a)
;;=>nil
(defmacro if-let*
  "Multiple binding version of if-let"
  ([bindings then]
   `(if-let* ~bindings ~then nil))
  ([bindings then else]
   (if (seq bindings)
     `(if-let [~(first bindings) ~(second bindings)]
        (if-let* ~(vec (drop 2 bindings)) ~then ~else)
        ~else)
     then)))

这里是if let*:

(defmacro when-let*
  "Multiple binding version of when-let"
  [bindings & body]
  (if (seq bindings)
    `(when-let [~(first bindings) ~(second bindings)]
       (when-let* ~(vec (drop 2 bindings)) ~@body))
    `(do ~@body)))
user=> (when-let* [a 1 b 2 c 3]
                (println "yeah!")
                a)
;;=>yeah!
;;=>1


user=> (when-let* [a 1 b nil c 3]
                (println "damn! b is nil")
                a)
;;=>nil
(defmacro if-let*
  "Multiple binding version of if-let"
  ([bindings then]
   `(if-let* ~bindings ~then nil))
  ([bindings then else]
   (if (seq bindings)
     `(if-let [~(first bindings) ~(second bindings)]
        (if-let* ~(vec (drop 2 bindings)) ~then ~else)
        ~else)
     then)))
用法:

user=> (if-let* [a 1 
                 b 2 
                 c (+ a b)]
              c
              :some-val)
;;=> 3

user=> (if-let* [a 1 b "Damn!" c nil]
              a
              :some-val)
;;=> :some-val

编辑:事实证明绑定不应该以else形式泄漏。

如果让*
宏泄漏
,也可以很好地回答我的问题;)但是它并不存在——我看不到处理“else”部分的好方法。你不能只使用
other
两次吗
(如果让[a…](如果让[b…]操作其他)其他))
?@andrewcooke“你可以说应该有一个单一的替代方案”:没错。当所有窗体的计算结果均为true时执行
操作
,当至少有一个窗体为NIL时执行
其他
(另请参见)。但我不明白你为什么担心易变性。我根据你的要求编写了一个函数。希望它能有所帮助!这里可以找到一个更健壮的版本