6

想象一下两种语言(除了类型信息)确实具有完全相同的语法,但一种是静态类型,而另一种使用动态类型。然后,对于每个用静态类型语言编写的程序,可以通过删除所有类型信息来派生一个等效的动态类型程序。由于这不一定是可能的,因此动态类型程序的类严格大于静态类型程序的类。让我们称之为动态类型程序,其中没有变量到类型的映射,使它们成为静态类型真正的动态类型程序”。

由于这两个语言家族都绝对是图灵完备的,我们可以肯定,对于每一个真正的动态类型程序,都有一个静态类型程序在做完全相同的事情,但我经常读到“有经验的程序员能够编写非常优雅的代码动态类型语言”。因此我问自己:有没有真正动态类型程序的好例子,任何等效的静态类型程序显然更复杂/更不“优雅”(无论这意味着什么)?

你知道这样的例子吗?

4

3 回答 3

2

我敢肯定,对于静态语言的许多“优雅”问题,静态类型检查本身并不是罪魁祸首,而是该语言实现的静态类型系统缺乏表达能力以及编译器的有限能力。如果这样做“更正确”(例如在 Haskell 中),那么程序突然变得简洁、优雅……并且比动态对应的程序更安全。

这是一个插图(C++ 特定的,抱歉):C++ 是如此强大,它使用它的模板类系统实现了一种元语言。但是,仍然很难声明一个非常简单的函数:

template<class X,class Y>
? max(X x, Y y)

有大量可能的解决方案,例如 ?=boost::variant<X,Y>或计算 ?= is_convertible(X,Y)?(X:is_convertible(Y,X):Y:error),但没有一个真正令人满意。

但是现在想象一个预处理器,它可以将输入程序转换为等效的延续传递样式形式,其中每个延续都是一个可调用对象,它接受所有可能的参数类型。max 的 CPS 版本如下所示:

template<class X, class Y, class C>
void cps_max(X x, Y y, C cont) // cont is a object which can be called with X or Y
{
 if (x>y) cont(x); else cont(y); 
}

问题消失了,max 调用了一个接受 X 或 Y 的 continuation。所以,对于 max 有一个静态类型检查的解决方案,但是我们不能用它的非 CPS 形式表达 max,untransform(cps_max)可以说是未定义的。所以,我们有一些可以正确处理的论点max,但我们没有办法这样做。这是缺乏表现力。

2501 更新: 假设有一些不相关的类型 X 和 Y,并且有一个bool operator<(X,Y). 应该max(X,Y)返回什么?让我们进一步假设,X 和 Y 都有一个成员函数foo();。我们怎样才能写出:

void f(X x, Y y) {
    max(X,Y).foo();
}

返回 X 或 Y 并在结果上调用 foo() 对于动态语言来说没有问题,但对于大多数静态语言来说几乎是不可能的。但是,我们可以通过重写 f() 来使用 cps_max 来获得预期的功能:

struct call_foo { template<class T> void operator(const T &t) const { t.foo(); } };

void f(X x, Y y) {
 cps_max(x,y,call_foo());
}

所以这对于静态类型检查来说不是问题,但它看起来很丑陋,并且除了简单的示例之外不能很好地扩展。因此,这种静态语言缺少的是我们无法提供静态可读的解决方案。

于 2010-07-23T13:33:16.810 回答
1

是的,请查看 Eric Raymonds Python 成功案例。基本上,它是关于使用动态类型编程语言的反射类型任务有多容易。

于 2010-07-23T13:01:49.850 回答
0
  1. Groovy 和 XML
  2. Groovy 和特定领域的语言
于 2010-07-23T12:05:46.027 回答