20

Coffeescript は素晴らしい言語だと思います。コーヒースクリプトに静的分析を追加するプロジェクト/問題/機能を探していました。しかし、いくつか検索した結果、Coffeescript faqこのページは、静的分析が実行できない可能性があることを示唆していることがわかりました。

コーヒースクリプトで静的解析/静的型チェックを実装する際に根本的な問題があるとしたら、この種のものがコンパイラにまだ存在していないため、疑問に思っていましたか?

また、重要なチェックでは実行できないが、単純な分析でのみ機能する可能性があることはありますか? 簡単に言うと、ユーザーが関数を同じ名前 (クラス内) で 2 回定義したか、トップレベル (または関連する .coffee ファイルのコレクションのトップレベル) で定義したかなど、些細なことをチェックすることを意味します。 .

静的解析/型チェックの実装が簡単ではない/可能でない/時間を費やす価値がある理由を示す例を誰かが指摘していただければ幸いです。

どうもありがとうございました!

4

2 に答える 2

13

私もこれに興味があるので、この答えはちょっとしたブレインダンプです。それが役に立てば幸い。

Google Closure Compiler を使用して、CoffeeScript が生成するコードを静的に分析します。非常に優れた静的アナライザーがあり、ここで車輪を再発明する正当な理由があるかどうかはわかりません。簡単な方法は、注釈を手で書くことです:

###*
   * @param {number} x
   * @param {number} y
   * @return {number}
###
adder = (x, y) -> x + y

少し冗長ですが、一方で、非常に強力で多くのチェックが可能なクロージャ コンパイラの静的解析機能を借りています。実際にはもう少し簡潔な方法で型注釈を記述し、コーヒー ファイルを書き換えるスクリプトを作成します。私のコードは次のようになります。

#! {number} x {number} y @return {number}
adder = (x, y) -> x + y

リライターが非常に簡単であることがわかると思います。

先に進む前に簡単なメモ。クロージャ コンパイラを使用してコードを実行する場合は、必ず(bare)でコードをコンパイルしてください。-bクロージャ コンパイラは非常に優れていますが、データ フロー分析を行うほどスマートではありません。デフォルトでは、CoffeeScript はコードを無名関数でラップするため、コンパイラがトリップします。

同じパスに沿った別のオプション (これは CoffeeScript との互換性を損なうことになりますが、はるかにクールです) は、Coffee コンパイラに次のようにコンパイルさせることです。

adder = (number x, number y): number -> x + y

次のように JS に変換します。

/***
  * @param {number} x
  * @param {number} y
  * @return {number
  */
var adder = function(x, y) {
  return x + y;
};

これは、コンパイル時にクロージャ コンパイラに入力できます。エラーがなければ、コンパイラはすべてのコメントを削除できます。

実際、この男はまさにこれを行っているように見えました。悲しいことに、彼の作品は不完全な状態にあるようです。

これらすべてのケースで、大変な作業 (静的型チェック) をクロージャ コンパイラに委ねます。あなたがこれをやりたくないのなら、私には理解できますが、まったく新しい静的分析ツールをゼロから構築する価値があると私に納得させるのは難しいでしょう. :)

1年後に編集:最近はタイプスクリプトを使用しています。:)

于 2012-06-04T22:07:16.110 に答える
8

私は CoffeeScript の専門家ではないので、これは完全に間違った答えかもしれませんが、基本的には次のようになります。これは、はるかに厳密に定義されたセマンティクスを持つ標準 ML のような言語とは対照的です。一般に、高階言語で静的解析を行うことは非常に難しいと考えられています。つまり、実際の高次プログラム (Haskell、ML、特に制御の流れがはるかに柔軟であるため、eval などの理由で javascript は難しいだけです。実際、高階言語の静的解析ソリューションは、過去 20 年ほどでしか検討されていません。(特に、 CFA のチュートリアル形式の説明に関するMatt Might の記事を参照してください。)

基本的に、理由は次のとおりです。

  • 分析を行うには、高階関数をぶち壊すことによって得られるフロー制御から生じる表現上のセマンティクスの問題に対処する必要があります。
  • タイピングを行うために、通常、これらの言語にはより豊富なタイプのセットが用意されています。たとえば、Ruby (C、Java、ML など) で静的型を変数に割り当てようとすると、エラーが発生するという非常に一般的な状況がありますが、プログラムの特定のパスが決して割り当てられないためです。実行しました、大丈夫です。それに加えて、Ruby などの言語は、クールなプログラミングを行うために実際に使用される暗黙の型変換を大量に追加します。私がよく知っているこの分野での注目すべき仕事(Ruby の静的型の動的解析)は、私が一緒に仕事をしている何人かの人々によるものですが、確かに他の例もあります。
  • 基本的に、言語ははるかに動的な方法で使用され、より表現力豊かなセマンティクスがあり、それについて静的に推論することははるかに難しく、不正確になりがちです。これにアプローチする基本的な前線 (最近) はハイブリッドに見え始めています: プログラムの一部を静的に分析することができ、プログラマーが何らかのテストケースを提供して何らかの洗練された分析を行うことを要求することもできます。

これがあなたの質問にいくらか答えてくれることを願っています.CoffeeScriptに適用されるので、あなたの質問の直接的な懸念に直接対処することはできません. Javascript の実際の問題のいくつかは、その奇妙なセマンティクスに起因することに注意してください。プロトタイプの継承は推論が難しく、特に eval()! 通常、これらの言語のプログラム分析では、分析をより実行可能にするために、特定の制限 (たとえば、eval を完全に破棄する!) を課します!

于 2012-06-04T00:48:41.123 に答える