<blockquote>(define (solve-2nd f y0 dt)
(define y (integral (delay dy) y0 dt))
(define dy (integral (delay ddy) y0 dt))
(define ddy (stream-map f dy y))
y)</blockquote>
2008. 8. 27.
연습문제 3.77
<blockquote>
(define (integral delayed-integrand initial-value dt)
(cons-stream initial-value
(let ((integrand (force delayed-integrand)))
(if (stream-null? integrand)
the-empty-stream
(integral (delay (stream-cdr integrand))
(+ (* dt (stream-car integrand))
initial-value)
dt)))))</blockquote>
2008. 8. 26.
연습문제 3.64
해당 스트림에서 다음번 얻어지는 값은 cdr중 car한 값 즉, cadr 값이다.
따라서 우선 스트림에서 cadr을 수행하는 stream-cadr을 만든다.
이제 stream-limit을 정의한다.

따라서 우선 스트림에서 cadr을 수행하는 stream-cadr을 만든다.
(define (stream-cadr s)
(stream-car (stream-cdr s)))
이제 stream-limit을 정의한다.
(define (stream-limit s tol)
(if ( < (abs (- (stream-car s) (stream-cadr s)) tol)
(stream-card s)
(stream-limit (stream-cdr tol)))
2008. 8. 25.
2008. 8. 23.
2008. 8. 21.
연습문제 3.48
<blockquote>(define (make-account number balance)
(define (withdraw amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds"))
(define (deposit amount)
(set! balance (+ balance amount))
balance)
(let ((balance-serializer (make-serializer)))
(define (dispatch m)
(cond ((eq? m 'withdraw) withdraw)
((eq? m 'deposit) deposit)
((eq? m 'number) number)
((eq? m 'balance) balance)
((eq? m 'serializer) balance-serializer)
(else (error "Unknown request -- MAKE-ACCOUNT"
m))))
dispatch))
(define (serialized-exchange account1 account2)
(let ((serializer1 (account1 'serializer))
(serializer2 (account2 'serializer)))
(if (< (account1 'number) (account2 'number))
((serializer2 (serializer1 exchange))
account1 account2)
((serializer1 (serializer2 exchange))</blockquote>
account1 account2))))
연습문제 3.47
a.

<blockquote>(define (make-semaphore-mtx maximal)
(let ((count maximal)
(mutex (make-mutex)))
(define (the-sema m)
(cond ((eq? m 'release)
(mutex 'acquire)
(unless (= count maximal)
(set! count (+ 1 count)))
(mutex 'release))
((eq? m 'acquire)
(mutex 'acquire)
(cond
((> count 0)
(set! count (- count 1))
(mutex 'release))
(else
(mutex 'release)
(the-sema 'acquire))))
(else
(error "Unknown request -- " m))))
the-sema))</blockquote>
b.
<blockquote>(define (loop-test-and-set! cell)
(if (test-and-set! cell)
(loop-test-and-set! cell)
'()))
(define (make-semaphore-ts maximal)
(let ((count maximal)
(guard (cons #f '())))
(define (the-sema m)
(cond ((eq? m 'release)
(loop-test-and-set! guard)
(unless (= count maximal)
(set! count (+ 1 count)))
(clear! guard))
((eq? m 'acquire)
(cond
(loop-test-and-set! guard)
((> count 0)
(set! count (- count 1))
(clear! guard))
(else
(clear! guard)
(the-sema 'acquire))))
(else
(error "Unknown request -- " m))))
the-sema))
</blockquote>
연습문제 3.43
세 계정을 각각 a, b, c라고 하고 계정의 잔액을 맞바꾸는 연산을 e-ab, e-bc, e-ca라고 하자.
이 경우 프로세스가 차례대로만 돌아준다면 다음과 같은 순서가 유지된다.
phase 1 e-ab: 20 10 30
phase 2 e-bc: 20 30 10
phase 3 e-ca: 10 30 20
phase 4 e-ab: 30 10 20
phase 5 e-bc: 30 20 10
phase 6 e-ca: 10 20 30
즉 6번의 수행후에는 다시 원래대로 반복된다.
그렇지만 줄세워지지않은 exchange로 변동되는 경우
phase 1의 계산중이라면 아직 10 20 30 순으로 저장되어 있으나 a, b의 차액 -10은 계산이 되어있다고 하고, 바로 phase-3가 끝났다고 하면 금액은 30 20 10 이 된다.
이제 phase 1이 마무리되면 a에서 -10을 빼고 b에 -10을 더해야하므로 40 10 10 이라는 결과가 나온다.
따라서 계정 금액이 무너지게 된다.
다만 계정에서 더하고 뺀 값의 총합은 0이기 때문에 전체 금액의 변화는 없게된다.

이 경우 프로세스가 차례대로만 돌아준다면 다음과 같은 순서가 유지된다.
phase 1 e-ab: 20 10 30
phase 2 e-bc: 20 30 10
phase 3 e-ca: 10 30 20
phase 4 e-ab: 30 10 20
phase 5 e-bc: 30 20 10
phase 6 e-ca: 10 20 30
즉 6번의 수행후에는 다시 원래대로 반복된다.
그렇지만 줄세워지지않은 exchange로 변동되는 경우
phase 1의 계산중이라면 아직 10 20 30 순으로 저장되어 있으나 a, b의 차액 -10은 계산이 되어있다고 하고, 바로 phase-3가 끝났다고 하면 금액은 30 20 10 이 된다.
이제 phase 1이 마무리되면 a에서 -10을 빼고 b에 -10을 더해야하므로 40 10 10 이라는 결과가 나온다.
따라서 계정 금액이 무너지게 된다.
다만 계정에서 더하고 뺀 값의 총합은 0이기 때문에 전체 금액의 변화는 없게된다.
연습문제 3.40
줄세우지 않은 경우는 여러가지가 가능하다.
P1을 모두 계산하고 P2를 계산하는 경우 : 1000000
P2를 계산하고 P1을 계산하는 경우 : 1000000
P1의 계산이 끝난후 P2를 계산하고 P2의 덮어쓰기 이후 P1의 덮어쓰기가 일어나는 경우 100
P1의 계산이 끝난후 P2를 계산하고 P1의 덮어쓰기 이후 P2의 덮어쓰기가 일어나는 경우 1000
P2의 계산이 끝난후 P1을 계산하고 P2의 덮어쓰기 이후 P1의 덮어쓰기가 일어나는 경우 100
P2의 계산이 끝난후 P1을 계산하고 P1의 덮어쓰기 이후 P2의 덮어쓰기가 일어나는 경우 1000
줄세운 겨우에는 P1의 끝나고 P2가 수행되므로 1000000 이 나온다.

P1을 모두 계산하고 P2를 계산하는 경우 : 1000000
P2를 계산하고 P1을 계산하는 경우 : 1000000
P1의 계산이 끝난후 P2를 계산하고 P2의 덮어쓰기 이후 P1의 덮어쓰기가 일어나는 경우 100
P1의 계산이 끝난후 P2를 계산하고 P1의 덮어쓰기 이후 P2의 덮어쓰기가 일어나는 경우 1000
P2의 계산이 끝난후 P1을 계산하고 P2의 덮어쓰기 이후 P1의 덮어쓰기가 일어나는 경우 100
P2의 계산이 끝난후 P1을 계산하고 P1의 덮어쓰기 이후 P2의 덮어쓰기가 일어나는 경우 1000
줄세운 겨우에는 P1의 끝나고 P2가 수행되므로 1000000 이 나온다.
연습문제 3.38
a.
Peter, Paul, Mary -> 45
Peter, Mary, Paul -> 35
Mary, Peter, Paul -> 40
Mary, Paul, Peter -> 40
Paul, Peter, Mary -> 45
Paul, Mary, Peter -> 50
b. Peter가 실행해서 일단 balance를 110으로 계산한다. 다음에 Pault은 이전 balance 100을 가지고 해당 값을 80으로 맞춘다. paul의 프로세스가 balance를 110으로 맞춘다. 마지막으로 mary가 값을 55로 맞춘다. 이런 시나리오가 가능하다.

Peter, Paul, Mary -> 45
Peter, Mary, Paul -> 35
Mary, Peter, Paul -> 40
Mary, Paul, Peter -> 40
Paul, Peter, Mary -> 45
Paul, Mary, Peter -> 50
b. Peter가 실행해서 일단 balance를 110으로 계산한다. 다음에 Pault은 이전 balance 100을 가지고 해당 값을 80으로 맞춘다. paul의 프로세스가 balance를 110으로 맞춘다. 마지막으로 mary가 값을 55로 맞춘다. 이런 시나리오가 가능하다.
2008. 8. 20.
연습문제 3.35
(define (squarer a b)
(define (process-new-value)
(if (has-value? b)
(if (< (get-value b ) 0)
(error "square less than 0 -- SQUARER" (get-value b))
(set-value! a (sqrt (get-value b)) me))
(if (has-value? a)
(set-value! b (square (get-value a)) me) )))
(define (process-forget-value)
(forget-value! a me)
(forget-value! b me))
(define (me request)
(cond ((eq? request 'I-have-a-value)
(process-new-value))
((eq? request 'I-lost-my-value)
(process-forget-value))
(else
(error "Unknown request -- SQUARER" request))))
(connect a me)
(connect b me)
me)
(define (process-new-value)
(if (has-value? b)
(if (< (get-value b ) 0)
(error "square less than 0 -- SQUARER" (get-value b))
(set-value! a (sqrt (get-value b)) me))
(if (has-value? a)
(set-value! b (square (get-value a)) me) )))
(define (process-forget-value)
(forget-value! a me)
(forget-value! b me))
(define (me request)
(cond ((eq? request 'I-have-a-value)
(process-new-value))
((eq? request 'I-lost-my-value)
(process-forget-value))
(else
(error "Unknown request -- SQUARER" request))))
(connect a me)
(connect b me)
me)
2008. 8. 14.
연습문제 3.30
(define (ripple-carry-adder lista listb lists c)
(let ((lc '()))
(define (inner-ripple la lb ls ck)
(if (null? la)
'ok
(begin
(let ((cout (make-wire)))
(full-adder (car la) (car lb) ck (car ls) cout)
(append cout lc)
(inner-ripple (cdr la) (cdr lb) (cdr ls)) cout))))
(inner-ripple lista listb lists c)))
뒤쳐지는 시간을 논리곱, 논리합, 인버터 시간으로 표현하면..
inner-ripple은 모두 n번 호출되므로 full-adder 역시 n번 호출된다.
full-adder는 2개의 half-adder와 하나의 논리합으로 구성되어있다.
half-adder는 두개의 논리곱, 하나의 논리합, 하나의 인버터로 구성되어 있다.
따라서 full-adder는 네개의 논리곱, 세개의 논리합, 하나의 인버터 만큼 시간지연이 발생한다.
그러므로 ripple-carry-adder는 총 4n 논리곱 + 3n 논리합 + n인버터 지연시간이 필요하게된다.
연습문제 3.29
드 모르강의 법칙에 따라 P v Q = (~ (~ P ^ ~Q))와 같으므로..
와 같이 정의할 수 있다.
이때 발생하는 delay는 and-gete-delay + (3 * inverter-delay) 와 같다.

(define (or-gate a1 a2 output)
(let ((na1 (make-wire))
(na2 (make-wire))
(nand (make-wire)))
(inverter a1 na1)
(inverter a2 na2)
(and-gate na1 na2 nand)
(inverter nand output)))
와 같이 정의할 수 있다.
이때 발생하는 delay는 and-gete-delay + (3 * inverter-delay) 와 같다.
연습문제 3.28
(define (or-gate a1 a2 output)
(define (or-action-procedure)
(let ((new-value (logical-or (get-signal a1) (get-signal a2))))
(after-delay or-gate-delay
(lambda ()
set-signal! output new-value))))
(add-action! a2 or-action-procedure)
(add-action! a1 or-action-procedure)
'ok)
2008. 8. 13.
연습문제 3.27
memorize가 호출되면 새로운 환경이 생성된다.
이 환경에서 table이 구성되며, 테이블에 넘겨진 인자 n과 다른 값이 들어오면 기존의 factorial lambda연산을 수행하고 그렇지 않은 경우에는 테이블을 lookup 하게 된다.
memo- fib를 (memorize fib)로 변경한 경우 fib자체가 memo-fib에 의해 정의되지 않기때문에 이전에 테이블에 저장되지 않은 값의 경우 이전처럼 지수비례로 자라난다. 물론 이전에 계산한 데이터의 경우에는 테이블에서 lookup하여 찾을 수 있다.

이 환경에서 table이 구성되며, 테이블에 넘겨진 인자 n과 다른 값이 들어오면 기존의 factorial lambda연산을 수행하고 그렇지 않은 경우에는 테이블을 lookup 하게 된다.
memo- fib를 (memorize fib)로 변경한 경우 fib자체가 memo-fib에 의해 정의되지 않기때문에 이전에 테이블에 저장되지 않은 값의 경우 이전처럼 지수비례로 자라난다. 물론 이전에 계산한 데이터의 경우에는 테이블에서 lookup하여 찾을 수 있다.
2008. 8. 12.
연습문제 3.24
(define false #f)
(define (make-table same-proc)
(let ((local-table (list '*table*)))
(define (assoc key records)
(cond ((null? records) false)
((same-proc key (caar records)) (car records))
(else (assoc key (cdr records)))))
(define (lookup key-1 key-2)
(let ((subtable (assoc key-1 (cdr local-table))))
(if subtable
(let ((record (assoc key-2 (cdr subtable))))
(if record
(cdr record)
false)))))
(define (insert! key-1 key-2 value)
(let ((subtable (assoc key-1 (cdr local-table))))
(if subtable
(let ((record (assoc key-2 (cdr subtable))))
(if record
(set-cdr! record value)
(set-cdr! subtable
(cons (cons key-2 value)
(cdr subtable)))))
(set-cdr! local-table
(cons (list key-1
(cons key-2 value))
(cdr local-table)))))
'ok)
(define (dispatch m)
(cond ((eq? m 'lookup-proc) lookup)
((eq? m 'insert-proc!) insert!)
(else (error "Unknown operator -- TABLE" m))))
dispatch))
연습문제 3.23
Deque 문제는 양방향 링크 리스트로 푼다.

(define (make-deque) (cons '() '()))
(define (front-ptr deque) (car deque))
(define (rear-ptr deque) (cdr deque))
(define (set-front-ptr! deque item) (set-car! deque item))
(define (set-rear-ptr! deque item) (set-cdr! deque item))
(define (empty-deque? deque) (null? (front-ptr deque)))
(define (front-deque deque)
(if (empty-deque? deque)
(error "Empty deque")
(cadr (front-ptr deque))))
(define (rear-deque deque)
(if (empty-deque? deque)
(error "Empty deque")
(cadr (rear-ptr deque))))
(define (front-insert-deque! deque item)
(let ((ele (list '() item '())))
(cond ((empty-deque? deque)
(begin
(set-front-ptr! deque ele)
(set-rear-ptr! deque ele)))
(else
(begin
(set-car! (cddr ele) (front-ptr deque))
(set-car! (front-ptr deque) ele)
(set-front-ptr! deque ele))))))
(define (rear-insert-deque! deque item)
(let ((ele (list '() item '())))
(cond ((empty-deque? deque)
(begin
(set-front-ptr! deque ele)
(set-rear-ptr! deque ele)))
(else
(begin
(set-car! ele (rear-ptr deque))
(set-car! (cddr (rear-ptr deque)) ele)
(set-rear-ptr! deque ele))))))
(define (front-delete-deque! deque)
(cond ((empty-deque? deque)
(error "Empty queue " deque))
(else
(begin
(set-front-ptr! deque (caddr (front-ptr deque)))
(set-car! (car (front-ptr deque)) '())))))
(define (rear-delete-deque! deque)
(cond ((empty-deque? deque)
(error "Empty queue " deque))
(else
(begin
(set-rear-ptr! deque (car (rear-ptr deque)))
(set-car! (cddr (rear-ptr deque)) '())))))
(define (print-deque deque)
(define (print-dl double-list)
(if (null? double-list)
(display "")
(begin
(display (cadr double-list))
(print-dl (caddr double-list)))))
(cond ((empty-deque? deque) (display ""))
(else
(print-dl (front-ptr deque)))))
연습문제 3.22
(define (make-queue)
(let ((front-ptr '())
(rear-ptr '()))
(define (set-front-ptr! item)
(set! front-ptr item))
(define (set-rear-ptr! item)
(set! rear-ptr item))
(define (empty-queue?)
(null? front-ptr))
(define (insert-queue! item)
(let ((new-pair (cons item '())))
(cond ((empty-queue?)
(set-front-ptr! new-pair)
(set-rear-ptr! new-pair))
(else
(set-cdr! rear-ptr new-pair)
(set-rear-ptr! new-pair)))))
(define (delete-queue!)
(cond ((empty-queue?)
(error "DELETE! called with an empty queue"))
(else
(set-front-ptr! (cdr front-ptr)))))
(define (print-queue)
(display front-ptr))
(define (dispatch m)
(cond ((eq? m 'insert-queue!) insert-queue!)
((eq? m 'empty-queue?) empty-queue?)
((eq? m 'print-queue) print-queue)
((eq? m 'delete-queue!) delete-queue!)
(else
(error "Unknown request -- MAKE-QUEUE" m))))
dispatch))
연습문제 3.21
Ben은 queue가 리스트를 가르키는 pair임을 잊고 이다. queue는 car에는 리스트의 가장 앞을, cdr에는 리스트의 가장 뒤를 가르키고 있기때문에 실제 출력을 한다면 해당하는 리스트 전체와, 가장 뒤 요소를 동시에 출력하게 된다.
front-ptr 로 얻어진 리스트는 해당하는 queue 전체의 내용과 동일하므로 다음과 같이 print-queue를 만들 수 있다.

front-ptr 로 얻어진 리스트는 해당하는 queue 전체의 내용과 동일하므로 다음과 같이 print-queue를 만들 수 있다.
(define (print-queue queue)
(cond ((empty-queue? queue) (display ""))
(else
(display (front-ptr queue)))))
2008. 8. 11.
2008. 8. 7.
연습문제 3.5
((define (monte-carlo trials experiment)
(define (iter trials-remaining trials-passed)
(cond ((= trials-remaining 0)
(/ trials-passed trials))
((experiment) (iter (- trials-remaining 1) (+ trials-passed 1)))
(else (iter (- trials-remaining 1) trials-passed))))
(iter trials 0))
(define (random-in-range low high)
(let ((range (- high low)))
(+ low (random range))))
(define (square-area x1 y1 x2 y2)
(let ((width (- x2 x1))
(height (- y2 y1)))
(* width height)))
(define (estimate-integral p x1 y1 x2 y2 trials)
(let ((test
(lambda ()
(p (random-in-range x1 x2)
(random-in-range y1 y2)))))
(* (square-area x1 y1 x2 y2)
(monte-carlo trials test))))
(define (square x) (* x x))
(define (P rx ry)
(<= (+ (square (- rx 5)) (square (- ry 7))) 9))

(define (iter trials-remaining trials-passed)
(cond ((= trials-remaining 0)
(/ trials-passed trials))
((experiment) (iter (- trials-remaining 1) (+ trials-passed 1)))
(else (iter (- trials-remaining 1) trials-passed))))
(iter trials 0))
(define (random-in-range low high)
(let ((range (- high low)))
(+ low (random range))))
(define (square-area x1 y1 x2 y2)
(let ((width (- x2 x1))
(height (- y2 y1)))
(* width height)))
(define (estimate-integral p x1 y1 x2 y2 trials)
(let ((test
(lambda ()
(p (random-in-range x1 x2)
(random-in-range y1 y2)))))
(* (square-area x1 y1 x2 y2)
(monte-carlo trials test))))
(define (square x) (* x x))
(define (P rx ry)
(<= (+ (square (- rx 5)) (square (- ry 7))) 9))
2008. 8. 6.
CLISP + SDL 연동
몇달간에 뻘짓을 거쳐서 성공했다.. 여기에 그 글을 올린다. -ㅇ-
준비물
예전에 emacs + clisp + slime을 연동시켰다.
일단 홈디렉토리를 찾는다.. 내 경우는 D:\util\msys\home 이었다.
이것은 윈도에서 환경변수에 HOME을 등록시켜주면 된다.
해당하는 홈디렉토리에 .emacs를 만들고 거기에 다음과 같이 넣어주면 clisp+slime 연동은 끝!
두번째로 clisp에서 asdf설정을 해주어야한다.
그 리고 asdf:*central-registry*를 설정했는데 이상하게 asdf.lisp과 같은 디렉에 있으면 뻑나길래 걍 다른 디렉토리 만들어 설치했다. 이 내용으로 HOME 디렉토리(D:\util\msys\home)에다가 .clisprc파일을 만들어 그 안에다 넣는다.
세번째 CFFI를 설치한다.
CFFI는 일단 최신 버전을 설치해주었다.
또한 여기에 의존이 걸린 Bebel, alexandria, trivial-features를 설치한다.
위에 4개의 모듈을 모두 d:/util/clisp/lib/ 에 풀어주었다.
네번째 lispbuilder-sdl을 설치한다.
일단 몰라서 lispbuilder-sdl관련 패키지는 모두 깔았다.
http://lispbuilder.sourceforge.net/ 에 가면 별에 별 패키지가 다 있다.
또 SDL을 설치한다. 혹시 SDL설치하기 짜증난다면 위에 사이트에서 windows binaries가 있다. 해당하는 패키지도 모두 받아서 설치하자.
마지막, 즐거운 시동
시 동에 앞서서.. 모든 모듈안에 들어있는 .asd 파일을 일단 단축 아이콘을 만들어 d:/util/clisp/lib/ 에 넣는다. 이름은 원래 파일명과 동일하게 모두 바꿔준다. 리눅스에서 ln을 통해서 링크 만들어준다고 하면 된다.

준비물
- asdf
- cffi
- lispbuilder-sdl류..
예전에 emacs + clisp + slime을 연동시켰다.
일단 홈디렉토리를 찾는다.. 내 경우는 D:\util\msys\home 이었다.
이것은 윈도에서 환경변수에 HOME을 등록시켜주면 된다.
해당하는 홈디렉토리에 .emacs를 만들고 거기에 다음과 같이 넣어주면 clisp+slime 연동은 끝!
;; Slime Module + CLISP필 요한 것은 사실 몇줄 안된다. 상단에 load-path에는 slime이 설치된 곳(slime은 cvs로 설치했다) 을 inferior-lisp-program에는 clisp.exe의 경로를 적어주면 끝이다. 이후 (require 'slime) (slime-setup)은 단순한 실행 셋업이다..
(add-to-list 'load-path "d:/util/slime/") ; your SLIME directory
(setq inferior-lisp-program "d:/util/clisp/clisp.exe") ; your Lisp system
(require 'slime)
(slime-setup)
(add-hook 'lisp-mode-hook (lambda() (slime-mode t)))
(add-hook 'inferior-lisp-mode-hook (lambda () (inforior-slime-mode t)))
(autoload 'paredit-mode "paredit"
"Minor mode for psedo-structurally editing Lisp code." t)
(add-hook 'lisp-mode-hook (lambda () (paredit-mode +1)))
두번째로 clisp에서 asdf설정을 해주어야한다.
(load "d:/util/clisp/asdf/asdf.lisp")asdf는 어떻게 설치했느냐고? asdf는 cvs로 설치했다.
(pushnew "d:/util/clisp/lib/" asdf:*central-registry* :test #'equal)
그 리고 asdf:*central-registry*를 설정했는데 이상하게 asdf.lisp과 같은 디렉에 있으면 뻑나길래 걍 다른 디렉토리 만들어 설치했다. 이 내용으로 HOME 디렉토리(D:\util\msys\home)에다가 .clisprc파일을 만들어 그 안에다 넣는다.
세번째 CFFI를 설치한다.
CFFI는 일단 최신 버전을 설치해주었다.
또한 여기에 의존이 걸린 Bebel, alexandria, trivial-features를 설치한다.
http://common-lisp.net/project/cffi/releases/cffi_latest.tar.gzdarcs도 깔아주었다. 이 놈은 CVS, SVN과 비슷한 놈인거 같은데.. 일단은 설치..
http://common-lisp.net/project/babel/releases/babel_latest.tar.gz
darcs get http://common-lisp.net/project/alexandria/darcs/alexandria
darcs get http://common-lisp.net/~loliveira/darcs/trivial-features
위에 4개의 모듈을 모두 d:/util/clisp/lib/ 에 풀어주었다.
네번째 lispbuilder-sdl을 설치한다.
일단 몰라서 lispbuilder-sdl관련 패키지는 모두 깔았다.
http://lispbuilder.sourceforge.net/ 에 가면 별에 별 패키지가 다 있다.
또 SDL을 설치한다. 혹시 SDL설치하기 짜증난다면 위에 사이트에서 windows binaries가 있다. 해당하는 패키지도 모두 받아서 설치하자.
마지막, 즐거운 시동
시 동에 앞서서.. 모든 모듈안에 들어있는 .asd 파일을 일단 단축 아이콘을 만들어 d:/util/clisp/lib/ 에 넣는다. 이름은 원래 파일명과 동일하게 모두 바꿔준다. 리눅스에서 ln을 통해서 링크 만들어준다고 하면 된다.
<span class="br0"></span><blockquote><span class="br0">(</span>asdf:<span class="me1">operate</span> 'asdf:<span class="me1">load</span>-op :<span class="me1">lispbuilder</span>-sdl<span class="br0">)</span></blockquote><span class="br0">
해서 정상적으로 컴파일이 되었다면
</span><span class="br0"></span><blockquote><span class="br0">(</span>asdf:<span class="me1">operate</span> 'asdf:<span class="me1">load</span>-op :<span class="me1">lispbuilder</span>-sdl-examples<span class="br0">)</span></blockquote><span class="br0">
으로 examples를 컴파일하고 실제 예제를 실행시키면 된다.
</span><span class="br0"></span><blockquote><span class="br0">(</span>sdl-examples:<span class="me1">bezier</span><span class="br0">)</span></blockquote><span class="br0">
이상으로 3개월에 걸친 뻘짓을 마친다.
주의해야할 점은..
</span>
- CFFI는 항상 최신버전을 사용하고..
- .ASD의 단축 아이콘을 asdf:*central-registry* 에 포함된 디렉토리에 넣어야한다.
<br /><br />는 점이다.<br />이거 몰라서 <span class="br0">뻘짓한거 생각하면 참 우울하다..</span>
연습문제 3.4
(define (make-account balance password)
(let ((invalid-count 0))
(define (withdraw amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds"))
(define (call-the-cops msg)
(error "Invalid password" msg))
(define (deposit amount)
(set! balance (+ balance amount))
balance)
(define (dispatch pass m)
(cond ((eq? password pass)
(cond ((eq? m 'withdraw) withdraw)
((eq? m 'deposit) deposit)
(else (error "Unknown request -- MAKE-ACCOUNT" m))))
(else
(begin
(set! invalid-count(+ invalid-count 1))
(if (> invalid-count 7)
(call-the-cops "help")
(lambda (x) "Bad Password"))))))
dispatch))

(let ((invalid-count 0))
(define (withdraw amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds"))
(define (call-the-cops msg)
(error "Invalid password" msg))
(define (deposit amount)
(set! balance (+ balance amount))
balance)
(define (dispatch pass m)
(cond ((eq? password pass)
(cond ((eq? m 'withdraw) withdraw)
((eq? m 'deposit) deposit)
(else (error "Unknown request -- MAKE-ACCOUNT" m))))
(else
(begin
(set! invalid-count(+ invalid-count 1))
(if (> invalid-count 7)
(call-the-cops "help")
(lambda (x) "Bad Password"))))))
dispatch))
연습문제 3.3
(define (make-account balance password)
(define (withdraw amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds"))
(define (deposit amount)
(set! balance (+ balance amount))
balance)
(define (dispatch pass m)
(cond ((eq? password pass)
(cond ((eq? m 'withdraw) withdraw)
((eq? m 'deposit) deposit)
(else (error "Unknown request -- MAKE-ACCOUNT" m))))
(else (error "Incorect password" pass))))
dispatch)

(define (withdraw amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds"))
(define (deposit amount)
(set! balance (+ balance amount))
balance)
(define (dispatch pass m)
(cond ((eq? password pass)
(cond ((eq? m 'withdraw) withdraw)
((eq? m 'deposit) deposit)
(else (error "Unknown request -- MAKE-ACCOUNT" m))))
(else (error "Incorect password" pass))))
dispatch)
피드 구독하기:
덧글 (Atom)