Haskell,Lisp和详细

对于那些在Haskell和Lisp方面有经验的人,我很好奇在Haskell和Lisp中编写代码是多么“愉快”(用一个可怕的术语)。

一些背景:我现在正在学习Haskell,之前曾经在Scheme和CL上工作过(还有一些进入Clojure)。 传统上,你可以认为我是dynamic语言的粉丝,他们提供的简洁和快速。 我很快就爱上了Lisp的macros,因为它给了我另一种避免冗长和样板的方法。

我发现Haskell 非常有趣,因为它向我介绍了我不知道存在的编码方式。 它肯定有一些方面,似乎有助于实现敏捷性,如易于编写部分function。 然而,我有点担心失去Lispmacros(我想我失去了它们;事实上被告知我可能还没有学到它们呢?)和静态分类系统。

那些在这两个世界上都做了大量编码的人,会不会介意经验的不同,你更喜欢哪一个,如果说偏好是情境的话?

简短的回答:

  • 几乎任何你可以用macros来做的事情,你可以用一个更高级的函数来做(我包括单子,箭头等等),但是它可能需要更多的思考(但只是第一次,而且很有趣,你会成为一个更好的程序员),和
  • 静态系统是足够一般的,它永远不会妨碍你,有点令人惊讶的是它实际上“有助于实现敏捷性”(如你所说),因为当你的程序编译时,你几乎可以肯定是正确的,所以这个确定性让你尝试你可能会害怕尝试的东西 – 编程有一个“dynamic”的感觉,尽pipe它与Lisp不一样。

[注:有一个“ 模板Haskell ”,可以让你像Lisp一样编写macros,但严格来说,你永远不需要它。]

首先,不要担心丢失dynamictypes等特殊function。 由于您熟悉Common Lisp,这是一个非常精心devise的语言,因此我认为您知道语言不能简化为其function集。 这完全是一个连贯的整体,不是吗?

在这方面,Haskell和Common Lisp一样明亮。 它的function结合在一起,为您提供了一种编程方式,使代码变得非常简短和优雅。 macros的缺乏可以通过更复杂(但同样更难理解和使用)概念(如monads和arrow)来减轻。 静态types系统增加了你的能力,而不像在大多数面向对象的语言中那样陷入困境。

另一方面,Haskell的编程与Lisp的交互性要差得多,Lisp等语言中存在的大量reflection并不适合Haskell预设的世界的静态视图。 因此,这两种语言的工具集有很大不同,但很难相互比较。

我个人更喜欢Lisp的编程方式,因为我觉得它适合我更好的工作方式。 但是,这并不意味着你也一定要这样做。

Haskell中的元编程需要比Common Lisp更less,因为很多可以围绕monad来构造,并且附加的语法使得embedded式DSL看起来不像树,但是总是存在如ShreevatsaR所提到的Template Haskell,甚至是Liskell (Haskell语义+ Lisp语法)如果你喜欢括号。

关于macros,下面是一个讨论它的页面: Hello Haskell,Goodbye Lisp 。 它解释了一个在Haskell中不需要macros的观点。 它带有一个比较的简单例子。

需要LISPmacros以避免评估两个参数的示例情况:

(defmacro doif (xy) `(if ,x ,y)) 

Haskell没有系统地评估两个参数的例子,没有像macros定义那样的需要:

 doif xy = if x then (Just y) else Nothing 

我是一个Common Lisp程序员。

前段时间尝试Haskell后,我的个人底线是坚持CL。

原因:

  • dynamicinput(检查dynamic与静态input – 由Pascal Costanza进行的基于模式的分析 )
  • 可选和关键字参数
  • 统一的homoiconic列表语法与macros
  • 前缀语法(不需要记住优先级规则)
  • 不纯,因此更适合快速原型devise
  • 强大的对象系统与元对象协议
  • 成熟的标准
  • 广泛的编译器

哈斯克尔当然有其自身的优点,并以一种完全不同的方式做一些事情,但从长远来看对我来说并没有削减。

在Haskell中,你可以定义一个if函数,这在LISP中是不可能的。 这可能是因为懒惰,它允许程序中有更多的模块化。 这篇经典文章:John Hughes 为什么selectFP ,解释了懒惰如何提高可组合性。

在我继续Haskell学习之旅的过程中,似乎帮助“replace”macros的一件事是定义自己的中缀操作符并定制其优先级和关联性的能力。 有点复杂,但一个有趣的系统!

在Lisp中,有很多非常酷的事情,用Haskell中的macros很麻烦(如果可能的话)。 以“memoize”macros为例(见Peter Norvig的PAIP第9章)。 有了它,你可以定义一个函数,比如foo,然后简单地评估(memoize'foo),它用一个memoized版本replacefoo的全局定义。 你能用Haskell在高阶函数中达到同样的效果吗?