keiji


keijiです

自身のユーティリティ関数が溜ってきたので追加していきます。よければ取り入れて下さい。

let$ (副作用を適用し元の値を返す)

(define (let$ val . proc)
  (if (null? proc)
      val
      (begin ((car proc) val)
             (apply let$ val (cdr proc)))))
;; 例

(let$ (make <z> :x 80 :y 20) display) ;; オブジェクトの生成と同時に出力

and=> (xが真であるなら yを適用する)

この関数は僕のお気に入りです。condの代わりやその他様々な場面で使っています。

(define-syntax and=>
  (syntax-rules ()
    ((_ x) x)
    ((_ x y) (and x (y x)))
    ((_ x y . z) (and x (and=> (y x) . z)))))

;; 例

(and=> (assq 'jojo ((jojo . ORA!) ...)) cdr) => ORA!
(and=> (assq 'jojo ((dio . ORA!) ...)) cdr) => #f

ones (一度だけしか実行されない関数)

というよりも、最初の実行の計算結果を保存する関数であるといった方がわかりやすいかも。

(define ones
  (lambda (proc)
    (let ((call? #f) (result #f))
      (lambda args
        (if call?
            result
            (begin (set! result (apply proc args))
                   (set! call? #t)
                   result))))))

keywords-fold (キーワードにfoldをかます)

(define (keywords-fold proc seed keywords)
  (let lp ((seed seed)
           (rest keywords))
    (if (null? rest) seed
        (lp (proc (car rest) (cadr rest) seed)
            (cddr rest)))))

''proc''は''キー''と''対応する値''と''seed''を受け取る

define-enum (C風enum)

(define-syntax define-enum
  (syntax-rules ()
    ((_ (count (id %val)))
     (define-syntax id
       (syntax-rules ()
         ((_) count)
         ((_ 'val) %val))))
    ((_ (count (id val) . rest))
     (begin
       (define-enum (count (id val)))
       (define-enum ((+ count 1) . rest))))
    ((_ ((id val) . rest1) . rest2)
     (define-enum (0 (id val) . rest1)))
    ((_ (count (id val) . rest1) . rest2)
     (begin
       (define-enum (count (id val) . rest1))
       (define-enum . rest2)))))

;; 例

;; HTTP Status Code
(define-enum
  (100
   (HTTP_CONTINUE "Continue")
   (HTTP_SWITCHING_PROTOCOLS "Switching Protocols") ...)
  (200
   (HTTP_OK "OK")
   (HTTP_CREATED "Created")...)
  ...)

(HTTP_OK) => 200
(HTTP_OK 'val) => "OK" 

最終更新 : 2006/09/14 04:54:38 UTC