rwa*_*ace 11 programming-languages functional-programming language-design lazy-evaluation
很明显为什么想要懒惰的函数式编程语言需要纯粹.我正在考虑相反的问题:如果一种语言想要纯洁,那么懒惰是否有很大的优势?哈斯克尔的一位设计师提出的一个论点就是它消除了诱惑; 也许,但我正试图权衡更具体的优势.
鉴于您想要进行函数式编程,内置惰性可以让您更清楚,简单或简洁地表达事物的用例是什么?
简单地说:为什么懒惰如此重要以至于你想把它变成语言?
(我正在寻找更多面向应用程序而不是演示的用例 - 我知道你可以通过过滤无限的自然数列表来创建无限的素数列表,但是谁写了十次午餐...)
npo*_*cop 19
"在其他地方需要之前,没有任何东西被评估"是一个简化的比喻,它没有涵盖懒惰评估的所有方面(例如,它没有提到严格性现象).
从理论的角度来看,在设计纯语言时有三种方法可去(当然,如果它基于某种lambda演算,而不是基于更奇特的评估模型):严格,非严格和完整.
他们每个人都有自己的优点和缺点,所以你需要阅读相应的研究论文.
总的语言是这三种语言中最纯粹的.在另外两个中,非终止可以被视为副作用,因此必须构建严格性和总体分析器以保持实现有效.这两种分析都是不可判定的,因此分析仪永远不会完整.
但是,总语言最不具有表现力:总体语言不可能是图灵完整的.获得足够好的表达能力的一种常用方法是使用内置的证明系统进行有根据的递归,这种方法比非总语言的分析器更容易构建.
从实际角度来看,非严格语义使您可以更轻松地定义控件抽象,因为控制结构本质上是非严格的.在严格的语言中,您仍然需要一些具有非严格语义的地方.例如,if
即使在严格的语言中,构造也具有非严格的语义.
因此,如果您的语言严格,控制结构就是一种特殊情况.相反,非严格语言可以统一为非严格 - 它在严格的结构中没有固有的需要.
至于"谁在午餐前写了十次" - 任何使用Haskell进行项目的人都可以.我认为使用一种语言(在你的情况下是一种非严格的语言)开发一个非玩具项目是掌握其优点和缺点的最佳方法.
以下是非玩具示例所示的一些懒惰的通用用例:
控制流很难预测的情况.想想属性语法,当没有懒惰时,你必须对属性进行拓扑排序以解决dependensies.每次更改依赖关系图时重新排序代码都是不切实际的.在Haskell中,您可以在没有显式排序的情况下实现属性语法形式,并且在Hackage上至少有两个实际的实现.属性语法在编译器构造中有广泛的应用.
"生成和搜索"方法可以解决许多优化问题.在严格的语言中,你必须交错生成和搜索,在Haskell中你只需要编写单独的生成和搜索函数,你的代码在语法上保持模块化,但在运行时交错.想想旅行商问题(TSP),当您生成所有可能的旅程,然后使用分支定界算法搜索它们.请注意,分支绑定算法仅检查巡视中的某些第一个城市,仅生成路线的必要部分.即使在最纯粹的配方中,TSP也有多种应用,例如规划,物流和微芯片的制造.稍微修改后,它似乎是许多领域的子问题,例如DNA测序.
惰性代码具有非模块化控制流,因此单个函数可以根据其执行的环境具有许多可能的控制流.这种现象可以被视为某种"控制流多态",因此惰性控制流抽象更通用与他们的严格对应物相比,高阶函数的标准库在惰性语言中更有用.想想Python生成器,循环和列表迭代器:在Haskell列表函数中涵盖所有三个用例,控制流由于懒惰而适应不同的使用场景.它不仅限于列表 - 想想Data.Arrow和iteratees,懒惰和严格版本的State monad等.另请注意,非模块化控制流程既有优点也有缺点,因为它使得对性能的推理更加困难.
懒惰可能无限的数据结构在玩具示例之外是有用的.查看Conal Elliott关于使用try来记忆高阶函数的作品.无限数据结构在Python意义上显示为无限搜索空间(参见2),无限循环和永不耗尽的生成器(参见3).