自身のユーティリティ関数が溜ってきたので追加していきます。よければ取り入れて下さい。
(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) ;; オブジェクトの生成と同時に出力
この関数は僕のお気に入りです。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
というよりも、最初の実行の計算結果を保存する関数であるといった方がわかりやすいかも。
(define ones
(lambda (proc)
(let ((call? #f) (result #f))
(lambda args
(if call?
result
(begin (set! result (apply proc args))
(set! call? #t)
result))))))
(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-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"