首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 其他相关 >

【转】响动态语言的语义思考

2012-11-16 
【转】动静态语言的语义思考动态,变量实际是个指针,可指向内存任何一块。 (当然是运行的不同时期指向不同的内

【转】动静态语言的语义思考

动态,变量实际是个指针,可指向内存任何一块。
【转】响动态语言的语义思考

(当然是运行的不同时期指向不同的内存块)

看看下面几句:

?

代码
  1. JavaScript:???var?a?=?5;?? ?? ML:?val?a?=?5; ??
  2. Scheme:?(define?a?5) ??
<script>render_code();</script>

?

这些语句应该理解为, (等号右边)表达式evaluate出来一个值,这个值绑定到变量a里面去。用来描述上述代码语义的正确的词是binding。

看看下面ML语言解释器对ML代码的解释:

代码
  1. Moscow?ML?version?2.01?(January?2004) ?? Enter?`quit();'?to?quit. ??
  2. -?a; ?? !?Toplevel?input: ??
  3. !?a; ?? !?^ ??
  4. !?Unbound?value?identifier:?a ?? -?val?a?=?5; ??
  5. >?val?a?=?5?:?int?? -?a; ??
  6. >?val?it?=?5?:?int?? -?val?a?=?"foobar"; ??
  7. >?val?a?=?"foobar"?:?string ?? -?a; ??
  8. >?val?it?=?"foobar"?:?string ??
<script>render_code();</script>
注意第七行的提示。

?

第十行,第十四行光打入a,也是个表达式,evaluate出来的值,绑定给省缺变量it。

看看下面Scheme语言解释器对Scheme代码的解释:

?

代码
  1. >?a ?? ;?Unbound?variable:?a ??
  2. ?? >?(define?a?5) ??
  3. ;?Value:?a ?? ??
  4. >?a ?? ;?Value:?5??
<script>render_code();</script>
注意第二行的提示。

?

一定要分清动态语言的变量绑定和静态语言的变量赋值的区别。变量是一个数学上的概念,在静态语言中,叫变量其实不合适,还不如直接叫a memory box,更能清楚地说明其本质。

对于静态语言,弱类型是致命伤,因为在声明变量的时候,内存块已经分配好了,往这个内存块里写一块内存块存储不下的数据,带来的伤害是致命的。对于动态语言,强弱类型未必重要。

在C/C++/Java/C#里面,内存是可以分配到Stack里面,也可以分配到Heap里面, 程序员一定要搞清楚区别, 像在C里:

?

代码
  1. int?a?=?5; ?? int?b[]?=?{?1,?2,?3,?4} ??
  2. int*?ptr?=?(int*)malloc(10*sizeof(int)); ??
<script>render_code();</script>

?

a 和 b 所分配的内存都在stack里,c 指向heap里的一块,退出前不把c 给free掉,就会遗漏内存。给function传值的时候,更要小心,传a是把5这个值给传过去,传b是传b这个array第一个元素的地址。

到了C++,更加繁琐,因为C++的 Object是可以分配在stack上的,随便写几句代码,都会用到assignment operator = , address-of operator &, copy constructor.

?

代码
  1. const?ClassFoo?e1;????//?default?constructor,?destructor?later ?? ClassFoo?e2(e1);??????????//?copy?constructor ??
  2. e2?=?e1;?????????????????????//?assignment?operator ?? ClassFoo?*pe2?=?&e2;???//?address-of?operator?(non-const) ??
  3. const?ClassFoo?*pe1?=?&e1;???//?address-of?operator?(const) ??
<script>render_code();</script>

?

C++编译器自动生成这些函数,有时不符合需要就要自己手写。

Java里面所有的object allocation, 都是分配在Heap里的,光这一点,就大大减轻了编程的繁琐度。从Java转向C++的朋友,一定要记住这一点。C++的 Object是可以分配在stack上的。

Java里面的primitive变量是分配在Stack上的,其实如果废除这八个primitive types,全部用Object reference,动静态语言的差别已经不那么大了。Type inference在C# 3里面,已经开始实现了:

?

代码
  1. var?str?=?"Hello?world!"; ?? var?num?=?42; ??
  2. var?v?=?new?TypeWithLongName<andwithtypeparameter></andwithtypeparameter>(); ??
<script>render_code();</script>

?

欧美计算机专业的第一门语言,一般是ML或Scheme。这些语言,做到了程序员不用思考内存是分配在stack上还是heap上,内存回收由GC管,因而可以集中精力,学习算法,递归等等。

用编程来解决问题,需要三方面的技能:1. 对编程语言,语义及运行环境的掌握,2. 对解决问题的算法的掌握,3. 拥有写出结构清晰,简洁易懂的代码的能力。

第一点和第二点经常交汇在一起,因为语言,经常是为了解决某个领域的问题而设计的,解决算法,递归之类的问题,用functional programming language,操作系统,应该用C,web领域之PHP,科学计算之Matlab,试验仪器控制之labview,关系数据库之SQL,莫不如此。

那么什么算是通用语言,什么算是DSL?通用不通用是相对的。C是一门通用语言,但也可以说是操作系统的DSL。从某种角度来说,能够全面控制计算机的,才叫通用语言,那么只有汇编才符合这个条件,C和C++勉强算得上。

新手上路,该学什么?应该从某个领域学起,学习解决那个领域问题需要的方法,而且学习那个领域的DSL。这样成效出的最快,而且不受干扰。

现在学校里教学静态语言占主流,有历史原因。以前计算机不够快,用C编程是唯一的选择。现在对运行效率要求很高的领域,还得用C,C++。但是在很多领域,这已经不是个问题了。由于历史的惯性,静态语言还在继续教。学校老师学新知识的动力,可不大。这些老师教出的学生,只会静态语言,那么公司为了保证人手充足,也会倾向静态语言。这种状况,慢慢会打破。

?

静态类型定义语言
一种在编译期间数据类型固定的语言。大多数静态类型定义语言是通过要求在使用所有变量之前声明它们的数据类型来保证这一点的。 Java 和 C 是静态类型定义语言。

动态类型定义语言
一种在运行期间才去确定数据类型的语言, 与静态类型定义相反。 VBScript 和 Python 是动态类型定义的, 因为它们确定一个变量的类型是在您第一次给它赋值的时候。

强类型定义语言
一种总是强制类型定义的语言。 Java 和 Python 是强制类型定义的。您有一个整数, 如果不明确地进行转换 , 不能将把它当成一个字符串。

弱类型定义语言
一种类型可以被忽略的语言, 与强类型定义相反。 VBScript 是弱类型定义的。在 VBScript 中, 您可以将字符串 '12' 和整数 3 进行连接得到字符串'123', 然后可以把它看成整数 123 , 所有这些都不需要任何的显示转换。

热点排行