什么是clojure的长文件?

时间:2015-10-16 23:15:04

标签: clojure

我已经学习了几个星期的clojure,最近我开始阅读一些开源代码:clojure和clojurescript编译器以及一些像om,boot,figwheel这样的库。

我注意到一些clojure文件非常长,其中一些超过一千个LOC。鉴于clojure的代码是非常简洁和低级的仪式,该代码意味着比其他语言中的大文件更多的代码。

来自OO背景,你通常每个文件有一个类,并且你试着保持你的课程简短(SRP)我发现有点奇怪。

我知道clojure代码主要由纯函数组成,并且它们比一些可变类更容易推理,你需要记住当前状态,我发现我可以阅读和理解最多一次一个的功能。但是大多数这些功能设计得非常好,以至于它们不相互依赖:即使你可以使用(filter odd?),它也不代表filter和{{1} } 有关系。但对于"每天"代码(LOB应用程序,网络应用程序等)很难将这些功能保持为自包含(至少这是我对OO编程的体验)。

我还看到了一些clojurescript应用程序(om,试剂等)的演示,他们在同一个文件中声明了所有组件。我不知道这是不是因为它只是一个演示而且在现实生活中我只有odd?product.clj或者#&# 39; s只是clojure方式:每个命名空间/模块/有界上下文有一个文件。

我认为,如果我打开一个文件夹并看到category.cljproduct.cljcategory.clj等,我可以一眼就知道该文件夹的内容,比拥有order.cljcomponents.clj更好。

所以,我的问题是:

  1. "每天都很常见" clojure代码有这些很长的文件?或者只是因为我正在阅读图书馆代码和#34;正常"代码更多"模块化",我的意思是:更多的文件和更少的长度。
  2. 拥有像这样的长文件是否真的让人难以理解应用程序的内容是什么?比如我上面的产品/类别/订单示例,或者某些不是问题的clojuresque属性。
  3. 如果长文件是" clojure方式",如何处理冲突,重构,团队编程......如果每个人都在触摸同一个文件?

4 个答案:

答案 0 :(得分:5)

1:我查看了我现在正在进行的相当大的非图书馆clojure项目,并运行了这个项目:

ls **/*.clj | xargs wc -l | awk '{print $1}' | head -n -1 > counts

并打开一个repl并运行

user> (float (/ (reduce + counts) (count counts)))
208.76471

我看到在17k LOC 的项目中,我们的平均clojure文件中有200行。我发现一个有1k LOC。

2:是的,一旦我有空的时间,我就会开始打破那个长的。一些非常长的,例如clojure.core是非常长的因为clojure的一次通过设计和自我引导的需要。他们需要建立能够拥有许多名称空间的能力,然后才能这样做。对于其他花哨的图书馆,很可能他们有一些大型文件的其他设计理由,尽管通常它是一个"拉请求欢迎"在我的expierence。

3:我在一个拥有几个大文件的大型团队中工作,我们处理与git的合并冲突,但是因为这些变化往往是在一个函数中出现,对我来说,比其他语言更少。我发现这根本不是问题。

答案 1 :(得分:1)

  1. 当你开发它们时,它们往往会变长。假设您需要一个函数foo来对数据结构K执行过程[ab ...]。首先(def)函数的签名并继续实现辅助函数ab ...因为它们可能是所有纯函数和foo所需的功能很复杂,命名空间往往会变长。

  2. 有时,但是repl是一个非常有用的工具,为了理解新库的主要功能,我经常在函数上使用clojure.repl / source,然后按照它的方式向后工作辅助功能。我发现很多时候Clojure图书馆的文档要么含糊不清要么不存在,但社区中的很多人都喜欢说Clojure的功能'来源是自我记录。

  3. 我没有在大型团队工作的经验,但是Arthur Ulfeldt是正确的,大多数变化都发生在一个函数中,我通过使用Github的Blame功能阅读pull请求的差异来收集它。

答案 2 :(得分:1)

  1. 避免依赖是务实的(clojure或不是)。命名和分类抽象的东西使我们的智力感觉良好,但当必须将所有部分缝合在一起时,它会放弃。为什么要做三个文件呢?
  2. 只需阅读代码,即可了解app / lib的全部内容?有“什么”,还有“如何”。如果你想潜入后者,最好有一个关于前者的线索。如果您正在阅读代码以获得有关应用程序目的的线索,我不确定将其拆分为更多文件会使其更容易。对你的例子三思而后行,如果没有其他事情,这些事情都不会存在。
  3. 大型团队的困难是分享最新的知识,而不是文件或行,感谢git。也许拥有同一个文件的每个人毕竟都是一个该死的好东西? 不,大文件在clj或其他方言中不是问题。单元< - >文件是一个完全javartificial概念,帮助编译器,而不是男人。拆分fg缓冲区。

答案 3 :(得分:1)

除了其他人给出的答案外,还有两个答案。

  1. 可能有些文件很长,因为在Clojure中,每个命名空间使用一个文件最直接,所以如果你想在同一个命名空间中使用所有这些定义,那么它就是更容易将它们放在一个文件中。希望定义驻留在同一名称空间中的一个原因在#2中给出。

  2. Clojure编译器不允许在命名空间之间使用某些类型的循环依赖关系(命名空间之间的其他循环依赖关系很好)。避免非法循环依赖的一种方法是将相互依赖的定义放在同一名称空间中。如果您这样做,那么将属于有问题的定义的其他定义也引入单个命名空间可能是有意义的。有关此答案的其余部分,请参阅#1。

  3. (我自己的口味是针对几个较小的文件,虽然不像许多Java类文件那么小。另外:代码通常不像作者所想的那样自我记录。即使作者和阅读代码以后是同一个人。)