Guild icon
swift-developers-japan
コミュニティ / swift-zoomin
Avatar
今週の土曜日( 10 月 20 日)の 21 時から、本チャネル #swift-zoomin で Swift Tweets 2018 Fall https://swift-tweets.connpass.com/event/94689/ を開催します。これまで Swift Tweets は Twitter 上で開催されていましたが、 Twitter の制約や、元々想定していた双方向コミュニケーションが思ったようにうまく機能していなかったため、今回は試験的に Discord 上で開催してみることになりました。よろしくお願いします!
# 概要 Swift Tweets はこれまで Twitter 上で開催されていましたが、 Twitter の制約や、元々想定していた双方向コミュニケーションが思ったようにうまく機能していなかったため、今回は Discord の swift-developers- ...
😀 9
swift 7
12:47 AM
内容についても、これまでの発表形式ではなく、より双方向性の高い Interactive Round Table ( iOSDC Japan 2018 で行われていた催し https://blog.iosdc.jp/entry/2018/07/24/100415 )のような形を考えています。
こんばんは。 iOSDC Japan 2018 実行委員長の長谷川です。 先日、iOSDC Japan 2018 のタイムテーブルを公開しました。 その中に「IRT」という時間がありますが、今日はそのIRTのご紹介です。 IRT: Interactive Round Table IR...
Avatar
30 分後、 21 時から Swift Tweets を始めます。
👀 7
👌 4
😀 2
Avatar
あと1分ー
👍 7
Avatar
参加者のみなさん、今からSwift Tweetsを始めます。よろしくおねがいします!
🎉 14
👏 8
12:00 PM
本日、総合司会を担当します @koogawa です。どうぞよろしくお願い致します。
swift 1
Avatar
よろしくおねがいしますー!
Avatar
まず最初に、今回TwitterではなくDiscordでの開催になった経緯を主催者の @koher さんからお話していただきます
12:01 PM
@koher さん、よろしくおねがいします!
Avatar
よろしくおねがいします!
12:01 PM
前回、前々回と発表中に Twitter の制約に引っかかり
😩 5
12:01 PM
発表途中にアカウントを凍結されてしまうというトラブルがありました。
12:02 PM
また、 Twitter の規制は厳しくなっている傾向がありました。
12:02 PM
Organizer の @koogawa さんと @takasek さんと話し合ったのですが、
12:03 PM
Twitter では結構一方公的な発表になってしまっていて
Avatar
当初見込んでいた、みんなで Swift についてわいわい話そうということもなかなか実現できてなかったので
12:03 PM
思い切って今回は Discord でやってみてはどうかという結論に至りました。
12:04 PM
新しい試みでどうなるかわからないのでドキドキですが、ワクワクもしてます!
12:04 PM
みなさん、よろしくおねがいします!
👍 5
🙆 3
🎉 3
12:04 PM
Twitter のときよりも発言しづらいかもしれませんが、
Avatar
ワクワク
😊 2
Avatar
↑に書かれてる通り絵文字リアクションも有効活用してみて下さい。
😊 1
Avatar
発言しづらいかもけど絵文字リアクション投げやすいので良さそう
😊 5
Avatar
図だ
Avatar
DIscord 慣れてない人もいるかもしれませんが
swift 2
🐥 1
12:05 PM
↑の図の赤丸のところから新しい絵文字リアクションを、
12:06 PM
緑丸のところから既存のリアクションに自分も乗っかることができます。
🐥 1
12:06 PM
ちなみに、今参加してるよって方はどれくらいいますか?この発言に絵文字リアクションつけてみて下さい。
😃 4
👌 4
🐥 2
🍓 2
🙌 2
🙋 6
🐶 2
🤗 3
🐕 2
🎯 2
rust 2
💯 1
swift 2
swift 17
Avatar
いろとりどりー
🐥 1
Avatar
ということで、今日はよろしくおねがいします!僕からは以上です。
😊 1
👏 5
Avatar
koherさん、ありがとうございます!
12:08 PM
では、今回の流れをざっくり説明します
12:08 PM
今回のSwift Tweetsでは、特定のテーマについてディスカッションを行います テーマは「オブジェクト指向」「値型」の2つで、各テーマについて30分で議論をします
12:09 PM
各テーマには「テーマ司会者」がいます。テーマ司会者はディスカッションをリードします。  ・テーマ1:オブジェクト指向 @takasek さん  ・テーマ2:値型 @koher さん
12:09 PM
ディスカッション参加者は聞いているだけでも良いですし、可能であれば質問したり、回答したり、議論に参加します。
🙋 1
Avatar
今のオンライン人数80くらい👀
😆 5
8⃣ 2
0⃣ 2
👀 1
Avatar
Yeah!
12:09 PM
2つのテーマについて、ディスカッションが終わったあとは、ボイスチャットでのディスカッションも予定しております。それまでに挙がったトピックについてより深く議論できればと思います(進行状況によってはやらない場合もあります)
12:10 PM
本会の終了時刻は23:00です。
12:11 PM
それでは、最初のテーマ「オブジェクト指向」に移りたいと思います。テーマ司会の @takasek さん、よろしくおねがいします
Avatar
どうもtakasekです
👏 16
😄 1
12:11 PM
今日は「オブジェクト指向」について、みんなで話してみたいなあと思いました
12:12 PM
(あっ、原稿どこだ)
12:12 PM
(あわわ)
😂 3
😮 3
😇 1
Avatar
Avatar
お見苦しいところお見せしました
👌 2
12:13 PM
takasekです。最近PEAKSで「iOS設計パターン入門」を書いてます
12:13 PM
アーキテクチャ設計のすべてを濃縮! すべてのiOSアプリ開発者が待ち望んでいた、アプリケーション・アーキテクチャ解説本の執筆プロジェクト! 近年ますます大規模&複雑化しているiOSアプリ開発に...
😀 4
👀 4
🆒 3
12:13 PM
この本、けっこうがんばって書いてまして、設計の歴史とか超調べてるんですよ
12:13 PM
アーキテクチャの歴史とか、1980年あたりからがっつりあたってます
12:14 PM
今、自分の章では「設計するということ」「設計にパターンを適用する前に」という章が公開されている
12:14 PM
Clean Architecture, Fluxの章も公開されています
12:14 PM
というわけで、今購入すると、いちはやくそこらへんが読めます!
12:14 PM
と宣伝はおいといてですね
12:14 PM
なのでオブジェクト指向についても調べてみてまして、まあ本には別にその話はあんま出てこないんですけど
12:14 PM
そんな折に、最近Qiitaとかでも「オブジェクト指向」の話題が盛り上がって、
12:14 PM
みんな、この話題好きだなーと
Avatar
盛り上がってますねー
Avatar
というわけで、こういう双方向の話題にはピッタリなんじゃないかと
12:15 PM
そう思ってテーマを選びました
👍 1
Avatar
そうそうそう
Avatar
あれ?これは古い記事だった。
Avatar
よい記事ですねー
12:16 PM
(ネタバレされた!)
😅 1
😂 3
Avatar
タイムラインに流れてきたので最近書かれたのかと思ってました。
Avatar
まず最初のトピックなんですが 「オブジェクト指向」って何? という話をしたいなと
12:16 PM
オチを言ってしまえば、今の記事の話になっちゃうんですがw
12:17 PM
いくつかみなさんに質問します まずは、このリンクを見ないで答えてみて下さい
🙈 3
12:17 PM
Q1. Swift好きな人ー 🙋🙅
😋 5
🙋 24
swift 3
Avatar
すみません😂
Avatar
Q2. Objective-C好きな人ー 🙋🙅
😄 1
😅 7
🤔 2
🙋 11
🙅 5
12:17 PM
Q. どっちのほうがオブジェクト指向的だと思う? 1⃣Objective-C 2⃣Swift (edited)
1⃣ 19
2⃣ 6
🤔 11
3⃣ 1
Avatar
2が二つある、
Avatar
直ったw
Avatar
おー、Obj-Cの票が多い!
Avatar
3w
Avatar
3とは
Avatar
3とは
Avatar
Kishikawa Katsumi 10/20/2018 12:19 PM
私は両方に入れました
Avatar
選択肢が増えてるw
Avatar
同じく両方にいれました 🙂
Avatar
3 は @d_date さんだ。意見を聞いてみたい🙂
Avatar
あ、聞いてみたい
Avatar
3は両方ですw
😮 3
💡 1
Avatar
そういう解釈ww
Avatar
なるほどw
Avatar
Kishikawa Katsumi 10/20/2018 12:20 PM
1+2=
3⃣ 5
Avatar
@swift-4.2.4 print(1+2)
Avatar
takasek、この手の質問答えは1でも2でもないとか言いだしがちなのでひねくれてみました
Avatar
3
3⃣ 2
Avatar
鋭い
12:21 PM
そう 実はオブジェクト指向って、ひとつのものを指すものではないんですよね
😳 2
12:21 PM
ひとつはObj-C的なオブジェクト指向 もうひとつはSwift的なオブジェクト指向
😮 1
👀 1
12:22 PM
前者は、アランケイが目指した、いわば「メッセージング」を中心とした概念です
12:22 PM
そして後者は、ストラウストラップという人が道筋をつけた、抽象データ型をベースにしたオブジェクト指向
12:22 PM
てことで、世界にはいろんな開発コミュニティはあるけど、オブジェクト指向って何か?を理解するにあたっては、Swift界隈のみなさんが一番真実に近い立場にいると思ってるんです
😲 2
😮 1
12:23 PM
…実はこれ、音声でやろうかと思ってまして
12:23 PM
今テキストでぱちぱち打つのが結構遅くてテンポ悪い感があります
12:24 PM
なので、さっきのリンクを解禁します!
12:24 PM
忙しい人のためのまとめ一般に「オブジェクト指向プログラミング」と呼ばれる考え方には発案者が異なる二..
12:25 PM
アランケイのオブジェクト指向は、 「すべてのものはオブジェクト」と捉えて、それぞれがメッセージを送り合うという世界観です
12:25 PM
なので、それぞれのオブジェクトが何をやっているかはそれぞれは知らない
12:26 PM
逆に、抽象データ型のほうは、可能な限り静的に「できることだけをできるようにする」ものでした
Avatar
Obj-C が「メッセージング」の方のオブジェクト指向だというのは良く聞くんですが、「抽象データ型」の方の代表格の Java ととても近いような気がするんですが、違いは動的に解決されてる部分ですか?
Avatar
というと、Obj-CとSwiftの、それぞれの雰囲気でなんとなく分かるかと思います
12:27 PM
Javaは歴史的には「抽象データ型」の代表格としては微妙らしいですねー
😲 2
Avatar
runtimeapiによるメッセージングと、vtableの差みたいなとこ
Avatar
メイヤーは「オブジェクト指向入門」という本の中で、Javaは中途半端に色々取り込んだけれど実現できていないものが多い、と批判しています
12:28 PM
初期のJavaにはGenericsもありませんでした
12:29 PM
さて、この話のオチをどこにもっていきたかったかなんですが
12:29 PM
@dynamicMemberLookupの話に繋げたかったのです
😮 2
12:29 PM
全地球100億人のSwifterな皆さん、コンバトラーっ! tobi462 でーっす! え、いつもとノリが違う?まぁ、そういう日もあるんじゃないでしょうか。 そんなわけで、前回・前々回と続き Swift 4.2 の記事です。 今...
🐧 4
12:30 PM
Swift4.2で、@dynamicMemberLookupという機能が導入されました
12:30 PM
@swift-4.2.4 @dynamicMemberLookup struct Employee { subscript(dynamicMember member: String) -> String { let properties = ["name": "Taylor Swift", "city": "Nashville"] return properties[member, default: ""] } subscript(dynamicMember member: String) -> Int { let properties = ["age": 26, "height": 178] return properties[member, default: 0] } } let e = Employee() let name: String = e.name // "Taylor Swift" let city: String = e.city // "Nashville" let age: Int = e.age // 26 let height: Int = e.height // 178 let city_wrongType: Int = e.city // 0 let height_wrongType: String = e.height // ""
Avatar
no output
Avatar
(printしなきゃ意味がなかった…!)
😂 3
😅 2
Avatar
This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - apple/swift-evolution
Avatar
この機能は、抽象データ型側のオブジェクト指向にゴリゴリに寄っていたSwiftに、
Avatar
dynamicMemberLookup気持ち悪い
Avatar
メッセージ指向的な考えをもたらすものでもあるのかなあと
Avatar
たしかに。
Avatar
そんなことを思って見たのですが、みなさんどう思いますか、というかんじの
12:32 PM
そういうお話でした。
12:32 PM
おわり。
Avatar
その機能、interopのためにいれた機能という認識なんですが、そういうメッソージ指向的な意向もあったんでしょうか
Avatar
@takasek はDMLを外部言語バインディング以外にも使うことを想定しているんですか?
12:33 PM
こいつを使えばたしかにUIKitのtarget-actionパターンみたいなものも実装できそう。
Avatar
基本的には、同じ型表現ができるなら静的型付けのほうが利点があると思います アランケイも、静的型付けを否定してはいなかったはず
Avatar
@dynamicMemberLookup 自体はメッセージ指向のために入れたわけじゃないけど、そういう捉え方をしてみるとおもしろそうってことでしょうか?
Avatar
そういう捉え方をしてみるとおもしろそうってことでしょうか?
はい、そうです
Avatar
逆に、動的型付けのオブジェクト指向言語はメッセージ指向と言えるんでしょうか?
Avatar
気持ち悪かったのでアホな記事かいたのだ https://qiita.com/masakihori/items/c2686e25bfc448400e0e
Swift 4.2 で Dynamic member look up というものが導入されました。 これを使うことで Key が String の Dictionary で下のコードのようにプロパティを使うように要素にアクセスでき...
👍 3
Avatar
@masakihori JSON をプロパティでアクセスする例が Proposal に書かれてますね。
👍 1
Avatar
Javaは歴史的には「抽象データ型」の代表格としては微妙らしい
Avatar
動的型づけだと主語がでかすぎる気はしますが、そういう主張をしてる言語はある気がしますね
12:36 PM
Rubyとか
Avatar
This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - apple/swift-evolution
Avatar
というのはJavaがObjective-Cの影響が強いからかな。
Avatar
アラン・ケイは「Ruby は Smalltalk-76 に似ている」と言っていたそうです
12:37 PM
おお、 @rizumita さんがいた
Avatar
皆さんもこれを使ってtypoに苦しんでください。
Avatar
rizumitaさんは、まさにJavaとオブジェクト指向の話をQiitaで挙げられていました https://qiita.com/guitar_char/items/8f526416a7649cd2c2be#comment-267bffec225fa1d1b68f
オブジェクト指向を勉強していたところに、なんかブームがきているっぽいので便乗します。 基本的にこちらのwikiの背景部分を、自分なりにざっくり編集して、時々コメントを追加しています。 https://ja....
Avatar
なんか、 Erlang くらいまでいかないと、実際使ってる上では Ruby でも Python でも Java でも Obj-C でも大した違いは感じないような気がするんですけどどうでしょう?
Avatar
nominalなsubtypeかどうかはだいぶ違うなって感覚があります
Avatar
返り値の同期的な待機をやめると、一気にメッセージング感が出ますね
😃 3
🙂 1
Avatar
https://www.infoq.com/jp/news/2010/07/objects-smalltalk-erlang
Armstrong博士は、... Erlangは「唯一のオブジェクト指向言語かもしれない」と考えているようだ。
とありますね
QCon London 2010のインタビューで、Erlangの最初の開発者であるJoe Armstrong博士とSmalltalk、OOP、パターンに長い間関係しているRalph Johnson博士に、オブジェクト指向に関して、私たちは長年「間違った道」を下って...
Avatar
nominalなsubtypeかどうかはだいぶ違うなって感覚があります
確かに、ダックタイピングかどうかは結構大きな違いですね。
Avatar
同期的・非同期的の話になると、今度はオブジェクト指向とアクターモデルの話になってきそう(詳しくないですが) 当初のメッセージ指向の実装としてのSmalltalkは、同期的だったと聞きます
Avatar
非同期をいれるとプロセス代数とかの並列処理をあつかう体系に近づく気がしますね
Avatar
多分僕が動的型付け言語を使ってるときでも静的型付け言語的な考え方をしてるから違いを感じづらいのだと思います。でも、 Obj-C だからメッセージ指向ともあまり感じないような・・・。黒魔術を使うときくらい?
12:42 PM
Swift Concurrency Manifesto. GitHub Gist: instantly share code, notes, and snippets.
Avatar
lldbでデバックするときは型がわかんなくてもメッセージおくればなんとかなるって性質つかいますね
Avatar
非同期というとNSConnectionとかが出てきそう。deprecatedだけど。
Avatar
macOSのobjcにはdistributed objectってあって,普段のobjcと同じ構文のまま,相手先のオブジェクトは別プロセスにいるとかネットワーク越しにいるとか,そういうのできたので,だいぶメッセージ送信ぽさあった気はします
Avatar
なるほどです。
Avatar
最近、セキュリティの関係でプロセスを分割してく文化ありますけど、それがオブジェクト指向っぽいかというと、どうなんでしょ
12:44 PM
ボクの感覚的には別って感想です
Avatar
そもそも書いてる側でメッセージ指向っぽいなあって思うプログラムってどんなものなんでしょう?
🤔 3
Avatar
オブジェクト指向といえばGUI Toolkitというイメージ
Avatar
@IBOutlet@IBAction をつなげてるときは
Avatar
とりあえずFirstResponderに投げとけ
Avatar
そういう気分になりますね
12:46 PM
コード側の変更にXIBが追従してなくてメソッド名がなくなってたりすると
😂 1
12:46 PM
実行時に落ちるし。
Avatar
あと伝統的にはシミュレータなんですけど、あんま経験はないですね
Avatar
型を無視した呼び出しができちゃう点ですかね。メッセージ指向っぽさ。
Avatar
それだと動的型付けと何が違うんでしょう?
Avatar
セレクターオブジェクトが実行時に存在してるってところもかなあ。
12:48 PM
静的リンクされたメソッド呼び出しにおいてはメソッドはただの番号でしかないから
Avatar
動的型付けとメッセージパッシングは直行した概念なんじゃないんですかね
Avatar
いや、まさに動的型付け的な点がメッセージ指向っぽいのかなと思ったわけですけど。
Avatar
@koher 個人的には、classやprototypeが実行時に書き換えられる、rubyやJavaScriptは、 そういう意味でメッセージング指向的だと思います
😀 1
12:50 PM
シェルスクリプトとかは静的に型はつかないけど、オブジェクト指向っぽくはないですし
😮 1
Avatar
動的束縛と動的型付けは区別する必要があって、
Avatar
なるほど。
Avatar
動的束縛は必要だけど、動的型付けは必要ではないはず
Avatar
動的束縛の束縛ってどういう概念ですか?
Avatar
(定義引っ張り出してきてます、ちょっとお待ちを)
Avatar
メソッドディスパッチの事か。
Avatar
じゃあvtableみたいなのがあれば動的束縛ってことです?
Avatar
vtableは動的束縛の一つ ってことで、そうなりそうですね
Avatar
なるほどー
Avatar
vtableは動的束縛の一つ ってことで、そうなりそうですね
JavaScript とかは vtable がない例かな。
Avatar
出た、prototype chain
Avatar
@takasek さんの「動的束縛は必要だけど」は、何を満たすのに必要っていう意味ですか?
Avatar
Swift の witness table は動的束縛?
Avatar
の一種だと思いました > witness table
🙂 1
Avatar
witness tableは動的束縛っぽいですね。
Avatar
そういう実装の話につっこむと、SwiftとかのLint time optimizationとかが進んでコンパイル時には静的に解決されてる、とかになるとどうなるんですかね
Avatar
witness table ってインスタンスに紐付いてないからオブジェクト指向っぽくなくないですか?
Avatar
ん、あれ、すみません、メッセージング指向の話ではなかったかも<動的束縛が必要
Avatar
existential container からは参照されてるけど。
Avatar
Kishikawa Katsumi 10/20/2018 12:57 PM
動的束縛はオブジェクト指向に必要ってことを言いたかったのでは?
Avatar
オブジェクト指向入門によると、動的束縛の実現手段として多相とサブタイプによる再定義があって、…という話の流れでした (edited)
Avatar
インスタンスに紐付いてないけど、 元の型に紐付いたテーブルが、アップキャストされる抽象的な型とペアにされるという意味で、 vtableと同じ感じがする (edited)
Avatar
で、この本を書いたメイヤーが論じているのは抽象データ型の話なので
Avatar
@koher 言語の内部実装は、言語がオブジェクト指向っぽいかどうかにはあんまり関係ないんじゃないですかね。
Avatar
@hironytic それはそうなんですが、さっきの
セレクターオブジェクトが実行時に存在してるってところもかなあ。
>静的リンクされたメソッド呼び出しにおいてはメソッドはただの番号でしかないから みたいな話もあったので。
1:00 PM
元記事に書かれてたように論文読まないとふわふわした議論になりそう? 同じ理由で、オブジェクト指向という概念を特定の言語の(俗に「オブジェクト指向」向けと称される)機能から外挿して学ぶのは難しいし、間違った「オブジェクト指向」を創造してしまう危険がある。少し遠回りに思えても、それぞれの考案者自らがその主張を綴った論文を読んで理解を試みるほうがいい。
1:01 PM
ちなみに、論文読んだことのある人いますか? 🙋 読んだ 🙅 読んでない
🙅 18
Avatar
だれもいない..
😮 1
😅 1
😂 1
Avatar
(メイヤー本しか読んでおりません…メッセージ指向は雰囲気でしかわからない) (edited)
Avatar
ぼくは、言語上では、プロトコルで抽象化されたメソッドを呼ぶと、実行時のオブジェクト型に応じて振る舞いが変わるから、オブジェクト指向っぽいと思ったわけです。
Avatar
いまから急いで読むしか
Avatar
みなさま!
🙂 1
🙋 1
1:03 PM
盛り上がってきたところ大変申し訳ないのですが、
1:03 PM
いったんこの辺りでテーマ1を終了させていただきたいと思います 🙇
🙂 2
👌 6
1:04 PM
話足りない点もあると思いますので、続きはぜひ、テーマ2のあとに予定しておりますボイスチャットにてお願い致します!
1:04 PM
ここで5分のインターバルを取りたいと思います。22:10 から次のテーマに移ります。
Avatar
お付き合いいただき感謝します。オブジェクト指向の話でわいわいできて楽しかったです、ありがとうございました!
👏 17
😀 2
Avatar
takasek さん、ありがとうございました!
Avatar
テーマ2も盛り上がって終了時間になると予想 🤔
Avatar
うーむ、たしかに 🤔
Avatar
盛り上がったらボイスチャットは次回のお楽しみでもいいかも?
🙂 1
👌 1
Avatar
ですね!
Avatar
休み時間中にアンケートです。 1⃣ Discord の方が Twitter より良さそう 2⃣ やっぱりいつもの Twitter の形の方がいい
🤔 2
1:08 PM
次回開催の参考までに。
1⃣ 13
2⃣ 1
3⃣ 9
1:10 PM
3⃣ 出たw
Avatar
Twitter の形式も割と好きだったので選ぶのが難しい! 😂
1:11 PM
なので3
🙂 2
Avatar
絵文字リアクションはツイッターよりも反応人数が多くて良いですね
👌 6
Avatar
リアクションのしやすさとか、わいわい感とかがあってDiscordすごくいいんですけど、Twitter形式は整ってる感じがあって…
Avatar
Discord 、人がいる感じはありますね。
Avatar
さて!!
1:12 PM
では、2つ目のテーマ「値型」に移りたいと思います。
👍 2
Avatar
わーわー 🎉 (edited)
Avatar
テーマ司会の @koher さん、よろしくおねがいします!
Avatar
はい、始めます!よろしくおねがいします。
👏 16
1:14 PM
あまり僕から話すことは用意してなくて、自由に話し合いたいんですけど、
1:14 PM
最初に若干だけ僕が考えていることを話すと
1:14 PM
すごく単純化して考えると、 Swift の値型はミュータブルクラスと
1:14 PM
イミュータブルクラスのいいとこどりをしたような存在だなと考えてます。
1:15 PM
参照型と値型はインスタンスが共有されるかどうかという違いがあるわけですが
1:15 PM
それ自体はどっちが優れているというわけではないんですが、
1:15 PM
ミュータブルクラスだと振る舞いが型で表現できないケースがあるのが微妙に思ってます。
1:16 PM
class Group { ... } class User { ... } let group: Group = ... let owner: User = group.owner owner.age += 1 // 何が起こる?
1:16 PM
Group が内部に保持してるインスタンスをそのまま返してたら Groupownerage もインクリメントされますけど
🎂 3
1:17 PM
もし防御的コピーをしてたりすると owner.age += 1group に影響を与えません。 (edited)
Avatar
🎂
😂 2
Avatar
だれか誕生日?
Avatar
誕生日ですからね
Avatar
センス高
Avatar
そういうことかw
1:18 PM
値型だとインスタンス共有が存在しないので、振る舞いが定まります。
1:18 PM
これをドキュメントやコーディング規約(たとえば必ず防御的コピーをする)とかで管理しようとしても
1:18 PM
巨大なコードベースでは次第にそれが破られてきて、そのうち何が起こるか確信できないコードの塊が生まれるんじゃないかと思います。
1:19 PM
イミュータブルクラスだとそういう問題はないですが、
1:19 PM
状態の更新が大変です。
1:19 PM
class User { let name: String let age: Int ... } var user = User(name: "Swift", age: 4) user = user(name: user.name, age: user.age + 1) (edited)
1:19 PM
インスタンスを作り変えないといけないです。
1:20 PM
ミュータブルクラスなら楽なのに。 // ミュータブルクラス class User { var name: String var age: Int ... } let user = User(name: "Swift", age: 4) user.age += 1 // 楽 (edited)
1:21 PM
これを struct でやると // struct struct User { var name: String var age: Int } var user = User(name: "Swift", age: 4) user.age += 1 // 楽 (edited)
1:21 PM
楽だけどインスタンス共有もされなくて挙動が定まってうれしい
❤ 7
1:22 PM
と両者のいいとこどりをできます(単純化すれば)。
1:22 PM
で、とは言っても普通の言語だとコレクションが参照型なので
1:22 PM
値型でできることの範囲が結構狭いんですが、
1:23 PM
Swift だとコレクションも値型なので、やろうと思えば全部値型で書くこともできなくはないです。
1:23 PM
標準ライブラリもほとんど値型しかないですし。
1:23 PM
というわけで、値型って Swift にとってとても重要だと思うんですけど、
1:23 PM
実際にはいろいろ限界があって難しいこともあり、
1:24 PM
みなさん実際使っててどうですか?ということを話し合ってみたいです。
1:24 PM
こういうのは値型は難しいよね、とか、ここが値型でおもしろいよね、とか何かありますか?
Avatar
値型にした箇所に関しては共有仕様の悩みが無いから書くときも使うときも楽でいいですね
Avatar
インスタンスをコピーしつつ、一部フィールドを更新する文法自体は、他言語にもわりとあるんですけど
Avatar
@mzp Kotlin とか JS とかそうですよね。
Avatar
ネストしてるフィールドを一発で更新できるのはなくて、Swiftすごいなーって思ってる機能ですね
1:26 PM
ない->ボクは知らない
Avatar
それ僕もおもしろいと思ってるとこで、ネストした先の mutating func とかおもしろいですよね。
Avatar
参照型だとコピーコストがGCコストにもなっちゃうんで、防御的コピーだらけにするのも神経を使う
Avatar
↓とか。 foo.bar.baz.isEnabled.toggle() (edited)
❤ 4
Avatar
そのへん、値型だと気楽で良い Arrayの場合もCOWが効くから気楽
Avatar
mutating funcinout が使いやすさのキーになってる気がしてて
Avatar
参照型でプログラマが意識的に気遣っていた部分をSwiftの値型が意識しなくて済むようにしてくれた気がします。
Avatar
C# とかも struct あるけど、途中で computed property が挟まったりしたら更新できないんですよね。
😀 1
Avatar
C#の値型はプリミティブなもの以外ほとんど使いませんね。
Avatar
似たようなのでは、 Obj-C でできなかった view.frame.origin.x += 10; とか。 (edited)
1:30 PM
これ辛かった・・・。
😱 5
❓ 1
😣 3
Avatar
え、それダメなんですか
😂 1
Avatar
一度はやってしまうやつだ。。。
Avatar
でたーw
Avatar
Kishikawa Katsumi 10/20/2018 1:31 PM
それがダメなのはObjecitve-Cのドット記法の問題ですけどね。
Avatar
@mzp view.frameが返すCGRectがstructで、最終的にviewのsetFrameは呼ばれないです
Avatar
なるほど
Avatar
toggle でおもしろいのは、
1:33 PM
This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - apple/swift-evolution
Avatar
Kishikawa Katsumi 10/20/2018 1:34 PM
view.frameが返すCGRectがstructで、最終的にviewのsetFrameは呼ばれないです
厳密には view.frame.origin.x += 10; はコンパイルエラー
(edited)
1:34 PM
CGRect frame; frame.origin.x += 10; はOK 話外れました 🙏 (edited)
👍 1
Avatar
This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - apple/swift-evolution
Avatar
あれ、そうでしたか。記憶違いでした。>コンパイルエラー
Avatar
このあたりの mutating func とか inout は機能としてはあったけど、
Avatar
lvalueかな
Avatar
それを十分に有効活用した API を用意できてなかったのは
1:35 PM
設計した側でもこれらの挙動が新しくて十分使いこなせてなかったのかなと思ったり。
1:36 PM
reduce(into:...) って inout な引数を持つ高階関数(メソッド)ですけど
1:37 PM
そういうことができる言語を Swift の他に知ってる方いますか?
Avatar
C++は似たような事ができる部分がありますね
💪 1
Avatar
↓みたいなことができる。 let idToUser = users.reduce(into: [:]) { idToUser, user in idToUser[user.id] = user } (edited)
1:38 PM
C++は似たような事ができる部分がありますね
たしかに C++ は大概のことはできそう・・・
(edited)
Avatar
Swiftは値型を使ってオブジェクト間のつながりを薄めてるみたいな感じがしてて、Objective-C的オブジェクト指向とは別世界にいる感覚になる。 そういう意味では前の話と関連するけど、メッセージ指向っていうのは「相手の状態を気にしない」というのがあると思ってて、
let owner: User = group.owner owner.age += 1 // 何が起こる?
というのはメッセージの境界を超えてるっていう感じがする。ために、そういう実装するなら値型がふさわしいんじゃないかって思う。
Avatar
@rizumita Swift の値型はメッセージ指向的だということですか?
Avatar
いや、メッセージ指向からはなれるというか。
Avatar
だいたいのことは、「それ、C++でも(がんばれば)できるよ」 ってなりがちなんだけど、 ドットチェーン代入はSwiftじゃないとできなくて、すごいと思ってる
Avatar
Rubyのeach_with_objectがちかそう > reduce(into:)
Avatar
Ruby って参照渡しあるんですっけ?
1:42 PM
あー、参照型だからできるのか。
1:43 PM
参照渡し( inout )って時代遅れの遺物的な扱いされてた(主観)けど、値型で見事に活用されてるのとかもおもしろいと思います。
Avatar
参照型がメインだと、into:じゃないreduceで何も問題ないんですよね。
Avatar
そうなんですよ。値型だからこそ活きる。
Avatar
Rubyでは「すべてが参照である」って肯定的に言われてた気がしてて(要出典)
Avatar
既存の概念をうまく組み合わせてる感じがしてすごいですよね、Swiftの値型
👍 1
Avatar
参照型に寄せていくのが良いパラダイムシフトとされていたが、 Swiftはその点逆方向を向いてる部分があって新しい
👍 1
Avatar
「すべてがオブジェクトである」と「オブジェクトは参照型である」と合わせ技かな
😀 2
1:44 PM
Ruby
Avatar
いちおう突っ込んでおくと、inout は概念上は call by copy-restore です。
Avatar
一方で値型の限界があって、前に @takasek さんが言ってたんですけど、非同期処理と相性が悪い・・・
😢 2
Avatar
おっ、そうなんですか
Avatar
@rintaro そのまま参照されてるわけではなくて、最後に書き戻されるって意味ですよね?
1:46 PM
で、最適化によって問題がない場合は参照になる。
Avatar
はい、たいていの場合は最適化で参照になります。
👀 6
1:47 PM
computed property とかも inout で渡せますが当然参照できないので、 get で読み出されて set で書き戻されます。
swift 3
Avatar
rintaroさんが言ってるのは、computed property...あ、かぶった
Avatar
mutating func であっても、コールバックで self を書き換えることはできないですし、 mutating func foo() { DispatchQueue.main.async { self.bar += 1 // できない } }
1:48 PM
これ、今提案されてる async/await で結構問題になる気がしてて
🤔 1
Avatar
そうすると、概念上は、into:付きのreduceもinto:なしのreduceも(最適化がなければ)一緒。。。 (edited)
Avatar
mutating func foo() async { await baz() self.bar += 1 // コンパイルエラー } (edited)
Avatar
get で読み出されて set で書き戻されます。
ここでコピーコストが2回かかるのを最適化するために、 途中状態オブジェクトをコルーチンで保持したまま参照で扱える、 readアクセサ, modifyアクセサがSwift5で入るぞ
👌 1
🙌 4
‼ 7
5⃣ 3
😍 1
swift 4
Avatar
↑のコードが mutating func なのに self 変更できないのとか、初見でとまどいそう。
1:52 PM
あと、↓とかもミュータブルクラスだと簡単だけど値型と inout だと自分同士でできない。 // ミュータブルクラス func sendMoney(from user1: User, to user2: User) { user1.money -= 100 user2.money += 100 } sendMoney(from: user1, to: user2) // OK sendMoney(from: user1, to: user1) // OK
Avatar
うおお、リアクションがすごい。 実はmaster版だと試せます↓ #swiftbot-sandbox に実行例を貼っておきました。 https://gist.github.com/omochi/b31f4916fda78e9a2e804c4b2233370d
GitHub Gist: instantly share code, notes, and snippets.
swift 3
Avatar
// struct func sendMoney(from user1: inout User, to user2: inout User) { // これ自体は OK user1.money -= 100 user2.money += 100 } sendMoney(from: &user1, to: &user2) // OK sendMoney(from: &user1, to: &user1) // コンパイルエラー
1:54 PM
他に、こんなときに値型辛かったとかありますか?
Avatar
全然別の例なんですが、 varlet の間にもうちょいなんかほしいなーと思うことはあって、 struct User { let name: String var age: Int } do { let group = Group( id: 1, owner: User(name: "hoge", age: 16) ) // groupがletなのでこれはできない // group.owner.age += 1 } // というのはいいんだけど do { var group = Group( id: 1, owner: User(name: "hoge", age: 16) ) group.owner.age += 1 print(group) // Group(id: 999, owner: __lldb_expr_1.User(name: "ほげほげぴよぴよーー", age: 65536)) // 👆!!?? } // 実はこうなってました struct Group { let id: Int var owner: User { didSet { self = Group(id: 999, owner: User(name: "ほげほげぴよぴよーー", age: 65536)) } } }
Avatar
sendMoney(from: &user1, to: &user1) // コンパイルエラー は、 @rintaro さんの話を聞いてから見ると納得感はありますね。
Avatar
みなさま!
🐶 1
1:57 PM
そろそろお時間がきてしまいました! 🙇
1:57 PM
このあとボイスチャットを予定していたのですが、やはり時間が足りなくなってしまいました。 申し訳ないのですが次回のお楽しみということで宜しくお願い致します! 🙏
😊 6
🗓 1
😂 2
👏 11
🎙 1
1:58 PM
次回の開催日は未定ですが、もしテーマ司会をやってみたい方がおりましたら @koher さん宛にご連絡ください!
Avatar
サイクル的には多分 1 月でしょうか。
1⃣ 2
Avatar
ですねー 3ヶ月後
1:59 PM
Discordでの開催は第1回目ということもあり、不慣れな点もございましたが、最後までご参加いただきありがとうございました!
👏 10
1:59 PM
それでは、今日はこれでクローズしたいと思います。おつかれさまでした 😀
👏 16
Avatar
おつかれさまでしたー!ありがとうございました!!
👏 16
2:00 PM
ノーテーマでフリートークとかもおもしろそう😁
Avatar
88888888888888888888 (って書く必要がもうない)
👍 2
8⃣ 12
Avatar
2020年4月24日(金)の19:30より、こちらで『Swift Zoomin' チャレンジ』を開催します。 https://swift-tweets.connpass.com/event/171382/
# Swift Zoomin' チャレンジ Swift Zoomin' チャレンジはプログラミング言語 Swift に関するオンラインイベントです。 Zoom を使って音声やスライド・画面共有でコミュニケーションを取りながら、 Swift に関係した課題に取り組みます( Zoom アプリは無料でインストールできます)。 # 課題『 Fat View Controllerを倒せ!』 本イベントは、主催者が用意した Fat View Controller をリファクタリングし、どれだけクリーンな設計とコードを実現できるかというコンペティションです...
👏 6
2:31 PM
こちらのテキストチャット用チャネルは補足的に利用します。メインは『音声チャット』の swift-zoomin チャネルなので、そちらにアクセスして下さい。 (edited)
👍 3
Avatar
聞こえてますー(今米炊いてるからROMります)
🍚 4
Avatar
そろそろ始めます!
👏 15
10:31 AM
最初の10分は接続確認を行います
👍 4
10:31 AM
もし、音声がうまく聞こえない方がいましたら教えてください
Avatar
ここです。
Avatar
聞こえてます! (edited)
Avatar
🙋‍♀️
Avatar
聞こえてます!
Avatar
聞こえてます
Avatar
Yuto Mizutani 4/24/2020 10:35 AM
b
Avatar
ゆきむら(古) 4/24/2020 10:35 AM
(`・ω・´)ゞ
Avatar
聞こえてます!
Avatar
b
Avatar
聞こえています!
Avatar
聞こえてます!
Avatar
聞こえてます
Avatar
🙋‍♂️
Avatar
うほーい
Avatar
聞こえています!
Avatar
聞こえてまーす!
Avatar
聞こえています!
Avatar
聞こえてます
Avatar
聞こえてます。
Avatar
sugigami(susieyy) 4/24/2020 10:35 AM
😋
Avatar
聞こえてます
Avatar
花芽尋かすみ 4/24/2020 10:35 AM
hi
Avatar
聞こえてます!
Avatar
⭐ 1
Avatar
🙋‍♀️🙋‍♂️
Avatar
hamayokokuririn 4/24/2020 10:35 AM
聞こえてます!
Avatar
聞こえます!
Avatar
ありがとうございます!
Avatar
kashihararara 4/24/2020 10:36 AM
🤙
Avatar
ちょっと部屋うるさいのでミュートしますw
Avatar
Kishikawa Katsumi 4/24/2020 10:37 AM
聞こえてます 👍
Avatar
すみません。どこから画面みれるでしょうか。(discord初めてなもので。。。)
Avatar
音声テスト中です。19:40 〜開始します
Avatar
今日は音声のみです!
10:38 AM
「Screen Sharingもできるけど50人までしかできないみたいなので」
10:38 AM
「今日は発表ではなくコードを書くイベントなので、画面がなくてもできるかなと思ってます」
Avatar
あ、音声のみに変わったとかいてあいました。失礼しました
😆 1
👌 1
Avatar
888888
Avatar
はじめます!!!
Avatar
Q. ボイスチャンネルはどう使うんですか? A. 説明とか、何か質問があったら聞いてもらうために使います
👍 1
Avatar
すみません、音声なんですが、koogawaさんに通話する感じで合っていますか...?(こちらも初心者ですみませんがどなたか...) (edited)
Avatar
チャンネルリストの下の方、「音声チャット」に swift-zoomin というのがあります
10:41 AM
Avatar
ありました!!ありがとうございます。🙇‍♀️
Avatar
こちらの「Swift-zoomin」から音声チャットにログインできます!
🙇‍♀️ 1
Avatar
キーボード音って「Krispによるノイズ抑制」で抑えられるのかな?
👍 1
Avatar
↑音声チャットは左メニューの下の方にあります (edited)
Avatar
チャンネルのアイコンがスピーカーなのが音声チャット、「#」なのが通常のチャットだと思います! 「swift-zoomin」は同名で両方ありますね
🙏 1
Avatar
Contribute to refactoring-challenge/reversi-ios development by creating an account on GitHub.
👀 6
👍 53
Avatar
👆今回のプロジェクトのリポジトリです
10:43 AM
「アクセスできた人はリアクションつけてもらえると、どれくらいの人がアクセスできたかわかって嬉しいです」
10:44 AM
「なにかわからないことがあったらいつでも、話してる最中でもミュート解除して聞いてください!」
Avatar
ミュートの解除は左下のこのマイクボタンからできます
Avatar
print("hello")
Avatar
テキストチャットはどんなときに使うのか
  • コードを使って質問したい
  • シンタックスハイライトも使えます トリプルバッククオートの後に言語名で
Avatar
print("hello world") (edited)
Avatar
print("hello")
Avatar
let uhooi = "うほーい"
Avatar
みなさん、Hello world を入力してみてください
Avatar
print("Hello world")
Avatar
print("hello")
Avatar
print("hello, world")
Avatar
print("Hello!")
Avatar
print("hello world")
Avatar
print("Hello World!")
Avatar
print("はろーわーるど")
Avatar
print("hello world")
Avatar
print("hello world")
Avatar
print("Hello World")
Avatar
hamayokokuririn 4/24/2020 10:46 AM
print("hello")
Avatar
swift print("hello")
Avatar
teppei_kikuchi 4/24/2020 10:46 AM
print("Hello World") テスト
Avatar
print("Hello World!")
Avatar
print("Work from home")
Avatar
print("Hello World!")
Avatar
print("Hello, World!")
Avatar
print("yeah!")
Avatar
print("Hello!")
Avatar
print("hello")
Avatar
Yuto Mizutani 4/24/2020 10:46 AM
print("Hello, world!")
Avatar
print("Hello world")
Avatar
'''swift
Avatar
print("Hello World")
Avatar
print("Hello!!!")
Avatar
print("hello")
Avatar
print("Hello World!")
Avatar
print("Hello World")
Avatar
swift print("Hi!")
Avatar
ゆきむら(古) 4/24/2020 10:46 AM
print("Hello")
Avatar
print("Hello, World!")
Avatar
print("ハローワールド")
Avatar
print("hello")
Avatar
@swift-5.2.5 print("Hello World")
Avatar
Hello World
Avatar
print("Hi")
Avatar
print("Hello world")
Avatar
Hello world
Avatar
Kishikawa Katsumi 4/24/2020 10:46 AM
@swiftbot help
Avatar
Usage: @swiftbot [--version=SWIFT_VERSION] [--command={swift, swiftc}] [--options=SWIFTC_OPTIONS] `​`​` [Swift Code] `​`​` Examples: @swiftbot `​`​` print("Hello world!") `​`​` @swiftbot --version=4.0.3 `​`​` print("Hello world!") `​`​` @swiftbot --command=swiftc --options=-dump-parse `​`​` print("Hello world!") `​`​` @swiftbot --platform=mac `​`​` print("Hello world!") `​`​` Subcommands: @swiftbot versions: show available Swift toolchain versions @swiftbot contribute: show repository URLs @swiftbot help: show help
👀 2
Avatar
'''swift print("hello")'''
Avatar
print("Hello World")
Avatar
swift print("Hello World")
Avatar
print("Hello world!")
Avatar
''' print("hello WORLD")
Avatar
print("hello")
Avatar
@swift-5.2.5 print("スターください")
⭐ 12
Avatar
スターください
Avatar
print("Hello")
Avatar
バッククォートを3つ打つ
Avatar
@swiftbot help
Avatar
Usage: @swiftbot [--version=SWIFT_VERSION] [--command={swift, swiftc}] [--options=SWIFTC_OPTIONS] `​`​` [Swift Code] `​`​` Examples: @swiftbot `​`​` print("Hello world!") `​`​` @swiftbot --version=4.0.3 `​`​` print("Hello world!") `​`​` @swiftbot --command=swiftc --options=-dump-parse `​`​` print("Hello world!") `​`​` @swiftbot --platform=mac `​`​` print("Hello world!") `​`​` Subcommands: @swiftbot versions: show available Swift toolchain versions @swiftbot contribute: show repository URLs @swiftbot help: show help
Avatar
こんな感じで書いて下さい。
👍 9
Avatar
swift print("Hello world!")
Avatar
print("Hello World")
Avatar
print("Hello")
Avatar
print("hello world")
Avatar
www
Avatar
print("hello")
Avatar
ゆきむら(古) 4/24/2020 10:47 AM
これ
Avatar
"""swift print("hello") '''
Avatar
@swift-5.2.5 print("Hello")
Avatar
Hello
Avatar
print("hello")
Avatar
ゆきむら(古) 4/24/2020 10:48 AM
入力中でも色変わってくれるの見易くてありがたいですね
Avatar
@swift-5.2.5
Avatar
Usage: @swift52 [SWIFT_OPTIONS] `​`​`​ [Swift Code] `​`​`​
Avatar
@shiz はいってる音声チャットのチャンネルが違いますよ
Avatar
@swift-5.2.5 print("Hello world") (edited)
Avatar
Hello world (edited)
Avatar
@swift-5.2.5
Avatar
Usage: @swift52 [SWIFT_OPTIONS] `​`​`​ [Swift Code] `​`​`​
Avatar
みんなでbotをいじめる会w
Avatar
print("hello")
Avatar
@swift-5.2.5
Avatar
Usage: @swift52 [SWIFT_OPTIONS] `​`​`​ [Swift Code] `​`​`​
Avatar
@swift-5.2.5
Avatar
Usage: @swift52 [SWIFT_OPTIONS] `​`​`​ [Swift Code] `​`​`​
Avatar
@swift-5.2.5 print("hello world")
Avatar
hello world
Avatar
@swift-5.2.5
Avatar
Usage: @swift52 [SWIFT_OPTIONS] `​`​`​ [Swift Code] `​`​`​
koher pinned a message to this channel. 4/24/2020 10:49 AM
Avatar
@swift-5.2.2
Avatar
teppei_kikuchi 4/24/2020 10:49 AM
@swift-5.2.5 print("test")
Avatar
@swift-5.2.5
Avatar
test
10:49 AM
Usage: @swift52 [SWIFT_OPTIONS] `​`​`​ [Swift Code] `​`​`​
Avatar
ゆきむら(古) 4/24/2020 10:49 AM
@swift-5.2.5
Avatar
Usage: @swift52 [SWIFT_OPTIONS] `​`​`​ [Swift Code] `​`​`​
Avatar
@swift-5.2.5 print("Hello!!")
Avatar
@swift-5.2.5 print(1 + 2 + 3 + 4 + 5)
Avatar
Hello!!
Avatar
よっしゃ。こうげきするぞ! @swift-5.2.5 swift print(""" _人人人人人人人_ >  無限ループ <  ̄Y^Y^Y^Y^Y^Y^Y^ ̄ """)
Avatar
15
10:49 AM
_人人人人人人人_ >  無限ループ <  ̄Y^Y^Y^Y^Y^Y^Y^ ̄
Avatar
@swift-5.2.2
Avatar
print("hello")
Avatar
@swift-5.2.5 print("hello world")
Avatar
Usage: @swift52 [SWIFT_OPTIONS] `​`​`​ [Swift Code] `​`​`​
Avatar
@swift-5.2.5 print("Hello WOrld!")
Avatar
Hello WOrld!
Avatar
@swift-5.2.5 print("hello")
Avatar
hello
Avatar
@swift-5.2.5
Avatar
Usage: @swift52 [SWIFT_OPTIONS] `​`​`​ [Swift Code] `​`​`​
Avatar
@swift-5.2.5
Avatar
Usage: @swift52 [SWIFT_OPTIONS] `​`​`​ [Swift Code] `​`​`​
Avatar
@swift-5.2.5 fatalError()
Avatar
exit status: 4 with stderr:Fatal error: file <stdin>, line 1 Current stack trace: 0 libswiftCore.so 0x00007ff43dc62490 swift_reportError + 50 1 libswiftCore.so 0x00007ff43dcd3b50 _swift_stdlib_reportFatalErrorInFile + 115 2 libswiftCore.so 0x00007ff43d9e954e <unavailable> + 1385806 3 libswiftCore.so 0x00007ff43d9e9157 <unavailable> + 1384791 4 libswiftCore.so 0x00007ff43d9e9782 <unavailable> + 1386370 5 libswiftCore.so 0x00007ff43d9e7a20 _assertionFailure(_:_:file:line:flags:) + 520 7 swift 0x00000000004f5d3e <unavailable> + 1006910 8 swift 0x00000000004fa5b2 <unavailable> + 1025458 9 swift 0x00000000004e7d6c <unavailable> + 949612 10 swift 0x00000000004dca99 <unavailable> + 903833 11 swift 0x00000000004d2abb <unavailable> + 862907 12 swift 0x00000000004cf72d <unavailable> + 849709 13 swift 0x0000000000459672 <unavailable> + 366194 14 libc.so.6 0x00007ff43fd0d740 __libc_start_main + 240 15 swift 0x00000000004591c9 <unavailable> + 365001 Stack dump: 0. Program arguments: /usr/bin/swift -frontend -interpret - -disable-objc-interop -I /Libraries/.build/x86_64-unknown-linux-gnu/debug -I /Libraries/.build/checkouts/SwiftBacktrace/Sources/CSwiftBacktrace/include -I /Libraries/.build/checkouts/SwiftBacktrace/Sources/Clibunwind/include -I /Libraries/.build/checkouts/swift-nio/Sources/CNIOHTTPParser/include -I /Libraries/.build/checkouts/swift-nio/Sources/CNIOSHA1/include -I /Libraries/.build/checkouts/swift-nio/Sources/CNIOAtomics/include -I /Libraries/.build/checkouts/swift-nio/Sources/CNIODarwin/include -I /Libraries/.build/checkouts/swift-nio/Sources/CNIOLinux/i
Avatar
USキーボードだと左上でなく右上ですね!
Avatar
@swift-5.2.5 print("hello world")
Avatar
hello world
Avatar
jis キーボードの場合は シフト押しながら @ です!>バッククォート
Avatar
@swift-5.2.5
Avatar
Usage: @swift52 [SWIFT_OPTIONS] `​`​`​ [Swift Code] `​`​`​
Avatar
@swift-5.2.5 print("hey!")
Avatar
hey!
Avatar
@swift-5.2.5 swift print("Hello World")
Avatar
Hello World
Avatar
@swift-5.2.5
Avatar
Usage: @swift52 [SWIFT_OPTIONS] `​`​`​ [Swift Code] `​`​`​
Avatar
あれ?ごめんなさいHHKBだからか…
Avatar
HHKBの場合は右上ですね。
Avatar
US の HHKB は右上でした
Avatar
@swift-5.2.5 print("rm -rf /")
Avatar
rm -rf /
Avatar
@swift-5.2.5 ​ print("Hello WOrld!")
Avatar
Hello WOrld!
Avatar
@swift-5.2.5 print(111)
Avatar
@swift-5.2.2 hello world
Avatar
111
Avatar
print("Hello")
Avatar
botsugoi
Avatar
@swift-5.2.5 hello world
Avatar
exit status: 1 with stderr:<stdin>:1:6: error: consecutive statements on a line must be separated by ';' hello world ^ ; <stdin>:1:1: error: use of unresolved identifier 'hello' hello world ^~~~~ <stdin>:1:7: error: use of unresolved identifier 'world' hello world ^~~~~
Avatar
@swiftbot print("はろー")
Avatar
Author icon
hironytic
print("はろー")
Version:
swift-5.2-RELEASE
Output:
はろー
Error:
Avatar
そんなつもりでは…w 入力できない方はコピペでもいいと思います!
😆 1
Avatar
しまった
Avatar
バッククオートコピペよう ` `
10:51 AM
あ、思ったのと違った
Avatar
swift print("hello")
Avatar
@swift-5.2.5 hello world
Avatar
exit status: 1 with stderr:<stdin>:1:6: error: consecutive statements on a line must be separated by ';' hello world ^ ; <stdin>:1:1: error: use of unresolved identifier 'hello' hello world ^~~~~ <stdin>:1:7: error: use of unresolved identifier 'world' hello world ^~~~~
Avatar
Contribute to refactoring-challenge/reversi-ios development by creating an account on GitHub.
Avatar
print("みえた")
Avatar
「このリポジトリをforkしてください」
10:53 AM
「GitHubアカウントを持ってない人はcloneしてください」 (edited)
10:54 AM
今回の趣旨: このFatViewControllerをリファクタしてみよう!
Avatar
あれ、これ音声チャンネルじゃないです?
Avatar
音声チャンネルです!
Avatar
oh,,,
Avatar
Github アカウントを持ってない方は git clone git@github.com:refactoring-challenge/reversi-ios.git
Avatar
画面共有はないやつですね
🙈 1
Avatar
こちらにいらしてください
koher pinned a message to this channel. 4/24/2020 10:55 AM
Avatar
あ、入れました!
👍 3
10:55 AM
yokattta
10:59 AM
初 commit です
Avatar
sugigami(susieyy) 4/24/2020 11:01 AM
こんばんわー 🙋‍♂️
Avatar
プロ勢揃い
Avatar
花芽尋かすみ 4/24/2020 11:01 AM
こんばんはー
Avatar
koher「今回やりたかった理由
  • 適度な例がほしかった
  • ふつうの勉強会では時間制限ゆえシンプルな例が多い
  • 実務では複雑すぎる
  • (2つめなんだっけ)
  • みんなで見せ合ったら面白そう
  • みんなで取り組むと共通言語ができるのでは。Reversiの○○パターンだね、みたいな
空中戦にならないように、具体的なコードをもとに語れるイベントやれると面白いと思った 」
(edited)
Avatar
あー、これ手に近い方からアニメーションするのか
Avatar
status: リポジトリのcloneはできたかな?できたら実行してみよう!
Avatar
途中から来られた方向け: ・今日は音声のみです。画面はありません ・チャンネルリストの下の方にある「音声チャット」に 🔊swift-zoomin というのがあります。そちらにお入りください ・このテキストチャンネルもコードを共有したり、補助的に使用します 今回のリポジトリはこちら。clone して実行してみてください https://github.com/koher/refactoring-challenge-reversi-ios 何かわからないことがあれば音声かこのチャットで遠慮なく聞いてください
Avatar
細かい仕様はREADMEに書いてあるので確認してください わかりにくい仕様: パスの時はアラートが表示される とか
Avatar
おー、両方Computerにしてたら、Resetのアラート中でも裏で盤面が進んでいく!
😮 6
Avatar
本来は「リファクタリング=壊さないように修正する」ですが、仕様を理解した上で作り直すでもOKです
Avatar
public enum Disk { case dark case light }
Avatar
status: コードの説明中
  • BoardView.swift
  • CellView.swift
  • DiskView.swift
  • Disk.swift
Avatar
// 3 列目・ 4 行目のセルの状態を取得 let disk: Disk? = boardView.diskAt(x: 3, y: 4) // 3 列目・ 4 行目のセルを黒のディスクが置かれている状態に変更 boardView.setDisk(.dark, atX: 3, y: 4, animated: false)
Avatar
花芽尋かすみ 4/24/2020 11:10 AM
このAPI初見したとき、すごくシンプルでわかりやす〜いってなりました
Avatar
boardView.setDisk(.dark, atX: 3, y: 4, animated: true) { isFinished in // アニメーション完了時に呼ばれる }
11:12 AM
extension ViewController: BoardViewDelegate { func boardView(_ boardView: BoardView, didSelectCellAtX x: Int, y: Int) { // x 列目・ y 列目のセルがタップされたときに呼ばれる } }
11:14 AM
Avatar
👆DiskViewが直接使われているところ (edited)
Avatar
Kishikawa Katsumi 4/24/2020 11:14 AM
なるほど!
Avatar
これら4つのファイルは変えなくてもリファクタできるように作っています (変えてはいけないという意味ではありません)
Avatar
👆READMEの「コード概要」セクションへのリンクです。
Avatar
Contribute to refactoring-challenge/reversi-ios development by creating an account on GitHub.
Avatar
👆ViewControllerを読むうえでの手がかりになるコードです。ここから読むのがわかりやすいかもしれません (edited)
Avatar
👆READMEの下の方にある画像です。IBOutletの関係の図なので是を見たらわかりやすいかもしれません ふたつの線が伸びているのはoutletCollectionです (edited)
Avatar
Fatでもわかりやすい…
Avatar
status: コード説明終了!今後の流れの説明
11:19 AM
  • 成果発表会は後日開催。3週間後、5/16です。
Avatar
# Swift Zoomin' Swift Zoomin' はプログラミング言語 Swift に関するオンライン勉強会です。普通の勉強会と同じようにスライドおよび音声で発表を行います。無料アプリのZoom を使う予定ですが、 Zoom 以外での開催の可能性もあります。 今回は Swift Zoomin' チャレンジ 〜Fat View Controllerを倒せ!〜で課題に取り組んだ報告会です。 Fat View Controller として実装されたリバーシアプリをリファクタリングし、どのようにしてクリーンなコードを実現したのかを発表者が説明...
Avatar
「こんなふうに解決したぜ!」と発表したい方は奮ってご参加ください
11:20 AM
(次回Zoomを使うかどうするかは未定です)
11:21 AM
3週間あるので、今日終わらなくても大丈夫!腰を据えて取り組んでみてください。
Avatar
花芽尋かすみ 4/24/2020 11:21 AM
声張ってこ(治安皆無(体育会系
🍴 2
Avatar
今日はもくもく会になると寂しいので、ミュート解除してわいわいやってください。ひとりごとも質問も大歓迎です
Avatar
あ、喋れない人はここを分報がわりに使うとか大丈夫です?
Avatar
花芽尋かすみ 4/24/2020 11:22 AM
僕もわかんないです
Avatar
はい
11:22 AM
🙏
11:22 AM
www
Avatar
花芽尋かすみ 4/24/2020 11:22 AM
なにもわからない
Avatar
会話しながらリファクタリングとかできるものなのみんな・・・
Avatar
AppCode 配信します
11:25 AM
音声は無ですが
Avatar
コードは雄弁でしょう(適当
Avatar
これってもうリファクタリング始まってます?笑
Avatar
テスト書きたくないのでなるべく書きません
11:26 AM
型で防御します
11:27 AM
あ、私も MVC ですね〜
11:27 AM
😏
11:27 AM
Sample App to learn a testable design (Smalltalk flavored MVC) - Kuniwak/TestableDesignExample
11:27 AM
私はこういう感じですねぇ
11:27 AM
テスト書いたら負けです
11:27 AM
型で
11:27 AM
守ります
😆 1
Avatar
設計本に合わせてFlux + MVVMで進めておりますm( )m
Avatar
enum VerticalIndex: Int { case one = 0 case two case three case four case five case six case seven case eight }
Avatar
MVVMになりそうかなあ
Avatar
ご覧ください
11:28 AM
絶対に out of index を起こさないいしを
11:28 AM
感じてください
Avatar
花芽尋かすみ 4/24/2020 11:28 AM
ww
Avatar
Swift Zoomin' チャレンジ の過激派枠で参加を申し込みました! https://t.co/JyGX731QWt #swiftzoomin
Avatar
sugigami(susieyy) 4/24/2020 11:28 AM
設計本の担当章に合わせて Reduxで進めております 🙋‍♂️
Avatar
花芽尋かすみ 4/24/2020 11:29 AM
MVP + クリーンアーキテクチャ脳なのでそれでやっていきます。 とりあえずデータの保存・読み込み周りのコンポーネント切り出しからやってます
Avatar
型の許す範囲に
11:29 AM
ダメな値があるからダメなのです
11:29 AM
ならば型を狭めましょう(過激派 (edited)
Avatar
僕はまず白と黒の星の画像に変えます
⭐ 4
Avatar
そこらへんはふふふ
11:29 AM
ですね!
Avatar
花芽尋かすみ 4/24/2020 11:29 AM
星は草
Avatar
足し算は overflow したら 多分 null とかになる
11:31 AM
あ、それは null にするんですよ
11:31 AM
なので、
11:31 AM
足し算するところで
11:31 AM
overflow するかいなかを検知させます
11:31 AM
なので、どこでおかしく鳴ったのかすぐわかりますね〜
11:31 AM
です!
11:31 AM
まあ死んだら諦めます
11:31 AM
過激派も引き際大事
Avatar
花芽尋かすみ 4/24/2020 11:32 AM
事前にやると言いつつ、昨日コード読んだだけの状態です🙇
Avatar
あ〜 Vim コマンど炸裂したんじゃ〜
11:32 AM
11:32 AM
twitter
11:32 AM
いいですよ〜
11:32 AM
ww
Avatar
なにが永続化されてるか見るか
Avatar
まず我々はドメインを定義する必要があるってやつです(適当
Avatar
花芽尋かすみ 4/24/2020 11:33 AM
アカウントふたつ用意したら
11:33 AM
いける
Avatar
swift の subscript setter のやり方忘れた、、、
11:34 AM
ほんとだwww
11:34 AM
クソザコなのがバレた
Avatar
sugigami(susieyy) 4/24/2020 11:34 AM
事前に取り組みさせてもらいました Reduxはとても相性がいいですよ! あと、コンピューターの考える時間を短くしてDebugしやすくしてます
👍 2
Avatar
MVC -> MVVMってすすめていったらわりとやりやすそう?
Avatar
花芽尋かすみ 4/24/2020 11:38 AM
@Kuniwak 文字がちょっとつぶれてしまっているので、サイズ大きくしていただけたりしますか?👀 (edited)
Avatar
はい?
11:39 AM
はい
11:39 AM
はい
11:40 AM
遅くなるからでしょうね〜
11:40 AM
私はあんま煩雑だとは思いませんねぇ
11:40 AM
人間が確信のある時のみ明示的に force unwrap すればいいのでは派です
Avatar
sugigami(susieyy) 4/24/2020 11:40 AM
ReduxのActionに落としやすかったです ただStateの差分更新をViewに実装するのは大変だったのでReducerで差分を計算しています ただ、いきなりReduxにリファクタリングは動作を保証しながら移行は難しくて 動作を確認しつつシンプルなMVCに移行してから、Reduxへと段階的に移行しました
Avatar
それでは、『SwiftのOptionalのベストプラクティス』というタイトルで発表します。 #swtws pic.twitter.com/OJfz2tk4sP— koher (@koher) 2017年4月15日 2 年程前、 ...
Avatar
リプレイとかUndoとかはReduxじゃないとめんどくさそう
Avatar
花芽尋かすみ 4/24/2020 11:43 AM
あー
Avatar
// Immutable 最高! // index がはみ出さないことを、初期値を Index で保証しているから、force unwrap しても安心だね!
11:43 AM
直近のコメントです
Avatar
sugigami(susieyy) 4/24/2020 11:44 AM
ActionでStateを変更するごとにごとにStateをDiskに履歴を保存して巻き戻すとか
Avatar
アッ、cdoe 思い
11:44 AM
AppCode 固まった
Avatar
稲見さんのHervestを覗くとその辺丁寧に例出してくれてますね (edited)
Avatar
AppCode!
11:45 AM
息をしてくれ!!!!
Avatar
🌾 Harvest: Apple's Combine.framework + State Machine, inspired by Elm. - inamiy/Harvest
Avatar
大事な布教のタイミングなんだ!
😆 1
11:46 AM
テスト書いたら負けです(テストを生業とするものの暴言
Avatar
ミュート・ミュート解除の音を皆に通知したくない場合は Preference >アプリの設定>通知 からオフにできるようです
🙏 1
Avatar
切り離しですねぇ
11:47 AM
AppCode 蘇生
Avatar
花芽尋かすみ 4/24/2020 11:47 AM
無い人だっているんですよ!!!
Avatar
あれ、これどこが (0, 0) だ
11:52 AM
まあ多分左上が 0, 0 であろう(適当)
11:52 AM
もはやあまり振る舞いを買えないを気にしていない
11:53 AM
あー、LLDB にするか
11:53 AM
型最高!
11:53 AM
あ、よかった
11:53 AM
LLDB 開こうと確認しちゃいました
11:57 AM
あれ、ReeactiveSwift だともうちょい簡単かもです?
11:57 AM
私特に困ったことないです(RxSwift でもあんま困ったことない
11:57 AM
私は速攻で ReactiveSewift と MirrorDiffKit を入れました
Avatar
Combineはいいぞ
🙂 5
Avatar
Combine この前入門に失敗したオタクなので
Avatar
型消去に慣れたらいい感じ
Avatar
protocol Foo { associatedtype PublisherType: Publisher where Output == Bar var bar: PublisherType { get } }
Avatar
ぐ、ご飯のため離席、、、また後日
🍚 5
Avatar
とりあえずデータ管理をロジック層に分離するため、現在の状態を返す BoardView.diskAt のfunc丸ごと消してコンパイルエラーを起こすことから始めました ここで起こったコンパイルエラーを新しく作る盤面管理するやつ使ってコンパイルエラー直してやる予定
👍 4
Avatar
あ、モノイド則満たすわあ
12:13 PM
完全に理解した
Avatar
私はフォルダ構成を整えてみました
12:14 PM
ここからどうしよう… MVPぽくしたいので、Presenterを作ってみようかな
Avatar
ところで途中から入ってきた人で、何か困ってる方いらっしゃいますか? なにかありましたらテキストでも音声でもお気軽に! リポジトリ情報などは 📌 アイコンから確認できます (edited)
👍 1
Avatar
今までひたすらソースを眺めていたけどやっと手を動かし始めました。 とりあえず BoardView のAPIをprotocolに切り出して、ロジックを具体的な BoardView から切り離してみたいと思ったけど、 placeDisk がいやらしい 😢
👍 1
Avatar
BoardView のAPIをprotocolに切り出して、ロジックを具体的な BoardView から切り離してみたいと思ったけど
12:36 PM
ですね。僕もBoardViewのAPIだけが欲しいと思いました
🤝 1
Avatar
リバーシの盤面は8x8であるものとするか、任意偶数の正方形サイズを許容すべきか、というどうでもいいことを考えてる
Avatar
sugigami(susieyy) 4/24/2020 12:39 PM
ViewControllerからロジックは切り離しやすいですが、BoardViewから切り離すときに動作も壊さず少しずつつリファクタリングするのに難儀しました
Avatar
var board: Board = Board(""" -------- x------- -o------ --ooo--- ---ox--- -----oox ---ooo-- --o-x--- """) do { try board.place(.dark, atX: 4, y: 5) XCTAssertEqual(board, Board(""" -------- x------- -x------ --xoo--- ---xx--- ----xxxx ---oxo-- --o-x--- """)) } catch let error { XCTFail("\(error)") }
Avatar
Kishikawa Katsumi 4/24/2020 12:48 PM
リバーシの盤面は8x8であるものとするか、任意偶数の正方形サイズを許容すべきか、というどうでもいいことを考えてる
おもしろいですね。なんか実際にもっと大きい・小さい盤面のオセロもあるみたいですね。
Avatar
中央の4x4の範囲の四隅に●の表示がほしいなーとか、リファクタリングと関係ないどうでもいいことを考えてしまったり
Avatar
なんでそんなことを考えていたかっていうと、 widthxRangestatic let でなかったからなんですよね static let でないと、インスタンス毎に違う場合がある(今回は8x8でない盤面が今後追加される計画がある)のではないかと勘繰ってしまう
Avatar
public enum State: Equatable { case beingPlayed(turn: Disk) case over(winner: Disk?) }
Avatar
Kishikawa Katsumi 4/24/2020 12:54 PM
私も大きさが変わっても大丈夫なように作っとくと思いますね。
👍 1
Avatar
Kishikawa Katsumi 4/24/2020 12:57 PM
turn = Disk ^ これも見通しの悪さに影響してるな😅直すぞ〜 (edited)
Avatar
let board: Board = Board(width: 6, height: 4) XCTAssertEqual(board, Board(""" ------ --ox-- --xo-- ------ """))
Avatar
2x2より小さくしたらどうresetするのか気になりますね。
Avatar
public struct Board { // ... public init(width: Int, height: Int, disks: [Disk?]? = nil) { precondition(width >= 2, "`width` must be >= 2: \(width)") precondition(height >= 2, "`height` must be >= 2: \(height)") precondition(width.isMultiple(of: 2), "`width` must be an even number: \(width)") precondition(height.isMultiple(of: 2), "`height` must be an even number: \(height)")
😂 1
Avatar
Kishikawa Katsumi 4/24/2020 1:00 PM
保存データのフォーマットは [現在のターン(黒・白)][先手番が人間かコンピュータか][後手番が人間かコンピュータか] [ボードの状態]
1:00 PM
こうですね。
Avatar
marty-suzuki 4/24/2020 1:01 PM
Viewの入出力を、ViewModelのinputとoutputに対して1対1で紐付けてこんな感じにしてみています。
Avatar
Kishikawa Katsumi 4/24/2020 1:01 PM
これは読みやすい
1:02 PM
動きは同じようになるんですか?
Avatar
marty-suzuki 4/24/2020 1:02 PM
動きも同じになるよにテストを書きつつ進めてました
1:03 PM
リセットを押してアラートは、そのままでますねw
Avatar
リセットは面倒くさいので画面丸ごと作り直しという仕様に落とし込むのが楽・・・?
Avatar
marty-suzuki 4/24/2020 1:07 PM
画面の優先度を仕様として決めてしまって ・表示しているものを閉じて表示する ・何もしない という処理にしてたりします
👀 1
Avatar
Kishikawa Katsumi 4/24/2020 1:07 PM
enum Player { case human case computer }
Avatar
podcastみたいになってるw
📻 1
Avatar
そこで日本語プログラミングですよ https://qiita.com/codelynx/items/9af94d8f9f24cee339e2
Swift に限った話ではありませんが、クラス名や変数名に Unicode が使えるようになってきました。🐶🐱を変数にするのも結構ですが、もっと日本語を積極的に使っていけば、開発や保守が楽になるケースがあると考えていました。今回、日...
Avatar
スピードスター 👀
Avatar
Kishikawa Katsumi 4/24/2020 1:12 PM
enum { case 黒 case 白 }
1:12 PM
これでよかったんや
1:12 PM
struct 手番 { 先手番 後手番 }
1:13 PM
棋譜でテストを書きたい
Avatar
「全取りは64:0扱いという仕様」再現されてませんね (edited)
🙌 2
😮 1
🎉 2
Avatar
Kishikawa Katsumi 4/24/2020 1:18 PM
struct Board { var discs: [Disc?] = [ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, .white, .black, nil, nil, nil, nil, nil, nil, .black, .white, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, ] }
Avatar
ZWJもskin toneもいけました (edited)
1:25 PM
Avatar
@swift-5.2.5 var 🎲: Int { (1 ... 6).randomElement()! } print(🎲) print(🎲) print(🎲)
Avatar
6 6 6
Avatar
@swift-5.2.5 var 🎲: Int { (1 ... 6).randomElement()! } print(🎲) print(🎲) print(🎲)
Avatar
1 4 6
Avatar
一度全部壊して作り直すならすぐなのですが、真っ当に少しずつリファクタリングをしていくとなると難しい・・・
Avatar
Kishikawa Katsumi 4/24/2020 1:34 PM
enum Disk: CaseIterable
1:34 PM
^ sides はCaseIterableで良さそう
1:40 PM
Disk.allCases()
Avatar
This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - apple/swift-evolution
Avatar
22:40 現在 元のViewController: 573行 私のViewController: 620行 https://github.com/uhooi/reversi-ios/blob/feature/refactor/Reversi/GameViewController.swift 泣きそう
Contribute to uhooi/reversi-ios development by creating an account on GitHub.
😂 3
Avatar
「Disk.light, darkを直そうと思ったらInterfaceBuilderで使われてるので駄目でした…」 「ViewController以外の4つのファイルは触らなくていいつもりだったので、触るときには自己責任で」
Avatar
game pieces called disks (often spelled "discs")
(edited)
Avatar
Kishikawa Katsumi 4/24/2020 1:47 PM
増えてる😂
😫 1
1:47 PM
どれだけ長くできるかというのもあり
Avatar
FizzBuzz Enterprise Edition is a no-nonsense implementation of FizzBuzz made by serious businessmen for serious business purposes. - EnterpriseQualityCoding/FizzBuzzEnterpriseEdition
1:50 PM
Avatar
Kishikawa Katsumi 4/24/2020 1:57 PM
override func viewDidLoad() { super.viewDidLoad() boardView.delegate = self messageDiskSize = messageDiskSizeConstraint.constant do { try gameManager.loadGame() } catch _ { gameManager.newGame() } updateUI() }
1:57 PM
^ とりあえずnew/load/saveを分離して初期表示はできるようになったよ
👏 5
Avatar
状態遷移の絵
Avatar
Kishikawa Katsumi 4/24/2020 1:59 PM
基本的にあとはプレイヤーの行動でGameStateが変化して updateUI()で最新の状態とUIをSyncすればOK、とするとツールアプリではだいたいそれでいいけど
1:59 PM
きちんと裏返るアニメーションをやろうとするとそんなシンプルには行かない気がする
Avatar
marty-suzuki 4/24/2020 2:04 PM
差分更新にすると、アニメーションの順番担保が難しかったので諦めました... (edited)
Avatar
[[Disk?]]だけだと差分更新でアニメーションつらそうですね
Avatar
なんだろう、Nextstep.fm復活してほしい
👍 2
Avatar
sugigami(susieyy) 4/24/2020 2:06 PM
基本的にあとはプレイヤーの行動でGameStateが変化してupdateUI()で最新の状態とUIをSyncすればOK、
僕もReduxでGameStateを変化して、updateUI()で最新の状態とUIをSyncする作りにしてます アニメーションだけ差分をRedcuerで計算して、データの差分をアニメーションしてます
Avatar
左上から一回転 let directions = [ (x: -1, y: -1), (x: 0, y: -1), (x: 1, y: -1), (x: 1, y: 0), (x: 1, y: 1), (x: 0, y: 1), (x: -1, y: 0), (x: -1, y: 1), ] ... for direction in directions {
Avatar
PDT 7amなので西海岸の人の気配を感じる
Avatar
Kishikawa Katsumi 4/24/2020 2:12 PM
// MARK: Reversi logics ^ とにかくここをなくす、のが私は重要だとみた
2:13 PM
現状はcountDisks だけなくせた
Avatar
Kishikawa Katsumi 4/24/2020 2:21 PM
// MARK: Game management ^ それとここだな
2:23 PM
たぶんこれらをUIから分離できると、最初の人がやってたみたいにUnit Testで盤面の細かい挙動を検証したりとかができるんだと思う。
Avatar
PRのdiffからwhitespaceを消す方法 あるいはURLパラメータに w=1 をつける
Avatar
sugigami(susieyy) 4/24/2020 2:26 PM
Redux(ReSwift)のViewContollerはこんな感じです Game managementの制御が全部Actionになってます
Avatar
marty-suzuki 4/24/2020 2:28 PM
SPMにしようにとしたんですがテストでRxTest使おうとすると、おそらくstaticビルドされてる関係でlinker errorになって解決に時間かかりそうだったのでcarthageにしました
Avatar
なぜか元のmasterのコードでもここで落ちるシリアライズを吐いてしまった
2:34 PM
loadするとおかしい,そうです (lldb) e print(self.gameState.serialized) o11 xxxxxxxo -ooooxxo ooxoxoxx ooxxooxx oxxxxoxx xxxxoxxx xxoxxxxx xxxxxxxx
Avatar
Kishikawa Katsumi 4/24/2020 2:38 PM
報告会までには続きを書こう。どうもみなさんお疲れさまでした 👋
😀 5
2:41 PM
class func animate(withDuration duration: TimeInterval, animations: @escaping () -> Void, // ここ completion: ((Bool) -> Void)? = nil)
2:41 PM
↑これって @escaping じゃないといけないの?
Avatar
Kishikawa Katsumi 4/24/2020 2:42 PM
animationsはスコープ外に保持されるのでそうですね。
Avatar
即時実行されるだけじゃなくて後から呼ばれるケースがあるんですっけ?
Avatar
Kishikawa Katsumi 4/24/2020 2:44 PM
delayする場合もあるし、繰り返しもあるし、というのと、
Avatar
なるほどー。
2:45 PM
delay の場合は delay した後で呼ばれるんですね。
Avatar
Kishikawa Katsumi 4/24/2020 2:46 PM
でも、もしかしたら@escapingなくせるのかな
Avatar
繰り返しがあると無理かも?
Avatar
Kishikawa Katsumi 4/24/2020 2:46 PM
言われてみると、なくせる気もします
Avatar
placeDisk をどうにかしたら終わろうと思ってましたが、どうにかできたと思ったとたん、アニメーション中のままと認識されて次の手が指せなくなる不具合を産んでしまったので、今日はこの辺であきらめます。。。 😢
2:49 PM
お疲れ様でした。
Avatar
Kishikawa Katsumi 4/24/2020 2:50 PM
animationBlock自体はすぐ呼ばれるからなくせる気がしますねえ
Avatar
お疲れ様でしたー。
Avatar
おつかれさまでしたー
Avatar
ありがとうございました!
Avatar
marty-suzuki 4/24/2020 2:50 PM
ありがとうございました!
Avatar
ありがとうございました
Avatar
おつかれさまです!
Avatar
sugigami(susieyy) 4/24/2020 2:51 PM
ありがとうございました!
Avatar
みなさん、ありがとうございました😀
👏 6
Avatar
ありがとうございました!
Avatar
ご飯を食べてなかったので、ご飯を食べながら Discord 眺めてます🍚
Avatar
@mesummery @rarara @teppei_kikuchi おそらく切り忘れで音声チャットに入ったままになっていると思います。ミュートになっているので実害はないかもしれませんが、もし誤ってミュート解除してしまうと、意図せず音声が共有されてしまうかもしれないのでご注意下さい。
👍 2
2:44 AM
2:44 AM
↑このボタンで音声チャット切断できます。
👍 1
Avatar
@ikemoti 音声チャットに繋ぎっぱなしですね、上記操作で切断できるのでお手すきの際に 🙏
Avatar
omochimetaru 4/27/2020 6:49 AM
多分気づいてない系は蹴ってあげたほうがいいかなあ?
6:49 AM
あーでも、一応通話して応答確認とかすべきだしなあ、めんどいな。
Avatar
eventmgrにキック権限持たせて
6:50 AM
イベント終わったら掃除してもらうのが運用上楽だと思います
Avatar
omochimetaru 4/27/2020 6:50 AM
このまえ @koher に渡してたevent-opsには実はそれは与えてあった
6:50 AM
荒らし対策でBANまでできるぞ
Avatar
与えてあっても説明してなければできないでしょw
Avatar
omochimetaru 4/27/2020 6:51 AM
右クリックしたらわかるかなって・・・
6:51 AM
サイレスかけるときに、BANも一緒に選択肢に出てるぜ。
Avatar
箇条書きで良いのでイベント開催マニュアル用意して、「イベントが終わったら気づかずに接続しっぱなしの人を音声チャットから切断させる」とあれば良さそう (edited)
👌 2
Avatar
ikemoti さんはイベント後にはいなかったので(いた人は↑でメンションしたので)、おそらくその後、誤操作で入ってしまったのかと思います。
Avatar
omochimetaru 4/27/2020 6:59 AM
あ〜なるほど。
Avatar
申し訳ないです🙏
👌 1
Avatar
誘惑に負けてテストを書いてしまった…(テストを書かぬと決意した人)
2:34 AM
今の所、累積で 3 bug、、、 (edited)
Avatar
@Kuniwak よかったら過激派の成果発表をお待ちしてますw画面共有でソースコード見せながら5分LTとかでも大丈夫です。 https://swift-tweets.connpass.com/event/174512/
# Swift Zoomin' Swift Zoomin' はプログラミング言語 Swift に関するオンライン勉強会です。普通の勉強会と同じようにスライドおよび音声で発表を行います。無料アプリのZoom を使う予定ですが、 Zoom 以外での開催の可能性もあります。 今回は Swift Zoomin' チャレンジ 〜Fat View Controllerを倒せ!〜で課題に取り組んだ報告会です。 Fat View Controller として実装されたリバーシアプリをリファクタリングし、どのようにしてクリーンなコードを実現したのかを発表者が説明...
Avatar
お、間に合えば〜
🙂 1
2:38 AM
そういえば、koher さんの書いた disk を置けるところの判定がよくできてて、ほえ〜ってなってました
Avatar
ありがとうございます。(アニメーションしない)リバーシは何度も書いてるので😅
Avatar
私は型的に間違った値が作られず、かつ性能がさほど悪くないを目指していますが、あれほどシンプルにはできないなぁ、みたいな
2:40 AM
型的に間違った値が作られない、結構面白いですよ
Avatar
もしかして盤外で nil を返すところですか? < シンプル (edited)
Avatar
あ、ちょっとお待ちを、関数名拾ってきます
Avatar
型的に間違った値が作られない、結構面白いですよ
型でこだわる題材としてリバーシはおもしろそうですね。
Avatar
flippedDiskCoordinatesByPlacingDisk
2:41 AM
です!
2:43 AM
あ、間違った値が作られないについてですが、 struct Line: Hashable { let start: Coordinate let end: Coordinate let direction: Direction let distance: Distance init?(start: Coordinate, direction: Direction, distance: Distance) { // NOTE: Be nil if the X is out of boards. let unsafeX: CoordinateX? switch direction { case .top, .bottom: unsafeX = start.x case .left, .topLeft, .bottomLeft: unsafeX = CoordinateX(rawValue: start.x.rawValue - distance.rawValue) case .right, .topRight, .bottomRight: unsafeX = CoordinateX(rawValue: start.x.rawValue + distance.rawValue) } // NOTE: Be nil if the Y is out of boards. let unsafeY: CoordinateY? switch direction { case .left, .right: unsafeY = start.y case .top, .topLeft, .topRight: unsafeY = CoordinateY(rawValue: start.y.rawValue - distance.rawValue) case .bottom, .bottomLeft, .bottomRight: unsafeY = CoordinateY(rawValue: start.y.rawValue + distance.rawValue) } switch (unsafeX, unsafeY) { case (.none, _), (_, .none): return nil case (.some(let x), .some(let y)): self.start = start self.end = Coordinate(x: x, y: y) self.direction = direction self.distance = distance } }
2:43 AM
がわかりやすいかもです
2:43 AM
これやりすぎなので、業務では参考にしないでほしいですが考え方としては面白いですよね
Avatar
unsafeX w
Avatar
この Line はひっくり返す時の線を表現していますが
2:45 AM
変にずれた角度にならず、かつ必ず盤上に収まる線しか実体化できません
Avatar
x と y ですら別の型になってるんですね・・・
Avatar
よく取りちがえるので、、、
Avatar
たしかに i, j を間違えるとかよくある話ですし、それを型で弾けるのおもしろいですね。
Avatar
ただ、rawValue は単なる Int なので、ここで油断すると死にます
Avatar
なるほどー。何をやっているのかわかってきました。
Avatar
なので、rawValue 操作するときは必ず、X とか x とかが確認できる名前にしています
2:49 AM
もしそこに不純物が混ざっていると xxX y みたいになってすぐわかるという寸法です
Avatar
絶対にエラーにならない Line を生成してるんですね。
Avatar
です
Avatar
これ、 DirectionDistance を渡して CoordinateInterval 的なのを返すメソッドを作って、 CoordinateCoordinateInterval の間に + (戻り値は Coordinate? )を実装するとシンプルになりませんか?
Avatar
それ考えたのですが(もし理解が間違ってたらすみません)、それだと加法で dx=1, dy=2 みたいな無効な線を作ってしまえると思って途中で方針を変えました (edited)
2:54 AM
なので、始点と角度と距離だけで構成できるようにしています
Avatar
direction.interval(of: distance)CoordinateInterval を作るのでそれを使う限りは dx = 1, dy = 2 みたいなのは作れないですが、 + の戻り値が型として不正な値を許容するのはその通りですね。ただ、イメージとしてはその結果を Line に使うんじゃなくて、前段のエラー判定をシンプルにできるかなと。
Avatar
あ、処理を別コンポーネントへ切り出したいって感じであってます?
Avatar
そうですね。↓みたいな。 init?(start: Coordinate, direction: Direction, distance: Distance) { guard let end = start + direction.interval(of: distance) else { return nil } self.start = start self.end = end self.direction = direction self.distance = distance }
3:00 AM
switch の二回の分岐が Direction.interval の一回にまとめられそうだし、
Avatar
ですよね!この + がどうしても外部に公開されてしまうし、何より + は便利すぎるけど今の所ここでしか使わなさそうだたので封印した結果あのコードになっています
Avatar
なるほど。
3:01 AM
よく考えたら一回にまとめるのはここに書いてもまとめられますね・・・。
Avatar
これは実用性を捨てて、とにかく間違った値を型設計で許さないという方針の元のやつなので
3:01 AM
はい、まとめられます
3:01 AM
ただ、これは認知のしやすさのために2段にしていて
3:01 AM
この 9 通りで間違わず x と y を設定する自信がなかったので
3:01 AM
上下と左右で分けてこのようにしました
Avatar
この + がどうしても外部に公開されてしまうし
こういうとき、僕は結構可読性のためだけに fileprivate extension 使ってコード分解したりしますね。
Avatar
はい、ただそれやると凝集性が落ちませんか?
3:03 AM
利用者側が不安全な便利関数を作るわけなので…
3:04 AM
本来は、提供側が安全な便利関数を提供するのがベストだと思います
3:04 AM
今回は過激な方針によってこれを満たせそうになかったので、このようなギョッとするコードになってしまう、、、
3:05 AM
ただ、初見の読みづらさはなんとかしたい…
Avatar
元のコードだと方向から差分を作る処理と、差分を足し込む処理が混ざっているので、それを分解したいなという気持ちになりました。
Avatar
わかります、わかります、、、、
3:06 AM
元々は CoordinateDelta という struct があって、まさにちゃんとそうやってました
Avatar
なるほど。それを経た上での検討の結果なんですね〜。
Avatar
あ、commit に残ってないw
3:07 AM
💀
3:07 AM
雑 commit が祟った、、、、
3:08 AM
ところで、私のコードは自動/手動テストで型検査を漏れて生まれたバグを記録しております: https://github.com/Kuniwak/reversi-ios/blob/f7c65cee30e981a66db6a241ae62a99801d27dd8/Reversi/MVCArchitecture/Models/LineContents.swift#L15
Contribute to Kuniwak/reversi-ios development by creating an account on GitHub.
3:08 AM
現在 3 バグ漏れています 💀
Avatar
厳密な型を使うことでどこまでテストを省けるのかは興味深いですね。
Avatar
こんなに過激な方針を敷いてもバグって出るのか〜みたいな学びを現在進行形で学んでおります
3:09 AM
結局これ書いちゃったので敗北感は強いっすね
3:10 AM
これ、同僚もここ見てるので釈明しますが、やってたのは昨日です…(進行形ってかくとお前仕事してないとかいい度胸だな?ってなりそうで怖い)
👁️ 1
3:12 AM
Line を型にするのおもしろいですね。
3:12 AM
もっと過激になれば、あるセルを起点としたライン型みたいなのも作れるんでしょうか。
Avatar
Delta の代わりに、間違った値が作られない型が必要だったのです
3:12 AM
あ、作れると思いますよ
Avatar
Line<X3, Y4> みたいな。
Avatar
型レベル自然数を作ってやる感じですね (edited)
3:12 AM
ですです
3:14 AM
ただ、今回のように不安全な値で nil になるようなコンストラクタを作ると、型レベル自然数導入しなくてもなんとかなるし、これでもまあ安全なのでいいかなぁ、という妥協をしました
3:15 AM
Contribute to Kuniwak/reversi-ios development by creating an account on GitHub.
3:15 AM
こいつと合わせてみないとわからないかも
Avatar
うーん、ちゃんと理解できてないのかもですが、 CoordinateDelta を導入しても Line の安全性は init? での検査で保証できそうな気がするんですが、どういう問題があったのでしょうか?
Avatar
あ、それでもできると思いますよ
3:17 AM
その場合、 + がわけわからない signature になるのです
Avatar
なるほど。
Avatar
CoordinateDelta.add(_:CoordinateDelta) -> CoordinateDelta?
3:17 AM
ならうまく行くんですが
3:18 AM
これって結局許される delta は
3:18 AM
各方向への単位ベクトルと、その長さのバリエーションだけなんです
Avatar
Coordinate.add(_: CoordinateDelta) -> Coordinate? だとどうですか? (edited)
Avatar
はい、それも昔は付いていましたが、それで何を計算したいかなんですよね
Avatar
盤上におさまっているか?
Avatar
はい、そこはもちろんそうなんですが
3:19 AM
結局、オセロで座標を移動したい時って Line にそったものしかないと思うんです
Avatar
なるほど、じゃあ↓だとどうでしょう? struct DirectedDistance { var direction: Direction var distance: Distance }
Avatar
はい、それは妥当な定義だと思います
Avatar
そもそもこういう不要な型をつくりたくない?
Avatar
いえ、そんなことはないですよ
3:22 AM
ただ、DirectedDistance は始点によって盤外に飛び出るのが何点ですね (edited)
3:23 AM
そうすると、つど DirectedDistance を使う場所で盤外検査が必要になってしまいます
3:23 AM
であれば、Line で番外に出ないことを最初に一括で保証できたら、
Avatar
そこで Coordinate.add(_: DirectedDistance) -> Coordinate? とか?
Avatar
という意図があの Line の 4 field の意図です
Avatar
あ、もちろん、その上で Line も作る気持ちです。
Avatar
はい、まさに Line の別表現ですね!
3:24 AM
DirectedDistance は結構いいと思いますね。これあったほうが読みやすいかな
Avatar
Lineinit? は読みやすくなるかなと思いました。 Line のメンバを startdirectedDistance に置き換えるかは悩みますね。
Avatar
戻り値はどうしようかな
Avatar
Kuniwak さんの実装、全体のリファクタリング方針だけじゃなくて、部分を切り出しても色んな LT ができそうですね。
Avatar
過激なだけあって可燃性はなかなかものと定評があります
Avatar
いや、真面目な話として、 Distance の話とか、 CoordinateXCoordinateY を分ける話とか、それらの間で演算をどう扱うかとか、 Line のイニシャライザで検査することで不正な Line を作れなくしてるとか、切り口がめちゃくちゃあって、それぞれで LT できそうだなと。
Avatar
ですねw
3:29 AM
まあどうせなら変わったことやろうというつもりで
3:29 AM
やっているので話せるところはお話ししようと思います
3:29 AM
多分 free talk の方が面白そう
Avatar
フリートーク形式でも大丈夫です🙂
👍 1
Avatar
```swift struct Line: Hashable { let start: Coordinate let end: Coordinate let directedDistance: DirectedDistance init?(start: Coordinate, directedDistance: DirectedDistance) { guard let end = start.moved(to: directedDistance) else { return nil } self.start = start self.end = end self.directedDistance = directedDistance } ```
3:40 AM
めっちゃシンプルになりました〜
🎉 1
Avatar
おお、読みやすくなった気がします😀
🙏 1
Avatar
さて再開するか〜
Avatar
やっぱり macOS でテスト動かした方が早い
Avatar
あれ、これパスする状況ってどうなるんだろう
11:03 AM
リバーシでパスが必要になる盤面の最短シナリオ is ...
Avatar
なんか僕の見てた最短パスの手が書かれたページがつながらなくて、他が見当たらないです・・・。
1:00 PM
自分の書いたテストを見てみると、パスが起こる直前の盤面から始めたテストが書かれてました。
1:24 PM
単にMacのChromeの調子が悪いだけでした💧
Avatar
おっ、ここがSwift型レベルチャンネルか?( 🤔
1:53 PM
このゲーム、ルールを変更して「ワインをたくさん飲んだ方が勝ち」にしたとき「オセロの元々のルールで勝利している場合、新たなルールでも常に勝利する」みたいなこと言えたりするかな? https://t.co/ENnSHp1NoU
1:54 PM
(それはおいておいて)リバーシ(オセロ?)だとこういう ☝️ のをやったことがあって、ちょっとこれ詳しいひと(?)に証明してもらいたいという気持ちがある(?)
Avatar
途中で飲みすぎて棄権負けパターンがありそうな・・・💧
Avatar
2 vs 2のチーム制でやったわけですが、終盤になるとたとえば5個ひっくり返したときにどっちが3飲むか?などで揉めるなどしますw
😅 1
Avatar
決着がついたときにはN/2枚ずつ置いてるはずで、途中にひっくり返し合った分は打ち消し合っているはずだから、最終的に多い方がたくさん飲んでるで合ってるように思います。 (edited)
4:10 PM
リバーシって序盤は少なく取った方が有利だけど、後半で盛り返すときに一気にたくさん飲まないといけなくてそこでダウンとかもありそう😂
4:13 PM
あ、置くときは飲まないのか。それでも、最終的な差分が飲んだ差分になっているはずだから、成り立ちそう。先手が置いて終わったときに1枚差だった場合に例外があり得る??
Avatar
僕もそうおもったんですが、パスを考慮してもうまくいくか?というのをTwitterで指摘されました。
Avatar
あー、パスがあると置く枚数が変わるんですね。なるほど。
Avatar
(僕も指摘されてはじめてオセロでパスという状況が生じるのを知りました)
Avatar
パスがあると成り立たなさそうに思いますね。極端な話、10連続パスとかあったら、飲まずに10枚稼げるので。
4:15 PM
そのままゲーム終了パターンもあり得るし。
Avatar
オセロはおそらくどこでも置けばパスよりはマシな結果になるはず(本当か?)なので、パスは置けない場合に限るというのにしたほうがいいかも。
Avatar
パスは置けない場合に限るはずです。
4:17 PM
どこでも置けばパスよりはマシな結果になるはず
これは違うと思います。いかに置きたくない場所に置かせるかというゲームだと思います。
Avatar
ほほー。
4:18 PM
序盤は少なく取った方が有利 このへんにつながるのかな。
Avatar
わかりやすいところでは角の周りの3マスは置きたくないですが、そこ以外に置けなくされると辛い状況になります。
Avatar
そこに置くと敵に角取るチャンスあたえるからか。
Avatar
そうですね。少なく取るというのは、より正確には相手の選択肢を狭めるように取ると言った方がいいんですが、多く取るとどうしても相手の選択肢が増えるので良くない手であることが多いです。
4:20 PM
角の周りでも↓の x が角として、 o の位置は場合によってなんとかなりますが、 - の位置はかなりきついです。 o- xo
4:22 PM
でも、昔自分の作ったAIと対戦してたら、序盤から中盤くらいに角を一つくれてバグったかと思ったら、その後パスか、打てる手が一つしかない状態のまま残り数十手が進んで、その角一つを残して63:1で負けたことがあります。なので、例外的にあえて角を与えて有効な場合もあるとは思います。 (edited)
4:29 PM
元の話に戻ると、相手のパスで枚数を稼げるから成り立たなそうだけど、相手のパス=自分がかなり有利な状態でひっくり返す枚数も増えそうだから、本当に証明するには反例を見つけないといけなくて、かなりレアな例になりそうだから、反例を見つけるのが難航しそうに思います。ある盤面で起こり得ても、ゲーム開始状態からその盤面にたどりつけるかもわからないし・・・。
Avatar
僕は背理法というか、パスをしてトータル石の数では負けつつもひっくり返した数では勝利する(ワインを多くのむ)という状況が成り立つと仮定して矛盾を引き出せないか?というアプローチをやってました。
Avatar
オセロは相手に角の隣を取らせるゲームなので、例えば白がそこに置くしかない状況になった場合、パスが自由だと白黒ともにパスをし続けて千日手になりますね。
Avatar
なるほどなw
4:36 PM
(しょうじき、このワインオセロやるまでオセロについて深く考えたことなかったですねw)
Avatar
この盤面は非常に簡単に作れる、というか
4:37 PM
上級者の対戦だと腕に少しの差があるだけで頻出する気がします (edited)
Avatar
オセロあまりやったことなくてワインオセロやるの死亡フラグ感がありますねw
Avatar
この盤面 = 角のまわりを取るしかない状態に対戦相手を追い込む ☝️ ってことかな。
Avatar
いや、違うのか、負けると飲まなくて済むのか。
Avatar
そうです
👍 1
Avatar
オセロあまりやったことなくてワインオセロやるの死亡フラグ感がありますねw
まあ、負ければあんまり飲まなくてもいい(ひっくりかえしたら飲む = 強い方が飲む)というのはあります。
4:40 PM
よくわかってなかったけど、対戦あいてもあんまりオセロのことをよくわかってなかった(のか酩酊したのか)とにかく勝利したのは覚えてます。(が、そのあと友人宅から帰れなくなって朝かえった)
Avatar
勝ち負けいずれにせよ、途中のひっくり返しあった分は双方飲んでるわけで、勝敗は誤差かもしれませんね😅
Avatar
パスさえなければ、基本置く石の数は同じなので、勝つ(石がトータル多くなる)にはひっくりかえした量で勝つしかないから、ワインたくさん飲んだ方 = 勝者だと思います。
4:42 PM
(僕もあんまりお酒が強くないので、途中はしょうじきなんでこんなことやってしまったのか?って思ってはいました)
Avatar
これ私の過去の棋譜から拾ってきたすごく極端な盤面です。この後黒の手番ですが、1個でも置くと確実に角が取られてしまう。 (edited)
4:46 PM
8三で逃げれるけど8ニを埋められたら詰むので実質変わらないですね
4:46 PM
こういう状況になるとパスが最も良い手として判断されると思います
Avatar
これはすごいw
Avatar
ところでこの後黒が勝ちます
Avatar
そういう予感(?)はしましたが、なるほどな。
Avatar
これ、3二で白がしのいでも
4:47 PM
7二で8一とったら上の列ひっくり返されちゃいますよね?
Avatar
7七と8八かな?
Avatar
--oooo-- --ooo--- -ooooooo oooxxooo ooxooooo oooooooo --oooo-- --oooo--
4:50 PM
から x が打って次の手で角取られないためには
4:50 PM
--oooo-- --ooox-- -oooxooo oooxxooo ooxooooo oooooooo --oooo-- --oooo--
Avatar
オセロ、Swiftで実装するなら ☝️ こういうフォーマットのインポート機能を実装しましょう(?)
Avatar
どこ置いても白は対応可能なので、角は渡すしかない
Avatar
--oooo-- --ooo--- xooooooo oxoxxooo ooxooooo oooooooo --oooo-- --oooo-- だけど
4:51 PM
結局 tarunon さんの言うように白はしのげるけど、
4:51 PM
たとえば --oooo-- --ooox-- -oooxooo oooxxooo ooxooooo oooooooo --oooo-- --oooo----ooooo- --oooo-- -ooooooo ooooxooo oooooooo oooooooo --oooo-- --oooo-- でしのいで黒が角をあげないといけなくなっても (edited)
Avatar
ちなみにこの後の手順ですが 黒2七 白1八 黒7七 白8八で角を2箇所渡してから逆転します
4:52 PM
実際にはこの時点で、黒が置いた箇所にしかもう白は置けないので、一見すると激ヤバな黒が、白を詰ませています
Avatar
あ、思った場所に打てなかった
4:56 PM
↓みたいなパターンのときに o が角とったけど一番上の行を取り返されるパターンのことが言いたかったことです。 o-ooooo- -ooooo-- oxoooooo ........
Avatar
このゲームで発生するのはそれのもっとひどい奴ですね
Avatar
この場合は x が少なすぎてこのパターンにならなかった。
Avatar
ところでワインを沢山飲むことになるのは勝者で良さそう
👀 1
Avatar
これだけ x が少ないとコントロールしやすそうですね。
4:57 PM
パスのときにひっくり返ることが有り得そうじゃないですか? < 勝者
Avatar
あるマスにおいてコマが任意の回数ひっくり返るわけですが、黒→黒とはならないので
4:59 PM
あるマスにおいて最終状態が黒である場合は、ひっくり返った数はn回の白とn(+1)回の黒
Avatar
なるほどな。盤面のステートに注目するという発送はなかった。
Avatar
ワインオセロのルールがよくわかってないですが、ひっくり返したときに飲むのではないんですか?
Avatar
ひっくり返した数が有意に勝者のほうが多くなるんですね
Avatar
それであってます > ひっくり返したときに飲む
Avatar
パスが連続したときにひっくり返さなくても枚数かせげますよね?
Avatar
例えば角を取った場合、角の黒を置いたからと言って飲みはしないですが、それは白も同じ
5:01 PM
いいえ、いいえ
Avatar
置いたままひっくり返されずに終わるマスがありえるので。
Avatar
あるマスにおける状態遷移の発生回数だけワインを飲んでいるはずなのです
5:01 PM
置いたままひっくり返されないマスは、黒白ともにワインは発生しません
Avatar
これは証明ができそうな気がするな!
Avatar
たとえば、白20黒5の状態から、白が10連続パスで黒が毎回1枚ずつ置いて1枚ずつひっくり返した場合、白10黒25になりますよね?
Avatar
これが特に(?)いいのは、パスだけではなくて、置けるところがなくなって終了するケースについてもケアできること。 (edited)
Avatar
それで両者パスになって勝敗が付いた場合、黒はパスの間に10杯しか飲んでませんが、
5:04 PM
その時点で白が黒よりたくさん飲んだまま勝敗が決する可能性がないですか?
Avatar
ないです
5:04 PM
すべてのマス目において、最終状態がどちらかの色であるとき
5:05 PM
その色のプレイヤーはかならず反対の色のプレイヤーと同じ数、または+1杯のワインを飲んでいます
5:06 PM
パスがどれくらい挟まって〜という話もさもありなんに見えるんですが
5:07 PM
パスが発生して色が固定されるのって端っこのマスが多いんですよね。沢山ひっくり返るのはむしろ真ん中のマスで
5:07 PM
真ん中のマスを埋めてる間はパスは発生しにくいので初期状態は黒白イーブンになる
5:08 PM
さて、真ん中のマスがどうなるか、ですが
5:09 PM
往々にしてオセロの勝者は最終局面に置いて真ん中のマスの多くを取るケースが非常に多い
5:09 PM
これだけ条件が重なっているので、よっぽど恣意的に操作しない限りは(可能かどうかもわかりませんが) 勝者が沢山飲んでいる、ということになると思います
Avatar
もちろん現実的にはほぼ成り立ちますが、数学的に証明するにはすべての例を検証しないといけなくないですか?
Avatar
ちょっとあってるか分からないんですけど、
いまあるマス (i, j) が白になった数をW_ij として、一方で黒になった数をB_ij とする。ただし置いた時点で 1 とする。 ゲーム終了時点で、マス(i, j) は次のように分岐する 1. 黒である => B_ij = W_ij + 1 2. 白である => B_ij = W_ij - 1
となり、これらの積がひっくりかえした数なんですが、最終ステート(石のトータル)でのみ決まっていることから、「石の数で勝利しているならばひっくりかえした数も多い」がいえそうということですかね?
(edited)
Avatar
そうですね
5:12 PM
他の考え方も出来る気がしていて
Avatar
シンプルな証明ですね。すばらしい 🎉
5:12 PM
これにはCoqもにっこり(本当か?)
Avatar
シンプルに石の数を合算して、1手ごとに減らした石の数をカウントする、としたときに 初期状態 黒2-白2 から 最終状態 黒34-白30 に至るまでの状態遷移において、黒が減った数が多くなる、というのは直感的には無理な気がしています。 (edited)
Avatar
僕も(こういうのもアレだけど)直感的にはひっくり返した数で勝敗が決まりそうだとは思いつつ、いい証明というか反例がありそうな予感がしていたというのがあります。
Avatar
今おいた証明筋のほうがシンプルに強そう (edited)
🤔 1
Avatar
ほほー。
Avatar
ワインを飲むかどうかは盤面関係なく、石の数の現象のみによって決定するので
Avatar
「石の数で勝利しているならばひっくりかえした数も多い」が、置いたままひっくり返されてない(飲まれてない)ものも含まれてるからルールが変わってませんか?
Avatar
含まれてないですよ
5:16 PM
1手目において黒2 - 白2 から 黒4 - 白1に遷移するわけですが、このとき白の数が1個減ってるので1カウント
5:17 PM
これを繰り返していって最終状態 黒34 - 白30になったときに、黒のほうが沢山減っている、というのは不可能ですね
Avatar
たしかに、koherさんのいっていることも僕はけっこう分かるというか、たしかにそこ僕はあんまりちゃんとわかってないかもな。
5:19 PM
そこは便宜上、おいたところを1にしたけど、それでいいのか的な。 (edited)
Avatar
白30枚、黒5枚の局面で、それまでにパスが発生していないなら黒は18枚、白は17枚置いています。そこからひっくり返された数の差し引きは白が+13枚です。そこから、先のように白が10連続パスになり、黒が各回で1枚ずつひっくり返すと、10枚置いて10枚ひっくり返すので黒が25枚、白が20枚になります。この状態で両者パスとなり勝敗が決したとき、まだ白は+3枚ひっくり返しているはずです。
5:20 PM
こんな極端な状況が起こり得るかはわかりませんが、滅多に起こらないというだけでは証明はできないと思います。
Avatar
1枚ずつ連続でひっくり返せる上限は盤面のマス数によって回数が決まっていて
5:21 PM
少なくとも10連続は不可能ですね (edited)
Avatar
たしかに最初に置いたところを「ひっくりかえった数を1とする」というのは、ワインは飲んでないけどひっくりかえった数としてカウントしていて、証明としては十分ではないかもな。
Avatar
白10枚、黒9枚で、白がパスして黒が置いて1枚ひっくり返して決着が付くと、両者同じ数だけ飲んだけど黒の勝ちになります。
5:23 PM
10連続は極端な例なので、もっと小さな数でもあり得るかと。
Avatar
まあでも、どこかに置くためにはどこかをひっくり返さないといけない、という制約をつかうことで、(i, j) だけでなくて隣接するところの条件を組み込んだりして、なんとかこの路線で攻められるか?
5:26 PM
あるいは、最終的に決着したとき場にあるそれぞれの色の石の数を、ひっくりかえった数カウンターから引いてやるとか?
5:26 PM
そうすると最初の+1はキャンセルして証明できるとかないか。
Avatar
白20枚・黒17枚の局面でこれまでパスがないとするとこれまでに飲んだ数は白が+3で、白が2連続パスして黒が1枚ずつひっくり返すと白18枚、黒21枚になり、黒は2杯飲むので白の+1です。
5:29 PM
これくらいだと起こり得るのでは?
5:29 PM
あ、飲んだ数が違うか。
Avatar
飲んだ数は白が+3
ここが間違ってる気がする
5:34 PM
正確には半分で1か2じゃないかしら
5:35 PM
初手 2-2 -> 4-1 で 黒は1個しかひっくり返していないので
Avatar
ここが間違ってる気がする
はい、間違えてて、 30:5 のときはちゃんと計算してたけど、 +3 は計算できてませんでした。
5:36 PM
↓は合ってますよね? これまでにパスがないと仮定して黒b枚、白w枚の局面では、黒はこれまでに b0 = floor((b + w) / 2) + 1 枚、白は w0 = floor((w + b) / 2) を置いている。このとき、白は黒よりも (w - w0) - (b - b0) 杯多くワインを飲んでいる (edited)
5:37 PM
あ、ちょっとまって
5:37 PM
最後の式をもう一回よく考える。
5:38 PM
最後の式はおかしいな
Avatar
直感的には間違ってそうな予感
Avatar
  • b を黒を置いた数、w を白を置いた数とする
  • ΣB_ij をゲームが終わった時点で(おいた時を1として)黒をひっくり返した数
  • ΣW_ij をゲームが終わった時点で白をひっくり返した数
☝️ とするとワインを飲む量はそれぞれ 黒: ΣB_ij - b 、白 ΣW_ij - w となる。そして、 1. b = w のとき……これはさっきの議論で消していいのでOK 2. b ≠ w のとき …… これをかんがえるか! という感じかな。b = w + k みたいな感じにして、そのうえで(1)を k = 0 のベースケースしたうえで帰納法まわせないか? k < 0 のケースあるから無理か……?
Avatar
一旦片方を勝者に固定すればOKだと思います。パスをしたプレイヤーはほぼ負けるので (edited)
5:42 PM
それが終わったあとで逆をしてもよいかと
Avatar
黒を勝ったことにすると、盤上の石が多いので、とりあえず ΣB_ij > ΣW_ij は間違いない。
5:43 PM
そのうえで、黒がパスをしつつも勝つ場合(つまり b < w のケース)が存在するか? (edited)
5:43 PM
でも、これおかしいというか矛盾はきだすか?
5:44 PM
矛盾はないか。たとえこんなケースが存在したとしてもワイン飲み量でも黒が勝つな。 (edited)
Avatar
えーとこういうのはどうでしょうか
5:46 PM
プレイヤーが置いた石って、高々盤上のマス目の数しかないので
5:48 PM
多分ですけど、それを織り込んで数式立てれないかな
Avatar
☝️ このアプローチでとりあえず(多少微妙でもナイーブには)やれそうな予感がちょっとしていますが、反例あるかな。
Avatar
高々というか完全に 盤上の石の総数==ひっくり返さない石の数
Avatar
そうだと思います。
5:50 PM
ねんのための確認ですが、僕の定義だと 盤上の石の総数 = b + w になると理解してます。 (edited)
Avatar
これを使えば、負け側のひっくり返した数が勝るという条件(パスの数)が算出できて、それが発生しないことを示せれば終わりそう
Avatar
場合わけしていって、どういう場合でも無理みたいな感じですかね。
Avatar
黒が先手、黒の枚数を b 、白の枚数を w で表し、黒・白がこれまでに置いた枚数をそれぞれ pb, pw 、黒・白がこれまでにひっくり返した枚数をそれぞれr fb, fw とする。黒と白のひっくり返した枚数の差を f = fb - fw とする。このとき、 b = 2 + pb + fb - fw = 2 + pb + f w = 2 + pw + fw - fb = 2 + pw - f が成り立つ。 (edited)
5:55 PM
パスがないとき、 pb = (b + w - 4 + 1) // 2 pw = (b + w - 4) // 2 が成り立つ(ただし、 // は除算後に切り捨て)。 (edited)
Avatar
+1は除算前の方が良さそう
5:56 PM
同じor1多い、なので
Avatar
除算前だと、黒が1手打った状態で0になっちゃいます。
Avatar
(5-4+1)/2で1では (edited)
Avatar
あれ、そうか。
6:04 PM
黒が打った直後(白の番で白が打つ前)には b + w が奇数なので、 pb = (b + w - 4 + 1) / 2 となる。
6:07 PM
試合開始からパスなく続き、黒が打った直後の状態のある局面の値をそれぞれ b1, w1 などと表す。
6:08 PM
この局面から白が n 連続パスし、黒が 1 枚ずつひっくり返した後の局面の値を b2, w2 などと表す。
Avatar
ちょっとこれ、できた気がするけどシンタックスの限界を感じつつあるな。
Avatar
このとき、 b2 = b1 + 2 * n w2 = w1 - n fb2 = fb1 + n fw2 = fw1 pb2 = pb1 + n pw2 = pw1 が成り立つ。 (edited)
6:12 PM
このとき、 f2 = fb2 - fw2 < 0 かつ、 b2 > w2 となるような b1, w1, n を見つけられれば、それが反例の候補となる。
Avatar
n は連続パスか。
Avatar
n = 10 は非現実的でも、 n = 23 くらいで見つけられる気がしてて、適当な数を入れて計算してみます。
Avatar
ちょっとkoherさんのシンタックスをつかいつつ、TeXで書いてます。
6:22 PM
PはPlay, FはFlipかな?
Avatar
place と flip でした。
Avatar
なるほどなw
6:27 PM
うーん、nを探索するのはやっぱり大変というか困難な気がするな。
6:27 PM
できなくはないかもしれないけど、n = 5は可能か?とかそういうのを1つ1つ考えていかないといけないので、たとえば5が不可能ならそれ以上も無理、みたいなのがあればどこかで止められるかもしれないけど、それはそれで別の補題(?)が必要になって証明が巨大化しそう。
6:29 PM
https://www.overleaf.com/read/tvcznmnwnjgy こういう ☝️ 路線でやっていってみてます。
An online LaTeX editor that's easy to use. No installation, real-time collaboration, version control, hundreds of LaTeX templates, and more.
6:29 PM
ちょっともう、さすがにこのDiscordのシンタックスでは数式を表現してられないのでw
Avatar
pb2pw2 の式が間違えてたので修正しました。
6:40 PM
@swift-5.2.5 let b1 = 17 let w1 = 24 let n = 3 let pb1 = (b1 + w1 - 4 + 1) / 2 let pw1 = (b1 + w1 - 4) / 2 let f1 = b1 - 2 - pb1 assert(f1 == -(w1 - 2 - pw1)) let pb2 = pb1 + n let pw2 = pw1 let b2 = b1 + 2 * n let w2 = w1 - n let f2 = f1 + n assert(f2 == b2 - 2 - pb2) assert(f2 == -(w2 - 2 - pw2)) print("BEFORE: b1 = \(b1), w1 = \(w1), f1 = \(f1)") print("AFTER: b2 = \(b2), w2 = \(w2), f2 = \(f2)") print("b2 - w2 = \(b2 - w2)")
Avatar
swift52 BOT 5/3/2020 6:40 PM
BEFORE: b1 = 17, w1 = 24, f1 = -4 AFTER: b2 = 23, w2 = 21, f2 = -1 b2 - w2 = 2
Avatar
↑の設定で、黒の方がひっくり返した枚数が少ないけど黒の勝利になりました。
6:41 PM
こういう手が実在するかは別問題ですが、3回連続パスなので、さっきよりは大分現実的かと。
Avatar
パスしたのは白ですかね?
Avatar
置いてある石の差 >= 2×飲んだワインの差 証明してないですが、これが常に成り立つはず、と言う予測があって
6:43 PM
その前提はこれを満たしていないので存在しない盤面だと思います
Avatar
パスは白です。
6:44 PM
b1 + w1 が奇数になるときは白の番なので。
Avatar
僕のTeXで書いたやつでは、黒が勝った状態でワインで負けるには、 黒がパス 嘘でした しないといけないというのが出てきてしまったんですよね 😇 (edited)
Avatar
n = 2 でもいけました。 @swift-5.2.5 let b1 = 17 let w1 = 22 let n = 2 let pb1 = (b1 + w1 - 4 + 1) / 2 let pw1 = (b1 + w1 - 4) / 2 let f1 = b1 - 2 - pb1 assert(f1 == -(w1 - 2 - pw1)) let pb2 = pb1 + n let pw2 = pw1 let b2 = b1 + 2 * n let w2 = w1 - n let f2 = f1 + n assert(f2 == b2 - 2 - pb2) assert(f2 == -(w2 - 2 - pw2)) print("BEFORE: b1 = \(b1), w1 = \(w1), f1 = \(f1)") print("AFTER: b2 = \(b2), w2 = \(w2), f2 = \(f2)") print("b2 - w2 = \(b2 - w2)")
Avatar
swift52 BOT 5/3/2020 6:45 PM
BEFORE: b1 = 17, w1 = 22, f1 = -3 AFTER: b2 = 21, w2 = 20, f2 = -1 b2 - w2 = 1
Avatar
(そして、そんな状態はない、というのをやってやるみたいな)
Avatar
これも存在しない盤面っぽい
Avatar
置いてある石の差 >= 2×飲んだワインの差
ちょっと考えます。
6:46 PM
もう全然頭が回ってない・・・
Avatar
これ、最初のkoherさんの定義を見たときに最初に思い付いた反論なんですが、あやふやすぎたのでしまってました
6:47 PM
拡張したゲーム(オセロの状態を全て含む)で多少検算してどうやら確からしい、という感じになってきた
Avatar
「存在しない盤面」はBEFOREですか、AFTERですか? (edited)
Avatar
BEFOREが存在しない
6:47 PM
存在しない盤面に対して成り立つとしているが、そもそもその盤面はないので、という感じ
Avatar
BEFOREは黒が17枚、白が22枚ということしか言っていないですよ。
Avatar
あ、ワイの証明あやまりあった 😇
Avatar
f1=-3も提示してませんか
6:48 PM
それが有り得ない
6:49 PM
(あくまで予想が正しいとした上での過程ですが
Avatar
黒が17枚、白が22枚のとき、これまでにパスがないとすると、盤に置かれた石は17+22=39枚で、最初に4枚置かれているので、黒は18枚、白は17枚の石をこれまでに置いたはずです。
6:51 PM
それが、黒17枚、白22枚になっているので、黒がひっくり返された枚数と白がひっくり返された枚数の差が-3だと導かれます。
Avatar
それはワインの差ではないですよね
Avatar
f1はb1とw1から機械的に導かれる数かと。
6:51 PM
ひっくり返したときにワインを飲むので、ひっくり返した枚数とワインを飲んだ回数は同じですよね?
Avatar
まず、ひっくり返した数を機械的に出してるのがあやまりで
6:52 PM
まああくまで予想
Avatar
ひっくり返した枚数( fb, fw )はわかりませんが、ひっくり返した枚数の差( f )は一意に決まりますよね? (edited)
6:52 PM
置いた枚数と、初期枚数と、現在の枚数から。
6:53 PM
b = 2 + pb + fb - fw = 2 + pb + f w = 2 + pw + fw - fb = 2 + pw - fpb = (b + w - 4 + 1) // 2 pw = (b + w - 4) // 2 から。 (edited)
Avatar
僕も感覚でいったら、盤面の状態を白とか黒の数とか、ひっくり返した数によって制約するのはややこしくなりそうには思います。これまでのやりとりで段々あきらかになってきてますが、たとえばいい組み合せが用意できても次に「その状態へどうやって到達できるか?(あるいはできないか)」の議論が必要になってしまいますね……
Avatar
僕のスタンスは、極稀なケースで反例がありそうだけど、反例をさがすのがとても難しそう、です。
Avatar
うーん
Avatar
反例は、可能な反例というか、証明にマッチしないケースならなんでもいいかわりに、オセロの前提を破壊してはダメな予感がします。たしかにまだ、すくなくとも僕の方法もうまくいってはないんですけど、とはいえ反例(おそらく勝利したけどワインで負ける)はオセロのルールにおいてもバリッドな状態が求められると思います。
6:57 PM
僕が、たぶんオセロで勝てばワインでも勝つという立場なんで、ちょっとバイアスかかった意見だということは謝っておきます。
Avatar
ちょっとまだあやふやなんですが https://discordapp.com/channels/291054398077927425/499393715140558881/706579249355685889 これを正とするのはあやしそう
Avatar
お、僕はひっくり返した枚数の差は、最後の盤面の石から決まるという立場だけど、無理か?
Avatar
--- 2,2,0,0,0 --- 5,0,1,0,2 4,1,1,0,1 --- 6,0,1,1,3 6,0,2,0,2 5,1,1,1,2 4,2,1,1,1 3,3,1,1,0 --- 7,0,3,0,3 7,0,2,1,3 6,1,2,1,2 5,2,2,1,1 4,3,2,1,0 --- 8,0,4,0,4 7,1,3,1,2 6,2,3,1,1
7:00 PM
これ途中まで検算した拡張オセロゲームのメモなんですが
Avatar
自分の枚数 = 2 + 置いた枚数 + ひっくり返した枚数 - ひっくり返された枚数 じゃないですか?
Avatar
えーと
7:01 PM
手前から順番に、場の石の数、増やした石の数、取った石の数の差分、で
Avatar
(これ、手元にオセロがいるなw)
Avatar
好きな方に足せる(任意のパスを許容) と 好きな数だけ石を取れる を許すことで
7:02 PM
全てのオセロの状態を内包できるようにしたものです。なのでこの状態はオセロの石の状態を含む集合として考えられるが
Avatar
好きな数だけ石を取るというのは、石を0個とるという(置くだけ)も可能でしょうか?
Avatar
1個以上は取るのが必須
Avatar
なるほど。
Avatar
ここがミソで、このルールを追加した事で https://discordapp.com/channels/291054398077927425/499393715140558881/706576685172260915 この仮定が確からしくなっているように見える
7:04 PM
大学の後輩にもこの問題みせてみたんですけど ☝️ 、独立に同じようなところに到達してますね。
Avatar
メモにもありますが、「それより小さくなる」ですね
Avatar
同じはNGですか?
Avatar
同じok それでいくと、koherさんの定義する状態は発生し得ないんですよ
7:06 PM
まあ今日は遅いのでここまで
Avatar
基本的なところが分かってなくて申し訳ないんですけど、拡張オセロと普通のオセロってどう違うんでしょうか?
Avatar
えーと拡張したのは
Avatar
好きな方に足せる(任意のパスを許容) 好きな数だけ石を取れる これです ☝️(けっきょく少なくとも1つは取らないといけないなど、違いがよくわかってない) (edited)
Avatar
判例を探すならより大きな集合に存在しないことを示すのもOKで、パスを許容するために拡張モデルを使った、です
Avatar
飲んだ数の差の二倍が石の差
僕はそうだと思ってます。厳密には、「飲んだ数の差の二倍が石の差」または「飲んだ数の差の二倍+1が石の差」
(edited)
Avatar
はい。その方針はいいと思うんですけど、一方で(普通のオセロと)なにが違うのか分からないんですよね。 (edited)
Avatar
あ、つまり盤面上の制約はないってことかな?
7:08 PM
数値だけを操作してよいということ?
Avatar
盤面上の制約を省くと、数値だけになりますよね
7:08 PM
その時についでにパスのルールも省くと、オセロを圧縮したモノを内包した巨大な集合が出来るので
7:09 PM
その中でワイン問題を立証するのが一番楽そうだ、という
7:10 PM
https://discordapp.com/channels/291054398077927425/499393715140558881/706582713645137920 これ+1ではなく-1じゃないかな、そうすると全て成り立ちそう
Avatar
これは、オセロで勝つならワインでも勝つという立場のやつならOKですねw なるほどな。
7:11 PM
つまりより広い集合において、オセロで勝ちながらワインで負ける手段がないことを示せば、
Avatar
そういうことです
Avatar
それより狭い集合であるオセロにおいても、そういうパスがないってことになるわけですね。
Avatar
では後は数値が一定の増え方をするモデルを定義して
7:12 PM
その中にそう言った組み合わせが存在しなければ(具体的には1列-2列が正で5列が負) ゲームセット
7:13 PM
因みに全て正の数なのは、反対側は同じ数の並びを逆転させただけになるので省略してるからです
Avatar
これ+1ではなく-1じゃないかな、そうすると全て成り立ちそう
2:2から始めて黒が1枚置いて1枚ひっくり返して4:1になったとき、石の差は3、ひっくり返した差は1-0=1なので、3=2*1+1です。
(edited)
7:18 PM
引き算足し算というか、0側にシフトする?が正しそう
Avatar
これ-3じゃなくて-2なはずなんですよね
はい、これは計算を間違えてたので、その後ちゃんと計算し直しました。
7:19 PM
それが、 b = 2 + pb + fb - fw = 2 + pb + f w = 2 + pw + fw - fb = 2 + pw - f と、パスが発生していないとき、 pb = (b + w - 4 + 1) // 2 pw = (b + w - 4) // 2 です。
Avatar
僕はだんだん議論についていけなくなってるな。 (edited)
Avatar
通常のオセロの範囲でこの式に間違いはないと思ってます。間違いがあると指摘してもらえるとうれしいです。
Avatar
さすがにもうしんどい
Avatar
@Yusaku 単純に、「黒の枚数 = 初期の2 枚 + 置いた枚数 + ひっくり返して獲得した枚数 - ひっくり返されて失った枚数」という式です。 (edited)
Avatar
因みに2倍説があると何が嬉しいかというと、連続パスのn回の束縛がそこにかかってきて到達不能になりそうだからです。おやすみ
Avatar
おやすみなさい。
7:23 PM
とりあえず僕の考えは、「黒17枚、白22枚となる盤面(や、他に条件が成り立ちそうな盤面)は無数に考えられるので、そのうち、ゲーム開始状態から到達可能な盤面はたくさんありそう。その中で、白が2回連続でパスとなり、黒が1枚ずつひっくり返すケースは考えられ得るので、反例が存在する可能性が高いのではないかと考えている。しかし、それを見つけるのはとても大変そう。」というものです。 (edited)
Avatar
最後に2倍というのの2がどこから出てきたのか知りたかったけど、ちょっととんでもない話題を投入してしまったと反省してます 🙇‍♂️ (edited)
7:23 PM
長時間おつかれさまでした、いろいろありがとうございます!
Avatar
楽しかったです。ありがとうございました😀
Avatar
ふーむ。(まだやっていいのか不明だけど)「黒17枚、白22枚となる盤面(や、他に条件が成り立ちそうな盤面)は無数に考えられるので、そのうち、ゲーム開始状態から到達可能な盤面はたくさんありそう」ということも証明しなければならず、問題の難易度が変化しているのだろうか?という疑問はあります。
Avatar
因みにf1=-2になった場合、黒が2連で1マス取って勝利した場合、ワインは同数飲んだことになるから逆転はしてないような
Avatar
はい、なので 2 連続パスのときは f1 = -3 となる局面が必要です。
Avatar
黒17白22は-2なので未達成かと (edited)
Avatar
黒17白22のときは、合計39枚で初期が2枚ずつなので、 39 - 4 = 35 枚が置かれた枚数で、黒が先手なのでパスがなければ黒が18枚、白が17枚置いたはずです。 (edited)
7:38 PM
そうすると、初期2枚と合わせると黒が20枚、白が19枚あるはずなのに、黒が17枚ということは差し引きで白が3枚多くひっくり返してるのではないでしょうか。
7:41 PM
そもそもなんですけど、これってひっくり返した人が飲むんですよね? --oo oxxo --x- ---- ↑の状態で o を置いて --oo oxoo --o- --o- になったときって、 o のプレイヤーが x のワインを 2 杯飲むんですよね?
Avatar
2倍っていうのはでてきた気がするな。
Avatar
やばい、バグが急増して 7 (+5)
2:48 PM
くそー、当たり前だけどぜんぶ型検査抜けてくる
Avatar
誘惑に負けてテストを書いてしまった
😅 1
11:42 AM
案の定、ポロポロ出てくる、、、
Avatar
@koher README.md にある、
アニメーションの途中でもユーザーの入力はブロックされません。
これ animationDuration を長くして試してみたんですが、盤面への配置がブロックされているように見えます。上記の説明でいう「ユーザーの入力」とはリセットや Manual <-> Computer 間の切り替えのことだけを意図している感じでしょうか?
Avatar
たしかにわかりにくい表現かもですね。 あとはリセットボタンとかもですね。
Avatar
あ、ですよね。ありがとうございます。アニメーション終わる前の操作を許す場合は AnimationQueue がくそ複雑になるので悩んでいたところでした
🙏 1
Avatar
小さいモデル(状態機械)の連結で苦しんでいて、あまりに想像がつかないのでモデル検査にかけてみたら deadlock 見つけられた時の顔をしています
😂 2
Avatar
これでモデルの1/3なんですが、すごくシンプルに設計したはずが既にこの状態数
1:54 PM
これでまだオートプレイ関連の状態を入れていません
1:55 PM
印刷機欲しいw
1:55 PM
ここまで来ちゃうと紙でやるしかない
1:59 PM
pan: elapsed time 0 seconds 1: (GameModel) (state 1) [gameState = GMReady] 2: (GameModel) (state 2) [gameStateDidChange!GMReady] 3: (AnimatedGameModel) (state 1) [gameStateDidChange?gameState] 4: (GameModel) (state 15) [((gameState==GMReady))] 5: (BoardAnimationModel) (state 1) [boardAnimationStateDidChange!boardAnimationState] 6: (AnimatedGameModel) (state 2) [boardAnimationStateDidChange?boardAnimationState] 7: (AnimatedGameModel) (state 18) [IF] 7: (AnimatedGameModel) (state 8) [IF] 7: (AnimatedGameModel) (state 5) [animatedGameState = AGMReady] 7: (AnimatedGameModel) (state 9) [.(goto)] 7: (AnimatedGameModel) (state 17) [.(goto)] 8: (BoardAnimationModel) (state 2) [((boardAnimationState==BAMNotAnimating))] 9: (AnimatedGameModel) (state 20) [animatedGameStateDidChange!animatedGameState] 10: (AnyView) (state 1) [animatedGameStateDidChange?animatedGameState] 11: (AnyView) (state 2) [animatedGameCommandQueue!AGMPass] 12: (AnimatedGameModel) (state 68) [animatedGameCommandQueue?animatedGameCommand] 13: (AnimatedGameModel) (state 69) [((animatedGameState==AGMReady))] 14: (AnimatedGameModel) (state 70) [((animatedGameCommand==AGMPass))] 15: (AnimatedGameModel) (state 71) [gameCommandQueue!GMPass] 16: (GameModel) (state 16) [gameCommandQueue?gameCommand] 17: (AnimatedGameModel) (state 99) [((animatedGameCommand==AGMPass))] 18: (AnimatedGameModel) (state 100) [(1)] 19: (GameModel) (state 17) [((gameCommand==GMPass))] 20: (GameModel) (state 18) [gameState = GMReady] 21: (AnyView) (state 2) [animatedGameCommandQueue!AGMPass] 22: (AnimatedGameModel) (state 68) [animatedGameCommandQueue?animatedGameCommand] 23: (AnimatedGameModel) (state 69) [((animatedGameState==AGMReady))] 24: (AnimatedGameModel) (state 70) [((animatedGameCommand==AGMPass))] spin: trail ends after 24 steps
1:59 PM
秘孔を突かれるまでのログ
1:59 PM
モデル検査便利…(原因全然わからん
Avatar
すごく厳密な状態管理がされてそうな雰囲気が伝わってきます😅
2:05 PM
deadlockってどこかでsyncする必要があったということですか??
Avatar
ReactiveSwift の ImmediateScheduler 以外でモデル定義するのがめんどかったので、ImmediateSchedular になってるんですがこれで再帰呼び出しでまずい経路(ReactiveSwift.Property の中で再起書き換えが発生したなど)が出たか、モデルが間違っているのどっちかですね
Avatar
あ、でも勘違いがあったので明日直そう、、、
3:26 PM
Rx 系の CSP なセマンティクス全然理解できてなかった
Avatar
(Rx もそうだし、DiapatchQueueもそうだった)
Avatar
本日 21 時から、こちらのチャンネルを Swift Zoomin' #2 https://swift-tweets.connpass.com/event/174512/ のチャットスペースとして利用します。また、 Zoom の定員を超えてしまった場合、音声チャットの swift-zoomin チャンネルのスクリーン共有機能を使って発表を中継します。よろしくお願いします。
# Swift Zoomin' Swift Zoomin' はプログラミング言語 Swift に関するオンライン勉強会です。普通の勉強会と同じようにスライドおよび音声で発表を行います。無料アプリのZoom を使う予定ですが、 Zoom 以外での開催の可能性もあります。 今回は Swift Zoomin' チャレンジ 〜Fat View Controllerを倒せ!〜で課題に取り組んだ報告会です。 Fat View Controller として実装されたリバーシアプリをリファクタリングし、どのようにしてクリーンなコードを実現したのかを発表者が説明...
Avatar
Kishikawa Katsumi 5/16/2020 7:50 AM
placeDisk(_:atX:y:animated:completion:) って animated: true しか使われてないですか?
7:51 AM
実はfalseのケースは消せる?
Avatar
それは消せる気がします。 animated を作ったのはちょっとミスリーディングだったかも・・・。
👍 1
9:06 AM
BoardViewsetDiskanimated: false で呼び出してる箇所はありますが。
Avatar
Kishikawa Katsumi 5/16/2020 9:16 AM
とりあえずギリギリですがまあまあいい感じになったのじゃないでしょうか。 https://github.com/refactoring-challenge/reversi-ios/pull/10
ViewControllerのリファクタリングの第一段階。 リファクタリングのゴールに至る一時的な移行処置としてGameManagerクラスを導入し状態だけを変更する処理を移譲する。 ViewControllerからGameManagerの状態変更を監視し、ViewControllerによるViewの変更は状態変更の通知を受けて行う。 これにより、 GameManagerの状態の変更 Vi...
🙏 1
Avatar
ありがとうございます。よかったら、今晩の Swift Zoomin' #2 でXcodeを画面シェアしながら簡単にでも解説してもらうとか可能でしょうか?
Avatar
Kishikawa Katsumi 5/16/2020 9:22 AM
OKですよ。もう参加者はいっぱいと聞いたので聞くだけにする予定でしたが時間があるなら。
Avatar
ありがとうございます!まだ発表枠は空いてます(参加枠も Discord 中継で拾える予定ですが)。 https://swift-tweets.connpass.com/event/174512/
# Swift Zoomin' Swift Zoomin' はプログラミング言語 Swift に関するオンライン勉強会です。普通の勉強会と同じようにスライドおよび音声で発表を行います。無料アプリのZoom を使う予定ですが、 Zoom 以外での開催の可能性もあります。 今回は Swift Zoomin' チャレンジ 〜Fat View Controllerを倒せ!〜で課題に取り組んだ報告会です。 Fat View Controller として実装されたリバーシアプリをリファクタリングし、どのようにしてクリーンなコードを実現したのかを発表者が説明...
Avatar
Kishikawa Katsumi 5/16/2020 9:23 AM
了解です👍🏻
🙇‍♂️ 1
Avatar
自分は動作確認する時 animated: false にしてペースを早めてますw
Avatar
Kishikawa Katsumi 5/16/2020 9:48 AM
なるほど!デバッグ用に便利なのか。
Avatar
イエス!
Avatar
@Kishikawa Katsumi Zoom の URL を登録者に一斉配信するので、「発表枠」で登録してもらえると助かります🙏
9:52 AM
ここはチャット用なので、メイン会場は Zoom になります。
9:52 AM
ちょっとわかりづらくて申し訳ないですが・・・。
Avatar
Kishikawa Katsumi 5/16/2020 9:54 AM
👍🏻Just a minute
9:55 AM
申込みました
Avatar
ありがとうございます!🙇‍♂️
Avatar
音が聞こえない場合は Zoom のメニューから設定>オーディオを開き、Speaker のテストをして出力先や音量を確認してみてください。
Avatar
発表者の方へ>ここを予め0にしてください!
12:05 PM
@marty-suzuki @Kuniwak こちらです!
12:09 PM
Discord ライブを見る場合は↑こちらの「ライブ」アイコンを押してください!
koher pinned a message to this channel. 5/16/2020 12:12 PM
Avatar
音が聞こえない場合は Zoom のメニューから設定>オーディオを開き、Speaker のテストをして出力先や音量を確認してみてください。
12:13 PM
只今、音声テスト中です。もし音声が聞こえていない方は↑こちらをお試しください
12:14 PM
@here 只今、音声テスト中です。もし音声が聞こえていない方は↑こちらをお試しください
Avatar
zoomの空きがあればURL知りたいです・・!
Avatar
Zoom is the leader in modern enterprise video communications, with an easy, reliable cloud platform for video and audio conferencing, chat, and webinars across mobile, desktop, and room systems. Zoom Rooms is the original software-based conference room solution used around the...
Avatar
ありがとうございます!
Avatar
↑こちらです
Avatar
一番上のままにする
✅ 25
2️⃣ 1
12:25 PM
1. オンラインペアプロ大会 2. 匿名質問会 3. リファクタリングチャレンジ第二弾 4. Swiftで競技プログラミング挑戦会
1️⃣ 12
2️⃣ 24
3️⃣ 30
4️⃣ 14
Avatar
いまもう録画開始してるんですか?
Avatar
Twitter見てるとDiscordの音声は誰かのPCのスピーカーの音も拾っちゃってる?感じらしい
Avatar
左下のマイクに赤線が入っていれば大丈夫ですかね?
Avatar
はい!赤線が入っていればミュートされています!
👍 1
12:31 PM
発表順: koher yaso_san sugigami takasek 休憩 koher Hiron marty-suzuki lovee 休憩 KishikawaKatsumi Kuniwak koher
Avatar
いまもう録画開始してるんですか?
録画開始されてるって言ってた気がします!(違ったらすみません)
Avatar
あ、はい、ありがとうございます。ぼくが書き込んだ時に開始されましたw
Avatar
はい!録画開始しました!
Avatar
Contribute to koher/clean-reversi-ios development by creating an account on GitHub.
👍 3
Avatar
どなたかわかないですが、Discordに登壇に関係ない誰かの会話が入ってきます (edited)
Avatar
status から複数人の肩のマイクが反応してしまっているっぽい
12:36 PM
namekichi さんと lovee さんのマイクが反応してそう
Avatar
たしかに
Avatar
私こっち mute してるのでどういう状況なのかがわからないですが…
Avatar
@namekichi8 san 生活音が入ってきているのですがマイクの状況ご確認してもらってもいいですか (edited)
🙇‍♂️ 1
Avatar
@herediscord のボイスチャットに入られている方は、発言するとき以外はミュートにしていただけますでしょうか 🙏
Avatar
Zoom だと host が guest を mute できたりしますけどこっちはできないのかな
Avatar
(不参加の者ですが横から失礼します) 他人をミュートすることはできます。権限があれば。 @koher には与えてあります。 (edited)
12:39 PM
(通りすがりなので状況が)よくわからないけど @koogawa にその権限を与えたらいい感じ? (edited)
🙏 1
Avatar
僕も横から失礼しました 🙇 (edited)
Avatar
@omochimetaru はい!権限いただけると嬉しいです
Avatar
@koogawa event-ops role を与えました。VCのところのユーザーを右クリックするとミュートできます。
Avatar
ありがとうございます!私の方でポチポチ ミュートにしていきます
12:42 PM
サーバミュート というやつでしょうかね
Avatar
キックやBANもできるので、全然関係ない外部の荒らしやスパムが来たらそれで対処できます。
🙏 1
12:43 PM
そうですね。通常の ミュート は、自分がその人の声を無視するだけの機能です。 サーバーミュート はその人の口を塞ぐ機能です。
Avatar
ありがとうございます 👍
12:44 PM
一旦発言者以外をミュートしました
Avatar
Kishikawa Katsumi 5/16/2020 12:52 PM
甘えを廃す😂
Avatar
単に Xcode 上で target を分けるだけじゃなくて Swift package にしているんですね
Avatar
Kishikawa Katsumi 5/16/2020 12:52 PM
厳しい💪🏻
Avatar
👏 👏 👏 👏 👏 👏 👏 👏 👏 👏
Avatar
Kishikawa Katsumi 5/16/2020 12:53 PM
👏
Avatar
8888888
Avatar
88888888
Avatar
👏👏👏👏👏👏👏
Avatar
8888888888888888
Avatar
ぱちぱちぱちぱちぱちぱち
Avatar
88888888
Avatar
888888
Avatar
Masayuki Iwai 5/16/2020 12:54 PM
👏
Avatar
(質問) swift package ではなくて、モジュール切り分けて作るのはありでしょうか?
Avatar
質問ある方は発言していただくか、こちらに書いていただければ拾います!
Avatar
swift packageの方がイマドキなんですね。 問題点も知れて良かったです。 ありがとうございます。
Avatar
ControllerとPresenterの関係性を聞き逃してしまったのですが、GameControllerはPresenterレイヤーのクラスということなのでしたっけ・・・?
Avatar
GameControllerはUse Caseにいたような気がしますね。
🙇 1
Avatar
’(質問)このような設計の場合、どのようにドキュメント(仕様書など)管理しているのでしょうか?
Avatar
これ私の発表順まで来られるかなw
👀 1
Avatar
koher/clean-reversi-swiftを拝見してます。テストを開始するためのエントリポイント(*.xcodeproj?)はどこになるのでしょうか。
Avatar
ありがとうございます!
Avatar
質疑応答に時間とってしまってすみません
Avatar
Kishikawa Katsumi 5/16/2020 1:01 PM
swift packageはまだ足りない機能も多いですが、Xcodeさえあれば使えるのがやはり大きなメリットですね。
👍 4
Avatar
ありがとうございます!
Avatar
marty-suzuki 5/16/2020 1:02 PM
タイムキーパーいた方が良さそうですね
Avatar
Kishikawa Katsumi 5/16/2020 1:03 PM
きっとKoherさんが自分で辻褄を合わせるはず
💦 1
Avatar
www
😂 1
Avatar
Masayuki Iwai 5/16/2020 1:03 PM
やそさん、音質がいい。
Avatar
特にアーキテクチャパターンが重要というわけでないのでまったく大丈夫です👍
Avatar
Kishikawa Katsumi 5/16/2020 1:07 PM
この図わかりやすいな。。。
Avatar
時間軸方向の状態管理、という視点が良いですね
Avatar
オートマトンみがある
Avatar
Kishikawa Katsumi 5/16/2020 1:08 PM
私も同じようなことを言うスライドがあるけど、
Avatar
ちなみにさっきの State は Entity レイヤーの State だったので、 Use Case の状態は別になります。 (edited)
👀 1
Avatar
Kishikawa Katsumi 5/16/2020 1:08 PM
困った
Avatar
私も一部そうですね
1:09 PM
そうか、私は一番説明が少なくていいんだ(発表を短くできる)
Avatar
コード見ながら聞きたいです。もしリポジトリのURLあればお願いします🙏🏻
Avatar
Contribute to objective-audio/reversi-ios development by creating an account on GitHub.
👍 1
Avatar
ありがとうございます!
Avatar
Interactor は誰が保持して解放されないようになっているんでしょう?
👀 2
Avatar
👏
Avatar
Masayuki Iwai 5/16/2020 1:18 PM
👏
Avatar
ゆきむら(古) 5/16/2020 1:18 PM
👏
Avatar
8888
Avatar
👏
Avatar
👏
Avatar
👏 (edited)
Avatar
88888888
Avatar
ぱちぱちぱちぱちぱちぱちぱちぱち
Avatar
Kishikawa Katsumi 5/16/2020 1:19 PM
なんか画面がかっこいいぞ
👍 1
Avatar
sugigami(susieyy) 5/16/2020 1:19 PM
登壇資料です! iOSリバーシリファクタリングチャレンジ w/ Redux https://qiita.com/susieyy/items/257dd802ab77af335f89 GitHubリポジトリにリファクタリングした結果を公開しています。 masterブランチがリファクタリング済みになります。 https://github.com/susieyy/refactoring-challenge-reversi-ios
リバーシリファクタリングチャレンジ koherさんが公開された、このFat View Controller、あなたはリファクタリングできますか?チャレンジに参加しました。 本チャレンジは、 Fat View Controll...
Contribute to susieyy/refactoring-challenge-reversi-ios development by creating an account on GitHub.
Avatar
何はなくとも状態管理ってのはすごい実感しました。最近、状態管理が10以上要るので地獄見たんで・・
Avatar
Interactorはシングルトンにしました
👍 2
Avatar
先ほどの資料にあった「Strong」「Weak」というのは「強参照」「弱参照」という意味でなく、どれくらい結合を強くするかってことでしょうか? (質問はDiscordでいいんでしたっけ?)
Avatar
時間押し気味ですみません! 🙏 以後、質疑応答は Discord でお願い致します
Avatar
@yasos 質問です。さっきの Interactor は誰が保持しているんでしょうか?👀
Avatar
強参照と弱参照の意味ですね
Avatar
どこかで強参照しておかないと解放されてしまうと思うんですが、どこかでは強参照されてるんですよね?
Avatar
なるほどです、ありがとうございます! 頭が追いついていないのでもう少し考えます…
Avatar
あ、すみません、 uhooi さんへの回答でした💦
Avatar
InteractorはViewControllerとは別のオブジェクトツリーとして考えて、今回はシングルトンにしました
👍 3
1:23 PM
シングルトン嫌がるならAppDelegate的なところで保持でも良いかもしれないですね
Avatar
自分のイメージだと弱参照は、循環参照を避けるために使う認識だったので、一方通行で弱参照しているがどういうことなのかわかっていません、、
Avatar
強参照は別のところでやっておいて、必要以上に保持したくないためにWeakにしてるという感じですかね
👍 1
Avatar
「InteractorはViewControllerとは別のオブジェクトツリー」だから、PresenterからInteractorがweak参照になっているということですかね
👍 1
Avatar
はい、そんな感じです
👍 1
Avatar
Kishikawa Katsumi 5/16/2020 1:29 PM
でもまあCodableで保存がちょうどいいと思う。ASCIIアート形式はデバッグ文字列とか文字列からもinitできるという感じにするのがいいんじゃないだろうか。
👍 1
Avatar
この一枚岩じゃないと導入しづらいのが Redux の辛いところですよね、、、
1:33 PM
部分的に書き換えていけるとほぼ Redux が理想一択でいい気がするのですが
👍 1
Avatar
8888
Avatar
👏
Avatar
888888
Avatar
88888888
Avatar
Masayuki Iwai 5/16/2020 1:34 PM
👏
Avatar
8888888888888
Avatar
👏
Avatar
888888
Avatar
Kishikawa Katsumi 5/16/2020 1:34 PM
小さい改善で整えながら、最後にチョイっとReduxをいれる、とできるといいんですよね。
👍 1
Avatar
👏
Avatar
ぱちぱちぱちぱちぱちぱちぱちぱちぱちぱち
Avatar
takasekさんのこえがdiscordで聞こえてない気がします
1:36 PM
あれ、コレ僕が悪いのかな
1:36 PM
あ、きこえます!
1:36 PM
🙇
Avatar
@sugigami(susieyy) ターンの数だけしかAIの処理が走らないというのは、 Manual / Computer をぽちぽち切り替えまくっても処理を継続して一つの思考結果を使うようになっているということですか?
Avatar
Kishikawa Katsumi 5/16/2020 1:39 PM
アニメーションが凄かった
Avatar
https://github.com/takasek/refactoring-challenge-reversi-ios が404です。どこかtypoしてますかね??
Avatar
多分 private なのかと思われます
Avatar
Kishikawa Katsumi 5/16/2020 1:43 PM
Privateになってそう
Avatar
public になっていないのかも
Avatar
sugigami(susieyy) 5/16/2020 1:44 PM
@koher 動きはこんな感じで割り込み中(Alert)だとコンピュータ同士の戦いは進行しません interrupt 状態になるとplayTurnOfComputerの処理が継続されません またturn状態になると再開されます ー> waitForPlay ー> playTurnOfComputer
Avatar
@takasek repo が private ぽいです
Avatar
8888
Avatar
ぱちぱちぱちぱちぱちぱちぱちぱちぱちぱちぱち
Avatar
sugigami(susieyy) 5/16/2020 1:45 PM
1:45 PM
👏
Avatar
👏
Avatar
👏
Avatar
88888888
Avatar
88888888
Avatar
88888888
Avatar
22:50 から再開します
Avatar
@takasek 影響スケッチの図はなにかツールを使って作られたのですか?
👀 7
Avatar
レガシーコード改善ガイドを読んでみたくなってきた
👍 3
Avatar
@uhooi 影響スケッチは、今回はKeynoteで作りました 矢印の向きを細かく調整できるので割と良かったです
👏 8
Avatar
Kishikawa Katsumi 5/16/2020 1:47 PM
自作だった!
Avatar
ええええw すごいです…
Avatar
@sugigami(susieyy) モバイルアプリとしてのReduxに目をつけたのはどういうきっかけからだったのでしょうか?
Avatar
あと、最初フローの矢印とプロパティの矢印を同じ色にしたらものすごく見づらかったけれど、色を変えたら途端に見やすくなりました レガシーコード改善ガイドでは両者を区別していませんでしたが、PCを使うのであれば色を活用すると良いと思いました
Avatar
まもなく第2部開始します!
Avatar
sugigami(susieyy) 5/16/2020 1:49 PM
@struuuuggle Reduxに目をつけたのは、FluxやReduxのような単一フロー制御を実現したかったのが一番の要望です。さらにReduxのロジックであるReducerは純粋関数なのでテストがしやすく、コードが読みやすいです。
👍 2
Avatar
今回よりもはるかに大きなプロジェクトやさらにFatなViewの場合、影響スケッチを書ききれないと思ったのですがそういう場合はどう手を付けるのでしょうか?
Avatar
こちらスケッチです。この後の発表でも一緒に置いておくと理解が深まるかもしれませんね
Avatar
この後の発表でも一緒に置いておくと理解が深まるかもしれませんね
!?
Avatar
@yuyuyu 本には「影響スケッチは、調査対象のクラスを利用するすべてのクラスを対象にする」とありました。なかなかハードですね。 別のアプローチとして、「試行リファクタリング」というものが紹介されていました。コミットはしない前提でとりあえずリファクタしてみると見えてくるものがあるよ、という方法です。
👍 3
Avatar
Kishikawa Katsumi 5/16/2020 1:53 PM
「試行リファクタリング」良さそう
Avatar
@takasek 「試行リファクタリング」!ありがとうございますー!
👍 1
Avatar
@sugigami(susieyy) なるほど!SwiftUIにはデータバインディングとViewの更新の機構がすでに土台に組み込まれており相性が良さそうだなとは思っていたんですが、UIKit時代にすでに単一フロー制御を実現するところに着目されていたんですね...すごい...
👍 1
koogawa pinned a message to this channel. 5/16/2020 1:56 PM
Avatar
Swift勉強中の者です。delegateパターンが、なぜ依存性反転となるのか教えていただけないでしょうか? (edited)
Avatar
予定終了時刻になりましたね
🙏 1
😅 1
Avatar
ようやく自分のプログラム(ある程度)完成させた 😅
Avatar
Kishikawa Katsumi 5/16/2020 2:05 PM
👏
Avatar
8888888
Avatar
88888888
Avatar
88888888
Avatar
Masayuki Iwai 5/16/2020 2:05 PM
👏
Avatar
👏
Avatar
「ViewがInterface Adapter」自分も前ひっかかって調べたけど正直よくわからなかったですね… UseCase層から見たらということなのかな
Avatar
👏
Avatar
8888888
Avatar
sugigami(susieyy) 5/16/2020 2:05 PM
👏
Avatar
あ、続けますか…?私どうしよう
Avatar
ぼくの発表資料とチャレンジ結果のリポジトリです。 スライド: https://speakerdeck.com/hironytic/swift-zoomin-challenge リポジトリ: https://github.com/hironytic/reversi-ios
Swift Zoomin' の Fat View Controllerを倒せ! 報告会の発表スライドです。
Contribute to hironytic/reversi-ios development by creating an account on GitHub.
Avatar
Swift勉強中の者です。delegateパターンが、なぜ依存性反転となるのか教えていただけないでしょうか?
という質問が来てます (ログ流れ防止 by @nishitaku san)
(edited)
🙏 1
Avatar
答えたいけど難しい… この絵じゃわかんないですよね? https://twitter.com/the_uhooi/status/1192300447232487427?s=20
DIの説明を絵にしてみた🥎 自分しか理解できないだろうな…
🇼 2
😆 7
2:09 PM
ごめんなさい忘れてください
Avatar
@nishitaku デリゲートを作ると、たとえばユースケースのデリゲートにプレゼンターが適合したら、ユースケースはプレゼンターのことを知らない(依存しない)けど、プレゼンターがそれに適合することでプレゼンターのメソッドを呼ぶことができるようになります。
Avatar
Kishikawa Katsumi 5/16/2020 2:14 PM
😆
Avatar
@nishitaku @swift-5.2.5 // Use Case class UseCase { var delegate: UseCaseDelegate? func foo() { delegate?.showX(42) } } protocol UseCaseDelegate: AnyObject { func showX(_ x: Int) } ////////////////// // Presenter class Presenter: UseCaseDelegate { func showX(_ x: Int) { print(x) } } let useCase = UseCase() useCase.delegate = Presenter() useCase.foo()
Avatar
42
Avatar
@koher デリゲートはprotocolだと思っていて、その実体はプレゼンターに存在すると思ってます。そうなると、そのデリゲートを使っているユースケースは、プレゼンターに「依存している」とは言えないのでしょうか? とんちんかんなことを言っていたらすいません
👀 1
Avatar
↑で、ユースケースのレイヤーはプレゼンターを知りませんが、プレゼンターのメソッドを呼べています。「依存」というのはソースコードの依存なので、 import せずに実現できるかということですね。
👍 1
Avatar
👏
Avatar
@nishitaku 「protocol」には依存していても、「プレゼンター」には依存していないですね
Avatar
Masayuki Iwai 5/16/2020 2:17 PM
👏
Avatar
ぱちぱちぱちぱちぱちぱちぱちぱちぱちぱち
Avatar
8888
Avatar
8888
Avatar
極端な話、こんなものでも可能なので: class Presenter: UseCaseDelegate { func showX(_ x: Int) { // 何もしない } } ↑これはプレゼンターでもなんでもなく、ただ単にxをとって無視してるだけのオブジェクトですね
2:18 PM
@nishitaku
Avatar
Kishikawa Katsumi 5/16/2020 2:19 PM
うおー、そんな手段があるのか
Avatar
@nishitaku nishitakuさんのいいたいことめちゃくちゃわかります… Protocolに依存するということは、具体的な型には依存していなくて、外から何を依存させるか選べる(注入できる)から、依存にはならないんですよね(伝われ〜)
👍 2
Avatar
ただDelegateメソッドの名前としては、個人的には showX はあまりよくないかなと言う思いはあります、show はなんとなくプレゼンテーション処理に見えるので、xDidChange とかの方がよりDelegateメソッドとしてふさわしいと思います @nishitaku
👍 1
Avatar
marty-suzuki 5/16/2020 2:22 PM
Contribute to marty-suzuki/reversi-ios development by creating an account on GitHub.
GitHub Gist: instantly share code, notes, and snippets.
GitHub Gist: instantly share code, notes, and snippets.
Avatar
ちぇまたん 5/16/2020 2:24 PM
@nishitaku ”○○さん”にXXの処理をお願いするから、delegateを使うことで、XXの処理ができる”誰か”に変えることができると思ってるんご だから○○さん指名じゃなくて、XXができるなら誰でもいいよになる感じ?(難しい) (edited)
👍 1
Avatar
依存というのを概念としてとらえるのではなくて、コードとして完結できるかと考えるとわかりやすいかもです。もしユースケースのコードでプレゼンターを使っていたら、ユースケース単独でコンパイルするとプレゼンターがなくてコンパイルエラーになりますよね?
👍 1
Avatar
ワイのイメージ ビュー: はえー、ビューを更新する大変や。リクエストしてモデルさんから帰ってくるデータがたくさん来るからな。いそがしいそがし モデル: … なあ、相談したいことあるんやけど。 ビュー: なんやモデルさん。なんかあった? モデル: せや、ワイ、ビューを直接変えたいねん。 ビュー:ファッ?それはなんでや モデル:お前の意図とは関係なく、データAが来るんや。仕様やと、ビューにそのデータAを表示せんといかんねん ビュー:ファッ、それってワイをメンバ変数としてモデルさんのところに定義せんといかんやん。密結合や!ワイがリクエストした時に表示すればええんちゃう? モデル:… やけど、仕様やからな。お前がリクエストしたのと全然関係ないねん。 ビュー:ファーッ。それきついわ。相互につっよい依存関係できてしまうわ。モデルさんに対して全部アクセス権を与えたくないねん。 モデル:うーん。どうすればいいやろ ビュー:。。。せや!ワイに処理を”移譲(デリゲート)”してくれ。デリゲートしてくれたら、ワイを直接もたんでええやん。 モデル:それはどういうことや ビュー:あくまで、ワイを「データAが来たときにデータAを投げる先」として捉えるようにデリゲートProtocolを作って定義やれば、ワイを強い実体として持たなくてええんや。わいはそのProtocolに準拠すればええ。それでワイがデータAだけを受け取ってワイが更新すればええんや モデル:それって変数として持つのとどう違うん? ビュー:まず、モデルさんがビューという強い実体を持つのはダメなんや。やからデリゲートを通じるようにするだけにして「データを投げるなにか」として抽象化できるんやで。 モデル:ということはあれか。わいはおまえをビューとして知らんでええやん。「ただデータを投げる先」やな ビュー:せや!これでビュー -> モデルの関係はあるけど、逆は「ビュー」としての依存ではなく、「何かデータAを投げる先」として扱えるんや (edited)
😆 1
Avatar
依存がないということは、ユースケースだけでコンパイルできるということです。デリゲートを作れば、ユースケースはプレゼンターのコードがなくてもコンパイルできます。
👍 1
Avatar
わかってる、説明できないってことはDelegateパターンを完璧に理解できてないってことはよぉ!!! なんとなく使えればいいやと思ってここまで来ちゃったんだよぉ!!!(白状) #swiftzoomin
Avatar
依存がないということは、ユースケースだけでコンパイルできるということです。デリゲートを作れば、ユースケースはプレゼンターのコードがなくてもコンパイルできます。
そうですね、付け加えて言えば、個人的にはコンパイルできるだけでなく、Delegateがなくても、自分自身単体で自分自身の責務を正しく果たせるかどうか、までが依存ですかね
Avatar
@here 予定時間を大幅に過ぎてしまって申し訳ありません! suzuki さんの発表の後に、残りの発表者の方を別日に移動させていただこうか、ご意見を伺いたいと思っております 🙏
👍 1
Avatar
@koher @uhooi @lovee @ちぇまたん @freddi みなさんご丁寧に回答いただき、ありがとうございます。 自分でも理解を深めてみます!
👍 4
Avatar
8888
Avatar
👏
Avatar
sugigami(susieyy) 5/16/2020 2:30 PM
👏
Avatar
Masayuki Iwai 5/16/2020 2:30 PM
👏
Avatar
8888
Avatar
👏
Avatar
ちぇまたん 5/16/2020 2:30 PM
👏
Avatar
88888888
Avatar
wwwww
Avatar
88888888
2:33 PM
↑アンケート投票状況
Avatar
# Swift Zoomin' #3 Swift Zoomin' はプログラミング言語 Swift に関するオンライン勉強会です。 # 内容 次の四つから検討中です。 1. オンラインペアプロ大会 2. 匿名質問会 3. リファクタリングチャレンジ第二弾 4. Swiftで競技プログラミング挑戦会 # 参加方法 日時: 2020 年 7 月 11 日(土) 21:00- 本ページより、「参加枠」または「発表枠」で参加登録をして下さい。 参加者宛に、後日参加のための URL を連絡しますので、connpassからのメー...
Avatar
88888888
Avatar
ありがとうございました
Avatar
888888888
Avatar
ありがとうございました・・!
Avatar
ありがとうございましたー
Avatar
8888888888
Avatar
ありがとうございました!!
Avatar
88888888888
Avatar
88888
Avatar
ゆきむら(古) 5/16/2020 2:34 PM
👏
Avatar
ありがとうございました!!
Avatar
🙇‍♂️
Avatar
sugigami(susieyy) 5/16/2020 2:34 PM
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ホスティングありがとうございました!
Avatar
ありがとうございました!
Avatar
👏
Avatar
ありがとうございました!!
Avatar
【質問】koherさんに。このような設計の場合、どのようにドキュメント(仕様書など)管理しているのでしょうか? (複雑になるほど仕様変更にかかるドキュメントも大変なので教えて欲しいです)
Avatar
Masayuki Iwai 5/16/2020 2:34 PM
ありがとうございましたー。
Avatar
ありがとうございました!
Avatar
ありがとうございました😊
Avatar
ありがとうございました。
Avatar
ありがとうございました!
Avatar
ありがとうございました
Avatar
〜ここから希望者のみ Q&A タイム〜
Avatar
marty-suzuki 5/16/2020 2:35 PM
ありがとうございました!
Avatar
koherさん、回答ありがとうございました!
Avatar
とても勉強になるイベント本当にありがとうございました! @koher さんに質問させてください CleanArchitectureでEntityを何に設定するのかが難しいなと思ってたんですが、どうやって見つける?どう考えるとかってありますか?逆にこういうのをEntityとするとよくないとかありますか?
👍 1
Avatar
コンソール?でしょうか
Avatar
Confluenceですね
Avatar
Confluence
2:37 PM
です
Avatar
ありがとうございます。調べてみます。
Avatar
ナレッジとコラボレーションの共有スペースです。適切な情報があれば、チームは素早く決定を下し、仕事の進め方を調整したり変更したりすることができます。
👍 1
Avatar
回答ありがとうございました!
Avatar
iOS Clean Architecture勉強会 sponsored by Sansan - connpass https://connpass.com/event/158269/ の発表資料です。

参考資料

Clean Architecture 達人に学ぶソフトウェアの構造と設計 (アスキードワンゴ) | Robert C.Martin, 角 征典, 高木 正弘 | 工学 | Kindleストア | Amazon https://www.amazon.co.jp/dp/B07FSBHS2V マイクロサービスとクライアント: 
理想と...
Avatar
UseCaseが依存している普遍的なもの=Entityって理解ですかね
Avatar
Yoshikuni Kato 5/16/2020 2:45 PM
あまり詳しくないのですが、Clean Architectureとドメイン駆動設計(DDD)の関係について何か視点があれば聞かせてもらえるとうれしいです。Clean Architectureの説明でも「ドメイン」という説明が度々出てくるので、近いのでは、と思うのですが、もし知見があれば聞きたいです。
Avatar
詳しく回答頂いてありがとうございました!! 資料も読ませて頂きます🙏
Avatar
確認意味の質問ですが、つまりCAはDDDの1種のやり方と言ってもいいでしょうか?
2:50 PM
りかいしました。ありがとうございます!
Avatar
エヴァンスのドメイン駆動設計より
Avatar
Yoshikuni Kato 5/16/2020 2:55 PM
DDDのドメインとPresentation-Domain SeparationのDomainが微妙に意味が違いそうというのは勉強になりました。ありがとうございます。
👍 2
Avatar
wwww キャラも動くのね
2:57 PM
くしゃみと同時で動いたのがおもしろくて
2:58 PM
わーお、すぐには理解できないほど複雑な仕組みでうごいてたんですねー (edited)
Avatar
sugigami(susieyy) 5/16/2020 2:58 PM
僕の登壇もloveeさんと同じでグリーンバックとOBSです
👍 3
Avatar
8888888
3:04 PM
解説ありがとうございました
3:05 PM
ありがとうございました!
Avatar
8888
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
おつかれさまです、ありがとうございました!
Avatar
ありがとうございました!
Avatar
おつかれさまでした!楽しかったです 🙂
Avatar
@sugigami(susieyy) OBSびっくりするほど軽いですよね!
Avatar
ありがとうございました。マイクミュート忘れすみません。
Avatar
ありがとうございました!
Avatar
sugigami(susieyy) 5/16/2020 3:07 PM
@lovee OBSは動作も軽いし機能も多いし、ハードウェアのミキシングキャプチャを買わなくてもソフトウェアだけで気軽にミキシングできるのがいいですね!
Avatar
@lovee OBSは動作も軽いし機能も多いし、ハードウェアのミキシングキャプチャを買わなくてもソフトウェアだけで気軽にミキシングできるのがいいですね!
@sugigami(susieyy) ですね、前はSnapCameraとか使ってましたけどOBSの方が全然高機能で軽いからこっちに移行しました、唯一の難点は微妙にVirtual Cameraのプラグインの導入だけちょっと面倒ですので早く本家に取り入れて欲しいですw
👍 1
Avatar
Discordの音声チャットの切断を忘れないようにお気をつけ下さい。
Avatar
DiscordのOutput Volumeを戻しておくの忘れるとこでした。あとでトラブルやつw
👍 2
Avatar
ここの   ☎
3:11 PM
☎
3:12 PM
✗から音声チャットを切断できます。
3:12 PM
まだ何人か音声チャット接続中のようでした
Avatar
全員こちらでディスコネクトしました。
Avatar
お、と思ったら今普通に.pkgでインストールできるようになりました! @sugigami(susieyy) https://github.com/johnboiles/obs-mac-virtualcam
Creates a virtual webcam device from the output of OBS. Especially useful for streaming smooth, composited video into Zoom, Hangouts, Jitsi etc. Like CatxFish/obs-virtualcam but for macOS. - johnbo...
👏 1
👍 2
💯 1
Avatar
Fat View Controller を倒せ!成果報告会の延長戦の参加受付を開始しました! https://swift-tweets.connpass.com/event/176893/
# Swift Zoomin' #2 延長戦 Swift Zoomin' はプログラミング言語 Swift に関するオンライン勉強会です。普通の勉強会と同じようにスライドおよび音声で発表を行います。無料アプリのZoom を使う予定ですが、 Zoom 以外での開催の可能性もあります。 今回は Swift Zoomin' チャレンジ 〜Fat View Controllerを倒せ!〜で課題に取り組んだ報告会です。 Fat View Controller として実装されたリバーシアプリをリファクタリングし、どのようにしてクリーンなコードを実現したのか...
🎉 2
Avatar
Zoom の URL 送ったけど自分宛てにメールが届かないんですが、 URL 届いてますか??
10:20 AM
お、 15 分遅れで届いた。 connpass のメール、そんなにラグあるのか。
Avatar
Kishikawa Katsumi 5/30/2020 10:27 AM
届いてないっすね。調子悪いのかも
Avatar
あれ?まだ届いてないですか?順番に処理されてて人によって違うのかな?
Avatar
Kishikawa Katsumi 5/30/2020 10:38 AM
私申し込んでなかった🙏🏻
10:38 AM
connpassのせいではなかったです
Avatar
19:19のタイムスタンプが付いてました
Avatar
送付は 19:05 なんですけどね💧 ラグがすごいですね・・・。
Avatar
sugigami(susieyy) 5/30/2020 11:08 AM
空きがあればZoomのURLを教えてもらえないでしょうか?🙏 ( Swift Zoomin' #2 に参加してたつもりが、 Swift Zoomin' #3 と混同してました 🙇‍♂️ )
Avatar
Topic: Swift Zoomin' #2 延長戦 Time: May 30, 2020 07:00 PM Osaka, Sapporo, Tokyo Join Zoom Meeting https://us02web.zoom.us/j/86719010066?pwd=eWlmdXAwWlAySk8zRGxKS1VHZUtPdz09 Meeting ID: 867 1901 0066 Password: 686227
11:09 AM
こちらになります。
Avatar
sugigami(susieyy) 5/30/2020 11:09 AM
ありがとうございます!
Avatar
ふむふむ
Avatar
バグったら人が死んでしまうリファクタリング・チャレンジ (リバーシ編) iOS版の回答. Contribute to Kuniwak/reversi-ios development by creating an account on GitHub.
👍 5
Avatar
Twitterのハッシュタグは #swiftzoomin です
11:18 AM
The latest Tweets on #swiftzoomin. Read what people are saying and join the conversation.
11:20 AM
本日のタイムテーブルです(あくまで目安) Kuniwak 20:20 KishikawaKatsumi 20:55 休憩 21:25 lovee 21:35 takasek 22:05 koher 22:35 クロージング 23:05
👀 1
Avatar
ほー
Avatar
Kishikawa Katsumi 5/30/2020 11:22 AM
クラッシュさせてはいけないということはクラッシュさせずに検査をする必要があるのか?
Avatar
H鉄鋼をベルコンベアーで高速移動プログラミング制御するようなものだね。こわー。
Avatar
話の展開がすごくおもしろい!
Avatar
ほー!
Avatar
厳密に網羅している
Avatar
なるほど、end の値を指定する代わりに向きと距離を指定するのか
Avatar
ほほー。Lineが作れたらOKなのか
Avatar
質問なし。この感じ好きです👍
Avatar
www
Avatar
おもしろいやりとりw
Avatar
moved の実装、僕は普通に間違えそう
Avatar
昔、処理が早いからインラインアセンブラで書いたら、理解しずらいと上司に怒られたのを思い出すw (edited)
Avatar
見えますー
Avatar
userName生成の時に3文字以外の決まりがあって、全部nilで返ってくるだけだと何が原因かは分からなくなりませんか?
Avatar
回答ありがとうございましたmm
Avatar
完全に例外処理の話になってる!勉強になります。
Avatar
Yoshikuni Kato 5/30/2020 11:49 AM
あまり本筋とは関係ないですが、型を用意して例外の値を受け取らない、というところでpointfree/swift-taggedを思い出しました
Avatar
常用している関数言語ななんですか? @Kuniwak
11:50 AM
ふむふむ、ありますね
11:50 AM
ありがとうございますー
Avatar
ReactiveSwift を採用しているのは Error の型を指定できるからでしょうか?
12:02 PM
ですです
12:02 PM
なるほどー
Avatar
Model Aggregateが具体的にどういうことをしているのか、見てみたいです
Avatar
今の話では、図左端?のData/Stateに属する物もモデルと呼んでいるように思いました。その理解でよろしいでしょうか。
Avatar
リアルタイムの変化がわかるのが大きいのでしょうか
12:06 PM
なるほど、よくわかりました!
Avatar
OKdesu。ありがとうございます
Avatar
間違いが起こらないようにコントロールしている印象を強く受けました。
12:08 PM
ありがとうございました!
Avatar
(バグを全て記録している。。??)
12:10 PM
(すごい)
Avatar
やっぱりモデルやばいwww
12:13 PM
モデル検査勉強してみます!
Avatar
長らく自動テストとテスト容易設計を生業としてきましたが、最近は色々な限界を感じて形式手法に取り組んでいます。 この記事では、既存の自動テストのどこに限界を感じてなぜ形式手法が必要なのかの私見を説明します。なお、私もまだ完全理解には程遠いため間違いがあるかもしれません。ご指摘やご意見はぜひ Kuniwak までいただけると嬉しいです。 著者について プログラマです。開発プロセスをよくするための自発的な自動テストを支援する仕事をしています(経歴)。ここ一年は R&D 的な位置付けで形式手法もやっています。 自動テストの限界 自動テストとは 私がここ数年...
👏 3
Avatar
sugigami(susieyy) 5/30/2020 12:15 PM
すごく興味深いし、とっても勉強になりました 👏👏👏👏👏👏
👏 1
Avatar
特にLineのところ、面白かったです。
Avatar
最近翻訳されてたDropboxの記事を思い出す… > フルスクラッチ
Avatar
セカンドシステム症候群ってやつですね
Avatar
めっちゃわかる…
Avatar
一度は考えてしまうフルスクラッチ
Avatar
わかりすぎる
Avatar
(フルスクラッチした人)
😆 1
12:21 PM
wwww
12:21 PM
それけいは仕事でやり飽きましたw
12:21 PM
5倍です
12:21 PM
(私空行多いのもあるかもですが
12:21 PM
(モデル検査されてるのでリスクは多分ない)
Avatar
言葉が身に沁みる
Avatar
初見:このままでもいいんじゃないの? 読んでいくと:やっぱりちょっとまずいな・・! →わかる
Avatar
(そういう時に、モデル検査のモデルとかで理解を試しながら書いていくと実はいきなりリファクタリングをできたりする)
👍 1
😮 1
Avatar
なるほど確かに
Avatar
オセロの実力がデバッグに必要たしかにw
Avatar
課題が徐々に明らかになってく
Avatar
再現経路するの大変でした!
12:31 PM
私は Wikipedia からパスの盤面拾ってきて再現しました
Avatar
たしか最短一桁手くらいでパスできたはず?
Avatar
まっさらから画面に反映させるのが最近のセオリー →
12:36 PM
そこにDiffable的なものを組み合わせていい感じにしているのですかね?
Avatar
たしか最短一桁手くらいでパスできたはず?
@koher https://github.com/Kuniwak/reversi-ios/blob/master/ReversiCore/ReversiCore/MVCArchitecture/DataTypes/GameStateTests.swift#L17-L44 これ 8 手ですね
バグったら人が死んでしまうリファクタリング・チャレンジ (リバーシ編) iOS版の回答. Contribute to Kuniwak/reversi-ios development by creating an account on GitHub.
👍 1
12:37 PM
あ、私もそうですよ〜
12:37 PM
試行錯誤はありました
Avatar
なるほど、そのまま持つだけ
Avatar
UIの状態で持っていたものをロジックに変更してあげるんですね
Avatar
テストを書きたくなってくるわかる
12:57 PM
これ私も全く同じテスト書いてるw
12:57 PM
バグったら人が死んでしまうリファクタリング・チャレンジ (リバーシ編) iOS版の回答. Contribute to Kuniwak/reversi-ios development by creating an account on GitHub.
Avatar
(このテストコードは岸川さんのGitHubにまだ反映されてないようだ。refactor2リポジトリの続きですかね。見たいです🙏🏻 @Kishikawa Katsumi
👀 1
Avatar
やっぱりどういうテスト書きたいかはだいたい似てくるなぁ
1:02 PM
8888888888
Avatar
8888888
Avatar
8888888
Avatar
sugigami(susieyy) 5/30/2020 1:02 PM
岸川さんのアプローチの過程や、意識していることが垣間見れて勉強になりました 👏👏👏👏👏👏
👍 3
Avatar
岸川さんの思考をトレースできるみたいで楽しかったです!
Avatar
22:09 再開します!
Avatar
:dogeza:
Avatar
Contribute to kishikawakatsumi/reversi-ios development by creating an account on GitHub.
1:06 PM
ここかなー、と思ったんですけどどうでしょう? @Kishikawa Katsumi
1:07 PM
来ました!ありがとうございます
1:08 PM
まっさらから画面に反映させるのが最近のセオリー → そこにDiffable的なものを組み合わせていい感じにしているのですかね? @Kishikawa Katsumi
Avatar
Kishikawa Katsumi 5/30/2020 1:10 PM
そこにDiffable的なものを組み合わせていい感じにしているのですかね?
最初はとりあえず何も考えずに全部のUIを毎回更新する、って感じですね。 そこからパフォーマンスの問題が出てきたら考えるでいいと思います。
Avatar
ありがとうございます!
Avatar
後半始まりました!
Avatar
凍結解除めでたい
Avatar
Kishikawa Katsumi 5/30/2020 1:10 PM
今回の例で言うと、変更通知があるととにかく何も考えずに self.updateMessageViews() self.updateCountLabels()
1:11 PM
を呼ぶって感じです。他にも画面の変わるところがあったら全部呼びます。
Avatar
しまったつぶやきすぎるからじゃまになりそう、、
Avatar
Kishikawa Katsumi 5/30/2020 1:12 PM
要するに状態を途中で切断しても状態を全部反映した画面になっている、そうなってたら前後の状態の繋がりを考えなくていいので安心ということです。
😃 2
Avatar
やばい、変なコメントを流してしまった
Avatar
自分はありがたかったです笑
Avatar
たしかにこの図はわかりやすい
Avatar
Twitterだけではなくて、こちらのURLにアクセスして呟くと、コメントスクリーンに反映されます。 絵文字も打てます💕 https://commentscreen.com/comments?room=swiftzoomin
👍 2
Avatar
すごいシステムだ
1:21 PM
依存逆転の原則であってます
Avatar
SOLID の D ですね
Avatar
DIP大事ですよね。
Avatar
大事です。慣れると DIP なものしか思いつかなくなる…
Avatar
ですね。
Avatar
Kishikawa Katsumi 5/30/2020 1:24 PM
確かに私はstart/finishThinkingにしたけどisThinkingだけでよかったな。 (edited)
Avatar
(すみません、若干離席します)
Avatar
おつかれさまです!
Avatar
ファンシーなアーキテクチャw
Avatar
88888888888
Avatar
sugigami(susieyy) 5/30/2020 1:51 PM
👏👏👏👏👏👏
Avatar
今回も時間が押してしまっているので、このあとの発表内容を変更しようと考えております🙏 このあとアナウンスいたします 🙏
Avatar
相談欄だ
1:53 PM
昔の新聞の人生相談
🤣 1
Avatar
「暫定。いずれ殺す」w
Avatar
とりあえずViewにテスト書いて後で解消するの、なるほどだなぁ。
Avatar
Social Distance
Avatar
避けよう!プログラミングの三密! ・密閉 実装がブラックボックス化されてて誰もメンテナンスできない状態。 ・密集 ひとつのクラスに機能が集中した状態。神クラス。 ・密接 クラス同士が密接に結合していて分離できない状態。単体テストが困難。
Retweets
1772
Likes
3120
Avatar
密閉悪くないのでは?
2:04 PM
誰もメンテナンスできないは問題が別にある気がする…
Avatar
そうですね。カプセル化自体は悪くない(というかいいこと)ですね。
👍 1
Avatar
ネタとしては面白いですww
Avatar
(そういえば私ほとんど SOLID 的なこと言わなかったな…)
Avatar
みんな同じだ。
Avatar
Kishikawa Katsumi 5/30/2020 2:09 PM
書き換えの過程がすごく上手だ
Avatar
まったく同じことやってる。
Avatar
Kishikawa Katsumi 5/30/2020 2:11 PM
なるほどI/Oはインターフェースを作った方がいいんだな
Avatar
分析するには自動生成しないほうがいい、なるほどなぁ。
Avatar
私が今回使ったモデル検査ツール SPIN は自動生成できるんですが配置がいじれないので
2:12 PM
そういうことがすごいよく考えられた SyncStich がオススメです
Avatar
自動生成後、自由に動かしたものも保存できるようになればいいね
Avatar
そうすると更新する時辛くないですか?
2:13 PM
SE の話だ!
Avatar
そうですね、変更部分が多いと差分じゃ自動管理できないかもですね
Avatar
そこ悩ましいですよねぇ、、、
2:14 PM
SE-0283 待望
2:14 PM
というか今までなぜなかった案件
Avatar
Tupleが使いやすくなるのは良いですねー
Avatar
これ僕のスライドにもありますw < SE-0283
Avatar
888888888888
Avatar
888888888
Avatar
👏
Avatar
sugigami(susieyy) 5/30/2020 2:15 PM
影響スケッチのフローが、リファクタリングの過程でシンプルになっていくので、人間にやさしいコードになってるのを実感しました 👏👏👏👏👏👏
Avatar
Spin です
2:15 PM
状態遷移図がいじれないんです
2:15 PM
あれ、
2:15 PM
Stich です
2:15 PM
c が抜けてた
Avatar
A Refinement Checker based on CSP. Contribute to hatsugai/SyncStitch development by creating an account on GitHub.
Avatar
あ、これ描画ツールじゃなくてモデル検査ツールなので用途が限られています!!
2:17 PM
あくまで、CPS という言語(正確には違うけど)で書かれたシステムの状態遷移図を自動生成できます(もちろん自動検証もできます)
2:17 PM
Hashable までは良さげですね
2:17 PM
Comparable は、、、
2:18 PM
というか、Error という protocol いらなくないです?
2:18 PM
必然性が全くわからないです
2:19 PM
だって何も実装を要求しないし、かといって Java の marker interface というわけでもないし、、、
2:19 PM
Int を throw できてもよくないです?
2:19 PM
extension Int: Error {} で投げられてしまうわけですから、そもそも
2:19 PM
防御としては弱すぎます
2:20 PM
ああ、ありますぬえ
2:20 PM
Go とかにも最近入りました
2:20 PM
まあ Error はオフトピですが、、、
2:21 PM
あー、それは私毎度 enum の case の associated value に詰めていってますね
2:21 PM
888888
Avatar
# Swift Zoomin' #3 Swift Zoomin' はプログラミング言語 Swift に関するオンライン勉強会です。 # 内容 次の四つから検討中です。 1. オンラインペアプロ大会 2. 匿名質問会 3. リファクタリングチャレンジ第二弾 4. Swiftで競技プログラミング挑戦会 # 参加方法 日時: 2020 年 7 月 11 日(土) 21:00- 本ページより、「参加枠」または「発表枠」で参加登録をして下さい。 参加者宛に、後日参加のための URL を連絡しますので、connpassからのメー...
Avatar
次回は
2. 匿名質問会
(edited)
Avatar
sli.do
Avatar
そういえば
2:26 PM
koher さんと omochi さんの会社何やってるんだろうみたいなのはあったので
2:26 PM
この CM は嬉しい
Avatar
た し か に
Avatar
しかしいまいち Swift 的なところがどこなんだろう的な
2:27 PM
(いまだにきになるのは omochi さんのコンパイラ勉強の時間は業務時間から捻出されているのかどうか)
2:27 PM
ありがとうございました〜
Avatar
88888888
Avatar
ありがとうございました!
Avatar
おつかれさまでした!!
Avatar
ありがとうございましたー!!
Avatar
sugigami(susieyy) 5/30/2020 2:28 PM
ありがとうございました!!
Avatar
ありがとうございましたー!
Avatar
おつかれさまでした!
Avatar
👏
Avatar
ありがとうございました!
Avatar
(実はまだ喋り足らなかった(まだこだわりポイントが…)
Avatar
今日も楽しかったです!ありがとうございました!!
Avatar
ありがとうございました!
Avatar
👏
Avatar
ushisantoasobu 5/30/2020 2:28 PM
初めて参加しましたが面白かったです、ありがとうございました〜。
Avatar
ありがとうございました〜
2:29 PM
👏
Avatar
Discoord の設定ちゃんと戻しとかないと、、、
Avatar
イベント中のツイートをまとめています。どなたでも編集可能です。日時:2020/5/30(土) 21:00 to 23:00会場:Zoom主催者:Swift Zoomin'詳細:ハッシュタグ:#sw..
👏 2
Avatar
"Swift Zoomin' #2 延長戦" の発表動画を公開しました。型でガチガチに縛って安全性を追求する @orga_chem さん、現実的なリファクタリングの思考過程をトレースして説明する @k_katsumi さん、オーソドックスなCocoa MVCを導入する @lovee さん、(続く) #swiftzoomin https://t.co/obRmy4y8ic
影響スケッチでコードがどのように絡まり合っているかを可視化し、それを解きほぐしていく @takasek さんと、同じ題材(リバーシアプリのリファクタリング)に対して四者四様の視点で切り込み、質問を交えながら一人一時間たっぷり語っていただきました。 #swiftzoomin
🙏🏻 5
Avatar
この後 21 時からこのチャンネルを Swift Zoomin' #3 のテキストチャット用に使います。
Avatar
結局 Zoom のチャットで足りました〜。
Avatar
本日 21 時から Swift Zoomin' #4 でこのチャンネルを使います。よろしくお願いします。 https://swift-tweets.connpass.com/event/182692/
# Swift Zoomin' #4 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 # 内容 今回の Swift Zoomin' は、 Swift で競技プログラミング( AtCoder )に挑戦します! * 競技プログラミングやってるけど Swift はわからないという方 * 普段 Swift を書いているけど競技プログラミングは未経験という方 双方向けに * 競技プログラミングとは * Swift が競技プログラミングに適していると思う理由 * Swift で競技...
👍 2
Avatar
今日は Swift で競技プログラミングに取り組みます。実際に AtCoder にアカウント登録をして、過去問に取り組んでコードを提出します( AtCoder にコードを提出すると制限時間内に正解できるかが判定されて結果が表示されます)。 (edited)
Avatar
よろしくお願いします!
🙏 2
Avatar
初参加です! よろしくお願いいたします!
🤝 3
Avatar
@シマポン そちらは音声チャットなのでこちらのテキストチャットを使います。
12:08 PM
わかりづらくてすみません。
Avatar
始まっております!現在は Zoom にて koher さんによるトーク中です
Avatar
今日の流れ 👉🏻 競技プログラミングって何? 👉🏻 Swift の特徴と競技プログラミング 👉🏻 Swift で競プロ( AtCoder )に挑戦しよう!
Avatar
https://atcoder.jp/register 登録はこちら!
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
Avatar
さきほどの実演まとめ: AtCoderの問題を標準入出力で解くなら Xcodeで File > New > Project > Command Line Tool でmain.swiftを作って、 let numbers = readLine()! // 標準入力から 1 行読み込む .split(separator: " ") // 文字列をスペースで分割 .map { Int($0)! } // 各要素を Int に変換 let sum = numbers.reduce(0, +) print(sum) // 標準出力に sum を出力 swift main.swift < input.txt > output.txt diff output.txt answer.txt という感じになります
Avatar
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
Avatar
AtCoderSupport Swift で AtCoder に取り組むためのサポートライブラリです。標準ライブラリや Foundation に不足しているアルゴリズムやデータ構造等が実装されています。 https://github.com/koher/swift-atcoder-support
Contribute to koher/swift-atcoder-support development by creating an account on GitHub.
Avatar
今みんなでこの問題を解いているところです https://atcoder.jp/contests/abs/tasks/practice_1
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
Avatar
AtCoder Beginners Selection https://atcoder.jp/contests/abs/tasks
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
1:00 PM
終わってしまった方は↑から解いていきましょう
Avatar
つぎの問題です B - Mix Juice https://atcoder.jp/contests/abc171/tasks/abc171_b
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
Avatar
1問目の回答例です let a: Int = Int(readLine()!)! let bc: [Int] = readLine()!.split(separator: " ").map { Int($0)! } let b = bc[0] let c = bc[1] let s: String = readLine()! print(a + b + c, s)
Avatar
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
Avatar
tardigradeさん情報
こちらのサイトから問題の難易度(非公式)が確認できます。 https://kenkoooo.com/atcoder#/table/
Avatar
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
Avatar
遅くまでありがとうございました!
Avatar
おつかれさまでした
🙂 1
Avatar
おおお、 AC が出てる!
3:02 PM
Avatar
時間がかかるのが難点かもですが、まさにゲームみたいで楽しかったです!装備も自分で事前に強化しておけるわけですし。
Avatar
ゲーム感ありますよね😀
Avatar
ですね!
Avatar
お疲れ様でした! ちょうど終わった後に間違いに気づいてACになりました〜
🎉 1
Avatar
おめでとうございます!
😆 1
Avatar
この前の最後の問題 "DNA Sequence" について、 @tardigrade さんが解説を書いてくれたので共有します。 Swift でこの問題の解説が読めるのは(おそらく)この記事だけです。 https://qiita.com/TARDIGRADE/items/37bba2ed25ab12c3b040
はじめに こんにちは!屋代高校PC同好会結成会のTARDIGRADEです。 本記事ではARC104 B - DNA SequenceをSwiftで解いていきたいと思います! 2020/10/24に開かれたSwift Zoomin...
😀 1
Avatar
# Swift Zoomin' #5 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 1. 先取り! Swift 6 の async/await 2. Swift で AtCoder 過去問に挑戦( 2 問) "先取り! Swift 6 の async/await" では Swift 6 の目玉機能 `async/a...
👍 2
Avatar
Zoom の URL は開始 1 時間ほど前を目安にお送りします。
connpass ですが、たまにメッセージの全送信にめっちゃ時間がかかるときあるので注意してください
🙏 2
10:52 AM
僕が前に送ったとき、1時間遅れでみんなに届いた
Avatar
参加許可待ち
Avatar
Atcoder 登録はこちら https://atcoder.jp/register
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
Avatar
AtCoderを解いてみよう、今日1つめの問題はこちらです Blocks on Grid https://atcoder.jp/contests/abc186/tasks/abc186_b
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
👍 1
Avatar
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
Avatar
↑暇な人はこちらに取り組んでみてください
Avatar
(readLine()!とprintを使うのだな、というのが実は一番詰まった)
Avatar
ただいま 
https://atcoder.jp/contests/abc186/tasks/abc186_b
 の解説中です
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
Avatar
便利関数を予め用意しておくかどうかで、差が付きそう
Avatar
https://github.com/koher/swift-atcoder-support こちらreadIntNほかの便利関数をまとめたリポジトリです
Contribute to koher/swift-atcoder-support development by creating an account on GitHub.
👀 2
12:34 PM
また、AtCoderの問題をSwiftで解くチュートリアル記事はこちら https://qiita.com/kntkymt/items/4f02c6b90462f354de6d
普段はiOS/Androidのアプリ開発をしている自分ですが、ここ最近競技プログラミングの人気が爆上がりしている1 という噂は聞いており、やろうかなと思っていた所... AtCoderでSwift5.2が使える様になった との情報を耳...
12:37 PM
準備運動のAtCoderがおわり、async/awaitの話に入りました
Avatar
ロボット超むずいんだけど・・・
Avatar
いつも あシンク と読んでしまう
Avatar
仮に経路数の数え上げができたとして、全部の経路制限の構築をイテレートするだけで明らかに計算量が多すぎるから、 数え上げ自体を畳み込めるんだろうか・・・??
12:44 PM
↑スライドです!
Avatar
SwiftFiddle is an online playground for creating, sharing and embedding Swift fiddles (little Swift programs that run directly in your browser).
SwiftFiddle is an online playground for creating, sharing and embedding Swift fiddles (little Swift programs that run directly in your browser).
👍 15
Avatar
JSONのデコードはJSONDecoderを使います
👍 4
Avatar
1こだけ貼るとコードが見える? https://swiftfiddle.com/m7nn4xoimfh2xdk7p5htbxmmau
SwiftFiddle is an online playground for creating, sharing and embedding Swift fiddles (little Swift programs that run directly in your browser).
Avatar
かっくん 1/23/2021 1:00 PM
SwiftFiddle is an online playground for creating, sharing and embedding Swift fiddles (little Swift programs that run directly in your browser).
Avatar
SwiftFiddle is an online playground for creating, sharing and embedding Swift fiddles (little Swift programs that run directly in your browser).
1:00 PM
むむむ
Avatar
まず補完が効くのがすごい!
Avatar
まちがえて Leave しちゃったので入れてもらってもいいですか。すいませんmm (Zoom) (edited)
👍 1
1:03 PM
ありがとうございました!
Avatar
SwiftFiddle is an online playground for creating, sharing and embedding Swift fiddles (little Swift programs that run directly in your browser).
SwiftFiddle is an online playground for creating, sharing and embedding Swift fiddles (little Swift programs that run directly in your browser).
👍 5
1:09 PM
SwiftFiddle is an online playground for creating, sharing and embedding Swift fiddles (little Swift programs that run directly in your browser).
SwiftFiddle is an online playground for creating, sharing and embedding Swift fiddles (little Swift programs that run directly in your browser).
👍 1
1:10 PM
1,2は単発、3はcallbackだとnestしてしまうようなやつ
1:10 PM
3はプレビュー出ないw
Avatar
og:image はちゃんとセットされているので、discord 側でプレビューを読み込めていないのかも? Slack だとプレビュー出ました
Avatar
swiftfiddle が重くなってしまった
Avatar
yutailang0119 1/23/2021 1:15 PM
止まった
Avatar
いけもと 1/23/2021 1:15 PM
入れないみたいです....
Avatar
かっくん 1/23/2021 1:15 PM
30秒経っても結果が返ってこない...
Avatar
落ちちゃった
🤣 1
Avatar
yutailang0119 1/23/2021 1:16 PM
お疲れ様でした
Avatar
いけもと 1/23/2021 1:16 PM
www
Avatar
あ、帰ってきた
1:16 PM
めっちゃおそいままw
Avatar
omochimetaru 1/23/2021 1:16 PM
コピペする問題コードが開けない
Avatar
omochimetaru 1/23/2021 1:18 PM
fiddleが開かないから3-Bのスタート地点に立てない。
Avatar
いけもと 1/23/2021 1:18 PM
問題開ないです....
Avatar
03A // サーバーから JSON を取得し、 // User インスタンスをデコードし、 // それに加えて User が保持する thumbnailURL から // サムネイル画像をダウンロードする非同期関数 // fetchUserWithThumbnail を完成させて下さい。 import Foundation import FoundationNetworking struct User: Identifiable, Codable { typealias ID = Int let id: ID var name: String var thumbnailURL: URL } func download(from url: URL, completion: @escaping (Result<Data, Error>) -> Void) { do { let data: Data = try Data(contentsOf: url) completion(.success(data)) } catch { completion(.failure(error)) } } func fetchUserWithThumbnail(for id: User.ID, completion: @escaping (Result<(user: User, thumbnail: Data), Error>) -> Void) { let url: URL = URL(string: "https://koherent.org/async-await-challenge/api/user?id=\(id.description)")! // 🚧 ここを実装する } fetchUserWithThumbnail(for: 123) { result in do { let (user, thumbnail) = try result.get() print(user.name, thumbnail.count) } catch { print(error) } }
🙇‍♂️ 1
1:19 PM
03B // サーバーから JSON を取得し、 // User インスタンスをデコードし、 // それに加えて User が保持する thumbnailURL から // サムネイル画像をダウンロードする非同期関数 // fetchUserWithThumbnail を完成させて下さい。 import Foundation import FoundationNetworking struct User: Identifiable, Codable { typealias ID = Int let id: ID var name: String var thumbnailURL: URL } func download(from url: URL) async throws -> Data { let data: Data = try Data(contentsOf: url) return data } func fetchUserWithThumbnail(for id: User.ID) async throws -> (user: User, thumbnail: Data) { let url: URL = URL(string: "https://koherent.org/async-await-challenge/api/user?id=\(id.description)")! // 🚧 ここを実装する } runAsyncAndBlock { do { let (user, thumbnail) = try await fetchUserWithThumbnail(for: 123) print(user.name, thumbnail.count) } catch { print(error) } }
1:20 PM
@swift-main -Xfrontend -enable-experimental-concurrency // サーバーから JSON を取得し、 // User インスタンスをデコードする // 非同期関数 fetchUser を完成させて下さい。 // // サーバーから JSON を取得するには // download 関数を用います。 // download の実装は擬似的なものですが // 変更せずにそのまま利用して下さい。 // // なお、通信やデコードに起因するエラーは // 起こらないものとします。 import Foundation import FoundationNetworking struct User: Identifiable, Codable { typealias ID = Int let id: ID var name: String var thumbnailURL: URL } func download(from url: URL) async -> Data { let data: Data = try! Data(contentsOf: url) return data } func fetchUser(for id: User.ID) async -> User { let url: URL = URL(string: "https://koherent.org/async-await-challenge/api/user?id=\(id.description)")! let data = await download(from: url) let user: User = try! JSONDecoder().decode(User.self, from: data) return user } runAsyncAndBlock { let user = await fetchUser(for: 123) print(user.name) }
Avatar
swiftNightly BOT 1/23/2021 1:20 PM
koher
Avatar
Kishikawa Katsumi 1/23/2021 1:21 PM
fiddle
Avatar
omochimetaru 1/23/2021 1:21 PM
@swift-main -Xfrontend -enable-experimental-concurrency import Foundation import FoundationNetworking struct User: Identifiable, Codable { typealias ID = Int let id: ID var name: String var thumbnailURL: URL } func download(from url: URL) async throws -> Data { let data: Data = try Data(contentsOf: url) return data } func fetchUserWithThumbnail(for id: User.ID) async throws -> (user: User, thumbnail: Data) { let url: URL = URL(string: "https://koherent.org/async-await-challenge/api/user?id=\(id.description)")! let data = try await download(from: url) let decoder = JSONDecoder() let user = try decoder.decode(User.self, from: data) let thData = try await download(from: user.thumbnailURL) return (user: user, thumbnail: thData) } runAsyncAndBlock { do { let (user, thumbnail) = try await fetchUserWithThumbnail(for: 123) print(user.name, thumbnail.count) } catch { print(error) } }
Avatar
swiftNightly BOT 1/23/2021 1:21 PM
koher 24121
Avatar
Kishikawa Katsumi 1/23/2021 1:21 PM
おちたか
🙏 1
Avatar
omochimetaru 1/23/2021 1:21 PM
3-Bできた
Avatar
yutailang0119 1/23/2021 1:21 PM
Among Us中にすいません
Avatar
omochimetaru 1/23/2021 1:21 PM
24121ってなんだ、バイト数かな
1:21 PM
じゃあできてそう
1:22 PM
あ、ほんとだ
Avatar
Kishikawa Katsumi 1/23/2021 1:24 PM
いっしゅんだけかな?
Avatar
かっくん 1/23/2021 1:24 PM
できた。こんなに簡単に書けるようになるのかと思うと感動する
👍 5
Avatar
問題 04 // サーバーから User とその Article 最新 10 件の JSON を取得し、 // それらを返す非同期関数 fetchUserWithArticles を実装して下さい。 // ただし、 User と Article の JSON は並行して取得するものとし、 // User と Artcile の取得には fetchUser および // fetchArticles を用いるものとします。 import Foundation import FoundationNetworking struct User: Identifiable, Codable { typealias ID = Int let id: ID var name: String var thumbnailURL: URL } struct Article: Identifiable, Codable { typealias ID = Int let id: ID var title: String } func fetchUser(for id: User.ID) async throws -> User { let url: URL = URL(string: "https://koherent.org/async-await-challenge/api/user?id=\(id.description)")! let data: Data = try Data(contentsOf: url) let user: User = try JSONDecoder().decode(User.self, from: data) return user } func fetchArticles(for userID: User.ID, limit: Int) async throws -> [Article] { let url: URL = URL(string: "https://koherent.org/async-await-challenge/api/articles?userID=\(userID.description)")! let data: Data = try Data(contentsOf: url) let articles: [Article] = try JSONDecoder().decode([Article].self, from: data) return articles } func fetchUserWithArticles(for id: User.ID, limit: Int) async throws -> (user: User, articles: [Article]) { // 🚧 ここを実装する } runAsyncAndBlock { do { let (user, articles) = try await fetchUserWithArticles(for: 123, limit: 10) print(user, articles) } catch { print(error) } }
👍 3
Avatar
omochimetaru 1/23/2021 1:41 PM
これすごいなあ
Avatar
yutailang0119 1/23/2021 1:45 PM
return のとこ、こう書けんの?ってので書けてまだソワソワする
Avatar
わかる え!?ってなる
Avatar
tryを書く位置がいくつかパターンありそう
Avatar
omochimetaru 1/23/2021 1:46 PM
タプルにまとめて1個かいた
1:48 PM
nn?
1:48 PM
async let user = try await fetchUser(for: id) async let articles = try await fetchArticles(for: id, limit: limit) return try (user: await user, articles: await articles)
Avatar
1,2行目のtry awaitなくていける気がする
Avatar
omochimetaru 1/23/2021 1:48 PM
ほお〜
1:48 PM
あそうか
1:48 PM
意味変わるのか
Avatar
yutailang0119 1/23/2021 1:49 PM
return try await (user: user, articles: articles) これが異常なソワソワ感だった
Avatar
omochimetaru 1/23/2021 1:49 PM
awaitもまとめていいのか。
Avatar
return try await (fetchUser(for: id), fetchArticles(for: id, limit: 10)) これだとasync letとは異なる??
Avatar
omochimetaru 1/23/2021 1:49 PM
あれ?それと一緒なのか?
1:49 PM
それはタプル引数の評価順が担保されるのか
Avatar
なるほど
1:50 PM
なおさら「async letというsyntax sugar」という表現がキモに思えてきた
Avatar
// ViewController の reloadUserButton が押されたときに // fetchUser 関数を使ってサーバーから User を取得し、 // userNameLabel.text に取得したユーザーの name を設定するように // onReloadUserButtonPressed メソッドを完成させて下さい。 import Foundation import FoundationNetworking class UIViewController {} final class UIButton {} final class UILabel { var text: String? } struct User: Identifiable, Codable { typealias ID = Int let id: ID var name: String var thumbnailURL: URL } func fetchUser(for id: User.ID) async throws -> User { let url: URL = URL(string: "https://koherent.org/async-await-challenge/api/user?id=\(id.description)")! let data: Data = try Data(contentsOf: url) let user: User = try JSONDecoder().decode(User.self, from: data) return user } final class ViewController: UIViewController { let reloadUserButton: UIButton = .init() let userNameLabel: UILabel = .init() let userID: User.ID = 123 // 🚧 このメソッドを完成させる func onReloadUserButtonPressed(_ sender: UIButton) { } } let viewController: ViewController = .init() viewController.onReloadUserButtonPressed(viewController.reloadUserButton) (edited)
Avatar
omochimetaru 1/23/2021 1:57 PM
user id がわからない
1:59 PM
ViewControllerのプロパティになっててinitで受け取るとかかな
Avatar
@asyncHandler、バグりそうって思ったけど func bar() { print(2) // foo1() DispatchQueue.main.async { print(4) // foo2() DispatchQueue.main.async { print(5) } } } みたいに書いてたよくあるコードと同じなんですね (edited)
Avatar
さっきの問題 04 の fetchUser でスレッドをスリープさせても fetchArticles の方が後に実行されるみたいですけれど、本当に同時にダウンロードされているんですか?(何か聞き逃していたらすみません)
👍 1
2:01 PM
なるほど
2:02 PM
ありがとうございます!
Avatar
@asyncHandlerをつけると、そのfunc自体をawaitできます?
2:03 PM
なるほどです
Avatar
omochimetaru 1/23/2021 2:04 PM
自体はできないんじゃないか
Avatar
yutailang0119 1/23/2021 2:05 PM
@asyncHandler 付けないと 'async' in a function that does not support concurrency ってエラーもちゃんと出る
Avatar
griffin-stewie 1/23/2021 2:07 PM
id って変数はないんじゃないでしょうか?
Avatar
一瞬 SwiftFiddle が 500 を返してきたけど動的にリロードされた...!
Avatar
// ViewController の cancelReloadingUser ボタンを押すと // reloadUser ボタンで実行されている User のリロードを // キャンセルするように ViewController の実装を完成させて下さい。 import Foundation import FoundationNetworking class UIViewController {} final class UIButton {} final class UILabel { var text: String? } struct User: Identifiable, Codable { typealias ID = Int let id: ID var name: String var thumbnailURL: URL } func fetchUser(for id: User.ID) async throws -> User { let url: URL = URL(string: "https://koherent.org/async-await-challenge/api/user?id=\(id.description)")! let data: Data = try Data(contentsOf: url) let user: User = try JSONDecoder().decode(User.self, from: data) return user } // 🚧 このクラスを完成させる final class ViewController: UIViewController { let reloadUserButton: UIButton = .init() let cancelReloadingUserButton: UIButton = .init() let userNameLabel: UILabel = .init() @asyncHandler func onReloadUserButtonPressed(_ sender: UIButton) { if let user = try? await fetchUser(for: 123) { userNameLabel.text = user.name } } func onCancelReloadingUserButtonPressed(_ sender: UIButton) { } } let viewController: ViewController = .init() viewController.onReloadUserButtonPressed(viewController.reloadUserButton) viewController.onCancelReloadingUserButtonPressed(viewController.cancelReloadingUserButton)
Avatar
omochimetaru 1/23/2021 2:17 PM
Task.Handleのdeinitってcancelしてくれるんでしたっけ
2:18 PM
Avatar
Task.Handleってstructじゃないですか?(classでいい気もしますが)
Avatar
型は Task.Handle<()> 型なんですね
🙇 1
Avatar
Task が実行されるスレッドって明示的に指定できたりするんでしょうか。現実的には userNameLabel.text = user.name とかは UI スレッドで実行したそう。
Avatar
func async() async
2:24 PM
// Thread X await DispatchQueue.main.async() // Main Thread
😲 1
Avatar
なるほどー。
Avatar
実際にcancelされているのかどうかが分からない
👍 1
Avatar
griffin-stewie 1/23/2021 2:27 PM
The Swift Programming Language. Contribute to apple/swift development by creating an account on GitHub.
😍 1
Avatar
これがcancelされるというわけではないのか
Avatar
omochimetaru 1/23/2021 2:29 PM
キャンセルの実現は自力でやる必要がある
Avatar
自力...
Avatar
omochimetaru 1/23/2021 2:30 PM
if Task.isCanceled { throw Task.CancelError() } 的な
Avatar
おー
Avatar
omochimetaru 1/23/2021 2:30 PM
非同期の根っこで使う割り込めるコールバック式のAPIもあるはずだけどまだ議論を見てないか忘れた
2:30 PM
asyncの世界の中である限り自分でifでチェックするだけで良い
Avatar
cancelできました
😲 3
Avatar
omochimetaru 1/23/2021 2:32 PM
ああ、チェックして投げてくれるやつがあるのか。
Avatar
// コールバックで結果を受け取る非同期関数 download を使って、 // async で結果を返す非同期関数 download を実装して下さい。 import Foundation import FoundationNetworking func download(from url: URL, completion: @escaping (Result<Data, Error>) -> Void) { do { let data: Data = try Data(contentsOf: url) completion(.success(data)) } catch { completion(.failure(error)) } } // 🚧 ここを実装する runAsyncAndBlock { do { let url: URL = URL(string: "https://koherent.org/async-await-challenge/api/user?id=123")! let data: Data = try await download(from: url) print(String(data: data, encoding: .utf8)!) } catch { print(error) } }
Avatar
treastrain / Tanaka.R 1/23/2021 2:39 PM
問題07 の Swift バージョンはリンク先だと 5.3.1 になっていますが、nightly-main にする必要はありますか?
2:40 PM
ありがとうございますm( )m
🙏 1
Avatar
withUnsafeThrowingContinuation自体をawaitできますか?
2:47 PM
ほぉーー
Avatar
Combine の Futureawait できるようになったりしたら、withUnsafeThrowingContinuation と役割被りそう
Avatar
# Swift Zoomin' #6 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 SwiftUI を使って、 2 時間のライブコーディングで @koher がアプリを作る様子を配信します。 Xcode プロジェクトを作るところから始めて、解説しながら実装します。 また毎回恒例で、 AtCoder の過去問を 1 問または 2 問...
Avatar
omochimetaru 1/23/2021 2:55 PM
ロボット問題、ついに入力例2の150が手計算で出せるアルゴリズムにたどり着いた (edited)
Avatar
# Swift競プロ部 Swift で AtCoder Beginner Contest 191 (以下、 ABC 191 )に挑戦し、コンテスト終了後にわいわい語り合います。会場は Discord の swift-developers-japan サーバーの音声チャンネル 🔊kyoprobu です。 ⛔ ABC 191 は個人戦です。コンテスト中に他人とコミュニケーションを取ることはできません。本イベントはコンテスト終了後に開催します。 # Swift と競プロ 競技プログラミングにおける Swift 使用人口は多くありません。だからこそ、 Swift 競プロerで集まってわい...
Avatar
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
Avatar
yutailang0119 1/23/2021 3:07 PM
長時間swiftfiddle使ってみて、実行ボタンは上の方に欲しい気がした
Avatar
Kishikawa Katsumi 1/23/2021 3:13 PM
上のほうが使いやすい?
Avatar
yutailang0119 1/23/2021 3:15 PM
13インチMBA/Safariで使ってたんですが、微妙にボタンが画面内に入っていなくて、スクロールしてました
3:16 PM
途中で、ブラウザ内のズームをちょっと縮小して解決した
3:16 PM
他の人はどうだったか知りたいなー
Avatar
Kishikawa Katsumi 1/23/2021 3:27 PM
あー、了解です。エディタをちょっと狭くするか、ボタンを移動するか、って感じか
Avatar
yutailang0119 1/23/2021 3:30 PM
確かに、エディタのサイズを調整する方法もあった
Avatar
Kishikawa Katsumi 1/23/2021 4:02 PM
全部上におけたらそのほうがいいかなあ。
4:02 PM
いまのレイアウトはCSSが難しくて、なりゆきでいちばん無難におさまった、というだけなのでそんなに明確な意思があるわけではないです。。。
Avatar
omochimetaru 1/24/2021 6:46 PM
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
6:48 PM
昨日思いついたと言っていたアルゴリズムは実は間違っていて問題Cが通らず、 愚直な実装も用意して小さいケースでいろいろとテストしたら間違っている事がわかり、 そこから更に新しいアルゴリズムを思いついて、 それでもまだ例3だけは通らなくて、 モジュロ演算に対する知識不足があったのをググったらやっとクリアできた
6:49 PM
取り組んだ時間を合計すると7時間半ぐらいかかっている。これは実戦でいきなりC問題をやっていても間に合わないですね。
Avatar
おおお、すごい!おつかれさまです。これは僕も解説なしで考えてみないと…。
👍 1
Avatar
Kishikawa Katsumi 1/30/2021 7:55 AM
https://swiftfiddle.com/ 調整して13インチのM1MacのファーストビューにUIがおさまるようにした。あとVPCのスペックをちょっと上げた。同時接続でだんだん重くなっていくのはしょうがないとして、なんとなくそれが継続してるように見えたのでコンテナがちゃんと掃除されるようにした(つもり)
SwiftFiddle is an online playground for creating, sharing and embedding Swift fiddles (little Swift programs that run directly in your browser).
👍 2
Avatar
yutailang0119 1/30/2021 2:48 PM
見ました!最高です!
👍🏻 1
Avatar
今週土曜日(24日) 21:00〜 開催です
  • AtCoder 過去問チャレンジ(abc196 B問題、解説 @koogawa
  • @koher さんによるライブコーディング(SwiftUIとFirebaseでチャットアプリを作ります)
https://swift-tweets.connpass.com/event/202441/
# Swift Zoomin' #6 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 SwiftUI と Firebase を使って、 2 時間のライブコーディングで @koher がチャットアプリを作る様子を配信します。新規 Xcode プロジェクトが作られたところから始めて、解説しながら実装します。 また毎回恒例で、 AtCod...
👍 2
Avatar
このあと21:00〜 開催です!
🙌 1
Avatar
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
11:58 AM
今日の問題
Avatar
Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。
12:09 PM
先日、こんなTweetをしましたが、DiscordにSwift・iOSなどに関連する開発者のサーバーを作ってみました。
Avatar
extension RawRepresentable where Self: Encodable, RawValue == UUID { func encode(to encoder: Encoder) throws { var container = encoder.singleValueContainer() try container.encode(self.rawValue.uuidString) } } のような感じで拡張する必要がありますが
Avatar
# Swift Zoomin' #7 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 みんなで Swift でリバーシの AI を作って対戦させるリバーシ大会を行います。 また毎回恒例で、 AtCoder の過去問 1 問に Swift で取り組みます。 # 参加方法 日時: 2021 年 7 月 24 日(土) 21:00- ...
Avatar
SwiftUI & Firebase のライブコーディング、密度が濃くてとても勉強になりました。 是非またお願いします!
🙂 2
Avatar
このあと21:00から開催します! https://swift-tweets.connpass.com/event/211603/
# Swift Zoomin' #7 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 みんなで Swift でリバーシ(オセロ)の AI のプログラムを作って対戦させるリバーシ大会を行います。 AI と言っても機械学習ではなく、昔ながらのコンピューターのプレイヤーを実装します。特に必要な前提知識はありません。たとえば、↓のコードだけで...
Avatar
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
Avatar
Contribute to koher/swift-reversi-run development by creating an account on GitHub.
Avatar
レベル○まで倒せた!
1️⃣ 6
2️⃣ 6
3️⃣ 6
4️⃣ 5
5️⃣ 4
Avatar
盤面って 8x8 固定でしたっけ?
Avatar
Avatar
uhooi
盤面って 8x8 固定でしたっけ?
固定です。
👍 1
Avatar
よろしくお願いします!
Avatar
お願いしますー
9.05 KB
Avatar
お願いします!
Avatar
members: [String] = 6 values { [0] = "koogawa" [1] = "log5" [2] = "kashihararara" [3] = "terry" [4] = "kagaffy" [5] = "ykws" }
Avatar
ドキドキする!
2:14 PM
【1回戦】 koogawa" 勝ち "log5" (edited)
2:15 PM
【2回戦】 "terry" 勝ち "kagaffy" (edited)
2:16 PM
3回戦 log5 dark kashiharara light 勝ち (edited)
2:17 PM
【4回戦】 terry dark ykws light 勝ち (edited)
2:19 PM
【決勝】 kashiharara dark 🥇 ykws light🥈 (edited)
Avatar
【3位決定戦】
2:27 PM
log5 dark 🥉 terry light
2:33 PM
# Swift Zoomin' #8 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 SwiftUI と Firebase を使って、 2 時間のライブコーディングで @koher がチャットアプリを作る様子を配信します。新規 Xcode プロジェクトが作られたところから始めて、解説しながら実装します。 また毎回恒例で、 AtCod...
Avatar
$ swift Welcome to Apple Swift version 5.3.2 (swiftlang-1200.0.45 clang-1200.0.32.28). Type :help for assistance. 1> let members = ["log5", "terry", "ykws", "kagaffy", "koogawa", "kashihararara"].shuffled() members: [String] = 6 values { [0] = "koogawa" [1] = "log5" [2] = "kashihararara" [3] = "terry" [4] = "kagaffy" [5] = "ykws" }
2:50 PM
koogawa ---+ A +---+ log5 ---+ +---+ kashihararara ---+ | terry ---+ +--- B +---+ | kagaffy ---+ +---+ ykws -------+ (edited)
2:51 PM
Aブロック 1回戦: koogawa vs log5 (edited)
2:54 PM
Bブロック 1回戦: terry vs kagaffy
2:55 PM
Aブロック 2回戦: log5 vs kashihararara
2:55 PM
Bブロック 2回戦: terry vs ykws
2:57 PM
決勝戦: kashihararara vs ykws
2:58 PM
🥇 kashihararara 🥈 ykws 🥉 log5
👏 1
Avatar
3位決定戦 log5 vs terrypy
Avatar
本日 21 時から、 Swift Zoomin' #8 でこちらのチャンネルを利用します。今回はハンズオン的に Actor のコードを書いてみる練習をします。今からでも参加登録可能です。 https://swift-tweets.connpass.com/event/220324/
# Swift Zoomin' #8 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 Swift 5.5 で追加される Actor について解説し、練習のためにみんなで実際に Actor を使ったコードを書いてみます。 # 参加方法 日時: 2021 年 10 月 23 日(土) 21:00- 本ページより参加登録をして下さい。...
👍 2
Avatar
Avatar
koher
本日 21 時から、 Swift Zoomin' #8 でこちらのチャンネルを利用します。今回はハンズオン的に Actor のコードを書いてみる練習をします。今からでも参加登録可能です。 https://swift-tweets.connpass.com/event/220324/
直前の申込みですみません。 先程申し込んだためzoomのURLを共有頂けると非常に嬉しいです。 (お忙しいとは思いますので無理のない範囲で。。。)
Avatar
Avatar
ok
直前の申込みですみません。 先程申し込んだためzoomのURLを共有頂けると非常に嬉しいです。 (お忙しいとは思いますので無理のない範囲で。。。)
こちらになります。ご登録ありがとうございます。 https://us02web.zoom.us/j/83681484743?pwd=MHB1b2RyRnlzTVdBWkF3QzZ1RmZKQT09 (edited)
😁 1
Avatar
もしZoomにつながらないなどあれば、ここでもいいのでご連絡下さい。
Avatar
音声チャットにも #swift-zoomin が存在しますが、今日はそちらではなくこのテキストチャンネルを使います
👍 2
Avatar
練習問題用リポジトリ https://github.com/koher/swift-zoomin-8 (edited)
Contribute to koher/swift-zoomin-8 development by creating an account on GitHub.
12:20 PM
Q1
👍 24
Avatar
21:25まで
Avatar
だめだわからん
Avatar
まさかのURLSession使ったことないパーソンがここに...(課題自体はできました
👏 4
Avatar
21:28 ぐらいまで延長
Avatar
Q1 func downloadData(from url: URL) async throws -> Data { let (data, response) = try await URLSession.shared.data(from: url) if let response = response as? HTTPURLResponse { guard response.statusCode == 200 else { throw ResponseError(statusCode: response.statusCode) } } return data }
12:38 PM
Q2
👍 25
Avatar
21:45 まで
Avatar
Cannot use let 'url' with a non-sendable type 'URL' from concurrently-executed code
12:40 PM
Sendable じゃない警告が出るな…一旦無視する
Avatar
↑私もです...
Avatar
みんな実装スピードおかしくない?
😋 3
Avatar
Taihei Mishima 10/23/2021 12:43 PM
改行位置とかスペース空けるとかによると思うけど10行ちょいになるすごい
Avatar
koher さんの名前とアイコンが出てきたら成功?
12:44 PM
よっしゃできた
👍 2
🎉 6
t_tensai 3
yoshi 1
Avatar
Avatar
Taihei Mishima
改行位置とかスペース空けるとかによると思うけど10行ちょいになるすごい
tochi86 - とち🐹 10/23/2021 12:45 PM
感動しますね!
Avatar
Result に get() メソッドなんて生えてるのか… (edited)
Avatar
griffin-stewie 10/23/2021 12:48 PM
get() 便利ですよね。swift-zoomin で koher さんに教えてもらった。
Avatar
使ったことなかった…調べます
Avatar
Q2 override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) // User の JSON の取得 Task { do { let url: URL = .init(string: "https://koherent.org/fake-service/api/user?id=\(id)")! let userData: Data = try await downloadData(from: url) let user: User = try JSONDecoder().decode(User.self, from: userData) // View への反映 title = user.name nameLabel.text = user.name // アイコン画像の取得 let iconData: Data = try await downloadData(from: user.iconURL) // Data を UIImage に変換 guard let iconImage: UIImage = .init(data: iconData) else { // エラーハンドリング print("The icon image at \(user.iconURL) has an illegal format.") return } // View への反映 iconImageView.image = iconImage } catch { // エラーハンドリング print(error) } } }
Avatar
griffin-stewie 10/23/2021 12:49 PM
self 問題は一旦スルーする感じでしょうか?
👍 1
Avatar
switch result { case .success } 常にみたいな感じでやってました、、
t_wakaru 1
Avatar
userの取得とiconの取得でエラーハンドリングを別々に行いたい場合はdo-catchが入れ子になることは避けられないでしょうか。
Avatar
tochi86 - とち🐹 10/23/2021 12:50 PM
try-catchがようやく本領発揮してきた感じがします
Avatar
Avatar
toya108
userの取得とiconの取得でエラーハンドリングを別々に行いたい場合はdo-catchが入れ子になることは避けられないでしょうか。
できない気がします… エラーの種類がわかっていれば catch を複数書けばいける?
🙇‍♂️ 1
Avatar
griffin-stewie 10/23/2021 12:51 PM
たしかに。あとで取り出す方が面倒な気がする。
Avatar
入れ子にしないでもguardで抜けちゃえばいいのでは?
Avatar
あ、入れ子か 入れ子にする必要はなさそうですね do-catch を 2 つ書けばよさそう
👍 1
Avatar
2つの目のdo-catchで1つ目の変数を参照するので入れ子にするしかなさそうな。。。 (edited)
Avatar
iOSDC はまだ観ていないのですが(絶対観る)、別の岸川さんと一緒に登壇されているトークで観たかもしれません
Avatar
Avatar
ok
2つの目のdo-catchで1つ目の変数を参照するので入れ子にするしかなさそうな。。。 (edited)
単にdoの手前で宣言してerrorの時はguardで抜けちゃえば使える。
🙇‍♂️ 1
Avatar
Avatar
1024jp
単にdoの手前で宣言してerrorの時はguardで抜けちゃえば使える。
あ、ということですね。 ありがとうございます!
👍 1
Avatar
例だと actor を使うってわかるけど、実務だと見逃して普通に class 使っちゃいそう、、
t_wakaru 1
Avatar
actor使わなくても問題に気が付かないことがありそうで怖い。
t_wakaru 1
Avatar
Taihei Mishima 10/23/2021 1:01 PM
これもはやclass使わないって割り切るのが良いのだろうか
Avatar
たとえばディクショナリとかで競合が起こるとクラッシュしたりするので、バグトラッカーのエラーログから「やばいなやっぱActor(DispatchQueue)がええな」ってなって変更するとかありそう(じっさいにあった
t_naruhodo 2
Avatar
たしかに actor でできなくて class のみができることってなんだろ? 継承とか?
Avatar
classのほうが楽にかける
Avatar
Taihei Mishima 10/23/2021 1:03 PM
楽にかけるはなるほどもって
Avatar
actor は難しいの?
1:03 PM
今から試すからそれでわかるか
Avatar
tochi86 - とち🐹 10/23/2021 1:04 PM
actor だとメソッドがほぼほぼ async になっちゃったりするのかな
Avatar
Q3
👍 14
Avatar
Avatar
uhooi
たしかに actor でできなくて class のみができることってなんだろ? 継承とか?
あと純粋にclassが裏でQueueで動いてない分パフォーマンスは高そう
Avatar
書けてると思うんだけど、どうなったら競合?
Avatar
Avatar
1024jp
書けてると思うんだけど、どうなったら競合?
たぶん両方100 or 他の同じ値が出ると競合じゃないですかね (edited)
Avatar
treastrain / Tanaka.R 10/23/2021 1:09 PM
Thread.sleep(forTimeInterval: 1.0) が入ると競合になります(なりやすい)かね
👍 1
Avatar
griffin-stewie 10/23/2021 1:09 PM
競合がおこらないw
t_wakaru 3
Avatar
tochi86 - とち🐹 10/23/2021 1:09 PM
なるほど、doの前で変数宣言しておくテクニックは便利そうです!
Avatar
Avatar
ok
2つの目のdo-catchで1つ目の変数を参照するので入れ子にするしかなさそうな。。。 (edited)
Q2 の do-catch をネストせずに書く例です。 override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) // User の JSON の取得 Task { let user: User do { let url: URL = .init(string: "https://koherent.org/fake-service/api/user?id=\(id)")! let userData: Data = try await downloadData(from: url) user = try JSONDecoder().decode(User.self, from: userData) } catch { // エラーハンドリング print(error) return } // View への反映 title = user.name nameLabel.text = user.name let iconData: Data do { // アイコン画像の取得 iconData = try await downloadData(from: user.iconURL) } catch { // エラーハンドリング print(error) return } // Data を UIImage に変換 guard let iconImage: UIImage = .init(data: iconData) else { // エラーハンドリング print("The icon image at \(user.iconURL) has an illegal format.") return } // View への反映 iconImageView.image = iconImage } }
Avatar
あああああああああああありがとうございます
Avatar
griffin-stewie 10/23/2021 1:10 PM
Task 自体の実行コストと Int の足し算のコストのバランスが悪いんだろうな
Avatar
Counter1に全部書いてあったw
Avatar
Avatar
ok
actor使わなくても問題に気が付かないことがありそうで怖い。
Taihei Mishima 10/23/2021 1:10 PM
sleepが1.0だと 100 200 200 200 100 200 こんな感じで場合により競合した
Avatar
tochi86 - とち🐹 10/23/2021 1:11 PM
データ競合は、なかなか再現しないから厄介なんですよね...
t_wakaru 3
Avatar
import Foundation final class BankAccount { var balance: Int = 0 var test: [Int:Int] = [:] func deposit(_ amount: Int) -> Int { balance += amount test[100] = 100 Thread.sleep(forTimeInterval: 1.0) return balance } } func bankAccountMain() { let account = BankAccount() Task { print(account.deposit(100)) } Task { print(account.deposit(100)) } }
t_tensai 1
t_naruhodo 2
Avatar
書き方が悪くてスリープ仕込んでも競合しない
Avatar
griffin-stewie 10/23/2021 1:13 PM
サンプルとして提供してくれている DataRace 版でもいくら実行しても綺麗に121212 しかならないw (edited)
Avatar
import Foundation final class BankAccount { var balance = 0 func deposit(_ amount: Int) -> Int { Thread.sleep(forTimeInterval: 1.0) balance += amount return balance } } func bankAccountMain() { let bankAccount = BankAccount() Task { print(bankAccount.deposit(100)) } Task { print(bankAccount.deposit(200)) } }
Avatar
tochi86 - とち🐹 10/23/2021 1:14 PM
1000回くらいループ実行すれば競合起きるんじゃないかな?w
t_tensai 1
t_kusa 1
Avatar
griffin-stewie 10/23/2021 1:14 PM
シミュレータのボタンを連打してみてる
Avatar
それでも起きない、、
t_sorena 3
Avatar
ひとまず100回ループしたけど上手に足してくれる
Avatar
treastrain / Tanaka.R 10/23/2021 1:15 PM
私は実機(iPad Air 4th.) で動かしているのですが、ちゃんと毎回競合します
Avatar
1つ目の数字が出てから1秒後(タップしてから2秒後)ぐらいに2つ目の数字が表示されてる気がします (edited)
Avatar
griffin-stewie 10/23/2021 1:16 PM
zoom に CPU 喰われて、もっさりした結果うまく競合しないようになってる気がする。
Avatar
これで競合してくれやすくなりました。 (edited)
Avatar
スリープ時間を長くすると競合するかも
1:17 PM
Thread.sleep(until: Date() + 10) みたいな
Avatar
5秒にしてもだめです💦
Avatar
griffin-stewie 10/23/2021 1:18 PM
僕も競合しないです。
Avatar
Counter1も競合しない
Avatar
counter1を5秒にしてます!
Avatar
Task.detached
Avatar
Taihei Mishima 10/23/2021 1:18 PM
僕はちゃんと競合しますねー
1:19 PM
ちゃんとと言うべきかわからんが
Avatar
import Foundation final class BankAccount { var balance = 0 func deposit(_ amount: Int) -> Int { balance += amount Thread.sleep(forTimeInterval: 1.0) return balance } } func bankAccountMain() { (1...100).forEach { _ in let bankAccount = BankAccount() Task { print(bankAccount.deposit(100)) } Task { print(bankAccount.deposit(100)) } } }
Avatar
treastrain / Tanaka.R 10/23/2021 1:19 PM
「Bank Account」ボタンを連打していますか?(2秒とか5秒待たずに)
Avatar
競合しない勢ですが、1個目のTaskが終わった後、2個めのタスクのsleepがはじまってそうですね
Avatar
競合しないマン
Avatar
M1+Monterey beta+Xcode 13.1 RCでやってます(競合しない
Avatar
ちな M1 Mac
Avatar
タイミングの確認は、Sim ではなく実デバイスで行うのが良いです.
Avatar
M1 です
Avatar
片方を Task.detached にしたら競合しました (at Intel) (edited)
Avatar
競合します
Avatar
griffin-stewie 10/23/2021 1:19 PM
僕 古い Intel で競合しない
Avatar
同じくM1
Avatar
M1で競合してないです (edited)
Avatar
treastrain / Tanaka.R 10/23/2021 1:20 PM
M1 と実機で競合します
Avatar
ヤベェ、開発機intelとM1で2つ用意しないといけないのか... (edited)
Avatar
Intelで競合しないですね・・・
Avatar
おおっこれで 200 が 2 回出力された import Foundation final class BankAccount { var balance = 0 func deposit(_ amount: Int) -> Int { balance += amount Thread.sleep(forTimeInterval: 1.0) return balance } } func bankAccountMain() { let bankAccount = BankAccount() Task.detached { print(bankAccount.deposit(100)) } Task { print(bankAccount.deposit(100)) } }
Avatar
片方だけdetachedにしたらいけましたね
💯 1
Avatar
Avatar
log5
片方だけdetachedにしたらいけましたね
はい!(なお意味はわかっていない)
Avatar
同じスレッド
t_sorena 1
Avatar
Avatar
n.0939
これで競合してくれやすくなりました。 (edited)
tochi86 - とち🐹 10/23/2021 1:21 PM
これで競合いけました!
Avatar
両方detachedだと競合しなくて、片方だけで試したら自分も競合しました!
Avatar
detached 付けたところ同じスレッドでしたね 🤔
Avatar
片方detachedで競合しました
Avatar
Taihei Mishima 10/23/2021 1:22 PM
両方detachした時に同じThread使ってしまうなんてあるのかな笑
Avatar
お。同じく片方detached で競合しました 🙏 スレッドも別でした
Avatar
Intelです
Avatar
griffin-stewie 10/23/2021 1:22 PM
全部同じスレッドだった
Avatar
意外なところで行き詰まる皆さま
Avatar
griffin-stewie 10/23/2021 1:23 PM
実機でやったらくっそ競合するようになったwwwww
Avatar
Avatar
tochi86 - とち🐹
これで競合いけました!
僕は片方 Task.detached に変えました。classをactorにしたときに、両方ともTask { ... } で囲む必要があるので。
t_thanks 1
Avatar
闇を感じる😌
Avatar
griffin-stewie 10/23/2021 1:24 PM
Avatar
片方detachいけた
Avatar
確かに両方 detached だと必ず同じスレッドで実行される
Avatar
griffin-stewie 10/23/2021 1:25 PM
実機だと競合100%でうけるw
Avatar
treastrain / Tanaka.R 10/23/2021 1:25 PM
両方 detached でも違うスレッドで実行されますね… M1 です
Avatar
むむ
Avatar
競合が起きて喜んでるの面白いですね
t_kusa 9
Avatar
griffin-stewie 10/23/2021 1:25 PM
iPhone 13 Pro は高級 Twitter マシンなので暇らしい。
Avatar
実機 or シミュレータとか?
Avatar
再現できないのは実務っぽい
t_sorena 4
Avatar
問題解決方法 → シミュレータで両方Task {}にする (edited)
1:29 PM
返すのも return self.balanceにしないと
Avatar
「並行処理は怖いですね」
1:30 PM
今日の名言
Avatar
griffin-stewie 10/23/2021 1:31 PM
actor にしたらその型のメソッドを外から呼び出す時には必ず await が必要になるんだろうか? (edited)
Avatar
func getInterest(with rate: Double) -> Int
Avatar
nonisolated
Avatar
新しい残高がニューバランスでスニーカーみたいになった (edited)
t_wakaru 1
😄 1
t_kusa 4
Avatar
これ実装したあとなにすればいいですか? あと BankAccont はもうずっと actor ?
1:38 PM
ずっと actor りょうかいです!
Avatar
griffin-stewie 10/23/2021 1:39 PM
雑に同一 Task 内で deposit したあとに getInterest した
Avatar
現実味のありすぎる利率にしてしまったせいで変動がなかった…
Avatar
どうなれば正解でしたっけ?
Avatar
sendableはなぜsendableなんでしょう。どこにsendするイメージ? > The Sendable protocol indicates that value of the given type can be safely used in concurrent code.
Avatar
griffin-stewie 10/23/2021 1:44 PM
Thread に Send しても安全って事なのかな?
👍 1
Avatar
正解がわからない ↓のコードで以下のように出力されるのは正しい? 100 200 300 300 import Foundation actor BankAccount { var balance = 0 func deposit(_ amount: Int) -> Int { balance += amount Thread.sleep(forTimeInterval: 1.0) return balance } func getInterest(with rate: Double) -> Int { let newBalance = Double(balance) * (1.0 + rate) return Int(newBalance) } } func bankAccountMain() { let bankAccount = BankAccount() Task.detached { print(Thread.current) print(await bankAccount.deposit(100)) print(await bankAccount.getInterest(with: 0.5)) } Task { print(Thread.current) print(await bankAccount.deposit(100)) print(await bankAccount.getInterest(with: 0.5)) } } (edited)
Avatar
griffin-stewie 10/23/2021 1:45 PM
@uhooi getInterest のなかで deposit を呼び出さないと
👍 2
Avatar
なるほど?やってみます
Avatar
This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - History for proposals/0302-concurrent-value-and-concurrent-closures.md - apple/swift-evolution
1:48 PM
Hello everyone, With the recent introduction of Swift concurrency, and most notably actors to the language, Swift gained powerful and foundational building blocks for expressing thread-safe concurrent programs. This proposal aims to extend Swift's actors with the ability to work equally well for distributed systems thanks to the introduction of...
Avatar
こうなった 理解できていない 100 200 500 1250 import Foundation actor BankAccount { var balance = 0 func deposit(_ amount: Int) -> Int { balance += amount Thread.sleep(forTimeInterval: 1.0) return balance } func getInterest(with rate: Double) -> Int { let newBalance = Int(Double(balance) * (1.0 + rate)) let balance = deposit(newBalance) return balance } } func bankAccountMain() { let bankAccount = BankAccount() Task.detached { print(Thread.current) print(await bankAccount.deposit(100)) print(await bankAccount.getInterest(with: 0.5)) } Task { print(Thread.current) print(await bankAccount.deposit(100)) print(await bankAccount.getInterest(with: 0.5)) } }
Avatar
Swift 1.0から書いてると徐々にややこしい機能が足されてきた感じだけど、今いきなりSwiftやり始めるとむずかしそう。
t_sorena 3
t_wakaru 4
Avatar
1.0足しちゃダメな気がします。
👍 1
Avatar
それだ
Avatar
今Swift 5.5 + SwiftUI始める人つらそう。マジでえらい。
t_wakaru 3
Avatar
そのuhooi銀行いいな・・・
t_kusa 8
Avatar
口座開きます!
Avatar
100 200 300 450 import Foundation actor BankAccount { var balance = 0 func deposit(_ amount: Int) -> Int { balance += amount Thread.sleep(forTimeInterval: 1.0) return balance } func getInterest(with rate: Double) -> Int { let interest = Int(Double(balance) * rate) let balance = deposit(interest) return balance } } func bankAccountMain() { let bankAccount = BankAccount() Task.detached { print(Thread.current) print(await bankAccount.deposit(100)) print(await bankAccount.getInterest(with: 0.5)) } Task { print(Thread.current) print(await bankAccount.deposit(100)) print(await bankAccount.getInterest(with: 0.5)) } }
Avatar
フエール銀行かな?
Avatar
griffin-stewie 10/23/2021 1:52 PM
ウホーイ銀行が利息を見直した
😢 1
Avatar
ウホーイ銀行解約します
Avatar
griffin-stewie 10/23/2021 1:52 PM
いや、それでも5割.... ゴクリ...
😆 1
😋 2
Avatar
これ必ず↓の順序で呼び出されるってこと? Task.detached { print(Thread.current) print(await bankAccount.deposit(100)) // 1 print(await bankAccount.getInterest(with: 0.5)) // 3 } Task { print(Thread.current) print(await bankAccount.deposit(100)) // 2 print(await bankAccount.getInterest(with: 0.5)) // 4 }
1:53 PM
利息 5 割はかなりいいよ〜みんな契約してね〜〜〜
Avatar
Taihei Mishima 10/23/2021 1:53 PM
コードの実行順はそうだけどThread違うから場合によっては下が先に処理されるのでは
👍 2
Avatar
私は4が先に呼ばれてるかも
Avatar
func getInterest(with rate: Double) -> Int { deposit(Int(Double(balance) * rate)) }
Avatar
tochi86 - とち🐹 10/23/2021 1:54 PM
そうか、returnいらないんだ
Avatar
なるほど
1:55 PM
print(await bankAccount.deposit(100)) print(await bankAccount.getInterest(with: 0.5))
Avatar
スレッド内は上から下という認識であってますか?
Avatar
↑は上から先に必ず呼ばれるかな って書こうとしたらそうとのことだった(完)
🙏 1
Avatar
Q5
👍 13
Avatar
あ、throw忘れてた
2:00 PM
マイナスになったらthrow?
2:00 PM
コメントに書いてあった...
Avatar
transfer に async が付いているのは、同一インスタンスからでも非同期で呼び出したいから? (edited)
Avatar
throwもできた
Avatar
ああ、そうだ
2:02 PM
ありがとうございます
🙂 1
Avatar
競合に手こずりすぎた
Avatar
(めっちゃ喋りすぎたかも、失礼しましたmm
t_yasashii 1
t_waiwai 2
Avatar
griffin-stewie 10/23/2021 2:04 PM
競合起きない問題じゃないかな? freddi さんは場を繋いでくれていた認識です。
👍 3
❤️ 1
Avatar
arigatougozaimasu!
Avatar
適当なエラーで何を返すかいつも迷う
2:05 PM
フレディさん、どう考えてもありがたすぎます
Avatar
TOEIC890点ワイ「OkaneTarinaiErrorでええやろ」
Avatar
わかる、無に向かって話すのさびしい
Avatar
(聴いてる方もためになりました…)
Avatar
雑なエラー名にした struct AccountError: Error { }
Avatar
throw NSError(domain: "おかねがたりません", code: -9)
Avatar
treastrain / Tanaka.R 10/23/2021 2:07 PM
throw NSError() にしました…)
👍 2
Avatar
そうか、空のNSErrorにすればいいのか(import Foundationが要るけど)
t_naruhodo 2
Avatar
そんなテクが
Avatar
20日がいい(勝手 → いや、13でもなんとかなるか (edited)
Avatar
# Swift Zoomin' #8-2 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 Swift 5.5 で追加される Actor について解説し、練習のためにみんなで実際に Actor を使ったコードを書いてみます。 # 参加方法 日時: 2021 年 11 月 13 日(土) 21:00- 本ページより参加登録をして下さ...
1️⃣ 11
2️⃣ 6
Avatar
いや、私の個人的な用事なので気にしないでください...
🙇‍♂️ 1
Avatar
griffin-stewie 10/23/2021 2:10 PM
extension String: LocalizedError { public var errorDescription: String? { self } }
t_tensai 1
2:11 PM
雑なエラー
Avatar
1️⃣ 13 日 2️⃣ 20 日
1️⃣ 14
2️⃣ 3
Avatar
Q5 の回答 <NSThread: 0x6000024e8680>{number = 6, name = (null)} <NSThread: 0x6000024d4240>{number = 7, name = (null)} 100 200 300 450 250 50 import Foundation struct AccountError: Error { } actor BankAccount { var balance = 0 func deposit(_ amount: Int) -> Int { balance += amount Thread.sleep(forTimeInterval: 1.0) return balance } func getInterest(with rate: Double) -> Int { deposit(Int(Double(balance) * rate)) } func withdraw(_ amount: Int) throws -> Int { let newBalance = balance - amount guard newBalance >= 0 else { throw AccountError() } return deposit(-amount) } func transfer(_ amount: Int, to account: BankAccount) async throws { let newBalance = balance - amount guard newBalance >= 0 else { throw AccountError() } _ = deposit(-amount) _ = await account.deposit(amount) } } func bankAccountMain() { let bankAccount = BankAccount() Task.detached { print(Thread.current) print(await bankAccount.deposit(100)) print(await bankAccount.getInterest(with: 0.5)) print(try await bankAccount.withdraw(200)) } Task { print(Thread.current) print(await bankAccount.deposit(100)) print(await bankAccount.getInterest(with: 0.5)) print(try await bankAccount.withdraw(200)) } } (edited)
Avatar
決定:次回開催日は 2021/11/13 21:00〜
Avatar
transferはwithdrawをtry
Avatar
たしかにw
2:17 PM
withdrow と deposit は完全に切り分けたほうがいいですね…
Avatar
ほう、precondition
Avatar
SwiftになってUInteger使わなくなったなぁそういえば (edited)
Avatar
griffin-stewie 10/23/2021 2:18 PM
transfer したあとのもらった側のアカウントの残高をプリントする目的で ¥0 deposit してた
Avatar
private(set) var balanceでprint(account.balance)の方が良さそう。
👍 1
Avatar
await account.balance でアクセスするとよろしかもです
Avatar
あ私もdeposit使ってました。なるほど。
Avatar
getterもawaitが🐬
Avatar
tochi86 - とち🐹 10/23/2021 2:20 PM
assertよりもpreconditionがいいのかな
Avatar
要るかが🐬になる
🦈 3
Avatar
DbC
Avatar
tochi86 - とち🐹 10/23/2021 2:20 PM
いるか
Avatar
サメじゃん...
Avatar
tochi86 - とち🐹 10/23/2021 2:22 PM
Swiftのエラー4分類の話ですね
Avatar
deposit/withdraw前に処理するべきだからpreconditionで良いと思う。 (edited)
Avatar
これは Swift Tweets の発表をまとめたものです(次回開催はこちら)。イベントのスポンサーとして Qiita に許可をいただいた上で投稿しています。 ありがとうございました!Q&Aは他の人の発表中でも構わないので...
Avatar
エラー4分類 今までに何度も読んでお世話になってます!!
Avatar
よく参考にしてます笑
Avatar
エラー4分類は神でした…見返します…
Avatar
The Swift Programming Language. Contribute to apple/swift development by creating an account on GitHub.
Avatar
できた(ネタバレ注意) import Foundation struct WithdrawError: Error { } actor BankAccount { var balance = 0 func deposit(_ amount: Int) -> Int { balance += amount Thread.sleep(forTimeInterval: 1.0) return balance } func getInterest(with rate: Double) -> Int { deposit(Int(Double(balance) * rate)) } func withdraw(_ amount: Int) throws -> Int { precondition(amount > 0) guard balance - amount >= 0 else { throw WithdrawError() } balance -= amount Thread.sleep(forTimeInterval: 1.0) return balance } func transfer(_ amount: Int, to account: BankAccount) async throws { _ = try withdraw(amount) _ = await account.deposit(amount) } } func bankAccountMain() { let bankAccount = BankAccount() Task.detached { print(Thread.current) print(await bankAccount.deposit(100)) print(await bankAccount.getInterest(with: 0.5)) print(try await bankAccount.withdraw(200)) } Task { print(Thread.current) print(await bankAccount.deposit(100)) print(await bankAccount.getInterest(with: 0.5)) print(try await bankAccount.withdraw(200)) } }
Avatar
precondition と assert は似ているので、どういうケースでどちらを使うべきか意識してないと不適切な使い方をしてしまいます。本投稿では、 precondition と assert をどのように使い分けるべきかについて...
Avatar
拡張子 .rst 初めて見た気がする
Avatar
Python使いなのかな.rst
Avatar
tochi86 - とち🐹 10/23/2021 2:28 PM
なるほど、assertはリリース時はクラッシュしない、preconditionはリリース時もクラッシュするんですね、ありがとうございます!
Avatar
assertは開発者向けの気をつけてねメッセージなイメージ
t_naruhodo 2
Avatar
griffin-stewie 10/23/2021 2:29 PM
むしろ preconditionFailure しかつかったことないかも。
Avatar
assert 使ったことないマン 脳死で precondition or preconditionFailure を使っている、、 ちゃんと記事を見返さないと
Avatar
nilになるはずないけど将来よくわからなくて殺す必要まではないときにguard let foo = ふにゃふにゃ else { return assertionFailure() } はよく使う
t_naruhodo 2
Avatar
preconditionとassertの使い分けは今でも迷うなあ・・・
Avatar
これも怖い時よくやる → assert(Thread.isMainThread)
t_wakaru 1
👀 1
t_naruhodo 4
Avatar
tochi86 - とち🐹 10/23/2021 2:35 PM
@discardableResult ←これ補完効かないのきつい... (edited)
t_wakaru 3
Avatar
throws付きのプロパティ知らなかった。学びだ。
Avatar
わいも知らなかった・・・
Avatar
griffin-stewie 10/23/2021 2:36 PM
get throws { } 初めまして
Avatar
そういえばcomputed propertyは実態が関数ってきいたことあるので、まあできないことはないのか
Avatar
actor以外のプロパティにもasyncつけられるのか
Avatar
setもthrow, asyncできますか?
Avatar
そうなんだ! actorのvarは自動的にprivate(set)
Avatar
tochi86 - とち🐹 10/23/2021 2:40 PM
学びが深い
t_sorena 2
Avatar
なるほどです!勉強になりました。ありがとうございます
Avatar
88888888
Avatar
8888888
Avatar
griffin-stewie 10/23/2021 2:43 PM
88888
Avatar
888888
Avatar
8888888888
Avatar
ありがとうございました!
Avatar
ありがとうございました。
Avatar
今日の面白かったです。
Avatar
88888888
Avatar
こちらこそ遅くまで色々教えていただき
Avatar
treastrain / Tanaka.R 10/23/2021 2:43 PM
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
888888888888
Avatar
ありがとうございました!!!
Avatar
ありがとうございました!
Avatar
ありがとうございました。
Avatar
ありがとうございました!
Avatar
ありがとうございました.
Avatar
ありがとうございました!
Avatar
# Swift Zoomin' #9 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 考え中。リファクタリング的な内容になりそうです。 # 参加方法 日時: 2022 年 1 月 22 日(土) 21:00- 本ページより参加登録をして下さい。 当日の開始 1 時間程前に参加のための URL を連絡しますので、connpass...
Avatar
小さくコード書いていくの面白いな。
Avatar
888888
Avatar
tochi86 - とち🐹 10/23/2021 2:44 PM
ありがとうございました!初参加でしたがめちゃくちゃ勉強になりました!チャットの雰囲気もとても良いですね (edited)
Avatar
ありがとうございました!
Avatar
だいぶ先だ 1月 (edited)
Avatar
ありがとうございました〜
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
griffin-stewie 10/23/2021 2:45 PM
勉強になりました
Avatar
ありがとうございましたー!
Avatar
ありがとうございました!
Avatar
Taihei Mishima 10/23/2021 2:45 PM
ありがとうございましたmm
Avatar
次回開催日: #8-2 は 11/13(土)21:00 #9 は 1/22(土)21:00 (edited)
👍 1
Avatar
ありがとうございました〜〜〜! 私は最終的にこうなりました↓ <NSThread: 0x600003d4e1c0>{number = 6, name = (null)} <NSThread: 0x600003d3ae40>{number = 4, name = (null)} A: 100 A: 200 A: 300 A: 450 A: 350 A: 250 A:150 B: 100 A:150 B: 100 import Foundation struct WithdrawError: Error { } actor BankAccount { var balance = 0 func deposit(_ amount: Int) -> Int { balance += amount Thread.sleep(forTimeInterval: 1.0) return balance } func getInterest(with rate: Double) -> Int { deposit(Int(Double(balance) * rate)) } func withdraw(_ amount: Int) throws -> Int { precondition(amount > 0) guard balance - amount >= 0 else { throw WithdrawError() } balance -= amount Thread.sleep(forTimeInterval: 1.0) return balance } func transfer(_ amount: Int, to account: BankAccount) async throws { _ = try withdraw(amount) _ = await account.deposit(amount) } } func bankAccountMain() { let accountA = BankAccount() let accountB = BankAccount() Task.detached { print(Thread.current) print("A: \(await accountA.deposit(100))") print("A: \(await accountA.getInterest(with: 0.5))") print("A: \(try await accountA.withdraw(100))") try await accountA.transfer(50, to: accountB) print("A:\(await accountA.balance) B: \(await accountB.balance)") } Task { print(Thread.current) print("A: \(await accountA.deposit(100))") print("A: \(await accountA.getInterest(with: 0.5))") print("A: \(try await accountA.withdraw(100))") try await accountA.transfer(50, to: accountB) print("A:\(await accountA.balance) B: \(await accountB.balance)") } }
Avatar
次回用メモ: 10/23はQ5まで実施 https://speakerdeck.com/koher/swift-zoomin-number-8?slide=52 スライドは52枚目ぐらいまで進んだ 11/13 は Q6, Q7 をやる https://github.com/koher/swift-zoomin-8
Avatar
↑明日11/13(土)21:00〜からです!
👍 2
Avatar
今日の資料です。前回の続きを更新しています。これに加えて、最初に前回の復習をします。 https://speakerdeck.com/koher/swift-zoomin-number-8?slide=53
9:23 AM
演習で使うリポジトリです。前回と同じですが、 8-2 ブランチを使います。 https://github.com/koher/swift-zoomin-8/tree/8-2
Contribute to koher/swift-zoomin-8 development by creating an account on GitHub.
Avatar
tochi86 - とち🐹 11/13/2021 12:14 PM
こんばんはー
Avatar
こんばんは〜
Avatar
こんばんは!
Avatar
tochi86 - とち🐹 11/13/2021 12:26 PM
なるほど、納得の理由です
Avatar
へー、そこまで手を入れられるのか。@unchecked
Avatar
なるほど、現時点ではエラーにならない オプションを付けて warning を出すこともできるが、現時点では動きが怪しい
Avatar
Actor-isolated Context の引継ぎの関するswift-developers-japan でのやりとり https://discord.com/channels/291054398077927425/291054454793306112/890858321693769748
12:47 PM
👍 9
Avatar
View の反映のビルドエラーが解決できない
12:56 PM
[ネタバレ注意] // View への反映 title = state.$user.name nameLabel.text = state.$user.name iconImageView.image = state.$user.iconImage
12:57 PM
そもそも SwiftUI や Combine がわからないゆえのエラーです泣
Avatar
ああ、cancellableで保持しないといけないのか…
Avatar
tochi86 - とち🐹 11/13/2021 1:03 PM
メインスレッドでreceiveするのを忘れてアプリが落ちてしまった
Avatar
(速。録画を見たいです)
Avatar
Q6 import UIKit import Combine final class UserViewController: UIViewController { private let state: UserViewState private let iconImageView: UIImageView = .init() private let nameLabel: UILabel = .init() private var cancellables: Set<AnyCancellable> = [] init(id: User.ID) { self.state = UserViewState(id: id) super.init(nibName: nil, bundle: nil) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() // レイアウト iconImageView.translatesAutoresizingMaskIntoConstraints = false iconImageView.layer.cornerRadius = 40 iconImageView.layer.borderWidth = 4 iconImageView.layer.borderColor = UIColor.systemGray3.cgColor iconImageView.clipsToBounds = true view.addSubview(iconImageView) nameLabel.translatesAutoresizingMaskIntoConstraints = false view.addSubview(nameLabel) NSLayoutConstraint.activate([ iconImageView.widthAnchor.constraint(equalToConstant: 80), iconImageView.heightAnchor.constraint(equalToConstant: 80), iconImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor), iconImageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16), nameLabel.centerXAnchor.constraint(equalTo: iconImageView.centerXAnchor), nameLabel.topAnchor.constraint(equalTo: iconImageView.bottomAnchor, constant: 16), ]) // View への反映 state .$user .receive(on: DispatchQueue.main) .sink { [weak self] user in self?.nameLabel.text = user?.name } .store(in: &cancellables) state .$iconImage .receive(on: DispatchQueue.main) .sink { [weak self] iconImage in self?.iconImageView.image = iconImage } .store(in: &cancellables) } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) Task { await state.loadUser() } } } (edited)
1:06 PM
import Combine import Foundation import class UIKit.UIImage final class UserViewState { let id: User.ID @Published private(set) var user: User? @Published private(set) var iconImage: UIImage? init(id: User.ID) { self.id = id } func loadUser() async { do { // User の JSON の取得 let url: URL = .init(string: "https://koherent.org/fake-service/api/user?id=\(id)")! let data = try await downloadData(from: url) // JSON のデコード let user: User = try JSONDecoder().decode(User.self, from: data) // state への反映 self.user = user // アイコン画像の取得 let iconData = try await downloadData(from: user.iconURL) // Data を UIImage に変換 guard let iconImage: UIImage = .init(data: iconData) else { // エラーハンドリング print("The icon image at \(user.iconURL) has an illegal format.") return } // state への反映 self.iconImage = iconImage } catch { // エラーハンドリング print(error) } } }
Avatar
loadUser()の中にTaskを書くよりもloadUserをasyncにした方が良いのでしょうか?
1:09 PM
なるほど、ありがとうございます。
Avatar
Taskの中でselfを書かなくていいのはなぜなんでしょうか クロージャの中だとselfを明示的に書きなさいっていつも怒られるんですが。。。 Sendableだとselfを書かなくていいとか?
1:10 PM
あああああああなるほど
1:10 PM
ありがとうございます!
Avatar
tochi86 - とち🐹 11/13/2021 1:10 PM
へぇー!
Avatar
extension Task where Failure == Never { ... @discardableResult @_alwaysEmitIntoClient public init( priority: TaskPriority? = nil, @_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping () async -> Success ) { ... } }
👀 1
1:13 PM
The Swift Programming Language. Contribute to apple/swift development by creating an account on GitHub.
👍 1
Avatar
解説しながらのコードタイプ、ゆっくり目でお願いしますー🙏
Avatar
これは知らなきゃ解けない予感がする Actor-isolated property '$user' can not be referenced from the main actor
Avatar
僕もエラーになってますねー
Avatar
おなじく
Avatar
tochi86 - とち🐹 11/13/2021 1:16 PM
Xcodeバージョンかも?
Avatar
Version 13.1 (13A1030d)
Avatar
tochi86 - とち🐹 11/13/2021 1:16 PM
13.1でエラーです
Avatar
Xcode 13.0 です
Avatar
13.1 でエラーです
Avatar
ビルドしたら消えるのやめて
Avatar
tochi86 - とち🐹 11/13/2021 1:19 PM
Task {} 1個の中に複数のawaitを詰め込むか、Task {} を複数用意するかで迷ってしまう
Avatar
Q7 import UIKit import Combine final class UserViewController: UIViewController { private let state: UserViewState private let iconImageView: UIImageView = .init() private let nameLabel: UILabel = .init() private var cancellables: Set<AnyCancellable> = [] init(id: User.ID) { self.state = UserViewState(id: id) super.init(nibName: nil, bundle: nil) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() // レイアウト iconImageView.translatesAutoresizingMaskIntoConstraints = false iconImageView.layer.cornerRadius = 40 iconImageView.layer.borderWidth = 4 iconImageView.layer.borderColor = UIColor.systemGray3.cgColor iconImageView.clipsToBounds = true view.addSubview(iconImageView) nameLabel.translatesAutoresizingMaskIntoConstraints = false view.addSubview(nameLabel) NSLayoutConstraint.activate([ iconImageView.widthAnchor.constraint(equalToConstant: 80), iconImageView.heightAnchor.constraint(equalToConstant: 80), iconImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor), iconImageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16), nameLabel.centerXAnchor.constraint(equalTo: iconImageView.centerXAnchor), nameLabel.topAnchor.constraint(equalTo: iconImageView.bottomAnchor, constant: 16), ]) // View への反映 Task { await state .$user .receive(on: DispatchQueue.main) .sink { [weak self] user in self?.nameLabel.text = user?.name } .store(in: &cancellables) } Task { await state .$iconImage .receive(on: DispatchQueue.main) .sink { [weak self] iconImage in self?.iconImageView.image = iconImage } .store(in: &cancellables) } } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) Task { await state.loadUser() } } } extension Published.Publisher: @unchecked Sendable where Output: Sendable {} (edited)
1:21 PM
import Combine import Foundation import class UIKit.UIImage actor UserViewState { let id: User.ID @Published private(set) var user: User? @Published private(set) var iconImage: UIImage? init(id: User.ID) { self.id = id } func loadUser() async { do { // User の JSON の取得 let url: URL = .init(string: "https://koherent.org/fake-service/api/user?id=\(id)")! let data = try await downloadData(from: url) // JSON のデコード let user: User = try JSONDecoder().decode(User.self, from: data) // state への反映 self.user = user // アイコン画像の取得 let iconData = try await downloadData(from: user.iconURL) // Data を UIImage に変換 guard let iconImage: UIImage = .init(data: iconData) else { // エラーハンドリング print("The icon image at \(user.iconURL) has an illegal format.") return } // state への反映 self.iconImage = iconImage } catch { // エラーハンドリング print(error) } } }
Avatar
これ、loadUser()から async 取り去って良いのですか?
Avatar
extension Published.Publisher: @unchecked Sendable {} が強引っぽく見えるのですが、これは製品コードでも問題ないのでしょうか?
Avatar
あ、Task{}で包んでました
Avatar
あと警告を完全に解消する方法があれば知りたいです
1:26 PM
りょうかいです、ありがとうございますm( )m
Avatar
tochi86 - とち🐹 11/13/2021 1:26 PM
警告消えるの楽しみ!
Avatar
user は 1 つなのに for 文を使うのがピンと来ない
1:31 PM
なるほど、ストリームにどんどん流れてくるのを for 文で表しているのか ありがとうございます!
Avatar
(こんなふうに書けちゃうのか...!)
Avatar
画像が反映されず、名前しか反映されない おとなしく解答を待つ…w
Avatar
griffin-stewie 11/13/2021 1:35 PM
動いてるけど、購読のキャンセルがどうなっているのか謎なコードになってる。
Avatar
なるほど、ワイのコードは user の for ループから抜け出せないから画像が反映されないのか
Avatar
self書かなくてもいけましたけど、これはstrongされているのかな?
Avatar
griffin-stewie 11/13/2021 1:39 PM
それなら何故僕が動いているのかわからないな
Avatar
return でいいのか、for 文だから break の感じがした
Avatar
Taskのイニシャライザに渡したクロージャは,クロージャ内部で明示的にスレッドを切り替えない限り,イニシャライズしたスレッドで実行されるという認識であってますでしょうか?? (edited)
Avatar
tochi86 - とち🐹 11/13/2021 1:49 PM
self なくてもエラー出ないと、問題に気づきにくいですよね。。
Avatar
griffin-stewie 11/13/2021 1:50 PM
Koher さんの修正版を Leaks でみてるけど結局 UserViewController のインスタンスは常に1個生き続けてるのは SwiftUI のせい?
Avatar
self がない場合は続けても仕方ないので return でおk ありがとうございます!
Avatar
なるほど,だからストリームの購読のときに書いていたメインスレッドを指定する処理をなくせるんですね.ありがとうございます!
Avatar
(横道です: >修正版を Leaks でみてるけど Leaksって3rdパーティのツールの名前ですか?) @griffin-stewie さん
Avatar
griffin-stewie 11/13/2021 1:56 PM
#f82121c396d に戻して、Task もコメントアウトしてもインスタンスが1個残り続ける問題が解消されていませんでした。Swift Concurrency 関連とは無関係の問題のようです。
Avatar
Q8 の解答例も一応貼ってもらったほうが良さそうでしょうか
Avatar
Avatar
n.0939
(横道です: >修正版を Leaks でみてるけど Leaksって3rdパーティのツールの名前ですか?) @griffin-stewie さん
griffin-stewie 11/13/2021 1:57 PM
Xcode 付属のプロファラの中の計測方法?の名前です。⌘I で実行して、Leaks というのを選べば今生きているインスタンスが見えます。
Avatar
Avatar
griffin-stewie
Xcode 付属のプロファラの中の計測方法?の名前です。⌘I で実行して、Leaks というのを選べば今生きているインスタンスが見えます。
ありがとうございます!!
Avatar
Q8 import UIKit import Combine final class UserViewController: UIViewController { private let state: UserViewState private let iconImageView: UIImageView = .init() private let nameLabel: UILabel = .init() private var cancellables: Set<AnyCancellable> = [] init(id: User.ID) { self.state = UserViewState(id: id) super.init(nibName: nil, bundle: nil) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() // レイアウト iconImageView.translatesAutoresizingMaskIntoConstraints = false iconImageView.layer.cornerRadius = 40 iconImageView.layer.borderWidth = 4 iconImageView.layer.borderColor = UIColor.systemGray3.cgColor iconImageView.clipsToBounds = true view.addSubview(iconImageView) nameLabel.translatesAutoresizingMaskIntoConstraints = false view.addSubview(nameLabel) NSLayoutConstraint.activate([ iconImageView.widthAnchor.constraint(equalToConstant: 80), iconImageView.heightAnchor.constraint(equalToConstant: 80), iconImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor), iconImageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16), nameLabel.centerXAnchor.constraint(equalTo: iconImageView.centerXAnchor), nameLabel.topAnchor.constraint(equalTo: iconImageView.bottomAnchor, constant: 16), ]) // View への反映 do { let task = Task { [weak self] in guard let state = self?.state else { return } for await user in await state.$user.values { guard let self = self else { return } self.nameLabel.text = user?.name } } cancellables.insert(.init { task.cancel() }) } do { let task = Task { [weak self] in guard let state = self?.state else { return } for await iconImage in await state.$iconImage.values { guard let self = self else { return } self.iconImageView.image = iconImage } } cancellables.insert(.init { task.cancel() }) } } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) Task { await state.loadUser() } } } extension Published.Publisher: @unchecked Sendable where Output: Sendable {} extension UIImage: @unchecked Sendable {} import Combine import Foundation import class UIKit.UIImage actor UserViewState { let id: User.ID @Published private(set) var user: User? @Published private(set) var iconImage: UIImage? init(id: User.ID) { self.id = id } func loadUser() async { do { // User の JSON の取得 let url: URL = .init(string: "https://koherent.org/fake-service/api/user?id=\(id)")! let data = try await downloadData(from: url) // JSON のデコード let user: User = try JSONDecoder().decode(User.self, from: data) // state への反映 self.user = user // アイコン画像の取得 let iconData = try await downloadData(from: user.iconURL) // Data を UIImage に変換 guard let iconImage: UIImage = .init(data: iconData) else { // エラーハンドリング print("The icon image at \(user.iconURL) has an illegal format.") return } // state への反映 self.iconImage = iconImage } catch { // エラーハンドリング print(error) } } }
1:59 PM
extension URL: @unchecked Sendable {}
2:00 PM
👍 17
Avatar
extension URL: @unchecked Sendable {} のような Sendable に準拠するだけのエクステンションは 1 つのファイルにまとめるのが一般的でしょうか? そもそもなんで Sendable に準拠していないんだろう…
Avatar
tochi86 - とち🐹 11/13/2021 2:02 PM
これ準拠させないままSwift6に行くのはやめて欲しいですねw
Avatar
まだ普及していないので何が一般的かわからない、UIKit でまとめて 1 つのファイルにするのもありかも おいおい Sendable に準拠する可能性がある 理解しました、ありがとうございます!
Avatar
protocolにglobalActorを付与したらそのprotocolに準拠するものも同じglobalActorで実行されることが保証されるんでしょうか?
Avatar
(ワーニング全部消えた。。)
Avatar
おおー警告がすべて消えた!!!
Avatar
Q9 import UIKit import Combine @MainActor final class UserViewController: UIViewController { private let state: UserViewState private let iconImageView: UIImageView = .init() private let nameLabel: UILabel = .init() private var cancellables: Set<AnyCancellable> = [] init(id: User.ID) { self.state = UserViewState(id: id) super.init(nibName: nil, bundle: nil) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() // レイアウト iconImageView.translatesAutoresizingMaskIntoConstraints = false iconImageView.layer.cornerRadius = 40 iconImageView.layer.borderWidth = 4 iconImageView.layer.borderColor = UIColor.systemGray3.cgColor iconImageView.clipsToBounds = true view.addSubview(iconImageView) nameLabel.translatesAutoresizingMaskIntoConstraints = false view.addSubview(nameLabel) NSLayoutConstraint.activate([ iconImageView.widthAnchor.constraint(equalToConstant: 80), iconImageView.heightAnchor.constraint(equalToConstant: 80), iconImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor), iconImageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16), nameLabel.centerXAnchor.constraint(equalTo: iconImageView.centerXAnchor), nameLabel.topAnchor.constraint(equalTo: iconImageView.bottomAnchor, constant: 16), ]) // View への反映 do { let task = Task { [weak self] in guard let state = self?.state else { return } for await user in state.$user.values { guard let self = self else { return } self.nameLabel.text = user?.name } } cancellables.insert(.init { task.cancel() }) } do { let task = Task { [weak self] in guard let state = self?.state else { return } for await iconImage in state.$iconImage.values { guard let self = self else { return } self.iconImageView.image = iconImage } } cancellables.insert(.init { task.cancel() }) } } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) Task { await state.loadUser() } } } extension Published.Publisher: @unchecked Sendable where Output: Sendable {} extension UIImage: @unchecked Sendable {} import Combine import Foundation import class UIKit.UIImage @MainActor final class UserViewState { let id: User.ID @Published private(set) var user: User? @Published private(set) var iconImage: UIImage? init(id: User.ID) { self.id = id } func loadUser() async { do { // User の JSON の取得 let url: URL = .init(string: "https://koherent.org/fake-service/api/user?id=\(id)")! let data = try await downloadData(from: url) // JSON のデコード let user: User = try JSONDecoder().decode(User.self, from: data) // state への反映 self.user = user // アイコン画像の取得 let iconData = try await downloadData(from: user.iconURL) // Data を UIImage に変換 guard let iconImage: UIImage = .init(data: iconData) else { // エラーハンドリング print("The icon image at \(user.iconURL) has an illegal format.") return } // state への反映 self.iconImage = iconImage } catch { // エラーハンドリング print(error) } } }
Avatar
これでも機能しました! @MainActor protocol StateProtocol {} final class UserViewState: StateProtocol { ... }
Avatar
すみません先程聞き逃してしまいましたので、なぜmain thread(receive(on: DispatchQueue.main))に戻す処理をしなくて良いのをもう一度教えてもいいですか?
2:10 PM
Yes
Avatar
griffin-stewie 11/13/2021 2:12 PM
なるほど。冒頭で説明してくれていたコンテキストの話がここでも効いてくるのか。
Avatar
VCのActorがMainActorなので、stateがActorであっても、await後の処理はVCのactorに戻るので、await後は必ずMainということですか
2:15 PM
完全に理解!ありがとうございます。
👍 1
Avatar
何も表示されなくなってしまった 😂
Avatar
何が悪かったのかシミュレーターごとクラッシュしてしまった... 2021-11-13 23:22:28.460902+0900 SwiftZoomin8[66695:7888964] [boringssl] boringssl_metrics_log_metric_block_invoke(144) Failed to log metrics Combine/Publisher+AsyncSequence.swift:65: Fatal error: Received an output without requesting demand 2021-11-13 23:22:28.483897+0900 SwiftZoomin8[66695:7888923] Combine/Publisher+AsyncSequence.swift:65: Fatal error: Received an output without requesting demand Process finished with exit code 0 -> 不要なコードが残ってたのが原因でした(消したら治りました) (edited)
👍 1
Avatar
griffin-stewie 11/13/2021 2:23 PM
willChange だから変更される前のタイミングで通知されるとおっしゃっていましたが、正常に動作しているのはなぜでしょうか?
2:24 PM
なるほど。
Avatar
tochi86 - とち🐹 11/13/2021 2:25 PM
DispatchQueue.main.async で呼んでいるようなものか...
Avatar
Q10 import UIKit import Combine @MainActor final class UserViewController: UIViewController { private let state: UserViewState private let iconImageView: UIImageView = .init() private let nameLabel: UILabel = .init() private var cancellables: Set<AnyCancellable> = [] init(id: User.ID) { self.state = UserViewState(id: id) super.init(nibName: nil, bundle: nil) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() // レイアウト iconImageView.translatesAutoresizingMaskIntoConstraints = false iconImageView.layer.cornerRadius = 40 iconImageView.layer.borderWidth = 4 iconImageView.layer.borderColor = UIColor.systemGray3.cgColor iconImageView.clipsToBounds = true view.addSubview(iconImageView) nameLabel.translatesAutoresizingMaskIntoConstraints = false view.addSubview(nameLabel) NSLayoutConstraint.activate([ iconImageView.widthAnchor.constraint(equalToConstant: 80), iconImageView.heightAnchor.constraint(equalToConstant: 80), iconImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor), iconImageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16), nameLabel.centerXAnchor.constraint(equalTo: iconImageView.centerXAnchor), nameLabel.topAnchor.constraint(equalTo: iconImageView.bottomAnchor, constant: 16), ]) // View への反映 let task = Task { [weak self] in guard let state = self?.state else { return } for await _ in state.objectWillChange.values { guard let self = self else { return } self.nameLabel.text = state.user?.name self.iconImageView.image = state.iconImage } } cancellables.insert(.init { task.cancel() }) } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) Task { await state.loadUser() } } } extension UIImage: @unchecked Sendable {} import Combine import Foundation import class UIKit.UIImage @MainActor final class UserViewState: ObservableObject { let id: User.ID @Published private(set) var user: User? @Published private(set) var iconImage: UIImage? init(id: User.ID) { self.id = id } func loadUser() async { do { // User の JSON の取得 let url: URL = .init(string: "https://koherent.org/fake-service/api/user?id=\(id)")! let data = try await downloadData(from: url) // JSON のデコード let user: User = try JSONDecoder().decode(User.self, from: data) // state への反映 self.user = user // アイコン画像の取得 let iconData = try await downloadData(from: user.iconURL) // Data を UIImage に変換 guard let iconImage: UIImage = .init(data: iconData) else { // エラーハンドリング print("The icon image at \(user.iconURL) has an illegal format.") return } // state への反映 self.iconImage = iconImage } catch { // エラーハンドリング print(error) } } }
Avatar
for 文で要素を使わないのに違和感がある…
2:29 PM
たしかに
Avatar
stateのobjectWillChangeはvalueをawaitで受け取らずにsinkしても挙動としては同じとなるでしょうか?
Avatar
とはいえ ObservableObject にしてまとめて購読すると、コードがスッキリしていいですね✨
Avatar
分かりました、ありがとうございます。
Avatar
tochi86 - とち🐹 11/13/2021 2:33 PM
これでも動きますね。 state.objectWillChange .receive(on: DispatchQueue.main) .sink { [weak self] in guard let self = self else { return } self.nameLabel.text = self.state.user?.name self.iconImageView.image = self.state.iconImage } .store(in: &cancellables) (edited)
👀 1
2:34 PM
ですねw
Avatar
ContentView に↓を追加 NavigationLink { UserView(id: 1234) } label: { Text("User View (SwiftUI)") }
Avatar
tochi86 - とち🐹 11/13/2021 2:45 PM
今日の学び「@MainActorで黙らせる」
💪 6
Avatar
おみごと👏
t_saikou 4
Avatar
tochi86 - とち🐹 11/13/2021 2:49 PM
SwiftUI力が足りない...!
2:51 PM
ありがとうございました!
Avatar
ありがとうございました!
Avatar
Q11のコードも見たいですー
Avatar
# Swift Zoomin' #9 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 考え中。リファクタリング的な内容になりそうです。 # 参加方法 日時: 2022 年 1 月 22 日(土) 21:00- 本ページより参加登録をして下さい。 当日の開始 1 時間程前に参加のための URL を連絡しますので、connpass...
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました!大変勉強になりました 📝
Avatar
ありがとうございました。
Avatar
ありがとうございました!
Avatar
tochi86 - とち🐹 11/13/2021 2:52 PM
次回も申し込みました〜
Avatar
ありがとうございました!
Avatar
ありがとうございました。
Avatar
griffin-stewie 11/13/2021 2:52 PM
ありがとうございます。
Avatar
ありがとうございました!
Avatar
ありがとうございました
Avatar
ありがとうございました!
Avatar
ありがとうございました。
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございましたーすごい充実した内容でした
Avatar
Q11 import SwiftUI @MainActor struct UserView: View { @StateObject private var state: UserViewState init(id: User.ID) { self._state = StateObject(wrappedValue: UserViewState(id: id)) } var body: some View { VStack(spacing: 16) { Group { if let iconImage = state.iconImage { Image(uiImage: iconImage) .resizable() } else { Color.clear } } .frame(width: 80, height: 80) .clipShape(Circle()) .overlay(Circle().stroke(Color(uiColor: .systemGray3), lineWidth: 4)) if let name = state.user?.name { Text(name) } Spacer() } .padding(16) .task { await state.loadUser() } } }
Avatar
tochi86 - とち🐹 11/13/2021 2:53 PM
まずは Other Swift Flagsに-Xfrontend -warn-concurrencyを設定します!
👍 2
Avatar
ありがとうございましたーーー!!!!!
🙏 1
Avatar
21時から、Swift Zoomin' #9 始めます。テキストチャットにここを使います。
Avatar
tochi86 - とち🐹 1/22/2022 11:59 AM
よろしくお願いします
🙌 2
Avatar
初参加です、よろしくお願いします!
👏 2
Avatar
よろしくお願いします🙇‍♂️
👍 2
Avatar
tochi86 - とち🐹 1/22/2022 12:10 PM
ツイートし過ぎると、制限かかるんですか?
Avatar
Contribute to refactoring-challenge/login-challenge development by creating an account on GitHub.
Avatar
Avatar
tochi86 - とち🐹
ツイートし過ぎると、制限かかるんですか?
たしか1時間以内で◯ツイート以上ツイートすると制限がかかる、という制約がありました!
t_naruhodo 1
12:23 PM
UIKit で作られたアプリと SwiftUI で作られたアプリの両方のリファクタリングに取り組むことができる! 👏
😄 1
Avatar
tochi86 - とち🐹 1/22/2022 12:24 PM
僕もIDは値オブジェクトにしてますね。
👍 2
12:26 PM
IDプロトコル良さそうですね、真似してみます!
Avatar
単純にtypealiasでID=Stringと独自型を用意するより何がより良くなるのか気になりました 👀
Avatar
tochi86 - とち🐹 1/22/2022 12:29 PM
typealiasだと、ただの別名を付けているだけなので、例えばUserIDが欲しい引数に、全く関係のない文字列を渡せてしまいます。
👍 5
Avatar
あーそうか、より明示的になるんですね、ありがとうございます!
👍 1
Avatar
tochi86 - とち🐹 1/22/2022 12:32 PM
ミスった時に、エラーですぐわかるようになるのが、メリットですね!
Avatar
この書き方、かっこいいですね 🆒 await dismiss(animated: true)
🆒 2
Avatar
tochi86 - とち🐹 1/22/2022 12:41 PM
なるほど、completionHandlerが呼ばれるまで待っているんですね 👀
Avatar
Xcode13.2、iOS14.8実機では実行時エラーが発生するようです (edited)
12:46 PM
iOS15の実機では実行できました
12:47 PM
共有まで
t_thanks 1
Avatar
tochi86 - とち🐹 1/22/2022 12:47 PM
普段Rxばかり書いているんですが、Combineに挑戦してみようかな
👍 4
Avatar
クローンしてきた後に
  • Missing package product 'APIServices'
  • Missing package product 'Entities' 上記のエラーが出てビルドできなかったんですが、
パスが読み込めてないのかと思って以下を試してみたらビルドできました。 Frameworks, Libraries, and Embedded Content>+ボタン>Add files>ローカルのAPIServices, Entitiesを選択してOpen いなさそうですが同じ現象で困った人いたら試してみてください🙇
t_thanks 2
12:55 PM
こちらで解決しました。
Avatar
特に問題なくビルドできました
Avatar
Avatar
toya108
クローンしてきた後に
  • Missing package product 'APIServices'
  • Missing package product 'Entities' 上記のエラーが出てビルドできなかったんですが、
パスが読み込めてないのかと思って以下を試してみたらビルドできました。 Frameworks, Libraries, and Embedded Content>+ボタン>Add files>ローカルのAPIServices, Entitiesを選択してOpen いなさそうですが同じ現象で困った人いたら試してみてください🙇
自分は上記+XCode再起動で直りました
Avatar
自分の場合は、scheme を選択して Entities と APIServices を先にビルドしたらいけました。
Avatar
僕の場合はキャッシュ系killして、再起動でindexingの終了を待ってからbuildしたらいけました。
Avatar
tochi86 - とち🐹 1/22/2022 12:57 PM
僕はXcodeを再起動したらいけました
Avatar
みなさん、対応方法をありがとうございます🙇‍♂️
Avatar
余談ですが、自分のメイン実機がたまたまiOS14.8だったので、Concurrencyのバックポートだけかなと、プロジェクトのターゲットをいじってしまい、ちゃんと見るとSwiftUIでコンパイルエラーが出てるのにRunできてしまうんですね>Xcode13.2
1:17 PM
ビルドしてもBuild Succeededになるのか。。
1:19 PM
ありがとうございますー
1:20 PM
CIにXcode13.2おいてビルドエラーにならなくて気づかないハマってしまうとかないかなぁと思ってしまいました
1:22 PM
主旨と関係ないですので、すみません。雑談です
Avatar
リファクタリング報告会はいつがよいですか? 1️⃣ 2/5(土)21:00 2️⃣ 2/12(土)21:00 (edited)
1️⃣ 22
2️⃣ 22
Avatar
(2/5はABCが。。。)
Avatar
22:45 に締め切ります!
1:46 PM
リファクタリングの結果報告会は 2/12(土)21:00 に決定しました!
🙇 1
🙆‍♂️ 1
👍 1
1:46 PM
connpass にイベントつくります
1:48 PM
# Swift Zoomin' Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 今回は Swift Zoomin' #9で課題に取り組んだ報告会です。iOSアプリのログイン画面のコードを各自の考える理想の状態にリファクタリングし、どのようにしてクリーンなコードを実現したのかを発表者が説明します。 # 発表内容 5 - 15 分間のプレゼンテー...
Avatar
vcのdismissの話なつかしい。私もずっと昔にそんな話をきいた記憶が蘇ってきました。
1:56 PM
前提環境 iOS 14.4 Xcode 12.1 / Swift 5.3 疑問 私は、UIViewControllerのdismiss(:animated)はシンプルに「自身を閉じる」メソッドだと思い込んでいたのですが...
Avatar
https://developer.apple.com/documentation/uikit/uiviewcontroller/1621505-dismiss
If you present several view controllers in succession, thus building a stack of presented view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack.
Avatar
親側から閉じるとなると、子vcでタスクが終わったら、うまーく親vcにコールバックしないといけないんだったような。面倒なのでよくある今のdismissのコールでもいいよ、って確かそういう話になったような
t_naruhodo 2
1:59 PM
obj-c時代ですね
2:00 PM
循環参照になるので?
2:00 PM
presenting なるほど
Avatar
ありがとうございましたー!時間内にやり切れなかったので
2:03 PM
終わったらpushしてみます!
Avatar
お疲れ様でした!
Avatar
ありがとうございました!
Avatar
ありがとうございましたー!
Avatar
お疲れ様です!
Avatar
presentingViewController?.dismiss(animated: true) と書く方が、 よりリファレンスに忠実なのでしょうかねぇ。
qiitaより。これがお作法ですね
(edited)
Avatar
ありがとうございましたー
Avatar
tochi86 - とち🐹 1/22/2022 2:04 PM
ありがとうございました!
Avatar
おつかれさまですーありがとうございましたー
Avatar
ありがとうございました!
Avatar
ありがとうございました。
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
お疲れさまでした、楽しみながら取り組めました👍
Avatar
ありがとうございました〜
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました! 次のアクション - 各自リファクタリングを進めて頂く(2/12 まで) - forkしたブランチをできたところまで push - 発表していただける方は2/12の報告会で発表! - 普通に参加したい方も参加枠でぜひ!
👍 1
🙇‍♂️ 1
Avatar
親vc.present(子vc, animated:true) // 子を表示する presentingViewController(親vc).dismiss() // 子を閉じる そうか、確かにこの方が APIの対称性がある、揃ってますね
👍 2
Avatar
ちょっと昔話になりますが、やはり iOS 3.2、4.2系 は iPad 専用でしたね (つまり、iOS 3.2、4.2 は iPhone にはインストールできなかった) https://secondflush2.blog.fc2.com/blog-entry-904.html
●iPhoneDeviceiPhoneModel12 mini1212 Pro12 Pro MaxReleased (iPhone)2020.11.132020.10.232020.11.13iOS Ver.Released14.12020.10.20●●●●14.22020.11. 5●●●●14.2.12020.11.19●●●●14.32020.12.14●●●●14.42021. 1.26●●●●14.4.12021. 3. 8●●●●14.4.22021. 3.26●●●●14.52021. 4.26●●●●14.5.12021. 5. 3●●●●14.62021. 5.24●●●●14.72021. 7.19●●●●14.7.12021. 7.26●●●●DeviceiPh...
Avatar
おおお、すっかり覚えてないです。かすかに、言われてみればなんかそんなのあったかもくらいの感じですね。
2:13 PM
Twitterを見て、僕のコーディング見てる人いたんですね。途中で guard の条件反転してバグってハマったりしてたから恥ずかしい😅
t_waiwai 3
Avatar
僕が今日進めた分は fork したリポジトリに push しておきました。 LoginViewController のロジックを VM 的な LoginViewState に切り出しました。次は AuthService を抽象化して APIServices への依存をなくし、単体テストを書いていきたいです。 https://github.com/koher/login-challenge
👀 1
👍 1
koogawa pinned a message to this channel. 2/11/2022 12:36 PM
12:37 PM
# Swift Zoomin' Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 今回は Swift Zoomin' #9で課題に取り組んだ報告会です。iOSアプリのログイン画面のコードを各自の考える理想の状態にリファクタリングし、どのようにしてクリーンなコードを実現したのかを発表者が説明します。 # 発表内容 5 - 15 分間のプレゼンテー...
👍 1
👀 1
👏 2
Avatar
もし可能でしたら、最初の方に発表したいです
🆗 1
Avatar
tochi86 - とち🐹 2/12/2022 12:14 PM
おお〜、ミニアプリ!
Avatar
はじまりました!
12:20 PM
今日の発表順: 1. まつじさん 2. ueshun109さん 3. tochi86さん 4. koherさん
Avatar
コード補完を意識してfileprivateで呼び出しを分けるって面白いです! (edited)
Avatar
tochi86 - とち🐹 2/12/2022 12:20 PM
人が間違う余地を無くすのは良さそう〜
Avatar
ProductionEnvironment付近はこれだけなんですねー。
Avatar
interactorとかpresenter注入を挟み忘れたら動けなくなるとかですか?build()でassertion入れておくとか
Avatar
tochi86 - とち🐹 2/12/2022 12:29 PM
VIPERのコードを初めて見ました 👀
Avatar
なるほどです!build()にも制限をかけている感じですね (edited)
12:31 PM
いいですね
Avatar
tochi86 - とち🐹 2/12/2022 12:35 PM
マジシャンみたいw
12:38 PM
888888
Avatar
続いては 2. ueshun109さん
Avatar
ひとり開発で迷うのめっちゃわかりみ
Avatar
Contribute to ueshun109/login-challenge development by creating an account on GitHub.
Avatar
tochi86 - とち🐹 2/12/2022 12:48 PM
おっ、callAsFunction 使っていますね!
Avatar
griffin-stewie 2/12/2022 12:51 PM
callAsFunctionstatic func の違い(メリ・デリ)がまだ理解できてない
Avatar
tochi86 - とち🐹 2/12/2022 12:52 PM
callAsFunction はインスタンスメソッドなので、例えばインスタンスに他のオブジェクトをDIすることができますね
Avatar
考え方の筋道も含めて、めちゃくちゃ丁寧な発表ですごかったですね👍🏻
Avatar
Avatar
tochi86 - とち🐹
callAsFunction はインスタンスメソッドなので、例えばインスタンスに他のオブジェクトをDIすることができますね
griffin-stewie 2/12/2022 12:53 PM
ありがとうございます。
👍 1
Avatar
tochi86 - とち🐹 2/12/2022 12:55 PM
僕は callAsFunction を使うと、関数定義に一発でコードジャンプできなくなるので、あまり使わない派ですw
Avatar
griffin-stewie 2/12/2022 12:55 PM
それはつらい
Avatar
tochi86 - とち🐹 2/12/2022 12:58 PM
888888
Avatar
つづいては 3. tochi86さん (86はハム!)
Avatar
tochi86 - とち🐹 2/12/2022 1:00 PM
Contribute to tochi86/login-challenge development by creating an account on GitHub.
🙏 1
Avatar
uiStateのおかげですごくコードの可読性が高くていい感じがしました 今回はエラー表示すればOKというケースなんですけれど、応答が必要なダイアログで多重にダイアログが出るケースってないんでしょうか?
Avatar
griffin-stewie 2/12/2022 1:11 PM
Google さんはこのあたりが親切だなぁ。
Avatar
Android界隈は公式が推奨アーキテクチャを出してくれるおかげでそれに従ってる案件間の移動がやりやすいというのは感じますね
1:18 PM
ちゃんと状態を作りこめば大丈夫そうですね、エラーアラートを出した、未応答、応答後、みたいな形で
Avatar
つづいては 4. koherさん
1:26 PM
Contribute to koher/login-challenge development by creating an account on GitHub.
Avatar
guard case 面白い
Avatar
状態遷移をメソッドにすることで仕様が完全にコードに落とし込まれてる感じがすごいですね…!
Avatar
状態遷移をメソッドで表すの参考になる 👀
Avatar
griffin-stewie 2/12/2022 1:41 PM
二段構えになっているのいいなぁ。外向きとして、ViewState の利用側は単純にどうすればいいかが分かるフラグだけみればいい。内向きとして、状態遷移を知りたい場合は ViewState の中を見ればサクッとわかる。と。 (edited)
Avatar
細かい点ですけどif isLoadingUser { return }guardを使って書く派なのですがどっちがわかりやすいんでしょうか? (edited)
Avatar
griffin-stewie 2/12/2022 1:48 PM
アーリーイグジット はできるだけ guard で書きたい(絶対にその先のコードに進まない条件があることが明確になるから)けど、二重否定みたいな表現になってしまってちょっとだけ脳みそを余計に使うのはイヤだなぁと迷い続けてる。( !list.isEmpty じゃなく list.notEmpty 的な表現にしたい気持ち。好みの問題だとは思う。) (edited)
Avatar
二重否定みたいな表現になってしまってちょっとだけ脳みそを余計に使うのはイヤだなぁ
1:50 PM
とてもわかります。。
Avatar
tochi86 - とち🐹 2/12/2022 1:50 PM
わかります。。
1:52 PM
クリーンアーキテクチャ、この同心円の図の通りに実装する必要はないですが、その原則は常に意識しておきたいです。
t_sorena 1
Avatar
XCTContext.runActivity()、ActivityとActivityの間で状態を維持してしまうのが苦手です。(setup/teardownをsuccessとfailのテストの間で呼びたくなって)
Avatar
tochi86 - とち🐹 2/12/2022 2:03 PM
Quickの context の中で beforeEach を書くようなことをしたいんですね。
Avatar
それです!Activity同士が基本連続せず独立している単位になることが多く、リセットを挟みたいと思い (edited)
Avatar
tochi86 - とち🐹 2/12/2022 2:06 PM
たしかに、不便ですね。。
Avatar
griffin-stewie 2/12/2022 2:07 PM
宣言的UIをきっちり使えていればロジックをテストできていればある程度 UI のテストもした事に限りなく等しくなるのか
Avatar
tochi86 - とち🐹 2/12/2022 2:08 PM
Swift Concurrencyを利用したコードの単体テストを書くノウハウをどんどん溜めていきたい...!
Avatar
ちょっと思いついたレベルの質問なんですけれど、stateをcomputed propertyにする箇所はguard caseよりもswitchの方が新しいstateに対応しやすいのかな?と思ったんですけれど、guardの方が可読性高いしテストで担保できるからOKみたいな感じなんでしょうか?
Avatar
if let error = error { // 早期脱出 }
2:12 PM
guard error == nil else { let error = error! // 早期脱出 } (edited)
Avatar
# Swift Zoomin' #9 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 考え中。 # 参加方法 日時: 2022 年 4 月 23 日(土) 21:00- 本ページより参加登録をして下さい。 当日の開始 1 時間程前に参加のための URL を連絡しますので、connpassからのメールを受信できる状態にしておいて...
Avatar
お、SwiftUIなのにPreview使ってないんですね。
2:22 PM
1段かまして、なるほどー
2:22 PM
なりますね!
2:22 PM
なるなる。
Avatar
tochi86 - とち🐹 2/12/2022 2:22 PM
やっぱりそうなんですね
Avatar
Preview本当に壊れて諦めてます........ (edited)
Avatar
griffin-stewie 2/12/2022 2:23 PM
Preview 系(SwiftUI でも UIKit でも)しょっちゅうぶっ壊れてストレスだからあまり使わないようにしてる
Avatar
ぶっ壊れるわかります
Avatar
そうなんですよね。Swift ver1, ver2の頃のDerived?の消し消し味を感じます。
Avatar
griffin-stewie 2/12/2022 2:23 PM
すなおにシミュレータをビルドした方が圧倒的に早い。M1 Max ならなおさら。
t_kusa 4
t_tashikani 1
Avatar
Avatar
griffin-stewie
すなおにシミュレータをビルドした方が圧倒的に早い。M1 Max ならなおさら。
確かにそうなんですよねー
Avatar
ありがとうございましたー!
Avatar
tochi86 - とち🐹 2/12/2022 2:24 PM
ありがとうございました、楽しかったです!
Avatar
ありがとうございました!
Avatar
ありがとうございました。
Avatar
ありがとうございました!
Avatar
griffin-stewie 2/12/2022 2:24 PM
ありがとうございました~
Avatar
ありがとうございました!
Avatar
ありがとうございましたー
Avatar
ありがとうございました
Avatar
Concurrencyの使っている範囲とかもコード読ませていただけてすごい面白かったですありがとうございましたー!
Avatar
ありがとうございました!👏🏻
Avatar
ありがとうございました
Avatar
ありがとうございました!楽しかったです〜👏
Avatar
griffin-stewie 2/12/2022 2:26 PM
プレビューぶっ壊れる問題は、モジュールを分けて、モジュール毎に実行できるプロジェクトを内部で用意してシミュレータ実行するのが結果的に早そうだなとも思った。(Cookpad さんのミニアプリスタイル)
t_naruhodo 2
Avatar
ご参加いただきありがとうございました! (最後にプレビューぶっ壊れる問題の話ができてよかったです😂
😂 1
Avatar
僕は個人プロジェクトは細かくPreviewしていってます。
Avatar
2, 3 日前に、 Preview ぶっ壊れるから画面確認するためのカタログアプリ作るかという話を社内でしたとこでした😂
👍🏻 1
Avatar
tochi86 - とち🐹 2/12/2022 2:31 PM
Flutterのホットリロードが便利すぎるので、SwiftUIのPreviewにも期待しているんですが... 😭
👍🏻 1
Avatar
動いてるときは便利なんですけどね。レイアウト微調整するときとか。問題は大抵動かないことなんですが😇
👍🏻 1
Avatar
本日21:00〜開催します! https://swift-tweets.connpass.com/event/239584/
# Swift Zoomin' #10 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 Swift 5.6 の any 、 Swift 5.7 の some と、 Swift らしいプロトコルの使い方について、ライブコーディングで実演しながら説明します。 # 参加方法 日時: 2022 年 4 月 23 日(土) 21:0...
👍🏻 4
👏 2
Avatar
ZoomのURL、メールでもお送りしてますが、こちらにも貼っておきます。 https://us02web.zoom.us/j/81955550318?pwd=Y05BdHdYRnBEdjVUeGNrU1RPa3FuQT09 Meeting ID: 819 5555 0318 Passcode: 923749
Avatar
わいわい
🙌 8
Avatar
# Swift Zoomin' #11 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 未定 # 参加方法 日時: 2022 年 7 月 16 日(土) 21:00- 本ページより参加登録をして下さい。 当日の開始 1 時間程前に参加のための URL を連絡しますので、connpassからのメールを受信できる状態にしておいてく...
t_waiwai 5
Avatar
Xcodeに文章が、、初めて見ました。こういうの。良いですねー (edited)
Avatar
Xcodeのウィンドウだけ配信してる状態でもpdfをプレビューできるからスライド出せるのかw
12:09 PM
僕は問題なく見えてます
Avatar
見やすいですー
12:14 PM
1と2面白い!
Avatar
ワンニャン
Avatar
にゃるほど!
Avatar
animal は何バイト?
1️⃣ 1
2️⃣ 3
3️⃣ 8
4️⃣ 9
Avatar
1️⃣ 1バイト 2️⃣ 4バイト 3️⃣ 8バイト
12:18 PM
4️⃣ 40バイト
Avatar
metatypeとPWTですね
12:23 PM
protocol witness table
Avatar
Yusuke Hosonuma 4/23/2022 12:24 PM
In this advanced session, find out how structs, classes, protocols, and generics are implemented in Swift. Learn about their relative...
👀 2
Avatar
速度はよくなるけれど、バイナリサイズ的にはマイナスな気がしますね
Avatar
JavaはGenericsがない時代との互換のために型消去されてObject型で扱われるんじゃないかな~
👍🏻 1
12:48 PM
decodable()が型を渡す必要性があるのもその辺なのかな
Avatar
最初の実験でやっていたような MemoryLayout.size(ofValue:)-> some Animal に対して使うと、動的に変化しますね。
👍🏻 4
12:59 PM
ありがとうございました。
Avatar
このときSequenceの中のIteratorProtocolをIteratorProtocol<Element>って簡単に書けるようにはならないのでしょうか?
Avatar
omochimetaru 4/23/2022 1:10 PM
後からopaque化するとABI互換性が壊れそうだけど治せるのかなあ
1:11 PM
ソース互換性も壊れるかw
Avatar
kashihararara 4/23/2022 1:11 PM
some が使えない現在は標準ライブラリ内で様々な具体的な型を羅列しているとかなんですか?
t_desudesu 1
Avatar
標準ライブラリの中に同じようなコードを生成するpythonスクリプトがあったような…
Avatar
kashihararara 4/23/2022 1:12 PM
ありがとうございます。なるほど。
Avatar
(はー、そうなんだ)
Avatar
omochimetaru 4/23/2022 1:13 PM
みえてます
Avatar
見えてます
Avatar
omochimetaru 4/23/2022 1:13 PM
CombineのPublisherみたいな雪だるま
Avatar
Combineほんとやばい型が作られますよね
Avatar
Swift 6 で any 指定が必須になると使ってるライブラリほぼ全てを回って any を貼る作業が起きるってことになりますよね?
t_desudesu 1
1:15 PM
なるほどありがとうございます!
Avatar
omochimetaru 4/23/2022 1:15 PM
マイグレーターのバグを踏んでぶっ壊れたところを治す作業はあるかもしれん
😂 3
Avatar
griffin-stewie 4/23/2022 1:15 PM
今日の話と AnyPublisher みたいな型消去は絡む話なんだろうか?まったく無関係な話なんだろうか?
Avatar
メソッドの返り値にもany Animalが書けるようになるんでしょうか?それは今でもできるんです?
Avatar
Avatar
griffin-stewie
今日の話と AnyPublisher みたいな型消去は絡む話なんだろうか?まったく無関係な話なんだろうか?
omochimetaru 4/23/2022 1:17 PM
関係あって、type erasureを手書きする必要が無くなります
👍🏻 2
Avatar
Avatar
omochimetaru
関係あって、type erasureを手書きする必要が無くなります
griffin-stewie 4/23/2022 1:18 PM
ありがとうございます。そうなんですね。それはうれしいですね。
Avatar
端的な見解ですが、some Pが改良かつ充実されて結局any P(換言するとexistential)の出番がほとんど出なくなりそうな印象ですがあってますかね?
Avatar
griffin-stewie 4/23/2022 1:19 PM
さっきの let foo = animal.foo() の foo が Any 型だと、foo 変数に対していろいろコードを書きたいときに補完が効かなくて面倒くさそう。as! Int とかしないとダメなのかな? (edited)
Avatar
any P(existential)の出番がvar: any P = condition ? A() : B() くらいかな
Avatar
今のSE-0309 で associatedType つきの Protocol をフィールドに入れれるから型消去がいらなくなるってことですかね? (AnyAnimal を用意する必要がいらなくなる)
Avatar
Avatar
dsxsxsxs
any P(existential)の出番がvar: any P = condition ? A() : B() くらいかな
omochimetaru 4/23/2022 1:21 PM
今日の話で出てきた例だと、↓この2つの使い分けは残ると思います。 func fooAny() -> [any Animal] func fooSome() -> [some Animal] fooSomeは要素がすべて同じ型になるけど、fooAnyは一個一個バラバラ。 (edited)
👍🏻 7
t_thanks 1
Avatar
Avatar
griffin-stewie
ありがとうございます。そうなんですね。それはうれしいですね。
griffin-stewie 4/23/2022 1:23 PM
koher さんの説明でさらに理解が深まった!ありがとうございます。 (edited)
Avatar
Avatar
omochimetaru
今日の話で出てきた例だと、↓この2つの使い分けは残ると思います。 func fooAny() -> [any Animal] func fooSome() -> [some Animal] fooSomeは要素がすべて同じ型になるけど、fooAnyは一個一個バラバラ。 (edited)
なるほどです。Pを型として扱う時は今までと変わらないで良く、ですね (edited)
Avatar
kashihararara 4/23/2022 1:28 PM
余談ですが、↑の例のような Cat も Dog も同じ配列で扱いたいけど func fooAny() -> [any Animal] だと動的ディスパッチでパフォーマンスに難がある場合に enum associated values で無理やり 静的ディスパッチにしちゃうアイデアがあったりします
👍🏻 2
1:28 PM
Rust ですがイメージこんなかんじですhttps://qiita.com/carrotflakes/items/896ce7f49931c64a2954
Avatar
(「Bool.random() ? A : B 」、良いなー)
t_wakaru 4
Avatar
AnyView でラップみたいなのはそれがなかったころの話なのかな
Avatar
kashihararara 4/23/2022 1:36 PM
あってます!
Avatar
Avatar
shimastripe
今のSE-0309 で associatedType つきの Protocol をフィールドに入れれるから型消去がいらなくなるってことですかね? (AnyAnimal を用意する必要がいらなくなる)
omochimetaru 4/23/2022 1:36 PM
SE-0309は any Sequence が書けるようになりますが、パラメータ指定ができないので、type erasureのユースケースの代用には不足です。 SE-0353で any Sequence<Int> とパラメータ指定もできるようになって、代用品として完成します。 (edited)
Avatar
よくある依存逆転なんとかで大体existentialで注入しているけど、今後はopaqueで書いて良さそうですね。そういう場合はsomeのできないことにぶつからないはずなので
Avatar
Avatar
omochimetaru
SE-0309は any Sequence が書けるようになりますが、パラメータ指定ができないので、type erasureのユースケースの代用には不足です。 SE-0353で any Sequence<Int> とパラメータ指定もできるようになって、代用品として完成します。 (edited)
!!ありがとうございます。たしかにたしかに、なるほどです。 (edited)
1:38 PM
便利になってすごく良いですね
👌 1
Avatar
griffin-stewie 4/23/2022 1:54 PM
理解が深まりました。ありがとうございました。
Avatar
めちゃ話が分かりやすかったです…!
1:56 PM
# Swift Zoomin' #11 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 未定 # 参加方法 日時: 2022 年 7 月 16 日(土) 21:00- 本ページより参加登録をして下さい。 当日の開始 1 時間程前に参加のための URL を連絡しますので、connpassからのメールを受信できる状態にしておいてく...
Avatar
ライブコーディング、面白かったです!
Avatar
ありがとうございました。
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました!!
Avatar
ありがとうございました!!!
Avatar
ありがとうございました!!
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
any 導入の経緯もわかってすごく勉強になりました。ありがとうございました!!おもちさんもありがとうございます。
🙌 1
Avatar
ありがとうございました!
Avatar
ありがとうございました!!
👍🏻 1
Avatar
ありがとうございました!!!!!!!!
Avatar
griffin-stewie 4/23/2022 1:59 PM
おもちさんもありがとうございました 🙇
😆 1
Avatar
今日参加できなかったのですが、any はできる限り使わないのが望ましいですよね?? 配列のポリモーフィズムでいろんな型を入れたいときくらいかなと思っています
Avatar
Avatar
uhooi
今日参加できなかったのですが、any はできる限り使わないのが望ましいですよね?? 配列のポリモーフィズムでいろんな型を入れたいときくらいかなと思っています
any を使うべきよくあるケースはそれですね。あとは、前に uhooi さんからツイートでいただいた相互参照になるようなケースは僕の中で答えが出てないんですが、 any を使わざるを得ないかもしれません。後は、基本は some で考えてみて、 any がないと無理そうであれば any という考え方がいいんじゃないかと考えています。
👍 1
Avatar
遅くなりましたが、ありがとうございました!勉強になりました!!
🙂 1
Avatar
Avatar
koher
any を使うべきよくあるケースはそれですね。あとは、前に uhooi さんからツイートでいただいた相互参照になるようなケースは僕の中で答えが出てないんですが、 any を使わざるを得ないかもしれません。後は、基本は some で考えてみて、 any がないと無理そうであれば any という考え方がいいんじゃないかと考えています。
ありがとうございます、自分の認識通りだったのでよかったです! 相互参照は any を使わざるを得ませんよね、、自分はそうしています。
Avatar
Swift Zoomin'のアーカイブはYoutubeチャンネル上にあるもので全てでしょうか。 いくつかの回が抜けており、どこかにあるなら見たいなあと思いまして。 https://www.youtube.com/channel/UCNR0oDJWIGRGt6GpMvf9TLg
Avatar
Avatar
IKEH
Swift Zoomin'のアーカイブはYoutubeチャンネル上にあるもので全てでしょうか。 いくつかの回が抜けており、どこかにあるなら見たいなあと思いまして。 https://www.youtube.com/channel/UCNR0oDJWIGRGt6GpMvf9TLg
すみません、一部編集が必要になる回などがあり、それらは手を付けられておらずアップロードできていません。とりあえず #9 分を早めにアップロードしたいと考えています。
👍 1
Avatar
Avatar
koher
すみません、一部編集が必要になる回などがあり、それらは手を付けられておらずアップロードできていません。とりあえず #9 分を早めにアップロードしたいと考えています。
ありがとうございます、楽しみに待っています! 前回のany/someの話が面白く(今更ながら)過去のものを見させてもらっています 🙇‍♂️
iine 1
Avatar
Avatar
IKEH
ありがとうございます、楽しみに待っています! 前回のany/someの話が面白く(今更ながら)過去のものを見させてもらっています 🙇‍♂️
ありがとうございます!アップロードしたら、ここでも報告させていただきます!
😊 2
Avatar
夜分遅くに失礼します。 https://github.com/koher/login-challenge-slides 以前のswift-zoominを復習していてどう解決すべきかわからず気になりご意見をお聞きできないでしょうか? 型パラメータのInjectionを用いて、@StateObject private var state: HomeViewState<UserService> ObservableObject を用意すると、Usecase層のモックが非常にやりやすくてすごく良かったのですが、 例えばViewのスナップショットテストを実現したいと思ったときに、SwiftUIのViewやUIViewControllerでこのObservableObjectのUserServiceをモックしようとすると、ViewのPropertyは具象のUserServiceに依存してしまっていて、モックが困難に感じます。 現状Propertyに型パラメータをProtocolのまま持たせることはできないと思っているのですが、Swift@5.7のanyなどが入るとこういった問題を解決できたりするのでしょうか? (edited)
Avatar
Avatar
shimastripe
夜分遅くに失礼します。 https://github.com/koher/login-challenge-slides 以前のswift-zoominを復習していてどう解決すべきかわからず気になりご意見をお聞きできないでしょうか? 型パラメータのInjectionを用いて、@StateObject private var state: HomeViewState<UserService> ObservableObject を用意すると、Usecase層のモックが非常にやりやすくてすごく良かったのですが、 例えばViewのスナップショットテストを実現したいと思ったときに、SwiftUIのViewやUIViewControllerでこのObservableObjectのUserServiceをモックしようとすると、ViewのPropertyは具象のUserServiceに依存してしまっていて、モックが困難に感じます。 現状Propertyに型パラメータをProtocolのまま持たせることはできないと思っているのですが、Swift@5.7のanyなどが入るとこういった問題を解決できたりするのでしょうか? (edited)
僕は次の二つの方法のいずれかを用いています(スナップショットテストはしていませんが、 Xcode Preview のためにやっています)。 ① 一つは、 @StateObject を保持する View とレイアウトする View を分離し、前者が後者を利用する形にすることです。 // state 保持用の View とレイアウト用の View を分離する例 struct FooStateView: View { @StateObject private var state: FooViewState<FooService> ... var body: some View { FooView(bar: state.bar, baz: $state.baz) } } struct FooView: View { let bar: Int @Binding var baz: String ... } こうしておけば state とは独立に FooView の任意の状態を簡単に実現できるので、スナップショットテストやプレビューのためのモックが必要なくなります。↑は SwiftUI の例ですが、UIKit の場合でも、外から渡された状態を再現するだけの VC と、 state を保持して状態を伝えるだけの VC とに分離することで、同様のことが実現可能です。 ② もう一つは、公開する state のプロパティをすべて @Publsihed public var にしてしまうことです。そうすれば、スナップショットテストやプレビューの際に、任意の状態の state を簡単に作れます。 UserService 等にはダミーのテスト用実装を渡して何の仕事もさせないようにします。なお、 computed property の場合は setter を作れないので、↓のように republish する必要が生じます。 // computed property の代わりに republish が必要になる例 // Before @MainActor public final class FooViewState<FooService: FooServiceProtocol>: ObserbalbleObject { @Published public var baz: String = "" public var isQux: Bool { baz.isEmpty } ... } // After @MainActor public final class FooViewState<FooService: FooServiceProtocol>: ObserbalbleObject { @Published public var baz: String = "" @Published public var isQux: Bool = false ... init(...) { ... $baz.map(\.isEmpty).assign(to: &$isQux) // republish } ... } ①②とも一長一短で、①は実装が冗長になりがちです。②は外から触っていいものといけないもの(本来 private(set) であるべきもの)の区別が付きづらいです。テスト以外のケースで、本来メソッドを通して状態を変更しなければならないプロパティを setter で変更してしまうと、 state の状態を壊してしまう可能性があります。 @testable import を前提に、 internal(set) にするのも良いかもしれません。
🙇‍♂️ 1
Avatar
Avatar
koher
僕は次の二つの方法のいずれかを用いています(スナップショットテストはしていませんが、 Xcode Preview のためにやっています)。 ① 一つは、 @StateObject を保持する View とレイアウトする View を分離し、前者が後者を利用する形にすることです。 // state 保持用の View とレイアウト用の View を分離する例 struct FooStateView: View { @StateObject private var state: FooViewState<FooService> ... var body: some View { FooView(bar: state.bar, baz: $state.baz) } } struct FooView: View { let bar: Int @Binding var baz: String ... } こうしておけば state とは独立に FooView の任意の状態を簡単に実現できるので、スナップショットテストやプレビューのためのモックが必要なくなります。↑は SwiftUI の例ですが、UIKit の場合でも、外から渡された状態を再現するだけの VC と、 state を保持して状態を伝えるだけの VC とに分離することで、同様のことが実現可能です。 ② もう一つは、公開する state のプロパティをすべて @Publsihed public var にしてしまうことです。そうすれば、スナップショットテストやプレビューの際に、任意の状態の state を簡単に作れます。 UserService 等にはダミーのテスト用実装を渡して何の仕事もさせないようにします。なお、 computed property の場合は setter を作れないので、↓のように republish する必要が生じます。 // computed property の代わりに republish が必要になる例 // Before @MainActor public final class FooViewState<FooService: FooServiceProtocol>: ObserbalbleObject { @Published public var baz: String = "" public var isQux: Bool { baz.isEmpty } ... } // After @MainActor public final class FooViewState<FooService: FooServiceProtocol>: ObserbalbleObject { @Published public var baz: String = "" @Published public var isQux: Bool = false ... init(...) { ... $baz.map(\.isEmpty).assign(to: &$isQux) // republish } ... } ①②とも一長一短で、①は実装が冗長になりがちです。②は外から触っていいものといけないもの(本来 private(set) であるべきもの)の区別が付きづらいです。テスト以外のケースで、本来メソッドを通して状態を変更しなければならないプロパティを setter で変更してしまうと、 state の状態を壊してしまう可能性があります。 @testable import を前提に、 internal(set) にするのも良いかもしれません。
なるほどありがとうございます!!特に internal(set) で対処するのが自分のユースケースにピッタリ合っていて非常に勉強になります 🙇‍♂️
🙂 1
Avatar
今日21時から Swift Zoomin' でこのチャンネルを使います。
👍 3
9:28 AM
# Swift Zoomin' #11 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 「SwiftUIを支えるSwiftの言語機能」について話します。KeyPath Member Lookup, Result Builder, Property Wapper, Opaque Typeなどの言語機能と、それらがSwiftUIでどう機能...
9:29 AM
今週末のSwift Zoomin https://t.co/FpbZ5503Yd ですが、「SwiftUIを支えるSwiftの言語機能」について話します。KeyPath Member Lookup, Result Builder, Property Wapper, Opaque Typeなどの言語機能と、それらがSwiftUIでどう機能しているか実演しながら説明します。 #swiftzoomin
Avatar
griffin-stewie 7/16/2022 12:01 PM
よろしくお願いします。
Avatar
# Swift Zoomin' #12 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 未定 # 参加方法 日時: 2022 年 10 月 29 日(土) 21:00- 本ページより参加登録をして下さい。 当日の開始 1 時間程前に参加のための URL を連絡しますので、connpassからのメールを受信できる状態にしておいて...
👍 1
Avatar
こんな感じで見えてますね
👍 2
Avatar
griffin-stewie 7/16/2022 12:18 PM
koher さんの声とビルド時の音のバランスがちょっとわるくてビルド時の音が大きく感じて毎回びっくりする。
👌 1
12:21 PM
聞こえます。けど小さくなりました。
12:21 PM
ありがとうございました。
👍 1
Avatar
tochi86 - とち🐹 7/16/2022 12:29 PM
なるほどー
Avatar
30分遅れで参加…! 🙏
12:32 PM
やっべアンミュートでした、、(多分音は入ってないはず)
12:32 PM
ビルド音かわいいw
Avatar
音は入ってないっす 👍
Avatar
よかた
12:35 PM
ビルド成功と失敗で音が違うのか
Avatar
griffin-stewie 7/16/2022 12:35 PM
そこで Dynamic Member Lookup
Avatar
(意図せずアンミュート状態で生活音が入ってしまっていると判断した場合はホスト権限でミュートにします 👍
🙏 1
👍 2
Avatar
@dynamicMemberLookup enum JSON: ExpressibleByDictionaryLiteral, ExpressibleByArrayLiteral, ExpressibleByStringLiteral, ExpressibleByIntegerLiteral, ExpressibleByFloatLiteral, ExpressibleByBooleanLiteral, ExpressibleByNilLiteral, CustomStringConvertible { case object([String: JSON]) case array([JSON]) case string(String) case number(Double) case boolean(Bool) case null init(dictionaryLiteral elements: (String, JSON)...) { self = .object([String: JSON](elements) { a, b in a }) } init(arrayLiteral elements: JSON...) { self = .array(elements) } init(stringLiteral value: String) { self = .string(value) } init(integerLiteral value: Int) { self = .number(Double(value)) } init(floatLiteral value: Double) { self = .number(value) } init(booleanLiteral value: Bool) { self = .boolean(value) } init(nilLiteral: ()) { self = .null } subscript(index: Int) -> JSON { guard case .array(let elements) = self else { preconditionFailure() } return elements[index] } subscript<Key: StringProtocol>(key: Key) -> JSON { guard case .object(let members) = self else { preconditionFailure() } return members[String(key)] ?? .null } subscript(dynamicMember key: String) -> JSON { self[key] } var description: String { switch self { case .object(let members): return members.description case .array(let elements): return elements.description case .string(let value): return value case .number(let value): return value.description case .boolean(let value): return value.description case .null: return "null" } } } // [2, 3.0, "ABC", null] // { "x": 2, "y": { "z": true }} } let a: JSON = [2, 3.0, "ABC", nil] let b: JSON = ["x": 2, "y": ["z": true]] print(a[0]) print(a) print(b["y"]["z"]) print(b.y.z)
👍🏻 8
swift 2
Avatar
griffin-stewie 7/16/2022 12:39 PM
パフォーマンスはほんのちょっとだけ悪くなりますか?
12:39 PM
普通のサブスクリプトと比べてです。
12:40 PM
hai.
12:40 PM
ありがとうございました
Avatar
(dynamicMember key: String)をつくってしまうと、ドットの補完がなんでもきくようになってしまいますか?
12:41 PM
なるほどです!
12:41 PM
思わぬタイポでコンパイル通ってしまうときもあると
Avatar
tochi86 - とち🐹 7/16/2022 12:41 PM
呼び出し元だけ見るとコンパイルエラーしてくれそうに見えますよね
Avatar
griffin-stewie 7/16/2022 12:41 PM
だから、Dynamic Member Lookup 使ってるコードを使ってると補完が効かなくて書きにくいですよねw
t_naruhodo 1
12:47 PM
KeyPath は function として使えるのは map とかするときに便利ですよね。
Avatar
WritableKeyPathは推論で書けるショートハンドな書き方はない感じですかね? \User.age
Avatar
griffin-stewie 7/16/2022 12:49 PM
サブスクリプトも KeyPath として書けるのか。しらなかった....
Avatar
見えます!!
12:52 PM
おーーー
Avatar
Option 押しながらクリックして推論した型が見えるの知らなかった
Avatar
ReferenceWritableKeyPathはstructにも効きますか?
Avatar
ありがとうございます!
Avatar
ありがとうございます!
Avatar
KeyPath struct User { var name: String var age: Int } var user: User = .init(name: "Swift", age: 8) //print(user.age) //user.age = 9 let keyPath: WritableKeyPath<User, Int> = \.age let keyPath2 = \User.age print(user[keyPath: keyPath]) user[keyPath: keyPath] = 9 print(user[keyPath: keyPath]) print(user.age) var userGroups: [String: [User]] = ["id0": [user]] print(userGroups["id0"]?[0].age as Any) let keyPath3: KeyPath<[String: [User]], Int?> = \.["id0"]?[0].age print(userGroups[keyPath: keyPath3] as Any) // AnyKeyPath // PartialKeyPath<Root> // KeyPath<Root, Value> // WritableKeyPath<Root, Value> // ReferenceWritableKeyPath<Root, Value>
Avatar
tochi86 - とち🐹 7/16/2022 12:58 PM
Swift5.1はXcode11から
Avatar
griffin-stewie 7/16/2022 1:02 PM
Writable じゃないから?
1:03 PM
すげー
Avatar
tochi86 - とち🐹 7/16/2022 1:04 PM
おおー!
Avatar
griffin-stewie 7/16/2022 1:04 PM
この場合は入力補完は効くのかな?
👍 1
Avatar
Valueがclassだった場合はどうなります?
Avatar
おーーーーーーーー
1:06 PM
さっきStringでタイポを気にしていたら、KeyPathが使えて全然いいですね。すごい (edited)
Avatar
KeyPath Member Lookup struct User { var name: String var age: Int } @dynamicMemberLookup final class Box<Value> { var value: Value init(_ value: Value) { self.value = value } subscript<T>(dynamicMember keyPath: WritableKeyPath<Value, T>) -> T { get { value[keyPath: keyPath] } set { value[keyPath: keyPath] = newValue } } } //var a: User = .init(name: "Swift", age: 8) //var b = a //a.age = 9 //print(a.age) //print(b.age) let a: Box<User> = .init(User(name: "Swift", age: 8)) let b = a a.age = 9 print(a.age) print(b.age)
Avatar
Xcode のバージョンとか…?(わからないけど)
1:14 PM
いや普通にプロパティラッパーはトップレベルで使えないのかな
Avatar
Swift 5.4 で Function 内の Local Variable 内で使えるようになって、5.5 から 引数パラメータにも使えるようになったからトップレベルはまだできないように見えますね......?
👍🏻 1
Avatar
tochi86 - とち🐹 7/16/2022 1:19 PM
not yet supported と書いてあったから、将来サポートされるのかな...?
Avatar
それ思いました!
Avatar
@Ref var a = User( get: ..., set: ...) って書き方もできますか?
Avatar
griffin-stewie 7/16/2022 1:21 PM
$ のやつだったっけ。 < projectedValue
Avatar
ありがとうございました。よくわかりました。
Avatar
Property Wrapper struct User: Equatable { var name: String var age: Int } @propertyWrapper final class Box<Value> { var wrappedValue: Value init(wrappedValue value: Value) { self.wrappedValue = value } var projectedValue: Ref<Value> { Ref<Value>( get: { self.wrappedValue }, set: { newValue in self.wrappedValue = newValue} ) } } @propertyWrapper struct Ref<Value> { let get: () -> Value let set: (Value) -> Void var wrappedValue: Value { get { get() } set { set(newValue) } } } do { var a: User = .init(name: "Swift", age: 8) //var b: Ref<User> = .init(get: { a }, set: { newValue in a = newValue }) @Ref var b: User _b = .init(get: { a }, set: { newValue in a = newValue }) b.age = 9 print(a.age) print(b.age) print(a == b) //print(b.wrappedValue.age) @Box var c: User = .init(name: "Swift", age: 8) @Ref var d: User _d = $c }
👍🏻 1
Avatar
濃密すぎてあっという間です
Avatar
(環境音みたいなのが聴こえたので、いったんkoherさん以外のマイクをミュートにさせていただきました)
👍🏻 1
Avatar
tochi86 - とち🐹 7/16/2022 1:30 PM
This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - swift-evolution/0258-property-wrappers.md at main · apple/swift-evolution
👍 4
Avatar
Writableにする必要がありそうですかね? (edited)
Avatar
tochi86 - とち🐹 7/16/2022 1:40 PM
ほぉ〜、そうなっていたんですね!
Avatar
あとで復習します……
Avatar
griffin-stewie 7/16/2022 1:42 PM
うまいことできてるなぁ
Avatar
以前OpaqueResultType でBlockを書けるようにした話もすごいなってなりましたけどこれもすごく面白いです。 (edited)
Avatar
よくわからずに $使ってました・・!
Avatar
KeyPath Member Lookup と Property Wrapper の組み合わせ @propertyWrapper @dynamicMemberLookup struct Ref<Value> { let get: () -> Value let set: (Value) -> Void var wrappedValue: Value { get { get() } nonmutating set { set(newValue) } } subscript<T>(dynamicMember keyPath: WritableKeyPath<Value, T>) -> Ref<T> { Ref<T>( get: { wrappedValue[keyPath: keyPath] }, set: { newValue in wrappedValue[keyPath: keyPath] = newValue } ) } }
Avatar
こういうUIの作り方って他にはないですよね?むちゃくちゃ先進的なんでしょうか?
Avatar
tochi86 - とち🐹 7/16/2022 1:44 PM
$user.age に初見では気持ち悪さを感じましたが、腑に落ちました
t_wakaru 3
Avatar
なるほど Binding<User>
Avatar
Binding<Int>になるの、Binding がExpressibleByIntLiteralを準拠してたりするんでしょうか
Avatar
bindingはfunctorとして捉えていいですか。subscriptがmapに見えて、propertyが取れる限り無限にmapしていける感じ (edited)
t_tashikani 1
Avatar
griffin-stewie 7/16/2022 1:47 PM
ViewThatFits はちょっとニュアンスが近いことをやってくれている印象があります
Avatar
ありがとうございました。
Avatar
SwiftUI のために Swift の言語仕様が進化した感ありますよね
Avatar
tochi86 - とち🐹 7/16/2022 1:48 PM
値型の世界で宣言的UIを使いやすいように実装したら、こんな感じになったのかな
Avatar
$user : Binding<User>
1:49 PM
$user.age : Binding<Int>
Avatar
なるほどです。Bindingの実装なんですね。
Avatar
確かに、ありがとうございます
Avatar
SwiftUI で if 文挟めるの、なんでかめちゃ気になっていた…! Kotlin みたいに式だったらわかるんだけど
1:52 PM
なるほど、ここで @resultBuilder なのか
1:57 PM
@resultBuilder は改行が意味を持つってこと…?
1:58 PM
改行というか、1つ1つがステートメントになるのか
Avatar
tochi86 - とち🐹 7/16/2022 2:04 PM
This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - swift-evolution/0289-result-builders.md at main · apple/swift-evolution
Avatar
Result Builder @resultBuilder struct ArrayBuilder<Element> { static func buildExpression(_ expression: Element) -> [Element] { // 2 -> [2] [expression] } static func buildBlock(_ components: [Element]...) -> [Element] { // [[2, 3, 4], [5, 6]] -> [2, 3, 4 ,5, 6] components.flatMap { $0 } } static func buildOptional(_ component: [Element]?) -> [Element] { component ?? [] } static func buildEither(first component: [Element]) -> [Element] { component } static func buildEither(second component: [Element]) -> [Element] { component } static func buildArray(_ components: [[Element]]) -> [Element] { // [[7], [8], [9], [10]] -> [7, 8, 9, 10] components.flatMap { $0 } } } extension Array { init(@ArrayBuilder<Element> builder: () -> [Element]) { self = builder() } } //let array: [Int] = .init { // [2, 3, 6] //} let array: [Int] = .init { 2 // [2] 3 // [3] if Bool.random() { 4 // [4] 5 // [5] } else { 0 0 } // [4, 5] 6 // [6] for i in 7 ... 10 { if i.isMultiple(of: 2) { i // [i] } } // [8, 10] } print(array)
Avatar
ちょっと質問させてください
2:08 PM
式文の並びを引数の並びに変換する仕組みってSwiftにはないですよね?
2:08 PM
BuildBlockのやってることですね
2:09 PM
sukosi
2:09 PM
すこし研究してみます
2:09 PM
ありがとうございました
Avatar
resultBuilderってSwiftUI以外で何か目的があって導入されたのかな…?使い道がいまいち
Avatar
たぶんSwiftUIのために導入されたんだと思います、そんな議論してるのをみたことがあります
Avatar
なるほどです、ありがとうございます! こういうの覚えるとつい使ってしまいがちなので、、、
Avatar
griffin-stewie 7/16/2022 2:13 PM
数年前に同僚が UIKit で UIStackView の組み立てを resultBuilder を使って SwiftUI 風に書けるようにしてましたね < resultBuilder の使い道
😮 2
Avatar
最近だとRegexBuilderでも使われてましたね
👍 1
t_naruhodo 3
Avatar
Background(Padding( Background(Padding( Background(Padding( Background(Padding( Background(Padding( Background(Padding( Background(Padding( Frame( Spacer() , width: 20, height: 20) , 20), Color.violet) , 20), Color.indigo) , 20), Color.blue) , 20), Color.green) , 20), Color.yellow) , 20), Color.orange) , 20), Color.red)
Avatar
griffin-stewie 7/16/2022 2:19 PM
@main もアットマークがついてますね
Avatar
そっか、知らない@Attributeを見たときに出自を確認しないといけないんですね。
Avatar
tochi86 - とち🐹 7/16/2022 2:19 PM
今のところ、~Builder~Actorなど、命名規則から判別する運用なのかな (edited)
Avatar
marker protocolってまだ正式に言語機能に入ってなかったんですね。知らなかった。。 (edited)
Avatar
tochi86 - とち🐹 7/16/2022 2:27 PM
公式ドキュメントに記載あったけど、初見じゃ絶対わからないですw https://developer.apple.com/documentation/swiftui/observedobject/wrapper (edited)
👍 1
Avatar
Avatar
shimastripe
そっか、知らない@Attributeを見たときに出自を確認しないといけないんですね。
@main は小文字始まりだからアトリビュート…ってコト!?
2:27 PM
すみません返信1つずれました、、
👌 1
Avatar
@Published@StateObject ( @ObservedObject ) の projectedValue の違い import SwiftUI import Combine final class UserViewModel: ObservableObject { @Published var user: User = .init(name: "Swift", age: 8) } //let viewModel: UserViewModel = .init() // //viewModel.$user // Publisher<User, Never> struct UserView: View { // var _user: State<User> @StateObject var viewModel: UserViewModel = .init() // @State private var user: User = .init(name: "Swift", age: 8) // @ViewBuilder var body: some View { VStack { Text(viewModel.user.name) .font(.title) AgeCounterView(age: $viewModel // ObservedObject<UserViewModel>.Wrapper .user // Binding<User> .age // Binding<Int> ) } } } struct AgeCounterView: View { @Binding var age: Int init(age: Binding<Int>) { self._age = age } var body: some View { Text("age: \(age)") Button("Next Year") { age += 1 } } } struct UserView_Previews: PreviewProvider { static var previews: some View { UserView() } } (edited)
Avatar
そういった挙動を知るにはデバッガで型を見て研究していく必要があるということですよね?
Avatar
griffin-stewie 7/16/2022 2:29 PM
ちょっと戻るんですが、KeyPath から文字列表現を取り出す方法は未だに公式 API ってないですよね? _kvcKeyPathString で一応取れるんですが。例: https://github.com/kishikawakatsumi/RealmTypeSafeQuery/blob/3d0670215e2ce369b2d729da524e0a846a1dced9/RealmTypeSafeQuery/Operators.swift#L28
A type-safe Realm query extensions using Swift 4 Smart KeyPaths - RealmTypeSafeQuery/Operators.swift at 3d0670215e2ce369b2d729da524e0a846a1dced9 · kishikawakatsumi/RealmTypeSafeQuery
Avatar
ありがとうございますmm
Avatar
$のくだりですね
2:32 PM
そうですね、ありがとうございました
2:33 PM
遠い道のりだ……
Avatar
tochi86 - とち🐹 7/16/2022 2:36 PM
内部実装はブラックボックスですからね...
t_sorena 3
Avatar
やはり難しいですよね...。 この辺り挙動はわかっているのですが、中身がわからずモヤモヤしています...。
Avatar
tochi86 - とち🐹 7/16/2022 2:36 PM
StateObjectの実装例は見つかりました https://gist.github.com/Amzd/8f0d4d94fcbb6c9548e7cf0c1493eaff
StateObject that works in iOS 13. GitHub Gist: instantly share code, notes, and snippets.
👍 1
👀 1
Avatar
SwiftUI-compatible framework for building browser apps with WebAssembly and native apps for other platforms - GitHub - TokamakUI/Tokamak: SwiftUI-compatible framework for building browser apps with...
👍 1
👀 1
Avatar
ありがとうございます!見てみます!
Avatar
tochi86 - とち🐹 7/16/2022 2:37 PM
多分、そんな感じです
Avatar
Open source implementation of Apple&#39;s Combine framework for processing values over time. - GitHub - OpenCombine/OpenCombine: Open source implementation of Apple&#39;s Combine framework ...
👍 2
👀 1
Avatar
griffin-stewie 7/16/2022 2:40 PM
ありがとうございます。
Avatar
SwiftUIのdata系のPropertyWrapperのライフサイクルの違い、WWDCでも話されていましたね https://developer.apple.com/wwdc20/10040
Data is a complex part of any app, but SwiftUI makes it easy to ensure a smooth, data-driven experience from prototyping to production...
👀 1
👍 2
2:43 PM
StateObject話されているやつです!
👍 2
Avatar
ありがとうございました、おつかれさまでした。
Avatar
お疲れさまでした!次回は10/29です(内容は未定) https://swift-tweets.connpass.com/event/254338/
# Swift Zoomin' #12 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 未定 # 参加方法 日時: 2022 年 10 月 29 日(土) 21:00- 本ページより参加登録をして下さい。 当日の開始 1 時間程前に参加のための URL を連絡しますので、connpassからのメールを受信できる状態にしておいて...
swift 2
Avatar
ありがとうございます。めっさおもろかったです!
Avatar
ものすごく有益でした。
Avatar
ありがとうございました! 今まで曖昧だったところが明確になり大変勉強になりました!mm
Avatar
ありがとうございました。
Avatar
tochi86 - とち🐹 7/16/2022 2:45 PM
SwiftUI勉強する気が湧いてきました!
Avatar
griffin-stewie 7/16/2022 2:45 PM
ライブコーディング良かったです!ありがとうございました!
Avatar
ありがとうございました!!
Avatar
ありがとうございました!
Avatar
ありがとうございました 👏
Avatar
ありがとうございましたー!
Avatar
非常にわかりやすかったです
Avatar
ありがとうございました!!major respectです
Avatar
ありがとうございました
Avatar
ありがとうございました!
Avatar
ありがとうございました 👏
Avatar
ありがとうございました!魔法が理解できました!!
Avatar
ありがとうございます。めっちゃ勉強になりました!
Avatar
「SwiftUIを支えるSwiftの言語機能」について動画を公開しました。SwiftUIはKeyPath Member LookupやProperty Wrapper等の言語機能を活用し、UIフレームワークとして唯一無二の使い勝手を実現しています。それらをライブコーディングでわかりやすく説明しました #swiftzoomin https://t.co/yYGl50Nfcz
👏 7
Avatar
今日21時から Swift Zoomin' でこのチャンネルを使います。 https://swift-tweets.connpass.com/event/254338/
# Swift Zoomin' #12 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 "Swift 5.7におけるProtocol-Oriented Programming" と題し、ライブコーディングを行います。 Swift 5.7 では Opaque Type (some) や Existential Type (any...
🙏 2
Avatar
# Swift Zoomin' #13 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 未定 # 参加方法 日時: 2023 年 1 月 28 日(土) 21:00- 本ページより参加登録をして下さい。 当日の開始 1 時間程前に参加のための URL を連絡しますので、connpassからのメールを受信できる状態にしておいてく...
12:08 PM
ビルド音、私は気になりませんでしたが、もし気になる方がおりましたら教えて下さい 👍
🙇 1
yoshi 1
Avatar
someany の復習 わかりやすい
👍 4
Avatar
tochi86 - とち🐹 10/29/2022 12:46 PM
associatedtypeは型の実装者が決める、型パラメータは型の利用者が決める
👍 1
Avatar
griffin-stewie 10/29/2022 12:50 PM
それは面倒だ(Generics 方式の例)
Avatar
dynamic dispatchだからclassもパフォーマンス的に不利なのは知ってましたが、existentialほどじゃないんですね
Avatar
griffin-stewie 10/29/2022 12:59 PM
もはや地獄ですねw
😂 3
Avatar
なるほどありがとうございます〜
Avatar
protocol MyIteratorProtocol<Element> { associatedtype Element mutating func next() -> Element? } protocol MySequence<Element> { associatedtype Element associatedtype Iterator: MyIteratorProtocol<Element> func makeIterator() -> Iterator // func makeIterator() -> any MyIteratorProtocol<Element> } protocol MyCollection<Element>: MySequence { associatedtype Index: Comparable associatedtype Indices: MyCollection where Indices.Element == Index associatedtype SubSequence: MyCollection where SubSequence.Element == Element, SubSequence.Index == Index, SubSequence.SubSequence == SubSequence subscript(index: Index) -> Element { get } subscript(range: Range<Index>) -> SubSequence { get } var indices: Indices { get } }
1:13 PM
struct Pair<Element>: MySequence { var elements: (Element, Element) func makeIterator() -> some MyIteratorProtocol<Element> { PairIterator(pair: self) } } struct PairIterator<Element>: MyIteratorProtocol { var pair: Pair<Element> var index: Int = 0 mutating func next() -> Element? { defer { index += 1 } switch index { case 0: return pair.elements.0 case 1: return pair.elements.1 case _: return nil } } }
1:13 PM
let pair: Pair<Int> = .init(elements: (2, 3)) //for element in pair { // print(element) //} var iterator = pair.makeIterator() while let element = iterator.next() { print(element) }
1:14 PM
// ジェネリクス地獄 class MyIteratorProtocol<Element> { func next() -> Element? { fatalError() } } class MySequence<Element, Iterator: MyIteratorProtocol<Element>> { func makeIterator() -> Iterator { fatalError() } } class MyCollection< Element, Index: Comparable, IndicesIndex, IndicesIterator: MyIteratorProtocol<Index>, Indices: MyCollection< Index, IndicesIndex, IndicesIterator, >, Iterator: MyIteratorProtocol<Element>, SubSequenceIterator: MyIteratorProtocol<Element>, SubSequence: MyCollection< Element, Index, SubSequenceIterator, SubSequenceIterator, SubSequence > >: MySequence<Element, Iterator> { subscript(index: Index) -> Element { fatalError() } subscript(range: Range<Index>) -> SubSequence { fatalError() } var indices: Indices { fatalError() } }
1:15 PM
Swift のプロトコルは、 Java や C# などのインタフェースのようなものと説明されることが多いですが、いくつかの違いがあります。最も大きな違いの一つが、 Swift のプロトコルはジェネリクスをサポートしていないということで...
Avatar
# Swift Zoomin' #13 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 未定 # 参加方法 日時: 2023 年 1 月 28 日(土) 21:00- 本ページより参加登録をして下さい。 当日の開始 1 時間程前に参加のための URL を連絡しますので、connpassからのメールを受信できる状態にしておいてく...
Avatar
Java等の言語にたいして、Swiftのprotocolは何を解決するために存在していると言えるんでしょうか? protocolがどうこうというより、値型で色々表現するためにprotocolが必要だったという理解なんですがあってます?
1:20 PM
パフォーマンスを考えるとdynamic dispatchは避けたいのが本質ということですかね
Avatar
アプリ開発においてPOPをバリバリ活かす場面ってあったりします?genericにするとやりやすい場面はしばしばだけど
Avatar
ありがとうございます!
Avatar
組み合わせ共存共栄ですね。理解しました!ありがとうございます。
Avatar
すごく腑に落ちました
1:29 PM
👏
Avatar
ありがとうございました!
Avatar
tochi86 - とち🐹 10/29/2022 1:29 PM
良いお年を〜
Avatar
👏🏻
Avatar
良いお年を〜
Avatar
ありがとうございましたー
Avatar
ありがとうございました!良いお年を〜
Avatar
ありがとうございましたー
Avatar
ありがとうございましたー良いお年を〜
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました!良いお年を〜
Avatar
ありがとうございました!良いお年を〜〜
Avatar
ありがとうございました。
Avatar
ありがとうございました
Avatar
ありがとうございました!
Avatar
griffin-stewie 10/29/2022 1:29 PM
ありがとうございました
Avatar
ありがとうございました〜
Avatar
treastrain / Tanaka.R 10/29/2022 1:29 PM
ありがとうございました!
Avatar
ありがとうございました!
Avatar
本日21時から Swift Zoomin' でこのチャンネルを使います。 https://swift-tweets.connpass.com/event/264710/
# Swift Zoomin' #13 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 AsyncSequence を時系列的に発出される値のストリームと考えると、 Combine の Publisher と同じものを表現していると考えられます。実際に、 Combine 同様のオペレーターを提供する Swift Async A...
👍 4
Avatar
すいません、ちなみに前回#12の動画は上がる予定はありますでしょうか?
Avatar
Avatar
shimastripe
すいません、ちなみに前回#12の動画は上がる予定はありますでしょうか?
すみません、アップできてませんでした。アップします・・・。
Avatar
ありがとうございます!いくつか復習したいところがあったのでとても嬉しいです!
🙇‍♂️ 1
Avatar
今日の参加用の Zoom URL です。 Zoomには下記URLから参加して下さい。 https://us02web.zoom.us/j/83479844929?pwd=UFhrd1RCdjlzS3lEa2lVZzZFZ1lLQT09 ミーティングID: 834 7984 4929 パスコード: 839294
Avatar
griffin-stewie 1/28/2023 12:00 PM
よろしくお願いします。
12:02 PM
下に出ますね。
Avatar
わいわい
Avatar
# Swift Zoomin' #14 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 未定 # 参加方法 日時: 2023 年 4 月 29 日(土) 21:00- 本ページより参加登録をして下さい。 当日の開始 1 時間程前に参加のための URL を連絡しますので、connpassからのメールを受信できる状態にしておいてく...
Avatar
質問・感想があればこちらにお願いいたします 👍
👍 1
Avatar
preview出したいとき、preview でコード補完が効くのでおすすめです👍 (edited)
👀 1
12:26 PM
楽しくないwww
t_kusa 2
Avatar
strongSelf weakSelf とか書いてたなぁ
Avatar
謎だwww
Avatar
https://twitter.com/yaapete/status/1605494021920415745 次の5.8 からはguardしたあとのselfも省略できるってみました 👀
🪄 Starting with Swift 5.8, self is now implicit after unwrapping it
Likes
592
👀 6
🪄 2
Avatar
なるほどー (型推論)
12:35 PM
Xcode Previewって音も正しく出してくれるんだw
Avatar
griffin-stewie 1/28/2023 12:43 PM
なるほど。安易に weak self して満足してしまいそうだ
Avatar
AnyCancellableを自作する機運…
Avatar
AsyncChannel と Concurrency に標準で入っている AsyncStream の違いは外部のオブジェクトから channel に値を send できることですか?
Avatar
さっきのAsynStoreだと for await count in state.counterCurrentValueSubjectと違って購読時の最新の値が飛んでこない可能性があるから、気をつける必要がある? (edited)
Avatar
SpecializeしてAsyncStreamにしないといけないかと思ってました
1:28 PM
です!
Avatar
treastrain / Tanaka.R 1/28/2023 1:33 PM
自ら AsyncStream.Continuation.finish() を呼ぶ必要がなく、async/await を使いたい場合は init(unfolding:onCancel:) の方を使う手もあります init(unfolding:onCancel:) | Apple Developer Documentation https://developer.apple.com/documentation/swift/asyncstream/init(unfolding:oncancel:)
👀 1
Avatar
なるほどです!ありがとうございます
Avatar
ありがとうございます!!
Avatar
全然知らなかったwww
Avatar
ジュニア 1/28/2023 1:54 PM
@rethrowsはprotocolにつけるんですね
Avatar
かっくん 1/28/2023 2:05 PM
Combineだと2, 3, 5が2回printされそうだけど1回しか出ない?
Avatar
参加いただいた皆さまありがとうございました!次回は4/22(土)を予定しております(内容は未定) Swift Zoomin' #14 https://swift-tweets.connpass.com/event/273604/
# Swift Zoomin' #14 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 未定 # 参加方法 日時: 2023 年 4 月 29 日(土) 21:00- 本ページより参加登録をして下さい。 当日の開始 1 時間程前に参加のための URL を連絡しますので、connpassからのメールを受信できる状態にしておいてく...
t_waiwai 12
🌸 2
Avatar
ありがとうございました👏👏👏 (edited)
Avatar
ありがとうございました!
Avatar
ジュニア 1/28/2023 2:23 PM
ありがとうございました!
Avatar
ありがとうございました!rethrowsの仕組みすごい面白かったです!!
Avatar
ありがとうございました!
Avatar
ありがとうございました!!
Avatar
treastrain / Tanaka.R 1/28/2023 2:23 PM
ありがとうございました!
Avatar
ありがとうございました!
Avatar
griffin-stewie 1/28/2023 2:23 PM
ありがとうございました
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
面白かったです。ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございましたー!
Avatar
@koher AsyncPublisherでnext と next の間で値 drop しちゃうってやつです! https://developer.apple.com/forums/thread/709672 (edited)
🙏 1
Avatar
TODO:
  • AsyncChannel がバッファを持っている件、 sendasync で消費されるまで待つ件をについて補足
  • Publisher を単純に valuesfor await で購読すると、バッファを持たない場合に次の next までの間に発出された値が見逃されてしまう件について補足
Avatar
今日ライブコーディングで書いたコードです。 https://github.com/koher/combine-to-async-sequence
Avatar
@matsuji @shimastripe AsyncStream を使った場合は next までの間に yield されても消失しないみたいですね。バッファに貯められてるっぽいです。 let values: AsyncStream<Int> = .init { continuation in Task { for i in 0 ..< 100 { try? await Task.sleep(nanoseconds: 100_000_000) continuation.yield(i) } continuation.finish() } } for await value in values { print(value) try await Task.sleep(nanoseconds: 1_000_000_000) }
3:18 PM
↓だと、さっき教えてもらった通り消失しました。 let subject: PassthroughSubject<Int, Never> = .init() let values = subject.values Task { for i in 0 ..< 100 { try? await Task.sleep(nanoseconds: 100_000_000) subject.send(i) } subject.send(completion: .finished) } for await value in values { print(value) try await Task.sleep(nanoseconds: 1_000_000_000) }
👀 1
3:20 PM
Publishervalues は危険そうですね・・・。
Avatar
確認ありがとうございます! Publisher の sink() でやる処理がそのまま values にできるわけじゃないのかなり罠なんですよね.....
😢 1
Avatar
Avatar
shimastripe
すいません、ちなみに前回#12の動画は上がる予定はありますでしょうか?
遅くなりましたが、10月分の動画を公開しました🙇‍♂️ https://twitter.com/koher/status/1622387395919482880
Swiftの標準ラリブラリでどのようにProtocol-Oriented Programming(Swift 5.7のsomeやPrimary Associated Typeあり)が活かされているかを、ライブコーティングで実演した動画を公開しました(10月のSwift Zoomin’の分です)。 https://t.co/4KMhWb25Zp
👍 2
t_waiwai 8
🙇 1
Avatar
本日のSwift Zoomin' #14ですが、こちらのチャンネルを使います。よろしくおねがいします!
😆 13
Avatar
次回の申し込みページです↓ https://swift-tweets.connpass.com/event/281856/
# Swift Zoomin' #15 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 未定 # 参加方法 日時: 2023 年 7 月 22 日(土) 21:00- 本ページより参加登録をして下さい。 当日の開始 1 時間程前に参加のための URL を連絡しますので、connpassからのメールを受信できる状態にしておいてく...
swift 3
Avatar
質問・感想などあればこちらにお願いします 👍
12:09 PM
四次元迷路アプリ『Maze 4D』を作りました。一見行き止まりに見えてもW軸方向に迂回できたりしておもしろいです。実験的にGPT-4を使ってiOSアプリ開発してみたんですが、驚異的なことに8割ほどのコードをAIが書いてくれました。 https://t.co/ETtMja4wmc
Likes
127
Avatar
3時間で25メッセージの制限心配だな
Avatar
エックスと読んでました!
Avatar
とんとんぼ 4/22/2023 12:14 PM
何ができて、何ができないのか
ここが知りたかったから、ありがたい
Avatar
なるほどAIならでは、という感じですね😀
Avatar
そこの入力欄ぶっこわれてますよね
Avatar
昨日ゆめみの花見会でも似たことやったんですが、途中で25個使い切って、GPT3.5で継続しましたね
😲 4
t_desune 1
Avatar
とんとんぼ 4/22/2023 12:16 PM
ChatAI系の入力欄はみんなぶっ壊れている希ガス Bingとか特に (edited)
t_tashikani 1
Avatar
漢字変換確定時のEnterキー入力でメッセージが飛んでいってしまう悲しみ...
t_wakaru 3
Avatar
とんとんぼ 4/22/2023 12:18 PM
Shift+Enterで改行できるけど、めんどいし、慣れない・・・
t_sorena 1
12:20 PM
これが近未来型コーディング・・・
Avatar
いきなり元定義の Element:Numeric 追加してきたの気に食わんなあw (edited)
😿 1
Avatar
結構噛み砕いて食わせていく感じなんですね 流石にいきなり「迷路アプリ作ってください+色々条件指定」はキツイ...? (edited)
Avatar
<Element> が余ってて解決できなそうだけどどうなんだ
12:25 PM
そうだよね
12:27 PM
乗算が何も言わずに要素積
12:33 PM
おーかしこい
12:35 PM
indexの式の実装とか信用ならんけどあってそうだったw (edited)
Avatar
とんとんぼ 4/22/2023 12:35 PM
ネスト深いの出してくるのは勘弁w
Avatar
すごい
Avatar
お〜
Avatar
途中で途切れたときの呪文は「再開してください」「続けてください」などの派閥がありますね
t_kusa 2
Avatar
途切れた場合でもリクエストを一つ消費してしまうんですね🥲
Avatar
ZとWの壁、おおたしかに (edited)
Avatar
GPT3.5と4でSwiftUIのコードは特にだいぶ差がある印象でした(学習期間の問題なのか)
Avatar
モデルのパラメータ数が100倍ぐらい違いますよ
😱 1
👀 1
12:48 PM
指示したWとZの-2について理解しておる (edited)
Avatar
波動拳インデント
t_kusa 2
Avatar
おおお
Avatar
普通に目で解いてるのがウケる
Avatar
とんとんぼ 4/22/2023 12:51 PM
ぽくなってきた!
Avatar
X-Y と W-Zのダブルパット使いやすそう
Avatar
サイズ12までだけど、欲しい迷路はそんなもんでしょ?って判断かな?
Avatar
koherさんも経験的に修正してて、前から2つここだよねって見つけたところから2つ修正しちゃうの面白い。人間自体がだいぶ確率的にコードを理解してる感あるw
Avatar
ゲームを作らせるのは難しいのかなと思ってましたが むしろゲームみたいなアウトプットがわかりやすい方が作りやすそうですね(?)
Avatar
SF Symbolsの名前調べるのめんどくさかったので、これが聞けるだけでも嬉しい気がします
Avatar
謎の型でてきたw
Avatar
シンボル名は関数の中じゃないんかいw (edited)
😆 1
1:01 PM
おもろすぎる
Avatar
ジュニア 4/22/2023 1:01 PM
迷路の難易度が上がった
Avatar
とんとんぼ 4/22/2023 1:01 PM
えーあいが考えた、最強のコントローラーw
Avatar
omochimetaru 4/22/2023 1:01 PM
そのままいくんかいw
Avatar
AI的に難易度は迷路にあらず、入力UIにあるわけですなwww (edited)
Avatar
将棋の複雑な盤面でAI評価値の考えてることがもう分からないみたいなw
Avatar
GPT4.0、コメント上限があるのが本当に惜しい、早く解除されないかなー
Avatar
omochimetaru 4/22/2023 1:07 PM
maze.startPosition あったっけ?
Avatar
おお
Avatar
omochimetaru 4/22/2023 1:08 PM
www
1:08 PM
賢いけどヤバい奴だ・・・
Avatar
(略)してくれるのトークン的には嬉しいが... (edited)
Avatar
omochimetaru 4/22/2023 1:09 PM
無いよねえ > startPosition (edited)
1:12 PM
www
Avatar
とんとんぼ 4/22/2023 1:12 PM
こいつ・・・動くぞ・・・
Avatar
👏
👏 13
Avatar
omochimetaru 4/22/2023 1:21 PM
お〜できてる
1:22 PM
その式解けたらえらいな
1:23 PM
んん?
1:23 PM
xだけじゃだめじゃないか
1:25 PM
あいだのパディングの考慮
1:25 PM
そう
1:27 PM
お〜
Avatar
やっぱり今の指示無し!みたいなステップ戻るようなことも可能なんですかね?
t_naruhodo 1
1:33 PM
かなりリッチにやり直しできるんですね 👀
Avatar
omochimetaru 4/22/2023 1:33 PM
会話の分岐残ってるの面白いですね
Avatar
コンパイルエラーでGPTに聞く流れ、GPTがIDEに入ってくれたらめちゃ便利そうですね (edited)
1:36 PM
もうそろそろメッセージ上限が...(?)
Avatar
またrectを渡しちゃってます
😿 1
Avatar
omochimetaru 4/22/2023 1:39 PM
上限は25回/3hの話では? (edited)
👍 1
Avatar
25messages per 3 hoursの話のつもりでしたw(が、トークンの話もそうですね) (edited)
1:43 PM
ただ修正できるだけだと思ってたらツリーになってるのはすごいですね
Avatar
omochimetaru 4/22/2023 1:44 PM
分岐済みの会話ログでノベルゲームみたいな読み物作れそう
t_naruhodo 1
1:44 PM
そのコンパイルエラーもGPTに対応させたら?
1:45 PM
むずいか?
Avatar
ジュニア 4/22/2023 1:45 PM
aとbの型明示するだけじゃだめですかね
Avatar
omochimetaru 4/22/2023 1:45 PM
@koher そのコンパイルエラーの対応もやらせたらできるかみてみたい
Avatar
間違ってないけど単に式が複雑でコンパイル通らない時と 間違ってて&解析できなくてコンパイルできない時がありますよねこのエラー
😢 1
1:48 PM
Xcodeの嘘エラー文をパターンとして学習してるか気になりますね()
Avatar
Avatar
kntk
間違ってないけど単に式が複雑でコンパイル通らない時と 間違ってて&解析できなくてコンパイルできない時がありますよねこのエラー
omochimetaru 4/22/2023 1:48 PM
(2)でしたね。
👍 1
1:49 PM
Xcodeの方の元に戻るスタックの分岐間違えましたね・・・ (edited)
😿 1
Avatar
ジュニア 4/22/2023 1:51 PM
やっぱり現時点でのコードと常に同期させたくなりますね
👍 2
Avatar
rectを渡しちゃってます3回目
😄 1
Avatar
またrectが
Avatar
omochimetaru 4/22/2023 1:55 PM
ブレてるところと安定して間違えてるところがどっちもあって意味わからん (edited)
t_sorena 4
Avatar
地獄だ
Avatar
omochimetaru 4/22/2023 1:57 PM
wwww
Avatar
ジュニア 4/22/2023 1:57 PM
wwww
Avatar
omochimetaru 4/22/2023 1:57 PM
ぶっ壊れたw
Avatar
嘘つき(Xcode)と嘘つき(GPT)の戦い (edited)
t_kusa 1
2:01 PM
ああ、CanvasのinitってViewBuilderじゃなくてただのクロージャー...? (edited)
Avatar
ただの for になるはずですよね、きっと
Avatar
CoreGraphics版みたいですか?
👍 10
Avatar
omochimetaru 4/22/2023 2:11 PM
UIGraphicsImageRenderer 使うと機能としてはCoreGraphicsと同じだけど座標系がUIKitに準拠したコンテキストがセットされた状態で使えるので便利ですね (edited)
t_naruhodo 1
Avatar
文脈(トークン)が積み重なったから弱体化してきたのか、そもそもここに弱いのか (edited)
Avatar
パフォーマンスとは
Avatar
8888888888
Avatar
参加いただいた皆さまありがとうございました!次回は7/22(土)を予定しております(内容は未定) https://swift-tweets.connpass.com/event/281856/
# Swift Zoomin' #15 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 未定 # 参加方法 日時: 2023 年 7 月 22 日(土) 21:00- 本ページより参加登録をして下さい。 当日の開始 1 時間程前に参加のための URL を連絡しますので、connpassからのメールを受信できる状態にしておいてく...
👍 2
Avatar
ありがとうございました。めっちゃ楽しかったです (edited)
Avatar
とても面白かったです!ありがとうございました!!
Avatar
ありがとうございました。
Avatar
ありがとうございました!
Avatar
ジュニア 4/22/2023 2:20 PM
ありがとうございました!
Avatar
たくさんヒントやコツをもらえた気がします。ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
面白かったです!!
Avatar
ありがとうございました!
Avatar
ありがとうございました。
Avatar
大変参考になりました、ありがとうございました!
Avatar
ありがとうございました。
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました。めちゃくちゃ面白かったです 👍
Avatar
ですね。WWDCの後に聞けるの楽しみです。
Avatar
ありがとうございました〜!😆
Avatar
ありがとうございましたー
Avatar
🍤ACエビフライ🔌 4/22/2023 2:26 PM
ありがとうございましたー!
Avatar
ご参加ありがとうございました!!
👏 9
Avatar
今日のコードをpushしました。 https://github.com/koher/swift-zoomin-14
❤️ 7
Avatar
本日21:00〜のSwift Zoomin' #15ですが、こちらのチャンネルを使います。よろしくおねがいします! 内容: Swift 5.9 の Observation を使って、 SwiftUI で iOS アプリを作る様子をライブ配信します。簡単に使い方を説明し、 Observation で遊びながら、 Combine ( ObservableObject )と比べて考え方を変えなければいけなそうな部分について検討します。 https://swift-tweets.connpass.com/event/281856/
# Swift Zoomin' #15 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 Swift 5.9 の Observation を使って、 SwiftUI で iOS アプリを作る様子をライブ配信します。簡単に使い方を説明し、 Observation で遊びながら、 Combine ( ObservableObject )...
t_waiwai 16
Avatar
# Swift Zoomin' #16 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 未定 # 参加方法 日時: 2023 年 10 月 21 日(土) 21:00- 本ページより参加登録をして下さい。 当日の開始 1 時間程前に参加のための URL を連絡しますので、connpassからのメールを受信できる状態にしておいて...
12:09 PM
質問・感想などはお気軽にどうぞ t_waiwai
Avatar
ObservationのPR自体WWDC23に間に合うか分からないスケジュールじゃなかったでしたっけ(?) Apple側のの資料作成が間に合わなかったとか...?
12:15 PM
感想ですw
12:15 PM
kusa
12:16 PM
なるほどです
Avatar
何かしら変わりそう
😿 1
12:17 PM
それよりなぜiOS17以上なのかが理解できない、Swift Macrosは普通に13以上なのに
😿 1
Avatar
backportの仕組み自体はあるはずなのに全然使われてない気がするのはなぜなんでしょう
Avatar
確かフォーラムで見たんですが、新しい型を追加しないといけないものはbackport難しいらしいですね Swift Conncurrencyが例外だったとか
t_naruhodo 2
Avatar
Conversation about back deployment has been practically rendered off-topic discussion: This reason was given for why Observation cannot be back deployed: As far as I can tell, no technical reason has been revealed. Also, it seems like there could be at least one way it could be made to work with older SwiftUI runtimes. That said, I trust the...
👀 1
❤️ 1
Avatar
Concurrencyは開発者の圧力がかなり厚かったからね、いろいろ無理やりしてもらってた感じです
t_desune 1
t_naruhodo 3
12:24 PM
?
Avatar
Avatar
kntk
backportの仕組み自体はあるはずなのに全然使われてない気がするのはなぜなんでしょう
treastrain / Tanaka.R 7/22/2023 12:30 PM
関数なら SE-0376 によって back deploy できるけれど型は難しい、ということみたいです(forums を見る限り)
This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. - apple/swift-evolution
🙇‍♂️ 2
Avatar
ありがとうございます!見てみます
Avatar
griffin-stewie 7/22/2023 12:35 PM
マクロを展開したコードの中にある「変数名に$マークついている奴」って何か意味あるんでしたっけ?
Avatar
griffin-stewie 7/22/2023 12:59 PM
import Observation を書いたら Expand Macro が動くようになった
Avatar
import SwiftUI //var counter: Counter = .init() struct ContentView: View { @StateObject private var state: ContentViewState = .init() // @State private var state: ContentViewState = .init() var body: some View { let _ = print("A") VStack { Text("Foo") CounterView(counter: $state.counter) // CounterView(counter: state.counter) // CounterView(counter: Binding( // get: { // counter // }, set: { newValue in // counter = newValue // } // )) } .padding() } } @MainActor final class ContentViewState: ObservableObject { @Published var counter: Counter = .init() // ... } //@MainActor @Observable //final class ContentViewState { // var counter: Counter = .init() // // nonisolated init() {} //} (edited)
1:08 PM
import SwiftUI struct CounterView: View { @Binding var counter: Counter // @Bindable var counter: Counter var body: some View { let _ = print("B") VStack { Text(counter.count.description) Button("Count up") { counter.countUp() } Button("Reset") { counter.reset() } } .padding() } }
1:08 PM
struct Counter: Sendable { private(set) var count: Int = 0 mutating func countUp() { count += 1 } mutating func reset() { count = 0 } } //final class Counter { // private(set) var count: Int = 0 // // func countUp() { // count += 1 // } // // func reset() { // count = 0 // } //} //import Observation // //@MainActor @Observable //final class Counter: Sendable { // private(set) var count: Int = 0 // // func countUp() { // count += 1 // } // // func reset() { // count = 0 // } //}
Avatar
treastrain / Tanaka.R 7/22/2023 1:26 PM
最近の変更で @Observable が struct にはつけられなくなってしまいましたね… [5.9] Observable protocol non-marker, @Observable class only by natecook1000 · Pull Request #67196 · apple/swift https://github.com/apple/swift/pull/67196
Explanation: Three top-level changes: Converts Observable to be a non-marker protocol, which in turns requires a change in the @Observable macro to emit a conformance extension only when the targe...
👀 7
Avatar
ジュニア 7/22/2023 1:29 PM
一部のプロパティだけ監視しないようにしたいとき、ObservableObjectのときは単に@ Publishedをつけないだけでよかったですが、@ Observableなクラスでは可能なんでしょうか? 大したオーバーヘッドではないかもですが監視不要なプロパティまでObservationTracked由来の処理が走ってしまうのかなと
1:30 PM
聞き逃してただけだったらすみません!
Avatar
Avatar
ジュニア
一部のプロパティだけ監視しないようにしたいとき、ObservableObjectのときは単に@ Publishedをつけないだけでよかったですが、@ Observableなクラスでは可能なんでしょうか? 大したオーバーヘッドではないかもですが監視不要なプロパティまでObservationTracked由来の処理が走ってしまうのかなと
griffin-stewie 7/22/2023 1:30 PM
@ObservationIgnored , 実際にマクロを展開したら付けられてますね。
❤️ 2
Avatar
ジュニア 7/22/2023 1:32 PM
不要なレンダリングが走らないため問題ないのは理解しつつ、get setで不要な処理が走ってしまうのかなと気になった次第でした。 回答ありがとうございます!
Avatar
griffin-stewie 7/22/2023 1:48 PM
アットマークが随所で使われていてそれがマクロなのかプロパティラッパーなのか一瞬わからなくなるw
t_wakaru 7
Avatar
// // ContentView.swift // ObservationPlayground // // Created by Yuta Koshizawa on 2023/07/22. // import SwiftUI //var counter: Counter = .init() struct ContentView: View { // @StateObject private var state: ContentViewState = .init() @State private var state: ContentViewState = .init() var body: some View { let _ = print("A") ScrollView { VStack { Text("Sum: \(state.countSum)") ForEach(state.counters.indices, id: \.self) { i in // CounterView(counter: $state.counters[i]) CounterView(counter: state.counters[i]) Divider() } // CounterView(counter: state.counter) // CounterView(counter: Binding( // get: { // counter // }, set: { newValue in // counter = newValue // } // )) } .padding() } } } //@MainActor //final class ContentViewState: ObservableObject { // @Published var counters: [Counter] = (1...100).map { _ in Counter() } // // ... //} @MainActor @Observable final class ContentViewState { var counters: [Counter] = (1...100).map { _ in Counter() } var countSum: Int { counters.lazy.map(\.count).reduce(0, +) } nonisolated init() {} }
1:50 PM
import SwiftUI struct CounterView: View { // @Binding var counter: Counter @Bindable var counter: Counter var body: some View { let _ = print("B \(counter.count)") VStack { Text(counter.count.description) Button("Count up") { counter.countUp() } Button("Reset") { counter.reset() } Stepper("", value: $counter.count) } .padding() } }
1:50 PM
//struct Counter: Sendable { // private(set) var count: Int = 0 // // mutating func countUp() { // count += 1 // } // // mutating func reset() { // count = 0 // } //} //final class Counter { // private(set) var count: Int = 0 // // func countUp() { // count += 1 // } // // func reset() { // count = 0 // } //} import Observation @MainActor @Observable final class Counter: Sendable { var count: Int = 0 func countUp() { count += 1 } func reset() { count = 0 } }
Avatar
treastrain / Tanaka.R 7/22/2023 2:09 PM
購読の部分、objectWillChange みたいなものだと思っていたので、少し前の Observation に含まれていた AsyncSequence だった values(for:)changes(for:) の方がしっくりきてしまっていましたw
👀 1
Avatar
griffin-stewie 7/22/2023 2:10 PM
Observation 自体は Darwin 系以外の環境でも動くんでしょうか?(CombineはDarwinに依存してるから云々ってプロポーザルに書かれてたので)
Avatar
Observable+@Bindableてやる場合は、ObservableObject+@ObservedObjectと同じですね。Counterだけ見る場合 (edited)
2:15 PM
Yes
2:16 PM
(書きやすくなっただけか
Avatar
letだけで、ObservableObjectを子にバインドできるのがシンプルになっていいですね (edited)
Avatar
Avatar
treastrain / Tanaka.R
購読の部分、objectWillChange みたいなものだと思っていたので、少し前の Observation に含まれていた AsyncSequence だった values(for:)changes(for:) の方がしっくりきてしまっていましたw
values(for:) の AsyncSequenceが無くなったってことは for await的な書き方はできなく(なっ)てwithObservationTrackingを使うようになったって認識であっているでしょうか......? (edited)
Avatar
Avatar
shimastripe
values(for:) の AsyncSequenceが無くなったってことは for await的な書き方はできなく(なっ)てwithObservationTrackingを使うようになったって認識であっているでしょうか......? (edited)
treastrain / Tanaka.R 7/22/2023 2:20 PM
その理解をしています
❤️ 1
Avatar
なるほどです!ありがとうございます。本当にCombineっぽい感じからより離れてますね
Avatar
Avatar
treastrain / Tanaka.R
その理解をしています
treastrain / Tanaka.R 7/22/2023 2:21 PM
この pull request で AsyncSequence だった values(for:)changes(for:) などが無くなっちゃいました… Refocus observation to it's core capability by phausler · Pull Request #65528 · apple/swift https://github.com/apple/swift/pull/65528 (edited)
This is a draft of a leaner and more focused Observation. It removes some of the features that caused restrictions to the usages of the APIs in favor for leaving those for future development (and p...
👀 4
Avatar
withObservationTrackingの購読のキャンセルってできるのかなってパッと聞いて想像しました
2:27 PM
ですよね!AsyncSequenceとかCombineのCancellableを想像していたので何か書かないと行けなそうだなって思いました
Avatar
内部的にSwiftyな進化は遂げなかったのは悲しいですが 利用者側からだけで見ると、CombineのObservableObject比べると順当進化な気はします(?) (edited)
t_wakaru 1
Avatar
いや、Jetpack Composeがそういうものかどうかは、知らないw (edited)
Avatar
Avatar
kntk
内部的にSwiftyな進化は遂げなかったのは悲しいですが 利用者側からだけで見ると、CombineのObservableObject比べると順当進化な気はします(?) (edited)
まあそれいうとそもそも最近のSwiftは初心者に厳しくなりつつあるからな…初期のSwiftと違って
😿 5
t_sorena 6
Avatar
griffin-stewie 7/22/2023 2:32 PM
正直もうよく分からない
Avatar
Avatar
hironytic
いや、Jetpack Composeがそういうものかどうかは、知らないw (edited)
Jetpack ComposeのStateっていうのが、getterとsetterで値をラップしていて(これは事実)、そのgetterでアクセスしてきたものに対してsetterで更新している感があったので(ここは想像)
Avatar
Macrosはさらに理解さえるのに難しい 😇
Avatar
SwiftUI駆動開発で狂い始めた...
Avatar
まあ展開できるのはいいのはわかりますw
Avatar
griffin-stewie 7/22/2023 2:33 PM
Expand Macro したところにブレイクポイントって仕込めたんでしたっけ?
Avatar
ただSwiftのコアチームがなんか一部のクッソつよつよエンジニアが手短くかきたいだけの欲が強すぎた気がする
2:36 PM
正直いまだに @Envinroment(\.id) var id みたいな型宣言(?)がないプロパティ宣言気持ち悪いと思ってる
😿 1
2:36 PM
あるかも
Avatar
でもObservationをbodyが購読する機構自体はまだブラックボックスのマジックですもんね...?
Avatar
SwiftUIとOSのデカプリングはよ
Avatar
多少推測はしやすいのでCombineよりマシですか (edited)
2:38 PM
www
Avatar
griffin-stewie 7/22/2023 2:38 PM
いつも言われることだけど、開発環境のクオリティをちゃんとしてほしい。 最近ビルドエラーの箇所をエディタ上に表示してくれなくなって辛い。 シミュレータをしょっちゅう再起動しないといけなくて辛い。
😿 3
Avatar
Macro はXCodeでしかExpandできないですよね。GitHubなどのところでExpandさせる手段は当分なさそう。。。
Avatar
griffin-stewie 7/22/2023 2:39 PM
残っちゃうの辛いから消すためのショートカットキーを設定したw
Avatar
謎のエラーに悩まされてどこ見ても訳わかんなくて仕方ないからXcode再起動したら治った、みたいなね
t_aruaru 4
Avatar
Internal inconsistency error (didStartTask).....
Avatar
griffin-stewie 7/22/2023 2:40 PM
最近コード書いて Build & Run しても変更が反映されないケースがちょくちょくある。クリーンしたら直るw
Avatar
Xcodeは嘘つき
Avatar
griffin-stewie 7/22/2023 2:40 PM
Preview も辛い
Avatar
エラー吐いて「また嘘やろーw」って思って信じてなかったらたまに本当のこと言ってて無駄に時間を食われます (edited)
Avatar
ジュニア 7/22/2023 2:41 PM
オオカミXcode
🐺 3
t_kusa 1
Avatar
griffin-stewie 7/22/2023 2:41 PM
昔は Xcode カワイイって思えてたけど Swift になってっていうか SwiftUI くらいの時期から Xcode に不満が出てきた。
Avatar
きっとXcodeの裏にはもううんコードにうんコード重ねて誰も手を出しにくいんですよ(死んだ魚の目
😿 1
Avatar
griffin-stewie 7/22/2023 2:42 PM
14.3.1 は確実壊れてますねw
Avatar
(AppCode生き返ってほしい...)
t_wakaru 1
Avatar
ジュニア 7/22/2023 2:43 PM
iPad向けのSwift Playgroundsが進化してXcodeに置き換わる時代が来ないかなって妄想してます
t_kusa 4
Avatar
そもそもSwiftUIが複雑な画面遷移に弱いのいつになったら治るのかな…
😿 3
Avatar
中途半端なNavigationStackを出しちゃったから、数年はこれから進化しないことが確定されちゃって辛いです
Avatar
最近2019年のWWDC見直しててSwiftUIの公開でみんなすっごい大喜びで叫んでたの見て、苦笑いしかできないのと、考えてみたら自分の当時その中の一人だったの思い出してなんとも言えない気分になった…
2:46 PM
夢を見させすぎた…
2:47 PM
まあ UIHostingController の存在は偉大ですよ(遠い目
Avatar
xrOS以降もずっとSwiftUI主軸のようですね。逃れない
Avatar
SwiftUIの不満は、宣言的UIなのが問題なのか 未熟でUIKitのラッパーだから問題なのかって言ったらどっちでしょうね Flutterとか不満どうなんでしょうか
Avatar
後者な気がする
😿 2
Avatar
griffin-stewie 7/22/2023 2:48 PM
マルチプラットフォームなのが足を引っ張ってる気がする。
Avatar
機能が足りなすぎるんだよなSwiftUI、画面遷移にしろなんにしろ
😿 1
Avatar
もっと言えば、未熟(Appleのコントリビューション)なのが問題なのか SwiftUIの変換後に、命令的UIが存在してしまうラッパーだから根本的に無理があるのか (edited)
Avatar
まあ最終的には命令的なコードにはなるしかないですよ、アセンブリになったら
😿 1
Avatar
なるほどです
Avatar
高級言語がどんなに高級でも、最終的にマシンを動かすには命令するしかないので
😿 1
Avatar
それで言うとReactが良いのは、DOMとVDOMの乖離が少ないからってことですかね... (edited)
Avatar
griffin-stewie 7/22/2023 2:52 PM
SwiftUI のリファレンスが読みにくいのをどうにかしてほしい。その機能ってそこにドキュメントあるんだ!みたいなことが多い気がする。っていうか見つけられない。(UIKit ならそれっぽいオブジェクトを見つけてせいぜい継承関係とかProtocolをみれば大体すぐにわかるのに)
2:53 PM
modifire つらい
2:53 PM
wakaru
Avatar
それでも最近のアップルのドキュメントだいぶ充実してきた方だと思いますよ、ひと昔と比べて
😿 1
t_wakaru 1
Avatar
次回は10/21(土)を予定しております(内容は未定) https://swift-tweets.connpass.com/event/290613/
# Swift Zoomin' #16 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 未定 # 参加方法 日時: 2023 年 10 月 21 日(土) 21:00- 本ページより参加登録をして下さい。 当日の開始 1 時間程前に参加のための URL を連絡しますので、connpassからのメールを受信できる状態にしておいて...
👍 8
Avatar
あら
Avatar
それ聞きたかったので楽しみです!
t_me_too 1
Avatar
ご参加いただいた皆さまありがとうございました!
Avatar
ありがとうございました!!!
Avatar
ジュニア 7/22/2023 2:55 PM
ありがとうございました!
Avatar
griffin-stewie 7/22/2023 2:55 PM
ありがとうございました。
Avatar
愚痴大会してすいませんでした!ありがとうございました!! (edited)
Avatar
ありがとうございました!!
Avatar
ありがとうございました!!!
Avatar
ありがとうございました!
Avatar
ありがとうございました!!
Avatar
ありがとうございました!
Avatar
ありがとうございましたー
Avatar
treastrain / Tanaka.R 7/22/2023 2:55 PM
ありがとうございました!
Avatar
ありがとうございました!!
Avatar
面白かったです
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました!!
Avatar
withObservationTracking 使ったコード貼り忘れてました。 import SwiftUI import UIKit struct FooView: UIViewControllerRepresentable { func makeUIViewController(context: Context) -> some UIViewController { FooViewController() } func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) { } } final class FooViewController: UIViewController { private let state: FooViewState = .init() private let label: UILabel = .init() override func viewDidLoad() { super.viewDidLoad() label.translatesAutoresizingMaskIntoConstraints = false view.addSubview(label) let countUpButton: UIButton = .init(type: .system) countUpButton.translatesAutoresizingMaskIntoConstraints = false countUpButton.setTitle("Count up", for: .normal) countUpButton.addAction(.init { [state] _ in state.countUp() }, for: .touchUpInside) view.addSubview(countUpButton) let resetButton: UIButton = .init(type: .system) resetButton.translatesAutoresizingMaskIntoConstraints = false resetButton.setTitle("Reset", for: .normal) resetButton.addAction(.init { [state] _ in state.reset() }, for: .touchUpInside) view.addSubview(resetButton) NSLayoutConstraint.activate([ label.centerXAnchor.constraint(equalTo: view.centerXAnchor), countUpButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), resetButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), countUpButton.centerYAnchor.constraint(equalTo: view.centerYAnchor), countUpButton.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 8), resetButton.topAnchor.constraint(equalTo: countUpButton.bottomAnchor, constant: 8), ]) updateViews() } private func updateViews() { withObservationTracking { label.text = state.count.description } onChange: { [weak self] in guard let self else { return } Task { @MainActor in self.updateViews() } } } } @MainActor @Observable final class FooViewState { var count: Int = 0 func countUp() { count += 1 } func reset() { count = 0 } }
❤️ 2
Avatar
この前話していた、 struct の Observation が難しい件についての Forums でのコメント、 shiz さんが教えてくれました。 https://discord.com/channels/291054398077927425/306995750418513920/1133125505936273489
❤️ 3
Avatar
本日21:00〜のSwift Zoomin' #16でこちらのチャンネルを使います。よろしくおねがいします! SwiftUIを使ってiOSを作るときにどうするのがいいのか色々考えてきたんですが、素直にシンプルに作るにはこうすればいいんじゃないかと最近思うことがあるので、明後日21日(土)の21時から #swiftzoomin https://swift-tweets.connpass.com/event/290613/ で実演しながら話そうと思います。 https://twitter.com/koher/status/1714816534768664838 (edited)
🙌 7
👍 4
Avatar
# Swift Zoomin' #17 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 未定 # 参加方法 日時: 2024 年 1 月 27 日(土) 21:00- 本ページより参加登録をして下さい。 当日の開始 1 時間程前に参加のための URL を連絡しますので、connpassからのメールを受信できる状態にしておいてく...
swift 6
Avatar
.task { } だと throws じゃないのは画面非表示時に裏でタスクをキャンセルするために戻り値が使われているからかなと思います. (edited)
👍 1
Avatar
treastrain / Tanaka.R 10/21/2023 12:29 PM
このサンプルプロジェクトにおいて、Swift 5.9 の Observation は用いることはできますか?
🙇 1
Avatar
はい
12:31 PM
そのキャンセルする処理のところがエラー前提で受け取りたくなかったのかなと (SwiftUI 内部の処理)
Avatar
同じ印象をこのセッションで持ちましたw
Avatar
例えばreload()を呼んだらリロードボタンが無効になることをテストしたいとき、Viewのインスタンスを使ってテストするイメージでしょうか?
t_wakaru 5
Avatar
some Viewにされるの辛いわかる。ViewControllerの時できてたことが色々できない…
Avatar
確かにバランス良いかもですね
Avatar
問題提起していただいたPublisherの繋ぎ込み面倒問題はObservableObjectがNestすると変更イベントが伝搬しないケースなどで発生すると思うので、元のViewState でも Swift 5.9 の Observation の形式になれば解決しそうですかね? (edited)
Avatar
プレゼンテーションロジックのテストはある程度諦めるってことですね (edited)
1:28 PM
「モデル(ロジック)」をちゃんとViewから出して、そこをテストしようってことですねw (edited)
t_wakaru 1
1:29 PM
www
Avatar
切り出した結果 EnvironmentObject とかが初期化時に使えないというのは再発するケースもありそうですね
😇 1
1:34 PM
React の Component がテストできるみたいな感じで View がテストできれば...
Avatar
Stateに関しては、DynamicPropertyの下のAPIが提供されていたら まだテスト書けるようなフレームワーク作れるかもしれないのに結局ブラックボックス...
1:53 PM
www
Avatar
# Swift Zoomin' #17 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 未定 # 参加方法 日時: 2024 年 1 月 27 日(土) 21:00- 本ページより参加登録をして下さい。 当日の開始 1 時間程前に参加のための URL を連絡しますので、connpassからのメールを受信できる状態にしておいてく...
Avatar
ありがとうございました
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
treastrain / Tanaka.R 10/21/2023 1:59 PM
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました!!
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございましたー
Avatar
ありがとうございました
Avatar
良いお年を
Avatar
ありがとうございましたー
Avatar
ありがとうございましたー
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございましたー!
Avatar
ありがとうございました〜!
Avatar
ありがとうございました!!
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました。
Avatar
ありがとうございました!(View のテストを SwiftUI 上で書いてプレビューで pass or failure を表示したらなんとかなるかも...?)
2:02 PM
見た目を見るのじゃなくてテスト結果をプレビューするって感じです.リストで
Avatar
TominagaTakuya 10/21/2023 2:03 PM
ありがとうございました!
Avatar
ありがとうございました!
👏 9
Avatar
Avatar
kebo
見た目を見るのじゃなくてテスト結果をプレビューするって感じです.リストで
Swift Playgrounds で iPad 上でアプリを書く時にテストを書くのにこれを使っているんですが,テスト自体は別に View をテストするわけじゃないのですが,テスト結果がプレビューのところに出てくるので,そこから思いついた発想です. https://github.com/Losiowaty/PlaygroundTester (edited)
PlaygroundTester enables you to easily run tests for your iPad Playgrounds 4 project. - GitHub - Losiowaty/PlaygroundTester: PlaygroundTester enables you to easily run tests for your iPad Playgroun...
👀 1
Avatar
ありがとうございましたー
Avatar
Avatar
kebo
Swift Playgrounds で iPad 上でアプリを書く時にテストを書くのにこれを使っているんですが,テスト自体は別に View をテストするわけじゃないのですが,テスト結果がプレビューのところに出てくるので,そこから思いついた発想です. https://github.com/Losiowaty/PlaygroundTester (edited)
Previewか、もしくはテスト用のView作ってテストするの良さそうですね。
t_desune 1
2:13 PM
ライブコーディングしていた内容をpushしました。 https://github.com/koher/swift-zoomin-16 (edited)
Contribute to koher/swift-zoomin-16 development by creating an account on GitHub.
🙇‍♂️ 6
🌟 6
2:13 PM
あ、zoomingになっちゃった。リネームします。 リネームしました。 (edited)
Avatar
こんな感じで実装用のビューを分けてやれば、 @Environment でDIを可能にしつつ、ViewStateを持つというのは一応できそうです。Observationを使う方なら。 struct UserView: View { let id: User.ID @Environment(UserStore.self) var userStore var body: some View { UserStateView(state: UserViewState(userStore: userStore, id: id)) } } struct UserStateView: View { let state: UserViewState var body: some View { VStack { Text(state.user?.name ?? "User Name") .redacted(reason: state.user == nil ? .placeholder : []) .font(.title) ...
Avatar
ただ、ViewStateの中でObservableなUserStoreを使う部分は注意が必要だと思っています。 https://github.com/hironytic/swift-zoomin-16/blob/76e6ae5bf9ccee97f36b76e00115a3223f18caf2/Zoomin/UserViewState.swift#L8 みたいにViewStateがView側に見せるものがComputed Propertyになってるなら、結果的にbodyからそれが参照されたときにUserStoreが参照されるのでうまく追跡の対象になって変わったときにViewが更新されるはず。ですが、ViewStateのロジックの中でUserStoreを参照しつつその結果を元にView側に見せるプロパティに代入する、といったことをしたい場合はViewState内で自分で withObservationTracking とかを使わないとダメなんじゃないかと思います。割と辛そう。
Avatar
↑あ、ミスった。 @State になってないから、これじゃViewが更新されるたびにViewStateも作り直されちゃう気が…
Avatar
ありがとうございます。これはできるんですが、これが必要になる時点で使い方に問題がある気がするんですよね。ViewStateの単体テストを書かないならうまみもないですし・・・
t_desune 1
Avatar
本日21:00〜のSwift Zoomin' #17でこちらのチャンネルを使います。よろしくおねがいします! https://twitter.com/koher/status/1749954334253887697
せっかくVision Pro発売直前なので、今週末の #swiftzoomin ではvisionOSアプリ開発の様子をライブコーディングで配信しようと思います。僕もビギナーなので今回は説明するというよりも遊んでみる感じになると思います。 1/27(土)21:00〜 https://t.co/mVq8Lq4NOn
👍 8
swift 8
Avatar
次回開催日も決定しております! https://swift-tweets.connpass.com/event/308457/ (edited)
# Swift Zoomin' #18 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 未定 # 参加方法 日時: 2024 年 4 月 27 日(土) 21:00- 本ページより参加登録をして下さい。 当日の開始 1 時間程前に参加のための URL を連絡しますので、connpassからのメールを受信できる状態にしておいてく...
🙌 1
Avatar
Swift6関連がいつくるか気になる…
Avatar
シミュレーター触ってるだけでも面白い👏
Avatar
疑問点ある方はこちらに書いていただければ読み上げます!
Avatar
この試行錯誤も面白い 😂
Avatar
壁抜けglitch
2:14 PM
見入ってて全然コメントできませんでしたが、とてもおもしろかったです ☺
Avatar
ありがとうございました!!面白かったです
Avatar
ありがとうございました!!
Avatar
ありがとうございましたー!
Avatar
とんとんぼ 1/27/2024 2:14 PM
ありがとうございました!
Avatar
たしかに今回は見入ってしまった👏
Avatar
ありがとうございました。楽しかったです!👏👏👏
Avatar
ありがとうございました!👏
Avatar
いますえ 1/27/2024 2:15 PM
ありがとうございました!
Avatar
ありがとうございましたー
Avatar
楽しんでもらえたみたいでよかったです!ありがとうございました!!
👏 9
Avatar
本日21:00〜のSwift Zoomin' #18でこちらのチャンネルを使います。よろしくおねがいします! https://twitter.com/koher/status/1783460589106540929
土曜日21時から、Swiftのエラーハンドリングの復習と、Swift 6で追加予定のTyped Throwsについて、実演しながら話します。 #swiftzoomin https://t.co/mmKQlsGK2U
🙌 10
Avatar
さっそくですが次回URLです https://swift-tweets.connpass.com/event/317594/
# Swift Zoomin' #19 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 未定 # 参加方法 日時: 2024 年 7 月 13 日(土) 21:00- 本ページより参加登録をして下さい。 当日の開始 1 時間程前に参加のための URL を連絡しますので、connpassからのメールを受信できる状態にしておいてく...
swift 5
12:12 PM
まずはSwiftのエラーハンドリングの復習から
Avatar
The Swift Programming Language. Contribute to apple/swift development by creating an account on GitHub.
👍 4
Avatar
これは良い余談
Avatar
... は確かに使ったことなかった〜
Avatar
let a: Int? = Int("2") let b: Int? = Int("x") let sum: Int? = a.flatMap { a in b.map { b in a + b } } print(sum as Any)
12:25 PM
guard let a = Int("2") else { // エラーハンドリング } print(a + 1)
12:25 PM
var stack = [2, 3, 5] print(stack.popLast() as Any) print(stack.popLast() as Any) print(stack.popLast() as Any) print(stack.popLast() as Any) var queue: ArraySlice<Int> = [2, 3, 5] print(queue.popFirst() as Any) print(queue.popFirst() as Any) print(queue.popFirst() as Any) print(queue.popFirst() as Any) let array: [Int] = [2, 3, 5, 7, 11] let slice: ArraySlice<Int> = array[...] print(slice)
12:27 PM
// Recoverable errors do { try foo() } catch { // エラーハンドリング }
Avatar
いま来た人向け)Swiftの4種類のエラーについて復習中です 1. Simple domain error 2. Recoverable error 3. Universal error 4. Logic failure (edited)
Avatar
func foo(values: [Int]) throws { if values.isEmpty { return } let shuffled = values.shuffled() guard let first = shuffled.first else { // preconditionFailure("...") try foo() } } do { let array = [2, 3, 5] let a: Int = array[0] let dictionary = ["a": 2, "b": 3, "c": 5] let b: Int? = dictionary["a"] } extension Array where Element: Comparable { mutating func mySort() { for i in indices { for j in indices.dropFirst(i) { // guard let a = self[i], let b = self[j] else { // // ??? // } if self[j] < self[i] { // let t = self[i] // self[i] = self[j] // self[j] = t swapAt(i, j) } } } } } var array = [3, 2, 7, 5] array.mySort() print(array) //extension Array { // func subscript(index: Int) -> Element { // precondition(indices.contains(index), "Index out of range.") // // } //} struct FooError: Error {} func foo() throws -> Never { throw FooError() } print(Array(zip([2, 3, 5, 7], ["a", "b", "c"]))) func myZip<T, U>(_ ts: [T], _ us: [U]) -> [(T, U)] { var result: [(T, U)] = [] for i in ts.indices { guard us.indices.contains(i) else { break } result.append((ts[i], us[i])) } assert(result.count == min(ts.count, us.count)) return result }
Avatar
propagation = 伝播、伝達 (edited)
Avatar
// Manual propagation struct FooError: Error {} func foo(string: String) -> Result<Int, FooError> { guard let number = Int(string) else { return .failure(FooError()) } return .success(number) } // Automatic propagation func foo(string: String) throws -> Int { let a = try bar() let b = try baz() return a + b }
Avatar
// Manual propagation struct FooError: Error {} func foo(string: String) -> Result<Int, FooError> { guard let number = Int(string) else { return .failure(FooError()) } return .success(number) } let a: Result<Int, any Error> = .success(2) let b: Result<Int, any Error> = .failure(FooError()) let sum: Result<Int, any Error> = a.flatMap { a in b.map { b in a + b } } print(sum) // Automatic propagation //func foo(string: String) throws -> Int { // let a = try bar() // let b = try baz() // return a + b //} //do { // try inputStream.readLine() // // try inputStream.readLine() // try inputStream.readLine() // try inputStream.readLine() // //} catch { // // エラーハンドリング //} // do { try foo() bar() try baz() } catch { // エラーハンドリング }
Avatar
// Typed propagation enum FooError: Error { case bar case baz } func foo() throws -> Int { 42 } func main() { do { print(try foo()) } catch { // エラーハンドリング } }
Avatar
//let a: Result<Int, any Error> = .success(2) //let b: Result<Int, any Error> = .success(3) // //func foo() throws -> Int //func foo() -> Result<Int, any Error> // //let sum: Result<Int, any Error> = a.flatMap { a in // b.flatMap { b in // .success(a + b) // } //} // //print(sum) let a: Task<Int, Never> = .init { return 2 } let b: Task<Int, Never> = .init { return 3 } extension Task where Failure == Never { func map<T>(_ body: @escaping (Success) -> T) -> Task<T, Never> { Task<T, Never> { body(await value) } } func flatMap<T>(_ body: @escaping (Success) -> Task<T, Never>) -> Task<T, Never> { Task<T, Never> { await body(await value).value } } } let square: Task<Int, Never> = b.map { $0 * $0 } print(await square.value) let sum: Task<Int, Never> = a.flatMap { a in b.map { b in a + b } } print(await sum.value)
Avatar
enum FooError: Error { case bar case baz(Int) } func foo() throws(FooError) -> Int { if Bool.random() { return 42 } else { throw .bar } } func main() { do { print(try foo()) } catch { switch error { case .bar: print("bar") case .baz(let x): print("baz: \(x)") } } } func main() { do { print(try foo()) } catch .bar { print("bar)") } catch .baz(let x) { print("baz: \(x)") } catch { preconditionFailure("Never reaches here.") } } main()
1:50 PM
// 複数のエラー型をthrowするとき enum FooError: Error { case bar case baz(Int) } enum BarError: Error {} func foo() throws(FooError) -> Int { if Bool.random() { return 42 } else { throw .bar } } func bar() throws(BarError) { } func main() { do { print(try foo()) try bar() } catch let error as FooError { print("foo: \(error)") } catch let error as BarError { print("bar: \(error)") } catch { preconditionFailure("Never reaches here.") } }
1:53 PM
enum FooError: Error { case bar case baz(Int) } enum BarError: Error {} func foo() throws(FooError) -> Int { if Bool.random() { return 42 } else { throw .bar } } func bar() throws(BarError) { } func main() { do throws(FooError) { print(try foo()) _ = try foo() } catch { switch error { case .bar: print("bar") case .baz(let x): print("baz: \(x)") } } }
Avatar
func foo() throws(Never) -> Int { 42 } func foo() -> Int { 42 }
1:56 PM
func foo() throws(any Error) -> Int { 42 } func foo() throws -> Int { 42 }
🍵 1
Avatar
enum FooError: Error { case bar case baz(Int) } func foo(_ x: Int) throws(FooError) -> Int { if Bool.random() { throw .bar } return x * x } //func foo() throws -> Int { // 42 //} extension Array { // func myMap<T>(_ transform: (Element) throws -> T) rethrows -> [T] { // var result: [T] = [] // for element in self { // result.append(try transform(element)) // } // return result // } func myMap<T, E: Error>(_ transform: (Element) throws(E) -> T) throws(E) -> [T] { var result: [T] = [] for element in self { result.append(try transform(element)) } return result } } let array = [2, 3, 5] print(array.myMap { $0 * $0 }) do { print(try array.myMap { try foo($0) }) } catch { print(error) } func main() { // do throws(FooError) { // print(try foo()) // _ = try foo() // } catch { // switch error { // case .bar: // print("bar") // case .baz(let x): // print("baz: \(x)") // } // } } let result: Result<Int, FooError> = .failure(.bar) do { try result.get() } catch { print(error) }
2:15 PM
enum FooError: Error { case bar case baz(Int) } func foo(_ x: Int) async throws(FooError) -> Int { if Bool.random() { throw .bar } return x * x } Task { async let x = foo(3) do { print(try await x) } catch { print(error) } }
Avatar
let never: () throws(Never) -> Void = {} let cat: () throws(CatError) -> Void = never let animal: () throws(AnimalError) -> Void = cat let creature: () throws(any Error) -> Void = animal
2:26 PM
let creature: (() throws(any Error) -> Void) -> Void = { _ in } let animal: (() throws(AnimalError) -> Void) -> Void = creature let cat: (() throws(CatError) -> Void) -> Void = animal let never: (() throws(Never) -> Void) -> Void = cat
Avatar
あんまり関係なく初歩的な質問ですが、preconditionとfatalErrorの使い分けについてご意見を伺いたいです!
2:29 PM
あそうそうPreconditionFailureです (edited)
Avatar
エラーの4分類で、preconditionFailure は Logic failure で、 fatalError は Universal error じゃないですかね。
Avatar
throws(FooError、BarError)みたいに複数指定はできない感じでしょうか?
Avatar
これは Swift Tweets の発表をまとめたものです(次回開催はこちら)。イベントのスポンサーとして Qiita に許可をいただいた上で投稿しています。ありがとうございました!Q&Aは他の人…
Avatar
その記憶は koher さんに作られたものだったかw
😆 4
Avatar
ありがとうございます
Avatar
ありがとうございます!
Avatar
ジュニア 4/27/2024 2:40 PM
こういう設計裏話おもしろいですよね
Avatar
Swiftzoominはqoncept様のZoom を使わせていただいております 🙏 https://qoncept.co.jp/
Qonceptは、AR(拡張現実感)を中心に画像処理技術を研究レベルから実用レベルに高め、実社会に浸透させることを目的とした、研究開発型ベンチャー企業です。
t_kansha 5
2:46 PM
# Swift Zoomin' #19 Swift Zoomin' はプログラミング言語 Swift に関するオンラインイベントです。 Zoom と Discord を使って開催されます。 Discord については swift-developers-japan サーバーの #swift-zoomin チャンネルを利用します。 # 内容 未定 # 参加方法 日時: 2024 年 7 月 13 日(土) 21:00- 本ページより参加登録をして下さい。 当日の開始 1 時間程前に参加のための URL を連絡しますので、connpassからのメールを受信できる状態にしておいてく...
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました!!
Avatar
ありがとうございました!余談含めてとても勉強になりました🙏
Avatar
お疲れ様でした〜ありがとうございました!
Avatar
皆様ありがとうございました!
Avatar
ジュニア 4/27/2024 2:48 PM
ありがとうございました!とても面白かったです!
Avatar
ありがとうございました!!!
Avatar
Swiftで競プロしてたので余談も勉強になりました!
Avatar
ありがとうございました!
Avatar
ありがとうございました!
Avatar
ありがとうございました!!😊
Avatar
遅くまでお付き合いありがとうございましたー🙏
swift 8
Exported 3,386 message(s)
Timezone: UTC+0