プログラミングGauche をよむ

とりあえず,.emacs に以下を追加した

(add-hook 'scheme-mode-hook
  '(lambda ()
     (setq indent-tabs-mode nil)
     ))

p56. 練習問題

(define (length lis)
  (define (length-in n lis)
    (cond ((null? lis) n)
          (else (length-in (+ n 1) (cdr lis)))))
  (length-in 0 lis))

(define (filter proc lis)
  (cond ((null? lis) lis)
        ((proc (car lis)) (cons (car lis) (filter proc (cdr lis))))
        (else (filter proc (cdr lis)))))

(define (filter2 proc lis)
  (define (filter-in init proc lis)
    (if (null? lis)
        init
        (filter-in (if (proc (car lis))
                       (cons (car lis) init)
                       init)
                   proc (cdr lis))))
  (reverse (filter-in '() proc lis)))

p68. 練習問題

(use srfi-1)

(define (for-each-numbers proc lis)
  (for-each proc (filter number? lis)))

(define (map-numbers proc lis)
  (map proc (filter number? lis)))

(define (numbers-only walker)
  (lambda (proc lis)
    (walker proc (filter number? lis))))

(define (tree-walk walker proc tree)
  (walker (lambda (elt)
            (if (list? elt)
                (tree-walk walker proc elt)
                (proc elt)))
          tree))

;(tree-walk (numbers-only for-each) print '((1 2 3) #f 4 5 (6 (7 #t 8))))

(define (numbers-only-for-tree walker)
  (lambda (proc lis)
    (walker proc (filter (lambda (x) (or (number? x) (list? x))) lis))))

(tree-walk (numbers-only-for-tree for-each) print 
           '((1 2 3) #f 4 5 (6 (7 #t 8))))

p101.練習問題

; 練習のため,any-pred と every-pred にも挑戦してみてください.

; どれかの述語が満たされる
(define (any-pred . preds)
  (lambda (x)
    (define (any-pred-in preds x)
      (let ((cur ((car preds) x))
            (rest (cdr preds)))
        (if (null? rest)
            cur
            (or cur (any-pred-in rest x)))))
    (any-pred-in preds x)))

; 全部の述語が満たされる
(define (every-pred . preds)
  (lambda (x)
    (define (every-pred-in preds x)
      (let ((cur ((car preds) x))
            (rest (cdr preds)))
        (if (null? rest)
            cur
            (and cur (every-pred-in rest x)))))
    (every-pred-in preds x)))

p112.

; コピーしない delete-1
(use gauche.test)

(define (delete-1 elt lis . options)
  (let-optionals* options ((cmp-fn equal?))
                  (define (loop lis)
                    (cond [(null? lis) lis]
                          [(cmp-fn elt (car lis)) (cdr lis)]
                          [else (let ((rest (loop (cdr lis))))
                                  (if (eq? rest (cdr lis))
                                      lis
                                      (cons (car lis) rest)))]))
                  (loop lis)))

; test
(let ((data (list 1 2 3 4 5)))
  (test* "non-copy delete-1" data (delete-1 6 data) eq?))
  • 名前の最後を! で終わらせる命名方法は,変数やデータ構造を破壊的に変更する操作であることを示すScheme の慣習です.
  • 一般的に,(setf x y) は,「x を評価した値がy になるように処理しておいてくれ」という指示として理解できる.とOn Lisp にあるらしい