`
bigpanda
  • 浏览: 109142 次
  • 性别: Icon_minigender_1
  • 来自: 斯德哥尔摩
文章分类
社区版块
存档分类
最新评论

对动静态语言的语义思考,再兼谈点其它的

阅读更多
在参与这个讨论http://www.iteye.com/topic/33971后,这段时间对这个话题有了一些新的思考,写下来和大家分享分享。

重点探讨一下动静态编程语言的语义,兼带些DSL及通用语言,以及新手上手难易问题。

编程语言的语义,在论坛里讨论不多。在这里先分析一下几门主流静态语言,C,C++,Java,C#的语义。这些语言从编程风格角度讲,都称之为”imperative programming language”,(命令式的编程语言)。究其原因,这些语言都是对计算机的核心部件,CPU及内存,施发号令的。

int a = 4 ;
int b = 4 + a;
int c = 5.2345;


第一句,具体语义是,在内存里分配一块内存,大小为4 bytes,在这块内存里,写入4。第二句,具体语义是,在内存里分配一块内存,大小为4 bytes,从a中取值,和4进行加法运算,结果写入b指向的4 bytes内存。第三句就是个潜在的错误,等号右边是个8 bytes的double,把8 bytes的数据写到4 bytes的内存块里去,数据会损失的。

要把这些静态语言内存分配的经验照搬来理解动态语言,完全是搞错了方向。看看下面一段javascript代码:
var a = 5;
alert(a);
var a = "foobar";
alert(a);


这是一段完全合法可以正确运行的javascript程序,然而对于只编过静态语言而且对静态语言的语义很了解的人,却很难理解。变量a,明显不是指向根据类型分配出来一块大小固定的内存块。

如何理解这一段代码的语义?

Revised Report on the Algorithmic Language Scheme一文里有这么一段:

引用

Scheme has latent as opposed to manifest types. Types are associated with values also (also call objects) rather than with variables. (Some authors refer to languages with latent types as weakly typed or dynamically typed languages. Other languages with latent types are APL, Snobol, and other dialects of Lisp. Languages with manifest types (sometimes referred to as strongly typed or statically typed language) include Algol 60, Pascal, and C.


Paul Graham在其“What Made Lisp Different”一文中这么说:

引用

A new concept of variables. In Lisp, all variables are effectively pointers. Values are what have types, not variables, and assigning or binding variables means copying pointers, not what they point to.


这两段合在一起,可以正确理解动态语言的语义。

静态,变量实际是分配的内存块,大小固定。



动态,变量实际是个指针,可指向内存任何一块。
[img]http://bigpanda.iteye.com/upload/picture/pic/1194/d5f5ae66-8f87-4872-be13-9542a7c5ab8a.jpg [/img]

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

看看下面几句:

JavaScript:   var a = 5;  
ML: val a = 5;
Scheme: (define a 5)


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

看看下面ML语言解释器对ML代码的解释:
Moscow ML version 2.01 (January 2004)
Enter `quit();' to quit.
- a;
! Toplevel input:
! a;
! ^
! Unbound value identifier: a
- val a = 5;
> val a = 5 : int
- a;
> val it = 5 : int
- val a = "foobar";
> val a = "foobar" : string
- a;
> val it = "foobar" : string

注意第七行的提示。

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

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

> a
; Unbound variable: a

> (define a 5)
; Value: a

> a
; Value: 5

注意第二行的提示。

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

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

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

  int a = 5;
  int b[] = { 1, 2, 3, 4}
  int* ptr = (int*)malloc(10*sizeof(int));


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

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

const ClassFoo e1;    // default constructor, destructor later
ClassFoo e2(e1);          // copy constructor
e2 = e1;                     // assignment operator
ClassFoo *pe2 = &e2;   // address-of operator (non-const)
const ClassFoo *pe1 = &e1;   // address-of operator (const)


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

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

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

var str = "Hello world!";
var num = 42;
var v = new TypeWithLongName<AndWithTypeParameter>();


