摘要: 用到的元素有9个:define,if,null?,cons car,cdr,lambda,let,named let,其实let 和 named let可以去掉.但那样会带来性能和可读性下降的问题.排序类型选的是经典的快速排序.;筛选函数(define (filter f x) (let recur ((x x)) (if (null? x) '() (if (f (car x)) (cons (car x) (recur (cdr x))) (recur (cdr x))))));三元合并函数,形如'(1 2) ... 阅读全文
posted @ 2013-10-28 01:50 LisPythoniC 阅读(612) 评论(0) 推荐(0) 编辑
摘要: 重写过程中,发现这种做法能加深对递归的理解,而且reduce还体现了函数式编程是如何通过参数传递来实现命令式编程中的状态改变的.(define (imap f x . y) (if (null? y) (let recur ((x x)) (if (null? x) '() (cons (f (car x)) (recur (cdr x))))) (let recur ((x x) (y y)) (if (null? x) '() (cons... 阅读全文
posted @ 2013-10-27 23:37 LisPythoniC 阅读(651) 评论(0) 推荐(0) 编辑
摘要: 首先是sum函数.最常见的用法似乎是:>>> sum([1,2,3])6但其实这是默认首个元素是数字0.我们可以指定其他数字:>>> sum([1,2,3],100)106也可指定一个列表对象:>>> sum([[1],[2],[3]],[])[1, 2, 3]>>> sum([[1],[2],[3]],['head'])['head', 1, 2, 3]来看filter,None参数特别用法:>>> filter(None,(1,2,None,3))(1, 2, 3)&g 阅读全文
posted @ 2013-10-27 22:24 LisPythoniC 阅读(413) 评论(0) 推荐(0) 编辑
摘要: procedure:(applyprocarg1...args)Procmust be a procedure andargsmust be a list. Callsprocwith the elements of the list(append (listarg1...)args)as the actual arguments.(define (f x y z) (+ x y z));等效:(f 1 2 3)(apply f '(1 2 3))(apply f 1 '(2 3))(apply f 1 2 '(3));将发生错误:;(apply f '(1) 阅读全文
posted @ 2013-10-27 14:48 LisPythoniC 阅读(582) 评论(0) 推荐(0) 编辑
摘要: named let和递归,闭包联系十分密切.而且还是提高性能的重要手段.先来看一个make-list函数的模拟,最原始的写法大概是:(define (imake-list n member) (if (= 1 n) (cons member '()) (cons member (imake-list (- n 1) member))))这种写法的毛病在于:1.递归过程中,member变量可能需要在全局作用域中查找,比局部作用域查找要慢.2.member是一个固定的参数,然而递归过程在不断重复将它传入imake-list.这个时候你需要 named let,完美... 阅读全文
posted @ 2013-10-27 00:04 LisPythoniC 阅读(402) 评论(0) 推荐(0) 编辑
摘要: 假设你需要递归地使用某个函数func,你给它4个参数:fixed1,fixed2,fixed3,arg1其中,fixed1,fixed2,fixed3表示在递归过程中固定不变的参数.(你可能还需要对它们进行一些处理,返回另外一些固定的数据,再一起加入到函数返回值中.)arg1是变动参数(它控制函数向递归的终点靠近).比如,出于某种奇特的念头,我想用递归的方法将某个字符串拆分成有特定前缀的列表:def func(fixed1,fixed2,fixed3,arg1): if arg1!='': yield '%s%s%s->%s'%(fixed1,fixed2 阅读全文
posted @ 2013-10-26 17:31 LisPythoniC 阅读(488) 评论(0) 推荐(0) 编辑
摘要: 今天模拟定义map函数.写着写着就发现Python可变长度参数的机制真是灵活而强大.假设有一个元组t,包含n个成员:t=(arg1,...,argn)而一个函数f恰好能接受n个参数:f(arg1,...,argn)f(t)这种做法显然是错的,那么如何把t的各成员作为独立的参数传给f,以便达到f(arg1,...,argn)的效果?我一开始想到的是很原始的解法,先把t的各个成员变为字符串的形式,再用英文逗号把它们串联起来,形成一个"标准参数字符串":str_t=(str(x) for x in t)str_args=",".join(str_t)str_a 阅读全文
posted @ 2013-10-25 09:55 LisPythoniC 阅读(5298) 评论(0) 推荐(0) 编辑
摘要: 说明,这是r5rs的用法.(letrec (( ) ...) ) 假设(( ) ...)是变量定义块V,是执行块B.letrec最常见的用法就是用于绑定函数对象,让V里面定义的所有变量可以在运行时相互引用,不受位置前后的限制.比如:> (letrec ((x (lambda () (+ y y))) (y 100)) (+ (x) y))300这说明运行(+ (x) y)时,函数对象x可以读取y对象的值,尽管y在x之后才绑定的. 这一点letrec很像顶层的运作模式:> (define x (lambda () (+ y y)))> (define y 100)> (+ 阅读全文
posted @ 2013-10-25 00:35 LisPythoniC 阅读(1497) 评论(0) 推荐(0) 编辑
摘要: 查了半天没有找到scheme中判断数据类型的函数,索性自己写了个type?,发现闭包和递归有着微妙的联系.本例中,自由变量是types,外层let初始化了types的值,内层let里的(set! types rest)则是在不断缩小types.直至为null.;let内嵌lambda,可以构成闭包;expr ...部分即可对freevar进行各种修改值的操作(define function (let ((freevar value) ...) (lambda (var ...) expr ... )))(define type? (let ((types (list ... 阅读全文
posted @ 2013-10-24 17:23 LisPythoniC 阅读(292) 评论(0) 推荐(0) 编辑
摘要: 想法源自:http://stackoverflow.com/questions/141642/what-limitations-have-closures-in-python-compared-to-language-x-closuresPython 2.7 的闭包中的自由变量(co_freevars)只读的.Python需要某些技巧来"变相修改"自由变量:>>> def add(n): freevar=[n] def closure(): freevar[0]+=1 return freevar[0] return closure>>> 阅读全文
posted @ 2013-10-24 14:20 LisPythoniC 阅读(744) 评论(0) 推荐(0) 编辑