静的および動的タむピング

この蚘事では、静的に型付けされた蚀語ず動的に型付けされた蚀語の違いに぀いお説明し、「匷い」型ず「匱い」型の抂念を調べ、異なる蚀語の型付けシステムの胜力を比范したす。 最近、プログラミングにおいおより厳栌で匷力なタむピングシステムぞの明確な動きがあるため、タむプずタむピングに぀いお話すずきの意味を理解するこずが重芁です。



タむプは、可胜な倀のコレクションです。 敎数は、倀0、1、2、3などを持぀こずができたす。 ブヌル倀はtrueたたはfalseです。 たずえば、「Give」ず「5」の倀が可胜な「Give Five」タむプなど、独自のタむプを考えるこずができたす。 これは文字列や数倀ではなく、新しい別個のタむプです。


静的に型付けされた蚀語は倉数の型を制限したす。たずえば、プログラミング蚀語はxが敎数であるこずを知っおいる堎合がありたす。 この堎合、プログラマヌはx = trueを行うこずを犁じられおおり、これは誀ったコヌドになりたす。 コンパむラはコンパむルを拒吊するため、そのようなコヌドを実行するこずさえできたせん。 別の静的に型付けされた蚀語には他の衚珟胜力があり、人気のある型システムはどれもDaiPyat型を衚珟できたせんしかし、倚くは他のより掗緎されたアむデアを衚珟できたす。


動的に型付けされた蚀語は倀を型でマヌクしたす。蚀語は1が敎数、2が敎数であるこずを知っおいたすが、倉数xが垞に敎数を含むこずを知るこずはできたせん。


蚀語ランタむムは、これらのラベルをさたざたな時点でチェックしたす。 2぀の倀を远加しようずするず、圌女はそれらが数倀、文字列、たたは配列であるかどうかを確認できたす。 次に、タむプに応じお、これらの倀を远加、接着、たたぱラヌを出したす。


静的に型付けされた蚀語


静的蚀語は、プログラムの開始前であっおも、コンパむル時にプログラムの型をチェックしたす。 型が蚀語の芏則に違反するプログラムはすべお䞍正ず芋なされたす。 たずえば、ほずんどの静的蚀語は、匏"a" + 1を拒吊したすCはこの芏則の䟋倖です。 コンパむラは、 "a"が文字列であり、1が敎数であり、 +が巊右の郚分が同じ型である堎合にのみ機胜するこずを知っおいたす。 そのため、問題があるこずを理解するためにプログラムを実行する必芁はありたせん。 静的に型付けされた蚀語の各匏は、コヌドを実行せずに定矩できる特定の型を参照したす。


倚くの静的型付け蚀語では、型を指定する必芁がありたす。 Java public int add(int x, int y)の関数はpublic int add(int x, int y) 2぀の敎数を取り、3番目の敎数を返したす。 他の静的に型付けされた蚀語は、型を自動的に刀別できたす。 Haskellの同じ加算関数は次のようになりたす add xy = x + y 。 蚀語の皮類はわかりたせんが、 +が数倀に察しおのみ機胜するこずがわかっおいるため、 xずyは数倀である必芁があるため、 add関数は匕数ずしお2぀の数倀を受け取りたす。


これは、「静的」型システムを枛らすものではありたせん。 Haskellの型システムは、静的で、厳密で、匷力な機胜で有名であり、これらのすべおの分野で、HaskellはJavaに先んじおいたす。


動的に型付けされた蚀語


動的に型付けされた蚀語では、型を指定する必芁はありたせんが、それ自䜓で型を定矩する必芁もありたせん。 倉数のタむプは、起動時に特定の倀を持぀たで䞍明です。 たずえば、Pythonの関数


 def f(x, y): return x + y 

2぀の敎数、接着線、リストなどを远加できたすが、プログラムを実行するたで正確に䜕が起こっおいるのか理解できたせん。 おそらくある時点で、関数fは2行で呌び出され、別のずきに2぀の数倀で呌び出されたす。 この堎合、xずyには、異なる時間に異なるタむプの倀が含たれたす。 したがっお、動的蚀語の倀には型がありたすが、倉数や関数には型がないず圌らは蚀いたす。 倀1は間違いなく敎数ですが、xずyは任意です。


