我在這一章遇到了一個大問題,就是書上用的那些函式 beside, wave, flip-vert 我統統用不了。我用的是 DrRacket 這個軟體,在網上查了半天,終於找到了解決辦法。
首先是官方教程,在 DrRacket 中依次開啟 File -> Package Manager...,在彈出的頁面中 "Do What I Mean" 選單頁的輸入:sicp,回車之後自動安裝就行了。
但是我試了好幾次,總是因為網路問題沒法下載成功,最後求助於 chatgpt 終於解決了。
首先是手動下載 sicp 包到 Racket 安裝目錄,然後開啟 cmd 命令列,輸入raco pkg install ./sicp
即可用本地的 sicp 目錄安裝包。
安裝好之後,重啟 DrRacket 軟體,依次點選上方選單欄的 Language -> Choose Language,在彈出的頁面中,找到 Teaching Languages(ctl-T) 下選擇 SICP(PLaneT 1.18),點選 OK。
再次回到程式碼編輯頁面後,就不需要開頭的 #lang racket 了,直接寫程式碼就行。
還有一點,安裝的 sicp 包裡也是沒有 wave, rogers 的,但是提供了 einstein,所以可以用(define wave einstein)
替換掉或者把書上所有程式碼裡的 wave 都用 einstein 代替。不過直接在檔案裡輸入einstein
或者wave
是看不到圖象的,而是以以 #procedure 的形式存在的,需要用(paint einstein)
顯式地呼叫,這樣就可以看到愛神的頭像了。
Exercise 2.44
Define the procedure up-split used by corner-split. It is similar to right-split, except that it switches the roles of below and beside.
這道題非常的簡單,就像題目所說的那樣,只要交換 below 和 beside 的位置就行。
(paint (right-split wave 1))
(define (up-split painter n)
(if (= n 0)
painter
(let ((smaller (up-split painter (- n 1))))
(below painter (beside smaller smaller)))))
(paint (up-split wave 1))
(define (corner-split painter n)
(if (= n 0)
painter
(let ((up (up-split painter (- n 1)))
(right (right-split painter (- n 1))))
(let ((top-left (beside up up))
(bottom-right (below right right))
(corner (corner-split painter (- n 1))))
(beside (below painter top-left)
(below bottom-right corner))))))
(paint (corner-split wave 1))
(paint (corner-split wave 2))
效果如下圖:
不過這是全新的內容,我覺得最好先理解 below 和 beside 的作用,其實就是字面意思,beside 是把2個圖形左右排列,第一個圖形在左邊;below 是把2個圖形上下排列,但是要注意它是把第二個圖形放在上面,如下圖所示:
(define wave einstein)
(paint (beside wave (below wave wave)))
(paint (below (beside wave wave) wave))