Scheme 介绍

时间:2024-10-23 07:48:24

最近一直在看 sicp 这本书,准备写点读书笔记,这篇当作是对 Scheme 语言的介绍,毕竟全书是用这门语言写的。

下面是我对书中使用的 mit-scheme 的一些理解,我没有正统学习过函数式或类 Lisp 语言,只有一些我自己在做这本书习题时的一些理解,文中表述可能不会太专业,请谅解。

Expressions

basic

(+ 1 2)

; 3
复制代码

compound

(* (+ 1 2)
   (+ 3 4))
   
; 21

复制代码

Variables

(define pi 3.14159)
(define radius 10)

(* pi (* radius radius))

; 314.159

复制代码

Procedure

; 定义 square 过程
(define (square x) (* x x))

; 调用 square 过程
(square (square 3))

;81
复制代码

Condition

cond

(define (abs x)
  (cond ((> x 0) x)
        ((= x 0) 0)
        ((< x 0) (- x))))

(abs -42)
; 42

(define (abs x)
  (cond ((< x 0) (- x))
        (else x)))

(abs -42)
; 42

复制代码

比较有趣的是,在 mit-scheme 里,变量,过程等是可以同名的,会选用最后的定义,所以上述代码是完全可以运行的。

if

(define (abs x)
  (if (< x 0)
      (- x)
      x))

(abs -42) 
; 42

复制代码

Logic

;; e Expression

(and <e1> <e2>)

(or <e1> <e2>)

(not <e>)

(and (> x 5) (< x 10))
复制代码

Lambda

无名字 procedure(其他语言也有叫做匿名函数),可作为 procedure 的参数传递,返回。

(define (inc x)
  (+ x 1))

;; 返回一个名字为 double 执行 proc 两次的 lambda
(define (double proc)
  (lambda (x)
    (proc (proc x))))


((double inc) 5)   

; 7
复制代码

Variable binding

let

(let ((x 10)
      (y 5))
  y)

; 5

;; reference binding
(let ((x 10))
  (let ((y (+ x 6)))
    y)) 
    
; 16

;; 用 let 会报错,因为在一个 let expression 里不能引用前面的 bindings
;; 使用 let*
(let ((x 10)
      (y (+ x 6)))
  y)
  
;Unbound variable: x
复制代码

let*

(let* ((x 10)                                                                                                    
       (y (+ x 6)))
  y)

; 16
复制代码

Data Structures

Pairs

(define x (cons 1 2))

(car x)
1

(cdr x)
2
复制代码

List

;; 下面两个等价

(list 1 2 3)

;Value: (1 2 3)
 
;; '() 表示空 list,相当于 nil
(cons 1 (cons 2 (cons 3 '())))

;Value: (1 2 3)
复制代码

Symbol

symbol 是以 ' 开头的字符,是不带语义的变量。

;; define a symbol
'apple

; apple

;; 空 list
'() 

; ()

;; list of symbol
(list 'a 'b 'c) 

; (a b c)

;; 可以简写成
'(a b c)

;(a b c)
复制代码

equal

;; symbol equality
(eq? 'apple 'apple))

; #t

;; return sublist of the list beginning with the first occurrence of the symbol
(memq 'apple '(x (apple sauce) y apple pear)) 

; (apple pear)
复制代码

待续