比范


ほずんどの動的蚀語は、型が誀っお䜿甚されるず゚ラヌをスロヌしたすJavaScriptはよく知られおいる䟋倖です。意味をなさない堎合でも、匏の倀を返そうずしたす。 動的に型付けされた蚀語を䜿甚する堎合、戊闘環境では"a" + 1ずいう圢匏の単玔な゚ラヌが発生する可胜性がありたす。 静的蚀語はそのような゚ラヌを防ぎたすが、もちろん、防止の皋床は型システムの胜力に䟝存したす。


静的蚀語ず動的蚀語は、プログラムの正確性に関する根本的に異なる考え方に基づいお構築されおいたす。 動的蚀語"a" + 1これが正しいプログラムです。コヌドが起動され、ランタむムに゚ラヌが衚瀺されたす。 ただし、ほずんどの静的に型付けされた蚀語では、匏"a" + 1はプログラムではありたせん。コンパむルも実行もされたせん。 これは、ランダムな文字のセットのような無効なコヌド!&%^@*&%^@*は無効なコヌドです。 正確さず䞍正確さずいうこの远加の抂念は、動的蚀語では同等のものではありたせん。


匷いタむプず匱いタむプ


「匷い」ず「匱い」の抂念は非垞にあいたいです。 それらの䜿甚䟋をいく぀か瀺したす。



やめたしょう。 これは、いく぀かの蚀語がこれらの定矩を満たす方法です。 ご芧のずおり、Haskellだけがあらゆる点で䞀貫しお「匷力」です。 ほずんどの蚀語はそれほど明確ではありたせん。


蚀語静的暗黙的な倉換厳栌なルヌルメモリにずっお安党ですか
C匷いどうやっお匱い匱い
Java匷いどうやっお匷い匷い
ハスケル匷い匷い匷い匷い
Python匱いどうやっお匱い匷い
Javascript匱い匱い匱い匷い

「暗黙的な倉換」列の「い぀、どのように」ずは、匷いものず匱いものずの区別が、蚱容できるず考えられる倉換の皮類によっお異なるこずを意味したす。


倚くの堎合、「匷い」および「匱い」ずいう甚語は、䞊蚘のさたざたな定矩、およびここに瀺されおいない他の定矩の䞍定の組み合わせを指したす。 この混乱により、「匷い」ず「匱い」ずいう蚀葉はほずんど意味がなくなりたす。 これらの甚語を䜿甚する堎合は、正確に䜕を意味するのかを説明するこずをお勧めしたす。 たずえば、「文字列に数字を远加するずJavaScriptは倀を返したすが、Pythonぱラヌを返したす」ず蚀うこずができたす。 この堎合、「匷い」ずいう蚀葉の倚くの意味に぀いお合意に達する努力を無駄にしないでしょう。 たたは、さらに悪いこずに、甚語が原因で未解決の誀解が生じたす。


ほずんどの堎合、むンタヌネット䞊の「匷い」および「匱い」ずいう甚語は䞍明確であり、特定の人々の意芋が䞍十分に定矩されおいたす。 圌らは蚀語を「悪い」たたは「良い」ず呌ぶために䜿甚され、この意芋は専門甚語に倉わりたす。


クリス・スミスが曞いたように 


匷い型付け私が倧奜きで、私が快適に感じる型システム。

匱いタむピング私を悩たせたり、気に入らない型システム。

段階的なタむピング


動的蚀語に静的型を远加するこずは可胜ですか ある堎合には、はい。 他では、それは困難たたは䞍可胜です。 最も明らかな問題は、動的蚀語のevalおよびその他の同様の機胜です。 Pythonで1 + eval("2")を実行するず3が埗られたすが、 1 + eval(read_from_the_network())は䜕を䞎えたすか 実行時に䜕がオンラむンになっおいるかによっお異なりたす。 数倀が埗られれば、匏は正しいです。 文字列の堎合、いいえ。 開始する前に調べるこずは䞍可胜であるため、型を静的に解析するこずはできたせん。


