Lisp 总结

 

基本语法

宏定义
(define pi 3.14)
(define hi "hello")
 
定义一个过程
(define (add a b) (+ a b))
(add 10 20)
 
 
一个序对
(cons 1 2)
(cons 1.1 "aa")
 
定义一个序对
(define x (cons 1 2))
(define y (cons 3 4))
(define z (cons x y))
 
car是Contents of Address part of Register寄存器的地址部分的内容
cdr是Contents of Decrement part of Register寄存器的减量部分的内容
(car (car z))  结果是1
(car (cdr z))  结果是3
 
(define c (cons 11 22))
(define d (cons 33 44))
(define x (cons a b))
(define y (cons c d))
(define z (cons x y))
(((1 . 2) 3 . 4) (11 . 22) 33 . 44)       #z的值
 
# (car z)
((1 . 2) 3 . 4)
 
#(caar z)
(1 . 2)
 
# (caaar z)
1
 
# (cdadr z)   相当于 cdr,car,cdr三个操作,先从cdr开始然后是car最后是cdr
# cdr后就是 (11 . 22) 33 . 44), car后就是(11,22),最后cdr就是22
22
 
# (cddar z)
按照上面的推论结果就是4

#if表达式
(if predicate then_value else_value)

and
or
not
# 条件分支
(define test-age (lambda (age)
  (cond
   ((< age 16) "未成年")
   ((and (> age 16) (< age 28)) "少年先锋队")
   ((and (> age 28) (< age 40)) "成年人")
   ((and (> age 40) (< age 55)) "中年人")
   ((and (> age 55) (< age 70)) "老年人")
   (else "很老的年纪"))
  ))

(test-age 19)

 

let语法

(let ((a 1)
      (b 2))
  (+ a b))

#定义一个lambda再内嵌lambda的函数,其中包含了let定义
(define gg
  (lambda (x)
    (let ((a 10)
          (b 20))
      (lambda (y)
        (let ((c 30)
              (d 40))
          (+ (+ a c) (+ x y)) 
          )))))

(gg 10)
((gg 1) 2)

#结果
3
#<procedure>
43

#实际上,let表达式只是lambda表达式的一个语法糖
(let ((p1 v1) (p2 v2) ...) exp1 exp2 ...)
;⇒
((lambda (p1 p2 ...)
    exp1 exp2 ...) v1 v2)
#let*表达式可以用于引用定义在同一个绑定中的变量。
#实际上,let*只是嵌套的let表达式的语法糖而已。

 

 

 

一些内置的函数

pair? 如果对象为序对则返回#t;
list? 如果对象是一个表则返回#t。要小心的是空表’()是一个表但是不是一个序对。
null? 如果对象是空表’()的话就返回#t。
symbol? 如果对象是一个符号则返回#t。
char? 如果对象是一个字符则返回#t。
string? 如果对象是一个字符串则返回#t。
number? 如果对象是一个数字则返回#t。
complex? 如果对象是一个复数则返回#t。
real? 如果对象是一个实数则返回#t。
rational? 如果对象是一个有理数则返回#t。
integer? 如果对象是一个整数则返回#t。
exact? 如果对象不是一个浮点数的话则返回#t。
inexact? 如果对象是一个浮点数的话则返回#t。

函数quotient用于求商数(quotient)。
函数remainder和modulo用于求余数(remainder)。
函数sqrt用于求参数的平方根(square root)。
三角函数sin,cos,tan,以及反三角函数asin,acos
指数函数exp
对数函数log

引用 quote
(quote (+ a b)) 等于
'(+ a b)

其他一些判断数字的函数
odd?
even?
postitive?
negative?
zero?

在比较字符的时候可以使用
char=?
char<?
char>?
char<=?
char>=?

比较字符串时,可以使用
string=?
string-ci=?

 

递归

(define (fact n)
  (if (= n 1)
      1
      (* n (fact (- n 1)))))
(fact 5)的计算过程如下:

(fact 5)
⇒ 5 * (fact 4)
⇒ 5 * 4 * (fact 3)
⇒ 5 * 4 * 3 * (fact 2)
⇒ 5 * 4 * 3 * 2 * (fact 1)
⇒ 5 * 4 * 3 * 2 * 1
⇒ 5 * 4 * 3 * 2
⇒ 5 * 4 * 6
⇒ 5 * 24
⇒ 120

 

尾递归

(define (fact-tail n)
  (fact-rec n n))

