Scheme 4 Javaer-4.Pair、car和cdr

Java中,除了基本类型,其他类型都属于类/接口类型。从讨论数据抽象的角度看,基本类型是更适合的标的物,因为从Java虚拟机规范和Java虚拟机实现层面,基本类型有了有效的接口与实现分离。而类/接口类型的数据抽象,通常我们介绍封装、信息隐藏和类的接口等概念,它们说明Java类作为数据抽象,用户需要了解的是类的接口。

Scheme中,我们可以从基本类型构造新数据类型,换言之,我们可以赤裸裸地观察新数据类型的实现细节(不像Java,基本类型的实现细节由Java虚拟机实现厂商完成;程序员的自定义类型依靠的是类/接口这种定义方式,因而本部分的内容对我们学习《编程导论(Java)·第4章   数据抽象》,是一个很好的补充)。

Scheme所有从序对构造出来的数据被称为表结构(list-structured)数据。因而Scheme的数据分两种:基本类型和list

Scheme构成新数据类型的方式,是将两个数据粘接在一起。现在我们就研究一下这个粘接剂502。

Pair

你将两个东西放在一起,并不能说明两者是什么关系。例如将《编程导论(Java)·1.2.5 案例:分数》中定义的分数/有理数的代码修改成如下。

public class X{
    private  int a; //分子numerator
    private  int b = 1; //分母denominator
    public int getA(){return a;}
    public int getB(){return b;}
}

你如何知道X是分数还是复数或什么别的东西呢?X的类型含义,由它的操作接口(分数的加法还是复数的加法)来刻画。

Scheme定义新类型的通用结构称为pair(对,序对——裘的翻译,我不经意地想到序偶),这里不关心数据类型的实际意义和它的接口,而是单纯地看看如何“二生三,三生万物”。

和pair相关的3个通用函数。

l        构造子(constructors,构造函数) cons,将两个东西放在一起。

(define x (cons 1 2))

l        选择子(selectors,选择函数) car和cdr,可以将car看成getOne,cdr看成getTwo。

(car x)

→1

(cdr x)

→2

(SICP介绍,The name cons stands for ``construct.‘‘ The names car and cdr derivefrom the original implementation of Lisp on the IBM 704. Car stands for``Contents of Address part of Register‘‘ and cdr (pronounced ``could-er‘‘)stands
for ``Contents of Decrement part of Register.‘‘)

可以用指针来了解序对(cons 1 2)。这里有3个指针,x或(cons1 2)整体作为一个指针,指向一个两单元的盒子;两单元中前者保存指针car,后者为cdr。

目前car指向的空间保存一个数字1。如果car或/和cdr指向的空间,保存一个指向序对的指针,由此就可以形成更复杂的数据整体(属于某一数据类型,形成某种数据结构)。

闭包(closure)

来自于抽象代数的概念,闭包(closure)用于说明某个集合的性质(如同SICP,我们也不考虑它的另外一个含义——带有数据的行为)。

“道生一,一生二,二生三,三生万物”。这里有一个前提,所有衍生的东西,都属于一个集合。如人生出的孩子,也是人,他们可以继续生孩子;整数相加的结果还是整数。所以,闭包(closure)说明了一个集合满足一个条件:对集合元素的操作,其结果属于该集合(因而可以再次对它进行操作)。

具有闭包性质的集合,具有“三生万物”的强大能力。序对cons作为通用构造块,可以演化出这种构造方式下最适合、好用而且复杂的各种数据类型——例如描述《数据结构》中各种结构的数据类型。

序列

序列(sequence)是一组有序数据的集合,如{1 2 3 4}。在Java中用数组或链表来描述/保存序列。

假设每个序对的car指向的空间(其实可以视为 本地) 保存一个数字,而cdr保存一个序对的指针,这样,每个序对如同一个单向链表的结点。注意:最后一个序对中包含了一个表明序列结束的nil(null的拉丁语)。

(cons 1  (cons 2  (cons 3 (cons 4 nil))))

这个简单的复合数据/数据结构很常用,Scheme提供了一个便宜操作符list,使程序员更方便地表示上面的表达式。

(list 1 2 3 4)

→(1 2 3 4)

(list 1 (list 2 3 4))

→(1 (2 3 4) )

(cons 1 (list 2 3 4))

→(1 2 3 4)

(cons (list 1 2) (list 34))

→( (1 2) 3 4)

(list (list 1 2) (list 34)) ; 用树来解释本表达式

→( (1 2) (3 4) )

值得注意的是,数据类型和数据结构的有趣关系。

(define x (cons 12)),我们不知道x是什么数据类型;

(define x (list 12)),或(define x (cons1  (cons 2  nil)))

我们知道x是一个list。

符号数据

假设(define x (cons 1 2))定义的,是一个分数1/2(不是复数),作为一般的应用,数学家们希望使用代数符号,例如(define x (cons a b))表示一个分数a/b。这里a、b是表示任意数的符号。