実際の䞍十分な解決策は、 eval()匏をAnyに蚭定するこずです。これは、䞀郚のオブゞェクト指向プログラミング蚀語のObjectたたはGoのむンタヌフェヌスinterface {}に䌌おいたす。これは、任意の倀を満たすタむプです。


Any型の倀は䜕によっおも制限されないため、評䟡システムを支揎する型システムの機胜はなくなりたす。 evalず型システムの䞡方を持぀蚀語は、 eval䜿甚されるたびに型安党性を攟棄しなければなりたせん。


䞀郚の蚀語には、オプションの入力たたは段階的な入力がありたす。デフォルトでは動的ですが、いく぀かの静的泚釈を远加できたす。 Pythonは最近、オプションの型を远加したした。 TypeScriptは、オプションのタむプを持぀JavaScriptアドむンです。 フロヌは、叀き良きJavaScriptコヌドの静的分析を実行したす。


これらの蚀語は静的型付けの利点の䞀郚を提䟛したすが、真の静的蚀語のように絶察的な保蚌を䞎えるこずはありたせん。 䞀郚の関数は静的に型付けされ、䞀郚は動的に型付けされたす。 プログラマヌは垞に違いを知り、泚意する必芁がありたす。


静的に型指定されたコヌドのコンパむル


静的に型指定されたコヌドをコンパむルするずき、コンパむラず同様に、最初に構文がチェックされたす。 次に、タむプがチェックされたす。 これは、最初は静的蚀語が1぀の構文゚ラヌに぀いお文句を蚀い、それを修正した埌、100の入力゚ラヌに぀いお文句を蚀うかもしれないこずを意味したす。 構文゚ラヌを修正しおも、これらの100個の入力゚ラヌは発生したせんでした。 コンパむラは、構文が修正されるたで型゚ラヌを怜出できたせんでした。


通垞、静的蚀語コンパむラは、動的蚀語コンパむラよりも高速なコヌドを生成できたす。 䟋えば、コンパむラヌがadd関数が敎数を受け入れるこずを知っおいる堎合、䞭倮凊理装眮のネむティブADD呜什を䜿甚できたす。 動的蚀語は、実行時に型をチェックし、型に応じお倚くの远加関数のいずれかを遞択したす敎数たたは浮動小数点を远加するか、文字列たたはリストを远加したすかたたは、゚ラヌが発生し、型が䞀臎しないこずを決定する必芁がありたす。 これらすべおのチェックには時間がかかりたす。 動的蚀語では、型に関する必芁な情報をすべお受け取った埌、実行時にコヌドが再コンパむルされるJITコンパむルゞャストむンタむムなど、最適化のためにさたざたなトリックが䜿甚されたす。 ただし、Rustなどの蚀語で適切に蚘述された静的コヌドの速床に匹敵する動的蚀語はありたせん。


静的および動的タむプの匕数


静的型システムの支持者は、型システムがないず、単玔な゚ラヌが本番環境で問題を匕き起こす可胜性があるこずを指摘しおいたす。 もちろんこれは事実です。 動的蚀語を䜿甚したこずがある人は、これを自分で経隓しおいたす。


動的蚀語の支持者は、そのような蚀語でコヌドを曞く方が簡単だず指摘したす。 これは、 evalを䜿甚したコヌドなど、私たちが時々曞くある皮のコヌドには間違いなく圓おはたりたす。 これは、定期的な䜜業では物議を醞す決定であり、「簡単」ずいう曖昧な蚀葉を思い出すのは理にかなっおいたす。 リッチ・ヒッキヌは 、「簡単」ずいう蚀葉ず、「簡単」ずいう蚀葉ずの぀ながりに぀いおよく語りたした 。 このレポヌトを芋るず、「簡単」ずいう蚀葉を正しく䜿甚するこずは容易ではないこずが理解できたす。 「軜さ」に泚意しおください。


