在本文中,我们介绍了流处理器到支持纯函数式的并发编程风格语言。流处理器允许在内部并发进程的层次结构状态。因此,它们支持大型程序的模块化设计。使用这里定义的流处理器,我们从流。我们为流处理器定义了许多组合子,但对流本身没有操作。我们已经考虑了流处理器的不同实现的数量,其中一些它们是确定性的,在一个纯粹的序列函数中工作没有任何扩展的语言,其中一些可以利用平行评价与非决定性选择(第20章).
我们还提供了一个用于构造的组合子库具有图形用户界面的应用程序(第二部分)和键入网络通信(第26章). 连同一系列应用程序,该库已经演示了流处理器/fudget概念可扩展;它不仅可以用来编程玩具示例,但更复杂的应用程序,如WWW浏览器(第32章)和语法导向的校对编辑器(第三十三章). 这里的一个关键组合词是循环吞吐量右SP
(第18.2条),允许现有流以类似于面向对象编程中的继承。
该库还演示了纯函数式编程语言适用于这些任务,而不是清楚这项工作何时开始。虽然GUI fudget程序可以相当数量的I/O,响应时间可以保持足够低(第27.5.3节).
因为我们通过发送为消息,我们已经能够编写高阶函数操纵软糖的I/O效果(第24章),其中提供了修改现有行为的可能性软糖。缓存机制(第24.1条)和点击输入输入模型(第24.2条)已使用此方法实现。
默认参数机制(第十五章和30)演示Haskell的类系统和高阶函数可以组合来模拟缺失语言功能。稍后,还有另外两个GUI库,Gadgets(第41.3.1条)和TkGofer(第41.4条),已采用此机制。
软糖图形F
在里面第27章表明可以在中高效地处理图形的显示和操作一种纯粹的功能性方式。它已在web浏览器中使用在里面第32章校对编辑阿尔法第三十三章。位于的顶部图形F
,我们还实施了一组组合符,允许面向语法的编辑器以高级风格构建,类似于组合符解析器(第28章). 我们使用这些组合器的经验是有限的sofar,但我们相信他们可以在Alfa的未来版本。
虽然我们展示的大多数流处理器都是在CPS样式,可以使用其他样式。简单的流处理器可以通过使用进行编程concatMapAccumlSP
和一个州过渡函数。也可以按原样使用单数风格在中演示第31章.
如相关工作所示第41章,数量为优雅的库和界面已经出现,用于GUI编程在过去的几年里,使用纯函数式语言。有可能吗评估和比较所有这些库和Fudget库?这在一定程度上是在[1995年11月]. 这里我们不做进一步的比较,但只需指出软糖和一般流处理器:
- 流处理器提供了一个简单的并发概念可以用任何纯函数语言实现。另一个的工具包,Concurrent Clean还提供了一个纯粹的功能过程概念,但它的实现相当复杂[96英亩].
fudget概念已经在许多GUI工具箱[1995年11月][泰伊96][RS93标准][CVM97型],这也证明了软糖很容易实施。
- 流处理器具有特殊的编程风格。自没有使用明确的流、通道或线路进程之间的信息必须使用组合词。这可以被视为范式的局限,有些人确实觉得很难收养。在USENET上,这被表述为:``。。。你可以用这样的东西用小工具构建GUI,但这比有牙齿有趣得多拉动“”[96欧]. 典型的示例所需的路由数量显示在
somF公司
英寸(第28.4条,图81),具有处理三个输出和三个输入的流处理器流。一个极端的例子是阿尔法的顶级骗局(第三十三章),其控制流处理器定义15路由函数,用于处理以下五个级别的深层消息要么
类型。通过使用一个在顶级fudget中添加新的子预算已经成为可管理的任务。它仍然需要太多的机械并且需要一些新的组合子集或进一步简化此编程任务的其他解决方案。有人可能会说,信息的组合管道对程序施加一定程度的结构健康。具有分布在上的流的显式标识符该程序很容易生成goto式的意大利面。功能约翰·巴克斯的FP语言[78岁]完全是基于使用组合子而不是命名变量。
- 流处理器概念还支持使用特殊功能操作迁移进程当一个进程被移动时,它与所有进程完全分离旧上下文中的流(第25章). 我们不知道任何其他工具箱或流程中类似的东西微积分。此外,由于流处理器是纯值(特别是,它们不使用命令变量),可以随时可以克隆。
如所示第25章,迁移机制可以应用于fudgets并用于实现GUI的拖放软糖。
Fudgets库中的惰性评估有多重要编程?Fudgets可以用ML实现吗?
当Fudgets的工作开始时,Haskell使用了基于流的I/O模型和流进程表示为列表功能。如今,基于连续性的表示使用了流处理器,Haskell已切换到单数I/O系统,两者都可以用严格的语言工作。所以,懒惰的评估不再重要。基于流的I/O的一个问题是存在退出的危险同步“”并读取一个结果太多或太少。是这样的吗你在实践中遇到过吗?
有一段时间,当我们使用基于列表的表示和该表示对程序员可见程序员必须了解“fudget法则”,即输入和输出消息之间的一一对应(请参见第20.4.1条). 我们有时会犯错误。什么时候?流处理器类型被抽象化,即福吉特定律变得内置,程序员不再思考此外,我们开始通过函数进行低级别I/O喜欢doStreamIOK(数据流IOK)
(第21.4节),有效地删除了所有此类问题。Haskell已从流式I/O转移到单体式I/O。您的操作是CPS风格的,但也可以是monad风格的。你是有意识地做出这个选择的吗?为什么?
当我们引入了CPS样式的组合符,因此我们没有制作有意识地选择CPS风格和一元风格。你有没有遇到过Haskell的类型系统阻止你做正确的事?
对。例如,类型X命令
应该是X Windows的接口,但我们添加了各种``pseudo在Haskell程序中处理且从不执行的命令“”输出到窗口系统。如果能定义一下就好了将适当的命令作为所有命令的子类型。做这个Haskell中的区别需要额外的标记级别,我们认为这是不合理的。类似地,类型X事件
包含一些“伪事件”。