首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Clojure函数定义中的运算符优先级是什么?

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

Stack Overflow用户
提问于 2013-12-29 12:43:44
回答 3查看 437关注 0票数 2

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

代码语言:javascript
复制
(defn leap-year? [input-year] (or (and (= (rem input-year 4) 0) (> (rem input-year 100) 0)) (= (rem input-year 400) 0)))
EN

回答 3

Stack Overflow用户

发布于 2013-12-29 13:06:01

显式地具有优先级和结合性,因为它们表示树。

像许多LISP方言一样,Clojure通过“大量恼人的多余括号”相当直白地暴露了这些内容:

计算中的表达式,s-

,sexprs或sexps (代表“符号表达式”)是嵌套列表(树形结构)数据的符号,是为编程语言Lisp发明并推广的,编程语言将它们用作源代码和数据。在Lisp常用的带括号的语法中,s表达式被归纳地定义为

  • 一个原子,或
  • 一个形式为(x。y)其中x和y为s-expressions.

就优先级和结合性而言,“运算符”与任意函数调用(或宏)没有什么不同。也就是说,Clojure代码有效地启动了一个Abstract Syntax Tree(+ a b)的形式与(fn a b)没有本质上的不同- +令牌,就像fnadd一样,只是结果S表达式中的一个原子。

格式化代码应该更多地显示树结构(这种格式化可以扩展到一行只包含一个原子和0..n括号):

代码语言:javascript
复制
(defn leap-year? [input-year]
  (or
    (and (= (rem input-year 4) 0)
         (> (rem input-year 100) 0))
    (= (rem input-year 400) 0)))

虽然源代码和扩展形式仍然是S表达式,但andor是。and的实现是:

代码语言:javascript
复制
(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表达式树建立。

此外,从实现可以看出,逻辑条件形式也像许多其他流行语言一样,从左到右缓慢地进行计算。

票数 10
EN

Stack Overflow用户

发布于 2013-12-29 13:02:45

在Clojure中,没有运算符优先级。所有函数从左到右和从内到外求值,都是在宏展开阶段完成的。

票数 6
EN

Stack Overflow用户

发布于 2013-12-31 20:30:00

在Clojure中没有运算符优先级,因为没有运算符:+-=>等都是函数。

您可以使用编辑器(我使用的是Clooj)缩进您的代码以显示其结构:

代码语言:javascript
复制
(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是否准确地除以一个数字,从而使逻辑更加清晰。

代码语言:javascript
复制
(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))))

便笺

andor是宏,在编译器看到它们之前,它们会被转换成其他东西。例如,(or x y)变为(if x x y)。这种复杂性在这里不起作用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20822229

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档