用于构造Clojure源代码的惯用法

时间:2010-06-17 14:47:43

标签: clojure code-structure

我对人们如何构建他们的Clojure源代码感兴趣。

习惯Java,我非常熟悉每个源代码文件一个类的范例,用适当的注释和注释等捆绑所有数据和方法定义。

然而Clojure提供了更多的灵活性,我不确定我应该如何构建我的项目(可能最终成为一个中型应用程序,可能是5000行,有三个或四个不同的子系统)

特别是我正在努力:

  • 我应该使用什么指南来确定代码是否应该在单个命名空间中而不是分隔成不同的命名空间?
  • 每个协议/数据类型是否应该拥有自己的命名空间+源文件以及相关的一组函数?
  • 我应该何时需要使用其他名称空间?

1 个答案:

答案 0 :(得分:8)

我也来自Java背景,还有相当多的Ruby和一点Go。这就是我现在正在做的事情,大约一个月进入Clojure:

  • 我正在考虑将命名空间作为语义单元,它是为特定目的而组合在一起的代码,如数据类型及其上的操作。

我有两个命名空间与文件的约定:

  • 对于在一个文件中舒适地适合的小型单元(我使用~1000行作为文件应该拆分的限制)我每个文件有一个命名空间,目录路径加文件名与命名空间相同。我认为这在Java中是一件好事,它使得从文件中查找命名空间或反之亦然。
  • 对于需要多个文件的较大单元,我使用Go约定:命名空间与目录路径匹配,并且目录中的所有文件共享相同的命名空间。在这些情况下,我通常会为主文件分配一个固定名称('main'),该文件加载并与其他文件进行交互。

作为名称空间示例,我有一个读取格式并将其转换为HTML的解析器。我有一个解析器的命名空间(语义单元)和目录中的几个文件分为子功能:Lexer,解析器,HTML转换和包含使用解析器的主公共API的主文件。

我不会自动为每个数据类型使用一个命名空间,它取决于数据类型的范围。如果它是一个大的,也许。但对于像Point这样的数据类型,有两个字段和几个函数,我宁愿将它包含在像Geometry这样更通用的命名空间中。

要求与使用:

  • 几乎在任何地方都需要一个适当短的别名。
  • 这也允许重用核心名称:我的专用树数据类型具有适合地图的操作“get”;使用require没有冲突:“get”是Clojure核心获取,“tree / get”是我的数据类型。
  • 我只是将“使用”用于我认为的“核心扩展”,比如当我创建自己的“map-if”时,即map和filter集合在一起。