言語は何を考えて設計するべきか

↓のような思考の流れもあって、言語をデザインする際に検討すべきポイントを既存の言語を参考に考えてみようか、という一人ブレスト。

これからのプログラミング言語の姿 - Game Scripting Memo
名前推論 - Game Scripting Memo

プログラム意味論やソフトウェア工学などには多くの資料がありますが、こういった言語デザインに関する良書・名論を不勉強なことに存じません。教えていただけるとたいへん嬉しく思います。

なお、日記らしからぬことに、このエントリは思いついたままに追加されていきます。お暇な方はコメント欄や tb でブレストにご参加ください。

  • 動作が速いこと
    • コンパイル可能
      • もしくは JIT コンパイル
      • せめてバイトコード実行
      • eval を入れない
    • 機械語への変換結果をプログラマが把握可能
      • 例:アセンブリ言語・C言語など
      • 抽象化を排除する
      • リッチな組み込み型・動的な型付け・GC などを排除
  • 書くのが速いこと
    • 型宣言不要
      • 動的な型付け
      • 型推論 例: OCaml, Haskell
    • リッチな組み込み型を略記法で使用可能
      • 例: LL 全般
      • 動的な配列
      • 連想配列
    • メモリ管理の自動化
      • GC
      • Linear Type とか (適用可能な範囲が限られますが)
      • プログラマが明示的に、メモリ確保時に、特定の object や tag や scope に生存期間を結びつけるように指定するような、何かクールな言語的仕組み。
    • λ式・無名関数・無名クラス
    • 識別子を手軽に入力できること
      • 名前推論
      • IDE でのコード補完
    • コレクション中のデータにまとめて操作を行うことが簡単に書ける事
      • map とか filter とか。fold だけで満足な人も?
      • ruby のブロック引き数を使った記法。
    • 例外的な処理(まれなエラーなど)用のコードをまとめられること
      • 例外
    • リファクタリング
      • IDE でのサポート
      • リフレクションのサポートですっきり書けることもある
  • いろいろ試すのが簡単なこと
    • お約束なしでいきなり文が書ける
      • そういう言語(Perl など)
      • IDE の機能 例: Eclipse JDT の ScrapBook, Squeak の Workspace
    • one-liner
    • インタプリタ(コンパイル不要)
    • Edit & Continue
      • 例: Visual Studio 2005
  • バグが生まれにくいこと
    • メモリ管理の自動化(再)
    • プログラマが意図を示すことにより、自動的に整合性を確認する仕組み
      • assert
      • 型推論
      • 契約プログラミング 例: Eiffel, D言語
    • 強い型付け
      • 型推論
      • Generics
    • 静的なモデル検査
      • 例: SPIN の Promela ……って実用言語じゃないですね
  • バグを直しやすいこと
    • 充実したデバッガ
    • (そもそも printf デバッグができること ←組み込み系では切実だったり)
  • テストが容易なこと
    • テスティングフレームワークを言語に埋め込む
      • 例: D言語
    • リフレクション
  • 設計がしやすいこと=プログラム構造が読みやすいこと
    • オブジェクト指向
      • 単一継承+インターフェイスがすっきり(個人的意見)
      • オーバーライドするときは明示させるべき (C# の override 修飾子, Java5.0 の @Override アノテーション)
    • mix-in
    • ファイル構造への意味の割り当て
      • Java の 1 ファイル 1 クラスなど
    • MDA (Model Driven Architecture)
    • 関数型言語という選択
      • 与える値と結果の論理的関係を書き下していく
  • コード断片が読みやすいこと
    • 変数かどうかが一見して分かる
      • 例: Perl, PHP などの $ 接頭
      • さらに、区別できたほうがよい型も一見して見分けられる
    • 文脈に依存せず、変数のスコープが分かる
      • 例: ruby の @ など
      • ローカル変数以外には何らかの装飾が付く(this. や self. を強制する)、など
    • どこの誰が呼ばれるのかが一見して分かる
      • 関数のオーバーロードの排除
      • 長い識別子名を標準に採用する
    • コードの見た目を意味に関連付けること
      • 例: Python や Clean のレイアウトによるブロック記述
    • 誰が書いても同じフォーマットになるよう、フォーマットを固定すること
      • 例: 同上
    • 一行一文
      • 文末のセミコロンの除去
      • 例: Python
    • 文の構造のパースに際して脳の負荷が少ないこと
      • レイアウトによるブロック記述(再)
      • 一行一文(再)
      • 十分に改行を入れるコーディング規約
    • 小さなスクリーンでも分かりやすい
  • 大規模なプロジェクトにも耐えられること
    • 独立なモジュールに分割できること
      • 名前空間の分割
      • カプセル化
    • オブジェクト指向(再)
    • 独立したライブラリとして管理可能なこと
    • バージョン管理フレームワーク
      • 例: Perl Module の $VERSION (言語機能ではないですが)
      • 例: .NET のアセンブリ
  • ドキュメント機能
    • ソースコード内にその場でリファレンスを書けること
      • 例: javadoc, doxygen
    • 簡単にドキュメントを引けること
      • 例: IDE のポップアップヘルプ, perldoc
  • マルチスレッド対応
    • 同期機構の専用 syntax
      • 例: Java の synchronized
    • 自動並列化
      • 例: OpenMP
    • メッセージ機構の隠蔽
      • Active Object
  • 安全に使えること
    • アクセス違反が起きない機構
      • インタプリタの実行時チェック
      • 静的+動的なチェック 例: Java のバイト・コード・ベリファイア, Fail-Safe C
    • sandbox として利用可能
      • 上のアクセス違反チェック+リソースへのアクセス制限+α
      • セキュリティレベルが設定可能なことも
      • 例: ruby の $SAFE, Java など
    • コードへの署名
    • 安全ではないデータを属性で区別
      • perl や ruby の taint
      • 型システムでもできるかも。monad になりそうな気もしますけど……。
  • 特定用途への組み込み機能
    • データベースへのクエリーと結果取得が言語に組み込まれている
      • R/O マッピング
    • Web サーバとの統合
  • 国際化対応
    • 文字列の内部表現と外部表現の区別
    • UTF-8 への対応
    • ストリング外部化機能
      • IDE でのサポート 例: eclipse
    • 表示の順番が入れ替わることを許す文字列テンプレート機能
  • 実装が軽いこと
    • メモリ使用量と実行速度
    • 特にインタプリタ
      • 組み込み python はやっぱり大きい
      • 家庭用ゲーム機では Lua くらいが限度という意見も
  • 覚えやすいこと
    • C言語っぽい syntax
      • 最近の俺言語業界では一歩進んで(?)JavaScript っぽいというか、ECMAScript っぽいものが流行のようです。
    • 同じ記号には文脈によらずできるだけ同じ意味を割り当てること
    • 妙な罠がないこと
    • 字句解析が一貫するよう注意して設計すること
      • 反面教師: C++ の vector >, ruby の b = a +2; (← は a(+2) と解釈される), OCaml の ( * ) (← (* はコメント開始を意味する)
    • syntax sugar を不用意に増やしすぎないこと
      • 反面教師: Perl の while (my $a = <>); は $a に偽値を読み込んでも終わらない
    • 文法がシンプルであること
      • Lisp は素晴らしい!
  • 非プログラマでも利用可能なこと
    • 関数という概念は一つ目のハードル
    • 再帰という概念はかなり高いハードル
      • この時点で、関数型言語は脱落……
      • 教え方が悪いという考え方は当然ありますが。
    • クラスとインスタンスの違いも難しい……
    • 実物と一対一の対応が見えるようなものがよい
      • モジュール化させるなら、プロトタイプベースがよいかもしれず
    • プログラマが見える世界と非プログラマが見えている世界の2層構造になっているのがベター?
  • Visual Programming Language
    • タイル型(下のタイルプログラミングとは異なる)←正しい呼称はなんでしょう……
      • AgentSheet, Tonyu
    • タイルプログラミング
      • SqueakToys
    • 制約ベース
    • データフロー
      • Prograph
    • 書き換え系
      • Viscuits
    • 論理型言語
      • ToonTalk

上記は当然、共存できる目標ではありません。応用に応じて、取捨選択すべきものです。

また、言語仕様として実装すべき要求と、IDE の機能として実現するべき要求もあると思っています。そこら辺の切り分けを進めていくためのブレストでもあります。