欧美计算机专业的第一门语言,一般是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++。但是在很多领域,这已经不是个问题了。由于历史的惯性,静态语言还在继续教。学校老师学新知识的动力,可不大。这些老师教出的学生,只会静态语言,那么公司为了保证人手充足,也会倾向静态语言。这种状况,慢慢会打破。

Reference:

[1] Revised Report on the Algorithmic Language Scheme 可以在这里找到:http://www.schemers.org/Documents/Standards/R5RS/r5rs.pdf
[2] Paul Graham的文章,What Made Lisp Different,http://www.paulgraham.com/diff.html

[3] 一篇介绍C# 3的很好的文章 http://www.codeproject.com/useritems/csharp3-concepts.asp

分享到:
评论
17 楼 mathgl 2007-07-06  
我以前上的那个学校的
CS第一门程序语言 是 smalltalk
然后是 java
C 倒反没有怎么提过 在电子工程系那里就有
16 楼 小帽子 2007-05-23  
good text~
15 楼 metaphy 2007-04-10  
其实重要的不是哪个语言开始,而是哪个系统开始。
如果学校的培养都是从linux开始的,中国与国外的差距会小很多
14 楼 xyz20003 2007-02-09  
不觉得对语言的选择,会造成思想上的重大差异。说实在的程序也只是工作而已,撤到艺术上就太远了,不是所有人都可以做得到科学家。

个人一直以为程序属于边缘交叉学科,是用来解决问题的途径。所谓的编程思想应该是脱离于具体语言之外的,一味地在语言本身差别上争论编程思想的重要,有偏离主题的嫌疑。倒不如说,哪类语言更容易解决哪类问题的好。
13 楼 bluecrystal 2007-01-15  
其实就我个人意见而言,我认为现在国内的计算机大学教育落后是事实,但未必为坏事儿
说老实话,本科的时候,学习c/c++/汇编,以及诸如单片机等,挺好
要知道,都这么多年了,计算机的体系结构也没有变化,学习c/c++/汇编之类,才会对计算机有本质的认识
所以,我还是觉得在大学里面老的东西,未必就是不好的

只是出于实际工作的情况,需要细分职位,所以现在大量的软件学院之类的教育机构诞生,只是为了适应计算机产业化对于不同工种的需求而以,如果作为从业人员的你,喜欢计算机,也愿意做一辈子,我看现在国内大学的计算机教育基本上还是很不错的

一家之言
12 楼 helloworld 2007-01-14  
讨论的问题应该是动静态类型语言,vbscript可以称为动态类型语言,但从来不能和传统的c和java等静态类型语言齐肩。引发动静态语言之争的并不在于是否强类型。2点,表达能力和执行效率。
11 楼 s5kk 2006-12-13  
引用

欧美计算机专业的第一门语言,一般是ML或Scheme。


念书的时候确实有用过 scheme, 不过学校里我看到 undergraduate 的第一门语言是java,
uml 没有专门的课讲,但是每个人必须会。
国外CS专业主要是培养应用人才的,理论上必须自己深造。


10 楼 dogstar 2006-11-25  
同意楼上。培养coder和培养思考能力,是软件学院和计算机科学专业的区别吧。呵呵。这么说来,软件学院的开办还是挽救了计算机科学的沦落
9 楼 dogstar 2006-11-25  
看到buaawhl写的,自问自答了.

如果类型是必须声明的,可读性倒是有一点优势,因为一眼可以看到这个变量的类型。
不过有些静态语言采用type inference,不需要声明。和动态类型语言一样,使用富有含义的名字,表示变量的意义。
8 楼 dogstar 2006-11-24  
moniker 写道
关于静态动态,强类型和弱类型,推荐看看:Dave Into Python一书:
摘要如下:

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

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

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

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




终于揭掉了我头顶的薄纱。那么就是静态类型语言为了保证能够在编译期间知道数据类型,就的采用强类型了。至于动态类型语言,强弱类型都无所谓。对否?非科班出身,见笑见笑..
7 楼 dogstar 2006-11-24  
lighter 写道
hurricane1026 写道

学校教育在计算机业面临全新的挑战,更确切的说是中国队 学校教育。老师们知识结构大幅度落伍,很少有人有心思好好教学生,都忙着混日子,养孩子,挣票子。大学生编程入门就是应该从lisp之类的开始。

