[追記] この記事は2014年、私が文系大学生の頃、手探りでプログラミングを独学し始めた頃の記事です。温かい気持ちで見ていただけたら幸いです。
ーー
!! おことわり !!
このブログには、いわゆる「技術記事」は一切ありません!!!(書きたくても書けない)
ただの「勉強記録ノート」です!!!
プログラミング初学者の勉強記録ノートです!「日記」です!!
生暖かい目で見ていただけたらさいわいですヽ(;▽;)ノ
Index
- “型のありがたみ”を覗く
- “型付けの弱い世界”を知る
- 動的型付けと静的型付け
- 型付けによる比較
- “型付け”と”型変換”
- 強い型付けと弱い型付け
- まとめ
- 追記 (あとで読むリストなど)
Introduction
よくTwitterのタイムラインで「型安全」という言葉を見ます。
でも、その意味を私は全く分かっていませんでした…そもそも「型安全」という言葉は
「安全な型」を指す(だから安全でない型もある?)のか
「型が安全」(どう安全なの?何と比べて?)なのかも分かっていませんでした。
(* この時点で私は「型による制約はあって当たり前」だと思っていたので、型のありがたみを知らなかったのです… )( 今まで触ったことのある言語は C言語, Haskell, OCamlで、どれも”型”を宣言するものだった。(型推論のあるHaskellなどでも私は必ず型を書くようにしてた)*)
私Twitterでよく見る「型安全」とかいうキーワード、実は全く意味が分かってないです…型が安全ってどういうこと???
— ちょまど@春休み中 (@chomado) 2014, 2月 15
“型のありがたみ”を覗く
Wikipediaを見ます。
型システム: http://ja.wikipedia.org/wiki/型システム
そしたら、一般的に言われる「型安全」とは、どうやら「型の安全性」の略称らしいです。(type safety)
メモ: 型の安全性とは、型エラーをどのくらい防ぐかっていう程度(範囲)
> A type error is erroneous or undesirable program behaviour caused by a discrepancy between differing data types for the program’s constants, variables, and methods (functions), e.g., treating an integer (int) as a floating-point number (float).
メモ: 型エラーというのは、違うデータ型同士の間での矛盾によって引き起こされる、望ましくない挙動のこと。たとえばInt型をFloat型として扱ったり
するとTwitterで南山まさかずさんにご教授頂きました!ヽ(;▽;)ノ
@chomado たとえば、1+1はちゃんとした式ですよね?
— 中2女子南山まさかず (@minamiyama1994) 2014, 2月 15
@chomado じゃあ、 2 + "Hello" は?
— 中2女子南山まさかず (@minamiyama1994) 2014, 2月 15
@chomado
そういうことです!
そういうおかしなことが出来ない、というのが型安全性、です
— 中2女子南山まさかず (@minamiyama1994) 2014, 2月 15
おお!(((o(゚▽゚)o)))なななるほどです!!!
おかしなことができないように型というシステムが守ってくれてるかんじかな?
さらに。
@chomado そういうことです。型検査によってコードの不正をより確実に検知できるほど、安全性が高いということになります。
— つくばなう (@KOBA789) 2014, 2月 15
なるほど、型には「安全性の高さ(どのくらい高いか)」というステータスがあるらしい。
@chomado 言い換えると、ソースコードの不正を型検査で見つけられるほど型に情報量が多い、つまり型の表現力が強いとも言えます。
— つくばなう (@KOBA789) 2014, 2月 15
型にいろいろ情報を突っ込めるとコンパイラが勝手にいろいろ検査してくれて安心だね、って話ですな
— つくばなう (@KOBA789) 2014, 2月 15
なるほど!!
メモメモφ(゚▽゚)oメモメモ
つまり「型安全」という言葉は、「安全な型がある(だから安全じゃない型もある?)」という意味ではなく「型により安全」「型システムの与えてくれる安全性」という意味でした!
“型付けの弱い世界”を知る
この会話
@chomado じゃあ、 2 + "Hello" は?
— 中2女子南山まさかず (@minamiyama1994) 2014, 2月 15
@chomado
そういうことです!
そういうおかしなことが出来ない、というのが型安全性、です
— 中2女子南山まさかず (@minamiyama1994) 2014, 2月 15
について。
同時にタイムラインに流れてきたもの。
2 + "Hello" は 2 です
— 愚か者 (@mpyw) 2014, 2月 15
2 + "Hello"は"2Hello"です
— がお (@gaogao_9) 2014, 2月 15
型が…あれ?
>RT
— ちょまど@春休み中 (@chomado) 2014, 2月 15
オイバカやめろ闇を見せるな
— 中2女子南山まさかず (@minamiyama1994) 2014, 2月 15
なんだかよくわからないことになっていました!!
えっ、なんで 2 + “Hello” が普通に評価されてるの???????!!!?!?!?!?
すると。
@chomado PHPやJSは型がゆるふわしてるので……
— 中2女子南山まさかず (@minamiyama1994) 2014, 2月 15
!?Σ(・□・;)
えっ?
そういうのって言語によって違うの?
言語によっては 2 + “Hello” が普通に通っちゃうの? そしてそれは型がゆるふわしてるか厳しいかで違いが出るんだ?
っていうかそもそも型にゆるふわとか強弱あったんだ????
型は型だからそんな強弱も何もないと思ってました
@chomado
勝手に文字列に変換されたりなんだりと割と闇なことをやってることが多いです
そういう言語の多くは動的型付け(実行時に型が判定される)なので、型が違ったら即エラーなどにするとプログラムがまともに書けなくなるのです(コンパイラによる支援が無いため)
— 中2女子南山まさかず (@minamiyama1994) 2014, 2月 15
ひょえー
私が今まで触ってきたものは全てそんなものじゃなかったので、とても新鮮でした。
@chomado
Python,Ruby,PHP,Perlなどの各種スクリプト言語はだいたい型がゆるいです
Awkもですね
あとshellも言語として捉えるとアレですね
他にもあると思うので他の人にも聞いて見てください
— 中2女子南山まさかず (@minamiyama1994) 2014, 2月 17
なるほど〜色んなのがあるんだなあ〜
私が今まで触ったことのあるもの(C言語, Java, Haskell, OCaml)がたまたまそんな感じじゃなかっただけかあ
動的型付けと静的型付け
動的型付け (Wikipedia)
対して、静的型付け (Wikipedia)
> 静的型の関数型言語では、キャストなどを基本的に許さず、不正なデータを処理する関数が原理的に書けないため、ほぼインスタンスの妥当性も保証されることになる。これをもって関数型言語の支持者は「ほぼ全てのバグを型エラーにより検出する事が可能」と提案している。
ふむふむφ(゚▽゚)oメモメモ
あとTwitterに載ってた@uchan_nosさんのパロディが分かりやすい&&面白かったです!(((o(゚▽゚)o)))
静的片付:まず何を何処に動かすか、何を捨てるかを決定してから、その決定に従って片付ける。計画的。
動的片付:とりあえず机が露出するまで物を移動する。時々無くしたと思ってたものが出てくる。臨機応変。
— あたいはチルノ (@uchan_nos) 2014, 2月 19
これめっちゃ分かります! 動的型付けのことはよく分からないのですが、静的については、私もちょっと複雑な関数を作る時はまず型を考えてからやるので、型が導いてくれるというか、型は設計書のような機能を果たしてくれるのです(((o(゚▽゚)o)))
型付けによる比較
他Wikipediaの「プログラミング言語の比較」というページにも型付けによる比較覧が載っていました。
→ http://ja.wikipedia.org/wiki/プログラミング言語の比較
型付けのところだけ抜き出して表にしてみました!
静的型付け (強い→弱い)
Ada | 宣言型の安全な強い静的型付け |
Fortran | 宣言型の安全な強い静的型付け |
OCaml | 構造型の安全で静的型付け、型推論 |
Haskell♡ | 強い静的型付き言語、型推論 |
Java | 強い静的型付け |
Scala | 強い静的型付け、部分的な型推論 |
Visual Basic .NET | 強い静的型付け |
Object Pascal | 宣言型の安全で(ただし安全でないのも許可してる)強い静的型付け |
C# | 強い安全である/ない静的型付け |
C | 安全でない弱い静的型付け |
C++ | 宣言型の安全でない強い静的型付け |
動的型付け (強い→弱い)
Common Lisp | 安全で強い動的型付け |
Prolog | 安全で強い動的型付け(単一化) |
Smalltalk | 安全で強い動的型付け, ダック |
Python | 強い動的型付け(ダック・タイピング) |
Ruby | 強い動的型付け(ダック・タイピング) |
Mathematica | 強い動的型付け |
Scheme | 動的型付け |
ColdFusion | 弱い動的型付け (ダック・タイピング) |
Erlang | 弱い動的型付け |
JavaScript | 弱い動的型付け |
Perl | 弱い動的型付け |
PHP | 弱い動的型付け |
“ダックタイピング”という言葉を初めて聞いたので、少しググりました。
Wikipediaより
つまり、オブジェクトがあるインタフェースのすべてのメソッドを持っているならば、たとえそのクラスがそのインタフェースを宣言的に実装していなくとも、オブジェクトはそのインタフェースを実行時に実装しているとみなせる、ということである。
それはまた、同じインタフェースを実装するオブジェクト同士が、それぞれがどのような継承階層を持っているのかということと無関係に、相互に交換可能であるという意味でもある。
(((o(゚▽゚)o))) …???
…難しくてよく分からなかったんですけどまぁこういう名前の作法があるみたいです!(((o(゚▽゚)o)))
==== 追記 (2/19) ====
「ダックタイピング」について教えて頂きました!
@chomado はいはい〜 ちなみにダックタイピングというのは、強い型付けの言語が「このメソッドは型定義に書いてあるから呼んでよし」とするのに対してダックタイピングの言語では型情報を解析せず(できず)、場当たり的に「あ、このメソッドあるじゃーん。呼んじゃおw」ってなるものです。
— THE RESOLVER (@KOBA789) 2014, 2月 18
@chomado 型情報がない、というより書けないんです。JavaScript とかそうです。なので実行時に「呼んじゃえ」ってやります。でも Java とかならコンパイル時に「このクラスはあのクラスから継承してて、継承元にメソッドがあるから大丈夫だな。よし」ってできます
— THE RESOLVER (@KOBA789) 2014, 2月 18
@koba789 !! なるほどです!
つまり、(他のクラスにあるものでも)同じメソッドを持っていれば同様に処理できるとみなし、ガンガン呼び出せる、ということですね!(怖い気がします)
— ちょまど@春休み中 (@chomado) 2014, 2月 18
@chomado そういうことです。JavaScript の場合、実行時にメンバ増やしたり置き換えたり消したり自由なので、呼ぶ時までわからないんですよ。めっちゃ怖いです。
— THE RESOLVER (@KOBA789) 2014, 2月 18
なるほどです!φ(゚▽゚)oメモメモ
いつもありがとうございます!m(_ _)m!
てか
JavaScriptは実行時にメンバ増やしたり置き換えたり消したり自由
これめっちゃ怖いですねΣ(・□・;)
====追記終わり===
とりあえず、列挙して表にしてみた結果、分かったのは、
各々のプログラミング言語が、型付けに関して、色々個性がある
ということでした!
ちょっと広く世界を俯瞰できたというか…そんな感じです!(((o(゚▽゚)o)))
“型付け”と”型変換”
ちょっとごっちゃになってきたのでまとめます。
型付け | 処理系が値に型というタグを付与すること. 特定の型に決めてしまうこと. (値1に型intを付ける、変数aに型intを付ける、…) |
型変換 | 型を変換すること. 型Aを型Bに変換すること. (型intの付いた値1の型を型uintに変換する、型intの付いた変数aを型uintに変換する、…) |
(* これもTwitterで皆さまから教えて頂きました! いつも本当にありがとうございます… *)
強い型付けと弱い型付け
またWikipediaの型システムのページからまとめます!(https://ja.wikipedia.org/wiki/型システム#.E5.BC.B7.E3.81.84.E5.9E.8B.E4.BB.98.E3.81.91.E3.81.A8.E5.BC.B1.E3.81.84.E5.9E.8B.E4.BB.98.E3.81.91)
(* 追記: 住井先生の記事から2箇所引用させていただきました! *)
強い型付け
- ある処理・演算が間違った型の引数をとることを禁止するというもの。
- 『検査を通れば、安全さ(safety)が保証される、という(普通は静的な)型つけ。MLとかHaskellとかJavaとか。Javaはバグがあったりしたので少し怪しいですが。』住井先生の記事から引用
弱い(ゆるい)型付け
- 言語が型の暗黙的な変換(またはキャスト)をする。
- 柔和な記述が可能(らしいけど私はただただとても怖いと思う)。
- 『検査を通っても、安全さ(safety)は保証されない、という型つけ。CとかPascalとか。』ここで、”安全さ”とは、『プログラムが言語仕様で定義されていない状態(Cのバッファオーバーフローとか)にならないこと。』住井先生の記事から引用
暗黙の型変換
var y := “37”;
x + y;
これは
5 + “37”
Int型+String型というものですが、これがどうなるかというと、
弱い型付け→ どんな結果になるか言語ごとに異なる
例) JavaScriptは”537″となり、AppleScriptでは42になる(左のオペランドの型のみによって決定されている)
また、暗黙の型変換において、どの型からどの型への変換が許されるかは言語によって異なります。
PHPなどのように文字列と数値が普通に計算できてしまう(怖い)ものもあれば、
Int + Double => Double になるのはOK、な限定的なのは多くの言語でよくある。(Haskellなどではそれすらできない(のが良い気がする))
C# の場合、暗黙的型変換といって、完全に互換性のあるキャストだけが暗黙的に行える。
long -> int (だめ)
int -> long (OK)
(@lambdaliceさんから教えていただきました!)
まとめ
今日知ったこと
- 「動的型付け」と「静的型付け」
- 型付けに強弱があること
- 型付けには「安全性の高さ(どのくらい高いか)」というステータスがあるらしい
ゆるふわですね…
でもこの話題は掘り下げようとしたらめちゃくちゃ大変だと思う(TAPLが出てきそうな)ので、とりあえず今日はここまでです!(((o(゚▽゚)o)))
追記
あとで読む!
これ紹介されました! あとで読む!
- Wikipedia『共変性と反変性』: http://ja.wikipedia.org/wiki/共変性と反変性
- 住井先生の日記『型推論と型検査、静的な型つけと動的な型つけ、強い型つけと弱い型つけ』: http://d.hatena.ne.jp/sumii/20051018/1129631080
- 『型システム入門 プログラミング言語と型の理論』 (HP) 第1章
- 論文『On Understanding Types,
Data Abstraction, and Polymorphism』 (pdf) - 『Proofs and Types』 6章の単純型付きλ計算の強正規化性の証明は、type theory を勉強する上では必須、らしい
- @jutememoさんの記事『Haskell のモジュールの階層化と、型クラス – パラメータ多相とアドホック多相』: http://jutememo.blogspot.jp/2009/05/haskell.html (誰かに勧められたわけじゃないけど個人的に気になった)
今後の課題
住井先生の
<https://twitter.com/esumii/status/435939531632562176>
ぬぬ…Wikipediaと書いてあることが違う…! Wikipediaは、「定義」と「特徴」を混同するような書き方なんだって。(さらに、type safetyの定義は研究者間でも揉めるらしい)
私は(Wikipediaだけでなく)もっと広く色々見なきゃいけないらしい!(((o(゚▽゚)o)))
田中さんのツイート
尊敬する田中さん(すごい人)です! めっちゃ参考になるので許可頂きました!φ(゚▽゚)oメモメモ
強い→安全
弱い→安全でない
といえば、基準は非常に明快。
安全な静的型付け言語
安全でない静的型付け言語
安全な動的型付け言語
安全でない動的型付け言語
んで、普通動的型付け言語は、安全でないじっそうにはしない。
— Hideyuki Tanaka (@tanakh) 2014, 2月 19
なるほどです…φ(゚▽゚)oメモメモ
「安全でない動的型付け言語とか使いもんにならないから、普通そういう実装にはしない」らしいです! たしかによく分からないことになりそうですね
(* 例えばこんなかんじで… https://www.destroyallsoftware.com/talks/wat *)
ちょまどさんのさっきの記事の言語リストの出所が http://t.co/44rMFR1Hom これみたいですが、なんかあやしいですね。 http://t.co/5NaK7H9JEG 英語版だとずいぶんちゃんと書かれているように見えますね。特にType Systemsのところ。
— Hideyuki Tanaka (@tanakh) 2014, 2月 19
ひょええΣ(・□・;)
他の著名な方々もおっしゃっていたのですが、どうやら日本語版のWikipediaはあんまり良くないらしいです…(それでも,かすってるだけでも我々初心者にはありがたいのですが)
英語の記事はちゃんとstructualかnominalか書いてあるし、日本でダックタイピングと呼ばれているやつは、ただのstructuralな動的型付けなので、特別記述することではないと思った。
— Hideyuki Tanaka (@tanakh) 2014, 2月 19
http://t.co/V9yl0wXzAl
"型の強弱で語られる要素はそれぞれ直行ではなく、また特殊ケースも多い …"
"このため、型システムについてあいまい性のない文章を書きたい場合、「強い型付け」という単語は避けられ、代わりに「型安全」などのより明確な単語が用いられる"
— Hideyuki Tanaka (@tanakh) 2014, 2月 19
φ(゚▽゚)oメモメモ
強い型付けとか、弱い型付けとか、まじめな文章では出てこないんで、あんまり今まで本気で考えたことなかったから、このページは勉強になった。
— Hideyuki Tanaka (@tanakh) 2014, 2月 19
なるほど、「強い型付け」「弱い型付け」って言い方は、ちゃんとした文章(論文とか?)では見かけないらしい!
だからフォーマルなところではあんまり使われない言葉みたい! 定義がゆるふわだからかな?
一般的に型の強弱で議論されるのは、次のような要素のあるなしのようだ
・暗黙の型変換 と type punning(unionとかreinterpret_cast)
・ポインタ
・タグなしunion
・動的型検査
・静的型検査
・意外性のなさ
・型推論
— Hideyuki Tanaka (@tanakh) 2014, 2月 19
ひょえ〜ヽ(;▽;)ノ
もうこの辺になるとガチ専門的になってきて理解ができなくなりましたもうダメです
まあとりあえず今の段階では「ゆるふわに」「なんとなく」「こんなもんかな」って感じで理解しておこうと思います…!
少し追記しました(((o(*゚▽゚*)o)))
・ダックタイピング
・静的片付けと動的片付け、という喩え
・“型付け”と”型変換”
・暗黙の型変換
もっと追記しました(((o(*゚▽゚*)o)))
追記が長すぎて「<h2>追記</h2>」ってスペース作ってしまいました
とてもためになりました。
はじめまして、
どうやら凄いスキルアップしましたね(^^)
個人的にはphpをよく使っています。
スクリプト系言語だと厳密な比較である
===、!==っていうのもありますよ。
それぞれ一長一短ありますからしっかり特徴を捉えてプログラムして下さい!!
C言語だと失敗するとかなり手痛い状態になるので
その辺りをちゃんとプログラム出来るようにならないといけませんね。
因みに元々のC++はCへのトランスレーターなのでCで出来る事は全てC++で出来ますf(^^
ダックタイピングという言葉から意味を捉えるのも面白いですよ。
西洋のことわざの「アヒルのように泣き、アヒルのように歩き、アヒルのように飛ぶのはアヒルだ」ということわざからきてるそうです。
つまり、メソッドで「泣け」、「歩け」、「飛べ」ってあったらアヒルってことにしようってことですね。PHPとかがこれですかね。
(そういうメソッドがあるならアヒルってことでいいよね。みたいな)
JavaとかC#とかはアヒル・インターフェースを定義して
(つまりちゃんとアヒルの定義)を用意して、それを実装しないとアヒルって認めない! ってことです。
なるほどです…! ありがとうございます!
Javascriptから覚え始めた者からしてみればそういうものだと思ってた。それ前提で書いているので何が怖いのかよくわからない。
暗黙の型変換便利でござる。便利でござr
Javascriptだとコンピュータへアクセスできる範囲に制限があるけどそうじゃない言語だと不正操作されたりのきっかけになるってことなのかな。
[…] するのであれば、下記のブログ記事が面白い。 「強い型付け」「弱い型付け」って言葉を知った! […]