型システムFAQ


Sit down, we need to talk about types


ポストに触発されます.人々は、間違った用語を使用して間違った結論を得るタイプについての多くの誤解を持っています.私は静的なタイプのシステムを提唱していない、私の唯一の懸念は、我々は建設的な議論をすることができますので、右の用語を使用してみましょう.
私は自発的にこのポストを書いた.私は、エラーがないことを望みます、しかし、あなたが何かを見つけるならば、私をなでてください.もっと自由に質問しなさい.これを一度に解決しましょう.

ダイナミックタイプ


動的型システムをuntypedと同じように考える人もいます.これは正しくない.型付けタイプは、型を区別する意味がないシステムです.そして、1つのタイプだけがあるならば、タイプを区別する感覚がありません.例えば、
  • アセンブリ言語:唯一の
  • ラムダ計算:唯一の1つのタイプは
  • 大きなことではなく、何でも、ダイナミックまたはuntypedと言うことがあります.実際には、ダイナミックで型付けされていない型を静的に設定すると、静的なタイプのシステムとは動的に逆のダイナミックなものになるので、2つのキャンプの動的対静的なタイプに分割された人々(それは不正確です、ダイナミックで静的に見てください).

    Languages that do not restrict the range of variables are called untyped languages: they do not have types or, equivalently, have a single universal type that contains all values.

    -- Type Systems, Luca Cardelli


    Untyped — programs simply execute flat out; there is no attempt to check “consistency of shapes”

    Typed — some attempt is made, either at compile-time or at run-time, to check shape-consistency

    -- Type Systems for Programming Languages, Benjamin C. Pierce


    ダイナミックvsスタティック


    動的型システムは、型が動的にチェックされるシステムです.
    スタティック型システムは、型が静的にチェックされるシステム(コンパイル時または移行時)です.
    彼らは反対ですか.いいえ、そうではありません.両方ともタイプです.両方とも、実際には、静的な型システムの大部分はダイナミック型チェックもあります.例として、入出力の妥当性検査を行うことができます.あなたが番号でタイプに仮定するユーザーから入力を読む必要があると想像してください.文字列の解析があなたに数値を与えるかどうかをランタイムでチェックします(例外をスローするか、NaNを返すことができます).与えられた入力が数値として考えられるかどうかチェックするとき、あなたはダイナミックタイプチェックをします.
    したがって、それは静的対ダイナミック型の戦争ではありません.両方を使用できます.
    さらに、静的な型チェックは複雑なプロセスです.プログラムの一部を静的に確認するのは非常に難しいので、静的ではなく動的型チェックに戻ることができます.
    スタティック型システムを静的チェックタイプとして考えてみましょう.
    動的にチェックされた型として動的型システムを考えます.

    スタティックタイプはコンパイル時に型を知っているときですか?


    いいえ、任意のパーサー(JSを含む)のソースコードを開くと、パーサーが解析時に値の型を知っていることがわかります(コンパイルプロセスの一部です).
    let x = "test";
    
    パーサーは"test" は文字列です.これは静的にタイプされますか?いいえ.

    段階的制度


    段階的なシステムは、例えば、プログラムの部品のタイプチェックをスキップすることを可能にする静的なタイプシステムです.any or @ts-ignore タイプスクリプトで.
    片側から、それはより安全になります.別の側面から、段階的なタイプのシステムを動的に入力された言語に徐々に型を追加することができます.

    サウンド対非音型システム


    サウンドタイプチェッカーは、タイプエラーでプログラムを「承認しない」チェッカーです.したがって、あなたがunsoundタイプチェッカーを使用するならば、あなたはまだあなたのアプリケーション😱. 慌てるな.実際には、それはあなたに影響を与えない場合があります.健全性は、タイプチェックアルゴリズムの数学的な性質です.多くのコンパイラ(タイプチェッカーの内部)が不健全です.
    サウンドタイプのシステムで動作したい場合は、ML -ファミリを見てください.
    サウンドタイプのシステムが無効なプログラム(偽陽性)を渡さないことをよく理解する必要がありますが、同様に有効なプログラム(false negative)を拒否することもあります.
    有効なプログラムを決して拒絶しないタイプシステムは完全と呼ばれます.
    私は両方を持つことができます-音と完了?私の知る限りでは、彼らは存在しない.私は確かではありませんが、それは根本的に不可能であるようです.

    弱い対強い


    私はこの用語が役に立つとは考えません.

    These languages can be euphemistically called weakly checked (or weakly typed, in the literature) meaning that some unsafe operations are detected statically and some are not detected. Languages in this class vary widely in the extent of their weakness.

    -- Type Systems, Luca Cardelli


    Probably the most common way type systems are classified is "strong" or "weak." This is unfortunate, since these words have nearly no meaning at all. It is, to a limited extent, possible to compare two languages with very similar type systems, and designate one as having the stronger of those two systems. Beyond that, the words mean nothing at all.

    -- What To Know Before Debating Type Systems, Steve Klabnik


    The terms "strong" and "weak" are extremely ambiguous. Here are some ways that the terms are used:

    • Sometimes, "strong" means "static". That's easy enough, but it's better to say "static" instead because most of us agree on its definition.
    • Sometimes, "strong" means "doesn't convert between data types implicitly". For example, JavaScript allows us to say "a" - 1, which we might call "weak typing". But almost all languages provide some level of implicit conversion, allowing automatic integer-to-float conversion like 1 - 1.1. In practice, most people using "strong" in this way have drawn a line between "acceptable" and "unacceptable" conversions. There is no generally accepted line; they're all arbitrary and specific to the person's opinions.
    • Sometimes, "strong" means that there's no way to escape the language's type rules.
    • Sometimes, "strong" means memory-safe. C is a notable example of a memory-unsafe language. If xs is an array of four numbers, C will happily allow code that does xs[5] or xs[1000], giving whatever value happens to be in the memory addresses after those used to store xs.

    -- Types - Programmer's Compendium, Gary Bernhardt


    静的型付け言語は型宣言を必要とするか?


    必ずしもではありません.時々、システムは型を推論することができます(コード構造に基づく推測).例えば(例: ).
    const x = "test";
    
    タイプシステムは"test" は文字列です.タイプシステムはx 定数は、例えば、再割り当てできないので、x は文字列です.
    その他の例
    const add = (x, y) => x / y
    //                        ^ Cannot perform arithmetic operation because string [1] is not a number.
    add(1, "2")
    
    タイプチェッカーは、我々が呼ぶのを見ますadd 数と文字列では、それを定義に戻るトレース.タイプチェッカーは、分割操作が数を入力として予想することを知っています.したがって、それは入力の1つとしてストリングを使用するためにこれがエラーと言います.
    SARは型宣言ではありませんが、静的チェックを行うこともできます.遅かれ早かれ、タイプシステムがすべてを推論することができないので、あなたは若干のタイプを書かなければなりません.しかし、静的に入力された言語は宣言についてではなく、ランタイムの前にチェックするタイプです.

    JavaScriptにコンパイルされているので、スクリプトは安全ですか?


    タイプスクリプトは不健全なので、安全でないアプリケーションを生成することができますが、それがコンパイルするものとは何の関係もありません.
    デスクトップコンパイル用のコンパイラのほとんどはアセンブリ言語にダウンします¯\_(ツ)_/¯ .
    しかし、コンパイルされたコードはブラウザで実行され、JSは安全ではありません.例えば、文字列が期待されたときにNULL値を与えることができます.
    良い質問.したがって、TSは、アプリケーション内の安全性を保証することができます、あなたが“世界の外の世界とTSの相互作用する場所の周りのガード”を置く必要があります.例えば、IO(input - output)を検証する必要があります:ユーザー入力、サーバー応答、ブラウザーストレージから読み取るなど.
    例えば、ELMでは"ports" これは.TSでは、IO TSなどを使用できます.
    この「ガード」は静的システムとダイナミック型システムの間にブリッジを作る.
    簡単な例
    const makeSureIsNumber = (x: any) => {
      const result = parseFloat(x);
      if (isNaN(result)) {
        throw Error("Not a number");
      }
      return result;
    }
    const read = (input: any) => {
      try {
        const n = makeSureIsNumber(input);
        // in this branch of code, n is for sure number
        // otherwise, we would get into a different branch of code
        // makeSureIsNumber "proofs" that n is number
      } catch (e) { }
    }
    

    コンパイラに必要な型だけですか?


    Types are just a hack to give hints to your compiler.

    -- Wout Mertens


    それは哲学的な問題だ.タイプはマシンのためではなく、人々に必要です.コンパイラは、人間によって書かれたプログラムであるので、型が必要です.
    現象としてのタイプは、人々のために存在します.それは別のバケット(またはカテゴリ)別のものを置く人間の心です.オブザーバーなしでは、彼らは意味をなさない.
    ここにあなたのための思考実験です.“人生のゲーム”について考えてください.あなたは2つの可能な状態のいずれか、生きているか死んでいる正方形のセルの2次元グリッドを持っている.すべてのセルは、水平方向、垂直方向、または斜めに隣接しているセルは、その8つの隣人と対話します.各段階で、次のような遷移が起こります.
  • 2つの生きている隣人より少ないどんな生きている細胞も、人口不足によって死にます.
  • 2つまたは3つのライブ隣人と任意の生細胞は、次世代に住んでいます.
  • 以上の3つの生きている隣人との任意の生細胞は、過疎のように死ぬ.
  • 正確に3つの生きている隣人とどんな死んだ細胞も、再生によってかのように生細胞になります.
  • それは“点滅”の正方形の束です.それで遊ぶonline .
    しかし、あなたは「グライダー」のようないくつかの構造を持っています

    あなたはそれを見ることができますか?それはグライダーの画面全体を右に移動ですか?今一時停止します.それは、実際に存在しますか?それはちょうど表示され、消える正方形を分離します.しかし、我々の脳は、実体として構造を観察することができます.
    あるいは、正方形が独立していない(隣人に依存している)、そして、グライダー自体が存在しないとしても、プラトンの概念としてのグライダーの概念が存在するので、我々はそれが存在すると言うことができます.
    今、型プログラミング言語の任意のプログラムを考える.私たちはタイプを見ることができます、右?しかしアセンブリコードはコンパイルされます.アセンブリコードとプログラムは同じものを表します、同じロジック(2番目のものは人間のために読みにくいです).コンピュータの観点から、型がない、ビットの文字列があります- sとs(デッド、生きている細胞)のコレクション.人々のためのタイプが存在する.

    PS


    私の以前の試みは、タイプについて書きます:
  • https://github.com/stereobooster/pragmatic-types

  • それらの記事は更新と若干の再仕事を必要とします.

    Cover image by reddit