匿名递归函数貌似仍是有过一段时间流行的,我这两天本身弄了个lisp,花了很多心思,来回调整完善,这不,暂时告一段落,我也体验一下吧,咱的lisp git
首先,给出调用lisp的go代码: github
package main import "github.com/hydra13142/lisp" func main() { console := lisp.NewLisp() // 建立一个执行环境,环境负责保持函数和变量 console.Eval(``) // 执行的lisp语句放入``内 // 下面一句的写法,能够让你从控制台输入lisp语句,执行并返回结果 // console.Eval(`(println (scan))`) }
咱们要制做的递归函数为求从1到整数n的全部整数的和 闭包
首先,我很高兴的说,咱的lisp那是有个self关键字的,这个关键字专门用来递归调用滴,咱们能够这样写: 函数
(lambda (n) (cond ((> n 0) (+ (self (- n 1)) n) ) (1 0) ) )不过大多数的lisp貌似没有self或者this关键字吧,因此咱们有以下的版本:
(lambda (n) (each (define (f n) (cond ((> n 0) (+ (f (- n 1)) n) ) (1 0) ) ) (f n) ) )
这里的each意为顺序执行下面的语句,最后一句做为返回值;而define毫无疑问就是定义了一个函数f(n) oop
不过这是妥妥的耍赖皮啊,虽然看起来是lambda,用起来也是lambda,其实倒是对有名字的函数包装而已 this
不要着急,咱们还有这一版: lua
( (lambda (f) (f n f) ) (lambda (n t) (cond ((> n 0) (+ n (t (- n 1) t) ) ) (1 0) ) ) 10 )
这一个版本,就使用了额外的参数来交叉调用实现递归(话说这个用法在lisp里简直是黄金手指) code
可是这样缺陷就是,一写出来就是调用的形式,咱们想要一个函数啊,因此修改以后以下: 递归
( (lambda (f) (lambda (n) (f n f)) ) (lambda (n t) (cond ((> n 0) (+ n (t (- n 1) t) ) ) (1 0) ) ) )
嗯,咱们接受一个lambda,返回一个lambda,这是闭包,可咱的lisp恰巧就支持闭包 it
固然,lisp很给力的地方就是它的宏系统,这个我也试了,放在(2)里了。
下面就和递归不要紧了;
lisp最让人不适应的地方,就是它排斥循环(虽然lisp通常仍是提供循环的),下面是个循环版:
(lambda (n) (each (define s 0) (loop (define i 0) (< i n) (each (define i (+ i 1)) (define s (+ s i)) ) ) s ) )固然咱们其实有终极必杀器:
(lambda (n) (/ (* (+ n 1) n) 2) )