原文件已上传到GitHub: 点这里
本次作业需要racket标准库文档:https://docs.racket-lang.org/
Scheme 大法好
天灭过程式 退C保平安
人在做 天在看 赋值语句留祸患
指针乱用天地灭 赶紧重写保平安
诚心诚念SICP好 Scheme大法平安保
众生都为函数来 现世险恶忘前缘
Scheme弟子说真相 教你编程莫拒绝
早日摆脱面向过程 早日获得新生
上网搜“九评丹尼斯·里奇” 有真相
文章目录
小结
因为这个课的第二部分换成了Racket(看起来和scheme完全一致),所以内容越来越接近sicp了。
所以有很多sicp的经典内容(或者说lisp的优秀特性,但是这部分我觉得这个课讲的更好),比如:
- 赋值语句的
side-effect
- Lisp原生强大的
macro
- 典中典之
lazy evaluation
- 特殊的
procedure
衍生的很有用的streams
set-cdr
,set-car
cons
即procedure
但是同时Racket是一个更加现代并且不断演进的语言,所以有很多sicp中没有提到的feature和技巧。
比如:
let
,let*
,letrec
三种赋值表达式thunk
– 形实转换的procedure
- 使用
[]
进行local bindings
- 一些库函数
Delay and Force
记忆化- 用表进行记忆化递归求解斐波那契数列
Tokenization
Assignment
#lang racket
(provide (all-defined-out)) ;; so we can put tests in a second file
;; put your code below
;; 1
(define (sequence low high stride)
(if (> low high)
null
(cons low (sequence (+ low stride) high stride))))
;; 2
(define (string-append-map xs suffix)
(map (lambda(x)
(string-append x suffix)) xs))
;; 3
(define (list-nth-mod xs n)
(cond [(< n 0) error "list-nth-mod: negative number"]
[(= (length xs) 0) error "list-nth-mod: empty list"]
[#t (car (list-tail xs (remainder n (length xs))))]))
;; 4
(define (stream-for-n-steps s n)
(if (= n 0)
null
(let ([next (s)])
(cons (car next) (stream-for-n-steps (cdr next) (- n 1))))))
;; 5
(define funny-number-stream
(letrec ([helper (lambda (x) (cons (cond [(= 0 remainder x 5) (* -1 x)]
[#t x]) (lambda () (helper (+ 1 x)))))])
(lambda () (helper 1))))
;; 6
(define dan-then-dog
(letrec ([helper (lambda(x) ((let ([tmp (cond [(= x "dog.jpg") "dan.jpg"]
[#t "dog.jpg"])])
cons (tmp) (lambda() (helper(tmp))))))])
(lambda () (helper "dog.jpg"))))
;; 7
(define (stream-add-zero s)
(lambda ()
(let ([pr (s)])
(cons (cons 0 (car pr)) (stream-add-zero (cdr pr))))))
;;8
(define (cycle-lists xs ys)
(letrec ([lenx (length xs)]
[leny (length ys)])
(letrec ([helper (lambda(x) ((let ([tmp1 (remainder lenx x)]
[tmp2 (remainder leny x)])
(cons (cons (car (list-tail xs tmp1)) (car (list-tail ys tmp2)))
(lambda() (helper(+ 1 x)))))))])
(lambda () (helper 1)))))
;;9
(define (vector-assoc v vec)
(letrec ([f (lambda (x)
(if (< x (vector-length vec))
(let ([val (vector-ref vec x)])
(if (and (cons? val) (equal? v (car val)))
val
(f (+ x 1))))
#f))])
(f 0)))
;;10
(define (cached-assoc xs n)
(letrec ([memo (make-vector n #f)]
[index 0])
(lambda (x)
;;如果能在缓存序列中得到
(let ([ans (vector-assoc x memo)])
(if ans
ans
(let ([new-ans (assoc x xs)])
(begin
(vector-set! memo index new-ans)
(set! index (remainder (+ index 1) (vector-length memo)))
new-ans)))))))