静态输入语言意味着什么?

时间:2010-09-02 01:53:05

标签: type-safety language-theory turing-complete

我的理解是,这意味着人们可以编写程序来正式证明用静态类型语言编写的程序将没有某些(小)缺陷子集。

我的问题如下:

假设我们有两种图灵完整语言,A和B.A被认为是'类型安全'而'B'被认为不是。假设我有一个程序L来检查用A写的任何程序的正确性。什么阻止我将用B写的任何程序翻译成A,应用L.如果P从A转换为B,那么为什么不是PL a任何以B编写的程序的有效类型检查器?

我接受过代数培训,而且我刚刚开始学习CS,所以可能有一些明显的原因,这不起作用,但我非常想知道。整个'类型安全'的东西已经有一段时间闻到了我的味道。

6 个答案:

答案 0 :(得分:7)

如果,您可以将每个 B'(用B编写的程序)翻译成等效的A'(如果B'是正确的话),则语言B享有与语言A一样多的“类型安全”(当然,在理论意义上;-) - 基本上这意味着B可以做到完美的类型推理。但对于动态语言来说,这是非常有限的 - 例如,考虑:

if userinput() = 'bah':
    thefun(23)
else:
    thefun('gotcha')

其中thefun(我们假设)是int参数的类型安全,但不是str参数。现在 - 你如何将其翻译成语言A ......?

答案 1 :(得分:5)

让A成为你的图灵完备语言,它应该是静态类型的,当你删除类型检查时,让A'成为你从A得到的语言(但不是类型注释,因为它们也用于其他目的)。接受的A程序将是A'公认程序的一部分。特别是,A'也将是图灵完成的。

鉴于您的翻译P从B到A(反之亦然)。该怎么办?它可以做两件事之一:

  1. 首先,它可以将B的每个程序y转换为A的程序。在这种情况下,LPy将始终返回True,因为A的程序按照定义正确键入。

  2. 其次,P可以将B的每个程序y转换为A'的程序。在这种情况下,如果Py恰好是A的程序,则LPy将返回True,否则返回False。

  3. 由于第一种情况没有产生任何有趣的东西,让我们坚持第二种情况,这可能是你的意思。在B程序中定义的函数LP是否告诉我们关于B程序的任何有趣内容?我说不,因为它在P的变化下不是不变的。因为A是图灵完全的,即使在第二种情况下,P也可以被选择,使得它的图像恰好位于A.然后LP将一直是真的。另一方面,可以选择P,使得一些程序映射到A'中的A的补码。在这种情况下,LP会为B的某些(可能是所有)程序吐出False。正如您所看到的,您没有得到任何仅依赖于y的东西。

    我还可以通过以下方式更加数学化:编程语言的C类,其对象是编程语言,其态射是从一种编程语言到另一种编程语言的翻译。特别是如果存在态射P:X - > Y,Y至少与X一样具有表现力。在每对图灵完备语言之间,两个方向都有态射。对于C的每个对象X(即对于每种编程语言),我们有一个相关的集合,比如那些可以由X的程序计算的部分定义函数的{X}(坏符号,我知道)。每个态射P:X - > Y然后诱导包含{X} - > {Y}套。让我们正式颠倒所有那些态射P:X - > Y诱导身份{X} - > {Y}。我将用C'调用结果类别(用数学术语表示C的本地化)。现在包含A - > A'是C'中的态射。然而,它不是在A'的自同构下保留的,即态射A - >。 A'在C'中不是A的不变量。换句话说:从这个抽象的角度来看,“静态类型”属性不是可定义的,可以任意附加到语言上。

    为了使我的观点更加清晰,您还可以将C'视为三维空间中几何形状的类别,同时将欧几里德运动视为态射。 A'和B是两个几何形状,P和Q是欧几里德运动,将B带到A',反之亦然。例如,A'和B可以是两个球体。现在让我们在A'上修一个点,它代表A'的子集A.让我们称这一点为“静态打字”。我们想知道B的点是否是静态类型的。所以我们采取这样一个点y,通过P映射到A'并测试,它是否是我们在A'上的标记点。正如人们可以很容易看到的那样,这取决于所选择的地图P或换句话说:球体上的标记点不会被该球体的自同构(即将球体映射到自身的欧几里德运动)保留。

答案 2 :(得分:1)

另一种表达同样观点的方法是,你的问题构成了一个矛盾的证明:

  • A无法映射到B
  • 类型安全不是语言的词汇属性

或两者兼而有之。我的直觉说后者可能是关键点:类型安全是一种元语言属性。

答案 3 :(得分:1)

没有什么“腥”的。 ;)

对于任何非常重要的[ 1 ]类型系统 T 而言类型安全的图灵完备语言集合是 strict 图灵完整语言的子集。因此,在一般情况下,不存在从 B A 的转换器 P -1 ;因此,任何翻译人员 -type-checker LP -1

对这种说法的下意识反应可能是:废话! A B 都是图灵完备的,所以我可以用语言表达任何可计算函数可以用任何一种语言表达任何可计算的函数;但是,很多时候,你也可以表达更多。特别是你可以构造其指称语义没有明确定义的表达式,例如那些可能会愉快地尝试取字符串“foo”和“bar”的算术和的表达式(这是 Chubsdad的要点 Alex Martelli 的答案)。这些类型的表达式可能在“em> B 语言中”,但可能在语言 A 中无法表达,因为指称语义是未定义的,因此没有明智的翻译它们的方法。

这是静态类型的一大优势:如果您的类型系统无法在编译时证明上述函数将接收任何参数,但是那些算术加法运算符的结果定义明确的参数,它可以被拒绝为不良类型。

请注意,虽然以上是解释静态类型系统优点的常用示例,但它可能过于谦虚。通常,静态类型系统不必仅限于强制参数的类型正确性,而是实际上可以表达可以在编译时证明的程序的任何期望属性。例如,可以构造类型系统,该类型系统强制执行约束,即释放文件系统句柄(例如到数据库,文件,网络套接字,)。被收购的范围相同。显然,这在诸如生命支持系统等领域中具有非常重要的价值,其中可证明系统的尽可能多的参数的正确性是绝对必要的。如果您满足静态类型系统,您可以免费获得这些类型的证明。

[ 1 ]非常重要的是,我的意思是并非所有可能的表达都是良好的类型。

答案 4 :(得分:0)

我的理解是,这与编译时与运行时有关。在静态类型语言中,大多数类型检查在编译期间执行。在动态类型语言中,大多数类型检查都是在运行时执行的。

答案 5 :(得分:-1)

让我以相反的方式回答这个问题:

有两种不同类型的“动态”编程。

一个是“动态类型”,这意味着你有一些shell可以通过在shell中键入定义来编程,可以把它想象成Python的IDLE shell。

另一种动态编程,更具理论性。动态程序,可以改变自己的源程序。它需要一定程度的内射,通常用于改变微控制器上的程序存储器。有时为数字运算生成查找表称为动态编程。