网络编程
位置:首页>> 网络编程>> JavaScript>> 极致之美——百行代码实现全新智能语言Lisp(6)

极致之美——百行代码实现全新智能语言Lisp(6)

作者:月影 来源:51js 发布时间:2010-07-13 13:07:00 

标签:Lisp,javascript

其他(略为复杂)的扩展:

下面我们定义变量的赋值操作[setq,paraName,paraValue]

LispScript.Run(
 [defun,'setq',['para','val'],
  [ret,[defun,'para',[],[_eval,'val']]]]
);

增加逻辑操作符or,[or,x,y]返回t如果它的自变量有一个为t,否则返回[]

LispScript.Run(
 [defun,'or',['x','y'],
  [not,[and,[not,'x'],[not,'y']]]]
);

增加循环控制foreach,[foreach,v,[paralist],[expr]]
foreach期望list是一个表,依次取表中的每一个原子作为expr的参数进行计算,返回计算结果的表

LispScript.Run(
 [defun,'foreach',['v','list','expr'],
  [cond,
   [[isNull,'list'],[]],
   [true,[cons,[_eval,[_,'expr'],[['v',[car,'list']]]],['foreach','v',[cdr,'list'],[_,'expr']]]]
  ]
 ]
);

增加批量赋值操作let,[let,[[a1,v1],[a2,v2]...]]

LispScript.Run(
  [defun,'let',['paralist'],
   [foreach,"'v'",'paralist',[_,[setq,[car,"'v'"],[car,[cdr,"'v'"]]]]]
  ]
);

总结

现在该回过头来看看我们究竟做了什么,以及这么做有什么意义了。
首先我们用javascript实现了一个简单的向下递归的词法分析器,它能对嵌套数组的每个原子进行简单处理,加上几个辅助函数(toEvalString(),Assert(),Element()和一个存放函数名称的堆栈...简单来说我们仅用了数十行代码实现了一种全新的“函数式”语言??LispScript的完整内核。
接着我们定义了7种原始操作,它们分别是quote,atom,eq,car,cdr,cons和cond
然后(相对较复杂地),我们定义了三种用来描述和调用函数的标记,它们分别是lambda, label以及defun,于是我们成功地用另外不到百行代码实现了LispScript语言的核心环境。
接着(接下来的部分已经可以完全独立于javascript)我们用7种原始操作符和函数定义标记defun定义出一些新的函数,分别是:isNull,and,not,append,pair,assoc,ret和str
然后我们惊喜地发现,可以仅用一行LispScript指令定义出自身的“解析器”??_eval函数
最后我们在此基础上定义出一些略为复杂的函数,它们包括:or,setq,foreach和let,其中一些新函数带给我们的新语言定义变量和处理循环的能力,加上前面实现的一些函数,一个比较完善的基础环境就搭建成了。

写在最后:LispScript和Lisp

事实上我们依照[ref. Paul Graham.]的精彩描述用javascript实现了LispScript,毫无疑问,它是一种Lisp(或者Lisp风格的函数式语言),尽管功能上还十分简陋,但它确实是符合Lisp的基本思想和拥有Lisp的基本特性。由于javascript数组文法的特点,我用[]取代了[ref. Paul Graham]中的(),用逗号取代了空格作为分隔符。同[ref. Paul Graham]的文章以及目前一些标准(或者相对标准)的Lisp不同的是,我根据javascript灵活的特点有意弱化了LispScript的语法结构,这样使得LispScript更加灵活,也更加方便实现,然而代价是一小部分的可维护性和安全性。
最后,LispScript还有许多需要完善的内容,例如,最明显地是它基本上还不具有基本的数值运算能力(相对而言,符号操作能力已经比较完善),另外对原子操作参数合法性的检验、副作用, 连续执行 (它得和副作用在一起才有用), 动态可视域、复杂数据结构支持以及注释文法(这相当重要!)也都是它所欠缺的,不过这些功能“都可以令人惊讶地用极少的额外代码来补救”。

感谢约翰麦卡锡,这位天才早在数十年前就向我们展示了一种程序设计领域内至今无人能超越的“极致的美”,他于1960年发表了一篇非凡的论文,他在这篇论文中对编程的贡献有如欧几里德对几何的贡献.1 他向我们展示了,在只给定几个简单的操作符和一个表示函数的记号的基础上, 如何构造出一个完整的编程语言. 麦卡锡称这种语言为Lisp, 意为List Processing, 因为他的主要思想之一是用一种简单的数据结构表(list)来代表代码和数据.

感谢保罗格雷厄姆,他用浅显易懂的语言将Lisp的根源和实质展现在我们面前,令我们能够幸运地零距离体验Lisp的这种“超凡的美”

如果你理解了约翰麦卡锡的eval, 那你就不仅仅是理解了程序语言历史中的一个阶段. 这些思想至今仍是Lisp的语义核心. 所以从某种意义上, 学习约翰麦卡锡的原著向我们展示了Lisp究竟是什么. 与其说Lisp是麦卡锡的设计,不如说是他的发现. 它不是生来就是一门用于人工智能, 快速原型开发或同等层次任务的语言. 它是你试图公理化计算的结果(之一).

随着时间的推移, 中级语言, 即被中间层程序员使用的语言, 正一致地向Lisp靠近. 因此通过理解eval你正在明白将来的主流计算模式会是什么样.

References
The Roots of Lisp Paul Graham. Draft, January 18, 2002.
LISt Primer Colin Allen & Maneesh Dhagat.Tue Feb 6, 2001.(http://mypage.iu.edu/~colallen/lp/lp.html)

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com