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))

2008. 8. 6.

CLISP + SDL 연동

몇달간에 뻘짓을 거쳐서 성공했다.. 여기에 그 글을 올린다. -ㅇ-

준비물
  1. asdf
  2. cffi
  3. lispbuilder-sdl류..
여기에 그 찬란한 뻘짓을 올린다.

예전에 emacs + clisp + slime을 연동시켰다.

일단 홈디렉토리를 찾는다.. 내 경우는 D:\util\msys\home 이었다.
이것은 윈도에서 환경변수에 HOME을 등록시켜주면 된다.
해당하는 홈디렉토리에 .emacs를 만들고 거기에 다음과 같이 넣어주면 clisp+slime 연동은 끝!

;; Slime Module + CLISP
    (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)))
필 요한 것은 사실 몇줄 안된다. 상단에 load-path에는 slime이 설치된 곳(slime은 cvs로 설치했다) 을 inferior-lisp-program에는 clisp.exe의 경로를 적어주면 끝이다. 이후 (require 'slime) (slime-setup)은 단순한 실행 셋업이다..

두번째로 clisp에서 asdf설정을 해주어야한다.

(load "d:/util/clisp/asdf/asdf.lisp")
(pushnew "d:/util/clisp/lib/" asdf:*central-registry* :test #'equal)
asdf는 어떻게 설치했느냐고? asdf는 cvs로 설치했다.
그 리고 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.gz
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
darcs도 깔아주었다. 이 놈은 CVS, SVN과 비슷한 놈인거 같은데.. 일단은 설치..

위에 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>
  1. CFFI는 항상 최신버전을 사용하고..
  2. .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))

연습문제 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)

연습문제 3.2

(define (make-monitored f)
  (let ((calls 0))
    (define (mf m)
      (cond ((eq? m 'how-many-calls) calls)
            ((number? m)
             (begin (set! calls (+ calls 1))
                    (f m)))))
    mf))

연습문제 3.2

(define (make-monitored f)
(let ((calls 0))
(define (mf m)
(cond ((eq? m 'how-many-calls) calls)
((number? m)
(begin (set! calls (+ calls 1))
(f m)))))
mf))

연습문제 3.1

(define (make-accumulator n)
  (lambda (a)
    (begin
      (set! n (+ n a))
      n)))