学习scheme的笔记

1 . write *.ss file with you editor
reciprocal.ss file:

define reciprocal
  (lambda (n)
    (if (= n 0)
        "oops!"
        (/ 1 n))))

2 . start petite and use reciprocal procedure

 (load "~/scheme/reciprocal.ss")
> (reciprocal 0)
"oops!"
> (reciprocal 2)
1/2

The expressions below are called procedure applications, because they specify the application of a procedure to a set of arguments.

+ 1/2 1/2) --> 1
(- 1.5 1/2) --> 1.0

(* 3 1/2) --> 3/2
(/ 1.5 3/4) --> 2.0 

quote:
we must tell Scheme explicitly to treat a list as data rather than as a procedure application.
We do this with quote.

quote (1 2 3 4 5)) --> (1 2 3 4 5)
(quote ("this" "is" "a" "list")) --> ("this" "is" "a" "list")
(quote (+ 3 4)) --> (+ 3 4) 

Because quote is required fairly frequently in Scheme code, Scheme recognizes a single quotation mark ( ’ ) preceding an expression as an abbreviation for quote.

(1 2 3 4) --> (1 2 3 4)
'((1 2) (3 4)) --> ((1 2) (3 4))
'(/ (* 2 -1) 3) --> (/ (* 2 -1) 3) 

Just as quoting a list tells Scheme to treat a parenthesized form as a list rather than as a procedure application,
quoting an identifier tells Scheme to treat the identifier as a symbol rather than as a variable.
(quote hello)
car returns the first element of a list, and cdr returns the remainder of the list.

let:
The general form of a let expression is:

let ((var expr) ...) body1 body2 ...) 

Scheme treats forms enclosed in brackets just like forms enclosed in parentheses. An open bracket must be matched by a close bracket, and an open parenthesis must be matched by a close parenthesis. We use brackets for let (and, as we’ll see, several other standard syntactic forms) to improve readability, especially when we might otherwise have two or more consecutive open parentheses.

let ([list1 '(a b c)] [list2 '(d e f)])
  (cons (cons (car list1)
              (car list2))
        (cons (car (cdr list1))
              (car (cdr list2))))) --> ((a . d) b . e)

Lambda:
The general form of a lambda expression is

(lambda (var ...) body1 body2 ...) 

((lambda (x) (+ x x)) (* 3 4)) --> 24
(lambda (x) (+ x x)) --> is a procedure, (* 3 4) is the argument of this procedure

(let ([double (lambda (x) (+ x x))])
  (list (double (* 3 4))
        (double (/ 99 11))
        (double (- 2 7)))) <graphic> (24 18 -10)

Here, we establish a binding for double to a procedure, then use this procedure to double three different values. 说白了,lambda就是一个有一个匿名函数,闭包就是一个有上下文的函数。

As mentioned above, the general form of lambda is a bit more complicated than the form we saw earlier, in that the formal parameter specification, (var …), need not be a proper list, or indeed even a list at all. The formal parameter specification can be in any of the following three forms:
a proper list of variables, (var1 … varn), such as we have already seen,
a single variable, varr, or
an improper list of variables, (var1 … varn . varr).

(let ([f (lambda x x)])
  (f 1 2 3 4)) --> (1 2 3 4) #second case

(let ([f (lambda x x)])
  (f)) --> () #second case

(let ([g (lambda (x . y) (list x y))])
  (g 1 2 3 4)) --> (1 (2 3 4)) #third case

(let ([h (lambda (x y . z) (list x y z))])
  (h 'a 'b 'c 'd)) --> (a b (c d)) #third case

Top-Level Definitions:

(define double-any
  (lambda (f x)
    (f x x)))

(define double-int
  (lambda (x)
    (+ x x)))

Conditional Expressions :

(define abs
  (lambda (n)
    (if (< n 0)
        ((- 0 n) 2)
        n))) 

closure:

