9

我是 clojure 的新手,我正在努力解决的主要问题是编写可读的代码。我经常会得到像下面这样的函数。

(fn rep 
  ([lst n]
    (rep (rest lst)
    n
    (take n 
      (repeat (first lst)))))
  ([lst n out]
    (if
      (empty? lst)
      out
      (rep 
        (rest lst) n
        (concat out (take n 
          (repeat 
            (first lst))))))))

有很多末端支架的堆积。减少这种情况或以一种更容易发现缺失括号的方式对其进行格式化的最佳方法是什么?

4

8 回答 8

15

使用 Emacs 的paredit模式(也在其他一些编辑器中模拟)意味着您通常 - 除非您使用鼠标/强制非结构化选择复制/粘贴 - 处理匹配的括号/大括号/括号和相关的缩进,不需要计数。

带有https://github.com/technomancy/emacs-starter-kit(强烈推荐!)的 Emacs 默认为 clojure 启用了 paredit。否则,请参阅 http://emacswiki.org/emacs/ParEdit

于 2012-04-10T20:17:53.600 回答
13

除了拥有支持大括号匹配的编辑器之外,您还可以尝试减少代码嵌套。我相信您的功能可以重写为:

(defn rep [coll n] (mapcat (partial repeat n) coll))

当然,这更像是一门艺术(工艺)而不是科学,但有一些指示(按随机顺序):

  • 4clojure上的问题及其顶级用户的解决方案(在解决特定问题后可见) - 我相信 Chris Houser 在处理chouser
  • 说到 CH——“Clojure 的乐趣”是一本非常有用的读物
  • 在 clojure.core 上浏览文档 - 那里有很多有用的功能
  • ->->>线程宏对于扁平化嵌套代码非常有用
  • stackoverflow - 世界上一些最聪明和最有帮助的人在那里回答问题;-)
于 2012-04-10T20:20:46.580 回答
7

在这种情况下,为括号着色的编辑器非常有用。例如,这是您的代码在我的 vim 编辑器中的样子(使用vimclojure):

彩虹色

由于您没有说明您使用的是哪个编辑器,因此您必须为您的编辑器找到适当的彩虹着色功能。

于 2012-04-10T19:48:33.033 回答
3
(fn rep 
  ([lst n]
    (rep lst n nil))
  ([lst n acc]
    (if-let [s (seq lst)]
      (recur (rest s) n (concat acc (repeat n (first s))))
      acc)))

我认为这更具可读性。注意:

  • 尾递归时应该使用 recur
  • 你应该测试seq- 见http://clojure.org/lazy
  • 重复可以计数
  • concat 将丢弃 nil,这样可以避免重复自己
  • 你不需要为每个打开的括号开始一个新行

至于括号 - 你的编辑器/IDE应该照顾好它。我这里是瞎写的,如有错误请见谅...

[Rafał Dowgird 的代码更短;我也在学习……】

[更新:]重新阅读“懒惰”链接后,我认为我一直在错误地处理懒惰序列,

于 2012-04-10T20:28:53.920 回答
3

我无法足够强烈地回应使用 paredit 或其他编辑器中的某些类似功能的价值。它使您完全无需关心括号 - 它们总是完美匹配自己,并且像“更改(foo (bar x) y)(foo (bar x y))”这样的繁琐且容易出错的编辑任务变成了一次击键。在一周左右的时间里,paredit 会让你难以置信,因为它会阻止你手动做事情,但是一旦你学会了自动处理 parens 的方法,你将永远无法回头。

我最近听到有人说,我认为它大致准确,写 lisp 没有 paredit 就像写 java 没有自动完成(可能,但不是很愉快)。

于 2012-04-10T20:37:18.803 回答
2

我不确定您是否可以避免所有括号。但是,我看到 Lispers 所做的是使用带有括号匹配/突出显示甚至彩虹括号的编辑器:http://emacs-fu.blogspot.com/2011/05/toward-balanced-and-colorful-delimiters 。 html

坦率地说,这些特性对非 Lisp 编辑器也很有用 :)

于 2012-04-10T19:44:15.617 回答
1

始终使用由至少 75% 的消费后材料制成的 100% 回收的右括号;那么你不必为使用这么多而感到难过。

于 2012-04-10T22:36:27.430 回答
1

随意格式化它。以读者喜欢的任何风格显示代码是编辑器的工作。我喜欢 C 风格的分层树形格式,在它们自己的行上带有一个括号(所有的 LISPers 都对此大发雷霆:-)))))))))))))

但是,我有时会使用这种风格:

  (fn rep 
  ([lst n]
    (rep (rest lst)
    n
    (take n 
      (repeat (first lst)) )  )   )    )

这是对括号间隔的传统样式的更新(log2 分支级别)

我喜欢空间的原因是我的视力很差,我根本无法阅读密集的文字。所以对于那些即将告诉我按照我所说的传统方式做事的愤怒的 LISPers,好吧,每个人都有自己的方式,放松,没关系。

等不及有人在 Clojure 中编写了一个像样的编辑器,它不是文本编辑器而是表达式编辑器**,然后格式问题就消失了。我自己写一个,但需要时间。这个想法是通过对表达式应用函数来编辑表达式,我使用拉链来导航代码,逐个表达式,而不是单词、字符或行。代码由您想要的任何显示功能表示。

** 是的,我知道有 emacs/paredit,但我尝试了 emacs 并且不喜欢它,抱歉。

于 2012-04-11T00:31:13.080 回答