大学生编程入门就是应该从lisp之类的开始?只是一家之言吧.
对我而言,当初大一第二学期的C语言的学习给了我很大的帮助,用C语言写了一些最简单的程序,这对后来学java或其他语言起很大的作用.



所以说我们都在写java,而不是别的什么。
6 楼 moniker 2006-11-24  
另外,关于楼主所说的,其实在Learning Pyton,第4.6节:The Dynamic Typing Interlude一节讲的就是这个。不过楼主的解释非常清楚。
5 楼 moniker 2006-11-24  
关于静态动态,强类型和弱类型,推荐看看:Dave Into Python一书:
摘要如下:

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

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

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

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

4 楼 taowen 2006-11-24  
是不是说静态类型语言由于是静态类型的,所以可以做到更好的效率优化。动态语言由于是动态的,使用者无需关心静态语言背后的内存分配之流的计算机机器语意,所以可以更关注要解决的问题本身?
3 楼 lighter 2006-11-24  
hurricane1026 写道

学校教育在计算机业面临全新的挑战,更确切的说是中国队 学校教育。老师们知识结构大幅度落伍,很少有人有心思好好教学生,都忙着混日子,养孩子,挣票子。大学生编程入门就是应该从lisp之类的开始。

大学生编程入门就是应该从lisp之类的开始?只是一家之言吧.
对我而言,当初大一第二学期的C语言的学习给了我很大的帮助,用C语言写了一些最简单的程序,这对后来学java或其他语言起很大的作用.
2 楼 Tin 2006-11-24  
从这个角度理解动态语言角度挺特别,看后感觉很清晰。
1 楼 cookoo 2006-11-24  
ML那个例子有点不妥。ML是静态类型语言,val a = 5 这样的不是引用而是值,ML限制side effect,所以在代码里一次赋值以后不能再更改了。但是在交互模式(toplevel)下为了调试方便允许重复声明。mutable的变量得声明成这样:val a = ref 5 这时a才是个引用。

