Giter Club home page Giter Club logo

sicp's Introduction

SICP

SICP,一本讲解编程真谛的经典教材。之前上大学期间,陆陆续续看了2遍这本书,无奈都没坚持到底。第一次只看完第一章,第二次只看完前三章。很多习题也没做。

这,是第三次进攻。这个 repo 会记录我在看 SICP 时的习题代码与一些自己的笔记与想法,这么做一方面是给自己查漏补缺,另一方面也为希望对今后阅读 SICP 的人有些许帮助。

为了方便检索,我使用 gitbook 制作了《SICP 读书笔记》电子书,供大家参考。

Why SICP

目标

2016年1月1号之前啃完所有章节与习题!! 失败告终。只完成前三章。

新的一年继续读书计划2016年6月30号前,完成剩下的第四章、第五章。 完成

建议

完完整整看完一本书是一件困难的事,本书更是如此。

这本书的很多内容、习题需要仔细揣摩才能领略其精髓,所以看这本书一定不要心急。 其次,在阅读时,请务必关闭手机上一些社交工具,并预留出至少 1 个小时的完整时间来看,否则我不认为你真的能有所收获。

学习是件很苦的事,大多数人都是三分钟热度,所以如果你觉得看这本书让你很烦躁,不妨出去运动一下,或听一会音乐🎵,第二天接着来。坚持下来,不要放弃,更不要失去对探索编程真谛的好奇心。

以上与所有 SICPer 共勉。

环境准备

工欲善其事必先利其器。下面说下我Mac上的scheme环境:

  • Mac 环境
  • mit-scheme 9.2,我的Mac版本是10.10.2,按照上这个官方scheme后点击图标,闪退,不清楚为什么,我这里直接把MIT:GNU Scheme.app/Contents下的Resources文件夹拷贝出来,并把它加入的PATH中,这样就能够运行了。 mit-scheme screencast
  • 这里安装好的scheme在交互式环境下无法使用方向键,可以通过安装rlwrap解决(brew install rlwrap)之后,用rlwrap mit-scheme启动就可以了。
  • 英文版epub+中文版实体书,计算机的书最好还是看英文原版,我这里买了中文版的实体书,英文版的好贵!不过多看对epub格式支持很好,放手机上看很方便,而且多看支持划词翻译,写笔记,笔记同步Evernote等等,真是太方便了,推荐大家使用。手机屏幕还是太小了,而且很容易分心,Kindle Paperwhite才是真爱,值得拥有💖。
  • mit-scheme直接从文件中读取代码并执行,例如有个文件名为fib.scm的文件,在scheme交互式环境下通过(load "fib.scm")命令就能够执行fib.scm中的代码了。
  • 2.2.4小节用到的图形语言采用Racket实现,这是它的文档
  • 2.4.3小节putget的实现,参考/exercises/02/lib/hash_table.scm

我的初始化环境就是这样了,后面如果有改变我会修改这里的说明。

辅助资料

QQ 群

欢迎在读或打算读 SICP 的朋友加入 SICP 读书 QQ 群:119845407,让我们一起探索编程的奥妙。

sicp_qq

手机 QQ 可直接扫码加入。

Timeline

  • 2015-5-17 第三次开启SICP之旅
  • 2015-7-12 结束第一章,构造过程抽象。我的总结
  • 2015-9-20 结束第二章,构造数据抽象。我的总结
  • 2015-12-26 结束第三章,模块化、对象和状态。我的总结
  • 2016-04-23 结束第四章,元语言抽象。我的总结
  • 2016-05-21 结束第五章,寄存器机器里的计算。我的总结

License

sicp's People

Contributors

johnnylai avatar liweinan0423 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sicp's Issues

README.md/辅助资料: MIT-OCW 6.001 的讲课笔记与线上教程作为辅助资料也不错啊


P.S.

线上教程的习题部分不错,难度低于 SICP 的习题,大部分可以自动批改(选择题除外);个人感觉这种即时反馈很能增加信心和成就感。

如果先刷线上习题,之后再推 SICP,应该能缓和总体的难度曲线(;同步进行应该也不错)。

习题3.62

div-series应该求任何两个级数,您的代码只能求分母的常数项是1的情况。
我的代码:
; 假设X= S1 / S2
; X = S1 * (1 / (S2 / c)) * (1 / c) (c是S2的常数项)

(define (div-series s1 s2)
(let ((c (stream-car s2)))
(if (= c 0)
(error "The series in the denominator has 0! constant terms")
(scale-stream (mul-series s1
(reciprocal-series (scale-stream s2 (/ 1 c))))
(/ 1 c)))))

