Objective-C是动态语言吗?为什么
1个回答
展开全部
什么是「动态语言」?这个概念其实没有一个明确的定义。基本上它是一个程度的度量。这个程度就是该语言的 runtime 到底使用多少 bookkeeping 数据。
读过《Design and Evolution of C++》的人一定知道 C++ 这个变态的 zero-bookkeeping 原则。任何 C++ 语言的高层概念,其实都已经在编译阶段被剥离掉了。从最后的目标代码中你很难再看出这是一种高级语言。当然,其代价就是程序员必须理解为什么 C++ 不能实现某些功能。而且必须从机器的角度去理解。
动态语言其实就是一个不断添加 bookkeeping 的过程。
比如说,C++ 中为了实现多态还是不得不有一个中间机制,这就是虚表。但是你很难说虚表就是一个 bookkeeping 结构。因为它太简单了。而 Objective-C 就大大增加了对成员函数调用的 bookkeeping 机制。因为如此,所以 Objective-C 对 action-message 的实现就简单多了,因为你可以判断一个成员函数是否存在。而且也可以在不确定对象类型的情况下,指定一个方法作为回调函数。
C++ 的另一个问题,内存管理,根本原因在于其对象引用采用 raw pointer 机制。Objective-C 并没有改善这一点。但是也并非全无改善,在 Objective-C 里,一个 pointer 几乎永远必须指向 NSObject,而这个东西是有引用基数的。当然,它并没有完全解决 over-release 或者 use-after-release 的问题。到了 Java,Python,Lua 这样的语言,raw pointer 就完全消失了。
而 C++ 的内存管理,除了 heap 就只有一个借助 CPU stack 管理的栈。在动态语言里,就要考虑 lexical scope 的表现,这就需要更多的 bookkeeping。这点 Objective-C 也并没有实现。
语法的处理,在 C++ 中是完全在 runtime 之前进行。而在 Python,Lisp,Lua 这样的语言中是有 eval 这样的机制存在的。
所以,Objective-C 是比 C 和 C++ 拥有更多动态特性,而比 Lua,Lisp 缺乏一些动态特性的语言。至于题目中进行比较的 Python,也只能说是个更少缺乏动态特性的语言。Python 缺乏 lexical scope,也缺乏对 continuation 的支持。它的 stack 借助 CPU stack(当然有一个 stackless-Python,不过非官方),相比之下,Lua 为了支持 coroutine,Lisp 为了 full-continuation,都是自行维护 VM stack 的。Python 的 bookkeeping 与 Lua 和 Lisp 比起来也是不够的。
===============
什么是 bookkeeping 信息:Bookkeeping 就是 source code 里的信息用 declarive 的方式来保留在目标码中。
这里举一个所有语言都会舍弃的 bookkeeping 信息,就是 local variable name。Compiler 或者 interpreter 在遇到一个 local variable 的时候,一定要给它分配一个寄存器或者 stack entry(其实寄存器也就是 stack entry 的一种,见我的 blog 《什么是寄存器》)。所以在 runtime 时 variable name 就成了多余的。所以几乎所有语言,不管是 native 还是 byte code,都会舍弃 local name。
再比如说 raw pointer,就是说编译之后的代码里没有一个固定的 field 来说明一个 value 到底是不是 pointer。一个 value 是不是 pointer 完全靠引用它的代码本身来解释。当然你去分析目标码本身可能会得出「这是一个 pointer」的结论,但这是从 imperative code 中分析的来的,而不是从一个 field 中得到的明确的 declartive 信息。
读过《Design and Evolution of C++》的人一定知道 C++ 这个变态的 zero-bookkeeping 原则。任何 C++ 语言的高层概念,其实都已经在编译阶段被剥离掉了。从最后的目标代码中你很难再看出这是一种高级语言。当然,其代价就是程序员必须理解为什么 C++ 不能实现某些功能。而且必须从机器的角度去理解。
动态语言其实就是一个不断添加 bookkeeping 的过程。
比如说,C++ 中为了实现多态还是不得不有一个中间机制,这就是虚表。但是你很难说虚表就是一个 bookkeeping 结构。因为它太简单了。而 Objective-C 就大大增加了对成员函数调用的 bookkeeping 机制。因为如此,所以 Objective-C 对 action-message 的实现就简单多了,因为你可以判断一个成员函数是否存在。而且也可以在不确定对象类型的情况下,指定一个方法作为回调函数。
C++ 的另一个问题,内存管理,根本原因在于其对象引用采用 raw pointer 机制。Objective-C 并没有改善这一点。但是也并非全无改善,在 Objective-C 里,一个 pointer 几乎永远必须指向 NSObject,而这个东西是有引用基数的。当然,它并没有完全解决 over-release 或者 use-after-release 的问题。到了 Java,Python,Lua 这样的语言,raw pointer 就完全消失了。
而 C++ 的内存管理,除了 heap 就只有一个借助 CPU stack 管理的栈。在动态语言里,就要考虑 lexical scope 的表现,这就需要更多的 bookkeeping。这点 Objective-C 也并没有实现。
语法的处理,在 C++ 中是完全在 runtime 之前进行。而在 Python,Lisp,Lua 这样的语言中是有 eval 这样的机制存在的。
所以,Objective-C 是比 C 和 C++ 拥有更多动态特性,而比 Lua,Lisp 缺乏一些动态特性的语言。至于题目中进行比较的 Python,也只能说是个更少缺乏动态特性的语言。Python 缺乏 lexical scope,也缺乏对 continuation 的支持。它的 stack 借助 CPU stack(当然有一个 stackless-Python,不过非官方),相比之下,Lua 为了支持 coroutine,Lisp 为了 full-continuation,都是自行维护 VM stack 的。Python 的 bookkeeping 与 Lua 和 Lisp 比起来也是不够的。
===============
什么是 bookkeeping 信息:Bookkeeping 就是 source code 里的信息用 declarive 的方式来保留在目标码中。
这里举一个所有语言都会舍弃的 bookkeeping 信息,就是 local variable name。Compiler 或者 interpreter 在遇到一个 local variable 的时候,一定要给它分配一个寄存器或者 stack entry(其实寄存器也就是 stack entry 的一种,见我的 blog 《什么是寄存器》)。所以在 runtime 时 variable name 就成了多余的。所以几乎所有语言,不管是 native 还是 byte code,都会舍弃 local name。
再比如说 raw pointer,就是说编译之后的代码里没有一个固定的 field 来说明一个 value 到底是不是 pointer。一个 value 是不是 pointer 完全靠引用它的代码本身来解释。当然你去分析目标码本身可能会得出「这是一个 pointer」的结论,但这是从 imperative code 中分析的来的,而不是从一个 field 中得到的明确的 declartive 信息。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询