简体   繁体   English

Clojure函数定义中的运算符优先级是什么?

[英]what is the operator precedence in Clojure function definition?

假设我们定义函数如下,Clojure中的运算符优先级是什么?

(defn leap-year? [input-year] (or (and (= (rem input-year 4) 0) (> (rem input-year 100) 0)) (= (rem input-year 400) 0)))

S-expressions explicitly have precedence and associativity , as they represent a tree. S表达式明确具有优先级和关联性 ,因为它们代表树。

Clojure, like many LISP dialects, exposes these quite bluntly with "Lots of Irritating Superfluous Parentheses": 像许多LISP方言一样,Clojure以“大量刺激的多余括号”直截了当地揭露了这些:

In computing, s-expressions, sexprs or sexps (for "symbolic expression") are a notation for nested list (tree-structured) data, invented for and popularized by the programming language Lisp, which uses them for source code as well as data. 在计算中,s表达式,sexprs或sexps(用于“符号表达式”)是嵌套列表(树形结构)数据的符号,由编程语言Lisp发明并推广,它将它们用于源代码和数据。 In the usual parenthesized syntax of Lisp, an s-expression is classically defined inductively as 在通常的带括号的Lisp语法中,s表达式归类地定义为

  • an atom, or 原子,或
  • an expression of the form (x . y) where x and y are s-expressions. 形式(x.y)的表达式,其中x和y是s-表达式。

As far as precedence and associativity, "operators" are no different than an arbitrary function call (or macro). 就优先级和关联性而言,“运算符”与任意函数调用(或宏)没有区别。 That is, Clojure code effectively starts life an an Abstract Syntax Tree and the form (+ ab) is not inherently different than (fn ab) - the + token, like fn or add , is just an atom in the resulting S-expression. 也就是说,Clojure代码有效地启动了一个抽象语法树 ,而形式(+ ab)本身并不与(fn ab)不同 - +标记,如fnadd ,只是生成的S表达式中的一个原子

Formatting the code should show the tree structure a bit more (and this formatting can be expanded until a line contains only a single atom and 0..n parenthesis): 格式化代码应该更多地显示树结构(并且可以扩展此格式,直到一行只包含一个原子和0..n括号):

(defn leap-year? [input-year]
  (or
    (and (= (rem input-year 4) 0)
         (> (rem input-year 100) 0))
    (= (rem input-year 400) 0)))

While the source and expanded forms are still S-expressions, and and or are macros . 虽然源和扩展形式仍然是 S表达式, and / or The implementation of and is: 执行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#))))

This allows (and ..) (via the recursive expansion of the macro), but does not allow "or" terms in the production as the form is already established by the outer S-expression tree. 这允许(and ..)经由宏的递归膨胀),但是不允许 “或”生产作为表单术语已经由外S-表达式树建立的。

Also, as can be seen by the implementation, logical condition forms are also lazily evaluated from left-to-right as in many other popular languages. 此外,从实现中可以看出,逻辑条件形式也像许多其他流行语言一样从左到右进行延迟评估

In Clojure there is no operator precedence. 在Clojure中没有运算符优先级。 All functions evaluate left to right and inside out, all done after the macro expansion phase. 所有功能从左到右和从内到外进行评估,所有功能都在宏扩展阶段之后完成。

There is no operator precedence in Clojure, because there are no operators as such: + , - , = , > and so on are just functions. Clojure中没有运算符优先级,因为没有这样的运算符+-=>等等只是函数。

You can use an editor (I used Clooj) to indent your code to show its structure: 您可以使用编辑器(我使用Clooj)缩进代码以显示其结构:

(defn leap-year? [input-year]
  (or
    (and
      (= (rem input-year 4) 0)
      (> (rem input-year 100) 0))
    (= (rem input-year 400) 0)))

You can make the logic clearer by extracting a local function (I've called it divides-by ) to tell you whether input-year divides by a number exactly. 您可以通过提取本地函数(我将其称为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))))

Note 注意

and and or are macros , which are translated into something else before the compiler sees them. and / or ,它们在编译器看到它们之前被翻译成其他东西。 For example, (or xy) becomes (if xxy) . 例如, (or xy)变为(if xxy) This complication has no effect here. 这种并发症在这里没有效果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM