https://www.youtube.com/watch?v=y2pOVDx7gVA
勉強会を始めるにあたって、当初予定していた The Swift Programming Language
に入っていく前に Swift.org
の About Swift
から眺めていくと「Swift ってどんなプログラミング言語なんだろう?」みたいなところから見ていけそうで楽しそうに思えたので、まずはここから始めていってみることにしますね。どうぞよろしくお願いします。
———————————————————————— 熊谷さんのやさしい Swift 勉強会 #2
00:00 開始 02:01 Swift.org 03:09 Swift 言語 04:49 Swift 言語の概要 07:11 目標を達成するために 09:00 Safe 10:10 安全性の重視がもたらす恩恵 12:39 エラーを通知する場面 19:57 エラーが発生する可能性を視覚的に表現 23:31 Fast 25:20 予測可能な速度性能 28:28 ARC 32:32 Expressive 35:17 ツールの重要性 39:31 クロスプラットフォーム 46:17 クロージング 47:48 質疑応答 ————————————————————————
Transcription & Summarize : 熊谷さんのやさしい Swift 勉強会 #2
今日は Swift について説明していきます。この Swift という言語がそもそも何なのか、見ていったら楽しいんじゃないかなと思って、今日は Swift.org というサイトの「About Swift」を皆さんと一緒に見ながら説明しようと思います。単に読むだけでは面白くないかもしれないので、それと実際の Swift を照らし合わせながら話していく予定です。
今回の目標は「About Swift」を全部読むことではなくて、時間の許す限りで読み進めて、読み切れなかった部分は次回に回すことにしますので、ゆっくりやっていきます。ちょっとしたことでも思ったことがあれば、遠慮なく話しかけてください。マイクをオンにしておいて大丈夫ですので、いつでも話しかけてくれて構いません。また、話しかけるのがちょっと怖いという方はチャットでも大丈夫です。私が適当にチャットを拾いますので、ぜひ積極的に参加してください。
では、いろいろ見ていきましょう。この Swift.org というウェブサイトには結構情報がまとまっているので、暇なときに眺めてみると Swift のことがよくわかると思います。では、「About Swift」に行きましょう。ここからのスライドはその「About Swift」の中からほぼそのまま切り出してきたスライドになっています。これを基本にやっていきますが、ホームページに書いてあることと同じ内容です。
「About Swift」には Swift 言語とは何かが記されている公式ドキュメントがあります。コンセプトや機能の方向性などが端的にまとめられているので、見ると意外と面白い内容です。
まず、Swift 言語ですね。2014年の WWDC、Apple の開発者カンファレンスで発表された言語になります。当時を見ていたからか、新しい言語というイメージを持っていましたが、もうだいぶ経ちますね。2021年でしょ、7年ですね。なんかそんなに経っている気がしないですね。もう3、4年、せいぜい5年くらいの時間感覚でしたが、あと3年で10歳ですよね。あっという間に10周年とか言って盛り上がりそうですね。開発当初から計算すれば10年経っているはずです。Apple の内部では盛り上がっているかもしれませんが、みんなが盛り上がるのは10年くらい経ったときでしょうかね。
そういう言語ですが、だからといって古くなってきたというわけでもないところが、また Swift 言語の面白いところかなと思います。
Swift 言語はどういったものとして作られているかを紹介します。今時のアプローチ、モダンと言われることが多いですが、安全性、性能、速度、デザインパターンに重点を置いて今時の技術でアプローチした汎用プログラミング言語とされています。汎用と呼ぶにはもう少し時間がかかる感じもしますが、それが目標として掲げられている言語です。
Swift プロジェクトのゴールは、様々な用途で使える最高の言語を目指すという非常に崇高なものが掲げられています。様々な用途で使えるというのはまだ途上ですが、最高の言語という部分では結構いい線行っているかなと個人的には思っています。言語は好みの問題もありますが、いろんな言語を等しく楽しんでいけたら良いかなと思います。
大事なところとして、Swift は正確なプログラミングを簡単に書いたり維持したりできるように、というのを念頭において作られているところが大きいです。これは徐々に実現されている印象がありますが、遠慮なく「ここ面白いよね」みたいなところがあれば言ってきてください。いつでもオッケーです。
さて、Swift では目標を達成するために3つのことが掲げられています。 セーフ・ファスト・エクスプレッシブ。これね、Swiftが発表された当初は、確か4つあって「セーフ・ファスト・モダン・インタラクティブ」だったような気がするんですけど、今はこの3つになってますね。
モダンがなくなったんですよ。まぁ、モダンなんて今では当たり前でしょ、みたいな感じですかね。今さら言わなくてもいいですよね。だから、モダンは死後になった、みたいな。そういう辺りでしょうか。
あと、インタラクティブも常識っていうところなんですかね。Swiftにとってはね。まあ、Swiftだけじゃないですよね。それより前からREPL環境、即座に実行して結果を得るようなものが既に充実というか先端のものとして存在していた中で、Swiftもそれに習ってREPLを充実させて、という感じで登場当初は歌い文句だったけど、まあ今はそこまで言うこともないかな、っていう時代になってるようですね。
で、この3つそれぞれを詳しく見ていこうかなと思うんですけど、Swiftで言う「セーフ」とはどういったものか。分かりやすいコードは安全に動作するコードでもあるはずっていう信念があるらしいです。未定義な動作は安全性の低下を招くっていうのもあります。開発者によるミスはソフトウェアが運用される前、要はランタイムより前に発見されるべきっていうね。こういったところを「セーフ」というコンセプトでまとめているようです。
自分がSwiftを使っていく中で如実に感じるのは、この「セーフ」ですね。これが売りみたいな、そんなふうにも感じるところなので、この辺を注目していくとSwiftが読み解きやすくなる、そんな印象を持ちます。
あと、About Swiftに面白いこと書いてあったんですけど、安全性を重視することで厳格で手間がかかる言語に思われがち、感じがちだけど、それが明瞭さや開発効率の向上につながると信じてる、みたいなことが書いてあったんですよ。
これはね、実際にSwiftをやったことなかった人がSwiftをいじってみて、最初は「なんだこの言語、うるさいな」って思いながらやってたけど、いつの間にかそれに馴染んでいくとすごく便利だ、開発効率の向上につながるって体感できると思うんですよ。この辺りがね、まさにその通りだなって思うところです。
最近、ちょうどこんな感じを再び感じたことがあって、ある外部SDKを使っている案件でSDKの内部でエラーが発生して、問題発生時にキャッチしようとしている話題がありました。そもそもiOSにおいてAPIがスローズじゃなくて、そもそもエラーが発生しないという方向になってて、エラーがあるとしてもランタイムエラーでどうしようもない問題だけで。それが当たり前になってて、別の言語で「なぜこういうことを心配してるのか」と最初は理解できなかったんですよ。話してみたらそういうことがありました。それで再び感じました。
そのランタイムではちゃんとエラーが外に通知されるみたいな感じで設計されてるんですね。通知する場合はスローズをつけて、全員がキャッチしないといけないし、それ以外のケースではもちろん必要がなくて、心配する必要もなくなります。
そうですよね。その辺りがね、特にエラーを通知する場面っていうのかな、通知する可能性がある場面では必ずthrows
っていうキーワードをつけることによって、そのAPIを使う側にとっても「ここは注意ポイントですよ」っていうのを知らせられるようになってます。例えば、それまでのオブジェクト指向言語とかでよくあった例外処理では、いきなり何の予告もなく突然ここでエラーが出る、みたいなことがありました。意外と簡単にかけてるつもりでも、思った以上に複雑であったりすることもあります。
具体的な話だと、こういう感じなんですけど、例えばfunc getData() throws -> Data
みたいなメソッドを作るとします。これを外で使うことになるわけですが、普通、例外が発生するような時にはそれを通知する必要があります。まず型で通知するというのをあらかじめ作り、次に実際にエラーをスローするという書き方をします。
Swiftの場合、エラーをスローするためには何らかの対応をしなければなりません。外に対してエラーを通知する必要があるのか、または内部で解決できるのかを考えなさい、と言われています。たとえば、この中でエラーを解消すれば済む場合は、それを内部で解決するように設計します。
イメージがしにくいかもしれませんが、こんな感じですね。 何かしらのコンディションがあって、イフ文で計算を行い、そのコンディションが成り立たなかった場合にエラー処理をすることが普通でしょう。そして、もしエラーが発生したときに自分の中で解決できる問題であれば、キャッチして何らかの処理をすることでエラーを解消します。まず、こういった設計になっていて、エラーが発生する可能性があるときにプログラマーが何をすべきか、エラーが発生したらどうすべきかをコンパイラーが指示するのです。これが最初のうちは面倒に感じるかもしれません。しかし、外部に任せる必要がある場合でも、必要なコードを書くように要求されます。
例えば、関数が何らかのエラーを投げる可能性があるときには、その関数がエラーを投げることを明示する必要があります。これによって、関数を実装する上でエラー処理が適切に行われることがプログラマーに要求されるのです。これによって、プログラマーがうっかりエラーの可能性を忘れることを防ぐことができます。実際に呼び出すときも、そのメソッドがエラーを返す可能性があることが throws
キーワードによって示されているので、コンパイラーがエラーで通知してくれます。このため、プログラマーは何らかのコードを書かなければならない状況に置かれるのです。
一見面倒なように見えますが、エラーが発生して思いがけないランタイムエラーが起きることを防ぐ重要なポイントです。例えば、エラーが起きちゃったらどうでもいいという場合には、トライビックリマーク(try!
)で表現できます。また、エラーが起こる可能性がある場合は do-try-catch
を使ってエラー処理を行う必要があります。これによってエラー処理を忘れることがなくなるのです。こうした安全設計がされているのが Swift の一部です。
このような設計により、エラーが発生する可能性があるコードが try
キーワードで明示されます。これは非常に便利で、初めて見たときに感動したポイントです。従来の言語では、 try-catch
が一般的でしたが、この方法だとどこでエラーが起こるかを把握していないといけません。JavaやC++、Objective-C でもそうだったと思いますが、Objective-C はエラーが発生するときの処理をあまり考えなくても書ける言語でした。
Objective-C では nil
にメッセージを投げても全く無視するという大胆な仕様がありました。それが意外とうまく動くこともありましたが、これは Swift とは対照的です。Objective-C ではデベロッパーが全て正しいという前提ですが、Swift ではコンパイラーが全て正しいという思想です。この違いが非常に面白いところですね。
Swift では do-try-catch
の導入により、コードを見ただけでどこでエラーが発生するかが明確になります。これが安全設計がもたらした過読性の高さと言えるでしょう。
Swift の面白い点は他にもたくさんあります。次に、「Fast」(高速性)についてお話しします。Swift は C言語ベースのプログラミング言語を置き換えることを目的としており、これは非常に大胆な目標です。C や C++、Objective-C などの言語は長い間プログラミング業界で支配的な地位を占めてきました。特に C 言語は処理速度が非常に速いことが特徴です。
続きはまた別の機会にお話しします。 Swiftはとりわけ速い速度性能を発揮することを目標としています。ただの一時的な速度ではなく、予測可能で安定的な速度が求められます。ここで、多くのプログラミング言語が持つガーベージコレクション(GC)とは異なるアプローチが必要になります。SwiftはGCを採用せず、代わりにオートマチック・リファレンス・カウンティング(ARC)を使用しています。例えば、Go言語は速いと言われていますが、GCに依存しています。それに対し、SwiftはGCを使わないため、異なる設計方針を持っているのです。もちろん、GCを使用する設計も便利な場合はありますが、Swiftの目標とは少し異なります。
一般的に、言語を簡略化してコードを書きやすくするためには、GCのような機能を導入し、クリーンアップを後回しにすることがあります。しかし、C++のようにメモリ管理をマネジメントすると非常に複雑な言語になることもあります。Swiftはこのバランスが非常に良く、安定的な速度を維持しながらも簡潔に素早くコードを書くことができるのが特徴です。
そして、iPhoneが長い間Androidよりも少ないメモリで同等以上の性能を発揮できていたのも、このメモリ管理のアプローチによるところがあります。例えば、iPhoneは最大でも3GBのメモリでしたが、Androidは早い時期から4GBや8GBのメモリを搭載していました。これは、AndroidがJava仮想マシン(JVM)を必要とし、JVMがGCに頼っているため、実質的にメモリ利用が膨らんでいってしまうためです。
Objective-Cも一時期GCを採用した時期がありましたが、それを止めてARCに移行しました。ARCの仕組みは、変数がスコープに従って管理されるというもので、例えば変数がスコープの中で使われるとき、明示的にリテインやリリースを指定しなくても自動的にメモリ管理が行われます。これにより、メモリの解放タイミングが自動的にスコープの終了に合わせて決定されます。
SwiftのARCにより、例えば以下のようなコードが自動的に管理されます:
var object = SomeClass()
// スコープ内で利用
// スコープ終了時に自動でメモリ解放
このように、後で別のメモリ管理サイクルが動いて未使用のメモリをまとめて廃棄するという手間をかけずに済みます。ARCがうまく働くことで、予測可能で安定的な速度性能が実現されているのです。
もし、Swiftのメモリ管理に興味がある場合、「ARC」というキーワードで調べると、様々な興味深い情報を見つけることができるでしょう。
次に、Swiftのもう一つの特長である「エクスプレッシブ」について説明します。これは、コードが表現力豊かであるということを指します。Swiftは、長年にわたって発展してきたコンピュータサイエンスの知見を取り入れ、開発者にとって楽しいと感じられる現代的な機能を提供しています。Swiftには終わりがないとも言われ、継続的な進化が期待されています。
このようにSwiftもどんどん進化し、興味深い変化を見せている点が魅力的だと感じました。 7年間でメジャーバージョンが5になった言語を見たことないですね。本当にそうかもしれないですね。Pythonなんて、これだけ長い時間かけてようやく今Python3ですしね。
確かに、それでいて古いものをどんどん削っていって、オープンソースになって若干速度が落ちましたけど。それなりに早い速度で古いものを消していくことで、古いもののしがらみがなくなる。結果として、今まで使っていた文化を開発者が捨てることを強いられることもありますが、それによって全体として発展していくという面もあります。
それなりに勉強は必要ですが、そのおかげでみんながレベルアップし、コードがより洗練されて、より快適に書けるようになるというのが面白いところです。
あと、ツールの重要性という点も大事です。確かSwiftが出て間もない頃に、Swiftのエコシステムにとってツールも重要だということが語られていました。実際にツールも発展していて、例えばXcodeがかなり発展し、より統合開発環境らしくなっています。プレイグラウンドのようなものが登場し、コードの読み込み・実行・結果表示がループサイクルで回ってリアルタイムに実行できるものが入ってきています。
Swiftだけでなく、開発ツール全体も発展しています。例えばOpenGLのレンダリングをキャプチャーできる機能や、ビューの階層をリアルタイムレンダリングしたりといった機能が強化されてきています。他にも、昨日のiOSのLT会でもあったようなVimのサポートなど、Xcodeの機能強化が進んでいることがわかります。
現状のXcodeは、Swift言語と密接に連携し、Swift言語をより効率的に開発できるような機能追加がなされています。今後もどんどんXcodeなどの開発ツールが発展していくと考えられます。
例えば今年のXcodeでは、ようやくIDEっぽくなってきたというコメントがありましたね。またXcodeクラウドのような新機能が出てきており、これからの発展が期待されています。
また、最近実装されたSwiftパッケージマネージャーなども挙げられます。さらに、Swiftプレイグラウンドも進化しており、iPadでiPadアプリが作れるようになりました。このため、Macを持っていなくてもアプリが作れる状況になっています。(ただし、Macアプリは作れないという制限はありますが)
Swiftの目標の一つにはクロスプラットフォームが掲げられています。現状ではまだ初期段階ですが、Swiftは最終的に全てのプラットフォーム間でソース互換性を提供する目標を持っています。つまり、将来的にはiPadのプレイグラウンドでMacOSアプリなども作れる可能性があります。
現在、AppleプラットフォームにはObjective-Cランタイムが組み込まれていますが、他のプラットフォームはそうではありません。そのため、Objective-Cランタイムに依存しない基礎的なフレームワークをコアライブラリで提供しているということが書かれています。SwiftUIもその一つで、これからの発展が期待されます。
まだまだ先の話かもしれませんが、AppleのMacOSだけでなく、LinuxやWindowsアプリなど、さまざまなプラットフォームを見据えているように感じられます。 実際、この「About Swift」の中でも一番最後に書かれている内容について話そうと思うと、相当後になるかもしれません。しかし、Swiftももう7年が経っており、いよいよiPadアプリがXcode以外でも作れるようになってきました。そろそろ10周年で大きな変化があるかもしれないと思うと、楽しみになってきますね。
そのためにはまず、SwiftUIを純粋にSwiftで作らないといけません。現状のSwiftUIはまだ裏でUIKitやAppKitが動いています。これが重要なポイントですね。SwiftUIというレイヤーがあることで、UIkit(iOS用)やAppKit(macOS用)の上にSwiftUIが入り、これらを取り除く準備が進んでいます。
将来が楽しみな状況になってきました。クロスプラットフォームが好きな人にとっても、これからが楽しみな段階に入っているのではないでしょうか。現状でもiOSとmacOSが同じコードベースで使える部分が増えてきています。全部ではないとはいえ、だいぶ共通して使えるようになってきているので、ここも面白いですね。
Appleプラットフォーム間でのクロスプラットフォームと言うと少し大げさかもしれませんが、その間でのクロスプラットフォームはかなり進んでいます。今後、LinuxやWindows、Java仮想マシンなどでもSwiftが使えるようになれば、さらに興味深い展開が期待できます。オープンソースプロジェクトやコアライブラリーが充実している今、積極的にアプローチするには良いタイミングかもしれません。
こういう視点でSwiftUIを捉え直すと、印象が変わってくるかもしれません。単純にUIKitやAppKitの代替としてのSwiftUIではなく、クロスプラットフォームを見据えた存在として捉えると、UIkitやAppKitが将来的に捨てられる可能性も出てくるでしょう。とは言え、共存を期待する人は早めに考え直したほうが良いかもしれません。
話を戻すと、次回予告になるかもしれませんが、今回はざっくりと「セーフ・ファースト・エクスプレッシブ」の3つについて、具体的なコード例を交えながら紹介しました。Swiftの特徴をだいぶ捉えられたような気がします。時間がなくなったので、Swiftの機能については次回お話ししましょう。オブジェクティブCから比べて追加された面白い機能など、具体的なコードと照らし合わせて紹介できればと思います。
とりあえず今回の勉強会はこんな感じでしたが、いかがでしたか?Swiftの概要についてや、新しい捉え方ができたのではないでしょうか。
「Swift.org」にもAbout Swiftの他にプログラミングガイドやAPIデザインガイドラインなどが細かく載っていますので、これも勉強会で順次見ていこうと予定しています。
川島さんの解説で、安全の重要性についても強く意識されているというのが印象深かったですね。Swiftで初めて出てきた「nil」がオプショナルじゃないと使えないという点には驚かされました。特にC言語を経験している人にとっては戸惑った部分ですが、iOSプログラマーの間でもオプショナルについて熱い議論が交わされましたよね。
オプショナルについても話題が尽きないので、その回もお楽しみください。About Swiftの中でも取り上げられているので、次回かその次の回で詳しく見ていきたいと思います。
では、ちょうど良い時間となりましたので、今回の勉強会はこれでおしまいにしようと思います。