2015-10-16 30 views
8

我一直在学习clojure几个星期,最近我开始阅读一些开源代码:clojure和clojurescript编译器以及一些类似om,boot,figwheel等库。clojure的长文件有什么用?

我注意到一些Clojure的文件是很长的,他们中的一些千余LOC。鉴于clojure的代码非常简洁而低级,该代码意味着比其他语言中的文件大得多的代码。

从OO背景的,你通常有每个文件一类和你尽量保持你的类短(SRP)我发现有点怪异。

我知道clojure代码主要由纯函数组成,它们比一些需要保持当前状态的可变类更容易推理,我发现我可以阅读和理解大多数一次一个的功能。但大多数功能设计得非常好,以至于它们不依赖于彼此:尽管您可以使用(filter odd?),但这并不意味着filterodd?是相关的。但对于“每一天”的代码(LOB应用程序,网络应用程序等)来说,很难保持这些函数的自包含性(至少这是我的OO编程经验)。

我也看到的,他们在同一个文件中声明的所有组件clojurescript应用程序(OM,试剂等)的一些演示。我不知道这是因为它只是一个演示,在实际生活中的应用,你就会有一个product.cljcategory.clj或者这只是Clojure的方式:让每个命名空间/模块/界上下文一个文件。

我想,如果我打开一个文件夹,我看到product.cljcategory.cljorder.clj,等我可以一目了然什么是关于该文件夹,不仅仅是有components.cljcore.clj更好的想法。

所以,我的问题是:

  1. 它是常见的“天天向上”的Clojure代码有这些非常长的文件吗?还是仅仅因为我正在阅读库代码,而“普通”代码更“模块化”,我的意思是:更多的文件和更少的长度。
  2. 这样长的文件是否会让人难以一目了然地理解应用程序的用途?像我上面的产品/分类/订单示例,或者一些clojuresque属性,这不是问题。
  3. 如果长文件是“Clojure的方式”,你如何处理冲突,重构,规划在一个团队......如果每个人都在接触相同的文件?

回答

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的一次通过设计和自引导的需要。他们需要在能够这样做之前构建具有许多名称空间的能力。对于其他花哨的图书馆来说,很可能他们有一些大型文件的其他设计理由,尽管通常这是我在期刊中的“请求受欢迎”的情况。

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

1
  1. 它们往往会随着您的发展而变长。假设你需要一个函数foo来执行数据结构K上的过程[ab ...]。首先(def)函数的签名并继续执行辅助函数ab ...因为它们可能都是纯函数和函数你需要foo是复杂的,命名空间往往会变长。

  2. 有时候,但repl是一个非常有用的工具,为了理解一个新库的主要功能,我经常在函数中使用clojure.repl/source,并在其辅助函数上反向工作。我发现很多时候Clojure图书馆的文档都不是神秘或不存在,但是社区中很多人喜欢说Clojure的功能来源是自我记录。

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

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

除了别人给出的答案之外,这里还有两个。

  1. 这可能是一些文件很长,因为Clojure中它是最简单的使用每个命名空间的一个文件,所以,如果你想都在同一个命名空间的定义,它更容易把它们放在一个文件。在#2中给出了让定义驻留在相同名称空间中的一个原因。

  2. Clojure编译器不允许命名空间之间的某些种类的循环依赖(命名空间之间的其他循环依赖很好)。避免非法循环依赖的一种方法是将相互依赖的定义放入相同的名称空间中。如果你这样做,将其他有问题的定义放入单个命名空间也是有意义的。请参阅#1了解其他答案。

(我自己的味道是几个较小的文件,虽然许多Java类文件不小。另外:代码功能,通常不如自文档作为笔者认为这可能保持甚至当笔者和稍后阅读代码的人是同一个人。)

相关问题