【问题标题】:Managing number of brackets in clojure管理clojure中的括号数量
【发布时间】:2012-04-10 19:37:54
【问题描述】:

我是 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))))))))

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

【问题讨论】:

  • 那是 Lisp-anese 给你的。使用有助于括号匹配的体面编辑器是一种方法。
  • 您总是可以将单括号放在自己的行上,并与左括号对齐(如 C# 或 Java 的标准花括号语法)。然而,一些铁杆 Lispers 可能会对你说不礼貌:)
  • 我想我会以“核心 lisper”的身份介入,尽管我只使用 lisp 两年。将括号放在自己的行上就像格式化的主要罪恶 - 你可以做出更糟糕的选择。 lisp 的许多方言都(或多或少地)选择了一种编码风格,因为它具有相当的可读性,不像类 C 语言,它们都有许多激发圣战的风格。不要因为你没有掌握它的窍门就放弃标准风格。

标签: clojure lisp readability code-readability


【解决方案1】:

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

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

【讨论】:

  • 当我第一次开始使用 emacs 时,我讨厌 paredit。但是,一旦我了解它对我的作用,(emacswiki.org/emacs/PareditCheatsheet) 我就不能没有它。
  • 我选择了另一个答案,因为我是 vim 用户,但为 paredit +1
【解决方案2】:

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

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

当然,这与其说是科学,不如说是一门艺术(工艺),但有一些提示(按随机顺序):

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

【讨论】:

  • 感谢您的提示!我已经在可能的情况下多次解决每个 4clojure 问题,至少一次使用递归,至少一次没有递归。这只是一个带有很多括号的示例。不过,您的上述提示无疑会非常有用
【解决方案3】:

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

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

【讨论】:

  • 对于 emacs,请参阅这个 SO 问题:stackoverflow.com/questions/2413047/…
  • 我在 emacs 中使用了一段时间的 Rainbow Parens。我不再这样做了,主要是因为我认为这会鼓励您实际进行手动/心理配对,而不是让 paredit 为您完成所有工作。但我承认 Rainbow Parens 看起来很酷,所以如果你只是为了好看我真的无法争辩。
  • @amalloy:你能同时使用 pareditrainbow-parens 吗?
  • @TacticalCoder 是的。我现在正在这样做。我同意它看起来很漂亮,而且它不会妨碍我,但我认为我并没有真正从中得到太多,就生产力而言。 (就我个人而言,真正喜欢的是括号匹配与全表达式突出显示,Emacs 也可以这样做。)
【解决方案4】:

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

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

【讨论】:

    【解决方案5】:
    (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 的代码更短;我也在学习...]

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

    【讨论】:

    • 感谢您的提示,我会在以后考虑它们。
    【解决方案6】:

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

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

    【讨论】:

      【解决方案7】:

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

      【讨论】:

        【解决方案8】:

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

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

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

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

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

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

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

        【讨论】:

        • 只要您不与任何人共享您的代码,就可以。但通常我们在代码上进行协作,然后像这样深奥的格式就成了一个大问题。
        • 有趣!我一直在研究基于表达式的 Clojure 代码编辑器,因为我经常对文本编辑器的局限性感到沮丧。你能告诉我你再次喜欢文本编辑器的主要原因是什么吗?
        • 格式化代码更像是格式化诗歌而不是散文——内容和形式交织在一起。以 lisps 为例,它们在格式方面更为严格。您仍然决定换行符 - 并为此烦恼。更重要的是,您的代码会更改以适应其格式(选择使用本地/内联 expr,选择适合行的标识符,在 Clojure 中选择何时使用画眉运算符,我什至有一些自己的宏来减少缩进) .此外,您的规范代码格式(包含“仅内容”的格式)会受到 grepping、diffing 等的影响。
        • 所有好点的欢呼。当我下次有机会在我的编辑器上工作时,我会牢记所有这些,尤其是关于在两种构象(内联或树形、画眉或嵌入式)之间切换的要点。但是,我要说的是,没有人真正同意“最好”的代码格式化方式,这是个人喜好问题,对于一个人来说看起来像逻辑流程的东西在另一个人看来是错误的。
        • 好吧,如果在表达式级别(后阅读器)比较代码,那么只会发现有意义的差异——在 Clojure 中很容易做到,在类 C 语言中则不那么容易
        猜你喜欢
        • 2015-02-07
        • 1970-01-01
        • 1970-01-01
        • 2021-08-20
        • 2023-04-02
        • 1970-01-01
        • 2012-01-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多