我自己的lisp,也来实现个匿名递归函数玩玩,嘿!

匿名递归函数貌似还是有过一段时间流行的,我这两天自己弄了个lisp,花了不少心思,来回调整完善,这不,暂时告一段落,我也体验一下吧,咱的lisp

首先,给出调用lisp的go代码:

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)

不过这是妥妥的耍赖皮啊,虽然看起来是lambda,用起来也是lambda,其实却是对有名字的函数包装而已

不要着急,我们还有这一版:

(
	(lambda
		(f)
		(f n f)
	)
	(lambda
		(n t)
		(cond
			((> n 0)
				(+
					n
					(t (- n 1) t)
				)
			)
			(1 0)
		)
	)
	10
)

这一个版本,就使用了额外的参数来交叉调用实现递归(话说这个用法在lisp里简直是黄金手指)

但是这样缺陷就是,一写出来就是调用的形式,我们想要一个函数啊,所以修改之后如下:

(
	(lambda
		(f)
		(lambda (n) (f n f))
	)
	(lambda
		(n t)
		(cond
			((> n 0)
				(+
					n
					(t (- n 1) t)
				)
			)
			(1 0)
		)
	)
)

嗯,我们接受一个lambda,返回一个lambda,这是闭包,可咱的lisp恰巧就支持闭包

当然,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)
)

转载于:https://my.oschina.net/liudiwu/blog/156230

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值