Lisp-方言-Scheme-学习

在 Archlinux 下安装:

1
sudo pacman -S guile

运行 Scheme 程序:

1
guile test.scm

以下是 The Little Schemer 一书的笔记.

1

三个基本的概念:

  • atom, 原子
  • list, 列表
  • collection, 集合

atom 指任意字符串, 如:

  • atom
  • turkey
  • 12938
  • a
  • *kajei$

list 指用 () 包裹一个或多个 atom:

  • (atom)
  • (atom turkey or)

其中, 这里的 3 个 atom 被称为 collection.

atomlist 都被称为 S-expression, (Symbolic expression)

因此:

  • (atom turkey)or 是两个 S-expression

() 指空列表 null (empty 列表)

car (Contents of Address Register)

其用于存储 list 的第一个 S-expression. 一般用于访问列表的第一个 S-expression.

注意不能请求 atom 和空列表的 car.

cdr (Contents of Decrement part of Register)

其返回列表的剩余部分,即从第二个元素开始的子列表.

同样不能请求 atom 和空列表的 cdr.

cons (construct)

其添加任意的 S-expression 到列表的开头处.

其有两个参数:

  1. 任意 S-expression
  2. 任意列表

如:

  • peanut(butter and jelly) 的 cons 为 (peanut butter and jelly)
  • (banana and)(peanut butter and jelly) 的 cons 为 ((banana and) peanut butter and jelly)

基本过程 (primitive procedure)

指由语言本身提供的内置过程或操作符.

car, cdr, cons 都是 primitive procedure.

null? 判断列表是否为空

1
(null? l)

在 Scheme 中 (quote ()) 等价于一个空列表.

因此:

1
(null? (quote()))

的结果是 true

注意, 不能对原子请求 null?

atom? 判断是否为原子

其接受一个参数 (任意 S-expression)

如:

1
(atom? s)

eq? 判断 a1a2 是否为相同的非数字原子

其接受两个参数 (都为非数字原子)

a1Harry, a2Harry:

1
(eq? a1 a2)

true.

2

define

用于定义变量或函数, 形式为:

1
(define <variable> <expression>)

如定义变量 x 并将其值设置为 5:

1
(define x 5)

定义一个名为 double 的函数, 参数为 x, 返回值为 x 的两倍:

1
2
(define (double x)
(* x 2))

lambda

用于创建匿名函数, 形式为:

1
(lambda <parameters> <body>)

如定义一个参数为 a, b, 返回其和的匿名函数:

1
2
(lambda (a b)
(+ a b))

cond 和 else

cond (condition) 用于进行条件判断和分支选择, 形式为:

1
2
3
4
(cond (<condition1> <expression1>) 
(<condition2> <expression2>)
...
(else <expressionN>))

如:

1
2
3
4
5
(define (check-number x)
(cond ((< x 0) "Negative")
((= x 0) "Zero")
((> x 0) "Positive")
(else "Invalid number")))

#t#f

#t 表示 true, #f 表示 false. 是 Scheme 中的布尔值表示.

or

如:

1
(or(null? l1)(null? l2))

and

如:

1
(and(null? l1)(null? l2))

3 用 cons 构筑宏

4 数字游戏

所有数字都是原子.

在 Scheme 中, tup (tuple) 指数字列表, 如:

  • (1 2 3 4)
  • ()

add1 让数字加 1

1
(add1 n)

sub1 让数字减 1

1
(sub1 n)

number? 判断是否为数字

1
(number? n)

9

返回函数, 如:

1
2
3
(lambda (a)
(lambda (x)
(eq? x a)))

define 只是给函数取名字:

1
2
3
4
(define eq?-c
(lambda (a)
(lambda (c)
(eq? c a))))

10

非一般性递归, 如:

1
2
3
4
5
6
(define keep-looking
(lambda (a sorn lat)
(cond
((number? sorn)
(keep-looking a (pick sorn lat)lat))
(else (eq? sorn a)))))

这里只对 lat 的一部分进行递归.

全函数部分函数 .

科拉茨猜想.

阿克曼函数.

停机问题.


Lisp-方言-Scheme-学习
http://example.com/2023/10/24/Lisp-方言-Scheme-学习/
作者
Jie
发布于
2023年10月24日
许可协议