> (define (foo x) (lambda (y) (* x y)))
> (define t2 (foo 2))
> t2
#<procedure>
> (t2 3)
6
> (t2 4)
8
> (define t10 (foo 10))
> t10
#<procedure>
> (t10 2)
20
> (t10 5)
50

currying:
假设你的函数需要两个参数,第一个是映射函数,第二个是具体的数据,你当然可以定义一个函数来一次性接收两个参数.
你也可以使用currying来包装你的函数,让程序one by one的来处理你的参数. 这只是语言的一种特性,每种特性都有利有弊.注意取舍.

> (define (my-map func)
      (define (map1 ls)                              
          (if (null? ls)                            
              '()
              (cons (func (car ls)) (map1 (cdr ls)))))
      map1)
> (define foo (my-map (lambda (x) (* x x))))
> foo
#<procedure>
> (foo '(1 2 3 4 5))
(1 4 9 16 25)

generator:
闭包的一个应用

> (define (make-odd-gen)   
      (let ((prev-number -1))
          (lambda ()     
              (set! prev-number (+ prev-number 2))
              prev-number)))
> (define gen-odd-num1 (make-odd-gen))
> (gen-odd-num1)
1
> (gen-odd-num1)
3
> (gen-odd-num1)
5
> (define gen-odd-num2 (make-odd-gen))
> (gen-odd-num2)
1
> (gen-odd-num2)
3
> (gen-odd-num2)
5

macro:

(define-syntax m-square
  (syntax-rules ()
    ((_ x) (* x x))))

**[S-exp] - evaluate –> [new s-exp] - evaluate –> return value of macro
macro expand**

the macro name is m-square
(_ x) 会匹配这样的s表达式:(m-square s-exp),所以如果输入是: (m-square (+ 1 2)) ,那么x就是 (+ 1 2),
所以最后宏展开会就是:
(* (+ 1 2) (+ 1 2))

> (define-syntax m-square
    (syntax-rules () 
      ((_ x) (* x x))))
>  (m-square (+ 1 2))
9
> (m-square (begin (display "oops") (+ 1 2)))
oopsoops9

> (define-syntax arithmetic-if
    (syntax-rules ()        
      ((_ test neg zero pos)
       (let ((var test))  
         (cond ((< var 0) neg)
               ((= var 0) zero)
               (else pos))))))
> (arithmetic-if -10 (+ 0 -1) (+ 0 0) (+ 0 1))
                 test neg      zero   pos
-1
> (arithmetic-if 10 (+ 0 -1) (+ 0 0) (+ 0 1))
1
> (arithmetic-if 0 (+ 0 -1) (+ 0 0) (+ 0 1))

macro with identifier:
> (define-syntax my-if                   
    (syntax-rules (then else)           
      ((_ test then e1 else e2) (if test e1 e2))
      ((_ test then e1) (if test e1 #f))
      ((_ test else e1) (if test #f e1))))
> (my-if #t then 'OK else 'NG)
OK
> (my-if #f then 'OK else 'NG)
NG
> (my-if #f then 'OK)
#f
> (my-if #t then 'OK)
OK
> (my-if #t else 'NG)
#f
> (my-if #f else 'NG)
NG

macro recursion:

> (define-syntax my-and                      
    (syntax-rules ()                        
      ((_) #t)
      ((_ a) a)
      ((_ a b ...) (if a (my-and b ...) #f))))
> (my-and)
#t
> (my-and 1)
1
> (my-and 1 2)
2
> (my-and #f)
#f
> (my-and 1 #f)
#f
> (my-and 1 2 #f)
#f

Lazy evaluation:

> (define laz (delay (+ 1 2)))
> laz
#<procedure>
> (force laz)
3
> (* 10 (force laz))
30

http://www.geocities.jp/m_hiroi/func/abcscm10.html
https://www.shido.info/lisp/scheme7.html
http://www.scheme.com/tspl4/start.html#./start:h8

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值