假设我们如下定义函数,Clojure中的运算符优先级是什么?
(defn leap-year? [input-year] (or (and (= (rem input-year 4) 0) (> (rem input-year 100) 0)) (= (rem input-year 400) 0)))发布于 2013-12-29 13:06:01
显式地具有优先级和结合性,因为它们表示树。
像许多LISP方言一样,Clojure通过“大量恼人的多余括号”相当直白地暴露了这些内容:
计算中的表达式,s-
,sexprs或sexps (代表“符号表达式”)是嵌套列表(树形结构)数据的符号,是为编程语言Lisp发明并推广的,编程语言将它们用作源代码和数据。在Lisp常用的带括号的语法中,s表达式被归纳地定义为
就优先级和结合性而言,“运算符”与任意函数调用(或宏)没有什么不同。也就是说,Clojure代码有效地启动了一个Abstract Syntax Tree,(+ a b)的形式与(fn a b)没有本质上的不同- +令牌,就像fn或add一样,只是结果S表达式中的一个原子。
格式化代码应该更多地显示树结构(这种格式化可以扩展到一行只包含一个原子和0..n括号):
(defn leap-year? [input-year]
(or
(and (= (rem input-year 4) 0)
(> (rem input-year 100) 0))
(= (rem input-year 400) 0)))虽然源代码和扩展形式仍然是S表达式,但and和or是。and的实现是:
(defmacro and
"Evaluates exprs one at a time, from left to right. If a form
returns logical false (nil or false), and returns that value and
doesn't evaluate any of the other expressions, otherwise it returns
the value of the last expr. (and) returns true."
{:added "1.0"}
([] true)
([x] x)
([x & next]
`(let [and# ~x]
(if and# (and ~@next) and#))))这允许(and ..) (通过宏的递归展开),但不允许在生产中使用“或”术语,因为表单已经由外部S表达式树建立。
此外,从实现可以看出,逻辑条件形式也像许多其他流行语言一样,从左到右缓慢地进行计算。
发布于 2013-12-29 13:02:45
在Clojure中,没有运算符优先级。所有函数从左到右和从内到外求值,都是在宏展开阶段完成的。
发布于 2013-12-31 20:30:00
在Clojure中没有运算符优先级,因为没有运算符:+、-、=、>等都是函数。
您可以使用编辑器(我使用的是Clooj)缩进您的代码以显示其结构:
(defn leap-year? [input-year]
(or
(and
(= (rem input-year 4) 0)
(> (rem input-year 100) 0))
(= (rem input-year 400) 0)))您可以通过提取一个本地函数(我称之为divides-by)来告诉您input-year是否准确地除以一个数字,从而使逻辑更加清晰。
(defn leap-year [input-year]
(let [divides-by (fn [d] (= (rem input-year d) 0))]
(or (and (divides-by 4) (not (divides-by 100))) (divides-by 400))))便笺
and和or是宏,在编译器看到它们之前,它们会被转换成其他东西。例如,(or x y)变为(if x x y)。这种复杂性在这里不起作用。
https://stackoverflow.com/questions/20822229
复制相似问题