問題タブ [static-typing]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - 動的型付けを補うための非セマンティック テストにうんざりしていませんか?
コンピューター エンジニアリングの勉強を始める前は、Rails (それ以前は PHP) で多くの Web プログラミングを行っていました。
それ以来、私は C で多くの学業を行い、Objective-C (Mac のもの) でいくつかの個人的なことをしました。静的型付けが好きになりました。
しかし今、私はプロの Web 開発 (フリーランス) を行う必要があり、Rails を再び手に入れました。非セマンティックな型チェック テストを作成するのは非常に面倒です。私はそれらを C および Objective-C コンパイラから無料で入手していました。Build を押して、システムにすべてのコードをチェックさせて、A が B を呼び出すことができるか、B が不明なライブラリ C を呼び出すことができるかなどを確認するのが好きでした。私がしなければならなかったのは、セマンティクスをテストすることだけでした。しかし、Rails では、私がコンパイラです。:(
誰かがこれと同じ道を歩んだことがありますか? C# と Java + x フレームワークを使用した Web 開発 ASP.NET MVC の唯一のオプションですか? いくつかの提案、または同情さえ探しています... :P
ちなみに、Ruby ではなく Rails に具体的に言及するのは、Ruby の動的な性質が、スクリプト作成などの単純な作業で問題にならないからです。しかし、Rails は非常に多くの gem に依存しており、通常は 1 つの gem が他の多数の gem を追加するため、動的型付けが問題になります。
ありがとう!
編集:
私はpstの提案をフォローアップし、Scalaを調べました。言語の作成者である Martin Odersky によって書かれた本 Programming in Scala を読んでいるときに、さまざまな方法で私の懸念とそれ以上のことを表現しているこのテキストに出くわしました。非常に興味深い読書。
Martin Odersky の Programming in Scala の 52 ページから引用:
Scala は静的に型付けされています
静的型システムは、保持および計算する値の種類に従って、変数と式を分類します。Scala は、非常に高度な静的型システムを備えた言語として際立っています。Java によく似た入れ子になったクラス型のシステムから始めて、型をジェネリックでパラメーター化し、共通部分を使用して型を結合し、抽象型を使用して型の詳細を隠すことができます。これらは、独自の型を構築および構成するための強力な基盤を提供するため、安全で柔軟に使用できるインターフェイスを設計できます。
Perl、Python、Ruby、Groovy などの動的言語が好きな人は、Scala の静的型システムが長所の 1 つとして挙げられていることに少し違和感を覚えるかもしれません。結局のところ、静的型システムがないことは、動的言語の主な利点として挙げられています。静的型に対する最も一般的な議論は、プログラムが冗長になりすぎる、プログラマーが自分自身を思い通りに表現できない、ソフトウェア システムの動的変更の特定のパターンを不可能にする、というものです。
ただし、多くの場合、これらの引数は一般的な静的型の考え方に反するものではなく、冗長すぎるか柔軟性がないと認識されている特定の型システムに反します。たとえば、Smalltalk 言語の発明者である Alan Kay はかつて次のように述べています。 /p>
この本で、Scala の型システムが「完全な苦痛」とはほど遠いことを納得していただけることを願っています。実際、静的型付けに関する通常の 2 つの懸念事項にうまく対処しています。型推論によって冗長性が回避され、パターン マッチングといくつかの新しい方法で型を記述および構成することによって柔軟性が得られます。これらの障害が取り除かれると、静的型システムの従来の利点をよりよく理解できるようになります。これらの利点の中で最も重要なものは、プログラムの抽象化の検証可能なプロパティ、安全なリファクタリング、およびより優れたドキュメントです。
検証可能なプロパティ
静的型システムは、特定の実行時エラーがないことを証明できます。たとえば、次のようなプロパティを証明できます。ブール値は整数に追加されることはありません。プライベート変数はクラス外からアクセスされません。関数は正しい数の引数に適用されます。文字列のセットに追加されるのは文字列だけです。
他の種類のエラーは、今日の静的型システムでは検出されません。たとえば、それらは通常、非終了関数、配列境界違反、またはゼロ除算を検出しません。また、プログラムがその仕様に準拠していないことも検出しません (仕様があると仮定します)。そのため、静的型システムはあまり有用ではないとして却下されてきました。そのような型システムは単純なエラーしか検出できないのに対し、単体テストはより広範なカバレッジを提供するため、なぜ静的型を気にする必要があるのでしょうか?
私たちは、これらの議論は的を射ていないと考えています。静的型システムは確かに単体テストに取って代わることはできませんが、そうでなければテストする必要があるいくつかのプロパティを処理することで、必要な単体テストの数を減らすことができます。同様に、単体テストは静的型付けに取って代わることはできません。結局のところ、Edsger Dijkstra が言ったように、テストはエラーの存在を証明することしかできず、エラーがないことを証明することはできません。したがって、静的型付けが提供する保証は単純かもしれませんが、どれだけのテストを行っても提供できないフォームの実際の保証です。
安全なリファクタリング
静的型システムは、コードベースを高い信頼度で変更できるセーフティ ネットを提供します。たとえば、メソッドに追加のパラメーターを追加するリファクタリングを考えてみましょう。静的に型付けされた言語では、変更を行い、システムを再コンパイルして、型エラーの原因となっているすべての行を単純に修正できます。これが完了したら、変更が必要なすべての場所を確実に見つけることができます。同じことが、メソッド名の変更やクラス間でのメソッドの移動など、他の多くの単純なリファクタリングにも当てはまります。すべての場合において、静的型チェックは、新しいシステムが古いシステムと同じように機能することを十分に保証します。
ドキュメンテーション
静的型は、コンパイラによって正確性がチェックされるプログラム ドキュメントです。通常のコメントとは異なり、型注釈が古くなることはありません (少なくとも、それを含むソース ファイルが最近コンパイラに渡された場合はそうではありません)。さらに、コンパイラと統合開発環境は、型注釈を利用して、より優れたコンテキスト ヘルプを提供できます。たとえば、統合開発環境では、選択が行われる式の静的タイプを判別し、そのタイプのすべてのメンバーを検索することにより、選択に使用できるすべてのメンバーを表示できます。
open-source - 静的に型付けされたオープン ソースのクロス プラットフォームの最新のプログラミング言語
ばかげた質問かもしれません。Java および .NET プラットフォームに代わるものはありますか?
どれの:
- プログラミング言語そのものです。言語ポートは、支配的にならない限り、実際には成功しているとは言えません。
- JVM のような独自の実行プラットフォームを備えている可能性があり、これは大きなプラスです。でも通訳もOK。
- 静的に型付けされます。
- オープン ソースであり、オープン コミュニティによって開発されています。
- Java のようなクロス プラットフォームです。一度コンパイルすると、どこでも実行できます。
- 最新です: マルチパラダイム (OOP とジェネリック、関数型がプラス)、コンカレント (少なくとも同時書き込みが可能)、ガベージ コレクションがプラス、リフレクションがプラスです。
この基準を満たす人気のない言語や実験的な言語についても教えていただければ幸いです。死んだ言語は大丈夫ではありません。
上記の (主観的な) 条件がすべて当てはまる言語は、おそらく 2 つのカテゴリのいずれかに分類されます。
- 静的に型付けされたインタープリター言語プロジェクト。これは、クロスプラットフォームのインタープリターとライブラリーを提供します。
- Java に似た言語ですが、Java ポートではなく、コミュニティによって開発されたという 2 つの違いがあります。
scala - カスタム Scala コレクションの動的な型が map() 中に確実に保持されるようにするにはどうすればよいですか?
Scala 2.8 コレクションのアーキテクチャーに関する非常に興味深い記事を読み、それを少し試してみました。まず、素晴らしいRNA
例の最終的なコードを単純にコピーしました。ここに参照用があります:
さて、ここに私の問題があります。これを実行すると、すべて問題ありません。
しかし、このコードは RNA をベクターに変換します!
これは問題です。クラスを認識しないクライアント コードは、からへのみマッピングする場合に代わりにRNA
クラスを に戻す可能性があるためです。それはなぜですか、それを修正する方法は何ですか?Vector
Base
Base
P.-S .: 暫定的な回答を見つけました (以下を参照)。間違っている場合は修正してください。
scala - 同じ型にマッピングするとき、Scala の map() は異なる動作をするべきですか?
Scala Collections フレームワークでは、 を使用するときに直感に反する動作がいくつかあると思いますmap()
。
(不変の) コレクションに対する 2 種類の変換を区別できます。結果のコレクションを再作成するために実装が呼び出されるものと、ビルダーを取得するためにnewBuilder
暗黙的に実行されるもの。CanBuildFrom
最初のカテゴリには、含まれる要素の型が変わらないすべての変換が含まれます。たとえば、、、、、、などです。これらの変換は、自由に呼び出してfilter
、呼び出さpartition
れたものと同じコレクション型を再作成することができます。a (またはコレクション フレームワークのアーキテクチャに関するこの記事で説明されている構造の例)をフィルター処理すると、常に別の(または)を返すことができます。それらをフィルタリング変換と呼びましょう。drop
take
span
newBuilder
List[Int]
List[Int]
BitSet
RNA
BitSet
RNA
変換の 2 番目のカテゴリはCanBuildFrom
、含まれる要素の型が変更される可能性があるため、s をより柔軟にする必要があり、その結果、コレクション自体の型を再利用できない可能性BitSet
がありますString
。anには sRNA
のみが含まれますBase
。そのような変換の例はmap
、flatMap
、collect
、scanLeft
、などです。それらをマッピング変換++
と呼びましょう。
さて、ここで議論すべき主な問題です。コレクションの静的な型が何であれ、すべてのフィルタリング変換は同じコレクションの型を返しますが、マッピング操作によって返されるコレクションの型は静的な型によって異なる場合があります。
これで、なぜこのように機能するのかがわかりました。所々に説明がある。CanBuildFrom
つまり、静的な型に基づいて暗黙的に挿入され、そのdef apply(from: Coll)
メソッドの実装に応じて、同じコレクション型を再作成できる場合とできない場合があります。
唯一のポイントは、同じ要素タイプ(コンパイラーが静的に決定できる) を持つコレクションを生成するマッピング操作を使用していることがわかっている場合、フィルター変換の動作方法を模倣して、コレクションのネイティブ ビルダーを使用できるということです。BitSet
sにマッピングするときに再利用したり、同じ順序でInt
新しいものを作成したりできます。TreeSet
次に、次のようなケースを回避します。
TreeSet
のインクリメントされた要素を同じ順序で出力しません
そう:
- 説明されているように、マッピング変換の動作を変更することは良い考えだと思いますか?
- 私がひどく見落とした避けられない警告は何ですか?
- どのように実装できますか?
パラメータのようなものについて考えていましたimplicit sameTypeEvidence: A =:= B
。おそらくデフォルト値はnull
(またはむしろimplicit canReuseCalleeBuilderEvidence: B <:< A = null
) で、実行時に使用して、より多くの情報を に提供し、CanBuildFrom
返されるビルダーのタイプを決定するために使用できます。
groovy - Groovy での型付き引数によるクロージャ
引数の型に関するクロージャーについて、より明確にしたいと思います。だから私は次のようなものを書くでしょう
Groovy がその型情報を使用しないことはわかっていますが、Groovy++ はコンパイル時にそれを使用する可能性があります。これを達成できますか(コメントに入れる以外に)?
更新: タイトルは誤解を招くように聞こえるかもしれませんが、上記の例でより明確になると思いました。関数の引数であるクロージャの型を指定することに興味があります。組み込みの を再定義したいとしcollect
ます。だから私は書くことmyCollect
ではなく、書くことに興味がありclos
ます。私が達成したいのは、コンパイル時エラーを取得することです
java - なぜインターフェースをJavaで宣言しなければならないのですか?
同じシグニチャを持ついくつかのメソッドを持つが、宣言されたJavaインターフェイスに対応しないクラスがいくつかある場合があります。たとえば、JTextField
とJButton
(のいくつかの他の中で javax.swing.*
)の両方にメソッドがあります
ここで、そのメソッドを持つオブジェクトを使用して何かを実行したいとします。次に、インターフェイスが必要です(または、自分で定義することもできます)。
私が書くことができるように:
しかし、悲しいことに、私はできません:
このキャストは違法です。クラスがそのインターフェースを実装することを宣言していないので、コンパイラーはそれがではないことを知っています...しかしそれは「実際に」それを実装します。JButton
CanAddActionListener
これは不便な場合があります。Java自体がいくつかのコアクラスを変更して、古いメソッドで作成された新しいインターフェイスを実装しています(String implements CharSequence
たとえば)。
私の質問は:なぜこれがそうなのか?クラスがインターフェイスを実装することを宣言することの有用性を理解しています。しかし、とにかく、私の例を見ると、なぜコンパイラーは、クラスJButton
がインターフェース宣言を「満たして」(その内部を見て)、キャストを受け入れることができないと推測できないのでしょうか?それはコンパイラの効率の問題ですか、それとももっと根本的な問題がありますか?
答えの要約:これは、Javaが何らかの「構造的型付け」(ダックタイピングのようなものですが、コンパイル時にチェックされます)を考慮に入れていた可能性がある場合です。そうではありませんでした。いくつかの(私にはわかりませんが)パフォーマンスと実装の難しさは別として、ここにははるかに基本的な概念があります。Javaでは、インターフェース(および一般的にはすべて)の宣言は、単に構造的(これらのシグニチャ)がセマンティック:メソッドは特定の動作/意図を実装することになっています。したがって、あるインターフェースを構造的に満たす(つまり、必要なシグニチャーを持つメソッドを持っている)クラスは、必ずしも意味的に満たすとは限りません。(極端な例:メソッドさえない「マーカーインターフェース」を思い出してください!)したがって、Javaは、これが明示的に宣言されているため(そしてそれだけのために)、クラスがインターフェースを実装していると断言できます。他の言語(Go、Scala)には他の哲学があります。
c# - フロートは2倍より遅いですか?64ビットプログラムは32ビットプログラムよりも高速に実行されますか?
タイプを使用するよりもタイプを使用するfloat
方が遅いdouble
ですか?
最近のIntelおよびAMDCPUは、floatよりもdoubleを使用して計算を高速に実行できると聞きました。
sqrt
標準の数学関数(、、、、、などpow
)はどうですか?単精度での計算は、浮動小数点演算が少なくて済むため、かなり高速になります。たとえば、単精度は倍精度よりも単純な数式を使用できます。また、標準の数学関数は64ビットモードの方が高速であると聞きました(コンパイルして64ビットOSで実行した場合)。これについての決定的な答えは何ですか?log
sin
cos
sqrt
sqrt
python - Python での静的型チェックのためのツール
私は大規模な既存の Python コードベースを使用しており、型注釈の追加を開始して、ある程度の静的チェックを取得できるようにしたいと考えています。Erlang、Strongtalk、またはTyped Scheme/Racketのようなものを想像しています。
関数パラメーターに基づいて動的チェックを挿入し、型の注釈を返す、簡単で汚いデコレーターを見てきましたが、より堅牢で、コンパイル時にチェックを実行するものを探しています。
この種のことのために、現在どのようなツールが利用可能ですか? 私はコンパイラと型チェックに精通しており、基礎がしっかりしていれば、不完全なツールを改善したいと思っています。
(注: 静的型付けの長所/短所の議論には興味がありません。)
編集:例:
put
関数に typeという注釈を付けたいと思いput<K,V>(dict<K,V>, K, V) -> None
ます。
UPDATE : 新しいPEP 484 (2014 年 9 月) は、Python 3.5+ の静的型付けと型注釈の標準を定義します。PEP 484 と互換性のあるmypyという型チェック ツールがあります。
haskell - 一部のデータが特定のタイプであるかどうかをHaskellでテストしていますか?
Haskell はそのような表現力豊かな型システムを持っているので、あるデータが何らかの型であるかどうかを問い合わせることができる直接サポートされているものはありますか? ラケットのように、(String? "Hi")
(戻りtrue
ます)などMyType? somedata -> Bool
c# - var を使用してフィールドを宣言できない理由
重複の可能性:
クラス フィールドを var にできないのはなぜですか?
ローカル変数でできるように、フィールドの複雑な/長い型定義を入力することは避けたいと思います。
なぜこれができなかったのか知りたいですか?