Clojure函数字面量中使用'rest arguments'宏在'discard'读取器宏之后。

4
我希望能够在Clojure中创建一个函数字面量,它可以接受任意数量的参数,但实际上并不使用它们。因此我发现了 %& (函数字面量的"剩余参数")和 #_ ("废弃"读取宏)。
但它们如何一起工作让我感到惊讶:
=> (macroexpand `#(... #_ %&))
(fn* [& rest__125459__125460__auto__] (...))

这看起来像我想要的(并且最终似乎有效),但这是discard宏应该如何工作吗?文档说:

#_后面的表单完全被阅读器跳过。

但显然,这里被忽略的%&表单具有副作用,即它会影响函数文字参数列表。我应该依赖这种行为还是看起来更像一个错误?
3个回答

3
丢弃读取器宏#_不应单独使用。以下是它的示例:

之前:

(println "first")
(do
  (print "second ")
  (dotimes [i 5]
    (print i " "))
  (newline))
(println "third")

first
second 0  1  2  3  4  
third

之后:

(println "first")
#_(do
    (print "second ")
    (dotimes [i 5]
      (print i " "))
    (newline))
(println "third")

first
third

所以递归地添加#_将舍弃应用于它的表单内的所有内容。

关于您最初的问题如何忽略参数,您有几个选择:

(mapv  #(do %& 42)        (range 3)) => [42 42 42]
(mapv   (fn [& _]   42)   (range 3)) => [42 42 42]
(mapv   (constantly 42)   (range 3)) => [42 42 42]

谢谢,我理解#_宏的作用以及其正常行为。我的问题是关于#_ %&的组合,是否有意图产生明显的副作用。也许我应该稍微修改一下问题的主题。 - alex

1
我说得太早了,可能不是一个错误,也许应该被禁止并给出错误。但是真正的#_是用于丢弃表单的,%&不是一个表单而是一个阅读器宏
所以#_%&就像#_@#_;一样不起作用。丢弃阅读器#_只能与像()[](等等)这样的“真实表单”一起使用。

0

#_子句仅适用于表单。 在您的示例中,它后面有一个空格,因此没有任何效果。

在任何列表/表单前加上#_以完全忽略它:

#_(do(print 42)(/ 0 0));;不会出错


实际上,在 #_ 后面是否有空格并不重要。 - alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接