[Swift 3.0] C-styleのforループがなくなる話
おばんです、昨日の地震は揺れの中にもかかわらずもくもくとissueを立て続けていた田中です。
前回++, --などのオペレータがなくなる話について、公式のproposalを読みながら解説していく記事をあげました。 今回は前回の内容とも関連のあるC-styleのforループがなくなる話です。
C-styleのforループというのはつまりこういうタイプのforループです。
for var i = 0; i < 10; i++ { // do something }
初期値と、繰り返し条件と、インクリメントのおなじみのforループです。 Swift 3ではこれをなくして、for-inタイプのみにしようというproposalがあがっています。
なぜC-styleのforループをなくすのかについて、swift-revolutionのproposals、0007-remove-c-style-for-loops.mdをオレオレ和訳・オレオレ解釈で読んでみることにしました。
訳・意味がおかしい等ありましたら@ktanaka117まで、こっそり教えてください。
以下はそのまとめです。
Remove C-style for-loops with conditions and incrementers(コンディションとインクリメントをもったC-styleのforループを除外する)
Introduction(紹介)
C-styleのforループは純粋にはっきりしたSwiftの構造というより、機械的にCから引き継いだもののように思われる。 めったに使うものでないし、とてもSwiftらしくない。
より典型的なSwiftの構造をしているのはfor-inとstrideである。 - ① forループを除外することは言語をシンプルにし、利用方法が共通理解としてある、すでに除外される予定の--と++に苦しまなくてすむ。
この構造の価値は限られており、C-styleのforループを除外するということは考慮するに値する事項であると思う。
このproposalはSwift EvolutionのリストのC-style For Loopsスレッドと[Review] Remove C-style for-loops with conditions and incrementersスレッドで議論された。
Advantages of For Loops(良い点)
Swiftは近しい作りの言語仕様をもった言語からきた初学者をサポートする。 forループはCの真似であり、この制御構文を理解するのにそんなに努力がいらない。
Disadvantages of For Loops(悪い点)
- for-inとstrideはどちらも、レガシーテクノロジーに依らない、Swiftらしい一貫性のあるアプローチをすることによって同等の振る舞いを提供する。
- はっきりとした表現の面での不利がある。forループとfor-inを比べると、for-inのほうが簡潔である。
- forループの実装はcollectionや他のSwiftの中心となる型を取り扱うのに適さない。
- forループは、じき排除される単項インクリメントとデクリメントの使用に力添えしてしまう。 - ②
- 宣言に制限を加えるセミコロンは、Cに似た言語以外からSwiftに来たユーザーの学習を妨げる。
- もしforループが今(Swift 2.x系に)存在しなければ、私はSwift 3に追加しないと思う。
Proposed Approach(提案)
Swift 2.x系ではdeprecatedとし、Swift 3では完全に除外することを提案します。 適用範囲は最新の2.2のアップデートの修正から除く。
Alternatives considered(考えうる代替案)
forループをSwiftから除外しないと、言語の合理性と不必要な制御構文を捨てる機会を失うことになる。
Impact on existing code(既存のコードへの影響)
AppleのSwiftのコードベースにおける調査によると、この言語仕様はめったに扱われないという。 Swift-Evolutionのメーリングリストに入っているコミュニティーメンバーは多くのプロレベルのアプリにおいてforループが取り上げられず、それらは対処できるということを認識している。
Swiftのgistにおける調査によると、このC-styleのforループを主として使うのは、ちょっとの言語スキルで新しく言語を始める人々や言語をマスターする前に次々に乗り換える人々である。
注釈
①for-inとstride
for-in
let nums = [0, 1, 2] for i in nums { print(i) } // 結果: // 0 // 1 // 2
stride
for i in 0.stride(to: 3, by: 1) { print(i) } // 結果: // 0 // 1 // 2
②インクリメントとデクリメントの除外
こちらの前回の内容の話。 元は0004-remove-pre-post-inc-decrement.md そもそもこれがなくなると、これまでのforループの最後にくるi++が書けなくなってくる。
まとめ
全体を読んでみてわかったことは、
- C言語からの脱却をしていきたい
- 初めてSwiftを学ぶ人にとって複雑である
- C-styleのforループは古めかしい、Swiftらしくないという感覚があるらしいこと
前回の++, --の話でも出ていましたが、C言語ファミリーから来た人にとっては当然あるものという感覚のこのforループ。
今回は力尽きたので訳せませんでしたが、Community Responsesもだいぶ面白い内容になっています。 「あんまり使わないよ」とか、「古めかしいにおいがする」とか。
そこも含めて読んでみると感覚として「イケてない」という印象がC-styleのforループにはあるようですね。 以前まで自分もこれまでのforループを結構使っていましたが、Swiftにおいてはfor-inの記述がとてもすっきりしていてそちらばかり使うようになりました。 「イケてない」というのは、言い換えるとプログラマーが避けたがる「冗長な書き方」みたいなところなのかなと思います。
もう
for var i = 0; i < nums.count; i++ { // hogehoge }
とか書きたくない。
自分の意見としてもC-styleのforループはなくしてしまっても構わないかなという感じです。 for-inが便利ですし、Swiftには他にもforEachやmap, filterなど近しい表言が多く出てきます。 そこに馴染んていくことが初学者にとってもより上達への近道になって良いんじゃないかなあと思います。