管理clojure中括号的数量

管理clojure中括号的数量,clojure,lisp,readability,code-readability,Clojure,Lisp,Readability,Code Readability,我是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

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

有很多端部支架。有什么最好的方法可以减少或格式化它,使其更容易发现缺少的括号?

我不确定您是否可以避免所有括号。然而,我看到Lispers所做的是使用带有paren匹配/突出显示甚至彩虹括号的编辑器:


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

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


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

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


Emacs with(强烈推荐!)默认为clojure启用了paredit。否则,请参见

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

(defn rep [coll n] (mapcat (partial repeat n) coll))
当然,这更多的是一门艺术(工艺)而不是科学,但一些指针(以随机顺序):

  • 顶级用户的问题及其解决方案(在解决特定问题后可见)-我相信Chris Houser就在那里
  • 说到CH——《Clojure的快乐》是一本非常有用的书
  • 浏览clojure.core上的文档-那里有很多有用的功能
  • ->
    ->
    线程宏对于展平嵌套代码非常有用
  • stackoverflow-世界上一些最聪明、最乐于助人的人在那里回答问题;-)
我认为这更具可读性。请注意:

  • 当尾部递归时,应该使用recur
  • 您应该使用
    seq
    进行测试-请参阅
  • 重复可以计数
  • concat将删除nil,这样可以避免重复您自己的操作
  • 你不需要为每一个开放的paren开始一个新的行
至于paren,您的编辑器/ide应该负责这一点。我在这里打字是瞎的,所以如果是错的请原谅我

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


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

我无法充分反映在另一个编辑器中使用paredit或类似功能的价值。它让你完全不必关心paren——它们总是完美地匹配自己,而像“将
(foo(bar x)y)
更改为
(foo(bar x y))
”这样单调、容易出错的编辑任务只需一次按键。一周左右的时间里,paredit会让你感到难以置信的沮丧,因为它会阻止你手工操作,但一旦你学会了自动处理Paren的方法,你就再也无法回头了


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

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

按你喜欢的方式格式化它。编辑的工作是以读者喜欢的任何样式显示代码。我喜欢C风格的层次树形格式,在它们自己的行上有一个括号(所有的Lisper都对此怒不可遏:-()()()()()()()(

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

  (fn rep 
  ([lst n]
    (rep (rest lst)
    n
    (take n 
      (repeat (first lst)) )  )   )    )
这是对传统样式的更新,在传统样式中括号是间隔的(log2分支级别)

我喜欢太空的原因是我的视力很差,根本看不懂密集的文字。所以对于那些愤怒的口齿不清的人,他们会告诉我要用传统的方式做事,我说,好吧,每个人都有自己的方式,放松,没关系

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


**是的,我知道有emacs/paredit,但我试过emacs,不喜欢它。对不起。

这是
Lisp anese
。使用一个合适的编辑器来帮助括号匹配是一种方法。你可以在它们自己的行上放一个括号,并将它们与左括号对齐(就像C#或Java的标准大括号语法)。然而,有些口齿不清的人可能会对你说些猥亵的话:)我想我会以“口齿不清的人”的身份加入进来,尽管我只使用了两年的口齿不清。把paren放在自己的行上就像是格式化的大罪——没有比这更糟糕的选择了。lisp的许多方言都(或多或少地)采用了单一的编码风格,因为它可读性很强,不像C语言,C语言都有许多激发圣战的风格。不要因为没有掌握标准样式的诀窍就放弃它。对于emacs,请看这个问题:我在emacs中使用了rainbow parens一段时间。我不再这样做了,主要是因为我认为这会鼓励您实际进行手动/心理paren匹配,而不是让paredit为您完成这一切。但我承认彩虹帕伦斯看起来很酷,所以如果你只是为了外表,我真的无法争辩。@amalloy:你能同时使用paredit和彩虹帕伦斯吗?@Tactical
  (fn rep 
  ([lst n]
    (rep (rest lst)
    n
    (take n 
      (repeat (first lst)) )  )   )    )