(define tan-series (div-series sine-series cosine-series))
;(display-top10 tan-series)
;0 1 0 1/3 0 2/15 0 17/315 0

3.31

你好,参考了你3.31习题的解答。这里想探讨一下。

我觉得你对half adder例子中inverter的分析是对的,不过加(proc)的原因我觉得措辞可以改一下。原因准确说不应该是让input不变的时候改变output,而是初始化的时候确保output会有正确的值。这里有一个初始化的限定,因为after-delay只是被调用了一次而已。

4.4

(define (eval-or exp env)
  (if (null? exp)
    true
    (or (eval (car exp) env)
        (eval-or (cdr exp) env))))

应该为

(define (eval-or exp env)
  (if (null? exp)
    false
    (or (eval (car exp) env)
        (eval-or (cdr exp) env))))

后面实现为派生表达式,我认为应该为

(define (eval-and exp env)
    (make-if (null? exp)
        true
        (make-if (car exp)
            (eval-add (cdr exp) env)
            false)))

但是,我感觉用派生表示式的话,就没有短路效果了!

你好请教一个关于练习3.17的问题

我发现,如果将代码

(define (count-pairs x)
  (if (not (pair? x))
    0
    (if (seen? x) 
      0
      (begin
        (set! already-seen (cons x already-seen)) ;;;修改这里
        (+ (count-pairs (car x))
           (count-pairs (cdr x))
1)))))

修改为

(define (count-pairs x)
  (if (not (pair? x))
    0
    (if (seen? x) 
      0
      (begin
        (set! already-seen (cons already-seen x))
        (+ (count-pairs (car x))
           (count-pairs (cdr x))
1)))))

就得不到正确答案了,而且如果表成环的话也会无限递归
这是为什么

我的环境是win10 64位 DrRacket
在github上不知道如何将代码格式化,抱歉了

2.83

2.83
感觉, 像

(define (raise scheme-number)
    (make-rational x 1))

应该放在 install-rational-package 包中

习题1.30错误

sum-iter的body部分多了一层括号,应为:

(define (sum term a next b)
  (define (sum-iter a result)
    (if (> a b)
        result
        (sum-iter (next a) (+ result (term a)))))
  (sum-iter a 0))

4.11 add-binding-to-frame!

您好
练习4.11 的add-binding-to-frame! 我觉得你实现错了
(define (add-binding-to-frame! var val frame) (cons (cons var val) frame))

这里不应该是简单的返回一个新的frame,而是要修改原来的frame

(define (add-binding-to-frame! var val frame)
  (let ((old-car (car frame)))
    (set-car! frame (cons var val))
    (set-cdr! frame (cons old-car (cdr frame)))))

