当前位置:首页>优优资讯 > 软件教程 > 电脑软件教程 > 向编程复杂性反击——Red语言

向编程复杂性反击——Red语言

作者:本站整理 时间:2015-06-25


  错综复杂和臃肿的解决方案无处不在,你是否曾对软件编程栈的混乱感到过困惑?但无论是在当代软件的构建还是维护环节,很少有架构师和程序员能真正意识到由此带来的成本。Red的存在正是为了反击这种复杂性,这是它最主要的设计目的。没错,在现代软件世界中,“简单”的工具和简单的解决方案仍是可以企及的。这是个所有人都竭力掖藏的行业秘密(这可不是什么好事儿),但自1997年以来,解决方案其实已由Rebol编程语言给出。Red继承自Rebol谱系,并尝试将Rebol原先的使用范围加以大大拓展。Red是个雄心壮志的项目,它想要成为首个全栈编程语言。以下是其主要特性和设计目标:
 
  范式无关,默认提供函数式/命令式/符号式范式
  支持基于原型的对象
  同像语言(Red语言是其自身的元语言)
  既能以静态方式,也能以JIT方式编译为本地代码
  强力支持并发和并行(通过Actor和并行聚集)
  通过内置Red/System DSL提供底层系统编程能力
  提供高级脚本特性和REPL控制台支持
  高度可嵌入(??像Lua一样,或者更好一些)
  低内存占用,支持垃圾回收
  低磁盘空间占用(<1MB)
  生成单个的命令行可执行文件
  零安装、零配置
  独立的跨平台工具链
  除运行的操作系统外,概无其他依赖
 
  Red语言,正如Rebol一样,依靠独特的途径来编程,与目前主流语言的主张有所不同。以下是JSON发明者Douglas Crockford对Rebol语言发表的评论:
  

 
  Red和Rebol的设计目标是要尽可能地提供表达能力,同时保持源代码的高可读性,事实上它们的源代码很接近自然语言。2013年的一项将程序设计语言按表达能力排序的研究项目中,Rebol语言名列第三,仅次于Augeas和Puppet这两种DSL(http://goo.gl/qyPXx)。这有力地表明,在所有通用型程序设计语言中,Rebol是表达能力最强的一个。Red和Rebol都遵守务实设计原则,没有哪部分是拍脑袋的决定,或是“为了不同而不同”。每个语法或语义背后,都有明确的设计理由。
 
  Red语言初探
 
  Red和Rebol如何在企及如此水平的效率的同时,又保持“简单”呢?根本的原因之一,是因为这两者都既是一种数据格式,又是一门程序设计语言。此特性继承自Lisp,特别是s-表达式概念。Lisp中也建立了Red和Rebol所依赖的元编程模型。它们都是同像语言,所有的代码都表示为数据。值存储在块中(使用方括号记法:[……]),即普通列表,这和Lisp的记法一样,但它们不要求函数调用的那对括号,这就使得代码看上去更像自然语言。函数在默认情况下采用前缀记法,然而,Red和Rebol也支持针对数学和布尔运算符采用中缀表示法,这为代码阅读提供了便利。采用这种纯元编程进行程序设计,反射、热补丁、甚至即时编码这些语言特性都能得到内建支持,不需要学习任何新API,也无须特别的库支持,只使用基本函数进行数据操作即可。以下是使用Red语言REPL的示例:
 
  $ red
  red>> code: ["hello"]
  == ["hello"]
  red>> insert code 'print
  == ["hello"]
  red>> code
  == [print "hello"]
  red>> do code
  hello
  red>> code/2: 123
  == 123
  red>> code
  == [print 123]
  red>> append code [+ 1]
  == [print 123 + 1]
  red>> do code
  124
  red>> length? code
  == 4
  red>> type? code/1
  == word!
  red>> foreach value code [probe type? value]
  word!
  integer!
  word!
  integer!
 
  如君所见,该语言的基本构件如下:
 
  1、值:它们代表着数字、时间、字符串、文件名和URL等,如123 45.6 10:20:30.456 192.168.1.0 "Hello" http://red-lang.org。
  2、字:它们可以被用作“变量”(但不是所有的都可以),如print block? string! map-each ?? + =。
  3、块:由值、字和块以任何顺序组合而成,如[1 2 3] [123 "abc" print 10:20]。
 
  这些就是用来表示数据、构建表达式、定义函数、创建对象、以及构造更复杂数据类型的基本构件。符号都是一等(first-class)值,也是一种更自然也更有效的字符串替代品,这对于很多用例都适用,尤其是涉及查找操作时就更能说明问题,因为符号可以以O(1)的效率比较,而字符串则要求O(n)。符号不区分大小写,所以print、Print和PRINT是等同的,人类语言不也是这样吗?
 
  Rebol或Red程序源代码通常都是UTF-8输入字符串,它们都会被LOAD化处理。LOAD是原生的核心功能,能够将任何字符串变换成包含在一个块中的内存二进制格式。块将值存储至128比特的相邻单元内。值主要分为标量值(其尺寸固定)或序列值(用户可以向其中添加/删除数据)。数字、日期、元组和值对是标量值的,而值块、字符串、URL、路径、文件和标签是序列值的示例。标量值通常可以置入单个存储单元,而序列值则需要额外内存。
 
  因此,块是带有垃圾回收的内存管理器进行保留和回收的主要分配单位。Rebol采用经典的stop-the-world标记和清理垃圾回收算法,而Red则依赖于stop-the-thread分代压缩垃圾回收算法(尚未完全实现),交替进行部分或全部遍扫。Red将扩充其垃圾回收算法,在未来实现增量回收,以使得它可以用来开发实时应用,例如60-FPS的街机游戏。
 
  一旦源代码被加载入内存,变成一个值块,它就只是纯粹的数据。默认地,在遍扫源代码,使之变换成Red或Rebol二进制文件时,就会对值进行计算。如果是用Rebol语言,加载的块会被解释执行;如果是用Red语言,它们就将被编译成本地代码,但目的都是为了完成计算。然而,值块以何种方式进行解释,则是依赖于语境的。解释方式有如下几种:
 
  1、函数式:由某个函数来取参计算
  2、作为一种特殊语法:即所谓方言(指DSL)
  3、通过Parse方言语句:匹配(matching)、回溯(backtrack),以及生成(production)
  4、ad-hoc代码:你想如何处理,由自己决定
 
  默认的(非纯的)、以函数式方式解释的语言(即我们通常所谓的“代码”),是一种面向表达式的语言,它带有很简单的语义规则:
 
  1、没有关键字
  2、带有称为“改进”的可选扩充的定参函数
  3、单一或多值的函数参数和返回值
  4、表达式由左到右求值
  5、中缀运算符优先级高于前缀函数调用
 
  因此,浮在语言上方的函数层可以很容易地被任何自定义计算体取代(例如,撰写一个类似于Prolog的解释器将非常简单)。这使得Red和Rebol具备了极好的可延展性,十分容易适应任何你可能的需要。这种灵活性是DSL得以成为一种自然的方式解决一些计算任务,通过提供特定领域的微语言对于给定的任务实现优化的基础。Red和Rebol凭借这种力量,在核心语言和标准库中广泛地使用了嵌入式DSL:
 
  1、VID:视图接口方言(View Interface Dialect)是用于建立GUI的DSL
  2、Draw:进行2D绘图的DSL
  3、Parse DSL:一种类BNF语法解析DSL
  4、Security Dialect:一种在运行时用于控制安全沙箱特性的DSL
  5、函数规格:函数原型亦使用DSL来描述
 
  使得嵌入式DSL的创建容易、便捷的因素有:
 
  1、Parse DSL:一种强大的TDPL,并带递归和回溯支持
  2、可将Red或Rebol代码直接内嵌于规则解析的能力
  3、丰富的数据类型:已支持数十种常用数据的字面量符号,所以没有必要建立特殊规则来解析之
  下面是一些在Rebol2中的GUI DSL的示例:
 
  按一个大小为100×100的红色按钮,以打开一个窗口:
  显示会触发一个动作的按钮:
 
  显示按钮,打印一个字段的内容:
  
  Red语言中的一个Parse DSL示例:
 


 
  与Rebol相比,Red带来了什么?
 
  由于想要解决Rebol语言的一些不足之处,Red语言应运而生。这些不足包括:
 
  1、性能不够高(接近Ruby/ PHP)
  2、缺乏底层编程能力
  3、不能利用多核,并发支持有限
  4、缺少对移动操作系统的支持(在2013年才对Android提供有限的支持)
  5、不开源(开源时限仅至2012年12月,且仅限于Rebol第3版)
 
  Red在解决以上大部分问题时都采用了创新设计:嵌入一个低层次的程序设计语言,它可以直接编译为本地代码,即Red/System。它采用Red语法(值仍为块的形式),但与C类似,语义级别更低。它是静态类型语言,并仅提供少数几种数据类型:integer!、float!、float32!、byte!、logic!、pointer!、struct!,以及function!。它算支持指针算术,这赋予了它近于C的力量。标准库也非常简约,所以纯Red/System编译后的代码尺寸非常小,下面这个程序:
 
  Red/System [
  Title: "Hello World app"
  ]
  print "Hello World!"
 
  编译后通常小于10KB。
 
  Red程序被编译成Red/System代码,并与Red标准库链接,而Red标准库则大部分采用Red/System,少部分用Red自身写就。该库目前未压缩体积约为200KB。我们的目标是在发行1.0版时,将其控制在500KB左右。
 
  Red与Red/System紧密集成,有数种方法在Red语言中调用或内嵌Red/System代码。其中最有用的一种是“常规”函数类型,它允许定义一个Red函数,其函数体为纯Red/System代码。Red语言会为你自动完成传递参数和返回值的装箱/拆箱操作。有了Red/System的帮助,Red语言便可以解决从硬件到DSL的任何抽象层次,从而成为真正的首个全栈编程语言。
 
  因此,Red依靠Red/System工具链来生成可执行文件。该编译器和链接器目前支持的目标平台包括:
 
  1、CPU:IA-32、ARMv5和有限的AVR-8支持(Atmel328P)
  2、文件格式:PE、ELF、Mach-o、.dll、so、APK,以及Windows驱动程序
  3、计划支持的其他格式:
  4、后端:IA-64、ARMv7、asm.js、JVM、CLR、Dalvik,以及LLVM
  5、文件格式:.lib、.a、.ipa,各种驱动程序格式,war(Web归档)
 
  除此之外,Red语言还依靠桥接技术,以访问像Java那样的虚拟机,尤其是提供对Android的支持。事实是,目前已可通过Red/Java桥,采用JNI技术来从Red程序远程控制Java和Android API,并获取事件返回。2014年晚些时候,我们还计划推出Red/Obj-C桥,以访问iOS和Cocoa API。
 
  尽管后端和文件格式的组合可能性繁多,但确定选用何种目标平台的Red配置文件却短小精悍。这就使得交叉编译变得非常简单,例如:
 
  从Linux或Mac平台上生成一个Windows平台的可执行文件:
 
  $ red -t Windows hello.red
 
  从Windows平台上生成一个Raspberry Pi平台的可执行文件:
 
  $ red -t Linux-ARM hello.red
 
  以下是关于这些目标平台的定义:
 
  Windows [
  OS:'Windows
  format: 'PE
  target:'IA-32
  type:'exe
  sub-system: 'GUI
  ]
  Linux-ARM [
  OS:'Linux
  format:'ELF
  target:'ARM
  type:'exe
  base-address: 32768; 8000h
  dynamic-linker: "/lib/ld-linux.so.3"
  ]
 
  Red语言的开发工作仍然任重道远。目前它的工具链部分使用Rebol2完成自举(指Red语言和Red/System编译器+链接器)。由于需支持JIT编译动态生成的Red/System代码,Red语言必须有自承载能力,所以所有工具链需要在1.0版之后用Red语言重写。新的工具链将能生成真正包含全部特征的Red语言,并同时为两种编译器提供优化层,生成更小更快的代码。目前,Red/System的性能实测下来大约比C慢4~6倍,这对于未经优化的本地代码而言已经不错了。
 
  性能还会随着即将到来的并发支持而得到提升。今年晚些时候,Red语言会提供一个完全异步I/O接口,以及M:N线程模型(M个轻量级线程,分发到N个OS线程中去)。根据目前的计划,更高级别的抽象会使用Actor模型,这是为了实现简单而高效的共享状态同步。从用户的角度看,Actor也只是个一等的数据类型,和使用任何其他对象都差不多,很少或者根本没有额外的语法负担。然而,考虑到Go语言的goroutine模型的拥趸之多,我们仍在斟酌各种选项以决定使用Red语言的最佳模式。
 
  Red语言是一个开源项目,采用BSD许可证。作为语言的作者,我全职工作于此业已三年。项目资金来自用户和支持者捐款。自2011年首次发布以来,得到的支持已然令我难以置信。开发者对于Red语言可提供的一切感到惊喜,尤其是那些了解Rebol语言能力的用户。Red语言对于他们中的大多数人,包括我自己,都是梦寐以求的工具。Red语言再次将乐趣带回了程序设计,将复杂性拒之门外,让程序员们再次感觉控制在握,就像那曾经经历的8位机时代。
 
  从中国开始
 
  由于Red语言将具备强大的Andr??oid支持,又格外适合新入行的程序员,我们希望它能够被世界上最大的Andr??oid市场——中国所接受。在中国,程序员数量巨大,而最有才华的Red语言贡献者中,就有一位是来中国上海的程序员谢晴天。
 
  你可以从http://www.red-lang.org/p/download.html下载Red二进制文件。可执行文件只有半兆字节,包含了整个工具链,其中包括Red语言和Red/System编译器,一个带有可选控制台的解释器,还有目前支持30余种数据类型的整个标准库。你也可以尝试虽然老旧一些,但比较完整的Rebol2解释器,尤其是在测试GUI DSL时。

相关文章

相关推荐

最新攻略

用户评论

(已有0条评论)
表情
注:您的评论需要经过审核才能显示哦,请文明发言!
还没有评论,快来抢沙发吧!