言語設計者は、特定の機能が正しく機能することを決定または証明するために何をしますか?


11

私は言語設計に興味があり、一般的に、広く知られている機能(たとえば、継承、ポリモーフィズム、デリゲート、ラムダ、キャプチャ、ガベージコレクション、例外、ジェネリック、分散、リフレクションなど)、特定の言語、実装方法、制限など。

過去数ヶ月で、Rustについて読み始めました。Rustには、オブジェクトの有効期間を静的に検証可能にすることにより、メモリの安全性と決定論的なリソース管理を保証する所有権システムがあります。言語の単純なユーザーの観点から、私はほとんどすぐにシステムを拾うことができました。

しかし、言語デザイナーの観点からは、Rustの物事がまさにその通りである理由を理解するのに少し時間がかかりました。所有権システムのいくつかの制限の背後にある理由をすぐに理解できませんでした。そのような側面がなければ、システムの整合性を侵害するケースを考え出す必要がありました。

私の主な質問は、Rustとその所有権とは特に関係ありませんが、必要に応じてコメント/回答の例として自由に使用してください。

言語設計者が新しい機能を設計するとき、機能が適切に機能することを決定するためにどのような方法論またはプロセスを使用しますか?

「新規」とは、既存の言語で既にテストされたものではないことを意味します(したがって、作業の大部分は他のデザイナーによって行われています)。「適切に動作する」とは、この機能が意図した問題を正しく解決し、合理的に防弾であることを意味します。「合理的な防弾」とは、機能の整合性に違反する言語または言語の特定のサブセット(「安全でない」コードのないサブセットなど)でコードを記述できないことを意味します。

  • シンプルな形の機能を考え出し、それを破る方法を見つけ、それをうまく破ったらパッチを当てて、繰り返すという意味で、試行錯誤のプロセスですか?そして、他の可能な違反を考えることができないとき、あなたは何も残っていないことを望み、それを1日と呼びますか?

  • または、機能が機能することを実際に(単語の数学的意味で)証明し、その証明を使用して最初から自信を持って機能を(またはほぼ正しく)取得する正式な方法はありますか?

(私はコンピューターサイエンスではなく、エンジニアリングのバックグラウンドを持っていることに言及する必要があります。したがって、CSの人々に明らかな何かが足りない場合は、お気軽にご指摘ください。)


「言語デザイナー」と言うとき、コンパイラを作成する人、または単に構文、またはその両方を意味しますか?
スヌープ

6
@StevieV:言語設計は実装とは異なり、独立しています。たとえば、Lispは、λ計算に代わるわかりやすい代替手段としてJohn McCarthyによって設計されました。しかし、彼はそれを実装しませんでした。実際、学生のスティーブラッセルがLispを実装したいと思ったとき、McCarthyは彼にLispを実装することは不可能だと信じていると言った!APLは数学を教えるための言語として設計されました。後に、IBMはこれを使用して、言語がいくつかの拡張機能を取得したSystem / 360の動作を正式に指定しました。現時点では、まだ実装されていません。PlankalkülはKonradによって設計されました
ヨルグW

4
Zuse 1942-1946は1975年にのみ実装されました。NiklausWirthは最初に言語を完全に設計し、設計が完了した後にのみ実装しました(そして、言語がどれだけ優れているかを理解するために言語自体で最初のコンパイラを作成しました)設計された-彼は彼の学生にブートストラップのためにコンパイラを別の言語に手で翻訳させた)。多くのアカデミック言語は実装されておらず、いくつかの言語機能を抽象的な方法で実証するためにのみ設計されています。Smalltalkは、相互の賭けの結果として作成されました。
アランケイ

3
紙の1ページでオブジェクト指向言語を設計し、Dan Ingallsは数日でその言語を実装できると考えています。(そして、彼はすべての言語のBASICでそれをしました!)言語は、コンパイラ/インタプリタとは独立して存在する数学的オブジェクトです。また、物理的な実装とは無関係に設計、研究、および議論できます。
ヨルグWミットタグ

3
読まなければならない:ゲーデル、エッシャー、バッハを。少し奇妙なこともありますが、最終的には言語設計の形式に大きな影響を与えるチューリング&ゲーデルの仕事の多くに取り掛かります。
ラバーダック

回答:


6

現時点では正確なリファレンスを見つけるのに苦労していますが、少し前に、Haskellのデザインに大きく貢献したSimon Peyton Jonesのビデオを見ました。ちなみに、彼は型理論、言語設計などの優れた講演者であり、YouTubeで無料で利用できる多くのビデオを持っています。

Haskellには、本質的にラムダ計算と簡単に操作できるようにいくつかの単純なものが追加された中間表現があります。コンピューターは物を計算する単なる人間であったため、ラムダ計算が使用され、証明されています。サイモン・ペイトン・ジョーンズが頻繁に行う興味深い点は、彼らが言語でワイルドでクレイジーなことをするときはいつでも、最終的にその中間言語に還元されるときにそれが根本的に健全であることを知っているということです。

他の言語はそれほど厳密ではなく、その代わりに使いやすさや実装が好まれています。彼らは、他のプログラマーが高品質のコードを取得するために行うのと同じことを行います。つまり、優れたコーディング慣行に従い、それを完全にテストします。Rustの所有権のセマンティクスのような機能は、忘れられたコーナーケースを見つけるために、多くの正式な分析とテストの両方を取得するはずです。多くの場合、そのような機能は、卒業論文として始まります。


