Gauche:イディオム
「Schemerの常識は他のプログラマの非常識」という理念に基づき、 実際のプログラムによく出てくる定型を列挙するコーナー。
といいつつ実際なんの役に立つのかわからないけどとりあえずおもしろいから いいやとか、単に笑えるだけの技なんかも集まるといいなあ。 大きいものは別に項目を立てるとして、こっちは10行くらいをメドに。
モデルにしたのはこのへん。
http://www.asahi-net.or.jp/~dp8t-asm/java/idiom/index.html
当面整理しないでただ並べておく。
関連
- Lisp:コメント
- Scheme:コーディングスタイル
- Scheme:!と?(変数名の慣習)
- Scheme:多値
- Scheme:named letの書き方
- Scheme:マクロ:anaphoric ifの代替
- Scheme:リスト処理
- Scheme:テキスト処理
- Gauche:入出力ポートの使い方
- Schematics Scheme Cookbook(一部 PLT Scheme 依存)
何も返さない
(values)
#<undef>を返す
(if #f #f)
- Gaucheでは(undefined)も使えるみたいですが、あえてundocumentedなんでしょうか?2004/12/22 00:50:37 PST
- Shiro(2011/01/09 15:30:40 PST): 今はofficialになっています。GaucheRefj:undefined
#<eof>を返す
(read-from-string "")
- ryoakg2011/01/09 04:47:14 PST (eof-object) というのが途中から入ったので、これを使えばよさそうです。 ChangeLog によると R6RS の関数らしいです。
exprが#fなら#fを、さもなければ#tを返す
(if expr #t #f) ;#fが省略できないことに注意! or (and expr #t) or (not (not expr))
[Guileには->boolという関数が用意されている]
- Shiro(2011/01/09 15:30:40 PST): booleanという関数があります。GaucheRefj:boolean
文字列の連結(最初の2つを除けば文字列以外でもかまわない)
(string-append str1 str2) or (use srfi-13) (string-concatenate (list str1 str2)) or #`",|str1|,|str2|" or (format "~a~a" str1 str2) or (with-output-to-string (lambda () (display str1) (display str2)))
n回の繰り返し
(dotimes (i 10) (print i)) or (use srfi-1) (for-each print (iota 10))
map して filter
(filter values (map proc xs))
or
(use srfi-1) (filter-map proc xs)
thunk をつくる
(cut proc arg)
例:
(call-with-input-file f (lambda (port) (port-map fn (cut read-line port))))
確実に後処理をする
(with-error-handler (lambda (e) (close-output-port port) (raise e)) (lambda () (begin0 (proc port) (close-output-port port))))
これは次のようにも書ける。上のコードに展開される。GaucheRefj:unwind-protect
(unwind-protect (proc port) (close-output-port port))
call/cc を使って proc の dynamic extent に出入りしない場合は以下も同じだけど、 call/ccが使われるかどうかは一般には知り得ない(procから呼んでるライブラリの 中で使われるかもしれない)ので、こういう目的でdynamic-windを使うことは あまりお薦めしない。
(dynamic-wind (cut values #f) (cut proc port) (cut close-output-port port))
手続き間の状態共有
(define func1 #f) (define func2 #f) (let ((shared 1) (variable 2)) (set! func1 (lambda () ...)) (set! func2 (lambda () ...)))
or
(define-values (func1 func2) (let ((shared 1) (variable 2)) (values (lambda () ...) (lambda () ...))))
define-values (var ...) expr なので、internal define は直接つかえない。
(define-values (func1 func2) (define shared 1) (define variable 2) (values (lambda () ...) (lambda () ...))) ; => *** ERROR: Compile Error: malformed define-values ...
let をはさめば大丈夫。
(define-values (func1 func2) (let () (define shared 1) (define variable 2) (values (lambda () ...) (lambda () ...))))
連想リストから値を取りだす
(cond ((assoc key alist) => cdr) (else #f))
or
(and-let* ((pair (assoc key alist))) (cdr pair))
or
(use util.list) (assoc-ref alist key)