swtws Promiseのやつ

0
koher @koher

それでは、 Swift 4 が出たばかりでやや気が早いですが "Proposalには載っていないSwift 5のasync/awaitが素晴らしいと思う理論的背景" というタイトルで発表します。 #swtws

2017-10-21 22:19:34
koher @koher

2ヶ月ほど前、 Chris Lattner から swift-evolution に "async/await + actors" というタイトルで驚きのメール lists.swift.org/pipermail/swif… が流れました。 #swtws

2017-10-21 22:19:56
koher @koher

これは Swift における並行処理関連の提案で、主に `async/await` と `actor` についてのものです。今回の発表では、そのうち `async/await` に着目します。 #swtws

2017-10-21 22:20:16
koher @koher

`async/await` といえば C# や JavaScript が思い浮かびますが、 Swift の `async/await` は Swift にフィットするように独自の変更が加えられています。 #swtws

2017-10-21 22:20:38
koher @koher

まだ正式な Proposal になっていませんが、 gist.github.com/lattner/429b90… から Proposal 全文を閲覧できます。これを読めば Swift の `async/await` がどのようなもので、何のために提案されているのかがわかります。 #swtws

2017-10-21 22:21:00
koher @koher

この Proposal は平易な英語で書かれていて読みやすいので、是非一読をオススメします。 Proposal に書かれていることをそのまま話してもおもしろくないので、今日は Proposal では詳しく述べられていない背景思想について説明します。 #swtws

2017-10-21 22:21:22
koher @koher

とはいえ、予備知識がなくても、基本的な Swift の構文さえ知っていれば `async/await` について一通り理解できるように説明するので安心して下さい。 #swtws

2017-10-21 22:21:42
koher @koher

実は、僕はこの Proposal の `async/await` とほぼ同じ内容のものを提案しようと考えていました。 GW 頃にまとめ、 @rayfix さんに英文のネイティブチェックをしてもらったものが gist.github.com/koher/3e04b4f1… です。 #swtws

2017-10-21 22:22:04
koher @koher

ただ、当時すでに Swift 4 のまとめの時期に入っており新機能を提案できる感じではありませんでした。 Swift 5 の議論が始まったら投稿しようと思ってそのまま寝かしていました。 #swtws

2017-10-21 22:22:26
koher @koher

そして、 8 月にようやく Swift 5 の議論が始まったのでそろそろ投稿しようかと思ってたところに冒頭の Chris Lattner のメールが投稿されました。中身を確認してみると自分が考えていたのとほぼ同じ内容だったのでびっくりというわけです。 #swtws

2017-10-21 22:22:48
koher @koher

しかし、 Proposal の説明は自体はとてもわかりやすいのですが、その説明は僕がほぼ同じ `async/await` に思い至った経緯とはずいぶん異なっていました。 #swtws

2017-10-21 22:23:10
koher @koher

この発表では、僕がそのような `async/await` に至った過程を説明することで、なぜこの `async/await` が Swift に良くフィットするのかを説明します。 #swtws

2017-10-21 22:23:32
koher @koher

## コールバック地獄 Swift の非同期処理にはコールバックが用いられることが多いです。 `Delegate` もありますが、 Obj-C 由来なのでここでは触れません。 #swtws

2017-10-21 22:23:54
koher @koher

コールバックの問題としてよく知られるものに『コールバック地獄』があります。↓のように、複数の非同期処理を連ねるとピラミッド状のネストが生まれてしまいます。可読性もメンテナンス性も良くありません。 #swtws gist.github.com/4ff848a1acfd0f… pic.twitter.com/l6SLlXsFjW

2017-10-21 22:24:16
拡大
koher @koher

## `Promise` コールバック地獄の対策の一つとして、 JavaScript で有名になった `Promise` があります。 #swtws

2017-10-21 22:24:38
koher @koher

`Promise<Foo>` は今はまだ手に入っていないけど、将来のいつか手に入る `Foo` 型の値を意味します。 #swtws

2017-10-21 22:25:00
koher @koher

たとえば、 `url` を渡して `Data` をダウンロードする関数 `download` を考えてみます。コールバック版と `Promise` 版のシグネチャはそれぞれ次のようになります。 #swtws gist.github.com/0e0c3d798f78a7… pic.twitter.com/YlOSQcCoRv

2017-10-21 22:25:22
拡大
koher @koher

`Promise<Data>` を将来のいつか手に入る `Data` 型の値と読めれば、 `url` を渡して `Promise<Data>` を返してくれる後者の方が(少なくとも僕は)わかりやすいと思います。 #swtws

2017-10-21 22:25:44
koher @koher

では、 `Promise` を使ってどのようにコールバック地獄を解消するのでしょうか?そのためにはもう少し `Promise` について説明しなければなりません。 #swtws

2017-10-21 22:26:06
koher @koher

### PromiseK 僕の勤務先である Qoncept では、 Swift 1.0 のリリースと同時に Swift を使い始めたんですが、 2014 年の年末頃にはコールバック地獄の問題が顕在化していました。 #swtws

2017-10-21 22:26:28
koher @koher

そんなときに、さっき発表してくれた僕の同僚の @omochimetaru が「 Swift にも JavaScript の `Promise` がほしい。」と言って Swift で再現したものをサクッと実装し、使い始めました。 #swtws

2017-10-21 22:26:50
koher @koher

僕はそのとき初めて `Promise` を知ったんですが、使ってみてなかなかいいなと思いました。しかし、使っている内に僕はいくつかの不満を抱き始めました。 #swtws

2017-10-21 22:27:12
koher @koher

たとえば、 Swift 1.0 の頃には `Optional` の `nil` でエラーを表すことが一般的でした。しかし、 JavaScript の `Promise` は非同期だけでなくエラーも扱っていました。 #swtws

2017-10-21 22:27:34
koher @koher

非同期処理はエラー処理を伴うことが多いとはいえ、本質的には二つは直交した概念です。 Swift にはせっかく `Optional` があるのに、 `Promise` を使うときは `Promise` でエラー処理をするというのが気に入りませんでした。 #swtws

2017-10-21 22:27:56
koher @koher

そこで、 JavaScript の `Promise` からエラー処理に関する機能を取り除いて非同期処理に特化した `Promise` ライブラリ PromiseK github.com/koher/PromiseK を作りました。 #swtws

2017-10-21 22:28:18
1 ・・ 8 次へ