functional-programming - 在 OCaml 中设计大型项目

标签 functional-programming ocaml

关闭。这个问题是opinion-based .它目前不接受答案。












想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题.

2年前关闭。




Improve this question




在 OCaml 中编写大型软件项目的最佳实践是什么?

你如何组织你的项目?

OCaml 的哪些特性应该和不应该用于简化代码管理?异常(exception)?一流的模块? GADT?对象类型?

建系统?测试框架?宬?

我发现很棒 recommendations对于haskell,我认为为OCaml 提供类似的东西会很好。

最佳答案

我将在我熟悉的条件下回答一个中等规模的项目,即 10 万到 100 万行源代码和最多 10 名开发人员。这就是我们现在正在使用的,用于两个月前于 2013 年 8 月开始的项目。

构建系统和代码组织:

  • 一个可源码的 shell 脚本为我们的项目定义了 PATH 和其他变量
  • 启动顶级 session 时,我们项目根目录下的一个 .ocamlinit 文件会加载一堆库
  • omake,速度很快(使用 -j 选项进行并行构建);但我们避免制作疯狂的自定义 omake 插件
  • 一个根 Makefile 包含所有基本目标(设置、构建、测试、清理等)
  • 一级子目录,而不是两级
  • 大多数子目录构建到 OCaml 库中
  • 一些子目录包含其他内容(设置、脚本等)
  • OCAMLPATH 包含项目的根目录;每个库子目录生成一个 META 文件,使项目的所有 OCaml 部分都可以使用 #require 从顶层访问。
  • 整个项目只构建了一个 OCaml 可执行文件(节省了大量链接时间;仍然不知道为什么)
  • 使用 opam
  • 通过安装脚本安装库
  • 本地 opam 包是为不在官方 opam 存储库中的软件制作的
  • 我们使用 opam 开关,它是以我们的项目命名的别名,避免与同一台机器上的其他项目发生冲突

  • 源代码编辑:
  • 带有 opam 包 ocp-indent 和 ocp-index 的 emacs

  • 源头控制和管理:
  • 我们使用 git 和 github
  • 所有新代码都通过 github 拉取请求进行同行评审
  • 非 opam 非 github 库的 tarball 存储在单独的 git 存储库中(如果历史记录太大,可能会被吹走)
  • github 上现有的前沿库 fork 到我们的 github 帐户中,并通过我们自己的本地 opam 包安装

  • OCaml 的使用:
  • OCaml 不会补偿糟糕的编程实践;教授品味超出了这个答案的范围。 http://ocaml.org/learn/tutorials/guidelines.html是一个很好的起点。
  • OCaml 4.01.0 比以前更容易重用记录字段标签和变体构造函数(即 type t1 = {x:int} type t2 = {x:int;y:int} let t1_of_t2 ({x}:t2) : t1 = {x} 现在有效)
  • 我们尽量不在我们自己的代码中使用camlp4 语法扩展
  • 我们不使用类和对象,除非某些外部库强制要求
  • 理论上从 OCaml 4.01.0 开始,我们应该更喜欢经典变体而不是多态变体
  • 我们使用异常来指示错误并让它们愉快地通过,直到我们的主服务器循环捕获它们并将它们解释为“内部错误”(默认)、“错误请求”或其他内容
  • 可以在有意义的情况下在本地使用 Exit 或 Not_found 等异常,但在模块接口(interface)中我们更喜欢使用选项。

  • 库、协议(protocol)、框架:
  • 我们对 OCaml 标准库中缺少的所有商品功能使用 Batteries;其余的我们有一个“util”库
  • 我们使用 Lwt 进行异步编程,没有语法扩展,并且绑定(bind)运算符 (>>=) 是我们使用的唯一运算符(如果您必须知道,我们不情愿地使用 camlp4 预处理来更好地跟踪绑定(bind)点的异常)。
  • 我们使用 HTTP 和 JSON 与第 3 方软件进行通信,我们希望每个现代服务都提供此类 API
  • 为了提供 HTTP 服务,我们在 nginx 后面运行我们自己的 SCGI 服务器(ocaml-scgi)
  • 作为 HTTP 客户端,我们使用 Cohttp
  • 对于 JSON 序列化,我们使用 atdgen

  • “云”服务:
  • 我们使用了很多它们,因为它们通常很便宜,易于交互,并为我们解决了可扩展性和维护问题。

  • 测试:
  • 我们有一个用于快速测试的 make/omake 目标和一个用于慢速测试的目标
  • 快速测试是单元测试;每个模块可以提供一个“测试”功能; test.ml 文件运行测试列表
  • 慢速测试是那些涉及运行多个服务的测试;这些是专门为我们的项目制作的,但它们尽可能多地涵盖了生产服务。一切都在 Linux 或 MacOS 上本地运行,除了我们想方设法不干扰生产的云服务。

  • 设置这一切是相当多的工作,尤其是对于不熟悉 OCaml 的人。目前还没有框架可以解决所有这些问题,但至少您可以选择工具。

    关于functional-programming - 在 OCaml 中设计大型项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19350590/

    相关文章:

    compiler-errors - 如何从 Ocaml 编译器中获取更多信息

    scala - 可折叠 "foldMap"采取部分功能 : foldCollect?

    functional-programming - 组织Clojure代码

    haskell - 对参数进行排序以利用柯里化(Currying)

    oop - 在 OCaml 的 OOP 构造中动态确定类型

    ocaml - OCaml 中 monad 有什么用?

    module - ocaml 模块和程序位于同一文件中

    scala - 在 Scala 中使用累加器映射列表的功能方法

    Java 8 函数 - 组合和然后

    ocaml - llvm OCaml 绑定(bind)