Haskell、Lisp 和冗长
对于那些既熟悉 Haskell 又熟悉 Lisp 的人来说,我很好奇用 Haskell 和 Lisp 编写代码有多“愉快”(用一个可怕的术语)。
一些背景:我现在正在学习 Haskell,之前曾使用过 Scheme 和 CL(以及对 Clojure 的一些尝试)。 传统上,您可以认为我是动态语言的粉丝,因为它们提供了简洁性和快速性。 我很快就爱上了 Lisp 宏,因为它给了我另一种避免冗长和样板代码的方法。
我发现 Haskell 令人难以置信很有趣,因为它向我介绍了我不知道的编码方式。 它肯定有一些方面看起来有助于实现敏捷性,例如易于编写部分函数。 然而,我有点担心丢失 Lisp 宏(我假设我丢失了它们;说实话我可能还没有了解它们?)和静态类型系统。
在这两个世界中进行过大量编码的人是否会介意评论体验有何不同、您更喜欢哪一种以及所述偏好是否是视情况而定?
For those of you experienced in both Haskell and some flavor of Lisp, I'm curious how "pleasant" (to use a horrid term) it is to write code in Haskell vs. Lisp.
Some background: I'm learning Haskell now, having earlier worked with Scheme and CL (and a little foray into Clojure). Traditionally, you could consider me a fan of dynamic languages for the succinctness and rapidity they provide. I quickly fell in love with Lisp macros, as it gave me yet another way to avoid verbosity and boilerplate.
I'm finding Haskell incredibly interesting, as it's introducing me to ways of coding I didn't know existed. It definitely has some aspects that seem like they would aid in achieving agility, like ease of writing partial functions. However, I'm a bit concerned about losing Lisp macros (I assume I lose them; truth be told I may have just not learned about them yet?) and the static typing system.
Would anyone who has done a decent amount of coding in both worlds mind commenting on how the experiences differ, which you prefer, and if said preference is situational?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
简短的回答:
[注意:有一个“Template Haskell”可以让你像在 Lisp 中一样编写宏,但是严格来说,您永远不会需要它。]
Short answer:
[Note: There is a "Template Haskell" that lets you write macros just as in Lisp, but strictly speaking you should never need it.]
首先,不要担心失去动态类型等特定功能。 由于您熟悉 Common Lisp 这种设计得非常好的语言,我想您知道语言不能简化为它的功能集。 这都是一个连贯的整体,不是吗?
在这方面,Haskell 与 Common Lisp 一样闪耀。 它的功能相结合,为您提供了一种使代码变得极其简短和优雅的编程方式。 宏的缺乏在一定程度上可以通过更复杂(但同样更难理解和使用)的概念(如单子和箭头)来缓解。 静态类型系统会增强您的能力,而不是像大多数面向对象语言那样妨碍您。
另一方面,Haskell 中的编程交互性比 Lisp 低得多,而且像 Lisp 这样的语言中存在的大量反射并不符合 Haskell 预设的静态世界观。 因此,两种语言之间可用的工具集有很大不同,但很难相互比较。
一般来说,我个人更喜欢 Lisp 的编程方式,因为我觉得它更适合我的工作方式。 然而,这并不意味着您也必须这样做。
First of all, don't worry about losing particular features like dynamic typing. As you're familiar with Common Lisp, a remarkably well-designed language, I assume you're aware that a language can't be reduced to its feature set. It's all about a coherent whole, isn't it?
In this regard, Haskell shines just as brightly as Common Lisp does. Its features combine to provide you with a way of programming that makes code extremely short and elegant. The lack of macros is mitigated somewhat by more elaborate (but, likewise, harder to understand and use) concepts like monads and arrows. The static type system adds to your power rather than getting in your way as it does in most object-oriented languages.
On the other hand, programming in Haskell is much less interactive than Lisp, and the tremendous amount of reflection present in languages like Lisp just doesn't fit the static view of the world that Haskell presupposes. The tool sets available to you are therefore quite different between the two languages, but hard to compare to one another.
I personally prefer the Lisp way of programming in general, as I feel it fits the way I work better. However, this doesn't mean you're bound to do so as well.
与 Common Lisp 相比,Haskell 中对元编程的需求较少,因为很多内容都可以围绕 monad 进行构建,并且添加的语法使嵌入式 DSL 看起来不那么像树,但总是有 Template Haskell,正如 ShreevatsaR,甚至Liskell (Haskell 语义 + Lisp 语法)如果你喜欢括号。
There's less need for metaprogramming in Haskell than in Common Lisp because much can be structured around monads and the added syntax makes embedded DSLs look less tree-like, but there's always Template Haskell, as mentioned by ShreevatsaR, and even Liskell (Haskell semantics + Lisp syntax) if you like the parentheses.
关于宏,这里有一个页面讨论它: Hello Haskell ,再见Lisp。 它解释了 Haskell 中不需要宏的观点。 它带有一个简短的示例进行比较。
需要 LISP 宏来避免对两个参数进行求值的示例:
Haskell 不系统地求值两个参数,而不需要宏定义之类的东西的示例:
瞧
Concerning macros, here is a page which talk about it : Hello Haskell, Goodbye Lisp. It explains a point of view where macros are just not needed in Haskell. It comes with a short example for comparison.
Example case where a LISP macro is required to avoid evaluation of both arguments :
Example case where Haskell does not systematically evaluates both argument, without the need of anything like a macro definition :
And voilà
我是一名 Common Lisp 程序员。
不久前尝试过 Haskell 后,我个人的底线是坚持使用 CL。
原因:
Pascal Costanza)
Haskell当然,确实有它自己的优点,并且以根本不同的方式做一些事情,但从长远来看,这对我来说并没有什么好处。
I'm a Common Lisp programmer.
Having tried Haskell some time ago my personal bottom line was to stick with CL.
Reasons:
Pascal Costanza)
Haskell does have its own merits of course and does some things in a fundamentally different way, but it just doesn't cut it in the long term for me.
在 Haskell 中你可以定义一个 if 函数,这在 LISP 中是不可能的。 这是可能的,因为惰性允许程序具有更多的模块化性。 这篇经典论文:约翰·休斯 (John Hughes) 撰写的为什么 FP 很重要,解释了懒惰是如何产生的增强可组合性。
In Haskell you can define an if function, which is impossible in LISP. This is possible because of laziness, which allows for more modularity in programs. This classic paper: Why FP matters by John Hughes, explains how laziness enhances composability.
在 Lisp 中你可以使用宏来实现一些非常酷的事情,而在 Haskell 中则很麻烦(如果可能的话)。 以“memoize”宏为例(参见 Peter Norvig 的 PAIP 的第 9 章)。 有了它,您可以定义一个函数,例如 foo,然后简单地求值 (memoize 'foo),这会用记忆版本替换 foo 的全局定义。 在 Haskell 中用高阶函数能达到同样的效果吗?
There are really cool things that you can achieve in Lisp with macros that are cumbersome (if possible) in Haskell. Take for example the `memoize' macro (see Chapter 9 of Peter Norvig's PAIP). With it, you can define a function, say foo, and then simply evaluate (memoize 'foo), which replaces foo's global definition with a memoized version. Can you achieve the same effect in Haskell with higher-order functions?
当我继续我的 Haskell 学习之旅时,似乎有助于“替换”宏的一件事是能够定义自己的中缀运算符并自定义它们的优先级和关联性。 有点复杂,但是一个有趣的系统!
As I continue my Haskell-learning journey, it seems that one thing that helps "replace" macros is the ability to define your own infix operators and customize their precedence and associativity. Kinda complicated, but an interesting system!