【发布时间】:2011-04-11 05:49:48
【问题描述】:
我已经读过,使用 Scala 或 Haskell 等静态类型语言无法创建或提供 Lisp apply 函数:
(apply #'+ (list 1 2 3)) => 6
或许
(apply #'list '(list :foo 1 2 "bar")) => (:FOO 1 2 "bar")
(apply #'nth (list 1 '(1 2 3))) => 2
这是真的吗?
【问题讨论】:
-
C# 是静态的,并且有一个名为
Invoke的函数,类似于apply。 -
IIRC,C# 使用动态来做到这一点,这意味着它会生成胶水代码,在传递它们之前检查所有 I/O 类型。
-
@sreservoir:在一般情况下,静态类型检查等同于解决停机问题,因此无法确定。这意味着存在类型安全但不可类型检查的程序。换句话说:任何静态类型的语言都会阻止您编写某些完全类型安全的程序。即使是最铁杆的静态打字爱好者,这也基本上是无可争议的。然而,在这个类是否包含任何有用的程序方面,静态类型和动态类型的支持者之间存在分歧。这基本上是在问
apply是不是这样的程序。 -
特别是,
apply和eval(尤其是特殊的eval)是动态类型的支持者经常声称不可能在静态类型语言中实现的一些程序。至少在实际存在的那些中。例如,如果你在Data.Dynamic模块中查看Haskell 的dynApply的源代码,这可能是最接近Scheme 的apply的东西,你会发现它使用了unsafeCoerce函数,这基本上是与 C 中不受限制的不安全强制转换相同,因此显式且有意地规避了类型系统。 -
@Jörg W Mittag:作为“硬核静态类型爱好者”(顺便说一句,C# 和 Java 不算真正的静态类型语言),我非常同意。有一些变通方法,但基本上没有办法在不以某种方式规避类型系统的情况下制作一个合适的一流
eval。事实上,如果你堵住所有的漏洞,并把静态类型归结为它的逻辑结论,那么根本就不可能为一种语言本身编写一个解释器。在迁移到 Haskell 之前使用过 Scheme 和 Ruby,我有时确实会想念这种事情......
标签: scala programming-languages haskell lisp static-typing