功能编程架构
我熟悉面向对象的体系结构,包括使用设计模式和类图进行可视化,并且我知道带有契约和协议绑定的面向服务的体系结构,但是用这种语言编写的系统的软件体系结构有什么特点?功能编程语言?
我知道FP已用于中型到大型项目。保罗·格雷厄姆(Paul Graham)撰写了Yahoo!的第一个化身。存放在Common Lisp中。一些Lisp开发系统很复杂。用功能语言编写的人工智能和财务系统可能会变得非常庞大。它们都至少具有某种固有的体系结构,但是,我想知道它们是否有共同点?
基于表达式求值的体系结构是什么样的? FP架构是否更具可组合性?
更新:凯尔(Kyle)提醒我,SICP是此主题的不错资源。
更新2:我在以下主题上找到了一篇不错的文章:函数式编程如何影响代码的结构?
解决方案
在功能语言中,最大的共性是使用函数存储数据。这有点像在没有对象的对象上使用访问器函数。而是在可以访问所需数据的环境中创建该函数。现在,此函数可以在任何地方传递和使用,并且仍然保留使用数据的功能。
这是一个非常简单的示例。这并不是纯粹的功能,因为它确实会改变状态,但是很常见:
(define (make-counter) (let ((count 0)) (lambda () (set! count (+ count 1)) count))) (define x (make-counter)) (x) returns 1 (x) returns 2 ...etc...
因此,我们有一个生成计数器的函数,该函数返回另一个具有内部计数器状态的函数。我们可以调用该新创建的计数器并观察内部的变化。
这就是功能程序的结构方式。我们有将函数作为参数的函数,有返回具有隐藏状态的函数的函数,等等。这比自己管理内存要干净得多。
我已经处理了一些相当大的功能项目。它们通常分为两个阵营(至少是我使用过的阵营):
- 极好的可扩展性/可靠性/并发性。事务模型可以非常紧密地构建到语言中。并发ML是一个很好的例子,使用并发ML的项目在并发正确性方面很难出错。
- 解析/修改框架。这些框架所基于的许多设计模式都非常容易用功能语言来表述/构建/修改。访客模式就是一个很好的例子。
我打印并查看了Ocaml中的"设计模式",它们使用模块和函子(和对象)来重新创建我们习惯的正常设计模式。这很有趣,但是我认为他们过多地使用对象,以至于无法真正看到功能语言的好处。 FP非常容易组合,这是其本质的一部分。我想我的简短答案是使用模块和函子。
我当前的项目很大,我们通过文件将每个模块分开-隐含在ocaml中。我也一直在寻找全面的资源,对于从项目中获得的真正成功的设计,可能会有其他看法或者想法。
我认为这可能会有所帮助;
Some of the patterns disappear -- that is, they are supported directly by language features, some patterns are simpler or have a different focus, and some are essentially unchanged.
[AIM-2002-005] Gregory T. Sullivan,可执行程序设计模式的高级编程语言功能"通过反射实现更好的模式
2002年3月22日
The Design Patterns book [GOF95] presents 24 time-tested patterns that consistently appear in well-designed software systems. Each pattern is presented with a description of the design problem the pattern addresses, as well as sample implementation code and design considerations. This paper explores how the patterns from the "Gang of Four'', or "GOF'' book, as it is often called, appear when similar problems are addressed using a dynamic, higher-order, object-oriented programming language. Some of the patterns disappear -- that is, they are supported directly by language features, some patterns are simpler or have a different focus, and some are essentially unchanged.
使用功能语言的项目"体系结构"中的共同点是,它们倾向于分为代数层,而不是传统系统体系结构意义上的子系统。
有关此类项目的绝佳示例,请查看XMonad,Yi和HappS。如果检查它们的结构,我们会发现它们由单层结构组成,中间夹有一些组合胶。
另请参阅Scala实验论文,该论文概述了一种体系结构,其中系统由对其依赖关系进行抽象的组件组成。
希望不要太切切,但对于浏览此问题的答案的任何人来说可能很有趣,这是Peter Norvig的演示"动态编程中的设计模式"。