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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/194.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 在这个例子中避免使用宏是好的吗?_Clojure - Fatal编程技术网

Clojure 在这个例子中避免使用宏是好的吗?

Clojure 在这个例子中避免使用宏是好的吗?,clojure,Clojure,我读到数据>函数>宏 假设您希望以后缀方式计算代码 哪种方法更好 ;; Macro (defmacro reverse-fn [expression] (conj (butlast expression) (last expression))) (reverse-fn ("hello world" println)) ; => "hello world" ;; Function and data (def data ["hello world" println]) (def

我读到数据>函数>宏

假设您希望以后缀方式计算代码

哪种方法更好

;; Macro

(defmacro reverse-fn [expression]
  (conj (butlast expression) (last expression)))

(reverse-fn ("hello world" println))
; => "hello world"


;; Function and data

(def data ["hello world" println])

(defn reverse-fn [data] 
  (apply (eval (last data)) (butlast data)))

(reverse-fn ["hello world" println])
; => "hello world"
谢谢

一般来说:

但是宏有它们的用途;宏在遇到宏时会展开,因此在生成的字节码中将内联一个或多个代码块。它们非常适合封装高阶DSL术语

另一方面,函数对于重用来说是非常好的,因为您可以本地化函数的纯度,并且可以从多个其他函数调用函数,而不会增加代码占用。它们非常适合本地或全球使用

REPL行为考虑:单个函数更易于返工,而无需担心完全评估整个源文件以确保更新所有宏引用扩展


希望这有帮助

简单的规则是最好的:如果可以使用函数,如果必须使用宏。

你的宏比你的函数好:宏比使用
eval
的函数好

但是,该函数不需要使用
eval
。你可以写

(defn reverse-fn [data] 
  (apply (last data) (butlast data)))
然后比如说像以前一样,

(reverse-fn [3 inc])
=> 4
在一个相关的话题上,你可能会发现一些有趣的问题


编辑:

请注意,函数是文本,从函数自身求值的意义上讲:

((eval +) 1 1)
=>  2

如果对代码中的任何类型的数据要求不同的求值行为,宏是最佳选择,因为它们可以在编译时将未求值的数据转换为希望求值的代码

Clojure有一个编程宏系统,允许编译器通过用户代码进行扩展。宏可用于定义需要原语或其他语言内置支持的语法结构。()

您提供的示例明确地说明了这一要求(“以后缀方式评估代码”),这就是为什么宏是正确的选择