Javascript实现Lisp列表(list)及操作
2014-03-04 00:07
519 查看
Lisp中列表(list)是一个值对,通过操作cons来创建值对,例如(cons 1 2), 1和2分别是值对的两个值。 cons操作具有闭包性,因此构成列表的元素可以是原子类型,也可以是列表类型本身,如(cons 1 (cons 2 3))。读取列表的操作有car、cdr,分别是读取值对的“左值”和“右值”,如(car
'(1 2)) 返回1,(cdr '(1 2)) 则返回2, car、cdr操作同样具有闭包性。
Lisp 递归的威力
对于用程序描述列表中是否包含某个元素这样一个功能,大多数的编程语言可以让你使用(for||while)迭代来完成,。但是Lisp可以完全使用函数递归来完成,而令我感到惊讶是它仅仅使用car、cdr。
(defun our-member (obj lst)
(if (null lst)
nil
(if (eql (car lst) obj)
lst
(our-member obj (cdr lst)))))
这种通过纯函数来表达计算过程, 比起过程化的for&&while语法来说更加简洁。 在学习lisp语言之前,我从来没有想过要遍历一个列表,除了迭代之外还可以用递归,而递归这种方法更适合用来描述一个数学计算问题。
对于Javascript这样的语言,它具有比lisp更加丰富的数据结构,通常我们会用一个Array来表示列表,它的语法更为直观如:
虽然如此,我仍然希望Javascript也可以仅仅使用cons,car,cdr函数的来完成列表的各种操作,谨此来引发对不同语言的思考,这也是我写这个笔记的目的。
Javascript 纯函数实现 cons、car、cdr
cons没有使用任何javascript数据类型来存储left 、right值,而是返回一个“列表函数“。借助Javascript的closure,cons把left,right传递到另一个高阶函数f,使得外部函数可以访问它们,最后为了取到列表的left和right,我们只要在car、cdr中实例化高阶函数f并传递给“列表函数"
list。
结语:数据去哪儿了?Javascript通过closure,让高阶函数接受自由变量作为参数,自由变量随高阶函数生与灭,而高阶函数在调用时不也被当做数据吗?这也正如函数式语言的宣称的那样,一切皆为函数。
注:Javascript closure 通常也叫做闭包,但和前面提到的闭包操作是不同的概念。
'(1 2)) 返回1,(cdr '(1 2)) 则返回2, car、cdr操作同样具有闭包性。
Lisp 递归的威力
对于用程序描述列表中是否包含某个元素这样一个功能,大多数的编程语言可以让你使用(for||while)迭代来完成,。但是Lisp可以完全使用函数递归来完成,而令我感到惊讶是它仅仅使用car、cdr。
(defun our-member (obj lst)
(if (null lst)
nil
(if (eql (car lst) obj)
lst
(our-member obj (cdr lst)))))
这种通过纯函数来表达计算过程, 比起过程化的for&&while语法来说更加简洁。 在学习lisp语言之前,我从来没有想过要遍历一个列表,除了迭代之外还可以用递归,而递归这种方法更适合用来描述一个数学计算问题。
对于Javascript这样的语言,它具有比lisp更加丰富的数据结构,通常我们会用一个Array来表示列表,它的语法更为直观如:
var list =[1,2,3,4]; for(var i =0;i< list.length;i++){ //list[i] }
虽然如此,我仍然希望Javascript也可以仅仅使用cons,car,cdr函数的来完成列表的各种操作,谨此来引发对不同语言的思考,这也是我写这个笔记的目的。
Javascript 纯函数实现 cons、car、cdr
var cons =function(left, right){ return function(f){return f(left,right);}; // 返回列表函数, 使left,right一直保存在内存中 } var car =function(list){ return list(function(left,right){return left;}); // 实例化高阶函数f,取left值 } var cdr = function(list){ return list(function(left,right){return right;});// 实例化高阶函数,取right值 } var list=cons(1,cons(2,3)); car(list);//1 car(cdr(list));//2
cons没有使用任何javascript数据类型来存储left 、right值,而是返回一个“列表函数“。借助Javascript的closure,cons把left,right传递到另一个高阶函数f,使得外部函数可以访问它们,最后为了取到列表的left和right,我们只要在car、cdr中实例化高阶函数f并传递给“列表函数"
list。
结语:数据去哪儿了?Javascript通过closure,让高阶函数接受自由变量作为参数,自由变量随高阶函数生与灭,而高阶函数在调用时不也被当做数据吗?这也正如函数式语言的宣称的那样,一切皆为函数。
注:Javascript closure 通常也叫做闭包,但和前面提到的闭包操作是不同的概念。
相关文章推荐
- javascript操作两个选择列表(有两个列表,如何实现在一个列表通过双击和多选列表中内容添加到另一个列表. )
- 用vector、 multimap、 list容器实现好友列表的各种操作 C++
- javascript控制服务器控件-js操作CheckBoxList实现全选、反选
- 用vector、 multimap、 list容器实现好友列表的各种操作 C++
- Python基于列表list实现的CRUD操作功能示例
- javascript控制服务器控件-js操作CheckBoxList实现全选、反选
- javascript利用控件对windows的操作实现原理与应用
- JavaScript实现多态和继承的封装操作示例
- 结合redis设计与实现的redis源码学习-8.3-t_list.c(列表键)
- 在CheckBoxList用JavaScript实现全选,反选及清空
- Java HashMap嵌套List实现对多目标进行列表分类
- JavaScript实现分类列表显示与隐藏的切换
- JavaScript连接SqlServer实现CRUD操作。js太强大了
- 使用JavaScript操作DOM动态生成下拉列表
- 纯javascript对撤销和重写(undo、redo)的完美实现,适用于任何页面元素操作
- JavaScript实现对下拉列表值进行排序的方法
- [JavaScript]操作下拉列表
- CircleList-使用UGUI实现的圆形列表
- Javascript应用--实现菜单列表展开闭合效果
- javascript实现点击商品列表checkbox实时统计金额的方法