今年秋?公開予定で現在まだ絶賛開発中の Swift 3.0 ですが、GitHub のレポジトリには昨日 Swift 3.0 API Guidelines に沿ってソースコードを修正したコミットの Pull Request が承認されました。これで 3.0 が正式に公開されたら間違い無く大半のプロジェクトはまた地獄のようなソースコード改修が余儀無く必要になってくるが、せっかくなのでその前にこの修正コミットの内容を見てみて、これからのソースコードはどういう風に修正されることになりそうなのか、心の準備も進めてみたいと思います。
まあ Standard Library 全体の修正だから修正箇所があまりにも多すぎるので全部見るのに時間がかかるからとりあえずスクロールして気になったところをピックアップしてみたいと思います。
まず第一の感想として、命名規約の冗長性がある程度改善されるようですね。まあこれ一番最初の修正ですからね。string.uppercaseString が、string.uppercased になります。同様に string.lowercaseString も string.lowercased になります。String 型のインスタンスプロパティなのでプロパティ名に string をわざわざ入れる必要もないんじゃね?という感じで今まで冗長しすぎた名前をある程度簡略化した感じになります。
次に思ったのは、メソッド名の構成の脱 Obj-C 化をを感じましたね。何が言いたいかというと、今までの Swift の関数名は、ずっと Obj-C の時の名残で、1 つ目の引数の説明はラベルではなく関数名に入れたまま作られています。例えば今回は dictionary.removeValueForKey(:) のメソッドが、dictionary.removeValue(forKey:) に変わりました。つまり 1 個目の引数の説明である forKey が、今まで関数名の中に入って removeValueForKey 全体が関数名でしたが、3.0 では関数名は動きを表す removeValue のみとなり、1 個目の引数の説明である forKey がラベルになったのです。これが引数一つしかない時だと割と「だから?」って感じがしないでもないかもしれませんが、でも引数が増えていくと、関数名とラベルの混在が初心者にとって混乱を引き起こしかねないという問題があるのではないかと思います。例えば SpriteKit ですと、SKAction というクラスに「移動する」というクラスメソッドがあります。これは Obj-C で書くと [SKAction moveToX: y: duration:]; という結構見やすい文法になりますが、Swift ではメッセージ式構文をやめて C と同じような構文にしたので、SKAction.moveToX(:, y:, duration:) という構文になってしまいました。これで moveToX までが関数名で、y と duration だけがラベルとなってしまいます。なんか気持ち悪いですよね、x と y は同列のはずなのになんで x は関数名に、 y はラベルに入るんですか?まあ慣れの問題でしょうけど Obj-C 触ったことのない Swift 初心者にとってはあまりフレンドリーではないのは事実です。今回の Pull Request はあくまでオープンソースの Swift に対してのもので SpriteKit に対しての修正がまだ見当たりませんが、この流れで行くとおそらく Swift 3.0 では SKAction.move(toX:, y:, duration:) に変わるんじゃないかと思われます。これでスッキリしますね、メソッド名はメソッド動作の move のみ、引数の扱い方 to も、引数 x も y も duration も全てラベルとなり初心者にとってわかり易いのではないかと思います。
そしてもう一つ大きな変化は、enum の case が UCC(UpperCamelCase。Pascal 記法とも呼ばれる?)もしくは大文字から LCC(lowerCamelCase) に変わるっぽいですね。例えば public enum ProcessTerminationStatus という enum がありますが、中身は今まで case Exit(Int) と case Signal(Int) でしたが、case exit(Int) と case signal(Int) に修正されました。Pull Request の修正内容見ると全部が変わったわけではありませんが、それは単に修正し忘れなのかそれとも仕様として残しているのか何なのかは正式リリース出るまでわかりませんが、おそらく多分 LCC に変わるでしょう、と個人的に思います。なぜなら Swift の命名規約としては、包括的な定義?、例えば class とか struct とか enum とかひいてはライブラリ名の Foundation とかは全て UCC 命名で、逆にそれらの具体的な部品?例えば class や struct のインスタンスとかメソッドとかプロパティとか変数とか(まあぶっちゃけ変数だって、例えば Int 型変数も Swift では Int という struct のインスタンスだけどね)は LCC 命名になります。このルールで見ると、確かに本来なら変数と同じような動きをする enum の case だけが UCC 命名になっていたのがおかしかったとも言えます。(ちなみに余談ですが現在筆者を一番悩ましてるのが C# の命名規則です。変数以外、プロパティ含めてほとんど何でもかんでも UCC 命名だから見てるとそれが何なのかすぐにはわかりづらい orz)
あとはまあ細かい英文法に則った修正ですかね、自分をソートした配列を返す array.sort() メソッドが array.sorted() に変わったとか(sort() だと自分自身に対して sort する mutating func sort() -> Void のような動きを感じさせるからな)split.maxSplit が split.maxSplits に変わったとか(まあ普通は複数形使うよなここ)みたいな細かい英文法的な修正です。細かいところですが、「ソースコード自体がドキュメント」(正確な名前忘れたけどどこかで見た気がします…)精神を Objective-C から引き継いだ Swift だからこそ、大体なものはドキュメントなんて用意しなくてもソースコード見れば何をどうしたいのかがすぐわかるように自然言語に近い文法でコーディングすることは非常に大切だと思います。そしてそれを実現するための第一歩がまさにこの変数名やメソッド名の吟味にありますね。