【问题标题】:How can Erlang support both single assignment and dynamic typing?Erlang 如何同时支持单一赋值和动态类型?
【发布时间】:2014-11-19 17:11:39
【问题描述】:
首先我要说我只是一个计算机科学爱好者,对该主题的了解相对较少。我的问题是:如果 single assignment 是一个变量(例如,A)只能被分配一个值而不改变该值的想法(A = 1,A = 2 -> @ 987654324@) 一种语言怎么也有动态类型?如果一个变量的值不能改变,那么它肯定不能改变它的类型……对吧?
【问题讨论】:
标签:
functional-programming
erlang
variable-assignment
dynamic-typing
【解决方案1】:
如果一种语言是动态类型的,这意味着在不运行程序的情况下通常无法确定任何给定表达式的类型。这并不一定意味着变量必须能够改变它们的类型,只是在不运行程序的情况下无法判断变量的类型。
所以以这段代码为例:
A =
if some_condition -> 42;
true -> "hello"
end
在这里,如果不知道条件是真还是假,我们就无法知道 A 是数字还是字符串(如果不运行代码,我们通常无法知道,因为它可以是任意复杂的表达式)。在静态类型语言中,上述内容是非法的,但在 Erlang 中是允许的。
【解决方案2】:
动态输入与分配无关。 Erlang 不会在编译时执行类型检查,而是在运行时执行。
比方说,我有一些功能:
foo() ->
%% Perform some computation
Result.
哪种类型会有函数结果?我不知道。二郎也是。接下来,比方说,我还有一个功能:
bar(Arg) ->
%% Some computation
Result.
我可以将哪些类型作为该函数的参数传递?同样,这个决定只会在运行时做出。
【解决方案3】:
您正在处理两个截然不同的概念。动态类型意味着程序的类型安全是在运行时确定的,而静态类型在编译时也是如此。
一个有用的过度简化可能是静态类型语言的构造使得类型安全(或正确性)可以通过检查以该语言编写的程序的文本来确定。动态类型语言不具有语言特性/结构,因此这是可能的,而是在运行时发现类型安全性。像所有计算机科学一样,一种类型系统代表了与另一种类型系统相比,赞成和反对的权衡。
另一方面,单次赋值并没有说明类型。它只是意味着一个变量只能被赋值一次。
假设你有一个函数 F(),如果我们说
X = F(),
Y = X ++ "I hope F returned a string",
Y = "This cannot work in a single-assignment language".
静态类型语言将能够在编译时推断字符串连接的类型安全性,而动态类型语言将(可能)无法在运行时做出此决定。
Erlang 是单一赋值的事实意味着在(希望)成功的字符串连接之后,Y 不能被重新赋值。
【解决方案4】:
单个赋值很容易,如果 A 绑定到 1(或者相反,我不知道如何使用这个动词 :o)任何其他赋值都会失败并创建异常
1> A = 1.
1
2> A = 1.0.
** exception error: no match of right hand side value 1.0
3> %% even strongly typed!
动态类型是一个不同的概念,它意味着在运行时检查变量的类型,而不是在编译时。例如,如果我们使用带有 A 变量(如 lists:reverse(A))在列表上工作的函数,编译器不会报错,它会生成一个有效的梁文件,如果执行这行奇怪的代码,它将崩溃。
来自 C,对我来说这看起来像是一种回归,因为它很晚才揭示错误,而它似乎很容易检测到。但实际上这样做有一些好处和义务,尤其是对于 Erlang:
- Erlang 程序未链接,因此您可以安全地执行一个模块,该模块已经包含需要其他尚未编写的模块的功能
- Erlang 支持代码重新加载,因此在编译时完成的验证可能已过时。
- 语法更简洁,不需要定义任何变量类型。
- 它符合“让它崩溃”的口头禅(更重要的是监督树)。