相关推荐

    可变值语义的本机实现_Native Implementation of Mutable Value Semantics

    为了解答这个问题,研究者们展示了如何将支持可变值语义的语言编译成高效的本地代码。这种方法依赖于栈分配进行静态垃圾收集,并利用运行时信息来避免不必要的拷贝,从而在不牺牲性能的同时,保持了可变值语义的优势...

    1110-全国-语言学概论.docx

    2. 汉语的语序典范:汉语通常被认为是SVO(主-动-宾)型语言,但描述中提到的是SOV(主-宾-动)型语言,这是某些语言如日语、韩语的典型语序,而不是汉语。 3. 英语句子的语法意义:“John has written the book.”...

    C#编程多年的学习思考

    ### C#编程多年的学习思考 #### 一、C#语法结构体系 C#是一种现代的、面向对象的编程语言,其语法结构体系主要包括以下几个方面: 1. **程序集(Assembly)**:C#应用程序是由一个或多个程序集组成的。程序集是C#...

    《现代C++语言核心特性解析》其他资料.zip

    《现代C++语言核心特性解析》是一本深入探讨C++编程语言最新特性的书籍,而“其他资料.zip”可能包含了该书的补充材料、代码示例或者课后习题解答等资源。虽然没有具体的标签来指示这些文件的具体内容,但我们可以...

    编程语言的类型系统Type Systems for Programming Languages

    模块化机制的批评和模块语言的设计反映了编程语言设计者对于模块化的思考和实现方式。 通过这些类型系统的概念和机制,程序员可以编写出更加可靠、易于维护和扩展的代码。类型系统的研究不仅对理论计算机科学有重要...

    广东省佛山市第一中学、珠海市第一中学、金山中学2020学年高一语文下学期期中试题(含解析).doc

    4. 参照与创新:建立中国叙事学理论体系的过程中,需要参考世界其他文化的智慧,但参照只是催化剂,真正的创造需要独立的思考和本土文化的深度理解。 5. 时间观念的差异:中国和西方在时间表达上的顺序不同,反映了...

    罗瑶光_DNA元基催化与肽计算第四版_第八章V005081

    最后,第三章“研发源码”给出了部分系统的核心代码,例如“StableData静态类”,这部分内容对于深入理解系统工作原理和技术实现至关重要,同时也方便其他开发者进行二次开发或改进。 综上所述,《罗瑶光_DNA元基...

    lovela:编程语言实验

    【标题】"lovela:编程语言实验"指的是一个与编程...通过参与“Lovela编程语言实验”,你可以深化对编程语言本质的理解,增强编程技巧,并可能激发对未来编程语言发展的创新思考。这是一个挑战性但极富价值的学习经历。

    网页设计作业-html-APP单页

    网页设计是数字时代的重要组成部分,尤其是在创建互动用户体验的领域中,HTML(超文本标记语言)作为构建网页的基础语言,扮演着至关重要的角色。本作业旨在深入理解和应用HTML技术,特别是针对APP单页的设计。通过...

    半导体行业事件点评:ChatGPT专题研究之一:探寻ChatGPT的能力圈,及“破圈”成长之路.pdf

    ChatGPT相较于其他语言模型的优势在于其语义理解的精确性、信息输出的准确性和逻辑连贯性。它的设计使得它可以理解和生成更加自然、流畅的文本,这得益于模型的复杂性以及训练过程中使用的海量文本数据。OpenAI利用...

    发现一篇专门吐槽 NLP 内卷现状的 ACL 论文 ... .rar

    5. **知识图谱的挑战**:在知识图谱构建和应用中,是否存在对复杂语义理解的忽视,以及如何避免知识图谱的封闭性和静态性? 6. **未来方向的思考**:面对内卷,NLP领域应如何调整研究策略,寻找新的突破口,如跨...

    深入理解C++11:C++11新特性解析与应用

    不仅详细阐述了C++11标准的设计原则,而且系统地讲解了C++11新标准中的所有新语言特性、新标准库特性、对原有特性的改进,以及如何应用所有这些新特性。全书一共8章:第1章从设计思维和应用范畴两个维度对C++11新...

    网页式个人简历

    这不仅可以展示个人的写作能力,还可以提供更多关于个人经验和思考的深度内容。 对于【标签】中的“静态网站”,意味着该网站不依赖服务器端的编程语言(如PHP、Python、Java等),所有的数据和交互都在客户端完成...

    Jasper:(alpha,请勿使用)-一种编程语言,旨在成为一种更简单,更漂亮的Javascript

    在编译过程中,Jasper可能会进行深入的语义分析,确保代码符合语言规范,并能正确地转换成JavaScript或其他底层代码。这一过程涉及符号表管理、类型推断和错误检测。 5. **编译到JavaScript**: 由于Jasper的目标...

    嵊泗事业编招聘2015年考试真题及答案解析考试版.docx

    【嵊泗事业编招聘2015年考试真题及答案解析】...这些知识点反映了事业单位招聘考试的多样性和综合性,涵盖了语言理解、法律知识、逻辑推理、科技理解等多个方面。对于考生来说,全面复习并熟练掌握这些知识点至关重要。

    北京大学网络教育软件工程作业.docx

    更具体地说,模型是在特定意图下所确定的角度和抽象层次上对物理系统的描述,通常包含对该系统边界的描述,并给出系统内部各模型元素以及它们之间的语义关系。 **3. 对问题域和运行平台之间“距离”概念的理解** 这...

    VerilogHDL.rar_tool

    Verilog HDL,全称为“Verilog Hardware Description Language”,是一种广泛使用的硬件描述语言,它允许工程师以接近于人类思考的方式描述数字系统的逻辑和行为。在电子设计自动化(EDA)领域,Verilog HDL扮演着至...

    programming-lang-u-washington:华盛顿大学编程语言

    同时,SML的严谨性和功能性也为学习其他编程语言,特别是现代函数式编程语言,如Haskell或F#,打下了坚实的基础。 课程中的编程作业和项目将提供实践经验,让学生亲手编写SML代码,解决实际问题。这不仅加深了对...

Global site tag (gtag.js) - Google Analytics