静的および動的タむピングシステムの長所ず短所はただ十分に理解されおいたせんが、蚀語ず解決される特定の問題に確実に䟝存しおいたす。


JavaScriptは、無意味な倉換「a1 "a" + 1を䞎える「a」 "a" + 1などを意味する堎合でも、動䜜を継続しようずしたす。 Pythonは、 "a" + 1堎合のように、保守的になり、゚ラヌを返すこずがよくありたす。


セキュリティレベルが異なるさたざたなアプロヌチがありたすが、PythonずJavaScriptはどちらも動的に型付けされた蚀語です。


Cは、プログラマヌがメモリ内の任意の堎所からデヌタを読み取れるようにするか、プログラムのクラッシュに぀ながる意味がなくおも、あるタむプの倀が別のタむプであるず想像できるようにしたす。


Haskellでは、これの前に明瀺的な倉換なしに敎数ず浮動小数点数を远加するこずはできたせん。 CずHaskellはどちらも静的に型付けされおいたすが、このような倧きな違いはありたす。


動的蚀語ず静的蚀語には倚くのバリ゚ヌションがありたす。 「Xに関しおは静的蚀語は動的蚀語よりも優れおいる」ずいう圢匏の無条件のステヌトメントは、ほずんどナンセンスです。 これは特定の蚀語の堎合に圓おはたるかもしれたせんが、「HaskellはXに関しおはPythonよりも優れおいる」ず蚀う方が良いでしょう。


さたざたな静的型付けシステム


静的型付け蚀語の2぀の有名な䟋を芋おみたしょうGoずHaskell。 Go型付けシステムには、他の型の「パラメヌタヌ」を持぀型は䞀般化されおいたせん。 たずえば、MyListリスト甚に独自のタむプを䜜成し、必芁なデヌタを保存できたす。 MyListの゜ヌスコヌドを倉曎せずに、MyList敎数、MyList文字列などを䜜成できるようにしたいず考えおいたす。 コンパむラヌは、次の分類に埓う必芁がありたす。敎数のMyListがあり、誀っおそこに行を远加した堎合、コンパむラヌはプログラムを拒吊する必芁がありたす。


Goは、MyListなどのタむプを蚭定できないように特別に蚭蚈されたした。 できる最善のこずは、MyListの「空のむンタヌフェむス」を䜜成するこずです。MyListにはオブゞェクトを含めるこずができたすが、コンパむラはそのタむプを認識したせん。 MyListからオブゞェクトを取埗するずきは、コンパむラヌに型を䌝える必芁がありたす。 「ラむンを取埗したした」ず蚀っおも、実際には倀が数倀である堎合、動的蚀語の堎合のように、パフォヌマンス゚ラヌが発生したす。


Goには、最新の静的型付け蚀語たたは1970幎代の䞀郚のシステムに存圚する他の倚くの機胜もありたせん。 Goの䜜成者には、これらの決定に察する独自の理由がありたしたが、この問題に関する倖郚の人々の意芋は、時には厳しく聞こえる堎合がありたす。


それでは、非垞に匷力な型システムを持぀Has​​kellず比范したしょう。 タむプをMyListに蚭定するず、「数字のリスト」のタむプはMyList Integerたす。 Haskellは、誀っおリストに文字列を远加させたり、リストの項目を文字列倉数に入れないようにしおいたす。


Haskellは、より耇雑なアむデアを型で盎接衚珟できたす。 たずえば、 Num a => MyList aは、「同じタむプの数字のMyList倀」を意味したす。 敎数、浮動小数点数、たたは固定粟床の10進数のリストを指定できたすが、コンパむル䞭にチェックされる文字列のリストになるこずはありたせん。


任意の数倀タむプで機胜する远加関数を䜜成できたす。 この関数の型はNum a => (a -> a -> a)です。 これは次のこずを意味したす。



最埌の䟋。 関数の型がString -> String堎合、文字列を受け取り、文字列を返したす。 ただし、 String -> IO String堎合、䜕らかの入力/出力も行いたす。 これは、ディスク、ネットワヌクぞのアクセス、端末からの読み取りなどです。


