Scheme和Common Lisp中对函数作为变量和返回值的处理方法差异
2013-12-30 23:24
274 查看
研究下Scheme和Lisp在lamba上的区别。今天晚上特别郁闷。本来想体会一下Lisp中函数作为第一等变量等柑橘,想不到却不知道载了多少个跟头。
后来Google搜索了相关的使用方法。原来Lisp中有两个Cell,姑且成为function cell和alue cell。所以允许函数名字和变量名字相同,解析器是根据位置来确定到底时解析成函数还是变量。通过之前说的boundp和fboundp来判断到底是变量还是函数。
本文完。
Scheme
Scheme作为Lisp的一个方言,由MIT研发,并且GPL的协议下发布。大家可以从GNU官网上下载其源码,然后编译安装。Scheme相对与Lisp结合了Agol(不确定)。我们现在来看一下载Scheme语言中如何返回一个函数:(define (repeat-2 fun) (lambda (x) (fun (fun x)))上述定义的函数将函数fun的功能重复两遍。其使用方法如下,假设定义了加1函数incf,
((repeat-2 incf) 1)这样就将incf重复了两次。
Lisp
如果对Scheme的使用方式比较熟悉,那么在使用lisp实现时会觉得很奇怪。因为Lisp解析器根据变量的位置不同来决定变量是函数还是变量。Lisp中由两个函数boundp和fboundp,分别判断一个名字是否时一个有值的变量或者函数。载Lisp中lambda是宏,其展开时会调用function。举个例子。(defun repeat-2 (fun) (lambda (x) (funcall fun (funcall fun x))))此时解析器会将其展开成如下:
(defun repeat-2 (fun) (function lambda (x) (funcall fun (funcall fun x))))Lisp允许我们只写lambda只是提供了一个语法糖,允许我们直接使用。注意到将函数作为变量值传递给函数时,调用方式不能像Scheme那样直接调用,而是需要funcall或者apply来调用。repeat-2返回将指定的函数重复2次的功能,返回的函数值,我们不能直接使用,也必须使用funcall或者apply。相对于Scheme好像有点复杂。
(funcall (repeat-2 #'incf) 1)今晚在测试的时候使用Lisp系统自带的incf,结果报错,说incf是宏,不是函数。当时没注意,以为是调用方式出问题,便加了#'。后来又报错说值不能放函数定义。后来回过头来想起,原来incf是,他们封装了set的功能。于是自己写了incf-my,然后按照上面的方式执行一遍,结果OK。
后来Google搜索了相关的使用方法。原来Lisp中有两个Cell,姑且成为function cell和alue cell。所以允许函数名字和变量名字相同,解析器是根据位置来确定到底时解析成函数还是变量。通过之前说的boundp和fboundp来判断到底是变量还是函数。
本文完。
相关文章推荐
- 1.正则表单验证2.全局变量作为形参传入函数内部操作之后,变量的值在全局上不发生改变的解决方法
- 类成员函数作为CallBack函数时3种访问类成员变量的方法
- C#委托本质探索 七、方法变量作为函数参数传递
- linux shell 自定义函数方法(定义、返回值、变量作用域)
- linux shell 自定义函数方法(定义、返回值、变量作用域)
- Ajax - 在函数中使用Ajax怎么使用返回值 - Ajax赋值给全局变量异常的解决方法
- 结构体变量作为函数的参数和返回值 .
- (struct)结构体变量作为函数参数调用的方法小结
- SpringMVC Controller函数参数问题(就是作为方法的参数,以类名小写开头可以在JSP页面中获得该变量的数据 )
- MFC中自定义消息方法及如何得到消息处理函数的返回值
- 结构体变量作为函数的参数和返回值
- JS中跨页面调用变量和函数的方法(例如a.js 和 b.js中互相调用)
- 函数与变量名字相同怎么处理?
- 详解PHP处理字符串类似indexof的方法函数
- MFC 主界面函数中线程等待避免界面卡死的处理方法
- Python中使用内建函数名作为变量标识符
- C++ ——vector作为函数返回值用法
- 使用Result代替ResultSet作为方法返回值
- node.js路由后添加有返回值(return)的处理函数
- 定义一个结构体变量(包含年月日),计算该日在本年中为第几天?要求写一个days函数。参数是此结构体类型的变量,返回值是整数