2
私は、あなたが探しているリファレンスシリーズ、おそらく「Haskellでは型との冒険」の一つであると信じて、この1 ...サムネイル画像でボードの内容与えられた
ジュール・

8

そのため、言語設計には、証明(またはバグ)があります。たとえば、「systems」と入力します。型とプログラミング言語は、型システムを説明する標準的な本であり、型システムの正確性と完全性の証明に焦点を当てています。文法には同様の分析があり、アルゴリズム(説明する所有権システムなど)には独自のアルゴリズムがあります。

言語実装の場合、他のコードと同様のコードです。単体テストを作成します。統合テストを作成します。コードレビューを行います。

言語を特別なものにする唯一のことは、それらが(ほとんどの場合)無限であることです。文字通りすべての入力をテストすることはできません。そして(理想的には)それらは奇妙で面白いことをしている多くの人々によって使用されているので、言語のバグは最終的に発見れるでしょう。

実際には、機能を検証するためにプルーフを使用する言語は比較的少なく、最終的には言及したオプションがいくつか混在しています。


4
The only thing that makes languages special is that they are (almost always) infinite. You literally cannot test all inputs.それは本当に特別ですか?それは私にとって一般的なケースのようです。例えば、引数としてリストをとる関数には、無限の数の入力があります。選択したサイズnには、サイズn + 1のリストがあります
。– Doval

@doval-そして文字列も、私は思う。良い点。
テラスティン

4

言語設計者が新機能を導入する際に最初に対処しなければならない最も難しいことは、言語の一貫性を保つことです。

  • 既存のコードを壊さずに言語文法にどのように統合できるか(これは数学的に証明できる)
  • 既存の機能との関係(たとえば、0..n-1のインデックスが付けられた固定配列がある場合、1..nのインデックスが付けられた新しい可変配列の機能は導入されません)(デザインの芸術的な部分です)
  • 新しい機能をエコシステム、ツールメーカー、プログラマーが吸収できるように、ツールチェーン全体に機能を実装する方法(実現可能性は概念実証で実証できますが、完全な実装はプログラミングに似たアプローチです)

この問題を解決するために、設計者は一連の設計ルールと原則に依存しています。このアプローチは、言語設計専用の希少な本の1つであるBjarne StroustrupのThe C ++の設計と進化」で非常に詳しく説明されています。非常に興味深いのは、言語が真空で設計されることはめったになく、設計者が言語が同様の機能をどのように実装しているかを確認することです。別のソース(オンラインおよび無料)は、Java言語の設計原則です

標準化委員会の公開議事録を見ると、それはもっと試行錯誤のプロセスであることがわかります。次のC ++モジュールの例は、言語の次のバージョンで導入される完全に新しい概念です。そして、ここでいくつかの言語の変更後に作成された分析は、その成功を評価します。そして、新しいapiなどの新しいJava仕様を定義するJava Community Processです。この作業は、コンセプトペーパーと最初の提案を創造的に作成する複数の専門家によって実行されることがわかります。その後、これらの提案は、より大きな一貫性を確保するために提案を修正する可能性のあるより大きなコミュニティ/委員会によってレビューされます。


4

プログラミング言語の機能をテストする方法は?それは非常に良い質問であり、最先端の技術が仕事にかかっているかどうかはわかりません。

各新機能は、他のすべての機能と対話できます。(これは、言語、ドキュメント、コンパイラ、エラーメッセージ、IDE、ライブラリなどに影響します。)抜け穴を開くために機能が組み合わされていますか?厄介なエッジケースを作成するには?

型の健全性を維持するために一生懸命働いている非常に賢い言語設計者でさえ、このRustのバグのような違反を発見します。Rustの型システムは私にはそれほど明白ではありませんが、この場合、型システムの値の寿命を追跡することは、通常のサブタイプ、強制、参照、および可変性に対する期待と寿命「サブタイピング」(サブレンジ)が衝突し、static寿命がrefは、スタックに割り当てられた値を指し、後でぶら下がり参照になります。

「適切に動作する」とは、この機能が意図した問題を正しく解決し、合理的に防弾であることを意味します。

多くのプログラマーが信頼できる生産ソフトウェアを構築するために使用する生産言語を目的とする言語の場合、「適切に動作する」とは、対象とする対象者に対して対象となる問題を正しく解決することを意味する必要があります

言い換えると、言語設計にとって、ユーザビリティは他の種類の設計と同様に重要です。これには、(1)使いやすさの設計(例:聴衆を知る)、および(2)使いやすさのテストが含まれます。

このトピックに関する記事の例は、「プログラマーは人、また、プログラミング言語であり、APIデザイナーはヒューマンファクターデザインの分野から多くを学ぶことができます。」です。

このトピックに関するSEの質問の例は、プログラミング言語の構文がユーザビリティテストされていますか?

ユーザビリティテストの例では、リスト反復機能(どの言語を覚えていないか)を拡張して複数のリストを取得することを検討しました。人々はリストを並行して、またはクロスプロダクトを反復することを期待していましたか?言語設計者は、ユーザビリティテストの結果に驚きました。

Smalltalk、Python、Dartなどの言語は、使いやすさに重点を置いて設計されました。Haskellは明らかにそうではありませんでした。


Haskellは実際、かなり使いやすいです。Python / C / Javaなどとはまったく異なるパラダイムであるため、学習するのは難しいだけです。しかし、言語としては非常に使いやすいです。
セミコロン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.