Scheme和Common Lisp中对函数作为变量和返回值的处理方法差异

  研究下Scheme和Lisp在lamba上的区别。今天晚上特别郁闷。本来想体会一下Lisp中函数作为第一等变量等柑橘,想不到却不知道载了多少个跟头。

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来判断到底是变量还是函数。

  本文完。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值