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

匿名递归函数貌似仍是有过一段时间流行的,我这两天本身弄了个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)
)
相关文章
相关标签/搜索