識別子の一致規則

今まで、バックエンド無いかなーとかif文できたーとかそんなのばっかでまともにQueenそのものを説明したことは無かったのですが、某記事に影響以下略晴れて許可が以下略と、意味不明な前書きを置いた上で、Queenの識別子の一致規則を説明したいと思います。
ソースコードの見た目を大きく左右するものに、識別子の、推奨の表記と、一致規則があります。

ここで推奨の表記というのはAdaならDo_HogeJavaならdoHogeみたいなものと思ってください。正式な用語は知らんです。Javaのそれは打ち易さではなかなかですが、気持ち悪さもなかなかです。PascalBorlandの推奨はDoHogeですが、処理系や環境で統一されていないのが実際です。BASICは、F-BASIC大好き人間としては全部大文字の区切り文字無しを主張します。VisualBasicはBASICとは認めません。ただしVisualBASIC for MS-DOSはOKです。閑話休題

一致規則は、文字ケースを無視するか厳密比較するか、ハイフンやアンダースコアを取り除くかどうかです。やはり正式な用語は知りません。この規則が緩く設定されていると、表記上はDo_Hogeみたいに区切りがわかるように書かれていても、Doh_Ogeと区別されなかったりします。

言語推奨の表記一致規則単語の境界による差境界情報のロスト
BASIC DOHOGE 文字ケース無視×
C dohoge 厳密 ×
C++ do_hoge厳密 ×
Java doHoge 厳密 ×
(Borland) PascalDoHoge 文字ケース無視×
Ada Do_Hoge文字ケース無視×
Lisp do-hoge文字ケース無視×
Myraid 不明、恐らくdo_hogeまたはDoHoge文字ケースとアンダースコア無視×

EiffelやHaskellRubyなどは文字ケースが意味を持っていますので省きます。
ここで、ソースから区切り情報が失われている言語を考えてください。

doHogeとDoHogeが違う意味になってもよい言語は論外という考え方も良いのですが、doHogeとdohOgeは同じか?という話です。増して、doh_ogeと、わざわざ区切りを入れて書かれているものが、doHogeと同じでいいのでしょうか?

BASICでプログラムに触れPascalで育った私には、文字ケース無視は空気のようなものではありますが、それでも、わざわざ含められている境界情報が考慮されないことには気味が悪いものがあります。具体的にはWPARAM wParam;みたいな宣言をそのまま移植できないあたり。まぁこんなのは型名と変数名に同じ綴りという汚いコードですので通らなくてもよいのですが、これが次の疑問を喚起させます。

果たして、abc defとa bcdefとab cd ef…等で意味が変わる単語列は、本当に存在しないのか?

具体例はさっぱり思いつかないのですが、変数名の衝突を避ける作業を繰り返すうちに、無意識のうちにこの手のパターンを回避するように脳が最適化されてしまっていたりしませんかね…?
そして…こんなの考えてる人はあまりいないかな…。

単語の頭を大文字にするのは確かに見易いが、シフトを押すのは通常打鍵よりもめんどい。

アンダースコアは日英キーボードで位置が変わる。

…よって、私の理想は、Lispのそれだったりします。

また、これから、以下のような予想が導かれます。

わざわざ区切りのために通常の文字よりもずっと打ちにくいにも関わらず苦労して入れている"_"が勝手に除去されてしまうと、万が一それで衝突してしまったときは、きっとものすごい怒りで恨み節たらたらになるだろーなー。

しかし、なるべく表記の揺れは同一視したいのが実際です。

マクロが無い言語でも推奨表記無視して定数全部大文字とかよく見ますし、API等、外部宣言の類をストレス無く使うには、原型のままでインポートして、その言語の表記で使える機能は、必須に思えます。そういう意味ではWindowsAPIやCのライブラリとPascalは、気持ち悪いながらもなかなかに折り合っていけています。しかしAdaは同じ文字ケース無視の言語ではありますがWindowsAPIやCのライブラリはアンダースコアを含みませんのでやや違和感があります。

結論として、境界情報は残したままで、可能な限りの同一視ができれば、それが理想となります。

さてQueenでは、この理想を実現するべく、以下の規則を採用しました。

  • 先頭はアルファベットのみ。二文字目以降は数字とスコア("_", "-")が使える。
  • "_"と"-"は同じ。
  • 小文字または数字から大文字に移るときスコアを補う。
  • 残りは文字ケース無視。なお実装の都合上内部では大文字で記憶します。

これで、以下のように使えます。

  • CreateFile = createFile = create-file (内部名:CREATE_FILE)
  • toUTF8 = To_UTF8 = to-utf8 (内部名:TO_UTF8)
  • int2str = Int2Str = int2-str (内部名INT2_STR)

最後のだけ違和感がありますが、F10とかWin32とかInt64とかDelphi2005とか数字は普通は前のものを修飾していると思うのでこれは使い方が悪いと言ってしまって…いやまあ数字の前にもスコアを補ってやればいい話ではありますが、これは実は今気付いた話で、2002年以降Queenの実装はずっとこんなです。*1今気付いたのは確かですので変えようと思ってます。

誰にも誉めてもらったことはないのですが、単なる文字ケース無視以上の価値は絶対あると思ってますので、これからコンパイラを書くであろう方々で、なんとなく文字ケース無視にしようと思っておられる方は、参考にしていただければ幸いです。
こじつけですがD言語の無意味なラッパーを含まない、というポリシーにも通じるものがあるのではないかと思います。

ところで、UNIXC言語の世界なので大文字小文字を区別して、WindowsというかDOSMicrosoftつまりBASICの世界なので大文字小文字を区別しない、という推測はどこから来たのでしたっけね。

あと、ソース解析ソフトとかIDEとかエラーメッセージでの表示は、宣言位置での表記を使いたいのが本当ですが、現在のQueenの実装は手抜きでオリジナルの表記を覚えてませんので変形後の名前を表示します。

最後に推奨表記ですが、この規則のおかげでかなりの揺れ幅を吸収できますので、境界さえ明確であれば、好きに書け、です。でも折角なのでLisp風推奨、って誰に何を推奨してんだ…。

*1:と、さりげなく年度を書くと、心を満たすことができて大変よろしいです。それ以前に言ってみたこともあるのですが相手にされませんでした。