Scheme:!と?
Schemeの名前づけの慣習には、一応こんなのがある。
- a. 破壊的操作を行う手続き、構文には!をつける (set-car! etc)
- a'. !のついた手続きの返り値は未定義(portableには利用できない)
- b. 真偽値を返す手続きには ? をつける
- b'. ?のついた手続きの返り値は真偽の判断のみに使える(#t以外の有用な
値を返すことはあてにできない)
a, bについてはほとんどの場合守られているといえるだろう。
ただ、よりきつい縛りであるa', b' については、srfiやライブラリレベルでは
守られていないこともあり、混乱を生じやすい。
ちょっとまとめてみる。
!の返り値
!の返り値が「利用できてしまう」もの
R5RS的には未定義だが、有用な値を返すもの。
portabilityを失うことを承知の上で使うぶんには構わない。
- set! : Gaucheではセットされた値を返す。他の実装でもそういうものが
あるかも。あまり返り値を使うことはお薦めしないが…
!の返り値を「利用せざるを得ない」もの
srfi-1, srfi-13, srfi-14等で"linear update version"と呼ばれる
!-つき手続きは、規約上「破壊的変更が許されている」という
ものなので、必ずしも引数が破壊的に変更されるとは限らない。
従って、結果を得たいなら必ず返り値を用いる必要がある。
- reverse! (srfi-1)
- append! (srfi-1) : 第一引数が()の場合は、返り値を使わないとリストの
先頭が取れない。
- remove! (srfi-1) : 先頭要素を削除する場合、返り値を使わないとリストの
先頭が取れない。
(MLでの説明)
- sort! (gauche) : 引数に渡した最初の
セルが返り値でも最初のセルに使われるとは限らない。
?の返り値
#f, #t以外を返す?-関数
述語としてもよく使われるが、#f, #t以外を返すために?がついていないもの
つまり、本来の規則(b+b')に忠実なもの
- member, assoc系
- any, every (srfi-1)
その他の記号
/
多くは、withの略。
- call/cc : call-with-current-continuation
- read/ss write/ss (srfi-38) : read-with-shared-structure, write-with-shared-structure
- string-concatenate/shared string-append/shared ... (srfi-13):
これらは -with-shared-string だと思う。
- call/ep : call-with-escape-procedure (一部のScheme実装にあり)
- read/case (Bigloo) : read with case (in)sensitivity
- error/location (Bigloo) : error with location
- process/ports (PLT) : (run) process with ports
単なる区切り記号
- open/rdonly, perm/iruser等 (Chicken) :
フラグ。"open/", "perm/" はただのprefix.
Obscureなもの
- read-string/partial (scsh) : ???
*
bindingのスコープが上から順番である、ということ (起源はlet*か)
- let*
- and-let* (srfi-2)
- let-optionals*, let-keywords* (いくつかの実装に見られる)
- let*-values (srfi-11) : '*' の位置がまぎらわしい
「順番に適用」というニュアンス (これもlet* からの類推だと思う)
- make-directory* create-directory* (Gauche, PLT) : 中間のディレクトリも
「順次」作る、というニュアンス。他のScheme実装では、'*'無しの
make-directoryで最後のディレクトリだけ作るmkdir相当のものがある。
- regexp-replace* (MzScheme): 全てのマッチに対してreplaceを適用
(regexp-replaceは最初のマッチだけreplace)。
- cons* (srfi-1) : (cons a1 (cons a2 ... (cons aN-1 aN) ...)) という具合に
consを適用してくってイメージか。
- list* (多数) : cons* と同機能。但しニュアンスとしては「ちょっとだけ違う」
というほうかもしれない。
手続き版に対するマクロ版で、裸のexpr...をlambdaでくるんでくれるもの
(但し、scshではマクロ版が'*'無し、手続き版が'*'あり、というものが
かなりあって、ややこしい)
- test* (Gauche)
- get-keyword*
汎化
- permutations* combinations* ... (Gauche): 要素の等価性を考慮する
- syntax-case* (MzScheme) : syntax-caseの汎化版
- system*, process* (PLT) : コマンド引数リストを取る版
- lambda*, define* (Guile) : キーワード引数等を指定できる
バリエーション
- call-with-input-file* (PLT) : 制御がprocを脱出したらすぐにportを閉じる
(call/cc再起動でprocを再開することを考慮しない)。
- define* (PLT) : このトップレベル定義の後にのみ見えるグローバル束縛を
作る。let*からの類推?
$
これに関しては特にScheme間でのコンセンサスはなさげ。
Gaucheでは部分適用を表すのに使っている。
- pa$ apply$ map$ for-each$ ...
- member$ find$ find-tail$ any$ every$
- 他たくさん
%
プライベートな手続き。なんとなく、「これは外の人は触っちゃいやーん」という
ニュアンス。Lispの方でよく見る。
- %macroexpand %macroexpand-1 (Gauche)
:
- namespace prefixの区切り。特に、組み込みのnamespace機構を持っていない
Schemeでad hocに使われる。SLIB等。CommonLispのpackageから?
- キーワードの表記。CommonLisp風に前置する ':foo' が多いが、
DSSSLは後置 'foo:' を採用。R5RSではこれらはともに有効なシンボル名となるので、
(おそらく)Guileではそれを嫌ってキーワードを '#:foo' にしている。
|
- CommonLispではシンボルに特殊文字を含めるためのエスケープ記号。
それを採り入れたSchemeも多い。
0, 1, ...
- begin0 (PLT, Gauche): これは、CommonLispのprog1から来てるんだと思う。
(prog1 a b c ...) は a b c ...を順に評価してaの値を返すフォーム。
順に評価するのはSchemeではbegin。だけどいまどきならカウントは0ベースでしょ、
ということで、0になったんだと想像。GaucheはPLTから輸入。
- let1 (Gauche) : 変数をひとつだけbindするから1。
#
特殊文字。r5rsで定義されたもの以外はかなり勝手に使われている。
SchemeCrossReference:Index:punctuation あたり参照。
&
多値を返すときによく使われる。返すのはこれ「と(&)」これな感じ。
- uri-scheme&specific (Gauche)
コンディション型(condition-type)のプレフィクス。
SRFI:35, SRFI:36, R6RSで使われる。
- &serious-condition, &error, &i/o-error など
この問題に関する議論
- vector srfiの議論でこのへんが話題になったような気がする。
見つけたらメモ。Shiro
- sort!の「atom以外」っていうところは予想なんですけど。違ってたらツッコミお願いします。hira
- ちょっと違いました。比較手続きが与えられた場合と与えられない場合で
使われるアルゴリズムが違うためです。詳しくは実装を見てください。
(今の実装がベストでもないんですが)。--Shiro
- もうちょっと広げて、Lisp的な名前の付け方のチュートリアルになってくれると嬉しいです。Lisp系では"&"とか"/"とか平気で使うので、よそから来た人は何事かと思うはず。"*"や"0"にどんなニュアンスがあるのかなんて私にもよくわかりません。begin0の0ってなに? --fuyuki
- 「その他」を設けて、マニュアルから目立つものを拾ってみました(ぐちゃぐちゃで申し訳ないっす)。
*は「ちょっとだけ違う」ていうニュアンスかなぁ。一般的なのは無印で、汎化・特化したものは*とか。%がプライベートっていうのは、どっかで見たことがあったんですけど、忘れちゃいました。私はC,Java風に_を先頭につけてプライベート感を出してますけど、邪道かも。--hira
- 凄い。一夜開けたら綺麗に整理されている。%がプライベートっていうのはnakamuraさんのところで見たのでした。この頭%以外全部exportって私も欲しいです==>Gauche:WishList --hira
- "*"のあたりえらい参考になりました。私もちょっとだけ追加。 --fuyuki
- そういや (lambda (_) ... の"_"がわかんなくて、そういう特殊な構文があるのかと思って調べて回ったこともあったな。初心者はそういうつまらないところではまるのです。 --fuyuki
- "_" と言えば syntax-rules 内にでてくる "..." なんか
秀逸だなぁと感心しました。cut-sea:2004/03/24 04:37:01 PST
- "->"というのもよく使われていますよね
--qawsklp
参考
Last modified : 2012/02/07 08:19:49 UTC