作者自述CSE语言设计思想(六)----基于HTML5跨越NativeApp与WebApp的一种途径
2011-12-30 22:48
288 查看
今天的主题是:用CSE仿真JavaScript语言
多范式语言
CSE是一门多范式编程语言,尽管在官方文档中CSE只宣称是基于函数式编程(FuntionalProgramming)的语言,并未宣称它是多范式语言,但从实际表现来看,它确实是一门不打折扣的多范式语言。
《CSE功能手册》中介绍了用CSE映射C、C++,CSE在支持基于过程、基于面向对象方面是完整的,CSE本身是脚本语言,与Python、Ruby类似,它的内核基于纯正的函数式架构,所以也可拓展用纯正函数式风格进行编程,前面我们有过介绍了:
作者自述CSE语言设计思想:用CSE模拟LISP语言(上)
作者自述CSE语言设计思想:用CSE模拟LISP语言(中)
作者自述CSE语言设计思想:用CSE模拟LISP语言(下)
在多范式方面,还有一门语言值得一提:Falcon(官方主页:www.falconpl.org/),中文介绍请参考维基百科中的词条(http://zh.wikipedia.org/wiki/Falcon编程语言)。Falcon宣称支持六种编程范式(见Falcon官方首页):
Ø procedural,过程式
Ø object oriented,面向对象
Ø prototype oriented,基于原型
Ø functional,函数式
Ø tabular,表格化
Ø messageoriented,面向消息
对Falcon多些了解后,我有一个挥之不去的感觉,Falcon为语言而语言了。创造一门语言要着眼于它能解决什么问题,Objective-C够土吧?但它解决了MAC、iPhone、iPad上高效率程序的开发问题,傻儿八唧并不影响它广泛流行。所谓表格化(还有面向消息),与函数式、面向过程、面向对象根本不在同一层面上,面向过程语言也可以构造消息驱动机制呀。把多范式作为一门语言的主要卖点去宣传,说明作者的思维方式还没进化。
同行相轻了?见谅。干同样技术活,忍不住多说几句。拿Falcon类比是要引出今天的话题,如何让CSE也具备Prototype Oriented(基于原型)的编程能力,JavaScript是基于原型编程的一个典范,我们要做的是,如何用CSE脚本仿真JavaScript语言风格。
模拟JS的意义
CSE是脚本语言,JavaScript也是脚本语言,用脚本语言模拟脚本语言,吃饱了撑着吗?
前面我强调:一门编程语言要强化它的应用特质,拿CSE仿真JS,不要只看到脚本语言仿真脚本语言,因为仿真的价值不在于CSE能实现原型编程,而是它可以仿真作为WEB终端开发事实标准的JavaScript的能力。“实现原型编程”是没多少价值的,基于函数式的语言都容易做到,但模拟WEB事实标准的开发形式却是高价值的。
进一步阐述我的思路,当前CSE聚焦于提供一种“用脚本化方式”快速开发“经编译、能高效运行”的程序,即,让开发者同时享受脚本语言与编译语言的优势,为实现这个目标我们耗用了七年。后面,我们还同样消耗若干年为CSE赋予更高使命:融合WebApp开发与NativeApp开发,或者说,让WebApp开发不要有那么多缺陷,也让NativeApp发行不再受限,当这个使命放在Html5注定流行的大背景下,它变得高大起来,你信吗?至少我是信的。
还没理解上面这段话的,请往下看,已理解了的,也请往下看。用CSE仿真JS是个契子,它会引伸出更多有趣的东西。
一个前提
用CSE脚本语言模拟JS,主要服务于软件开发阶段,release发布时应将CSE脚本译成JS,或译成C/C++。否则,如果发布仍用CSE脚本,用脚本仿真脚本,真是吃饱撑着了。
这种做法至少为WebApp解决两个难题,其一,性能问题,谁都愿用Html5开发跨平台游戏,但JS支持大型网游存在性能瓶颈。其二,安全问题,基于JavaScript与HTML5网页的程序,客户端代码很难保密,谁都不希望自己辛辛苦苦开发的东西,一发布就被别人盗用。
但脚本语言与C/C++编译语言存在鸿沟,前者是弱类型系统,后者是强类型系统,消除两者鸿沟,我们需作出一些限制,让弱类型系统模拟强类型系统的行为,就像当前CSE-CPP语言集,用脚本做开发、做调试,最后能翻译为强类型系统的代码。
类型系统
JS的类型比较简单,number、string、boolean、object,再就是null了,用CSE的int、wint、float可以模拟JS的number,CSE的string模拟JS的string,CSE的TBool模拟JS的bool,剩下只有object要费点事,后面专门介绍。
创建变量与变量读写:
这几行译成JS:
一个变量不应用作多个类型,如下代码尽管CSE能正确执行,译成JS也正确。
但译成C/C++会有问题。使用命名前缀,如上面iValue、sName,可有效避免误用。
控制语句与函数定义
CSE的if、else、while、for、try..catch、break、continue、return等语句,可以直译到JS代码。swith..case不支持,使用switch的场合均可用if..else替代,另外,JS的with也不支持,因为C/C++没有与之对应的语法。
CSE的lambda函数定义足以仿真JavaScript的函数。比如:
等效于JS中:
用JSON风格创建object
JavaScript创建object典型方式如下:
我们用CSE中interface风格的class模拟这种object,如下:
在CSE中创建与使用object如下:
给一个object随时增加成员变量(如上面classmate.age),或成员函数(如上面classmate.info)我们做到了。这里我们用CSE模拟JS还存在几个缺陷:
1. 没有用“{}”表达object的初始内容
2. 为object定义函数时,没像JS那样用this来虚指
这两点在本文后都会解决。我们先解决上述JS中JSON表达方式存在的一个问题,赋给classmate.info的函数一次定义后专供classmate对象使用,并未共享给其它object。如果我们创建另一个名为classmate2的变理,也用“classmate2.info = function()....”再赋一次值,太繁琐了。改用JS的prototype可解决这个问题,比如:
接着优化,让JS的类型声明独立出来,就像C++的class类声明,让JS中的object通过class类创建出来,即,上面“new Person()”看起来有点像C++的类实例创建,但Person是个函数。改成如下代码:
这里__init__相当于C++中的构造函数,上面Person定义是不是很像C++的class类声明了?New函数有点奥妙在其中,我们定义New_是为了转接待创建类的原型,为什么要这样转接留给大家自己琢磨。
让JS像C++那样定义类继承关系
继续对JS描述方式做优化,逐步让它长得像C++,我们才好动手用CSE描述它。
klass函数用来组织派生类的内容定义,实际就是将基类与新定义的派生类进行内容合并。上面我们用“Student = klass(Person,{ ... } )”的形式指明基类(Person),在花括号内定义派生类新增的函数,最后得到派生类Student。
经过前面改造,我们让JS代码长得很像C++了,如果大家还有别的更好方案,不妨告诉我一下。
用CSE模拟JS的类定义
把上面代码改用CSE表达,New与klass函数是公共基础函数,我们先不管。
让TObject成为所有仿真JavaScript实体的基类,一些通用的函数,如类型比较要在这个类中定义,这样,我们新定义的Person类要从TObject继承,Student类要从Person继承。
对比前面CSE代码与JS代码,不难看出这两者之间具备一一对应的直译关系,用CSE模拟JS不再困难。至于New与klass函数在CSE中如何实现,限于篇幅,本文不展开介绍,事实上,目前正在开发的CSE-SUPER语言未必就用上面举例的klass与New的方式定义类及创建对象(用CSE脚本还有更简洁的表达方式),本文用来论证语法表达形式兼容C++、CSE、JavaScript的可能性,就这样举例了。
多范式语言
CSE是一门多范式编程语言,尽管在官方文档中CSE只宣称是基于函数式编程(FuntionalProgramming)的语言,并未宣称它是多范式语言,但从实际表现来看,它确实是一门不打折扣的多范式语言。
《CSE功能手册》中介绍了用CSE映射C、C++,CSE在支持基于过程、基于面向对象方面是完整的,CSE本身是脚本语言,与Python、Ruby类似,它的内核基于纯正的函数式架构,所以也可拓展用纯正函数式风格进行编程,前面我们有过介绍了:
作者自述CSE语言设计思想:用CSE模拟LISP语言(上)
作者自述CSE语言设计思想:用CSE模拟LISP语言(中)
作者自述CSE语言设计思想:用CSE模拟LISP语言(下)
在多范式方面,还有一门语言值得一提:Falcon(官方主页:www.falconpl.org/),中文介绍请参考维基百科中的词条(http://zh.wikipedia.org/wiki/Falcon编程语言)。Falcon宣称支持六种编程范式(见Falcon官方首页):
Ø procedural,过程式
Ø object oriented,面向对象
Ø prototype oriented,基于原型
Ø functional,函数式
Ø tabular,表格化
Ø messageoriented,面向消息
对Falcon多些了解后,我有一个挥之不去的感觉,Falcon为语言而语言了。创造一门语言要着眼于它能解决什么问题,Objective-C够土吧?但它解决了MAC、iPhone、iPad上高效率程序的开发问题,傻儿八唧并不影响它广泛流行。所谓表格化(还有面向消息),与函数式、面向过程、面向对象根本不在同一层面上,面向过程语言也可以构造消息驱动机制呀。把多范式作为一门语言的主要卖点去宣传,说明作者的思维方式还没进化。
同行相轻了?见谅。干同样技术活,忍不住多说几句。拿Falcon类比是要引出今天的话题,如何让CSE也具备Prototype Oriented(基于原型)的编程能力,JavaScript是基于原型编程的一个典范,我们要做的是,如何用CSE脚本仿真JavaScript语言风格。
模拟JS的意义
CSE是脚本语言,JavaScript也是脚本语言,用脚本语言模拟脚本语言,吃饱了撑着吗?
前面我强调:一门编程语言要强化它的应用特质,拿CSE仿真JS,不要只看到脚本语言仿真脚本语言,因为仿真的价值不在于CSE能实现原型编程,而是它可以仿真作为WEB终端开发事实标准的JavaScript的能力。“实现原型编程”是没多少价值的,基于函数式的语言都容易做到,但模拟WEB事实标准的开发形式却是高价值的。
进一步阐述我的思路,当前CSE聚焦于提供一种“用脚本化方式”快速开发“经编译、能高效运行”的程序,即,让开发者同时享受脚本语言与编译语言的优势,为实现这个目标我们耗用了七年。后面,我们还同样消耗若干年为CSE赋予更高使命:融合WebApp开发与NativeApp开发,或者说,让WebApp开发不要有那么多缺陷,也让NativeApp发行不再受限,当这个使命放在Html5注定流行的大背景下,它变得高大起来,你信吗?至少我是信的。
还没理解上面这段话的,请往下看,已理解了的,也请往下看。用CSE仿真JS是个契子,它会引伸出更多有趣的东西。
一个前提
用CSE脚本语言模拟JS,主要服务于软件开发阶段,release发布时应将CSE脚本译成JS,或译成C/C++。否则,如果发布仍用CSE脚本,用脚本仿真脚本,真是吃饱撑着了。
这种做法至少为WebApp解决两个难题,其一,性能问题,谁都愿用Html5开发跨平台游戏,但JS支持大型网游存在性能瓶颈。其二,安全问题,基于JavaScript与HTML5网页的程序,客户端代码很难保密,谁都不希望自己辛辛苦苦开发的东西,一发布就被别人盗用。
但脚本语言与C/C++编译语言存在鸿沟,前者是弱类型系统,后者是强类型系统,消除两者鸿沟,我们需作出一些限制,让弱类型系统模拟强类型系统的行为,就像当前CSE-CPP语言集,用脚本做开发、做调试,最后能翻译为强类型系统的代码。
类型系统
JS的类型比较简单,number、string、boolean、object,再就是null了,用CSE的int、wint、float可以模拟JS的number,CSE的string模拟JS的string,CSE的TBool模拟JS的bool,剩下只有object要费点事,后面专门介绍。
创建变量与变量读写:
iValue as 3; print(iValue); sName as "example"; print(sName);
这几行译成JS:
var iValue = 3; print(iValue); var sName = "example"; print(sName);
一个变量不应用作多个类型,如下代码尽管CSE能正确执行,译成JS也正确。
iValue as 3; print(iValue); iValue as "example"; print(iValue);
但译成C/C++会有问题。使用命名前缀,如上面iValue、sName,可有效避免误用。
控制语句与函数定义
CSE的if、else、while、for、try..catch、break、continue、return等语句,可以直译到JS代码。swith..case不支持,使用switch的场合均可用if..else替代,另外,JS的with也不支持,因为C/C++没有与之对应的语法。
CSE的lambda函数定义足以仿真JavaScript的函数。比如:
test as lambda: i,j, return i + j; end; test2 as lambda: declare(i,j = 1), return i + j; end;
等效于JS中:
function test(i,j) { return i + j; } test2 = function(i) { j = arguments.length == 1? 1:arguments[1]; return i + j; }
用JSON风格创建object
JavaScript创建object典型方式如下:
var classmate = { name:"Wayne" }; print("name is " + classmate.name); classmate.age = 18; classmate.info = function() { print("name:" + this.name); } classmate.info();
我们用CSE中interface风格的class模拟这种object,如下:
class JsonClass: end as AInterface; class JsonClass: declare #dict as TEntryArray*; func JsonClass(me): ppDict as TEntryArray** = &me as TEntryArray**; *ppDict = new TEntryArray(); end; func `~JsonClass`(me): ppDict as TEntryArray** = &me asTEntryArray**; delete *ppDict; *ppDict = NULL; end; func `#1:`: ## get attribute declare(me,attr); if "#dict" == attr: return *(&me as TEntryArray**); end else: pDict as *(&me asTEntryArray**); ret as pDict->get(attr.toId()); if CseNull == ret: throw(EAttrError,"attribute(%s) inexistent" % [attr]); end else return ret; end; end; func `#1;`: ## set attribute declare(me,attr,value); if "#dict" == attr: throw(EAttrError,"attribute(#dict) is readonly"); end else: pDict as *(&me asTEntryArray**); pDict->set(attr.toId(),value); return value; end; end; end;
在CSE中创建与使用object如下:
classmate as JsonClass(); classmate.name = "Wayne"; classmate.age = 18; classmate.info = lambda: print("name:" + classmate.name); end;
给一个object随时增加成员变量(如上面classmate.age),或成员函数(如上面classmate.info)我们做到了。这里我们用CSE模拟JS还存在几个缺陷:
1. 没有用“{}”表达object的初始内容
2. 为object定义函数时,没像JS那样用this来虚指
这两点在本文后都会解决。我们先解决上述JS中JSON表达方式存在的一个问题,赋给classmate.info的函数一次定义后专供classmate对象使用,并未共享给其它object。如果我们创建另一个名为classmate2的变理,也用“classmate2.info = function()....”再赋一次值,太繁琐了。改用JS的prototype可解决这个问题,比如:
function Person(name) { this.name = name; } Person.prototype.info = function() { print("name:" + this.name); } var classmate1 = new Person("Wayne"); var classmate2 = new Person("George"); classmate1.info(); // output is: name:Wayne classmate2.info(); // output is: name:George
接着优化,让JS的类型声明独立出来,就像C++的class类声明,让JS中的object通过class类创建出来,即,上面“new Person()”看起来有点像C++的类实例创建,但Person是个函数。改成如下代码:
var Person = { __init__: function(name) { this.name = name; } info: function() { print("name:" +this.name); } }; function New(aClass,aParams) { function New_() { if (aClass.__init__) aClass.__init__.apply(this,aParams);} New_.prototype = aClass; return new New_(); } var classmate1 = New(Person,["Wayne"]); var classmate2 = New(Person,["George"]); classmate1.info(); classmate2.info();
这里__init__相当于C++中的构造函数,上面Person定义是不是很像C++的class类声明了?New函数有点奥妙在其中,我们定义New_是为了转接待创建类的原型,为什么要这样转接留给大家自己琢磨。
让JS像C++那样定义类继承关系
继续对JS描述方式做优化,逐步让它长得像C++,我们才好动手用CSE描述它。
function New(aClass,aParams) { function New_() { if (aClass.__init__)aClass.__init__.apply(this,aParams); } New_.prototype = aClass; return new New_(); } function klass(aBaseClass, aClassDefine) { function klass_() { for(var member in aClassDefine) this[member] = aClassDefine[member]; } klass_.prototype = aBaseClass; return new klass_(); }; var Person = { __init__: function(name) { this.name = name; } info: function() { print("name:" +this.name); } }; var Student = klass(Person, { __init__: function(name,No) { Person.__init__.call(this,name); this.No = No; } info2: function() { print("name:" + this.name+ ",No:" + this.No.toString()); } }); var classmate1 = New(Person,["Wayne"]); var classmate2 = New(Student,["George",11]); classmate1.info(); classmate2.info(); classmate2.info2();
klass函数用来组织派生类的内容定义,实际就是将基类与新定义的派生类进行内容合并。上面我们用“Student = klass(Person,{ ... } )”的形式指明基类(Person),在花括号内定义派生类新增的函数,最后得到派生类Student。
经过前面改造,我们让JS代码长得很像C++了,如果大家还有别的更好方案,不妨告诉我一下。
用CSE模拟JS的类定义
把上面代码改用CSE表达,New与klass函数是公共基础函数,我们先不管。
Person as klass(TObject, { __init__: lambda: name, me.name = name; end; info: lambda: print("name:" + me.name); end; }); Student as klass(Person, { __init__: lambda: name,No, INIT_CLASS(Person,name); me.No = No; end; info2: lambda: print("name:"+ me.name + ",No:" + me.No.toString()); end; }); classmate1 as New(Person,["Wayne"]); classmate2 as New(Student,["George",11]); classmate1.info(); classmate2.info(); classmate2.info2();
让TObject成为所有仿真JavaScript实体的基类,一些通用的函数,如类型比较要在这个类中定义,这样,我们新定义的Person类要从TObject继承,Student类要从Person继承。
对比前面CSE代码与JS代码,不难看出这两者之间具备一一对应的直译关系,用CSE模拟JS不再困难。至于New与klass函数在CSE中如何实现,限于篇幅,本文不展开介绍,事实上,目前正在开发的CSE-SUPER语言未必就用上面举例的klass与New的方式定义类及创建对象(用CSE脚本还有更简洁的表达方式),本文用来论证语法表达形式兼容C++、CSE、JavaScript的可能性,就这样举例了。
相关文章推荐
- 作者自述CSE语言设计思想(五)----用CSE模拟LISP语言(下)
- 作者自述CSE语言设计思想(九)---- CSE-Super语言设计思路(下)
- 作者自述CSE语言设计思想(三)----用CSE模拟LISP语言(上)
- 作者自述CSE语言设计思想(二)----CSE语言表达风格
- 作者自述CSE语言设计思想(一)----做50号语言,还是0号语言?
- 作者自述CSE语言设计思想(七)----CSE-Super语言设计思路(上)
- 作者自述CSE语言设计思想(八)----CSE-Super语言设计思路(中)
- 作者自述CSE语言设计思想(四)----用CSE模拟LISP语言(中)
- 一种基于DSP平台的快速H.264编码算法的设计
- 卡尔曾写道,“作为一种技术,书让我们的注意力集中,使我们免受充盈于生活中的分心事所干扰。而一台联网的电脑却做着完全相反的事,它设计出来就是用来分散我们的注意力的……在知道我们的思想深度与专注程度直接相
- 音视频同步系列文章之----一种基于RTP协议的客户端媒体流Buffer管理思想(2)
- 分享29个基于Bootstrap的HTML5响应式网页设计模板
- SVG一种基于XML的语言
- 设计基于HTML5的APP登录功能及安全调用接口的方式
- 基于敏捷思想的 iOS 平台软件的设计与实现
- 基于HTML5的WebGL设计汉诺塔3D游戏
- 一种基于Qt的可伸缩的全异步C/S架构服务器实现(三) 流水线结构线程池设计
- 如何全面的了解html5,为什么是当今主流的设计开发类语言?