【发布时间】:2011-02-22 20:06:18
【问题描述】:
我玩过一些函数式编程语言,非常喜欢 Lisps 使用的 s-expr 语法(尤其是方案)。
我还看到了使用纯函数式语言的优势。因此:
有没有纯函数式的 Scheme(或一般的 Lisps)?
【问题讨论】:
标签: haskell functional-programming scheme referential-transparency
我玩过一些函数式编程语言,非常喜欢 Lisps 使用的 s-expr 语法(尤其是方案)。
我还看到了使用纯函数式语言的优势。因此:
有没有纯函数式的 Scheme(或一般的 Lisps)?
【问题讨论】:
标签: haskell functional-programming scheme referential-transparency
新的Racket 语言(以前称为 PLT 方案)允许您使用 s 表达式(实际上是任何语法)实现您喜欢的任何语义。基础语言是一种热切评估的动态类型方案变体,但一些建立在其上的著名语言是惰性方案和称为父亲时间的函数式反应系统。
在 Racket 中制作纯函数式语言的一种简单方法是采用基础语言,并且不提供任何改变状态的过程。例如:
#lang racket/base
(provide (except-out (all-from-out racket/base) set! ...more here...))
组成一种没有set!的语言。
【讨论】:
我不相信有任何纯函数式的 Lisps,但 Clojure 可能是最接近的。
Clojure 的创造者 Rich Hickey:
我为什么要编写另一种编程语言? 基本上是因为我想要一个用于函数式编程的 Lisp 专为并发设计的,但找不到。
Clojure 是函数式的,具有不可变的数据类型和变量,但在某些特殊情况下或通过下拉到 Java(Clojure 在 JVM 上运行)可以获得可变行为。
这是设计使然 - Rich 的另一句话是
纯函数式编程 语言只对温暖你有好处 电脑。
【讨论】:
有没有纯函数式的 Scheme(或一般的 Lisps)?
ACL2 theorem prover 是一个纯 Lisp。然而,它旨在用于定理证明而不是编程,特别是它仅限于一阶程序。然而,它在其利基市场上非常成功。 除此之外,它还赢得了 2005 年ACM Software System Award。
【讨论】:
可能不是,至少不是玩具/概念证明。请注意,即使 Haskell 也不是 100% 纯功能性的——它有秘密的逃生口,IO 中的任何内容都是only "pure" in some torturous, hand-waving sense of the word。
也就是说,您真的需要一种纯粹的函数式语言吗?您几乎可以用任何语言编写纯函数式代码,但不便和低效程度各不相同。
当然,假设通用状态修改的语言使保持事物纯净变得很痛苦,所以也许您真正想要的是一种鼓励不变性的语言?在这种情况下,您可能会发现值得一看 Clojure 的理念。它是一个 Lisp,启动!
作为最后一点,请意识到 Haskell 的大部分“语法”都是厚厚的糖层。底层语言只不过是一种类型化的 lambda 演算,没有什么能阻止你以这种方式编写所有代码。不过,您可能会从其他 Haskell 程序员那里得到滑稽的表情。还有Liskell,不过不知道现在是什么状态。
最后一点,实用的说明:如果你想真正编写你打算使用的代码,而不仅仅是为了好玩而修补一些东西,你会真的想要一个知道如何工作的聪明的编译器使用纯代码/不可变数据结构。
【讨论】:
IO 总比没有好,但如果有足够的反常意图,它会让您面临许多与编码相同的陷阱和错误用不纯的语言会。 Haskell 提供的好处是更容易避免这种情况。但这听起来与提问者无关,所以不用担心。
不一致且不可扩展的语法
这里的“不一致”是什么?
仅根据语法选择语言是很奇怪的。毕竟,学习语法需要几个小时——这只是所需投资的一小部分。
相比之下,速度、打字规则、可移植性、库的广度、文档和社区等重要考虑因素对您能否提高工作效率的影响要大得多。
忽略所有的火焰诱饵,快速谷歌搜索不可变方案会产生一些结果: http://blog.plt-scheme.org/2007/11/getting-rid-of-set-car-and-set-cdr.html
【讨论】:
data、case 和 lambdas 即可让您做几乎所有想做的事情。
30年前有lispkit lisp
不知道今天它有多容易。
[那是我学习函数式编程的地方之一]
【讨论】:
owl lisp 是 R5RS 方案的一种方言,所有数据结构都是不可变的,还有一些额外的纯数据结构。它不是一个大项目,但似乎被一小群人积极开发和使用(从我在网站和 git 存储库上看到的)。还计划包括 R7RS 支持和某种类型的推断。因此,虽然可能还没有准备好用于生产,但这可能是一件有趣的事情。
【讨论】:
如果你喜欢 lisp 的语法,那么你实际上可以在 Haskell 中做类似的事情
let fibs = ((++) [1, 1] (zipWith (+) fibs (tail fibs)))
let fibs = 放在一边。你总是可以在 Haskell 表达式中使用 s-expr 语法。这是因为您始终可以在外面添加括号,这无关紧要。这是没有多余括号的相同代码:
let fibs = (++) [1, 1] (zipWith (+) fibs (tail fibs))
这里是“典型的”Haskell 风格:
let fibs = [1, 1] ++ zipWith (+) fibs (tail fibs)
【讨论】:
有几个项目旨在在 lispy 语法下使用 haskell。更老、更死板、更笨重的是“Liskell”。更新、更活跃、更轻的一个是hasp。我想你可能会觉得值得一看。
【讨论】: