在Clojure中传递评估方法名称的惯用法?

haw*_*eye 5 lisp hash function idiomatic clojure

我正在传递一个函数的名称,以便在另一个方法中使用.

(defn mapper [m function]
  (cond
   (= '() m) '()
   true (cons (function (first m))
            (mapper (rest m) function))))

(println (mapper '((blue red)(green red)(white red)) #'first))
Run Code Online (Sandbox Code Playgroud)

在clojure中有没有更惯用的方法呢?

Bri*_*per 9

  • 首选矢量列表.您不必在大多数情况下引用向量,并且对于很多事情(例如随机访问)具有更好的性能.在Clojure中使用的列表比在其他Lisp中使用得更少.
  • 首选关键字引用符号.关键字突出显示为"常量字符串"或枚举值.Clojure中的关键字可以属于命名空间,因此它们具有符号的所有优点.而且,没有必要引用关键字,这很好.除非你正在编写宏,否则在Clojure中很少使用带引号的符号.
  • #'first变量叫做"第一"; firstvar的值是"first",即fn.在这种情况下(#'first foo),(first foo)给出相同的答案,但#'first每次调用时都会进行额外的解除引用.所以不要这样做,除非你想要反复引用一遍又一遍.通常没有必要使用#'.
  • 内置map是懒惰的,而你的不是.内置map利用了chunked seqs以获得更好的性能,而你的没有.惯用代码不一定是懒惰的或者使用chunked seqs,但要记住内置函数有一些神奇的功能.所以利用它是好事.
  • 而不是(= '() x),对于空seq的惯用测试是(seq x),nil如果x为空则返回.请注意,在Clojure中,这(= '() nil)是假的.
  • 如果您确实需要使用空列表(您很少需要这样做),则不必引用它.只是用().
  • 内置map首先接受函数参数,因为它接受多个集合参数.当一个函数接受多个参数时,这些参数必须在参数列表中排在最后.我认为它的读法也更好:"(map f coll):在这个集合中映射这个函数".
  • cond如果您只有两个选项,则无需使用.你可以if改用.如果你if回来的其中一个分支nil,你可以使用when.这是很好的使用when,并if在适当的时候,因为他们马上显示你的意图给读者,而cond可以做任何事情,并强迫读者阅读更多.

RafałFowgird的版本是惯用的,除了我翻转的论点顺序.我会这样称呼它:

user> (mapper first [[:blue :red] [:green :red] [:white :red]])
(:blue :green :white)
Run Code Online (Sandbox Code Playgroud)