这段Clojure代码缩进正确吗?

3

我在这里发布了两种不同缩进方式的代码。当一个函数有多个参数时,我会感到困惑,不知道应该怎么做。每个参数应该放在不同的行上还是相同的行上?此外,当我们像(def xyz(fn abc[a1 a2]...时,(fn abc ...)是否应该放在另一行上?

我从这里阅读以下内容,但似乎不太合理。

**缩进和对齐

任何形式的运算符,即在开放圆括号之后的第一个子表单,决定了剩余表单的缩进或对齐规则。许多此位置的名称指示特殊的对齐或缩进规则; 这些是具有某些参数结构的特殊运算符、宏或过程。

然而,如果第一个子表单是非特殊名称,则如果第二个子表单在同一行上,则将所有后续子表单的起始列与第二个子表单的起始列对齐。如果第二个子表单在下一行上,则将其起始列与第一个子表单的起始列对齐,并对所有剩余的子表单执行相同的操作。

通常,Emacs会正确缩进Lisp代码。运行“C-M-q”(indent-sexp)以确保其正确缩进,并配置Emacs以使任何非标准形式适当缩进。

不可接受:

(+ (sqrt -1)
  (* x y)
  (+ p q))

(+
   (sqrt -1)
   (* x y)
   (+ p q))

可接受的:

(+ (sqrt -1)
   (* x y)
   (+ p q))

(+
 (sqrt -1)
 (* x y)
 (+ p q))

理由:列对齐使读者可以通过向下或向上扫描来直接跟踪任何操作的操作数,以匹配公共列。缩进指示结构;混乱的缩进是读者的负担,他们希望在没有手动匹配括号的情况下推导出结构。

1个回答

10

如果参数跨越多行(例如因为它们无法放在一行中),则所有参数应该具有相同的缩进。如果你将第一个参数放在新行上,那么缩进应该比函数本身更深一个级别(例如2个空格):

(foo (bar (baz
            arg1
            arg2)))
如果您将第一个参数与函数放在同一行,则其余部分的缩进应该相同:
(foo (bar (baz arg1
               arg2)))

我会按照以下方式缩进你的示例:

(defn get-neighbors [[x y] v]
  (for [y1 (range (dec y) (+ y 2))
        x1 (range (dec x) (+ x 2))
        :when (and (not (and (= x1 x)
                             (= y1 y)))
                   (in-bounds? x1 y1 v))]
    ((v y1) x1)))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接