Scheme中lambda表达式与函数指针小例
来源:互联网 发布:淘宝卖的玛咖是真是假 编辑:程序博客网 时间:2024/06/06 00:08
SICP/Chapter2/Exercise-2.4
Lambda表达式语法
(lambda kw-formals body)
题目描述
用过程性表示方式重写序对的cons、car、cdr
Scheme代码
(define (cons-24 x y) (lambda (m) (m x y)))(define (car-24 z) (z (lambda (p q) p)))
这段代码只有4行,但是逻辑关系并不好理解。
原因在于函数式语言的自顶向下实现方式不符合一般的逻辑习惯。
lambda以类似函数指针的方式提供了通用的接口,实现了动态绑定的功能。
拆解
(按照自底向上的顺序)
1 - procedure_1 = (lambda (p q) p)
Scheme语义:
- 参数格式:p,q
- body部分:p,意义是返回p
C实现:
- 没有更深层次的嵌套,为完整函数体。
- p,q暂且定义为int类型
int GetCar(int p,int q){return p;}
2 - (define (car-24 z) (z procedure_1))
Scheme语义:
- car-24接受一个参数z
- body部分:因为(z procedure_1), 可判断z为一个函数,其参数为procedure_1
- 函数z的参数procedure_1为一个函数(见1)
C实现:
- 首先应该定义一个procedure_1的函数框架(函数实例见1)
typedef int (*procedure_1)(int,int)
- 然后根据(z procedure_1)可以写出car-24的参数z的框架,返回值继承自M:
typedef int (*ARG_Z)(procedure_1)
- car-24 的参数为z,返回值继承自z。由此可写出car-24的函数框架:
int car-24(ARG_Z z){ return z(procedure_1);//只实现框架,并未绑定实例}
- 因为procedure_1的实例已经在对car-24的define中,所以此时M已经拥有了一个函数实现,可绑定。car-24因此变成:
int car-24(ARG_Z z){ return z(GetCar);}
3 - procedure_2 = (lambda (m) (m x y))
Scheme语义:
- 参数格式——接收一个m作为参数
- 因为lambda中(m)的body部分为(m x y),可知m是一个过程,过程m需要两个参数,x和y。
C实现:
- 仅有函数框架而没有具体实现,与函数指针相似。具体实现需要将抽象实例化,因此无法确定返回值。
- 首先定义参数m的框架:
typedef unknown (*m)(x,y);
- 然后可写出procedure_2的框架:
typedef unknown (*procedure_2)(m);
- 二者返回值未知,取决于绑定类型。procedure_2的返回值继承自m
4 - (define (cons-24 x y) procedure_2)
Scheme语义:
- 参数格式为x,y
- body部分为之前分析的procedure_2,因此这个define生成的是一个过程,需要接受x y参数。
C实现:
目前内层函数未被绑定,只能给出框架。唯一确定的是返回值为procedure_2类型,即返回一个函数指针。 typedef procedure_2 (*cons-24)(x,y)
(拆解完毕)
绑定过程
实例
(define test (cons-24 1 2))(car-24 test)
过程
1 - 生成一个名为test的cons-24实例,该实例需要一个过程作为参数
2 - car-24的参数为test,car-24内置的GetCar函数作为其参数test的参数,实现功能为test(GetCar)。
3 - 逻辑理解的难点:
- 框架和数据在cons-24中给定,却不做任何处理;而是将整个框架抽象成一个类型为过程的变量(或者说抽象成函数指针)。
- 使用时需要car-24接收此函数指针,传递自身的内置函数给这个函数指针作为参数,形成一个嵌套的环节。
- car-24仅仅是一个对内置函数封装,为内置函数加上一层壳
- 两部分间的正常使用需要一个默认的规则:即car-24的参数必须为cons-24类型的过程。这在逻辑上并没有体现。
- 如果从C的角度来看,函数间的层次关系并不清晰,相互依赖。
- 但是仅从抽象接口的目的来看,提供了一个相当好的过程接口。若以C函数实现那么需要三层嵌套的定义。由此可见函数式语言与面向过程语言的不同之处。
0 0
- Scheme中lambda表达式与函数指针小例
- c++11的lambda表达式与传统的函数指针
- C++11中的匿名函数指针(lambda函数,lambda表达式)
- C++ 理解函数对象与lambda表达式
- 委托(四):函数参数与Lambda表达式
- 函数式接口与 Lambda表达式
- C++ lambda表达式与函数对象
- Java8:函数式编程与Lambda表达式
- Kotlin 高阶函数 与 Lambda 表达式
- C++11 lambda表达式与函数对象
- Java函数式编程与Lambda表达式
- lambda表达式与eval(str)函数
- C++11中的匿名函数指针(Lambda表达式)
- Lambda表达式小例子
- Python中defaultdict与lambda表达式小结
- Scheme的Lambda与Ruby的Block
- C++11 在析构函数中执行lambda表达式(std::function)捕获this指针的陷阱
- 匿名函数 & Lambda 表达式
- Django 问题收集
- HttpGet方式调用有道词典API实现单词查询功能
- Linux分区问题
- spring AOP 笔记
- JSON使用案例--一次性解析比较大的json文件
- Scheme中lambda表达式与函数指针小例
- Java遍历文件夹及图像缩放批处理
- hibernate配置文件hibernate.cfg.xml的详细解释
- mount 命令挂载共享到/mnt
- 黑马程序员_JavaSE学习总结第01天_Java概述
- Linux汇编教程01: 基本知识
- Underscore.js
- 利用代码修改layout_marginBottom的属性
- poj1915 Knight Move