from 「名前的型システムと構造的型システムの違い」加筆案 「名前的型システムと構造的型システムの違い」加筆案メモ
Dart: Currently, typedefs are restricted to function types. We expect this to change.
「コーディングを支える技術で型の勉強をしてます」とTypeScriptの勉強会で言われて、確認してみたけどやっぱりstructualとnominalの違いの解説はなかった。加筆したい。
ブレスト 動的型付け言語に対する型ヒントの流れ 2014年の言語ランキングを後で調査
- https://www.immagic.com/eLibrary/ARCHIVES/GENERAL/TIOBE_NL/T140901I.pdf
- Java 14% C++ 5% C# 4%
- Python 3% JavaScript 2% Ruby 1%
- Scala 0.4% Haskell 0.3% scalaの話
- scala twitter
- Java 15% C++ 9% C# 4%
- Python 8% JavaScript 3% Ruby 1%
- Scala 0.4% TypeScript 0.2% Haskell 0.2%
TypeScriptは2012年リリース 2019年
辞書によって事前にどういう属性があるか明確化しなくて良くなった ハッカーと画家
- デッサンのための鉛筆 しかしundefinedの罠
- "" + 1
- 静的型付け言語「エラー」
- Python 実行時エラー TypeError: cannot concatenate ‘str’ and ‘int’ objects
- JavaScript “1”
{}["x"]
- Python: KeyError
- JavaScript: undefined
- これは静的型付けとの差ではない、動的型付け(動的検査)の言語の中でJavaScriptが特にひどいってだけ 問題の箇所から発覚箇所が離れてしまう 社会からのニーズによって急激に拡大したjsでの実装 実行がクライアントサイドで起きる 事前に問題に気づくことにたいする強いニーズ
- 2つのアプローチ
- Closure Compiler
- JavaScriptの文法に従ったまま静的チェック
- JavaDoc形式で型アノテーションを付与する
- 事例
- 2012
- JavaScriptをClosure CompilerのADVANCEDモードに完全対応させるその方法! - Cybozu Inside Out | サイボウズエンジニアのブログ
- サイボウズkintoneは2012年時点でJavaScriptのコードが10万行あった
- 2015
- Google Closure Toolsで作った大規模サービスにReactを導入した話
- サイボウズkintoneは2015年時点でJavaScriptのコードが30万行あった
- 2012
- AltJS
- 別の言語で開発し、JavaScriptに変換
- http://smurfpandey.github.io/altjs/
- たくさんの言語が誕生した
- TypeScriptもこの一つ
- 2015年の段階ではすでにTypeScript一強
-
- 2015年の2月ごろに逆転してる
- ちなみに日本人が作ったJSXというものもあるが、2019年現在ではJavaScript XMLの略としてのJSXに覆い隠されて検索困難になってしまっている
- プロジェクトページの著作権表示が2013年で止まっている
-
Copyright © 2012, 2013 DeNA Co., Ltd. et al.
-
- プロジェクトページの著作権表示が2013年で止まっている
- Closure Compiler
Python Type hints
- PEP 484 — Type Hints | Python.org
- PEP 483 — The Theory of Type Hints | Python.org
- Version3.5でライブラリとして提供された
- 2015年リリース
リスコフの置換原則
-
「サブタイプはスーパータイプの代わりに使って良い」
-
サブタイピングはサブクラス化ではない、の論文
- Cook, W.R.; Hill, W.L.; Canning, P.S. (January 1990). “Inheritance is not subtyping”. Proceedings of the Seventeenth Annual ACM Symposium on Principles of Programming Languages. San Francisco, California: 125–135.
-
Javaは1995年リリースなので、この論文は出ていた
-
型システム入門では「19.3 名前的型システムと構造的型システム」
- 型の研究としてはStructualの方が主流だった、システムがシンプル
- nominalは型が必ず名前を伴う
- class Cat extends Animal { … }
- Catという「名前のついた型」を作っている
- Subtypeであるかどうかの検証が容易
- 多分JavaなどでNominalが採用されたのは性能上の問題
- 「Scalaは遅い」という風評
- 後の研究でStructualでも高速に識別できる方法が生まれた
- 型のハッシュを作る
- この辺りのことが直接寄与したかどうか?
- Scalaが生まれた2004年から15年立つのでマシンの性能も上がっただろう
- (CPU性能よりもSSD化の方が大きいだろうか??)
- コンパイル時間の改善がStructual Typingの言語の普及に寄与した?
-
Goのインターフェイスの話、書く場所がなかった
-
https://stackshare.io/stackups/dart-vs-typescript
- TypeScriptが人気に見える
- TIOBEではDart 0.5%, TypeScript 0.2%だったけどな
- どちらも数が少なすぎてちょっとした状況で大小が逆転するって状況かなぁ
-
the more important idea is the separation of concept: data and behavior are two distinct concepts in Go, not conflated into a single notion of “class”.
-
C++ template functions exhibit structural typing on type arguments.
-
と書いてあるのだが、これって具体的にはどういう挙動のことだろう?
-
(moriyoshit)型パラメータに与えられた型のメンバに対する操作は、その型が何であれ構造が一致していればコンパイルが通るので、その旨かと
- こういうこと? cpp
-
struct A{
int i;
int j;
};
struct B{
int i;
int k;
};
template<class T>
int get_i(T& x){
return x.i;
};
int main(){
A a;
B b;
get_i<A>(a);
get_i<B>(b);
}
- これStructural Typingなのか??与えられた型パラメータで特殊化したget_iの実装が2つ作られていて、それぞれが普通にコンパイルされているだけでは。
- 普通のコンパイルにおいて"x.i"というコードはxがAでもBでも成功するけど、それをStructuralだ、と呼ぶのはどうなのか?
- `get_i<T>`の部分だけに注目する。Tに入ることができる型かどうかは「メンバーiを持っている型」という「名前ではなく構造によって決まる」
cpp
struct A{
int i;
int j;
};
struct B{
int i;
int k;
};
struct C{
int j;
int k;
};
template<class T>
int get_i(){
T x;
return x.i;
};
int main(){
get_i<A>();
get_i<B>();
//get_i<C>(); // error: no member named 'i' in 'C'
}
-
ジェネリクス(総称型)はJavaだと5.0で導入された。2004年のことである。
-
名前的な言語には、このような「総称的」機能…の拡張を持つものがある。しかしそういう拡張を施したものは、もはや純粋な名前的型システムではなく、二つのアプローチの少々複雑なハイブリッドである。発展的な型機能を備える言語の設計者は、構造的なアプローチを選ぶ傾向がある。
- 型システム入門 P.198
- C++にテンプレートが導入されたのはいつ?
- その辺りでNominalな仕組みに徐々にStracturalな仕組みが混ざり込み初めて、もはや純粋なNominalではない、ということかと
-
-
Constraints and concepts (since C++20) - cppreference.com
- https://en.cppreference.com/w/cpp/language/constraints
- 型に対してpredicateを定義でき、それがコンパイルタイムに検査される
- https://en.cppreference.com/w/cpp/language/constraints
-
(Javaは2004年にジェネリクス(総称型)の機能を採用した。これは名前的型だったJavaが構造的型とのハイブリッドに進む方向なのだが、それをページを割いて説明するかどうかは要検討)
- 要するにJavaにおいて「名前が違う」「継承関係にない」ならそれは全然別の型だったわけだが、特にコンテナなどには「そのコンテナに入れて良い」の条件を異なる型T1とT2で共有してたわけだ。
- 特定の特徴を持っているものならばコンテナに入れてよかった
- この辺のことがわかってきた段階で、純粋なNominalでは色々問題があるなぁって気づいたと言うことだな
- 要するにJavaにおいて「名前が違う」「継承関係にない」ならそれは全然別の型だったわけだが、特にコンテナなどには「そのコンテナに入れて良い」の条件を異なる型T1とT2で共有してたわけだ。
-
STLが1993年
-
function templates, class templates and, since C++14, variable templates. Since C++11
- https://en.wikipedia.org/wiki/Template_(C%2B%2B)
- あれ?と言うことは初期のSTLはテンプレートを使わずに実現されてたのか?
- 1996年のSTL解説でもテンプレートが普通に使われているなぁ
- つまり、仕様に入ったのが遅いだけで、個々のコンパイラは実装していたと言うことか?
- 1990
- https://en.cppreference.com/w/cpp/language/history
- 1990: The Annotated C++ Reference Manual
- This book described the language as designed, including some features that were not yet implemented. It served as the de-facto standard until the ISO.
- New features: namespaces, exception handling, nested classes, templates
- This book described the language as designed, including some features that were not yet implemented. It served as the de-facto standard until the ISO.
- というわけで1990にはデファクトになってた、と。
- C++11で入ったのは可変長のテンプレートであって、固定長のものは前からあったのだ
- https://en.wikipedia.org/wiki/Template_(C%2B%2B)