(define (fact-rec n p)
  (if (= n 1)
      p
      (let ((m (- n 1)))
    (fact-rec m (* p m)))))
fact-tail计算阶乘的过程像这样:

(fact-tail 5)
⇒ (fact-rec 5 5)
⇒ (fact-rec 4 20)
⇒ (fact-rec 3 60)
⇒ (fact-rec 2 120)
⇒ (fact-rec 1 120)
⇒ 120

 

 

用let实现循环和递归

let也可以用于递归
(define (fact-let n)
  (let loop((n1 n) (p n))           ; 1
    (if (= n1 1)                    
    p
    (let ((m (- n1 1)))
      (loop m (* p m))))))      ; 2


#letrec类似于let,但它允许一个名字递归地调用它自己。
#语法letrec通常用于定义复杂的递归函数
(define (fact-letrec n)
  (letrec ((iter (lambda (n1 p)
           (if (= n1 1)
               p
               (let ((m (- n1 1)))
             (iter m (* p m)))))))     ; *
    (iter n n)))

 

 

 

Lisp中的继续

#lang racket
(define (product ls)
  (let loop ((list ls) (acc 1))
    (cond
     ((null? list) acc)
     ((zero? (car list)) 0)
     (else (loop (cdr list) (* (car list) acc))
           ))))

(product '(2 4 7))


;另外一种形式
(define (mul list sum)
  (if (null? list) (return sum)
  (* 1 (mul (cdr list) (* (car list) sum)))))
(define (product list) (mul list 1))
(product '(2 4 7))

  

 

 

 

 

 

 

 

利用Racket画图

#lang slideshow
;定义一个填充的矩形,参数n是边长
(define (square n)
  (filled-rectangle n n)
)

;定义一个红色的矩形,将传入的矩形变为红色
(define (red p)
  (colorize p "red")
)

;定义一个黑色的矩形,将传入的矩形颜色变为黑色
(define (black p)
  (colorize p "black")
)

;定义上下左右四个同样的矩形,将传入的矩形按照上下左右做成四个对称的
(define (four p)
  (define two (hc-append p p))
  (vc-append two two)
)

;定义左右反转的四个矩形
(define (c-four p1 p2)
  (let ((x1 (hc-append (red p1) (black p2)))
        (x2 (hc-append (black p2) (red p1))))
        (vc-append x1 x2)
  )
)

; 4*4的矩形
(define (four-four p)
  (four (four p))
)

;4*4 颜色反转的矩形
(define (color-four-four p)
  (four (four (c-four p p)))
 )

;四个连在一起的图形,mk是一个函数
(define (series mk)
 (hc-append 5 (mk 5) (mk 10) (mk 15) (mk 20))  
)

;定义一个a的函数,这个函数跟color-four-four效果一样,只是传入的参数是size整数
(define (a size)
  (color-four-four (square size))
)

;(series a)
;跟上面的表达式执行结果一样,只是做成了一个匿名函数,这里series接受的参数是函数,这里就
;体现出了函数编程的强大
(series (lambda(size) (color-four-four(square size))))

;下面这个表达式也是一样的效果
(series (lambda(size) (four (four (c-four (square size) (square size))))))
执行结果


 

 

 

 

再画一个气泡

#lang slideshow
(define (rgb-series mk)
  (vc-append
   (series (lambda (size) (colorize (mk size) "red")))
   (series (lambda (size) (colorize (mk size) "green")))
   (series (lambda (size) (colorize (mk size) "blue"))))
)

(define (series mk)
 (hc-append 5 (mk 5) (mk 10) (mk 15) (mk 20))

;(series (rgb-maker circle))
(rgb-series circle)
;(series (lambda (size) (colorize (mk size) "red")))
;每一排的红色,绿色,蓝色气泡相当于下面这段
(series
  (lambda(size) (colorize (circle size) "red"))
  )


(define (rgb-maker mk)
  (lambda (sz)
    (vc-append (colorize (mk sz) "red")
               (colorize (mk sz) "green")
               (colorize (mk sz) "blue"))))
 
(series (rgb-maker circle))
;这里将一列当做一个元素 (rgb-maker circle)执行完后就是
(vc-append (colorize (circle size) "red"))
;再把上面的表达式运用到series中,size就是series函数的参数,有点像一列是一个整体

执行结果(第一个图是第一个函数rgb-series执行结果    第二个图是第二个函数rgb-maker的结果)


 

 

 

Schema入门教程          

猜你喜欢

转载自xxniao.iteye.com/blog/2359111
今日推荐