型の関数にIO がない堎合、I / O操䜜を実行しないこずがわかりたす。 たずえば、Webアプリケヌションでは、関数の皮類を調べるだけで、関数がデヌタベヌスを倉曎するかどうかを理解できたす。 これを行うには、動的蚀語も静的蚀語もほずんどありたせん。 これは、最も匷力なタむピングシステムを備えた蚀語の機胜です。


ほずんどの蚀語では、関数ずそこから呌び出されるすべおの関数などを凊理しお、デヌタベヌスを倉曎する䜕かを芋぀けようずする必芁がありたす。 これは、間違いを犯しやすい退屈なプロセスです。 そしお、Haskell型システムはこの質問に簡単か぀確実に答えるこずができたす。


この力をGoず比范しおください。GoはMyListの単玔なアむデアを衚珟するこずができず、「2぀の匕数を取り、それらは䞡方ずも数倀で同じタむプで、入出力を行う関数」は蚀うたでもありたせん。


Goアプロヌチを䜿甚するず、Goでプログラミングするためのツヌルを簡単に䜜成できたす特に、コンパむラの実装は簡単です。 さらに、必芁な抂念が少なくなりたす。 これらの利点が重芁な制限にどのように匹敵するかは、䞻芳的な問題です。 ただし、HaskellはGoよりも孊習が難しく、Haskellの型システムははるかに匷力であり、Haskellはコンパむル時にさらに倚くの皮類のバグを防ぐこずができるず䞻匵するこずはできたせん。


GoずHaskellは非垞に異なる蚀語であるため、甚語が正しく䜿甚されおいおも、「静的蚀語」の1぀のクラスにグルヌプ化するず誀解を招く可胜性がありたす。 実甚的なセキュリティ䞊の利点を比范するず、GoはHaskellよりも動的蚀語に近いです。


䞀方、䞀郚の動的蚀語は、䞀郚の静的蚀語よりも安党です。 Pythonは䞀般にCよりも安党であるず考えられおいたす。 静的たたは動的蚀語をグルヌプずしお䞀般化する堎合、蚀語間の膚倧な数の違いを忘れないでください。


タむピングシステム機胜の違いの具䜓䟋


より匷力なタむピングシステムでは、より䜎いレベルで制限を指定できたす。 以䞋にいく぀か䟋を瀺したすが、構文があいたいな堎合は、それらにこだわらないでください。


Goでは、「add関数は2぀の敎数を取り、敎数を返したす」ず蚀うこずができたす。


 func add(x int, y int) int { return x + y } 

Haskellでは、「関数は任意の数倀型を取り、同じ型の数倀を返したす」ず蚀うこずができたす。


 f :: Num a => a -> a -> a add xy = x + y 

Idrisでは、「関数は2぀の敎数を取り、敎数を返したすが、最初の匕数は2番目の匕数より小さくなければなりたせん」ず蚀うこずができたす。


 add : (x : Nat) -> (y : Nat) -> {auto smaller : LT xy} -> Nat add xy = x + y 

最初の匕数が2番目の匕数よりも倧きいadd 2 1を呌び出そうずするず、コンパむラヌはコンパむル時にプログラムを拒吊したす 。 最初の匕数が2番目の匕数より倧きいプログラムを䜜成するこずはできたせん。 たれな蚀語にはこの機胜がありたす。 ほずんどの蚀語では、このチェックは実行時に行われたすif x >= y: raise SomeError()ように蚘述したす。


Haskellには、䞊蚘のIdrisの䟋のような型に盞圓するものはなく、GoにはHaskellの䟋たたはIdrisの䟋に盞圓するものはありたせん。 , Idris , Haskell, Haskell , Go. , .



. , . . , .



, , . — Go, , .


(Java C#) — , .


, Mozilla (Rust) Apple (Swift).


(Idris and Agda) , . .



Source: https://habr.com/ru/post/J308484/


All Articles