lili对《The Little Schemer - 4th Edition》的笔记(5)

The Little Schemer - 4th Edition
  • 书名: The Little Schemer - 4th Edition
  • 作者: Daniel P. Friedman/Matthias Felleisen
  • 页数: 216
  • 出版社: The MIT Press
  • 出版年: 1995-12-21
  • 第1页
    Chapter -1 TOYS
    Scheme 原文件后缀名一版为scm
    术语:1.atom 2.S-expressions 3.list
    所有的atoms 和 lists 都是S-expressions。
    被括号包围的S-expressions都是list。被括号包围的空S-expressins也是list:()叫做null list。
    The Five Rules The Law of Car: the primitive car is defined only for non-empty lists The Law of Cdr: the primitive cdr is defined only for non-empty lists.The cdr of any non-empty list is always another list. The Law of Cons: The primitive cons takes two arguments. The second argument to cons must be a list. The result is a list. The Law of Null?: the primitive null? is defined only for lists. The Law of Eq?: the primitive eq? takes two arguments. Both of them must be non-numeric atoms. <cons> takes two arguments: the first one is any S-expression; the second one is any list. <atom?>take a argument. The argument can be any S-expression.
    永远不要对一个null list求car,cdr.
    car 返回第一个S-expression. 不一定是list 也有可能是atom
    cdr,cons的结果仍是一个list。
    ((quote ()) 是null list的一种表示。
    cdr 读做“could-er”
    "(cons a l)" 读做“cons the atom a onot the list l"
    2011-06-06 18:32:23 回应
  • 第15页
    Chapter 2 Do it, ....
    (cond ...) 功能为判断,
    (lambda ...) 创建一个函数
    (define ...) 取名字。
    (define lat?
    	(lambda (l)
    			(cond
    			  ((null? l) #t)
    			  ((atom? (car l)) (lat? (cdr l)))
    			  (else #f) ) ) )
    
    
    (or ...) 提两个问题,每次执行一个。如果第一个返回true则不在执行第二个,并返回ture。
    如果不是,则执行第二个并以第二个问题的返回结果为整个or的返回结果。(短路法)
    (rember ...) "Rember" is remove a member.
    (firsts l) 取得一个list l,返回一个由I中每一个内部list的第一个S-expression组成的list。
    Chapter 3 Cons the Magnificent
    The First Commandment: Always ask null? as the first question in expressing any function. The Second Commandment: Use cons to build lists. The Third Commandment: When building a list, describe the first typical element,and then cons is onto the natural recursion. The Fourth Commandment: Always change at least one argument while recurring. It must be changed to be closer to termination. The changing argument must be tested int the termination condition; when using cdr, test termination with null?
    Scheme has a similar construct, a special form called cond. The above example might be written in Scheme as
    (cond (test1
           (action1))
          (test2
           (action2))
          (test3
           (action3))
          (else
           (action4)))
    
    Notice that each test-and-action pair is enclosed in parentheses. In this example, test1 is just a variable reference, not a procedure call, i.e., we're testing to see if the value of the variable test1 is #f; if not, we'll execute (action1), i.e., call the procedure action1. If it is false, control "falls through" to the next test, and keeps going until one of the tests evaluates to a true value (anything but #f).
    Notice that we indent the actions corresponding to a test by one character. This lines the actions up directly under the tests, rather than under the opening parenthesis that groups them together.
    The else clause of a cond is optional; if present, that branch will be taken "by default"---if none of the other conditions evaluates to a true value, the else branch will be taken.
    We don't really need the else clause, because we could get the same effect by using a test expression that always evaluates to a true value. One way of doing this is to use the literal #t, the true boolean, because it's always true.
    (cond (test1
           (action1))
          (test2
           (action2))
          (test3
           (action3))
          (#t            ; literal #t is always true, so
           (action4)))   ; this branch is taken if we get this far
    
    The code above is equivalent to a nested set of if expressions:
    
    (if test1
        (action1)
        (if test2
            (action2)
            (if test3
                (action3)
                (if #t
                    (action4)))))
    
    2011-06-06 23:56:01 回应
  • 第60页
    Chapter 3 Numbers Games
    这一章主要是实现一些基本的算数操作符。
    名词tuple:元组。是一个有序列的一列元素集合。(顺序性)
    对待tuple和对待list时一样的。只不过把((null? lat) quote()) 换成 ((zero? n) 0)
    Commandment - 戒律
    First: When recurring on a list of atomes, lat, ask two questions about it: (null? lat) and else. When recurring on a number, n, ask two questions about it: (zero? n) and else. Second: When building a value with +,always use 0 fro the value of the terminating line, for adding 0 does not change the value of an addition. When building a value with *,always use 1 for the value of the terminating line, for multiplying by 1 does not change the value of a multiplication. When building a value with cons,alway consider null-list for the value of the terminating line.
    2011-06-08 12:11:47 回应
  • 第81页
    Chapter5 Full of Starts.
    Commandment
    When recurring on a list of S-expressions, l, ask three question about it: (null? l), (atom? (car l)), and else. Simplify only after the function correct.
    在(car l) 并不是atom的时候,要同时对(car l) , (cdr l) 递归求值。
    对于-* function 统一模式。
    (define func-name
    	(lambda (new old l)
    			(cond 
    			  ((null? l) (quote ()) /(zero? n) 0) ;; 对于lat用null,对于数字用zero
    			  ((atom? (car l))
    			   (cond
    				 ((eq? a (car l))
    				  (op (func-name a (cdr l))))
    				 (else
    				   (func-name a (cdr l)))))
    			  (else
    				(op (func-name a (car l))
    				      (func-name a (cdr l)))))))
    op为需要的操作。
    
    2011-06-09 10:51:01 回应
  • 第111页
    新手常出现的错误。
    1.程序结构性错误-括号没有正确匹配。导致程序逻辑性错误。如 (cond ...)的分支没有匹配。
    2.操作符前没有以(开头-导致无法执行相应操作。
    3给参数加上了括号. 如(car (lar)).这要常会显示"The object (lat) is not applicable.
    4.拼写错误。
    Chapter 7
    几个函数的功能: fun? :把rel中每个pair的first 提取出来放在一起检测是否为一个set。(各个元素不重复)
    fullfun?:把rel中每个pair的second提取出来放在一起检测是否为一个set。
    Chapter 8 Lambda The Ultimate
    术语:"Currying"--柯里化。是把接收多个参数的函数转变成接受一个单一参数(最初函数的第一个参赛)的函数。把剩下的参数变成一个每次只要一个参数的函数连。最后返回结果。简单来说就是一个单一参数的函数的返回值又是一个单一参数的函数。
    至于为什么要这样,是因为Lambda演算的历史原因
    --http://en.wikipedia.org/wiki/Currying
    e.g.
    (define fun-0 
       (lambda (arg1)
          (lambda (arg2)
            (...))))
    当我们调用(fun-0 arg1)时,fun-0就会返回一个期待arg-2参赛的一个无名函数,这时我们可以提供arg2给他 ((fun-0 arg1) arg2)。以此类推。注意括号的嵌套。
    注:函数eq?-c 在多处使用。定义于P127
    关于multirember-co 函数的具体解释:
    col只有第一次调用是a-friend? ,其他的时候都是那两个匿名函数之一,但是不同在于虽然col的功能肯相同(连续调用同一个匿名函数)但是每次的(car lat)是不同的这样才能构造一个list。要不然,假设匿名函数中的col始终是a-friend? 那么匿名函数中的(car lat)也始终是同一个值,因为col 和 (car lat)都在匿名函数内,没道理col保持不变而(car lat)每回都改变。若假设他俩不变,对multirember-co调用的结果有和假设的冲突。
      
      (define a-frined
       (lambda (x y)
       (null? y)))
      咱们分析一个例子
      (multirember-co 'a '(a b) a-friend)
      1.(null? lat) 不为空
      2(eq? (car lat) a) 相等
      
      要传递的匿名函数fun-1 A类(上面的那个)中col=a-friend (car lat)='a
      
      3递归相当于调用(multirember-co 'a '(b) fun-1)
      4(null? lat) 不为空
      5(eq? (car lat) a) 不想等
      
      要传递的匿名函数fun-2 B类(下面哪个)中col=fun-1 (car lat) ='b
      
      6递归相当于调用(multirember-co 'a '() fun-2)
      7(null? lat) 为空
      8(col '() '()) col=fun-2
      
      我们把这时的(fun-2 '() '()) 展开
      (fun-2 '() '()) -> (col (cons (car lat) '())
       '()) 而fun-2中col=fun-1 (car lat)='b 带入
      =(fun-1 (cons 'b '())
       '()) 我们再把fun-1展开类似于fun-2得到
      (col (cons 'b '())
       (cons (car lat) '())) col=a-friend (car lat)='a 带入得到
      =(a-friend '(b)
       '(cons 'a '()))
      =(a-friend '(b) '(a))
      调用a-friend 我们得到
      (null? '(a)) ->#f
    2011-06-11 23:46:36 回应