下面的例子中,虽然定义了分数a/b,但是a、b不是表示任意数的符号。

(define a 1 )

(define b 2 )

(define x (cons a b))

Scheme提供了前缀引号,例如’a表示这里的a是一个符号。

(list ‘a ‘b ‘c)

→( a b c )

下面再学习:粘接之后,我们要干什么。如(1)对于分数或复数,如何由它的操作接口刻画其类型;

(2)如何操作和应用list...

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-21 15:07:42

Scheme 4 Javaer-4.Pair、car和cdr的相关文章

Scheme初探

Scheme programs consist of expressions( everything is expressions ), which can be: •Primitive expressions: 2, 3.3, true, +, quotient, ... •Combinations: (quotient 10 2), (not true), ... 1. Primative expressions Numbers are self-evaluating; symbols(ju

ANSI_common-lisp

前言 本书的目的是快速及全面的教你 Common Lisp 的有关知识.它实际上包含两本书.前半部分用大量的例子来解释 Common Lisp 里面重要的概念.后半部分是一个最新 Common Lisp 辞典,涵盖了所有 ANSI Common Lisp 的操作符. 这本书面向的读者 ANSI Common Lisp 这本书适合学生或者是专业的程序员去读.本书假设读者阅读前没有 Lisp 的相关知识.有别的程序语言的编程经验也许对读本书有帮助,但也不是必须的.本书从解释 Lisp 中最基本的概念

zookeeper 基本概念

The ZooKeeper Data Model ZooKeeper has a hierarchal name space, much like a distributed file system. The only difference is that each node in the namespace can have data associated with it as well as children. It is like having a file system that all

全民Scheme(0):lat的定义

接下来我会写一写Scheme的学习笔记.嗯,Scheme是属于小众的语言,但合适用来教学的. 什么是lat,就是遍历list里的每个S-expression,如果发现其中某个不是atom的,则返回false,否则返回true. (define atom? (lambda (x) (and (not (pair? x)) (not (null? x))))) (define lat? (lambda (l) (cond ((null? l) #t) ((atom? (car l)) (lat? (

Scheme语言--简单介绍

一年前事实上有时间看完SICP这本书,后来由于种种原因,一直没有继续再学.由于SICP中使用Scheme确实应用不多.在Java,C++的语言眼里,Scheme确实非常另类.现在MIT已经放弃了使用Scheme作为SICP的教学语言而转向python之际,我在此開始学习这本书与这门语言的学习.SICP主要使用Scheme语言来解决计算机科学中的一些问题.为了督促自己,每天都能学习.积小流而成江海,把自己的学习过程放在这里,以供自己复习. 本系列主要包含两部分Scheme语言层面的问题及SICP中

与Scheme共舞

发表在<程序猿>2007年7月刊上.不log上写帖子不用考虑版面限制,所以这里的帖子比发表的啰嗦点.赵健平编辑,Jacky,和刘未鹏都给了我非常多帮助,在这里一并谢了.免费的Scheme实现非常多.我用的是PLT Scheme,能够到这里下载.PLT Scheme的IDE(Dr. Scheme)支持Emacs的键盘绑定,用emacs的老大们应该喜欢.Dr.Scheme内置中文支持: 以下是正文: 不能影响你思考方式的编程语言不值得学习 – Alan Perlis[1] 不少朋友问,为什么要学S

[Scheme入门]3 eqv?、loop、let、letrec、do等的比较和使用

一.对象的比较 1.eq? 这个函数用来比较2个对象的地址,如果相同的话就返回#t.在Scheme中真用#t表示,假则用#f. 例如,(eq? str str)返回#t,因为str本身的地址的是一样的,但是"scheme"和"scheme"则被存储在不同的地址中,因此函数返回#f.注意,不要用eq?来比较数字,因为在R5RS和MIT-Scheme中均没有被指定返回值,建议使用eqv?或者=代替.以下是一些示例: (define str "scheme&qu

Scheme 链表转置

原list: ( ( 1 2 ) ( 3 4 ) ) 转置: ( ( 3 4 ) ( 1 2 ) ) 深度转置: ( ( 4 3 ) ( 2 1 ) ) ( define tree ( list 1 ( list 2 ( list 3 4 ) 5 ) ( list 6 7 ) ) ) ( define nil '() ) ( define ( my-reverse items ) ( define ( rev-imp items result ) ( if ( null? items ) res

【Scheme归纳】3 比较do,let,loop

一.对象的比较 1.eq? 这个函数用来比较2个对象的地址,如果相同的话就返回#t.在Scheme中真用#t表示,假则用#f. 例如,(eq? str str)返回#t,因为str本身的地址的是一样的,但是"scheme"和"scheme"则被存储在不同的地址中,因此函数返回#f.注意,不要用eq?来比较数字,因为在R5RS和MIT-Scheme中均没有被指定返回值,建议使用eqv?或者=代替.以下是一些示例: (define str "scheme&qu