;;test
(let ((frame (make-frame '(a b c) '(1 2 3))))
  (add-binding-to-frame! 'd 4 frame)
  (display frame))

2.57代码不能对乘0和乘1操作进行化简,还产生了加号或乘号之后只有一个操作数的情况

我的不成熟的代码:
;重新定义make-sum过程,接受参数列表, 并整合成一个和式
(define (make-sum . items)
(define (iter result x)
(if (null? x)
result
(let ((first (car x)))
(if (=number? first 0)
(iter result (cdr x))
(iter (append result (list first))
(cdr x))))))
(let ((add (iter '() items)))
(if (null? (cdr add))
(car add)
(append '(+) add))))
;重新定义过程make-product, 接受参数列表, 并整合成一个乘式
(define (make-product . items)
(define (iter result x)
(if (null? x)
result
(let ((first (car x)))
(cond ((=number? first 0) (list 0))
((=number? first 1)
(iter result (cdr x)))
(else (iter (append result (list first))
(cdr x)))))))
(let ((mul (iter '() items)))
(if (null? (cdr mul))
(car mul)
(append '(*) mul))))

你好, 请教一下, 环境问题

恩, 我看你 3.50 习题里面是直接(load "lib/stream.scm")
想问下, 怎么设置成相对路径加载
我目前每次都要(load "~/sicp/xxx/xxx.scm") 感觉比较繁琐--> 虽然就多几个字符
谢谢

1.28.scm的题解有问题

sicp/exercises/01/1.28.scm

"1取模n的非平凡平方根",也就是说,是不是存在不等于1或者n-1的数,其平方取模n等于1。

你的代码没判断不等于1和n-1。

练习2.11的答案错了

习题2.11上,明确说了每种情况所需要的乘法不超过两次。但是答案中,当两个区间都横跨0轴的时候,计算了4次乘法。

习题 2.11 的 clojure 版本答案

(defn mul-interval-v1 [x y]
  (if (neg? (lower-bound x))
    (if (neg? (lower-bound y))
      (if (neg? (upper-bound x))
        (if (neg? (upper-bound y))
          ;;xl<0 xu<0 yl<0 yu<0
          (make-interval (* (upper-bound x) (upper-bound y))
                         (* (lower-bound x) (lower-bound y)))
          ;;xl<0 xu<0 yl<0 yu>0
          (make-interval (* (min (lower-bound x)
                                 (lower-bound y)) (upper-bound y))
                         (* (lower-bound x) (lower-bound y))))
        (if (neg? (upper-bound y))
          ;;xl<0 xu>0 yl<0 yu<0
          (make-interval (* (upper-bound x) (min (lower-bound y)
                                                 (lower-bound x)))
                         (* (lower-bound x) (lower-bound y)))
          ;;xl<0 xu>0 yl<0 yu>0
          (make-interval (* (min (lower-bound x)
                                 (lower-bound y))
                            (max (upper-bound x)
                                 (upper-bound y)))
                         (* (max (lower-bound x)
                                 (lower-bound y))
                            (min (upper-bound x)
                                 (upper-bound y))))))
      (if (neg? (upper-bound x))
        ;;xl<0 xu<0 yl>0 yu>0
        (make-interval (* (lower-bound x) (upper-bound y))
                       (* (upper-bound x) (lower-bound y)))
        ;;xl<0 xu>0 yl>0 yu>0
        (make-interval (* (lower-bound x) (upper-bound y))
                       (* (upper-bound x) (upper-bound y)))))
    (if (neg? (lower-bound y))
      (if (neg? (upper-bound y))
        (make-interval (* (lower-bound y) (upper-bound x))
                       (* (upper-bound y) (lower-bound x)))
        ;; xl>0 xu>0 yl<0 yu>0
        (make-interval (* (lower-bound y) (max (upper-bound x)
                                               (upper-bound y)))
                       (* (upper-bound x) (upper-bound y))))
      ;; xl>0 xu>0 yl>0 yu>0
      (make-interval (* (lower-bound x) (lower-bound y))
                     (* (upper-bound x) (upper-bound y))))))

由于没有 scheme 写所以就当一个补充了

4.9

while 的实现你没有写完,一次就停了:

(define (expand-predicate predicate i body)
  (if (predicate i)
    (cons 'begin body)))

(define (while->combination exp)
  (expand-predicate
    (while-predicate exp)
    (while-variable exp)
    (while-body exp)))

此外,for的实现我有疑问:

(define (expand-range start end proc)
  (cond
    ((< start end)
      (proc start)
      (expand-range (+ start 1) end proc))))

在这里面 (proc start)的求值需要环境吧?
是否需要写成这样?

(define (expand-range start end proc env)
  (cond
    ((< start end)
      (eval (lambda () (proc start)) env)
      (expand-range (+ start 1) end proc env)))

[sicp 3.76]

(define (make-zero-crossings input-stream smooth)
  (define (iter s last-value)
    (cons-stream (sign-change-detector (stream-car s) last-value)
                 (iter (stream-cdr s) (stream-car s))))
  (iter (smooth input-stream)))

iter 是双参吧

exercises/01/1.31.scm line 31

;(b)
(define (product2 a term b next)
(define (iter a result)
(if (> a b)
result
((iter (next a) (* (term a) result))))
(iter a 1))

2.87 关于多项式=zero?函数

(define (install-polynomial-package) 
  ;; ... 
  (put '=zero? 'polynomial 
    (lambda(poly) 
      (or (empty-termlist? (term-list poly))
          (= 0 (first-term (coeff (term-list poly)))))))
  'done)

应该不能只判断最高项的系数,而且如果想获得更好的抽象能力的话使用=zero?代替= 0应该会更好,(coeff (term-list poly))应该也有错

下面是我自己写的

(define (install-polynomial-package) 
...
 (define (=zero? poly) 
   (define (zero-terms? termlist) 
     (if (empty-termlist? termlist)
         true 
         (and (=zero? (coeff (first-term termlist))) 
              (zero-terms? (rest-terms termlist))))) 
   (zero-terms? (term-list poly))) 

(put '=zero '(polynomial) =zero?)
...
)

2.87----------

如果有错的话,欢迎大家纠正

3.66 to think in slowing clock

for the first pair procedure, you have a clock tick in normal speed
for the second pair procedure, 2 times slower
3: 4 times slower per tick
n: 2^(n-1) n s p t

then to get to the next pair procedure,
you have to take two step, per step is going to be a tick of a clock in that pair pro's world.
so you get total time of getting to (n, 1)'s location.
(n, 1):2^n - 1

then you consider walk to the other direction,
walk to (n, m) from (n, 1):
you get that it take one step to (n, 2)
and two step each to the next.
then you have every thing you get.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.