Guild icon
swift-developers-japan
main / swift
Avatar
omochimetaru 3/21/2017 2:16 AM
こっちにも貼っとくか
2:16 AM
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
Avatar
これは僕もfileprivate導入しっくり来てなかったです( ´・‿・`) (edited)
2:17 AM
ファイルスコープのprivate概念自体は好きです
Avatar
omochimetaru 3/21/2017 2:17 AM
「fileprivate廃止してswift2仕様に戻そうぜ」
Avatar
The private keyword should be reverted back to its Swift 2 file-based meaning and the fileprivate keyword should be deprecated.
これ派ですね
2:20 AM
こんなすぐ戻そう議論が出てくるくらいのものを https://github.com/apple/swift-evolution/blob/master/proposals/0025-scoped-access-level.md でどうして採用に至ってしまったのかなと不思議です🤔 メーリス漁れば分かりそうですが
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
Avatar
omochimetaru 3/21/2017 2:21 AM
そこらへんの空気感は謎ですね
🤔 1
2:22 AM
自分自身は、微妙な気はしつつも、SE25のレビュープロセスの時に当事者意識は無いので何も言えんけど (edited)
2:25 AM
@mono ここって招待自由ですか?
Avatar
@omochimetaru 自由です、アクセス権など弄って無いですが、それもじゃんじゃん付与してしまってよいかな気分です( ´・‿・`) でも、作って放置状態なので、ちゃんと話したい場合、 https://ios-developers-ja.slack.com の方がオススメだと思いますが( ´・‿・`)
Avatar
omochimetaru 3/21/2017 2:27 AM
@mono あれ、こんなのもあるの・・・
Avatar
omochimetaru 3/21/2017 2:28 AM
ほんとだ
Avatar
omochimetaru 3/21/2017 2:38 AM
あつまった
🎉 2
2:40 AM
@hiragram さっきの件だけど、メソッド足すだけでconformできるのと、フィールドも足さないとできないのは大きな違いがあると思う
Avatar
一番新しいので言うと、cellHeightsを管理するのは誰ぞという。何かしら任意のタイミングで変更しなきゃ使えないじゃん
2:42 AM
アイコン変えたい
Avatar
omochimetaru 3/21/2017 2:42 AM
@tarunon アイコン設定しよ
Avatar
変えた
Avatar
@tarunon willDisplayCellcellHeights を更新して、 estimatedRowHeightAtIndexPath で読み出すからdelegateメソッドでしか使われてないよね、という話ではなく?
2:43 AM
@mono おじゃまします 🙏
Avatar
omochimetaru 3/21/2017 2:45 AM
気持ちはわかる
Avatar
willDisplayCellだとestimatedRowHeightに関与できなくね
2:45 AM
できるの?
2:45 AM
おっと、打ち合せだ、一旦離脱します
Avatar
omochimetaru 3/21/2017 2:46 AM
気持ちはわかるんだけど、なんかそういうの楽にやりたいとかは、ビューとかに限った話で
Avatar
humu
Avatar
omochimetaru 3/21/2017 2:46 AM
ライブラリとかでそういうフィールドが外装されてる可能性があるとしんどい
Avatar
そのしんどみがまだピンときてないんだけど、ライブラリ使用者としてということだよね
Avatar
最近カスタムビュー作るほどではないなってときに Extension でプロパティ持てなくて死んだし、気持ちとしては間違いなくあるもののうーん
Avatar
omochimetaru 3/21/2017 2:47 AM
@biacco42 カスタムビューじゃないのにプロパティもつ意味がぜんぜんわからん
2:48 AM
@biacco42 生のUIViewを改造したいって意味?
2:48 AM
@hiragram そうだね、どこから何が変化してどういう状態遷移するのか、ソースコードだけから追いかけようとした時に
2:48 AM
@hiragram フィールド(StoredProperty)ってのは足場として重要
Avatar
ImageView にドラッグアンドドロップお試しでつけたいなー、お、Extension あるやんけ(死亡) みたいな (edited)
Avatar
あー、状態を持つものがあっちこっちにあるとそもそも読むの辛いよねという話ね
Avatar
omochimetaru 3/21/2017 2:48 AM
@biacco42 なんかそれは逆に継承してカスタムビュー作れば良いだけの話じゃない?
2:49 AM
カスタムビュー作るほどではない
2:49 AM
↑ここが気持ちが弱いだけに見える
2:49 AM
カジュアルにカスタムすればいいだけ
Avatar
気持ちが弱いのはそれはそう
Avatar
omochimetaru 3/21/2017 2:49 AM
あと、もしそれができちゃうと、別の所のImageViewも影響を受けちゃう
Avatar
それは思った
Avatar
omochimetaru 3/21/2017 2:50 AM
@hiragram うんうん
Avatar
読むの辛いはわかるものの、やっぱりextension+stored property欲しいという気持ちはある
Avatar
omochimetaru 3/21/2017 2:52 AM
問題はさ
2:52 AM
そのstored propertyがそのextensionだけからしか使われて無ければ
2:52 AM
いいけど
2:52 AM
そのstored propertyをまた他のところから参照してたりするとカオスになりそう
Avatar
それはわかる
Avatar
omochimetaru 3/21/2017 2:53 AM
@hiragram なので、ViewControllerとかは、あまり読む事大事じゃないと思ってて、1度書くことの重要性が実際高いと思う
2:53 AM
ViewControllerは画面仕様と結合度が高いから再利用する事自体稀だし。
Avatar
やりたいことはスコープというか文脈ごとにextensionを分けてその中のprivateなメソッドとプロパティで全部それぞれが完結して他のextension同士は互いを知らなくていいっていうのがやりたいなあなのでextension内のプロパティをそのスコープ外に公開したいきもちはない
Avatar
omochimetaru 3/21/2017 2:54 AM
それってさ
2:54 AM
そのやりたいことの単位を
Avatar
型に分けろ説はある
Avatar
omochimetaru 3/21/2017 2:54 AM
classかstructにまとめれば
2:54 AM
保証できるのでは?
Avatar
それな
Avatar
omochimetaru 3/21/2017 2:55 AM
で、実装本体は、そのまとめた単位を並べるコードと
2:55 AM
メソッドをそのまま転送するコードの束にすると
2:55 AM
見通しが良さそうだし再利用性も高そう。
Avatar
やっぱちゃんとやるならそうやって型に分けるべきだよね〜
Avatar
omochimetaru 3/21/2017 2:56 AM
やりたいことをextensionごとにわけて隔離するつもりがあるなら、型切っておけばうっかり相互依存するのも防げるしね
Avatar
でっかいクラスをザクザクextensionに分けまくっていらないプロパティを消しまくるみたいなリファクタを最近やったのでextension好き〜という気持ちが勝手に高まってるだけかもしれない
Avatar
omochimetaru 3/21/2017 2:57 AM
なるほど
2:57 AM
なんか引き継ぎで萎えてたやつかな
Avatar
そう
Avatar
omochimetaru 3/21/2017 3:02 AM
やっぱextensionでフィールド追加は良くないなあと思ってきた
3:02 AM
最近カスタムビュー作るほどではないなってときに Extension でプロパティ持てなくて死んだし、気持ちとしては間違いなくあるもののうーん
3:02 AM
↑これが氾濫しそう
3:03 AM
hirariの言ってる自作クラスの実装の縦割りのためならまだわかるけど
3:03 AM
UIKitに対してそれをやるようになって
3:03 AM
秩序が完全に終わりそう
Avatar
カスタムビュー作るほどではない
プロダクトコードなら殴りそう
3:04 AM
まーTextKitの系がヒラギノでレンダリング終わってて一括で変えたいとかはあるんだけど
Avatar
前述の通りプロトタイピングでお試し実装したかったときなのでさすがにプロダクションには載せないですね…
Avatar
omochimetaru 3/21/2017 3:04 AM
OtameshiImageView一個作っておけばok
💪 1
Avatar
UIKitに対してそれをやるようになって秩序が完全に終わりそう
それは起きそうなので出来なくていいので https://twitter.com/hiragram/status/844008993932505089 class HogeObj { } が書いてあるファイルでのみHogeObjのextensionにstored propertyを持たせられるようになったらな〜という話。これだったらUIKitのクラスに対してextensionでstored property足せない
大元の定義と同じファイル内だったらextension内でstored property使えるようにしてくれよ
Avatar
omochimetaru 3/21/2017 3:11 AM
なるほど。
Avatar
自作クラスの実装の縦割りのためならまだわかるけど
コレだけができれば僕ははっぴー
Avatar
omochimetaru 3/21/2017 3:11 AM
class本文の中で // MARK: -- で分けるのはどうかと思ったけど、 protocol conformanceが一番上に集まっちゃうから微妙かな (edited)
Avatar
結局みんなどうしてるのか気になる
Avatar
「このプロパティはこの範囲でしか使われない」ということを明示したくて、且つその範囲をなるだけ狭くしたいので、それだと達成できないかなー
Avatar
omochimetaru 3/21/2017 3:13 AM
やはりそれは別classだなという感じがしてくるw
3:13 AM
機能要件としては完全にそう
3:14 AM
他の言語だと、「あるprotocolへのconformanceは、フィールドでもってるこのオブジェクトに全部転送する」ことを1行で記述できたりするんで
Avatar
それが欲しいな
Avatar
omochimetaru 3/21/2017 3:14 AM
そういうのがあるとクラスで分けた時に、転送メソッドを書き下す手間が無くて良さそうじゃないか
Avatar
@omochimetaru それきになる 他の言語ってたとえばどれですか
Avatar
omochimetaru 3/21/2017 3:15 AM
ちょっとまってね
Avatar
omochimetaru 3/21/2017 3:23 AM
Rustで見た気がしたけど提案にすぎなかった
3:23 AM
Sorry if something similar has already been proposed. In short A nice feature of usual OO languages is the implicit code reuse through inheritance: the fact a subclass does not need to redeclare any method existing in its base class provided the behaviour is the one expected. Wouldn't it be a nice feature if Rust had some syntaxic sugar to mimic this ? Composition and inheritance When I have: // java-like language interface Foo { void doSomething(); } class Bar : Foo { void do...
3:23 AM
委譲 (delegation) とはオブジェクト指向プログラミングにおいて、あるオブジェクトの操作を一部他のオブジェクトに代替させる手法のこと。
3:23 AM
Go[編集] Go言語においては、他の言語と異なり始めから委譲を想定した委譲専用構文を備えている。
(edited)
3:24 AM
Goもそれっぽい機能があったけどなんか詳細が、コレじゃない感
Avatar
Goか
Avatar
omochimetaru 3/21/2017 3:25 AM
rubyのこれも近いけど、言語自体にinterfaceが無いせいでメソッド全部並べてるな・・・
3:26 AM
Kotlin is a statically typed programming language for the JVM, Android and the browser, 100% interoperable with Java
3:26 AM
あった!
3:26 AM
kotlinだ!
3:26 AM
interface Base { fun print() } class Derived(b: Base) : Base by b
3:27 AM
bはこれ、型名のところに書いてるけどコンストラクタ引数とフィールド定義を同時にやってるので、 bBase 型のフィールドで、 DerivedBase に conformさせるのを by b で指定してる。
3:28 AM
The by-clause in the supertype list for Derived indicates that b will be stored internally in objects of Derived and the compiler will generate all the methods of Base that forward to b.
Avatar
"Baseに準拠したbをもってDerivedもBaseに適合したことにする" ということよね
Avatar
omochimetaru 3/21/2017 3:29 AM
そうです〜
Avatar
これは良い
Avatar
omochimetaru 3/21/2017 3:29 AM
これが class の右にしか書けないけど、 Swiftなら conformanceがそもそもextensionに書けるわけだから
3:30 AM
extension UserStatusViewController : UIScrollViewDelegate by scrollViewDelegateMixIn {}
3:30 AM
みたいに書けたらイイネ
Avatar
おー
Avatar
omochimetaru 3/21/2017 3:31 AM
scrollViewDelegateMixInUserStatusViewController の storedProperty名で struct ScrollViewDelegateMixIn : UIScrollViewDelegate という型がついてる想定。 (edited)
3:31 AM
あーまあフィールドは class { } の中に書かないといけないならkotlinみたいに上のところでもいいのかな
Avatar
今でもscrollViewDelegateの実装をクラスに切り出すことは出来るはずで(VCがGenericsなら3.1以降で)
6:36 AM
extension ViewController { class ScrollViewDelegate: UIScrollViewDelegate { //ここに実装 } } だけどこれでも、ViewController.ScrollViewDelegateの宣言は本体側にないといけないよね、そこは解決しないのでは。まあすっきりはするか。
Avatar
omochimetaru 3/21/2017 6:42 AM
@tarunon うん、ここで話してたのは、クラスを切っても結局デリゲートメソッドを転送するだけのメソッドを全部書かないといけないのがめんどいね、という問題がのこるので、そこの糖衣構文がほしいねという事
Avatar
別にViewController.ScrollViewDelegateをDelegateにセットする、でも現状大きな問題ない気がするけどな
Avatar
それおもった
Avatar
だけど、糖衣構文が有ろうと無かろうと、var scrollViewDelegate: ScrollViewDelegateをどこに書くの?と言う問題は残っている
Avatar
omochimetaru 3/21/2017 6:47 AM
@tarunon ああ〜 tableView.delegate = self の右辺が self じゃなくてもいいじゃんって事か
Avatar
そう
Avatar
omochimetaru 3/21/2017 6:47 AM
すっかり忘れてたけどそれは確かにありだね
Avatar
class ScrollViewDelegate: NSObject, UIScrollViewDelegate { weak var parent: ViewController? } とかでまあおおよそ問題はないはず
Avatar
omochimetaru 3/21/2017 6:48 AM
var を書くのは本体class {} 部分でいいじゃんと思ってるけどね〜
Avatar
それでいいなら現状そういう作り方すれば問題はなくなる
6:49 AM
どこに入れるかは趣味がありそうだけどね
Avatar
omochimetaru 3/21/2017 6:49 AM
まあ、それで解決するのはScrollViewみたいな .delegate = なケースだけで (edited)
6:49 AM
一般のprotocol conformanceの話では成り立たないけど
Avatar
そうね
Avatar
omochimetaru 3/21/2017 6:51 AM
あれ、Discordって
6:51 AM
syntaxハイライトあるのか。
💯 1
Avatar
適当にmarkdown書いたら普通に動いてびっくりしてる
Avatar
omochimetaru 3/21/2017 6:52 AM
Slackに対する優位性だ
6:57 AM
let a = 3
6:57 AM
let a = 3
6:57 AM
おお〜〜〜
6:57 AM
言語指定構文も使えるやんけ
Avatar
めっちゃいいじゃんこれ
Avatar
# 見出し
6:57 AM
コードブロックだけか
Avatar
omochimetaru 3/21/2017 6:58 AM
  • aaa
6:58 AM
strong1 strong2 (edited)
Avatar
  • や _ による強調はできたけど
Avatar
引用もさっき使った感じなかった気がする
Avatar
箇条書きやリンクはできなかった
Avatar
引用だめなのか
Avatar
custom emojiはないんですか
Avatar
omochimetaru 3/21/2017 6:59 AM
@hiragram あるよ
Avatar
あ、リンクってのは Swift みたいなの。
Avatar
あるのか
Avatar
omochimetaru 3/21/2017 6:59 AM
僕が入ってる身内の鯖で変な絵文字流行ってる
Avatar
シンタックスハイライトはいいなぁ。できれば箇条書きもほしいけど。
Avatar
omochimetaru 3/21/2017 6:59 AM
- aaa - bbb
6:59 AM
なるほど
Avatar
@omochimetaru なんでコードフェンスの中に箇条書き書いてるの??
Avatar
omochimetaru 3/21/2017 7:01 AM
@koher なんかこの中がすごい構文なのかなって試した
7:01 AM
画面共有機能を含む「Discord」のアップデート予告が公開 https://t.co/YpgCv5yPkh
7:01 AM
画面共有できるようになるならSkypeのユースケース消えるわ
Avatar
引用は結構使うから > で引用できないのはちょっと微妙だなぁ。
Avatar
omochimetaru 3/21/2017 7:03 AM
@koher 引用や箇条書きは > や - のままでも見た目にわかるし平気な気もする
Avatar
@omochimetaru まあ、たしかに Slack みたいに >> の二段目だけ > になっちゃうよりマシかも?
Avatar
omochimetaru 3/21/2017 7:04 AM
2段目問題なんてあったのかw
Avatar
とりあえず > とか - で書いておいて Discord のアップデートに期待とか
👍 2
9:22 AM
@koher との合作でコメント投稿した
9:23 AM
class C { p: number; // Should be an error under --strictNullChecks method() { this.p; } }
💯 1
Avatar
やっぱ GitHub だと見やすいね。 Swift の ML も早く移行してほしい。
Avatar
omochimetaru 3/22/2017 9:23 AM
Swiftユーザー各位には信じられないと思うがTypeScriptが提供する --strictNullChecks は このようなコンストラクタでのフィールドの初期化忘れに対して何も検査しないため 簡単に undefined を踏むのだ (edited)
Avatar
Githubに移行して治安維持出来るのか気になるマン
Avatar
omochimetaru 3/22/2017 9:27 AM
GithubじゃなくてDiscorseという掲示板?サービスよ
9:28 AM
治安は悪くなるけどそれこそこういう事は減るんじゃないかな・・・ https://github.com/apple/swift-evolution/blob/master/proposals/0159-fix-private-access-levels.md
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
Avatar
www
9:29 AM
「俺達は雰囲気でfileprivateとprivateを使い分けている」
9:29 AM
って割りとありそう
Avatar
今日まさに、 private プロパティに(同じファイル中の) extension からアクセスしようとして残念な気持ちになった。
9:30 AM
private let な定数をそっと ViewController の外に出した・・・
Avatar
omochimetaru 3/22/2017 9:30 AM
外w
Avatar
private struct Hoge {} fileprivate struct Hoge {} これが一番モニョい
Avatar
omochimetaru 3/22/2017 9:31 AM
@tarunon 別に定義できんの?
Avatar
いや違う
9:31 AM
両者が(多分)同じ
9:31 AM
ああ、中身が外から見れなくなる違いはあるか?
Avatar
確かにトップレベル private 書く時、意味が fileprivate なので微妙な気持ちになる。private func とか。
Avatar
omochimetaru 3/22/2017 9:32 AM
あ、そうなのか。なるほど。
9:32 AM
トップレベルにおけるprivateはスコープがファイル、みたいな雰囲気か
9:33 AM
クラスの中とかだとprivateがそのクラス自身でfileprivateだと外側のファイルレベルまで広がると
Avatar
そのクラス自身
そのスコープ。同じファイルでも extension の中からはアクセスできない
Avatar
omochimetaru 3/22/2017 9:34 AM
extensionはクラスの外ってイメージでした。
9:36 AM
SwiftMLのフォーラム引越しのスレ見て
9:36 AM
スレッド別れまくってて「いいね!」みたいなレスがついてるだけだったりして
9:36 AM
やはりMLは無理ではという気持ちになる
9:37 AM
「引越しプランは追って出すけど忙しいからとりあえず方向性だけアナウンスしたよ」 って感じのようですね
Avatar
今日まさに、 private プロパティに(同じファイル中の) extension からアクセスしようとして残念な気持ちになった。
昨日まさに同じことになってた
Avatar
omochimetaru 3/23/2017 2:21 AM
class Cat { var a: String { didSet { // 呼ばれない print("nyaa") } } init() { self.a = "a" } } Cat() @here 知ってた?
Avatar
知ってる
Avatar
omochimetaru 3/23/2017 2:21 AM
おー
Avatar
最初にdidSet呼ばれない、はーーー
2:21 AM
ってやった
Avatar
omochimetaru 3/23/2017 2:21 AM
今ためしてて気づいてた。
Avatar
didSetはselfのメンバにアクセスできるから
Avatar
omochimetaru 3/23/2017 2:22 AM
そう!
Avatar
initより前に使えると破綻する
Avatar
omochimetaru 3/23/2017 2:22 AM
そのあたりの挙動を探ってて俺の推測も同じ結論。
2:23 AM
ワンチャンswiftも本物のヌルポが出せるのかと思ったが残念。
Avatar
omochimetaru 3/23/2017 4:38 AM
調べたけどよくわからなくなった
4:39 AM
https://gist.github.com/omochi/90326839d097cc162c0d7e30d5f5e9bb IUOの暗黙キャストについて調べた結果。メソッド呼び出しは T? へのキャストはされない事がわかった。 TT? 両方行けるときは T? になることがわかった。
Avatar
まあ妥当だと思う
4:39 AM
だけど遅そう
Avatar
omochimetaru 3/23/2017 4:39 AM
https://gist.github.com/omochi/ea49fb9cae8b1073c6cedfa1661b697c 元々のコンパイル時間の増大について調べた結果。要素が1つ増えると、コンパイル時間が4倍に増える。
4:41 AM
両方通る場合は T? になることから、 T では駄目になる事を検証しているという仮説は成り立たなかった。 TT? の倍々で増えていくという仮説についても、 4倍で増えていくことから成り立たなかった。
Avatar
うーん
4:45 AM
4:45 AM
これを見る限りはTとT?があり得る場合にTを優先しているようにも見えるんだが
Avatar
omochimetaru 3/23/2017 4:46 AM
ちゃう、それは俺の検証見るとわかるけど、そもそもメソッド呼び出しの時は T? への暗黙キャストはしない。
4:46 AM
.hoge() ってドット構文になった時点で Int しか試されない。
Avatar
ふむ
Avatar
omochimetaru 3/23/2017 4:47 AM
両方を試すのは関数が引数IntとInt?でオーバロードされてるときだった。
Avatar
func commonIntFunc(_ x: Int?) -> Int {...} func commonIntFunc(_ x: Int!) -> Int {...} この2つは共存出来ないのか
Avatar
omochimetaru 3/23/2017 4:49 AM
マジか
Avatar
IntとInt!は共存できるので
4:50 AM
引数としてはInt?の扱いに近い
Avatar
omochimetaru 3/23/2017 4:50 AM
ほんとだ〜〜
Avatar
この検証だと
4:51 AM
引数の時に特別扱いされることが考慮されていないので
4:51 AM
Int?が優先される証左にはならない気がする
Avatar
omochimetaru 3/23/2017 4:51 AM
うーんでも、純粋な検証はそもそもできないよ
Avatar
まあそらなw
Avatar
omochimetaru 3/23/2017 4:51 AM
常に何かしらの場合に依存した検証になってしまう。 (edited)
4:52 AM
さっきのはコンストラクタ呼び出しだったから
4:52 AM
コンストラクタ呼び出しと関数呼び出しで挙動が違う可能性は否定できないから
4:52 AM
まあコンストラクタも試してみたほうがいいかも。
Avatar
コンストラクタも同じっぽいね
4:53 AM
でもこれ
4:54 AM
TとT?をオーバーロードしてる時にどっちを優先するか、と
4:54 AM
T!からT?へキャストをするときの性質がどうなのか
4:54 AM
は、完全に別の問題な気がしていて
4:54 AM
この検証は面白い結果だけど
Avatar
ww
Avatar
omochimetaru 3/23/2017 7:59 AM
16個を試すと退勤時刻が来る・・・
Avatar
どんなmacでやってるのん
Avatar
omochimetaru 3/23/2017 7:59 AM
@hiragram ひらりのやつは引数が2個だったけど、シンプルに1個にして調べたよ
Avatar
okok
Avatar
omochimetaru 3/23/2017 8:00 AM
MacBook (Retina, 12-inch, Early 2015)
Avatar
ちっさいやつか
Avatar
omochimetaru 3/23/2017 8:00 AM
1.3 GHz Intel Core M
Avatar
つらすぎる
Avatar
omochimetaru 3/23/2017 8:00 AM
機種名: MacBook 機種ID: MacBook8,1 プロセッサ名: Intel Core M プロセッサ速度: 1.3 GHz プロセッサの個数: 1 コアの総数: 2 二次キャッシュ(コア単位): 256 KB 三次キャッシュ: 4 MB メモリ: 8 GB
Avatar
引数
引数2個で、5KのiMacで配列が6個のとき15秒なんだけど、引数1と2でこんなに違うんね
Avatar
omochimetaru 3/23/2017 8:01 AM
多分引数2個で要素6個は引数1個で12要素と同じだから
8:02 AM
で、僕のだと12個のとき33秒だから
8:02 AM
そっちが15秒なら2倍ぐらいの速度が出てるってことかな?
8:02 AM
多分並列化が効かないタスクで単純に周波数のスピードになってる
Avatar
2x6ってことか
Avatar
omochimetaru 3/23/2017 8:03 AM
3GHz x 4core ぐらいじゃない?
Avatar
↑機種名のやつってどこでみれるの
Avatar
omochimetaru 3/23/2017 8:03 AM
で、単純に単一コアでの3GHz : 1.3GHzの比率
8:03 AM
左上のりんごのアイコンから
8:03 AM
このmacについて → システムレポート
Avatar
機種名: iMac 機種 ID: iMac17,1 プロセッサ名: Intel Core i7 プロセッサ速度: 4 GHz プロセッサの個数: 1 コアの総数: 4 二次キャッシュ(コア単位): 256 KB 三次キャッシュ: 8 MB メモリ: 32 GB
Avatar
omochimetaru 3/23/2017 8:04 AM
4G!
8:04 AM
つっよ
Avatar
会社のだよ
Avatar
omochimetaru 3/23/2017 8:04 AM
うん。
Avatar
Speeeはアプリエンジニアこれだよ
Avatar
omochimetaru 3/23/2017 8:04 AM
おー
8:04 AM
俺のも会社費用だけど、個人的な希望で軽い方がいいから
8:04 AM
スペックは下げてる。
8:05 AM
MBP15inchの人が多いね。
Avatar
いま1個席が空いて1台余ってるのでスピ社どうぞ
Avatar
うちはMBP15inchすな
8:05 AM
ww
Avatar
omochimetaru 3/23/2017 8:05 AM
ここでリクルートするなw
Avatar
MBP Touch bar だけど、外付けキーボードないと発狂するよ
Avatar
omochimetaru 3/23/2017 8:05 AM
hiraraiためしに俺のgistのコードそのまんまで12個にしてやってみると何秒か教えて欲しい
Avatar
ok
Avatar
omochimetaru 3/23/2017 8:06 AM
俺は計測は time コマンドの real を張ってる。1回しかやってないし他の作業も止めてないからだいぶガバガバだけど。 (edited)
Avatar
~ (๑˃̵ᴗ˂̵)ﻭ < time swiftc compile.swift -o compile swiftc compile.swift -o compile 15.78s user 0.30s system 99% cpu 16.137 total
8:07 AM
33秒と比べると半分くらいか
Avatar
omochimetaru 3/23/2017 8:08 AM
引数2個x要素6個のときの12秒って結果とほぼおなじってことか。
Avatar
ぽい
8:12 AM
プロンプトが可愛いということに誰も触れてくれなくてかなしい
Avatar
omochimetaru 3/23/2017 8:13 AM
あ、それシェルに出てるのかw
Avatar
omochimetaru 3/23/2017 8:14 AM
いつ青い顔に変わるの?
Avatar
exit 0以外のとき
Avatar
omochimetaru 3/23/2017 8:14 AM
ステータスか
8:14 AM
へ〜
Avatar
Ctrl+Cしてもなる
Avatar
omochimetaru 3/23/2017 8:14 AM
Ctrl+Cはシグナル送るからだいたいそうなるね
Avatar
そそ
8:15 AM
コレ自体はどっかzshの設定といっしょに拾ってきた受け売りなんだけどね
8:15 AM
かわいいからきにいってる
Avatar
omochimetaru 3/23/2017 8:15 AM
なるほど
8:15 AM
かわいいけど飽きそう
Avatar
かなしい
Avatar
可愛いシェルより可愛いコード
8:21 AM
はやくして、やくめでしょ
Avatar
可愛いコードとは
Avatar
IUOでコンパイルタイム4^nは良いおやつだった
Avatar
おやつw
Avatar
fileprivateネタ手厚く載ってました( ´・‿・`) https://swiftweekly.github.io/issue-62/
This week swift-stdlib-tool was open-sourced, a number of proposals were accepted, Swift releases have themes, and a new proposal for fixing access controls in Swift is now under review!
Avatar
omochimetaru 3/24/2017 1:39 AM
TypeScriptの初期化をSwiftのように型安全にしようとして議論に参加している件だけど、 そもそもTSからコンパイルした先のJS ES2016のクラス機能の仕様が厳しくて、厳しくなってきた 厳しさ1. super()を呼び出した後でしか this が使えないためサブクラスのフィールドを埋める前に親クラスのコンストラクタが呼ばれる 厳しさ2. サブクラスのコンストラクタ内部で呼ばれた親クラスのコンストラクタにおいてメソッドを呼び出すと、それがサブクラスでオーバーライドされている場合、サブクラスの実装が呼ばれる これらの組み合わせによって、フィールドが未初期化のサブクラスのメソッドが呼ばれて、 undefined を踏む。 下記はその問題によって、純粋なJSユーザーが困っている事例2件 http://stackoverflow.com/questions/32615034/call-parent-function-which-is-being-overridden-by-child-during-constructor-chain http://stackoverflow.com/questions/32449880/parent-constructor-call-overriden-functions-before-all-child-constructors-are-fi
I've encounter a problem below with JavaScript(ES6) class A{ constructor(){ this.foo(); } foo(){ console.log("foo in A is called"); } } class B extends A{ constructor(){ sup...
ECMAScript 6 (Harmony) introduces classes with ability to inherit one from another. Suppose I have a game and some basic class to describe basic things for bot behavior. I simplify my real architec...
Avatar
omochimetaru 3/24/2017 2:02 AM
@mono 最後に乗ってるMatthewのコメントが不穏ですねw ファイルスコープになった private と、構文スコープになった scoped に再び分裂する、みたいな流れになったら草
Avatar
ww
Avatar
omochimetaru 3/24/2017 2:02 AM
たしかに機能が悪いんじゃなくてキーワードの名前が悪いって気はする。
Avatar
fileprivateと打つのは怠いですね
Avatar
omochimetaru 3/24/2017 2:03 AM
自然と手が伸びる方は private ですよねえ。
2:04 AM
お、 @ikesyo さんも来た (edited)
🤗 2
Avatar
omochimetaru 3/24/2017 2:43 AM
@here ここにKotlinのletメソッドについて知ってる人居ますか?Swiftに同じものを実装する事ができないんですけど、 @koher が演算子にしたらどう?って言っていて、わりと良さそうな気がしている。
2:45 AM
kotlinのletは・・・ https://github.com/JetBrains/kotlin/blob/1.1.0/libraries/stdlib/src/kotlin/util/Standard.kt#L62 /** * Calls the specified function [block] with `this` value as its argument and returns its result. */ @kotlin.internal.InlineOnly public inline fun <T, R> T.let(block: (T) -> R): R = block(this)
kotlin - The Kotlin Programming Language
2:46 AM
Rubyのtapとおそらく等価 http://ref.xaio.jp/ruby/classes/object/tap
2:47 AM
仮にこれを => 演算子でSwiftに導入すると、次のような事ができる
2:51 AM
// こんな関数があったとして func hogehogeFunc(str: String, int: Int) -> String { return "" } // こんなStructがあったとして struct Cat { var name: String var age: Int } // こんな関数が合ったとして func createPrettyCat() -> Cat { return Cat(name: "mike", age: 2) } // 従来は・・・ func demo1() { let cat = createPrettyCat() let result = hogehogeFunc(str: cat.name, int: cat.age) print(result) } // こういうのがシュッと1行にできなくて萎える // 提案のもとでは・・・ func demo2() { print(createPrettyCat() => { hogehogeFunc(str: $0.name, int: $0.age) }) } // 左から右にシュ〜っとかける
Avatar
Contribute to swiflet development by creating an account on GitHub.
2:53 AM
説明してる間に実装しちゃった。
2:53 AM
=> の方がいい?
Avatar
omochimetaru 3/24/2017 2:53 AM
@koher ホタルイカみたいな演算子 ->> より ダブルアローのほうが 打ちやすくていい
Avatar
任意の構造をモナドと見做してmapしたい感じですかね
Avatar
omochimetaru 3/24/2017 2:54 AM
モナドとは違うよ、 => 式の評価結果はクロージャの結果そのものだから、
Avatar
ですよねこれつよい
Avatar
omochimetaru 3/24/2017 2:54 AM
モナドに包まれる必要はない。
2:55 AM
ただ指摘の通り使い勝手はモナドに近い。
Avatar
確かに箱は存在してない
Avatar
=> にするか。
Avatar
Rubyのtapはレシーバ自身を返すので型変換はなく、等価じゃないですね
Avatar
omochimetaru 3/24/2017 2:55 AM
@ikesyo あ〜・・・そうですね
2:55 AM
あれ? tapの末尾に評価値かけなかったっけ
Avatar
hoge => { $0.piyo } => { $0.fuga }
Avatar
omochimetaru 3/24/2017 2:55 AM
@Biacco42 yes
2:55 AM
you can
Avatar
すごーい!たーのしー! (edited)
Avatar
omochimetaru 3/24/2017 2:56 AM
任意のテンポラリ値を変数に束縛できるので 左から右に書けない時に、だいたいそれができるようになります
2:56 AM
わざわざ let で変数におかなくちゃ〜〜 みたいな気持ちの時に効く
Avatar
Rename した
2:58 AM
前から @omochimetaru との間で Kotlin の let が Swift にほしい話があって、でも Any に extension でメソッド生やせないから諦めてた。
2:58 AM
で、さっきまたほしくなって、よく考えたら演算子だったらいいんじゃない?って思った。
2:58 AM
関数だと順序が気に入らないけど、演算子だと let メソッドと同じ順序で書ける。
Avatar
omochimetaru 3/24/2017 2:59 AM
それで、そうやってすぐ演算子に逃げるの良くないよと思ったんだけど、でも、Swiftでは何にでもあるメソッドって作れないから、実際メソッドとは違う特別な存在なんだよな、と思って。 (edited)
3:00 AM
class Cat attr_accessor :name, :age def initialize @name = "mike" @age = 3 end end p Cat.new.tap {|x| x.age } # => #<Cat:0x007f1790eb9b60 @name="mike", @age=3> Rubyのtapは確かに違った。。 (edited)
Avatar
SwiftPM に対応してるので、↓だけで使えます。 dependencies: [ .Package(url: "https://github.com/koher/swiflet.git", majorVersion: 0) ] (edited)
👏 1
Avatar
Objective-Cの時にまさにtapを作っていたのを思い出した https://github.com/ikesyo/NSObject-Tap
NSObject-Tap - tap: method for Objective-C borrowed from Ruby.
Avatar
omochimetaru 3/24/2017 3:40 AM
@ikesyo 本当だ〜
Avatar
この間のT! -> T?変換が遅い件、何も別にIUOをswitchしなくても
9:34 AM
func fastUnwrap<T>(_ arg: T!) -> T? { return arg } (edited)
9:34 AM
これだけでいい気がしてきた
9:37 AM
いけたっぽい
Avatar
それは暗黙の変換にはならないんですか
Avatar
暗黙の変換が return arg として出現していますが
Avatar
探すわけじゃないからいいのかな
Avatar
こいつはfuncで1回しか評価されないため
10:44 AM
差し当たりO(4)かな?
10:44 AM
fastUnwrapの方は別段問題が発生しない。明示的だから。
Avatar
ふむ
Avatar
omochimetaru 3/28/2017 2:09 AM
Swift3.1のGeneric Classのinner classって
2:09 AM
外側のGeneric Classの型パラメータによって
2:09 AM
static contextって分離されるの?
2:09 AM
つまり・・・
2:10 AM
class Outer<T> { static var staticVar: T class Inner { static var staticVar: T } }
2:10 AM
としたとき
2:10 AM
Outer<Int>.staticVar = 3 Outer<String>.staticVar = "abc" Outer<Int>.Inner.staticVar = 4 Outer<String>.Inner.staticVar = "xyz"
2:10 AM
こう?なんだっけ?
Avatar
そもそもstatic なT作れたっけ
Avatar
omochimetaru 3/28/2017 2:11 AM
えーっと、そもそものstaticなTについては、Swift3.0でも問題になるテーマだから、どうだろう。
2:12 AM
Innerがあってもそれを一貫して引き継いだ仕様になるか。
Avatar
そうだと思うよ
Avatar
omochimetaru 3/28/2017 2:12 AM
なんかアプデがエラーになっちゃってまだ試せていない・・・
Avatar
iPadで試そう
Avatar
omochimetaru 3/28/2017 2:12 AM
Swift Playgroundsは3.1なんだよねw
Avatar
omochimetaru 3/28/2017 2:30 AM
なんかAppStoreアプリぶっ壊れてXcodeのアプデが終わらん
Avatar
devから直接ダウンロードすればいいんでない?
Avatar
staticなTは無理みたいですね error: static stored properties not supported in generic types static var staticVar: T
Avatar
まあそうですよね (edited)
Avatar
omochimetaru 3/28/2017 2:56 AM
なるほど
2:56 AM
じゃあ CatInt, CatString は static contextが2つあるけど、 Cat<Int>, Cat<String> は1つしか無いんだな
Avatar
static var x = 0を生やして書き換えたら共有されるのかな?
Avatar
@tarunon
Tは暗黙的にT?だよ
古い話題ですが、これ、メソッドコールだと起こんないんですよね。 let a = 42 a.map { $0 } // error
(edited)
Avatar
そうですね、その場合はOptionalは決定しようがなさそう
Avatar
このあたりは使い勝手を考えると絶妙なラインだけど、法則がわかりづらすぎてやっぱり暗黙の型変換は邪悪・・・
3:09 AM
昔 Kotlin の Any?map を生やしてみたら、 Listmap が正しく動かなくなって大変なことに。
Avatar
ListがList?に変換されたのか
Avatar
はい。
Avatar
邪悪だ
Avatar
それで初めて、 Swift の T? への暗黙の型変換は起こる場合と起こらない場合が使い分けられていることに気付きました。
Avatar
swiftの場合は、他の要素によってOptionalが決定される場合にのみ暗黙的に変換されるので、辛うじて秩序を保てている(?)
3:11 AM
🤔
Avatar
正確なルールがどうなってるのかはわからないです。単に . の左側では暗黙の型変換をしないだけかもですが。
Avatar
.の左って暗黙変換すると非決定性が高すぎて実現不可能な気がするんですが
3:26 AM
他の言語で例があったりするのかな
3:26 AM
ObjCのidがある意味そうか。でもあれはobjc_msgSendだからswiftの話とは全然違う (edited)
Avatar
C++とかどうなってるんでしょう?
3:27 AM
暗黙の型変換ができる言語自体が少ない気も?
Avatar
vtableか何か、implを引ける仕組みがあれば、そこに乗せればいい気はしてるんですが
3:31 AM
そういうのが無い場合に出来るイメージが全く湧かない
3:31 AM
いや、左の型が非決定的だからvtableあっても意味ない
Avatar
Java のオートボクシングでできそうな気がしたけどできなかった。 public class Main { public static void main(String[] args) { System.out.println(2.compareTo(3)); } } $ javac Main.java Main.java:3: error: ')' expected System.out.println(2.compareTo(3)); ^ Main.java:3: error: not a statement System.out.println(2.compareTo(3)); ^ Main.java:3: error: ';' expected System.out.println(2.compareTo(3)); ^ 3 errors
Avatar
ObjCも本質的に違う話題ですね、あれはOオブジェクトとselectorからimpl引いてるだけだ
Avatar
↓なら OK 。 aint に変えたらダメ。 public class Main { public static void main(String[] args) { Integer a = 2; System.out.println(a.compareTo(3)); } }
Avatar
omochimetaru 3/28/2017 3:34 AM
C++の暗黙の型変換は引数に渡す時だけな気がする
3:34 AM
ドットオペレータでメソッドを呼ぶ時は差し込まれない
Avatar
単純にやっぱり、型を決定する材料足りないと思う
Avatar
omochimetaru 3/28/2017 3:34 AM
static var x = 0を生やして書き換えたら共有されるのかな?
そうそう。そこらへんが気になった。
(edited)
Avatar
KotolinのAny?の話は聞いた感じ
3:35 AM
😳😥😰って感じ
Avatar
まあ、基本的に nullable にメソッドは生えてないので、意図的に生やさなければ問題にはならないです。 (edited)
Avatar
map flatMapないのか
Avatar
let みたいな Any 由来のメソッドは使えるけど、それは暗黙の型変換なく使えるんで。
Avatar
そうか、kotlinはT??とT?が等価でしたっけ
Avatar
はい
Avatar
なるほど
Avatar
foo?.let { x -> bar(x) }
3:39 AM
↑が map かつ flatMap になります。
Avatar
なるほどー
3:40 AM
まあ実用上75%くらいは問題ないですね
Avatar
です。
Avatar
omochimetaru 3/28/2017 3:40 AM
?.let { } はアツいよね
Avatar
↑に気づく前の Kotlin を使い始めたばかりの頃に map を生やしてみたら、という話なので、実用上は問題ないです。
Avatar
Promise.thenみを感じる
Avatar
Kotlin と言えば、この前 @omochimetaru と話してた Ceylon : Anything : Null = Kotlin : Any? : Nothing? の話を整理して Qiita に書きたい。 (edited)
3:44 AM
typealias Anything = Any? typealias Null = Nothing? とすれば Ceylon と同じになる。
3:45 AM
typealias Object = Any これもいるか。
3:46 AM
で、これと関連して、 Swift の Never が bottom type になるかもという話も興味深い。
3:48 AM
Joe Groff の言ってる↓がもし実現されるなら https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170213/032267.html IMO, if we accept a single error type per function, there could be a simpler model for this. We could say that the `throws` type is a generic parameter of all function types, and it defaults to the uninhabited `Never` type for functions that don't throw. () -> () == () throws Never -> () () throws -> () == () throws Error -> () In this model, you'd get many benefits: - `rethrows` could become first-class, reducing down to just polymorphic `throws`: func foo(_: () throws -> ()) rethrows // Swift 3 func foo<T: Error>(_: () throws T -> ()) throws T // Swift X
3:48 AM
Never が bottom type でないと辻褄が合わない。
Avatar
ああ、そういう意味か
3:49 AM
いいですね、美しい
Avatar
これはこれでキレイなんですけど、 rethorws がただのシュガーになっちゃって、 reasync との対応の解釈が難しいです・・・。 https://gist.github.com/koher/df007741788cb197d65b6babe2acf480
Avatar
asyncの話は出てないんですか?
Avatar
ちゃんと watch できてないです・・・。
3:53 AM
でも Swift 4 のスコープじゃなさそうな気も?
3:54 AM
Generics と Memory Ownership と String でお腹いっぱいなんじゃないですかね。
Avatar
それはそんな気がする
3:55 AM
asyncも後から足して破壊的変更になるか、というと
3:55 AM
stdlib周りが壊れるかー
Avatar
壊れますか?追加だけなような気も。
Avatar
ああ、追加すれば良いのか
3:56 AM
殺さなくて良いので確かに
Avatar
↓の Chris Lattner のスライドの actor も Swift 5+ って書かれてるし、 4 ではない気がしてます。 http://researcher.watson.ibm.com/researcher/files/us-lmandel/lattner.pdf
3:58 AM
多分、 async レベルの変更は Core Team で良く練った上でマニフェストが出て、それベースで話し合いとかじゃないですかね?
7:11 AM
public class func Package(url: String, versions: ClosedRange<Version>) -> Dependency { return Package(url: url, versions: versions.lowerBound..<versions.upperBound.successor()) }
7:12 AM
a...ba..<b の両方に対応しようとすると、 a...b => a ..< b.successor() の変換をオーバーロードの内側でやらないといかんのか。
Avatar
あーーー
7:22 AM
Swift3.1でコンパイルできなくなった
Avatar
omochimetaru 3/28/2017 7:22 AM
w
Avatar
Swift2.2になって、Protocol周りのバグが幾つか修正されて、ProtocolとClassを組み合わせて使うシチュエーションが現実的になってきました。 ということで、Swift2.2から可能になったテクニックを備忘録も兼ねて...
7:25 AM
これ、extensionの束縛部分を他のライブラリに逃してたら今まで通ってたけど
7:25 AM
ついに殺されたっぽい
7:26 AM
エラーの出方もAmbiguous type nameじゃなくてセグフォだしとても嫌な感じだ…
Avatar
omochimetaru 3/28/2017 7:28 AM
たるのんのこれ、いまいちシナリオがわからなかったけど
7:28 AM
ここでいう recursive protocol constraints に該当するパターンかね
Avatar
それそれー
Avatar
omochimetaru 3/28/2017 7:28 AM
protocol Sequence { associatedtype Iterator : IteratorProtocol ... associatedtype SubSequence : Sequence // currently ill-formed, but should be possible } シーケンスのサブシーケンスはシーケンス、としたいけど現状はできない、とかがあるらしい
Avatar
今まではWorkaround作って無理やり押し通ってた
7:29 AM
しんでしまった
7:29 AM
どうしようかな~
Avatar
omochimetaru 3/28/2017 7:30 AM
あ〜
7:30 AM
protocol Eq { static func (a: Self, b: Self) -> Bool } ↑これはできるけど protocol EqX { associatedtype X static func (a: X, b: X) -> Bool } struct Hoge : EqX { typealias X = Hoge } これはできない? (edited)
Avatar
nn
7:31 AM
↑は↓の糖衣では
Avatar
omochimetaru 3/28/2017 7:31 AM
2つめのはできて、 protocol EqX { associatedtype X static func (a: X, b: X) -> Bool } protocol EqSelf { typealias X = Self } struct Hoge : EqSelf { } これが駄目なのかな?
Avatar
Equatableは暗黙的にassociatedだぞ
7:32 AM
えっとですね
Avatar
omochimetaru 3/28/2017 7:32 AM
記事で本題ってなってるケースは↑のEqXも駄目になりそう。
7:32 AM
protocol EqX { associatedtype X static func (a: X, b: X) -> Bool } struct Hoge : EqX { typealias X = Self } HogeじゃなくてSelfか (edited)
Avatar
protocol A { associatedtype B } class C: A { typealias B=Self } ↑できない
Avatar
omochimetaru 3/28/2017 7:33 AM
だよね
Avatar
サブクラスのBはサブクラス自身であってほしいが、それが出来ない
7:33 AM
しかし、Workaround積み上げまくってそれを実現してた
7:33 AM
バベルの塔はついに崩壊した
Avatar
omochimetaru 3/28/2017 7:33 AM
Cを継承したDがいるときに
7:34 AM
Cの中でSelfって書いておくとDにおいてそれがDになるやつよね
Avatar
そうそう
Avatar
omochimetaru 3/28/2017 7:34 AM
そもそもSelfって書けるの最近しったワw
7:34 AM
しかも self 式の型が Self だし。
7:35 AM
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
7:35 AM
RecursiveProtocolConstraintsはAcceptedになってるし
Avatar
4までおあずけかな
Avatar
omochimetaru 3/28/2017 7:36 AM
待ってれば綺麗な解決が来そう
Avatar
@tarunon これだとまた意味変わってきます? protocol HasB { associatedtype B } protocol A: HasB { } class AnyAs: HasB { typealias B = AnyAs.Type } class AnyA<T>: AnyAs where T: A { typealias B = T.B } class C: A { typealias B = C } AnyA<C>.B.self
Avatar
class D: C {}と書いたらどうなりますか?
10:05 AM
昔は、AnyAとか用意しなくても、常にA.B==Selfな型が作れたんですが、今は死んでしまったので。
Avatar
確かに継承してしまうと追いかけてくれないですね...うーむ
Avatar
なんかObjCと絡ませて型をしっちゃかめっちゃかするとコンパイル通らなくなるなー最小ケース探さないと
Avatar
omochimetaru 3/29/2017 1:30 AM
Swiftに慣れてくるとRubyのコードがこんなんばっかになる xs.map {|x| y = f(x) y ? [y] : [] }.flatten(1)
Avatar
みつけた
5:05 AM
セグフォです
Avatar
いけそうだけどダメなんですね 💧 fugaのみだと通るのか...
Avatar
Xが具体型なら通ります、この場合はStringに変更すればOK
Avatar
なるほど
Avatar
Swift3.1 ErrorからNSErrorへの暗黙の型変換追加されてるくさい
7:23 AM
邪悪すぎる
Avatar
omochimetaru 3/29/2017 7:23 AM
それ前からあったと思う
Avatar
いや
Avatar
omochimetaru 3/29/2017 7:23 AM
全てのError は is NSError だった
Avatar
error.method
7:23 AM
これでerrorがNSErrorになる
Avatar
w
Avatar
omochimetaru 3/29/2017 7:23 AM
あーそゆこと?まじ?
Avatar
多分
7:24 AM
もうちょっと掘るけど、かなり辛い感じ
7:29 AM
理解完了
7:29 AM
7:29 AM
こういうコードを書いた時に、前までだと
7:29 AM
キャストが先だったが3.1からNSErrorへのキャストが先に挿入されてから変換される
Avatar
NSErrorが優先されるのか
7:30 AM
あ、順番の話か
Avatar
omochimetaru 3/29/2017 7:30 AM
MyCustomErrorのhogeとNSErrorのhogeの値を変えて欲しい
Avatar
変えてる
Avatar
1と-1
Avatar
1と-1
Avatar
omochimetaru 3/29/2017 7:30 AM
あ、見間違えた
7:30 AM
ほんとだ・・・
Avatar
let error: Error 👉 error as NSError 👉 (error as NSError) as? MyCustomErrorProtocol ということ? (edited)
Avatar
そう
7:32 AM
強制的にNSErrorになってる
Avatar
21行目を let error: MyCustomError = MyCustomError() にしたらどうなるの?
7:32 AM
それは1か
Avatar
そう
7:32 AM
でもthrowがErrorだから型明記するの全く意味ない
Avatar
おー
7:33 AM
extension NSError: MyCustomErrorProtocol これ消せばちゃんと動くんよね
Avatar
それはそう
Avatar
へー
7:35 AM
参考までにこの変更で何が困ってるのか聞いてもいいですか
Avatar
Errorを受け取ってダイアログ出してるけど
7:36 AM
3.1にしたら全てが破壊されて???ってなった
7:36 AM
ダイアログはProtocolに基づいてラベル付をしている。
Avatar
カテゴリ分けみたいな意図でprotocolを使っていてってことかな
Avatar
error.method これでerrorがNSErrorになる
タイムリーに昨日話してた . の左の暗黙の型変換ですかw
Avatar
ほぼ
8:01 AM
それですね
8:01 AM
激怒ですよ
8:03 AM
なんか
8:03 AM
そのくせNSErrorの引数にError渡したらコンパイルエラー吐きやがったぞ…
8:03 AM
ふざけやがって…
Avatar
そっちは暗黙の型変換ないんですね。カオスw
Avatar
迂闊にNSErrorにprotocol準拠させて共通化するの危険になりましたね... 修正するならNSError用のcontainerで包むとか別で対応入れる形になるんでしょうか
Avatar
コンテナ作ってError型入れて
8:52 AM
Protocolでキャストして片方取り出しつつ、NSErrorの処理はそこに書く
8:53 AM
みたいなことしなきゃいけないです。あーめんどくせーーー
Avatar
やっぱりそうなりますよね。。NSErrorの存在感w
Avatar
protocolでキャストする必要が出てくるのでAssociatedなProtocolは死体ですねこれ
9:26 AM
無念
Avatar
全然関係ない話ですが、
9:35 AM
Swift PM の新しい pinning について、
Since package pin information is not inherited across dependencies, our recommendation is that packages which are primarily intended to be consumed by other developers either disable automatic pinning or put the Package.pins file into .gitignore, so that users are not confused why they get different versions of dependencies that are those being used by the library authors while they develop.
https://github.com/apple/swift-evolution/blob/master/proposals/0145-package-manager-version-pinning.md とあるんですが、これについて話していて pins ファイルは ignore しない方がいいんじゃないかという話になったんですがどう思いますか? アプリでは環境をそろえるために pins ファイルを共有した方がいいのは当然として、ライブラリ利用時には、依存している側からはライブラリ内部の pins ファイルは無視されるようなので、 "so that users are not confused why they get different versions of dependencies that are those being used by the library authors while they develop." という理由だけであればライブラリ開発者間で環境をそろえるために( atuo pinning も有効にして) pins ファイルも push した方がいいんじゃないかなぁという話です。
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
Avatar
omochimetaru 3/29/2017 9:38 AM
ライブラリ開発中は依存先のバージョンが
9:38 AM
微妙に変わったりした時に
9:38 AM
壊れる事を検出したいから
9:38 AM
固定しないほうがたまに壊れてくれて嬉しい気がする
9:38 AM
もし、特定のあるバージョンでしか、動かないライブラリなら
9:39 AM
pinじゃなくて、そもそものPakcage.Swiftのほうで、ピンポイント依存していをしないと
Avatar
それは明示的に repin して確認すればいい話なのでは?
Avatar
omochimetaru 3/29/2017 9:39 AM
いけないのではないか
9:39 AM
めんどくさくてやらなそう>明示的に
9:39 AM
とりあえず固定しないでおけば、いろんな人が作業するタイミングのズレで自然とバラける
Avatar
アプリにせよライブラリにせよ、それぞれが微妙にブレたバージョンで開発していたりすると微妙なバージョンのブレの組み合わせが原因で問題が起こったりして現象を再現できないから
9:41 AM
開発者間でバージョンをそろえて作業できるようにしたいというニーズがそもそもあって pinning が導入されたと思っていて
9:41 AM
色んなバージョンで動くかどうかの検証はそれとは別の話じゃないかな。 pinning してなくても網羅的にチェックできるわけじゃないし。
Avatar
cocoapods使っててPodfile.lockをignoreするかしないか論争のSwift PM版って話ですよね チームで開発してるときなんかはそれぞれで環境が変わると問題が起きたときに切り分けに困るのでpinsは共有した方が良い派です (edited)
Avatar
@moaible ですよねぇ・・・。
9:44 AM
ignore するか auto pinning を disable することが推奨って書いてあるんですけど、それによって得られるメリットが "users are not confused why they get different versions of dependencies that are those being used by the library authors while they develop" なのは納得がいかないんですよね・・・。
9:45 AM
@omochimetaru
めんどくさくてやらなそう
デフォルトが auto pinning になるから、もし pins ファイルを commit しないなら、少なくとも auto pinning を disable するか、 pins ファイルを ignore するかしないといけないんです。
Avatar
omochimetaru 3/29/2017 9:46 AM
--type libraryで初期化してもauto piningがデフォルトでoffになってない?
9:46 AM
それはよくわからないな。
9:47 AM
一貫性が無い
Avatar
The package manager will have automatic pinning enabled by default (this is equivalent to swift package pin --enable-autopin), although package project owners can choose to disable this if they wish to have more fine grained control over their pinning behavior.
(edited)
Avatar
omochimetaru 3/29/2017 9:48 AM
ウーム
Avatar
アプリ作る人はpinsを含めたほうがいいけど、ライブラリ作る人はpinsはignoreしたほうがいいってことじゃないんですかね。
Avatar
@rb-de0 そういう内容なんですが、それが微妙じゃないかなぁという話ですね。
9:59 AM
pins ファイルを commit することのデメリットが「まぎらわしいから」くらいなら、 commit するメリットが勝る気が。
10:00 AM
それに、ライブラリ開発環境の pins が含まれていれば、それを再現すれば最低限そのときと同じ環境でライブラリを動かすことができるわけで、利用者視点でも、トラブル発生時のドキュメントとしても価値があると思うんですよね。
Avatar
Swift2 -> 3のタイミングでのSwift PMは大分辛かった記憶があるのでpinsあるとその辺緩和されると嬉しいお気持ちはありますね
👍 1
10:03 AM
どこで依存壊れてんのか追うのがしんどかったです
Avatar
あんま詳しくないですが、ここに書いてあることと同じ意味なんじゃないですかね。http://sanemat.github.io/archives/langturn.com-translations-33/
Avatar
同じっぽい。rubyやnodejsの開発者のほうが
10:05 AM
ライブラリ小分けにしまくって依存が100個とかぶら下がるみたいな
10:05 AM
開発になれていて
10:05 AM
知見がありそう
Avatar
利用者側からすると依存関係のバージョンがズレていると使えないことになってしまって不便です。
Ruby 詳しくないですが、↑これって利用者側がライブラリ中の lock ファイルの影響を受けるってことですよね?
10:10 AM
Swift PM ではそれは起こらないのでは?
The pins file will also not influence dependency resolution for dependent packages; for example if application A depends on library B which in turn depends on library C, then package resolution for application A will use the manifest of library B to learn of the dependency on library C, but ignore any Package.pins file belonging to library B when deciding which version of library C to use.
Avatar
Gemって依存先のLockも見ちゃうのかな?その文章はどっちでも取れると思いますが
10:13 AM
Gemコマンドで扱われないような精密さを要求してしまうからです。
技術的にって意味じゃなくて、固定して開発するからコードがそうなっちゃうって意味かと思った。
2:49 PM
associatedtypeにデフォルト型置けるようになってる
Avatar
omochimetaru 3/29/2017 2:49 PM
話し合われてるのは知ってたけど3.1からだったか
Avatar
この間のwhere Voidの変態workaroundは用済みとなった
Avatar
omochimetaru 3/29/2017 2:51 PM
あれ謎だった
Avatar
LazyCollectionProtocolとか、その辺見て気が付いた
2:52 PM
あれ?associatedtypeでSelf??マジ?って
Avatar
omochimetaru 3/29/2017 2:52 PM
ふむふむ
Avatar
associcatedtypeのやつって2.xの時からできてたと思ったけど、何か違うものです? https://github.com/ikesyo/Himotoki/blob/1.7.0/Sources/Decodable.swift
Himotoki - A type-safe JSON decoding library purely written in Swift
Avatar
これforceじゃないですかね
2:57 PM
上書き不可能な気がする
2:57 PM
associatedtypeのそれは、他の型で上書きできます
2:58 PM
無宣言の時だけ=の向こう側になる
Avatar
これと同じに見える http://stackoverflow.com/a/36810484
I have been struggling very hard with Swift Protocols and Associated Types for a long time. I started again with basic to really understand what is going wrong and I followed this article of TypeEr...
3:02 PM
手元で今シュっと試せないのでハッキリとは分からないですが(>_<)
Avatar
iswift.orgで試したら3.0.2の時点で出来てたみたいですね
3:04 PM
2.2はSelfが消せなくてコンパイルエラー
Avatar
なるほど3.0でか
3:04 PM
ありがとうございます
3:07 PM
Gemfile/.lockはPodfile/.lockと同じで、それに依存する側からは関係ないはずという認識です。そのライブラリの利用者に影響を与えるのはgemspec, podspecでは?
Avatar
omochimetaru 3/29/2017 3:10 PM
であれば、条件設定はspmとgemで同じですね
3:11 PM
条件設定と、慣習が同じで、 ライブラリ開発時はロックをコミットするな、 で
3:11 PM
でもライブラリ開発同士でも環境が同期したほうが良いのでは?という話
Avatar
CarthageでもCartfile.resolvedはライブラリ利用者には影響を与えない
3:12 PM
Carthageではドキュメントでreslovedはコミットをすすめてるかな (edited)
Avatar
omochimetaru 3/29/2017 3:12 PM
ほー!
Avatar
あ、ですよね
Avatar
開発者間で同期すべきものという認識で、僕もその立場です
Avatar
そんな気はしてた
Avatar
omochimetaru 3/29/2017 3:16 PM
so that users are not confused why they get different versions of dependencies that are those being used by the library authors while they develop.
3:16 PM
実際これはよくわからないよなあ
Avatar
ロックするのはまさにこういうことかなぁ
それに、ライブラリ開発環境の pins が含まれていれば、それを再現すれば最低限そのときと同じ環境でライブラリを動かすことができるわけで、利用者視点でも、トラブル発生時のドキュメントとしても価値があると思うんですよね。
Avatar
omochimetaru 3/29/2017 3:17 PM
ライブラリ作者と違う依存先バージョンを取得していまう理由にユーザーが混乱しないから、と、言われても、依存の依存はLockを見ない、で説明終わるからなあ
3:19 PM
あ~
3:19 PM
CIをまわしている場合に
3:20 PM
CI botもpinしたバージョンでライブラリをビルドするけど
3:20 PM
pinよりも先のリビジョンアップデートがリリースされている場合に
3:20 PM
ライブラリ作者が明示的にupdateしてpinを更新しないと
3:20 PM
それが検査されない、みたいな違いはある?
3:20 PM
ライブラリのロックがコミットされていなければ、
3:21 PM
pushされるたびに依存先のバージョンの指定の範囲で最新のものが使われるから
3:21 PM
健全性は保ちやすい?
3:25 PM
@tarunon どこかで見たつもりだったけどこれしか見つからなかった rejectされた別の提案の一部として出てきてる https://github.com/apple/swift-evolution/blob/9cf2685293108ea3efcbebb7ee6a8618b83d4a90/proposals/0108-remove-assoctype-inference.md#default-type-for-associated-type
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
3:26 PM
うーんどこから入ったんだろう
Avatar
IBMのサンドボックスでは3.0.0時点から可能だった
3:27 PM
見落としてたのかーという気持ち
Avatar
omochimetaru 3/29/2017 3:27 PM
2からいけた可能性は?
Avatar
2.2はしんだ
Avatar
omochimetaru 3/29/2017 3:29 PM
なるほど・・・俺も釈然としない・・・
Avatar
コンパイラはAbortかなこれは
3:29 PM
ああ、まってね
3:30 PM
2.2にprotocol extensionって無かったよね
3:31 PM
いけたいけた
3:31 PM
2.2でも同様の型の作り方書いて上書きできた
Avatar
omochimetaru 3/29/2017 3:31 PM
えーじゃあ全然前からできたってこと?
Avatar
ぽい
Avatar
omochimetaru 3/29/2017 3:32 PM
あれ~~~🙄
Avatar
2.2だとprotocol extension無いからやるメリットはほぼない
3:32 PM
3.0からメリットの塊だけど、見逃し続けてた。今の今まで
Avatar
omochimetaru 3/29/2017 3:32 PM
Himotoki - A type-safe JSON decoding library purely written in Swift
3:32 PM
himotokiのこれも上書き可能ってことかね
Avatar
できちゃいますね
Avatar
omochimetaru 3/29/2017 3:33 PM
oh・・・
Avatar
でもHimotokiはそこら中でwhere Decodable==Selfって書いてた気がする
Avatar
omochimetaru 3/29/2017 3:33 PM
typealiasっていうキーワードの印象で上書きできないって思い込んでただけかな
Avatar
3.0からなんで出来ないと思い込んでたのかが謎
3:34 PM
HimotokiのDecodable==Selfはサブクラスをやっつけてるのかと勝手に解釈してた
Avatar
omochimetaru 3/29/2017 3:36 PM
あいや、それはそうなはずで
3:36 PM
# 先に結論 - Swiftのstaticメソッド制約はちょっとしたシンプルな機能に見えるけど便利で深い - Kotlin, TypeScript, Java で同じことをすると冗長で間接的なコードになってしまう - TypeScr...
3:36 PM
ちょうどこの記事書いたときにも確認してる
Avatar
うん、やっつけれるのは確かなんだけど
3:37 PM
それは兎も角Decoded=Intとか勝手にかけるそれらもやっつけ対象だったのは、完全に盲点だった
Avatar
ロックの件、CIも確かに話題としてありそう。CI上で勝手に新しいの使われてぶっ壊れるのも嫌な気もして、好みによりそう (edited)
3:38 PM
あとはブランチ指定かなー
3:39 PM
複数ライブラリを並行に開発してて、開発中のブランチを使いたい時に、ロックがないと用意に壊れる気がする
Avatar
omochimetaru 3/29/2017 3:39 PM
@ikesyo アプリAから見てライブラリBの依存先Cに勝手に新しいのを使われる事自体はそもそも防止できないのでは
3:40 PM
アプリユーザーはBのpinを無視する仕様だから、Bの開発者はCのリビジョンアップデートはそもそも対応を拒否できない
3:41 PM
(根本的に依存先定義をピンポイント指定すれば別だけど)
Avatar
@omochimetaru それはそうですね。そうなってから何か報告があれば直すというスタンスか、ライブラリ側でそういう状況を常に把握できるようにあえてロックしないか、というスタンスの違い
Avatar
omochimetaru 3/29/2017 3:41 PM
ああ、なるほどです。 (edited)
Avatar
まあその辺はsemverの世界観ではそうそう壊れないという期待はあると思う。compatibleなバージョン範囲を指定してる上では。
Avatar
omochimetaru 3/29/2017 3:44 PM
たまにRails触るとだいたいlibv8となんちゃらモンキーが問題起こしてたから、semverの世界に全く信用がおけない・・・
Avatar
依存先が勝手にアップデートされないためには完全バージョン固定するしかないけど、それはそれで依存の依存に新しいバージョン出てるのにそれが使えなくて困ると上位の利用者から文句言われることになりそう。なので~>とかになる (edited)
Avatar
omochimetaru 3/29/2017 3:46 PM
npmとかも一瞬で200個とかライブラリぶっこまれて、こんなん動くわけないやろって気持ちによくなる。でもnodejsはブラウザ向けとかはわりと動くんだよな。
3:46 PM
そうですね
Avatar
jsのライブラリ粒度はすごい世界だ……
Avatar
omochimetaru 3/29/2017 3:49 PM
ですよねww
3:49 PM
ワンファイルどころか10行ぐらいの関数単位のパッケージがザラにある
3:50 PM
browser swiftとか始まったらブラウザ差分吸収の需要からそういう世界になってしまうんだろうか
Avatar
依存先が勝手にアップデートされないためには完全バージョン固定するしかない
これだと、複数のライブラリが同じ別のライブラリの(互換性のある)バージョン違いに固定されちゃってたら、本来解決できるはずなのに解決できなくなっちゃいますよね?
Avatar
omochimetaru 3/30/2017 2:25 AM
それはそれで依存の依存に新しいバージョン出てるのにそれが使えなくて困ると上位の利用者から文句言われることになりそう。なので~>とかになる
2:25 AM
そういう事ですね
Avatar
ああ、「使えなくて困る」というのは、単に新しいのにしたいけどできないから古いの我慢するというだけじゃなく、そもそも不整合が起こって解決不能になるという意味も含んでいるのか。
2:28 AM
ワンファイルどころか10行ぐらいの関数単位のパッケージがザラにある
これ自体は別にいいと思う。むしろ粒度小さくした方がいい派。
2:32 AM
ライブラリのロックがコミットされていなければ、 pushされるたびに依存先のバージョンの指定の範囲で最新のものが使われるから 健全性は保ちやすい?
この目的だと、pinsファイルをignoreするよりも、開発者側がauto pinningをdisableして何もpinしないのが良さそう。ignoreしてる時点で開発者間で環境そろえられないからpinningの意味ない気がするし。
Avatar
omochimetaru 3/30/2017 2:51 AM
そもそも共有しないpinって意味あるんですか?
2:52 AM
pinが無いと自分の手元もどんどん新しくなるのかな
Avatar
Use Cases
Our proposal is designed to satisfy several different use cases for such a behavior:
1. Standardizing team workflows
When collaborating on a package, it can be valuable for team members (and continuous integration) to all know they are using the same exact version of dependencies, to avoid "works for me" situations.
This can be particularly important for certain kinds of open source projects which are actively being cloned by new users, and which want to have some measure of control around exactly which available version of a dependency is selected.
2. Difficult to test packages or dependencies
Complex packages which have dependencies which may be hard to test, or hard to analyze when they break, may choose to maintain careful control over what versions of their upstream dependencies they recommend -- even if conceptually they regularly update those recommendations following the true semantic version specification of the dependency.
3. Dependency locking w.r.t. deployment
When stabilizing a release for deployment, or building a version of a package for deployment, it is important to be able to lock down the exact versions of dependencies in use, so that the resulting product can be exactly recreated later if necessary.
3:23 AM
うーん、 commit しなくてもうれしいケースがあるとすると 2 かな?
3:25 AM
いずれにせよ auto pinning では 2 は実現できないから、 auto pinning が enabled な状態のまま、 pins ファイルを ignore するシナリオがよくわかんないな。
Avatar
omochimetaru 3/30/2017 3:25 AM
なるほど
Avatar
やっと再現できた
11:41 AM
まだ小さく出来たので小さくした。今のが最小かな
Avatar
omochimetaru 3/30/2017 1:58 PM
a
4.67 KB
1:58 PM
ビルド、実行できたよ
1:58 PM
$ cd a $ swift build $ .build/debug/a
Avatar
Avatar
omochimetaru 3/30/2017 1:59 PM
main.swift let a = F<O>() print(a.f())
Avatar
同じファイルだと動く
Avatar
omochimetaru 3/30/2017 1:59 PM
別のファイルだよ
1:59 PM
tarunonのgistをzipでおとしてから
Avatar
マジか
Avatar
omochimetaru 3/30/2017 1:59 PM
swift package initしたから
1:59 PM
全くおなじはず
Avatar
ふーむ
2:02 PM
出来るな
Avatar
omochimetaru 3/30/2017 2:02 PM
Swiftのライブラリの名前って
2:02 PM
Swiftに洒落を効かせたほうがいいんですかね
2:02 PM
たくさんライブラリを使うようになったら
2:02 PM
そういうのいちいちあるとややこしい気がするんだけど
2:03 PM
あーでも同じことをするライブラリが2つあったら微妙なのかな
2:04 PM
でもResultとかあるしな
Avatar
同じコードの二つのプロジェクトがあって
2:29 PM
片方は通って片方はセグフォになった
Avatar
omochimetaru 3/30/2017 2:29 PM
ええw
2:29 PM
ビルドキャッシュの影響じゃない?クリーンしたら同じになるよ
Avatar
いや、
Avatar
omochimetaru 3/30/2017 2:30 PM
import GlibC したとき何が使えるのかさっぱりわからん (edited)
Avatar
消しても再現するし、DerivedData消しても同じ
Avatar
omochimetaru 3/30/2017 2:31 PM
ふむ
2:32 PM
UbuntuならGlibc.swiftmoduleとかあると思うんだけど、あったとして、中身見る方法もわからんな・・・
Avatar
タイミングとしては、extensionに書いたfの解析中にセグフォで死ぬ
2:33 PM
今死んでる方はバグの再現できるプロジェクトから最小単位まで削ったコードで、会社のpcに最初からプロジェクト作って再現したのがあるから、
2:34 PM
明日そのプロジェクトをzipに詰めてアップロードしとこう
2:34 PM
githubに上げるのがはやいか
Avatar
omochimetaru 3/31/2017 1:45 AM
@ikesyo さんとか、HimotokiのLinux対応やったとき、Glibcの中身ってどうやって確認したんでしょうか
1:45 AM
サーバーサイドLinuxでGlibc叩いてる人は居ませんか〜〜
Avatar
HimotokiはstdlibとFoundationだけで済んでいてGlibcは使ってなかったと思います
Avatar
omochimetaru 3/31/2017 2:37 AM
あ〜 じゃあLinux固有のヘッダーを読む必要は無かったんですね
2:37 AM
Mac上でFoundationを外すだけで作業できた
Avatar
FoundationはLinux版でもcorelibs-foundation使ってるので外してはないですけど、Glibcを使う必要はなかったですね (edited)
Avatar
omochimetaru 3/31/2017 2:42 AM
corelibs-foundationってFoundationのLinux対応版の事ですか?
Avatar
https://github.com/apple/swift-corelibs-foundation/ Swift実装のFoundation(≒Linux版)
swift-corelibs-foundation - The Foundation Project, providing core utilities, internationalization, and OS independence
2:44 AM
macOSでもSwiftFoundationとして独立して動きます(なのでmacOSで開発、テストもできる)
Avatar
omochimetaru 3/31/2017 2:44 AM
なるほど
2:44 AM
なるほど〜
Avatar
omochimetaru 3/31/2017 3:12 AM
deferの中でthrowできないのか・・・
Avatar
returnより後ろだから無理じゃないの
Avatar
omochimetaru 3/31/2017 3:16 AM
var fileActions: posix_spawn_file_actions_t? try PosixError.run { posix_spawn_file_actions_init(&fileActions) } defer { try PosixError.run { posix_spawn_file_actions_destroy(&fileActions) } }
3:16 AM
これとかすごい素直なコードだと思うんだけど通らなくて悲しい
Avatar
いやVoid値返ってからエラー発生はおかしいでしょ
3:17 AM
それやったらtryがEitherと等価じゃなくなる
Avatar
omochimetaru 3/31/2017 3:17 AM
返ってからじゃなくてreturnの直前に差し込まれるんじゃないのかね
3:17 AM
コンパイル結果的には。
Avatar
返り値確定してから差し込まれてるから、deferの中にthrowは直感に反するというか
Avatar
omochimetaru 3/31/2017 3:18 AM
いや、てか、defer自体が open - defer { close } ってパターンが基本だと思うんだけど
Avatar
混乱生みそう
Avatar
omochimetaru 3/31/2017 3:18 AM
このcloseが失敗した時が無理じゃない?
3:19 AM
それができないなら、javaの try - catch -finally のfinallyの代替にはならないね 自分でwith resources文作らないといけないか
Avatar
foo() defer { bar() } return baz()foo() let r = baz() bar() return r と等価だと思ってた。
Avatar
omochimetaru 3/31/2017 3:21 AM
そうそう、そういう話しです
Avatar
それはそうなんですが
Avatar
omochimetaru 3/31/2017 3:22 AM
foo() return baz() bar() こう考えると、throwできないわけだ
Avatar
そう、それはthrowは出来ない
Avatar
omochimetaru 3/31/2017 3:22 AM
deferがいったいどこまで遅延するのか return前だと思っていたけど、後だと考えたほうが
3:22 AM
仕様とは合致して解釈できるね
Avatar
直感的に理解しやすいとは思う
Avatar
omochimetaru 3/31/2017 3:23 AM
微妙な仕様だな・・・
Avatar
defertry できないのは↓書いてるときに遭遇して、できてもいいのになぁと思った。 http://qiita.com/koher/items/e4c1d88981291c35d571
Swift には Java の検査例外によく似た仕組みがあります。 swift func foo() throws -> String { ... } // Java のような `throws` 節 ```swift...
Avatar
omochimetaru 3/31/2017 3:23 AM
with文作るのはいいけど、それだとネストが深くなっちゃうんだよな
3:23 AM
モナドにすればいいのか?
Avatar
iPhone版Playgroundめっちゃ欲しい
3:24 AM
こういうのスッと試したい
Avatar
omochimetaru 3/31/2017 3:24 AM
今mac無いの?
Avatar
でんしゃ
Avatar
omochimetaru 3/31/2017 3:24 AM
deinitもthrowできないし、Swiftのdeinitやdeferは全然RAIIパターンに使えねえんだなあ
3:25 AM
あ〜でもopenできたならcloseできない事はありえないし try! で辻褄あうのか
3:25 AM
一周回ってやっぱり何も問題無い気がしてきた
Avatar
iPhoneだと↓かなぁ。 https://swift.sandbox.bluemix.net/
An interactive website that lets you write, execute, and share Swift code in a server environment – on top of Linux!
Avatar
omochimetaru 3/31/2017 3:26 AM
↑このサイト叩くだけのwebviewアプリがあるといいのか
Avatar
ふむ
Avatar
omochimetaru 3/31/2017 3:27 AM
一応スマホ対応されてるんだな
3:27 AM
アプリ化しなくてもこれブックマークしておけば良い気もしてきた。
Avatar
うん。実行するとアニメーションして結果画面にスライドする。
Avatar
omochimetaru 3/31/2017 3:27 AM
一応SPAサイト化されてるなこれ
3:27 AM
えらい
3:28 AM
なんかいろいろおすとすりあがって来たりしてそれっぽい
Avatar
あ〜でもopenできたならcloseできない事はありえないし try! で辻褄あうのか
これよくわかんないんだけど、 close できないことがありえないならそもそも throws である必要ないんじゃ?
Avatar
APIの設計に依存しそう
3:30 AM
賢い作りならcloseできる時だけオブジェクトが存在してる
3:30 AM
メモリオーナーシップの機能は必要っぽい
Avatar
omochimetaru 3/31/2017 3:31 AM
@koher PosixError.runがそもそも public static func run(proc: () -> Int32) throws { let code = proc() guard code == 0 else { throw PosixError(code: code) } } こういうユーティリティだから try! PosixError.run { posix_spawn_file_actions_destroy(&fileActions) } try! になる
3:32 AM
もしそれをつかわないなら (edited)
3:32 AM
let ret = posix_spawn_file_actions_destroy(&fileActions) fatalError(ret == 0, PsoxiError(code: ret).description) (edited)
3:33 AM
っていうコードになるんだけど、これだと、 ret がスコープ汚染しちゃって、同じような処理を他にも書く必要があるから、これは採用できない。
Avatar
お、この前話してた >= の出番だ。
Avatar
omochimetaru 3/31/2017 3:34 AM
いや、えーっと、
3:34 AM
retの再定義が解決したとしても
3:34 AM
まだ冗長で
Avatar
そういや、 >=rethorws にしないといけない気がしてきた。
Avatar
omochimetaru 3/31/2017 3:34 AM
fatalError(ret == 0, PsoxiError(code: ret).description) 0判定、PosixErrorで包む、descriptionを呼び出す、などが冗長
3:35 AM
try! PosixError.run { posix_spawn_file_actions_destroy(&fileActions) } これならそのいずれもなくなっていて、同じことをする上で無駄が無い
Avatar
>=rethrowsじゃないとダメですね
Avatar
ですよね。
Avatar
はやく
3:38 AM
そういえばRxSwiftのどっかにrethrowsにして統合できる関数があったな
3:44 AM
昨日の、クラッシュするプロジェクトをGithubにおいたので
3:44 AM
Contribute to Xcode3_1Crashes development by creating an account on GitHub.
3:44 AM
お手すきの方コンパイルできるか試して頂けると
Avatar
@ukitaka が謎を解いてくれた
3:56 AM
コンパイラに渡すファイルの順番でコンパイルの可否が決まる
Avatar
えーw
Avatar
プロジェクトに寄って結果が違うのもそれ
Avatar
omochimetaru 3/31/2017 3:58 AM
なにそれw
3:58 AM
SPMだとソース回収だから一貫するけどXcodeだと追加順があるからか・・・
Avatar
プロジェクトタブの、CompileSourcesで順番弄ると
3:59 AM
コンパイル通ったり通らなかったりする
3:59 AM
笑う
Avatar
Foundation無しだとString.componentsすら無いのか・・・
Avatar
String.componentsが内部的にNSStringに依存してる?
Avatar
そこはわからんけど
Avatar
extension NSString { open func components(separatedBy separator: String) -> [String] @available(iOS 2.0, *) open func components(separatedBy separator: CharacterSet) -> [String] }
10:58 AM
これしか見つからん
Avatar
ってことはそもそも暗黙のアップキャスト?
Avatar
じゃねーかなー
Avatar
アップですらないな
Avatar
アップキャストではない気がする
10:59 AM
initしてますね
Avatar
暗黙のキャスト!
Avatar
ちょっと悪い事してみるか
10:59 AM
NSStringもSwiftStringも
11:00 AM
実行時はCFStringだからinstrumentsじゃ見分けつかねーんだわ
Avatar
へ~
Avatar
昔は_NSナンチャラStringが沢山居た気がするんだけど
11:01 AM
SwiftでNSString書いても最初からCFStringっぽい
Avatar
いたいたw
11:02 AM
_NSCFConfiguousString とかそんなん
Avatar
そうそれ
11:02 AM
あー
11:02 AM
じゃあObjC経由でswizzlingしてもだめか
11:02 AM
そもそも奴らはコンクリートクラスだからSwizzlingできねえ (edited)
11:02 AM
じゃあcomponentsかな?
11:08 AM
11:08 AM
詠唱完了
11:08 AM
確定ですね
11:08 AM
componentsはNSString由来、その上暗黙キャストが走ってる
11:08 AM
.の!!左側で!!!
Avatar
お〜〜なるほど
11:09 AM
method_exchangeImplementationsうけるな
Avatar
1年以上ぶりぐらいに詠唱したけど指が覚えてた
Avatar
ww
Avatar
一番知りたいのは
11:10 AM
NSStringがinitされてるか…なんだけど
11:10 AM
うーんどうやって調べれるかな
Avatar
initも同じように差し替えられないの?
11:12 AM
あ、initなんたらがたくさんあると捕まえられない可能性があるのか
Avatar
コンクリートクラスだから実体は違って、initは差し替えられなかった記憶がある
11:12 AM
俺の勘違いでなければ
11:14 AM
暗黙キャストというか
11:14 AM
違うな…なんだ…
11:15 AM
@omochimetaru 会社出ちゃった、NSStringにextension生やしてStringから呼べる?
Avatar
TのコンストラクタでUを受けるものは総じて本来的な型キャストで良いと思う
11:18 AM
import Foundation extension NSString { func piyo() -> Int { return 33 } } let a: String = "abc" a.piyo()
11:18 AM
@tarunon いけるね。
Avatar
実行時は同一のCFStringつまり
Avatar
あ〜、内部の実体が同じ場合はinitが呼ばれてない事もありえるね
Avatar
そそ
11:19 AM
てことはー
11:20 AM
Foundationをimportすると、StringがNSStringとして扱われる魔術がかかる
11:20 AM
structですらない
11:20 AM
ってところかな、キャストとは違う
11:21 AM
置き換わってるのはオブジェクトではなく、型自体だ
11:22 AM
いや、CFStringだからstructか
11:22 AM
むむ、わからんくなってきた
11:22 AM
Foundationに何か魔法が書いてそうだな
Avatar
確かどこかで見たことあるんですが、Objective-Cと互換性を持たせるようにimport Foundationで変更がかかるらしいです
Avatar
Stringはstructだからそれが可能ですね
11:24 AM
だがErrorはprotocolだから無理だな
Avatar
Foundationのクラスを優遇して推論してるような雰囲気ありますよね
Avatar
あーこれかなー
11:27 AM
swift-corelibs-foundation - The Foundation Project, providing core utilities, internationalization, and OS independence
11:27 AM
下の方に魔術用の型が存在する
Avatar
swift-corelibs-foundation - The Foundation Project, providing core utilities, internationalization, and OS independence
Avatar
これを見るに実行時に型変換は走ってるはず
11:28 AM
ですです
11:28 AM
一番下にも居ますね
11:29 AM
この辺が揃っていればコンパイラ君が実行時に暗黙的な変換を許してくれる…
Avatar
_SwiftBridgeable が気になる感
Avatar
2.xまでは内緒プロトコルも、取り敢えず名前を当てればコード見つけられたし、動く型を作れたんですが今はどうかな
Avatar
自分で書いたらStringから暗黙変換される型自作できんのか?w
Avatar
やってみて!
11:32 AM
いや、Stringからの暗黙変換は
11:33 AM
_NSBridgableと_CFBridgableだから
11:33 AM
Stringから、は無理かな
11:33 AM
Stringへ、はいけそう
Avatar
_SwiftBrideableとかが見えないっぽい
Avatar
見えなくても実装できる
11:34 AM
気合で!
Avatar
swift-corelibs-foundation - The Foundation Project, providing core utilities, internationalization, and OS independence
Avatar
3.0の時は気合で実装できたけど
11:34 AM
今はもう防がれた?
Avatar
気合とは・・・
Avatar
型名わかってれば、取り敢えず書くと
11:35 AM
2.xなら全てのメソッドが足りないよと怒られて出てきた
11:35 AM
3.0はどうやったんだったかな
11:36 AM
AnyObjectConvertible - Convert your own struct/enum to AnyObject easily.
11:37 AM
こういうのが出来た。今はもうこいつは要らない
Avatar
それって
11:37 AM
public protocol AnyObjectConvertible: _ObjectiveCBridgeable {}
11:38 AM
この_ObjectiveCBridgeableがFoundationをimportすると見えるからできたのでは?
Avatar
うーん、コード補完は効かないし、参照も出来なかった気がするんだけど
11:39 AM
ああ、2.xはprivate/internalが不完全で
11:39 AM
名前を当てれば動いてしまったからかな
Avatar
ww
Avatar
NSErrorは特にそれっぽいコードなさそうですね...
Avatar
いや、あったはず
11:43 AM
_BridgedStoredNSError
11:43 AM
この辺
Avatar
swift - The Swift Programming Language
Avatar
core側もおもろい
Avatar
昨日のNSErrorの件が気になりすぎてて、色々のぞいて見ます
Avatar
omochimetaru 3/31/2017 2:07 PM
// // util.swift // RuString // // Created by omochimetaru on 2017/03/31. // // internal func findSubArray<C: Collection, I>( array: C, index: I, target: C ) -> I? where I == C.Index { var i: C.Index = index while i < array.endIndex { if matchArray(array1: array, index1: i, array2: target, index2: target.startIndex, length: target.distance(from: target.startIndex, to: target.endIndex)) { return i } i = array.index(after: i) } return nil } internal func matchArray<C: Collection, I, D>( array1: C, index1: I, array2: C, index2: I, length: D) -> Bool where I == C.Index, D == C.IndexDistance, C.SubSequence.Iterator.Element : Equatable { if array1.index(index1, offsetBy: length) >= array1.endIndex { return false } if array2.index(index2, offsetBy: length) >= array2.endIndex { return false } let test1 = array1[index1..<array1.index(index1, offsetBy: length)] let test2 = array2[index2..<array2.index(index2, offsetBy: length)] for (x1, x2) in zip(test1, test2) { if x1 != x2 { return false } } return true }
2:07 PM
util.swift:16:46: Cannot convert value of type 'C.Index' to expected argument type '_.Index'
2:07 PM
うーん・・・
2:09 PM
referenceでもIndexがCollectionのassociatedtypeに書いて無くて
2:09 PM
なぞ
Avatar
型パラ2重に定義してないかこれ
Avatar
omochimetaru 3/31/2017 2:18 PM
最初は C.Index って書いてたんだけど
2:18 PM
それでもだめだった
2:19 PM
internal func findSubArray<C: Collection>( array: C, index: C.Index, target: C ) -> C.Index? { var i: C.Index = index while i < array.endIndex { if matchArray(array1: array, index1: i, array2: target, index2: target.startIndex, length: target.distance(from: target.startIndex, to: target.endIndex)) { return i } i = array.index(after: i) } return nil } internal func matchArray<C: Collection>( array1: C, index1: C.Index, array2: C, index2: C.Index, length: C.IndexDistance) -> Bool where C.SubSequence.Iterator.Element : Equatable { if array1.index(index1, offsetBy: length) >= array1.endIndex { return false } if array2.index(index2, offsetBy: length) >= array2.endIndex { return false } let test1 = array1[index1..<array1.index(index1, offsetBy: length)] let test2 = array2[index2..<array2.index(index2, offsetBy: length)] for (x1, x2) in zip(test1, test2) { if x1 != x2 { return false } } return true }
2:23 PM
あ〜〜〜〜いけた
2:23 PM
上の方の関数に where C.SubSequence.Iterator.Element : Equatable を付ける必要があった
Avatar
ああまあそりゃそうやね
Avatar
omochimetaru 3/31/2017 2:24 PM
エラーメッセージにつられてしまった
Avatar
Collectionの定義からIndex消えてるのはなんやろな
Avatar
omochimetaru 3/31/2017 2:24 PM
それ今のところ
2:25 PM
associatedtype Iterator = IndexedIterator<Self>
2:25 PM
この行によって
2:25 PM
IndexedIterator<T> の Tの制約が 間接的にSelfに掛かって
2:25 PM
SelfがIndex持ちになってる仮説を立てた
Avatar
無茶苦茶な
Avatar
omochimetaru 3/31/2017 2:25 PM
GenericClass<T> の Tのところ使って外側に制約かけてるのでは
Avatar
Collection、前はIndexableみたいな型貼り付けてたよね (edited)
2:27 PM
where Elements : _IndexableBase
2:27 PM
ははーん
2:27 PM
わかった
Avatar
omochimetaru 3/31/2017 2:27 PM
そのElementsがIndexedIterator<Elements>でしょ?
Avatar
_IndexableBase
2:27 PM
こいつはinternalなProtocolなので
2:28 PM
それが前提になったProtocolを外から観測すると
2:28 PM
消えて見える
2:28 PM
なので
Avatar
omochimetaru 3/31/2017 2:28 PM
消えて見えるw
2:28 PM
あ〜 _IndexableBaseにIndexが書いてあってCollectionはそれを継承してる?
2:28 PM
そう
Avatar
omochimetaru 3/31/2017 2:28 PM
でもそれだと、Self.Index見えるのがマズイ気が
2:28 PM
可視性汚染や
Avatar
まあそこはバグってことで
2:29 PM
報告したほうがええんやろか
Avatar
omochimetaru 3/31/2017 2:29 PM
public protocol Collection : _Indexable, Sequence {
2:29 PM
この_Indexableか
Avatar
そやね
Avatar
omochimetaru 3/31/2017 2:29 PM
なるほど・・・
2:29 PM
見えるけど見えない型とは。
Avatar
private/internal隠してるけど隠しきれてないな
2:30 PM
これはーーー
Avatar
omochimetaru 3/31/2017 2:30 PM
バグなのか仕様なのかよくわからんな
Avatar
バグでいいと思うけど
2:30 PM
いたずらできそう
Avatar
omochimetaru 3/31/2017 2:30 PM
まあねえ。
2:31 PM
あと
2:31 PM
String.UnicodeScalarView.init() は呼べるのに
2:31 PM
String.UTF8View.init()が呼べなくて
2:32 PM
これもなんなのか迷ってる
Avatar
謎いな
2:32 PM
悪いことしようとしたらPlayground死んだ
Avatar
omochimetaru 3/31/2017 2:33 PM
extension String.UnicodeScalarView : RangeReplaceableCollection { /// Creates an empty view instance. public init()
2:34 PM
extensionで生えてた
2:34 PM
UTF8Viewには無いのはなぜなんだ〜〜
Avatar
なんじゃこりゃ
2:37 PM
Reflection掘ってたらこんなのあった
2:37 PM
/// A type that explicitly supplies its own playground Quick Look. /// /// A Quick Look can be created for an instance of any type by using the /// `PlaygroundQuickLook(reflecting:)` initializer. If you are not satisfied /// with the representation supplied for your type by default, you can make it /// conform to the `CustomPlaygroundQuickLookable` protocol and provide a /// custom `PlaygroundQuickLook` instance. public protocol CustomPlaygroundQuickLookable { /// A custom playground Quick Look for this instance. /// /// If this type has value semantics, the `PlaygroundQuickLook` instance /// should be unaffected by subsequent mutations. public var customPlaygroundQuickLook: PlaygroundQuickLook { get } }
2:37 PM
楽しそう
Avatar
omochimetaru 3/31/2017 2:37 PM
ほ〜〜
2:38 PM
LiveViewはこの前使ったけど
2:38 PM
こっちはあれかな、1行ごとの結果とかを可視化する方
Avatar
そうそう
2:38 PM
Mirror周りもなんか色々悪いことできそうな感じになってる
2:38 PM
/// A type that explicitly supplies its own mirror. /// /// You can create a mirror for any type using the `Mirror(reflect:)` /// initializer, but if you are not satisfied with the mirror supplied for /// your type by default, you can make it conform to `CustomReflectable` and /// return a custom `Mirror` instance. public protocol CustomReflectable { /// The custom mirror for this instance. /// /// If this type has value semantics, the mirror should be unaffected by /// subsequent mutations of the instance. public var customMirror: Mirror { get } } /// A type that explicitly supplies its own mirror, but whose /// descendant classes are not represented in the mirror unless they /// also override `customMirror`. public protocol CustomLeafReflectable : CustomReflectable { }
Avatar
omochimetaru 3/31/2017 2:39 PM
numswチームに共有しとこ
Avatar
ObjectIdentifierっていうAnyからHash取れる構造も見つけた
2:40 PM
やっぱリフレクション最高やで!
2:40 PM
おもちゃ箱や
Avatar
omochimetaru 3/31/2017 2:41 PM
Hashってハッシュ値?それとも辞書のこと?
Avatar
public struct ObjectIdentifier : Hashable {
2:41 PM
Anyからinitできる
2:41 PM
ああ違う
2:41 PM
AnyObjectとAny.Typeだ
Avatar
まあAnyObject行けるなら事実上いけるか
Avatar
omochimetaru 3/31/2017 2:42 PM
同一性の抽象化か
Avatar
でもBoxになるやろうからあんまり使えないかな
Avatar
omochimetaru 3/31/2017 2:42 PM
In Swift, only class instances and metatypes have unique identities. There is no notion of identity for structs, enums, functions, or tuples.
2:42 PM
かいてあるね。
Avatar
だよなー
Avatar
omochimetaru 3/31/2017 2:42 PM
あ〜〜そうか、これが必要なのって
2:43 PM
== じゃなくて === ベースでDictionaryのキーにしたいときに
2:43 PM
[ObjectIdentifier: Hoge] こうすんのか
Avatar
できるね
2:49 PM
しかしCollectionからIndex消えてるのよろしくないな
Avatar
omochimetaru 3/31/2017 2:49 PM
前は見えたよねえ。
Avatar
不可視のtypealias/associatedtypeはどう考えてもやばい
Avatar
omochimetaru 3/31/2017 2:49 PM
splitメソッド、Foundationに合わせてcomponentsの方がいいんだろうか・・・
2:50 PM
なんかstdlibのジェネリクスは前からワケワカメすぎて、ヤバさがよくわからない
Avatar
いや
2:50 PM
Collection参照した時に
2:50 PM
subscript(index:Self.Index)って書いてあって
Avatar
omochimetaru 3/31/2017 2:51 PM
うん
Avatar
前は飛んでいったらIntが見つかるからああまあIntやねって感じ
Avatar
omochimetaru 3/31/2017 2:51 PM
そうなんよね
Avatar
今はそも飛べない
Avatar
omochimetaru 3/31/2017 2:51 PM
あ〜w
2:51 PM
たしかに。
2:51 PM
昔はそこでとべたな確かに。
Avatar
omochimetaru 3/31/2017 3:46 PM
/// Supply the default "slicing" `subscript` for `BidirectionalCollection` /// models that accept the default associated `SubSequence`, /// `BidirectionalSlice<Self>`. extension BidirectionalCollection where Self.SubSequence == BidirectionalSlice<Self>, Self.SubSequence.Index == Self.Index, Self.SubSequence.IndexDistance == Self.IndexDistance, Self.SubSequence.Indices == DefaultBidirectionalIndices<BidirectionalSlice<Self>>, Self.SubSequence.Iterator == IndexingIterator<BidirectionalSlice<Self>>, Self.SubSequence.SubSequence == BidirectionalSlice<Self>, Self.SubSequence._Element == Self._Element, Self.SubSequence.Indices.Index == Self.Index, Self.SubSequence.Indices.IndexDistance == Int, Self.SubSequence.Indices.Iterator == IndexingIterator<DefaultBidirectionalIndices<BidirectionalSlice<Self>>>, Self.SubSequence.Indices.SubSequence == DefaultBidirectionalIndices<BidirectionalSlice<Self>>, Self.SubSequence.Indices._Element == Self.Index, Self.SubSequence.Iterator.Element == Self._Element, Self.SubSequence.SubSequence.Index == Self.Index, Self.SubSequence.SubSequence.Iterator == IndexingIterator<BidirectionalSlice<Self>>, Self.SubSequence.SubSequence.SubSequence == BidirectionalSlice<Self>, Self.SubSequence.SubSequence._Element == Self._Element, Self.SubSequence.Indices.IndexDistance.IntegerLiteralType == Int, Self.SubSequence.Indices.IndexDistance.Stride == Int, Self.SubSequence.Indices.IndexDistance._DisabledRangeIndex == Int._DisabledRangeIndex, Self.SubSequence.Indices.Iterator.Element == Self.Index, Self.SubSequence.SubSequence.Iterator.Element == Self._Element, Self.SubSequence.Indices.IndexDistance.Stride.IntegerLiteralType == Int { public subscript(bounds: Range<Self.Index>) -> BidirectionalSlice<Self> { get } }
3:46 PM
あたまおかC
Avatar
omochimetaru 3/31/2017 6:12 PM
4> for (i, c) in "a\r\nb".characters.enumerated() { 5. print("[\(i)] \(c)") 6. } [0] a [1] [2] b CR + LFは書記素クラスタとして1つに結合するらしい
Avatar
この前のpinファイルと絡むネタです https://www.slideshare.net/mobile/teppeis/do-you-commit-yarnlock
Avatar
omochimetaru 4/1/2017 6:40 AM
読んでみました。20ページの「ユーザーは?」のところがよくわからない
Avatar
先週のString.compontentsの話
Avatar
omochimetaru 4/3/2017 2:34 AM
うん
Avatar
スタック見るの忘れてたからチェックしたら
2:35 AM
一応Stringに生えているみたいだった
Avatar
omochimetaru 4/3/2017 2:35 AM
あ〜
Avatar
libswiftFoundation.dylib`(extension in Foundation):Swift.String.components (separatedBy : Swift.String) -> Swift.Array<Swift.String>:
Avatar
omochimetaru 4/3/2017 2:35 AM
Foundationの中でextensionが生えてるだけか
2:35 AM
じゃあNSStringへの変換はやってないけど中で同じ実装は呼んでる (edited)
Avatar
そうそう
Avatar
omochimetaru 4/3/2017 2:35 AM
なるほど
Avatar
0x1032ae46b <+43>: callq 0x103326aaa ; symbol stub for: Swift.String._bridgeToObjectiveCImpl () -> Swift.AnyObject 0x1032ae470 <+48>: movq %rax, %r15 0x1032ae473 <+51>: movq %rbx, %rdi 0x1032ae476 <+54>: callq 0x10332706e ; symbol stub for: swift_unknownRetain 0x1032ae47b <+59>: movq %r12, %rdi 0x1032ae47e <+62>: movq %r14, %rsi 0x1032ae481 <+65>: movq %rbx, -0x38(%rbp) 0x1032ae485 <+69>: movq %rbx, %rdx 0x1032ae488 <+72>: callq 0x103326aaa ; symbol stub for: Swift.String._bridgeToObjectiveCImpl () -> Swift.AnyObject 0x1032ae48d <+77>: movq %rax, %r12 0x1032ae490 <+80>: movq 0x97881(%rip), %rsi ; "componentsSeparatedByString:" 0x1032ae497 <+87>: movq %r15, %rdi 0x1032ae49a <+90>: movq %r12, %rdx 0x1032ae49d <+93>: callq 0x103326f00 ; symbol stub for: objc_msgSend
Avatar
omochimetaru 4/3/2017 2:35 AM
それなら素直だな
2:36 AM
そのまんまなシンボルだ
Avatar
最後にobjc_msgSend
Avatar
omochimetaru 4/3/2017 2:36 AM
ひえっ
Avatar
そこからimplに流入してる
Avatar
omochimetaru 4/3/2017 2:36 AM
+80でレシーバ名リテラルをw
2:36 AM
可読性が高いアセンブリだ(?)
Avatar
String.componentsの、下の方見るとswift_rt_swift_dynamicCastClassとかあったりして
2:37 AM
なるほどーという感じ
2:39 AM
StringからNSStringのキャストと、NSArrayからArray<String>を持ってる
2:39 AM
String.componentsが見えない、参照できないのは
2:40 AM
Collectionにおける不可視のIndexと似た何かな?と思った
Avatar
omochimetaru 4/3/2017 2:41 AM
たしかにCmd+CLickでfoundationのトップが開いて
2:41 AM
シグネチャにとべないから
2:41 AM
変な事が起きてると感じてたけど
2:41 AM
飛べるはずのものが飛べない現象が他にもあるから
2:41 AM
これだけじゃなんとも言えないんだなあ
Avatar
2:42 AM
Foundationに何回か飛んだら見つけたわ
2:42 AM
import FoundationでFoundtationに飛んで、その中にあるimport Foundationからもう一回飛ぶと
2:42 AM
全部見えるようになった
Avatar
omochimetaru 4/3/2017 2:43 AM
ほんとだ!!
2:43 AM
なんだこれw
Avatar
カラクリだなぁ
2:43 AM
わからんよこんなの
Avatar
omochimetaru 4/3/2017 2:43 AM
めちゃめちゃ定義されとる
2:43 AM
2回飛ぶの
2:43 AM
覚えておこう
2:44 AM
あ、そもそも
2:44 AM
import Foundationの文から飛べば見えるわ
2:44 AM
メソッドのところからだと見えないバージョンの画面になる
Avatar
ひどい
Avatar
omochimetaru 4/3/2017 2:45 AM
(rintaroさんが知見を入力してる気配がする
Avatar
オーバーレイで定義されているメソッドに直行できないっていう単なる Xcode のバグなのかなと思っただけです。
Avatar
omochimetaru 4/3/2017 2:48 AM
直行できないだけじゃなくて、定義が無い空っぽ?のヘッダ空間みたいなものが出てくるんですよね
Avatar
これですけど、やってることは (self as NSString).components(separatedBy: separator)
Avatar
おおー
2:49 AM
_nsが生えてる
Avatar
omochimetaru 4/3/2017 2:49 AM
extension String { //===--- Bridging Helpers -----------------------------------------------===// //===--------------------------------------------------------------------===// /// The corresponding `NSString` - a convenience for bridging code. var _ns: NSString { return self as NSString } (edited)
2:49 AM
なるほど
Avatar
Xcode で飛んだときに上部に Foundation > String っていうパスが出ますけど、そんなものは無いと。
Avatar
omochimetaru 4/3/2017 2:52 AM
あ〜なるほど
2:53 AM
この何もない画面は Foundation/String
2:53 AM
いろいろ出てるやつは Foundation だから
2:53 AM
import Foundationから飛ぶと出てくるんですね 理解した
2:54 AM
てことは単純にクリックした時に 本当は Foundation の中の extension String に行くべきところが、 Foundation/String なページに飛ぼうとするところがバグっぽいですね。
Avatar
Xcode か SourceKit のバグですね。
Avatar
omochimetaru 4/3/2017 7:31 AM
@hiragram もしもし
Avatar
@omochimetaru もち
Avatar
omochimetaru 4/3/2017 7:32 AM
@tarunon それは確かに。ちょっと極端すぎる例だった。
7:32 AM
この話題最近俺も考えてた
7:32 AM
思うのは
Avatar
omochimetaru 4/3/2017 7:33 AM
うん
7:33 AM
APIに応じてフィールドが欠損したりする方と
7:33 AM
画面に表示するデータ構造をモデル化する方の型は
7:33 AM
別にせざるを得ないと思うんだよね
7:33 AM
扱ってるものが違うから
Avatar
うん
Avatar
元々の意味でのViewModelかな
Avatar
omochimetaru 4/3/2017 7:34 AM
そうだね、表示系の方はまさにViewModelかも。
Avatar
APIを扱うRepository層としてのエンドポイントのモデルと、アプリ内のデータ基盤としてのモデルがありそう
Avatar
omochimetaru 4/3/2017 7:34 AM
同意
7:35 AM
たぶん現在のSwiftの型システムでは
7:35 AM
現実のユースケースに対応しきれていない問題でもあると思ってて
7:35 AM
本当は欲しいのは
7:36 AM
一通りのキーが定義された型に対して
7:36 AM
静的に選択された一部のキーだけを持った
7:36 AM
部分構造型とでもいえばいいのかなあ
7:36 AM
そういうものが簡単な記法で生成できないと
7:37 AM
常に冗長なキーだらけの型で共通化したコードになっちゃう
7:38 AM
たとえば CommentListResponseの中の Comment.Userは名前しか持たないんだけど、そういう名前しかもたないNameOnlyUserに対して、完全なUserは User is NameOnlyUser な互換性がないといけない
Avatar
User型がエンドポイント毎に違って辛いのは
7:38 AM
User型単体ならそれほどでもないけど
Avatar
omochimetaru 4/3/2017 7:38 AM
プロトコルでシコシコ頑張ればできそうだけど記述量が多すぎる
Avatar
例えばTweet型にUser型が含まれる時に
7:38 AM
SearchとHomeTimeLineでUserの型が違うけどTweet型のプロパティは同じとかな
7:38 AM
そういうウンコみたいな状況が普通に発生し得る
Avatar
omochimetaru 4/3/2017 7:38 AM
うんうん。
7:39 AM
現状だと同じ部分について重複して書いた上で相互の変換メソッドを書き下す
7:39 AM
みたいになってしんどくなって
7:39 AM
ボトムタイプを作って逃げてしまう
Avatar
現状だと同じ部分について重複して書いた上で相互の変換メソッドを書き下す
それやってる つらい
Avatar
omochimetaru 4/3/2017 7:39 AM
ことになる
Avatar
Tweet<U: User>は有りなんじゃねーかなーとか
7:39 AM
考えたけどなぁ
7:40 AM
何れにしてもprotocol使ってHimotoki/Argoのアプローチだと
7:40 AM
重複したデコード処理書かなきゃいけなくなって辛い
Avatar
omochimetaru 4/3/2017 7:40 AM
Himotokiライクなデコーダは、例外的な事が起こらない時は機械生成可能だから
7:40 AM
それはそれでほしいよね
7:40 AM
Himotokiの、最もお行儀が良いスタンダードなパターンのdecodeメソッドについては手書きしたくない (edited)
7:45 AM
@hiragram ところでその、あるかないか未取得かの型は
Avatar
はい
Avatar
omochimetaru 4/3/2017 7:46 AM
enum NullableResponseField<T> { case .some(T) case .null case .notProvided } enum NonnullResponseField<T> { case .some(T) case .notProvided } とかやるか、 Optional<Optional<T>> とするしか無さそう (edited)
Avatar
そうそう
Avatar
omochimetaru 4/3/2017 7:47 AM
で、この2つを使ってフィールドを埋めまくった
Avatar
そこまでは発想できた
Avatar
二重Optionalは可読性が著しく下がりそう
Avatar
omochimetaru 4/3/2017 7:47 AM
struct UserResponse { var name: NonnullResponseField<String> var bio: NullableREsponseField<String> }
Avatar
二重optionalはやりたくないなあ
Avatar
omochimetaru 4/3/2017 7:47 AM
とかやって
Avatar
extension NonnullResponseField { var asOptional: E?? } ならまぁ。
Avatar
omochimetaru 4/3/2017 7:48 AM
protocol PartialResponseType { associatedtype ConcreteType } 的な何かで、 UserUserResponse を紐付けておくとなんか嬉しいところがあるかも・・・? (edited)
7:49 AM
ぐらいのところまでで考え中
Avatar
そうそう 大体そんな感じのことを考えていて、 NullableResponseField に当たる、Optionalみたいなパシッとした名前ないかなあというのが最初のツイート
7:50 AM
たるのん氏からAmbiguous案をもらったけど、若干エラーっぽい雰囲気があるのでもうちょっと他のないかなってかんじ
Avatar
omochimetaru 4/3/2017 7:50 AM
APIに依存した話だからOptionalみたいにセントラルな名前じゃなくて良い気がするなあ
Avatar
Optional<T> は T? みたいなシンタックスシュガーがあるけどこれから作るやつは無いからごちゃごちゃ長い名前を書きたくない というのがあった
Avatar
omochimetaru 4/3/2017 7:51 AM
なるほど。
Avatar
型シンタックスシュガー任意に作りてーと思ったけどあったらあったで混沌化しそう
Avatar
omochimetaru 4/3/2017 7:52 AM
使うファイルでだけ typealias K<T> = NulableResponseFiled<T> みたいな手はあるけどね
Avatar
シンタックスシュガー欲しい気持ちはあんまりないなあ 混沌化しそうわかる
7:53 AM
なぜK
Avatar
omochimetaru 4/3/2017 7:53 AM
Key
Avatar
なる
Avatar
omochimetaru 4/3/2017 7:55 AM
Absentable<T>
7:56 AM
Optionalの類義語探すだけになりそう。なんか有名なパターンとかないんかねえ。
Avatar
Optionalの類義語探すだけになりそう
そうなのよw
Avatar
omochimetaru 4/3/2017 7:57 AM
まあ、大事なのはその類義語に特別な意味を付与したってことをREADMEに書いておくことだから・・・
Avatar
エンドポイントによって型が違うのどーすんの問題にみんな悩んでいるということで安心した
Avatar
サーバーサイドをしばいてAPIを作り直させるというひどい方法もあります
Avatar
omochimetaru 4/3/2017 7:59 AM
Optionalだけ ? があってズルいっていうのはさもありなんだなあ
Avatar
Unbox使ってますがエンドポイントで変わりそうな箇所は全部雑にOptionalにしちゃってます
Avatar
omochimetaru 4/3/2017 8:14 AM
@moaible さっきのhiragramの要件では、実際に取得しなかったのか、値nullが入っているのかで、制御が変わる場面があるとのことです (edited)
Avatar
なんかOptionalにtypealiasつけて
8:15 AM
Maybeでもいいけど
8:15 AM
Maybe<T?>とかしておけば
8:16 AM
可読性そこまで犠牲にせずに済むのでは?って気もした
Avatar
あーそういうことですか... 🤔
Avatar
optionalにtypealiasってどゆこと
Avatar
omochimetaru 4/3/2017 8:16 AM
面白い
Avatar
typealias Maybe<T> = Optional<T>
Avatar
ああなるほど
Avatar
で、キーの有無についてはこれを使う
8:17 AM
まーコンパイラで制約違反を弾けないから微妙かな (edited)
8:17 AM
人間は怠惰で傲慢なので、決まりごとは守らないからコンパイラには厳しく躾けてもらう必要がある
Avatar
parser側で3パターンのenum(nonnull/nullable/responsenull)で定義したResponseFieldに合わせてdecodeするような作りだといまいちです?
8:43 AM
この例と被るのか enum NullableResponseField<T> { case .some(T) case .null case .notProvided } enum NonnullResponseField<T> { case .some(T) case .notProvided }
Avatar
omochimetaru 4/3/2017 8:43 AM
そうですね、あと、その3値enumの名前が悩ましいです。
Avatar
Swaggerとかだとnullableの属性が3.0から追加されるらしいのと、key自体の存在はrequiredだからrequiredの対義語とかだと通じやすかったりするんですかね
8:53 AM
ってなるとoptionalなのか...一周してしまう
Avatar
omochimetaru 4/3/2017 8:54 AM
そうなんですよね〜 omochimetaru - 今日 午後4時55分 Absentable<T> Optionalの類義語探すだけになりそう。なんか有名なパターンとかないんかねえ。 hiragram - 今日 午後4時56分 > Optionalの類義語探すだけになりそう そうなのよw
Avatar
やっと皆さんに追いついた感
8:58 AM
個人的には @omochimetaru さんが言ってた通りセントラルな名前じゃなくていい派ですね、用途が限定的なわけですし
APIに依存した話だからOptionalみたいにセントラルな名前じゃなくて良い気がするなあ
Avatar
omochimetaru 4/3/2017 8:58 AM
なるほど
Avatar
アプリ全体から見るとセントラルじゃなくていいけど、モデル層を別ターゲットに切り出してるのでそこでみると結構セントラルなのではという気がしている
9:00 AM
モデル層というかAPI叩く層
Avatar
レイヤー的に分けてるのであればAPIを意識した名前だと冗長なのも分かるし...うーん
Avatar
セントラルかどうかは僕はけっこうどうでもいい気持ちで名付けについては
Optional<T> は T? みたいなシンタックスシュガーがあるけどこれから作るやつは無いからごちゃごちゃ長い名前を書きたくない というのがあった
これに尽きる
9:02 AM
ところでdiscordって1メッセージに対するパーマリンクってどうやって取るの
Avatar
omochimetaru 4/3/2017 9:02 AM
見当たらないね>パーマリンク
Avatar
日付時刻を右クリックで取れるのが相場だろうが〜というきもちだ
Avatar
確かに
Avatar
うーん3値enumはダメな気がしてきた
11:01 AM
状態としては
11:01 AM
キーの有無とキーが存在する時にnullableである、という2つは独立であるはず
11:01 AM
なので、結局T??でしかない
11:01 AM
外側に名前をつけるべきなんだろう。
11:02 AM
typealiasはコンパイラ弱くなるから、型作るとしてもそれはKeyの有無を意味する型に留めるべき
11:02 AM
nullableはお前の仕事じゃねぇ
Avatar
omochimetaru 4/3/2017 11:02 AM
まあ理論的にはそうだよね
11:03 AM
Optionalの場合は3値で元々がNonnullの場合は2値で両方実装したりしないといけないし。
Avatar
いや
11:03 AM
T??って3値だよ
11:04 AM
switch x { case .none, case .some(.none) case .some(.some) }
Avatar
omochimetaru 4/3/2017 11:04 AM
enum NullableResponseField<T> { case .some(T) case .null case .notProvided } enum NonnullResponseField<T> { case .some(T) case .notProvided }
11:04 AM
3値方式だと、この2つを作らないといけなくなるってこと
Avatar
そうそう
11:04 AM
使いにくい、外側だけにして中身任意にしたほうが良い
Avatar
omochimetaru 4/3/2017 11:04 AM
クラスのプロパティの型が2重入れ子のジェネリクスになるのが微妙かなと思った
11:04 AM
ま〜でも Observable<Int?> とかも2重か
Avatar
まあ見た目はNullableResponseField<T?>になるし
11:05 AM
いいんじゃね
11:07 AM
ふーむ、大体わかってきた
11:09 AM
Genericsなnested classも作れるようになったし、その気になればなんとかなるかな?
11:09 AM
暇な時にもう一回試してみよう
11:10 AM
前回はうまく行かなかった
Avatar
omochimetaru 4/4/2017 1:43 AM
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
1:44 AM
rejectされたwwwww
Avatar
w
Avatar
今朝Elica氏の哀しみのツイット見て笑った
Avatar
メーリスではみんないいねいいね言ってなかった?
Avatar
omochimetaru 4/4/2017 1:46 AM
Finally, the core team discussed a different potential design for “private” that admits a limited form of type-based access control within files. We will open a separate discussion thread on Swift Evolution, with the subject "Type-based ‘private’ access within a file", and are seeking further discussion there and a motivated volunteer to turn it into a new proposal for Swift 4.
1:46 AM
型ベースのファイル内アクセス制御の方式について考える事にした?
Avatar
さっき流れてた Type-based ‘private’ access within a file はコレか
1:47 AM
typeprivateみたいなのはほしいと思ってた
Avatar
omochimetaru 4/4/2017 1:47 AM
あ〜
1:47 AM
ある型から見えるみたいな?
Avatar
同じ型からじゃないかな
Avatar
お、それは欲しい
1:47 AM
extensionからもアクセスできるのね
Avatar
omochimetaru 4/4/2017 1:47 AM
C++の friend 文はけっこ〜闇だったけど
Avatar
struct Hoge { typeprivate var fuga: String } extension Hoge { func sayFuga() { print(fuga) } } みたいな?
Avatar
それがファイルを超えてアクセス可能なのか、ライブラリ超えたらどうなるのか
Avatar
これほしいとおもっていた 今までfileprivateにするしかなかったのがもにょもにょしてた
Avatar
が、気になる
Avatar
omochimetaru 4/4/2017 1:48 AM
とりあえず突っぱねただけじゃなくてもっと考えるぞっって感じなら良さそう
Avatar
within a file だから同一ファイルだけじゃないかな
Avatar
ほんとだ
Avatar
fileprivateだと同じファイルなら別の型からも見えてたけど、同一ファイルでかつ同じ型じゃないとみれないのがType-based ‘private’ access within a fileだとおもう
Avatar
omochimetaru 4/4/2017 1:49 AM
ちなさっきの引用はこのメールね>[swift-evolution-announce] [Rejected] SE-0159: Fix Private Access Levels
Avatar
omochimetaru 4/4/2017 1:50 AM
ああ、本スレにもそのまま書き込まれてんのか
1:50 AM
[swift-evolution] Type-based ‘private’ access within a file
Avatar
swift-evolution-announceなんてMLがあったのか(今知った)
Avatar
あんまりアクセス修飾子をぽこじゃか追加しても、多くの人間は結局まともに使えないとかならないかな
Avatar
Type-based ‘private’ access within a fileについてはむしろfileprivateの本来あるべき姿な気がするのでこれは歓迎
1:51 AM
むしろType-based ‘private’ access within a fileじゃなくてfileprivateじゃなきゃこまるようなシーンなくない
Avatar
それはわかる
Avatar
omochimetaru 4/4/2017 1:51 AM
@hiragram うん、僕はアナウンスしか取ってない
Avatar
名前がわかりやすくなるならそれで良い
Avatar
omochimetaru 4/4/2017 2:06 AM
スレの提案を読んだ
2:06 AM
* An extension of “X” in the same file * The definition of “X”, if it occurs in the same file * A nested type (or extension thereof) of one of the above that occurs in the same file This design has a number of apparent benefits: + “private” becomes the right default for “less than whole module” visibility, and aligns well with Swift coding style that divides a type’s definition into a number of extensions. + “fileprivate” remains for existing use cases, but now it’s use it more rare, which has several advantages: + It fits well with the "progressive disclosure” philosophy behind Swift: you can use public/internal/private for a while before encountering and having to learn about “fileprivate” (note: we thought this was going to be true of SE-0025 <https://github.com/apple/swift-evolution/blob/master/proposals/0025-scoped-access-level.md>, but we were clearly wrong) + When “fileprivate” occurs, it means there’s some interesting coupling between different types in the same file. That makes fileprivate a useful alert to the reader rather than, potentially, something that we routinely use and overlook so that we can separate implementations into extensions. + “private” is more closely aligned with other programming languages that use type-based access control, which can help programmers just coming to Swift. When they reach for “private”, they’re likely to get something similar to what they expect—with a little Swift twist due to Swift’s heavy use of extensions. + Loosening the access restrictions on “private” is unlikely to break existing code.
2:08 AM
・privateは同じファイル内のエクステンションからも見えるようになる ・fileprivateは元々同じファイル内で別々の型の間で可視性をつなぐためで、コードを読む人にとって注意する場所として警告するためのキーワードで、その役割は残す
Avatar
妥当な感
Avatar
omochimetaru 4/4/2017 2:08 AM
とか書いてある
Avatar
現状のコードとの互換性を壊さずより便利に、だとこれが精一杯じゃないの
Avatar
omochimetaru 4/4/2017 2:09 AM
で、「これだと完全なスコープprivate無くなっちゃうけど何か欲しい?」とか、意見くれやって感じ
Avatar
今のprivate相当のものはほしいなあ
Avatar
scopedとか追加すんの?
Avatar
omochimetaru 4/4/2017 2:09 AM
そこらへんは、意見をくれや〜ってのが >>1
Avatar
ふむー
Avatar
omochimetaru 4/4/2017 2:10 AM
スレは結構伸びてるからまだわからん
2:10 AM
でもSE159の話のときみんなextensionのことばっか言ってたしだいたいこれで良さそうな気がする。個人的には。 (edited)
Avatar
スコープprivateなくなっておっけーってこと?
Avatar
omochimetaru 4/4/2017 2:11 AM
俺的には無くて良い気がするなあ
2:11 AM
なんかそれがあると結局同じループしそう
Avatar
うーむ
Avatar
増えてもヒトには扱えない、かなぁ
Avatar
omochimetaru 4/4/2017 2:11 AM
なるべくscopedにしろ派 vs 拡張の余地を残せ派 vs 適切に考慮しろ派
2:12 AM
第一印象であってまだ深く考えられてはないです
Avatar
アクセス修飾子についてあんまり深く考察してないけど↑だとなるべくscopedにしろ派かなあ
Avatar
昨日のGenericsネタ、この定義で試してみました
Optional<T> は T? みたいなシンタックスシュガーがあるけどこれから作るやつは無いからごちゃごちゃ長い名前を書きたくない というのがあった
これは解決できてないのでなんともですが ↓修正版 protocol FieldProperty { associatedtype Value } struct Field<T> { enum Requirable: FieldProperty { typealias Value = T case some(T) case notProvided } enum Nullable: FieldProperty { typealias Value = T? case some(T?) case notProvided } }
(edited)
Avatar
nested使ってもっと便利に書けるかと思ったけどそんなに変わらずですね 😰 (edited)
Avatar
ザハ先生の踏んだ2つのバグやばすぎるのなー
11:11 AM
⚠️ It looks like there is significant number of regressions in Swift 3.1 compiler ⚠️ The problems occur in Release builds when optimizations are turned on. It looks like Debug versions work ok so f...
Avatar
deinitやばそう
Avatar
omochimetaru 4/4/2017 11:15 AM
その件に絡んでた人アップルのSwiftの人だった
Avatar
deinitもですが、NSErrorのキャストでクラッシュも相当
Avatar
最適化で結構問題起きるので、ReactiveSwiftとかではReleaseでCI回してます
Avatar
この間見つけた強制キャストとのコンボで確実にクラッシュさせられる
Avatar
Errorもさっき確認した
Avatar
omochimetaru 4/4/2017 11:16 AM
コンボw
Avatar
強制キャストで死ぬの確認してないけど、多分死んでるの_bridging系だから死ぬと思う
Avatar
3.1移行してるんですが3.0に上げた時より破壊的な変更な気がしてます
Avatar
破壊的、仕様が変更されたではなく、unstableという意味ですか?
11:24 AM
壊れ方は書いてる型に依存しそう
Avatar
主にSwiftTaskで書いてる箇所と、TableViewでenum利用してsectionとrowを分けてるところが全部ビルドエラーですね..
壊れ方は書いてる型に依存しそう
このパターンなのが否めないです
(edited)
Avatar
SwiftTaskはそもそも3.0対応してましたっけ
Avatar
一応branchはあって、tagは切られておらずです
Avatar
inamiyさんがまだ同僚だった頃に同僚だし質問できるからと採用したら、RxSwiftかReactiveCocoaに移住してねと言われた記憶
Avatar
oh...
Avatar
3.1からのtypealiasの件、wandboxで試してみました 下記のコードで3.0.2までは動きますが、3.1-devとXcode8.3ではエラーになります open class Hoge<T> { public typealias ErrorInfo = (error: Error?, isCancelled: Bool) var receiveError: ((ErrorInfo) -> Void)? } Hoge<String>().receiveError = { (errorInfo: Hoge.ErrorInfo) in print(errorInfo) }
3:50 PM
これは3.1でも通ります open class Hoge<T> { public typealias ErrorInfo = (error: Error?, isCancelled: Bool) var receiveError: ((ErrorInfo) -> Void)? } Hoge<String>().receiveError = { (errorInfo: Hoge<Any>.ErrorInfo) in print(errorInfo) }
3:52 PM
型変数を定義してるスコープ内の型にアクセスする際は、アクセスする際に型変数を埋めることが3.1から必須になったってことみたいです // o Hoge<Any>.ErrorInfo // x: 3.1〜Hoge.ErrorInfoとHoge<T>.ErrorInfoは区別する Hoge.ErrorInfo (edited)
Avatar
ネストしたGenerics型作れるようになったので、妥当な感
3:53 PM
前まで通ってたのが謎ではある
Avatar
確かに以前の方がアクセスできてしまうのはおかしい感あります (edited)
Avatar
スコープがジェネリクス型の中ならinner typeを自身の型を省略して書ける。typealiasの宣言場所がprotocolなら、自身の型を書かなければいけないが、型パラメーターは省略可能、スコープが外なら型パラメーター含め全て書かないといけない
4:14 PM
こんな感じだったはず
Avatar
omochimetaru 4/5/2017 1:19 AM
@omochimetaru @KrunoslavZaher @juliobailon Looks like Erik from the optimizer team just fixed it: https://t.co/oUFgxzYCE0
Avatar
リリース待ちか
Avatar
omochimetaru 4/5/2017 1:21 AM
こんなスピード感あると思ってなかった
Avatar
またファイルを分けるとコンパイルが通らなくなるバグを踏んでしまった
Avatar
omochimetaru 4/5/2017 11:58 AM
またw
Avatar
protocol extensionをファイル毎に分割して生やしまくると死ぬっぽい
11:58 AM
最小ケース探しの時間だ…
12:02 PM
12:02 PM
InstantiateTestsResourceをビルドすると再現できる。電車に間に合わなくなる前に会社でよ
Avatar
これもコンパイル順っぽいですね…
4:00 PM
つら
Avatar
昨日の、associatedtypeにTupleを与えてるのがどうも良くなかったらしく
12:02 AM
GenericsなTuple2を作って入れ替えたら素直に動くようになった
12:03 AM
Tupleを使ってるとPlaygroundも動いたり動かなかったりで、まだ調べないといけない。結論出たらまた貼り付けます。
👀 1
Avatar
omochimetaru 4/7/2017 12:58 AM
良さそうなプロポーザルがガシガシ来てる
Avatar
なんか今朝めっちゃ賑やかだった
Avatar
7本?一体何が起こったんだ・・・
Avatar
omochimetaru 4/7/2017 1:06 AM
昨日の夜と今日起きてからで半々ぐらいに別れた
1:06 AM
あっちでは1日かな?
Avatar
たぶんね。
1:07 AM
まだ一日終わってないと思う。
Avatar
omochimetaru 4/7/2017 1:08 AM
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
Avatar
最近 structindirect なプロパティほしいなぁと思ってるんだけどどうでしょう?
Avatar
omochimetaru 4/7/2017 1:09 AM
プロパティがインダイレクトってどういうことです?
1:09 AM
型定義のときに使うやつ?
1:09 AM
enumとかで。
Avatar
struct Hoge { let a : Hoge } ↑できない
Avatar
omochimetaru 4/7/2017 1:09 AM
あー
Avatar
@tarunon そうそれ。
Avatar
omochimetaru 4/7/2017 1:09 AM
Box挟めばいいけど
Avatar
enumindirect の導入で解決された
Avatar
omochimetaru 4/7/2017 1:10 AM
いや、それできちゃまずくない?
1:10 AM
enumは、caseによってループが終端するけど
Avatar
どういうシーンでほしいのか気になりますね
Avatar
omochimetaru 4/7/2017 1:10 AM
structだとループから抜けられない
Avatar
あー、 Optional じゃないといけないかも。
1:11 AM
あれ? Optional だと入れられるのか
Avatar
omochimetaru 4/7/2017 1:11 AM
indirectは実装が参照なだけで、実際にはヌルにならないから。
Avatar
なんか最近これが出来なくて困ったことがあって
1:11 AM
なんだったかな
Avatar
うん、僕も困ったことが最近あって
Avatar
omochimetaru 4/7/2017 1:11 AM
Optionalならそもそも普通に書ける気が
Avatar
エンドレスにはなってなかったはず
Avatar
Optionalなら書けそう
Avatar
SwiftScriptのASTで再帰的な構造が出てきて
1:12 AM
コンパイルエラーになって気づいたから
1:12 AM
何かできないことがあったはず。
1:12 AM
で、そのときは enum に逃がして解決したはず。
1:12 AM
ちょっと今時間ないので後で調べてみます。
Avatar
omochimetaru 4/7/2017 1:13 AM
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
1:13 AM
これは例の0025の続きだな
Avatar
いやOptionalでも無理では
Avatar
1> struct Foo { 2. var bar: Int 3. var foo: Foo? 4. } error: repl.swift:1:8: error: value type 'Foo' cannot have a stored property that references itself struct Foo { ^
1:13 AM
ああそうか
Avatar
そう、Optionalで無理だから困ってた
Avatar
Optionalindirect じゃないからだ。
1:14 AM
indirectOptional を作れば解決するのか。
Avatar
omochimetaru 4/7/2017 1:14 AM
そのfooにindirectをつけたいということか
Avatar
indirect enum IndirectOptional<T> { case some(T) case none } struct T { let i: Int let a: IndirectOptional<T> }
1:15 AM
OK っぽい
Avatar
Avatar
omochimetaru 4/7/2017 1:15 AM
やっぱり
1:15 AM
ユーザー定義型構築演算子が
1:16 AM
ほしいね。
Avatar
そうなっちゃいますね
Avatar
omochimetaru 4/7/2017 1:16 AM
ww
Avatar
それか素Optionalが初めからindirectで、良いんじゃないって気がしたけど
1:16 AM
コンパイラの負荷が増大するかな
Avatar
うん、何がよくないのか今考えてました
Avatar
omochimetaru 4/7/2017 1:16 AM
それだと効率が悪い
1:17 AM
ペイロードがスタックに置けなくなる
Avatar
Optional で包んだ時点でヒープにいっちゃうのか
Avatar
あれ、よくわかってないんですが、Optionalがindirectじゃないって、じゃあなんで Hoge?? が書けるんですかね
Avatar
Optional<Optional<Hoge>>は別にループしてない
Avatar
omochimetaru 4/7/2017 1:19 AM
それはHogeがループしてるわけじゃないから
Avatar
あ、そうか
Avatar
Tがループする場合がindirectが要る
Avatar
理解です
Avatar
うーん
1:20 AM
IndirectOptional、普通に筋が悪い
Avatar
やっぱ↓みたいに書きたいなぁ。 struct Foo { var bar: Int indirect var foo: Foo? }
Avatar
indirect enum Foo { case Tail(int: Int, str: String) case Head(int: Int, str: String, foo: Foo) var int: Int { // switch書く } var str: String { // switch書く } var foo: Foo? { // switch書く } init(int: Int, str: String, foo: Foo?) { if let foo = foo { self = .Head(int: int, str: str, foo: foo) } else { self = .Tail(int: int, str: str) } } }
1:22 AM
Foo使う人にとってはこれが一番使いやすいな
1:22 AM
Fooを書く人は犠牲になってもらおう
Avatar
なるほど。
Avatar
omochimetaru 4/7/2017 1:23 AM
indirect var x : T? で良いと思う
Avatar
あればねw
Avatar
omochimetaru 4/7/2017 1:23 AM
同じこと書きたくないし。
Avatar
待ってる間、どう書くかを考えていて、IndirectOptional追加するのは
1:24 AM
使う側はしんどいなーと
Avatar
でも struct Foo { var bar: Int indirect var foo: Foo } はできないわけだし、ちょっとややこしそうだな。
Avatar
omochimetaru 4/7/2017 1:24 AM
なるる
Avatar
まあ、 enumindirect も同程度の理解を要求されるしいいのか?
1:25 AM
swift-evolution に投げてみてもおもしろいかも?
Avatar
indirect enum IndirectOptional<T> { case some(T) case none init(_ value: T?) { switch value { case .some(let t): self = .some(t) case .none: self = .none } } } extension IndirectOptional { var asOptional: T? { switch self { case .some(let t): return .some(t) case .none: return .none } } } struct T { var i: Int private var _a: IndirectOptional<T> init(i: Int, a: T?) { self.i = i self._a = IndirectOptional(a) } var a: T? { set { _a = IndirectOptional(newValue) } get { return _a.asOptional } } } 使う側も書く側も楽に出来た気がする。
1:30 AM
やっぱスッと書きたいですね
Avatar
Haskell とかだと問題にならない再帰的構造を作るときにひっかかっちゃうのは微妙ですね。
1:32 AM
Swift が値型で完結できる範囲を広げるには、やっぱり indirect プロパティほしいなぁ。
1:33 AM
enum も昔は参照で Box してたけど indirect で解決されたわけだから、 struct でだけ Box が必要って今の状況は変な気がする。
Avatar
omochimetaru 4/7/2017 1:34 AM
今ってindirectってプロパティじゃなくてenumの頭に付けてるんですよね?
Avatar
case にも付けられます。
Avatar
omochimetaru 4/7/2017 1:34 AM
なるほど
Avatar
enum IndirectOptional<Wrapped> { case none indirect case some(Wrapped) }
1:35 AM
↑のノリでプロパティにも indirect 付けたい。
Avatar
omochimetaru 4/7/2017 1:35 AM
今多分できてない理由の推測で
1:35 AM
indirectついたら、それは常にindirectなんじゃないかな
1:35 AM
おそらく、 indirect var a: Int?var b: Int? があるときに (edited)
1:36 AM
ab のメモリ上でのレイアウトが違っちゃって、 Int? に2種類のレイアウトがあることになるから
1:36 AM
うまいこと変換処理を挟まないといけないからとりあえず今は無いって木がする
Avatar
ん?? a だけアドレスになんじゃないの?
Avatar
omochimetaru 4/7/2017 1:36 AM
そのaを
1:37 AM
func f(x: Int?) に渡す時に
1:37 AM
あ、でも今もコピーしてるから同じか?
Avatar
struct Foo { var bar: Int indirect var foo: Foo? } のサイズは 64 bit 環境だと 16 バイト
1:37 AM
という想定。
Avatar
omochimetaru 4/7/2017 1:37 AM
いや、Fooのサイズは1種類だと思います。
1:38 AM
全然別の所で書かれた var xx: Foo?
1:38 AM
ポインタになってないって話し
Avatar
Foo? は 17 バイトでしょ??
1:38 AM
Foo は値型で、 Foo が 16 バイトだから。
Avatar
Foo.fooとxxで受け渡しするときに
1:38 AM
ポインタ型からOptionalへの変換が必要で
1:38 AM
これはまだない、ということ?
Avatar
omochimetaru 4/7/2017 1:39 AM
そう
1:39 AM
indirect Int?Int? の2つがあることを前提にコンパイラを修正しないといけない
Avatar
それって indirect case から値を取り出すときと何が違うの?
Avatar
omochimetaru 4/7/2017 1:39 AM
enumに関するindirectの場合は、「ついてない場合」を考えてない
1:39 AM
のではないかという推測
1:39 AM
常にBox型で取り回されてる
Avatar
indirect プロパティも「ついてない場合」なんてないのでは??
Avatar
omochimetaru 4/7/2017 1:40 AM
だから、単純に、indirectついてる場合をクラスと同じようにコンパイルするように切り替えるだけで良かった
1:41 AM
indirectプロパティは
1:41 AM
xxのような場合についてない。
1:41 AM
型に付いてるのではなく、プロパティについてるから (edited)
1:41 AM
型としては2種類ありえることになる
Avatar
indirect var foo: Foo?var foo: Box<Foo?> と読み替えるのでは?
1:42 AM
問題に鳴るのは
Avatar
indirectが書かれたpropertyを持ってる型はクラスと同じようにコンパイルする、とかだと上手くいくのかな
Avatar
値を変更するときだと思う。
1:42 AM
enum だと変更できない。
1:43 AM
いや、いいのか?取り出すときにコピーしてれば問題にならないか?
Avatar
omochimetaru 4/7/2017 1:43 AM
読み替えるついでに、Javaでいうところの AutoBoxingとAutoUnboxingの挿入が必要
Avatar
Box が取り回されるだけで。
Avatar
omochimetaru 4/7/2017 1:43 AM
enumにindirectを導入する際にはそのような修正は必要なかったけど
1:43 AM
プロパティにつける場合には必要になるから
Avatar
enum でもパターンマッチして取り出す時にアンボクシングしてるのでは?
Avatar
omochimetaru 4/7/2017 1:44 AM
実装の手間が違うから、とりあえずやらなかったんんじゃないか、という推測
1:44 AM
それは別に
1:44 AM
クラスからフィールド読むのと同じ
Avatar
indirectenum 全体が indirect されるわけじゃなくて、あくまで個別 caseindirect されるだけでしょ? (edited)
Avatar
omochimetaru 4/7/2017 1:45 AM
だからその個別のcaseが参照型だったと
1:45 AM
解釈できます
1:45 AM
でもそれは
1:45 AM
そのcaseは常にindirectだから
Avatar
caseに付けるときと、enumに付けるときとでバイナリに差が生まれるのか気になった
Avatar
だから、 struct でも個別のプロパティが Box だったと解釈すればいいんじゃないの?
Avatar
omochimetaru 4/7/2017 1:45 AM
そのcaseのindirectじゃないバージョンを考慮する必要がない
Avatar
プロパティの indirect じゃないバージョンも考慮する必要がないよ。
Avatar
omochimetaru 4/7/2017 1:46 AM
ありますよ
1:46 AM
だって Int? は実在してるから。 (edited)
1:46 AM
Fooの中で indirect Int? であっても、一般のInt?はそれとは別に存在する
1:46 AM
この2つは区別されて、適宜変換が必要
Avatar
だから、適宜変換が必要なのは enumcase も同じなんじゃないの?
Avatar
omochimetaru 4/7/2017 1:47 AM
いいえ
1:47 AM
caseは
1:47 AM
常にindirect
Avatar
enum に入れるときにはボクシングするし
Avatar
omochimetaru 4/7/2017 1:47 AM
それはassociated valueの話で
Avatar
だって、 enum そのものが indirect されてるわけじゃなくて
Avatar
omochimetaru 4/7/2017 1:47 AM
associated valueの話しはstructの中のフィールドの話し
Avatar
あくまで個別の caseindirect なだけだから。
Avatar
おもち君の言ってるのはassociatedvalueでkoher氏が言ってるのはenum型そのものやな
Avatar
enum Foo<T, U> { case bar(T) indirect case baz(U) }
1:48 AM
U だけ Box になる。
1:48 AM
enum Foo<T, U> { case bar(T) case baz(Box<U>) } ↑と等価。 (edited)
Avatar
enumはcaseから取り出すときにautounboxingを挟み込む余地があったから、楽だったのでは?
Avatar
うーん、それって struct のプロパティから値を取り出すときとそんな違いがありますか? indirect なプロパティなら unboxing すればいいだけな気が。
1:50 AM
ちょっと、昼までにやらなきゃいけない作業があるので離脱します・・・
Avatar
omochimetaru 4/7/2017 1:56 AM
enum-caseの場合は baz が indirectだからうんぬんってことを気にすればいいのが 明示的に記述される switch-caseでの分解の時だけってのが大きな違いだと思うって事
Avatar
enum Foo { indirect case bar(int: Int, str: String, foo: Foo) } この時に、barの中身が全部Boxingされてると仮定するなら、内側のFoo単体についてはBoxに纏わる何かを考えなくて良い。 従ってBoxが関わってるのは外側のFoo型でswitchなりif caseなりで一気になんとかできる。 structのpropertyとは別な印象があります。 (edited)
1:57 AM
SIL上でだけ存在する Box型があるみたい
Avatar
ン…
2:01 AM
でもswitch/if caseにBox処理入ってるのと,property { set get }にBox処理入ってるのそんなに違わない気がしてきたぞ
Avatar
omochimetaru 4/7/2017 2:02 AM
値型のプロパティアクセスって、
2:04 AM
house.cat.name = "tama" みたいなときのgetter/setterの差し込み , didSet等が無ければその省略
2:04 AM
とかあるから、ややこしそうな気がする
2:04 AM
常にcomputed property扱いにコンパイルしちゃえば同じ気がするね
Avatar
それで良い気がする
2:08 AM
メモリ周りの強化が入った時に
2:08 AM
プロパティの参照を取るってことができるようになりそうな気がしてて
Avatar
お…
Avatar
omochimetaru 4/7/2017 2:08 AM
その場合に、stored propertyとcomputed propertyで結構変わってきそう
2:09 AM
Rustの真似して、ある実体に対して、shared参照が複数、もしくは、inout参照が1つ、をフロー解析的に保証するとか書いてある (edited)
2:10 AM
func ==(left: shared String, right: shared String) -> Bool { ... } これとか面白い
2:11 AM
COWモデルのおかげで現状でもかなり早いと思うけど、これが入れば引数渡しのコストがC++に肉薄する
Avatar
pure funcを型レベルで保証するのってこの辺の話だっけ
Avatar
omochimetaru 4/7/2017 2:15 AM
それはまた別な気がする
2:16 AM
shared referenceで受けてる時は確かにそこから書き込めないから副作用が無いけど
2:16 AM
それで言うならSwiftの値型は常にコピー渡しだから普通に副作用無い
Avatar
まあそれはそうか
2:19 AM
sharedって、参照で渡すけど書き込み禁止って事だよね
Avatar
omochimetaru 4/7/2017 2:19 AM
です
2:20 AM
mutating funcが呼べない状態やね
2:20 AM
inoutは書き込める参照。現状仕様にあるやつ。
Avatar
今の何も書かない奴は、sharedと等価ではない?
2:20 AM
コピー走るからか
Avatar
omochimetaru 4/7/2017 2:21 AM
何も書かないやつはそもそも参照渡しじゃない
2:21 AM
値渡し(実体のコピーを伴う
2:21 AM
実体のコピーを伴うがCOWが仕込んであるからデータメモリまではコピーされないので話がややこしい。
Avatar
indirect property は現状これが一番現実的だと思う struct Foo { private var _inner: Any? = nil var inner: Foo? { get { return _inner.map { $0 as! Foo } } set { _inner = newValue } } } (edited)
Avatar
omochimetaru 4/7/2017 4:40 AM
お〜なるほど
4:40 AM
get { return _inner as! Foo? } はうまくいかないんですっけ?
Avatar
あ、いきますね
Avatar
そっか、privateならAny?でも問題ないか
Avatar
omochimetaru 4/7/2017 4:41 AM
AnyOptional<T> を入れる手と Optional<Any>AnyT にさせる手があるのかな
Avatar
as!アレルギー解除していかないと
Avatar
あーけどこれだとメモリ効率悪すぎるか。 Any に Any 込みの struct 入れたら絶対にヒープに入っちゃう。32バイト無駄すぎ。
5:17 AM
素直にBox作ったほうがいい気がしてきました。 これなら MemoryLayout<Foo>.size == 8indirect enum Box<T> { case val(T) init(_ val: T) { self = .val(val) } var val: T { switch self { case .val(let val): return val } } } struct Foo { private var _inner: Box<Foo>? var inner: Foo? { get { return _inner?.val } set { _inner = newValue.map(Box.init) } } }
👍 1
Avatar
@omochimetaru 前確かめた感じだとOptional<Any>のほうが筋が良かった。
5:22 AM
でもこの場合はBoxですね
5:23 AM
case 1個のindirect enum Boxすごい、脳汁出る
Avatar
omochimetaru 4/7/2017 5:28 AM
おおなるほど、まさに最適だ
Avatar
indirect のメモリ上の扱いの話ってどういうの見たらわかりますかね?
Avatar
omochimetaru 4/7/2017 6:47 AM
# 導入 Swiftには値型と参照型があります。また、Optionalはそれらと組み合わせてよく使われます。メモリ上ではどのように表現されているのでしょうか。調べてみました。(Swift 3.0.2) # メモリダンプ関数 メモ...
6:47 AM
↑これを真似すれば直接的なものは見れるよ
6:48 AM
あとはコンパイラを読むとかコンパイル後のLLVM-IRを読むとか。
Avatar
やっぱ基本的にはそーゆーアプローチになるのか
6:48 AM
ありがとうございます
Avatar
indirect enum Box<T> って class Box<T> じゃダメなんでしょうか? class 使わずあくまで値型で済ませるならってこと?
8:54 AM
あー、
8:54 AM
書き変えのときに
8:54 AM
いや、そんなことないか
8:54 AM
Box は隠蔽するからやっぱ class でも変わらないような?
Avatar
omochimetaru 4/7/2017 8:56 AM
BoxEは代入文でBoxEの実体も複製されて値的に振る舞うけど (edited)
8:56 AM
BoxCは代入文がBox自体の参照コピーになって
Avatar
ああ、そうか。コピーのときが問題なのか。
Avatar
omochimetaru 4/7/2017 8:56 AM
もともとのkoherがやりたいといった挙動と
8:56 AM
変わってる
Avatar
get, set のことばっか考えてた・・・
9:01 AM
Swift 1 で indirectclassBox で代替しても問題なかったのは、 enum がイミュータブルだからなのか。 (edited)
9:02 AM
もちろん Box そのものをいじっちゃったらダメだけど。
Avatar
omochimetaru 4/7/2017 9:02 AM
Swift1でもpattern matchしてBox自体をつかめば変な感じになりえますね (edited)
Avatar
多分 Swift 1 にパターンマッチはなかったです。
9:04 AM
あったんだっけ??どうやって enum の値取り出してたんだ??
Avatar
Swift1 でもパターンマッチはありましたよ。
9:44 AM
class Box でも大丈夫だと思います。Boxの中身がイミュータブルなら実用上は変わらないんじゃないかな。
Avatar
あれ?あったんですね・・・。
Avatar
2 で case let value? とかが追加になったくらい
Avatar
てっきり 2 で追加されたと勘違いしてました。
Avatar
omochimetaru 4/10/2017 2:07 AM
最近ふと気がついたんだけどSwiftのデストラクタがObjCの dealloc から deinit に名前が変わっている点について
2:07 AM
弱参照が残っている限りオブジェクトのペイロードメモリは解放されないから
2:08 AM
まさに dealloc じゃなくて deinit であるなあと気がついた
Avatar
それはdeallocの名前が不適切、ということ
Avatar
omochimetaru 4/10/2017 2:09 AM
UnsafePointer 周りの用語としても、 メモリ確保はAllocation/Deallocation、確保したメモリにオブジェクトをレイアウトする/剥がしてデストラクトするのが Init / deinit って用語がちゃんと揃ってる
Avatar
それとも呼ばれるタイミングがそもそも違う?
Avatar
omochimetaru 4/10/2017 2:09 AM
いやObjCも弱参照残っててもdealloc呼ばれるから
2:09 AM
そもそもdeallocじゃなかったわけなんだけど
2:09 AM
コレは仕方なくて
2:09 AM
iOS4以前は弱参照が無かったから
Avatar
確かに確かに
Avatar
omochimetaru 4/10/2017 2:09 AM
deallocされるときは絶対にメモリ解放されてたんよ
Avatar
言語仕様追加して名前と機能が噛み合わなくなった訳か
Avatar
omochimetaru 4/10/2017 2:10 AM
うんうん
Avatar
こんにちは
9:31 AM
Swiftのプロトコル、Compare+ableでComparableでしょ、Equate+ableでEquatableでしょ、Stride+ableがStrideableになるのってなんでなの
9:31 AM
これ気になってるんだけどだれか答え持ってませんか
Avatar
omochimetaru 4/10/2017 9:32 AM
なんちゃら XXXXeable ってよく間違えられてるから間違えてるのでは
Avatar
そうだよね
9:33 AM
MSにはStridableっていうなにがしかがある
Avatar
ぶ〜
9:33 AM
すごいな
Avatar
omochimetaru 4/10/2017 9:34 AM
ただ、たまに、
9:34 AM
アメリカ英語とイギリス英語で答えが違うとかあるから
9:34 AM
調べてみないとわからん
Avatar
そっちのほうがまだ信じられる
Avatar
Q&A for linguists, etymologists, and serious English language enthusiasts
😆 1
Avatar
convertibleとかあるし結構何でもありなのかも
9:38 AM
英語ネイティブじゃなきゃわからんきがする
Avatar
omochimetaru 4/10/2017 9:38 AM
swift-lang slackで意見聞けるかな
Avatar
正式な単語ではないからブレるのではという気も
Avatar
入ってないや > swift-lang slack
9:39 AM
送り仮名の揺れみたいなもんだな
9:39 AM
多分
Avatar
自動招待みたいなURLあったら教えて
11:27 AM
# 開催概要 potatotipsは 参加者全員がTipsを発表する というコンセプトのiOS/Androidアプリ開発者向けの勉強会です(ただし、最近はオーディエンス枠があります)。 今回はCyberAgent, Incさん主催での開催となります。 引き続き主催をいただける会社さんを募集中です。 (potatotipsの管理ページは コチラ です) # 内容 ## LT * 5分 × 発表者数で 2時間程度 * 途中で休憩を挟みます ## 懇親会 * LTフェーズ完了後に会場の時間の許す限り # 参加枠の種別 ## Tips発表枠 ### iOS/A...
❣ 3
Avatar
RxSwiftのCompleteableは直りましたね
Avatar
ものさんおるの?
Avatar
スパイから写真が来ました🥞
12:08 PM
僕は家です( ´・‿・`)
Avatar
スパイw
Avatar
Completeable治ったけど、[at]available書かずにやっちゃったからざわついてた
Avatar
omochimetaru 4/13/2017 3:07 PM
よくみたらものさんからスパイのヒント出てたっていうね
🥞 2
Avatar
SwiftのTupleは共変サポートされてないけど、クロージャの引数の型になっていればクロージャは半変サポートされているという話
12:39 AM
この間社内勉強会のえづらさんの会でたまたま気がついた
Avatar
omochimetaru 4/14/2017 1:07 AM
本当だw
1:07 AM
Swiftのタプル、いろいろあるべきものが足りてなくてたまに萎える
Avatar
コード補完が本当に雑魚い
1:11 AM
ラベル付きタプルをtypealiasに書こうものなら、いざコードを書くときに苦しみ抜いて死ぬことになる
😩 1
1:13 AM
仕方ないのはわかるから、再利用してinitが発生するような型パラにはTuple入れないでねってコーディング規約を最近提案した
Avatar
omochimetaru 4/14/2017 1:16 AM
なんか不便だから返り値とかにとどめて、 配列にいれて保持したりするならstruct定義してる たぶんその規約に従うとそうなりそう
Avatar
そう、返り値からメソッドチェインで次の引数になるような
1:16 AM
まさにmap/flatMapでは使うべき
1:17 AM
だけど、他の場所で宣言したものを入れる必要があるなら、struct作って、という感じ
Avatar
omochimetaru 4/14/2017 1:17 AM
本当にただパックしたい時だけって感じだよね
Avatar
tupleにinitが生えていてそれがコード補完されるなら、この規約はいらない
1:18 AM
Aliasからinit含むfunctionが補完されるか否かの差がめちゃくちゃ大きい。tupleだと無なので死ぬ
1:19 AM
まあそういうこともあって、上ので何か便利なworkaround産めないかと朝飯食いながら考えてるが、何も思い付かないw
Avatar
omochimetaru 4/14/2017 1:20 AM
ジェネリックマニフェストで、タプルにエクステンション書けるようにしたい、みたいな展望が書いてあって、 そこらへんの絡みで、ちゃんとした型に整備されたらいいなあ
Avatar
型パラにtuple入れるの、そう言えばそれ+αでコンパイラクラッシュするんだった
1:21 AM
struct Tuple2<A,B> ← 正直これ使いたくなるwww
Avatar
omochimetaru 4/14/2017 1:22 AM
C#とc++はマジでそれだけど使うと悲しくなるよ
Avatar
Javaもこんな感じじゃなかったっけ
1:23 AM
stdではないかな
Avatar
omochimetaru 4/14/2017 1:23 AM
気持ちはわかるけどそうなったらちゃんと名前つけた型つくる
Avatar
そう、Tuple2はラベルが付けられないのがダメ
1:24 AM
型推論はめちゃ強くなる
Avatar
omochimetaru 4/14/2017 1:24 AM
あーそれもあるか→ラベル
Avatar
型名は最悪typealiasでも良い
Avatar
omochimetaru 4/14/2017 1:24 AM
なるほど。たしかに。
Avatar
Genericsな実装があるメリットは大きい、でもラベル無いのが
1:25 AM
うーん
1:25 AM
まあ素直にstruct作るのが正解だな
Avatar
変性の話、↓もイケた。戻り値ならタプルも共変になる。 class Animal {} class Cat: Animal {} let cf: () -> (Cat, Cat) = { (Cat(), Cat()) } let af: () -> (Animal, Animal) = cf // エラーにならない let aa: (Animal, Animal) = af()
Avatar
omochimetaru 4/14/2017 2:23 AM
あ、じゃあそれを取り回せば・・・w
Avatar
おw
Avatar
普通のタプルが共変でないのなんでなんだろう・・・
Avatar
これは悪さが出来る
Avatar
omochimetaru 4/14/2017 2:24 AM
黒いなあ
Avatar
あ、Swift 3.0の方のマシンで試してしまった。3.1未確認。
Avatar
GenericsでU,T宣言してwhere U:Tが書けないから、出来ることが限られてるけど
2:25 AM
取りあえず大枠としての目標は、型消しで共変を無理矢理サポートさせるみたいな事がしたい。
2:26 AM
AnyHogeでラップしたら共編の範囲内で推論される
Avatar
タプルは値型だから var だったとしても共変で問題ないはずで、そもそもできないのが謎だけど何か理由があるのかな。
Avatar
あ、Swift 3.0の方のマシンで試してしまった。3.1未確認。
3.1でもイケるみたいです
Avatar
@moaible 確認ありがとうございます!
Avatar
omochimetaru 4/14/2017 2:27 AM
ドキュメントでそれに触れてるものを見たことはないです > 理由
Avatar
これは勝った
Avatar
↓値型と共変 class Animal {} class Cat: Animal {} class Dog: Animal {} var cats: [Cat] = [Cat()] var animals: [Animal] = cats // ここがコピーなので animals.append(Dog()) // これができても問題ない
2:28 AM
↑このコード、参照型言語の人が見たら発狂しそうw
Avatar
omochimetaru 4/14/2017 2:28 AM
そこのコピーってどうなってんだろう 共有してんのかな
Avatar
最終行でCoWで(実際の)コピーってのが理想だけど、どこでコピーが起こってるか確認したことはないなぁ。 (edited)
Avatar
omochimetaru 4/14/2017 2:30 AM
Swiftのclassはcovariance対応してないから
2:30 AM
Arrayのstruct部分の実Swiftコードで
2:30 AM
適切にその期待する挙動を書けない
Avatar
Array を Swift で実装するならってこと?
Avatar
omochimetaru 4/14/2017 2:31 AM
実際そうですよね?
Avatar
Array ってピュア Swift なんだっけ?違った気が。
Avatar
var cats: [Cat] = [Cat()] var animals: [Animal] = cats // ここがコピーなので_arrayForceCast() ってので実装されているので、cats.map { $0 } とほぼ同義です。 https://github.com/apple/swift/blob/master/stdlib/public/core/ArrayCast.swift#L30-L50
swift - The Swift Programming Language
Avatar
あ、そうですね
2:36 AM
Arrayの代入は暗黙的な変換です
2:36 AM
Arrayは引数と返り値の両方でTを使っているので
Avatar
おー、じゃあ先行してコピーされちゃうのかぁ。
Avatar
共変はない
Avatar
omochimetaru 4/14/2017 2:37 AM
おお
2:37 AM
@tarunon いや、COWにおいては最初のwriteをするまではreadonlyだから本来共変で共有できる
2:37 AM
writeする瞬間に共変性が破綻するのでコピーするっていうのが理想
Avatar
ふむ
2:37 AM
じゃあmapがlazyならokかな
Avatar
omochimetaru 4/14/2017 2:38 AM
Arrayがpure swiftだと思ってたのは勘違いだった
2:38 AM
というかソースを検索しても見当たらん
Avatar
実際試してみたけど、やっぱ代入時にコピーだ・・・。 import XCTest class SwiftCovariantCopyTests: XCTestCase { func testCopyWithoutAppend1M() { measure { let cats: [Cat] = [Cat](repeating: Cat(), count: 1_000_000) let animals: [Animal] = cats XCTAssertTrue(animals.last! is Cat) } } func testCopyWithAppend1M() { measure { let cats: [Cat] = [Cat](repeating: Cat(), count: 1_000_000) var animals: [Animal] = cats animals.append(Dog()) XCTAssertTrue(animals.last! is Dog) } } func testCopyWithoutAppend10M() { measure { let cats: [Cat] = [Cat](repeating: Cat(), count: 10_000_000) let animals: [Animal] = cats XCTAssertTrue(animals.last! is Cat) } } func testCopyWithAppend10M() { measure { let cats: [Cat] = [Cat](repeating: Cat(), count: 10_000_000) var animals: [Animal] = cats animals.append(Dog()) XCTAssertTrue(animals.last! is Dog) } } } class Animal {} class Cat: Animal {} class Dog: Animal {} Test Case '-[SwiftCovariantCopyTests.SwiftCovariantCopyTests testCopyWithoutAppend1M]' passed (0.592 seconds). Test Case '-[SwiftCovariantCopyTests.SwiftCovariantCopyTests testCopyWithAppend1M]' passed (0.790 seconds). Test Case '-[SwiftCovariantCopyTests.SwiftCovariantCopyTests testCopyWithoutAppend10M]' passed (4.162 seconds). Test Case '-[SwiftCovariantCopyTests.SwiftCovariantCopyTests testCopyWithAppend10M]' passed (6.556 seconds). (edited)
Avatar
_arrayForceCast() ってので実装されているので、cats.map { $0 } とほぼ同義です。
なので当たり前だけど。
Avatar
omochimetaru 4/14/2017 2:43 AM
appendの有無で変わらないと
Avatar
はい。計算量のオーダーが変わってなくて、純粋に append 分だけ遅くなってる。
2:43 AM
コピーが起こってなければ代入は O(1) 、コピーが起こってれば O(N) だから、 10 倍にしたときの増え方に変化が見られるはず。
2:44 AM
コピーというか、 map だから再生成って感じ?
Avatar
omochimetaru 4/14/2017 2:44 AM
ArrayはLazyCollectionじゃないからmapで普通に全コピー、であってる?
Avatar
最初のArrayのコンストラクトを measure 外に移したらどうなります?
Avatar
確かに。試してみます。
Avatar
omochimetaru 4/14/2017 2:45 AM
public var lazy: LazyRandomAccessCollection<Array<Element>> { get } これを使うとlazyになるのかあ。 (edited)
Avatar
ObjCランタイム(=Darwin)かつTがクラスなら #if _runtime(_ObjC) のほうに流れると思うのです。 (edited)
Avatar
lazyにしても、readした瞬間に遅延実行されない?writeじゃなくて。 (edited)
Avatar
実際にアクセスするまでmapのクロージャが走らないはず?
Avatar
swift - The Swift Programming Language
Avatar
omochimetaru 4/14/2017 2:48 AM
なんかそっちはバッファ共有っぽくみえる
2:48 AM
41行目の方は中身の保証があるからチェックなしの理想の共有で、 45行目の方は、アクセスに型チェックが挟まるのかな。Javaみたいな。
2:50 AM
Arrayのソースこれか?
2:51 AM
GYPになってるけど
public struct ${Self}<Element>
%{
arrayTypes = [ ('ContiguousArray', 'a ContiguousArray instance'), ('ArraySlice', 'an ArraySlice instance'), ('Array', 'an array'), ] }%
Avatar
Test Case '-[SwiftCovariantCopyTests.SwiftCovariantCopyTests testCopyWithoutAppend10M]' passed (0.624 seconds). Test Case '-[SwiftCovariantCopyTests.SwiftCovariantCopyTests testCopyWithAppend10M]' passed (2.282 seconds). Test Case '-[SwiftCovariantCopyTests.SwiftCovariantCopyTests testCopyWithoutAppend100M]' passed (4.037 seconds). Test Case '-[SwiftCovariantCopyTests.SwiftCovariantCopyTests testCopyWithAppend100M]' passed (23.242 seconds).
Avatar
omochimetaru 4/14/2017 2:51 AM
なんかここらへんが組み合わさってArrayのswiftコードが出てきそう
Avatar
初期化を measure の外に出した。
2:53 AM
いや、まちがえた
2:53 AM
これ measure の値じゃなかった
2:53 AM
普通に swift test が出してる値だった
Avatar
omochimetaru 4/14/2017 2:53 AM
Avatar
measure外で reserveCapacity() で +1 確保しておくと完全かと。
Avatar
Test Case '-[SwiftCovariantCopyTests.SwiftCovariantCopyTests testCopyWithoutAppend10M]' measured [Time, seconds] average: 0.000, relative standard deviation: 114.231%, values: [0.000023, 0.000005, 0.000003, 0.000003, 0.000003, 0.000003, 0.000003, 0.000003, 0.000003, 0.000003], Test Case '-[SwiftCovariantCopyTests.SwiftCovariantCopyTests testCopyWithAppend10M]' measured [Time, seconds] average: 0.163, relative standard deviation: 4.494%, values: [0.183134, 0.158554, 0.160044, 0.163250, 0.155895, 0.158189, 0.163386, 0.161289, 0.159981, 0.167179], Test Case '-[SwiftCovariantCopyTests.SwiftCovariantCopyTests testCopyWithoutAppend100M]' measured [Time, seconds] average: 0.000, relative standard deviation: 115.617%, values: [0.000020, 0.000003, 0.000003, 0.000003, 0.000003, 0.000003, 0.000003, 0.000003, 0.000003, 0.000003], Test Case '-[SwiftCovariantCopyTests.SwiftCovariantCopyTests testCopyWithAppend100M]' measured [Time, seconds] average: 1.762, relative standard deviation: 2.715%, values: [1.793434, 1.729103, 1.745168, 1.726823, 1.730955, 1.749660, 1.729168, 1.716899, 1.845567, 1.851858], (edited)
Avatar
最適化効いてるみたいですね。
Avatar
っぽいですね。 reserveCapacity はまだしてないです。 (edited)
2:57 AM
ということは、共変っぽい代入しても CoW が効いてると。
Avatar
@omochimetaru Arrayのソースはそれですが、 compiler intrinsic な処理もけっこう入るので Pure Swift とは言えない。
Avatar
omochimetaru 4/14/2017 2:57 AM
@rintaro ふむふむ
2:58 AM
_arrayForceCast って as! の時が基本の用途っぽいんですけど今回みたいな型安全な代入でも挿入されるのか今気になってて探ってるけどまだ手がかり無し
Avatar
む、 measure 外で reserveCapacity できない・・・。 animalmeasure の中で代入して生成されてるから・・・。
Avatar
-emit-sil %17 = function_ref @_TFs15_arrayForceCastu0_rFGSax_GSaq__ : $@convention(thin) <τ_0_0, τ_0_1> (@owned Array<τ_0_0>) -> @owned Array<τ_0_1>, loc "test.swift":7:27, scope 21 // user: %18 %18 = apply %17<Cat, Animal>(%14) : $@convention(thin) <τ_0_0, τ_0_1> (@owned Array<τ_0_0>) -> @owned Array<τ_0_1>, loc "test.swift":7:27, scope 21 // user: %19
Avatar
omochimetaru 4/14/2017 2:59 AM
おお!ありがとうございます
Avatar
cats で reserveCapacity しておけば、buffer 共有されているなら capacity 維持されるはずだから
3:01 AM
問題無いと思います。
Avatar
reserveCapacity したいのって、代入時にコピーが走ってるけど append でバッファのallocateが走ってしまってるから WithWithout で差が付いている可能性を排除したいってことですよね?
3:03 AM
代入時にバッファが共有されてる=CoWが効いてるのであれば、 append 時にはどのみち allocate されるから関係なくないですか?
Avatar
あー、ごもっともw
Avatar
あー
3:05 AM
Tupleで悪いことしようとしてたらまたコンパイラクラッシュした
Avatar
omochimetaru 4/14/2017 3:05 AM
すーぐ壊す
Avatar
今度はマジで天才だと思ったんだ
3:06 AM
undefined<T>以来のヒットだよ
3:06 AM
壊れたけど
Avatar
仮にコピーが走っているとすると 10M と 100M で差が出るはずですが、両方 0.000003 [s] だし、CoW効いてそう。観測下限って可能性もあるけど、さすがに100Mのコピーがこんなに速いことはない気がする。
Avatar
omochimetaru 4/14/2017 3:08 AM
C++と違ってユーザー定義コピーオペレータが書けないからそこがもどかしいんだよな
3:08 AM
C++なら Catの operator= とコピーコンストラクタと・・・ まあいろいろに printf しこめばはっきりする (edited)
Avatar
やりました
Avatar
omochimetaru 4/14/2017 3:09 AM
(ユーザー定義うんたらがあると Plainじゃなくなって動作が変わるかのうせいがあるけど
Avatar
型消しに共変性に近い機能を+する
Avatar
omochimetaru 4/14/2017 3:10 AM
後でみる
Avatar
@koher 上の最適化効いてるのは、catArrayの生成をmeasureの外に移した場合、ですか? (edited)
Avatar
omochimetaru 4/14/2017 3:27 AM
@tarunon 最適化はそもそも効いてたけど最初のArrayの生成が単純に重くて測定上のノイズになっていたという事
Avatar
あ、今気付いた。そうです。コードは↓。 import XCTest class SwiftCovariantCopyTests: XCTestCase { func testCopyWithoutAppend10M() { let cats: [Cat] = [Cat](repeating: Cat(), count: 10_000_000) measure { let animals: [Animal] = cats XCTAssertTrue(animals.last! is Cat) } } func testCopyWithAppend10M() { let cats: [Cat] = [Cat](repeating: Cat(), count: 10_000_000) measure { var animals: [Animal] = cats animals.append(Dog()) XCTAssertTrue(animals.last! is Dog) } } func testCopyWithoutAppend100M() { let cats: [Cat] = [Cat](repeating: Cat(), count: 100_000_000) measure { let animals: [Animal] = cats XCTAssertTrue(animals.last! is Cat) } } func testCopyWithAppend100M() { let cats: [Cat] = [Cat](repeating: Cat(), count: 100_000_000) measure { var animals: [Animal] = cats animals.append(Dog()) XCTAssertTrue(animals.last! is Dog) } } } class Animal {} class Cat: Animal {} class Dog: Animal {}
Avatar
ありがとうございます!
Avatar
上の最適化効いてるのは
これが、 Without の方が速かったのが、という意味ならその通りですし、 CoW が効いてるのがという意味なら @omochimetaru の言う通りどちらでも効いてて、生成が measure のノイズになっていたということです。
Avatar
CoW意図してました
3:31 AM
なるほど…
Avatar
omochimetaru 4/14/2017 3:32 AM
結論としては Linux版だと遅い
Avatar
Linux版だと遅い
これはどこから出てきたの?
Avatar
omochimetaru 4/14/2017 3:32 AM
ObjcRuntimeを積んでないから (edited)
3:32 AM
#if に入らない
Avatar
ObjCランタイム(=Darwin)かつTがクラスなら #if _runtime(_ObjC) のほうに流れると思うのです。
これか。
Avatar
omochimetaru 4/14/2017 3:33 AM
あい
Avatar
なるほど。そうじゃないと単純な map になっちゃうのか。
Avatar
omochimetaru 4/14/2017 3:34 AM
はい
Avatar
クラスじゃないとObjCに行かないなら、Cat/Animalをstruct/protocolで作ってる場合も同様に遅いのかな
Avatar
omochimetaru 4/14/2017 3:40 AM
そういうことだと思う
Avatar
omochimetaru 4/14/2017 3:52 AM
たるのんのさっきの gist やっと理解した
3:54 AM
いわゆるAnySequence<T> みたいなType Erasureを作るときに、AnySequence(cats) ってやると AnySequence<Cat> ができるけど、これの左辺をAnySequence<Animal> で受けたいってことね で、このパターンだと DogとDogAを足したときに、何も書き足さずに同じ仕組みでそれができると
Avatar
そうそう
Avatar
omochimetaru 4/14/2017 3:56 AM
・やりたいこと ・よく知られた手法で何ができないか を冒頭に書いてほしいでござるよ
Avatar
今までだと、多変数のprotocolだと多変数をバラバラに渡せばなんとかinit出来るみたいな
3:56 AM
すまんw
3:56 AM
状況であんまり嬉しくなかったのが、パラメータ1個渡せばいけるようになるから
3:56 AM
かなり便利
Avatar
omochimetaru 4/14/2017 3:56 AM
ちょっとかいてあったけどヒントが足りない
3:56 AM
ふむう
Avatar
UIKitのラップ周りで
4:01 AM
共変性持たせたいなーっていうシチュエーションが無限にあったので
4:01 AM
これはマジで嬉しい
Avatar
omochimetaru 4/14/2017 4:01 AM
あ〜
4:02 AM
AnimalとCatの代わりに UIView と UIImageViewとかがあって
4:02 AM
AnyXってのはViewModel<V: UIView> みたいな
4:02 AM
やつになる?
Avatar
ViewModelではないけど
4:02 AM
まっちくり
4:02 AM
一つはTransitioningAnimationの拡張周り
4:03 AM
この間SwiftTweetsで発表したやつの、3つ目の型変換が苦しかったのが
4:03 AM
ほぼほぼ解決する
Avatar
omochimetaru 4/14/2017 4:03 AM
ふむ
Avatar
これはSwift Tweetsの発表をまとめたものです。イベントのスポンサーとして Qiita に許可をいただいた上で、このような形(ツイートの引用)で投稿していま...
Avatar
ViewModelもGenericsで書いてたら嬉しいシチュエーションありそうだ
Avatar
omochimetaru 4/14/2017 4:19 AM
// こういうジェネリックなstructがあるときに struct S<T> { var s: T } var scat: S<Cat> = S<Cat>(s: Cat()) // ↓こんな事や var sani1: S<Animal> = sa // ↓次善でこんな事が var sani2: S<Animal> = sa.upcast() // できたらいいのにな (edited)
Avatar
そうそう
4:21 AM
C++だと
Avatar
omochimetaru 4/14/2017 4:21 AM
↑シンプルにこういう課題があると思うんだけど、簡単な解法がない・・・?
Avatar
Genericsパラメータに共変か反変かみたいなの
4:21 AM
書けるんだよね
Avatar
omochimetaru 4/14/2017 4:21 AM
std::enable_if<std::is_convertible<T, U>::value> なんかこんな雰囲気でできる。
Avatar
で、これ
4:22 AM
パラメータが1個なら
Avatar
omochimetaru 4/14/2017 4:22 AM
共変か反変かっていうのを概念として直接はかけないけど、代入可能かを静的に判定できるので、まあできる
Avatar
var sani1: S<Animal> = S(s: scat.s)
4:22 AM
まあこう書けばいいんで、そんなに苦じゃない
4:22 AM
でもパラメータが複数になると全部取り出すの辛いんだ
Avatar
omochimetaru 4/14/2017 4:22 AM
いや、1個でも苦しいよ・・・
Avatar
書いててだるい
4:23 AM
でー
Avatar
omochimetaru 4/14/2017 4:23 AM
まあフィールド数に比例してしまうのは終わってるね
Avatar
これをFunctionの共変/反変で判定するところまで持ち込んで、多変数でも1パラメータでいけるようにして、ってやったのが
4:24 AM
さっきの
Avatar
omochimetaru 4/14/2017 4:25 AM
C++で std::shared_ptr<Tp> から std::shared_ptr<Yp> へのアップキャストコンストラクタがこれ https://github.com/llvm-mirror/libcxx/blob/master/include/memory#L3531-L3535
Mirror of official libcxx git repository located at http://llvm.org/git/libcxx. Updated every five minutes.
Avatar
func some<T, U> (_ something: A<T>) -> A<U> where T: U
4:26 AM
こういうの書けないから今はFunctionに落とし込むしか無い
Avatar
omochimetaru 4/14/2017 4:26 AM
extension S { init<U>(_ o: S<U>) where T: U { self.init(s: o.s) } } // ↑これでいけるかとおもったけど駄目だった。 (edited)
Avatar
Tがprotocolじゃねーぞって怒られる
Avatar
omochimetaru 4/14/2017 4:27 AM
ですね。
4:27 AM
あくまでプロトコルコンフォーマンスだけがコンディションとしてかけて
4:27 AM
代入互換性が書けない事が問題と理解した
Avatar
functionの引数と返り値に関してはかなり強力な型チェックができるっぽいので
4:29 AM
それを頼るのが良さそう
Avatar
iOSアプリだとどうしてもクラスが出て来るけど、値型で書いてたらそもそも継承が出てこないから変性考える必要もない気も。
4:31 AM
プロトコル型で取り回すのもあんまりやらないし。
Avatar
まあ理想の世界はそうなんですがw
Avatar
omochimetaru 4/14/2017 4:32 AM
「iOSアプリだと」って、それが前提だからまあ・・・
Avatar
いや、なので、Swiftが変性まわりをないがしろにしてるのって、そういうこともあるのかなぁと。
Avatar
omochimetaru 4/14/2017 4:33 AM
ああ。Swiftyな世界ではstruct指向だからジェネリック型境界というテーマ自体の比重が軽いと
Avatar
はい
Avatar
omochimetaru 4/14/2017 4:33 AM
そういう意図は感じます
Avatar
とは言えclassが全く必要でないかというとそうでもなく
4:37 AM
現実の問題ではしばしばお世話になるはずなのでなんとかして欲しい
Avatar
ふと思いついたんですが、Swiftのタプルの辛みって「 (T, (S))(T, S) と同一視する」というルールを設ければ色々解決したりしませんかね
Avatar
今すでにそうなってるような。 type(of: (1, (2))) // (Int, Int).Type type(of: (1, 2)) // (Int, Int).Type
Avatar
(T)T と同一視する」はそうなってるんですが、それとは違って… と思ったけど言い方がよくなかったですね
12:45 AM
つまりタプルを単方向リスト的に処理できればいいんじゃない?という話をしたかったのでした (1,2) == (1, (2)) // 2 == (2) なので true (1,2,3) == (1,(2,3)) // Binary operator '==' cannot be applied to operands of type '(Int, Int, Int)' and '(Int, (Int, Int))' 下が通れば無限個のタプルを処理できるなーということです (edited)
Avatar
タプルは型として扱われてないから Equatable 準拠とか出来ないので == もタプルの要素数毎に定義されてますよね。(6要素まで) public func == <A : Equatable, B : Equatable, C : Equatable, D : Equatable, E : Equatable, F : Equatable>(lhs: (A,B,C,D,E,F), rhs: (A,B,C,D,E,F)) -> Bool { たぶんタプルを型として扱える様にしないとタプルのネストとか解決できない。
Avatar
はい、その6要素分の定義があまりにuglyなので… もし (A,B,C)(A,(B,C)) のシュガーシンタクスだと解釈できるようになれば、 public func == <A : Equatable, B : Equatable>(lhs: (A,B), rhs: (A,B)) -> Bool で全て賄えるはずだなと思ったんです、が… たしかにご指摘の通り、現状の言語仕様だとそもそもタプルをEquatable準拠させることが不可能なので、 B: Equatable が成立しないとこで詰みますね
1:17 AM
まあuglyなだけで、大抵は6要素分までのoperatorがあれば事足りるし、困ったら自分で拡張すればいいから、実運用上は何も問題ないってので今の実装なんだとは思いますけど
Avatar
Tupleが型Tuple2<A,B>になって、Conditional conformancesがある上でTupleNが全てTuple2の組み合わせのエイリアスなら成り立ちそうですが、これってバイナリツリーの平衡化とかも考えるんですか?効率は悪くなる気がしますね。
Avatar
omochimetaru 4/16/2017 6:18 AM
個人的には(A)と((A))はそのまま全く違う型なので、同一視はしないほうが嬉しいです 例えばjsonへの変換を考えると全く結果が違うし
6:19 AM
現状が型として不完全である問題の解決という意味なら、素直にタプルがらちゃんと型になってくれるほうが良いと思います
Avatar
omochimetaru 4/16/2017 6:30 AM
ああ一個だと同じなのか。ややこしいな。
Avatar
SE-0169がacceptされて読んでるけど英語大変
12:37 AM
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
Avatar
privateがextensionから見えるようになるよ、終わり!
12:51 AM
って感じに見える
Avatar
norio_nomura 4/18/2017 1:15 AM
fileprivate を使う機会を減らせそう
Avatar
@omochimetaru 多分言いたいのは ((A, B), C)(A, (B, C)) は違う型ということやんね?それは同意です。
2:05 AM
個人的にはタプルが nominal でないのは、タプルの乱用を防ぐためには理に適っているように思います。タプルを使うべきでないケースで struct を利用する圧力になっていると思う。
Avatar
omochimetaru 4/18/2017 2:05 AM
@koher そうです
2:06 AM
んん?
2:06 AM
仮にextensionが定義できるなど、型としてちゃんと扱えるようになったとしても
2:07 AM
ノミナルじゃないのはノミナルじゃないままで
2:07 AM
Swiftにおいてノミナルじゃない、というか、ストラクチュラルな型に対して、
2:07 AM
いろいろできない、
2:07 AM
という理解だったけど間違ってるかな
2:08 AM
それとも、 kotlinのPair<T, U>とかC#/C++のTuple2<T, U>, std::tuple<T, U> みたいな、ノミナルなタプル達を対比した発言?
Avatar
nominalじゃない=extensionが書けないの意図でした。
Avatar
omochimetaru 4/18/2017 2:09 AM
なるほど
2:10 AM
その下では、Swiftのtupleがいろいろ不便で、structへの圧力になってるという現状は僕もそう思っているけど、それがSwiftの設計思想上の意図なのか、単にズボラでこうなってるのかわからない
Avatar
norio_nomura 4/18/2017 2:14 AM
タプルって、メソッド呼び出し・戻りのペイロードを融通できるようにしたもので、効率が優先されるものだと想像。
2:15 AM
タプルを型として扱えるようにすると、その効率が維持できないと想像。
Avatar
omochimetaru 4/18/2017 2:15 AM
効率というのは実行速度の事ですか?
2:15 AM
それともコンパイル時間?
Avatar
norio_nomura 4/18/2017 2:15 AM
どっちもですかね。
2:16 AM
型にするとメタデータの生成が必要になり、それをメソッド呼び出し・戻りへ含めなければいけなくなる。 (edited)
Avatar
omochimetaru 4/18/2017 2:17 AM
他の struct 型と同様にそのような無駄なバイトは生まれないと思います (edited)
Avatar
norio_nomura 4/18/2017 2:19 AM
コンパイル時に型を決定できるならそうかもしれないけど
Avatar
omochimetaru 4/18/2017 2:22 AM
structと同様にfinal強制であれば大丈夫ですね
Avatar
値型なのにfinalでないこととかあるの??
Avatar
norio_nomura 4/18/2017 2:22 AM
プロトコルとか。
Avatar
protocolは値型ではないですね
2:23 AM
そもそもあれはただの型なので
Avatar
タプルの話ではなく??
Avatar
omochimetaru 4/18/2017 2:23 AM
@koher 値型なのにfinalでない事はありえないと思いますがそんな発言有った?
Avatar
@omochimetaru ↓これ。タプルの話だと思ってたから、当然そうだと思ってた。
structと同様にfinal強制であれば大丈夫
Avatar
omochimetaru 4/18/2017 2:25 AM
final強制と言っているのだから
Avatar
norio_nomura 4/18/2017 2:25 AM
タプルの中身がプロトコルの時とか、どういう扱いになるのだろう。
Avatar
omochimetaru 4/18/2017 2:25 AM
finalだというのが僕の意見ですよ。
Avatar
ああ、「であれば」が「だから」の意なのか。
2:26 AM
@norio_nomura それは struct がプロトコル型の stored property を持ってるのと同じじゃないですか?
Avatar
norio_nomura 4/18/2017 2:35 AM
あいや、今でもタプルのメタデータはちゃんと作られてるのか。
Avatar
omochimetaru 4/18/2017 2:35 AM
タプルの中身がプロトコルの時とか、どういう扱いになるのだろう。
プロトコルにassociatedtypeが無い場合しか無理なはずで、仮にprotocol P1 だったとすると、 var x: (P1, P1) の取扱は、 var y: P1 と、ただの単一変数が、 struct S { var y: P1 ; var z: P1 } とフィールドに並んだ場合と同じだと思います。
2:36 AM
メタデータってのは型の型の事ですかね、Anyに突っ込むことができるので存在はすると思います。
Avatar
norio_nomura 4/18/2017 2:38 AM
swift - The Swift Programming Language
Avatar
omochimetaru 4/18/2017 2:39 AM
おお。
2:39 AM
バイナリ表現まで規定されてるんですね
Avatar
norio_nomura 4/18/2017 2:39 AM
僕の認識は大きく間違っていました。
Avatar
omochimetaru 4/18/2017 2:40 AM
Tuple metadata has a kind of 9.
2:41 AM
Class metadata, instead of a kind, has an isa pointer in its kind slot, pointing to the class's metaclass record. This isa pointer is guaranteed to have an integer value larger than 4096 and so can be discriminated from non-class kind values.
2:41 AM
うわ、ここでも整数とポインタの同居が・・・
Avatar
norio_nomura 4/18/2017 2:44 AM
enum のペイロードもタプルだと思っていたのだけど、記述がない?
Avatar
omochimetaru 4/18/2017 2:45 AM
The nominal type descriptor is referenced at offset 1.
2:45 AM
ここからnominal type descriptorのところに
2:45 AM
For an enum:
2:45 AM
とかの節がありますが
Avatar
norio_nomura 4/18/2017 2:48 AM
For enums that are members of an enclosing nominal type, this is a reference to the enclosing type's metadata.
とあるので、複数型含む場合には enclosing type がタプルってことでいいのかな。
(edited)
Avatar
omochimetaru 4/18/2017 2:49 AM
ここは
2:50 AM
parentとか書いてあるし、enclosingっていうのは
2:50 AM
struct Cat { enum State {} } みたいな
2:50 AM
型の中の型の場合に
Avatar
norio_nomura 4/18/2017 2:50 AM
なるほど。
Avatar
omochimetaru 4/18/2017 2:50 AM
自身が定義される型の外側の型のメタデータを持つって記述では
2:50 AM
enum自体の中身がかいてああるのは、その一個上のoffset1のところで
2:51 AM
nominal type descriptorへの参照になってて、nominal type descritporの説明を読んでいくと、enumの場合について書いてありました
2:53 AM
あいや違う。
Avatar
omochimetaru 4/18/2017 2:53 AM
For an enum:
The number of payload cases and payload size offset are stored at offset 2. The least significant 24 bits are the number of payload cases, and the most significant 8 bits are the offset of the payload size in the type metadata, if present.
2:54 AM
↑こんなテキストのところ。
Avatar
norio_nomura 4/18/2017 2:55 AM
ありがとうございます
Avatar
omochimetaru 4/18/2017 2:57 AM
ABI周りって型のメタデータ一通りちゃんと規定する必要があるんだなあ・・・
2:57 AM
そりゃそうだよなあ大変そう
Avatar
norio_nomura 4/18/2017 2:57 AM
先に「ノミナル」って出てきてたのは Nominal Type Descriptor https://github.com/apple/swift/blob/master/docs/ABI.rst#nominal-type-descriptor を持つ型たち、ってこと?
swift - The Swift Programming Language
Avatar
omochimetaru 4/18/2017 2:58 AM
えーっと
2:58 AM
発端は @takasek さんの以下の発表で https://speakerdeck.com/takasek/what-is-a-nominal-type
❤ 1
2:58 AM
nominal type自体は
2:59 AM
型システム理論での概念で https://en.wikipedia.org/wiki/Nominal_type_system
In computer science, a nominal or nominative type system (or name-based type system) is a major class of type system, in which compatibility and equivalence of data types is determined by explicit declarations and/or the name of the types. Nominal systems are used to determine if types are equivalent, as well as if a type is a subtype of another. It contrasts with structural systems, where comparisons are based on the structure of the types in question and do not require explicit declarations.
❤ 1
2:59 AM
そこらへんを指して話していて
2:59 AM
僕はSwiftのNominal Type Descriptorとの対応でちゃんとは考えていませんでした。
2:59 AM
というか、そんなものがあるのは今しったw
3:01 AM
The kind of type is stored at offset 0, which is as follows: 0 for a class, 1 for a struct, or 2 for an enum. 結果的に認識とは一致していそう。タプルやファンクションはnon-nominalですね
Avatar
norio_nomura 4/18/2017 3:06 AM
「Swiftのタプルの辛み」をなんとかするには nominal type descriptor や protocol descriptor を持つ型にしないといけない雰囲気ですね。
Avatar
omochimetaru 4/18/2017 3:09 AM
non-nominalなままextensionとかが書けるようになったらいいと思うんですけどね
3:11 AM
GenericManifestoではそのトピックも上がっている
Avatar
norio_nomura 4/18/2017 3:12 AM
おお、まさにこれじゃん。
3:15 AM
Function typeにもextensionが欲しいと以前思ったことがあったんだけど "Extensions of structural types" っていう括りだと、それも含まれるのかな。
Avatar
omochimetaru 4/18/2017 3:16 AM
そう思います。
Avatar
Function typeはサブタイピングがあるからさらにややこしそう・・・
Avatar
omochimetaru 4/18/2017 3:18 AM
タプルもサブタイピングはほしくないですか?
3:18 AM
covarianceだから
Avatar
() -> Animal に対する extension() -> Cat にも使えるのか。
Avatar
omochimetaru 4/18/2017 3:18 AM
(Animal, Int)に対するextensionは(Cat, Int) でも使いたいですよね
Avatar
タプルは今のところ covariant になってないから、素直に考えればそれはないのでは?
Avatar
omochimetaru 4/18/2017 3:18 AM
あ〜
3:19 AM
Functionは今もう既になってるからか。
Avatar
うん
Avatar
Functionの引数と返り値のみ、何故かタプルもCovariantになりますけどね
3:19 AM
完全に謎
Avatar
omochimetaru 4/18/2017 3:19 AM
作りかけなだけだと思うんだよなあそこらへん
Avatar
引数と戻り値は、タプルだけどタプルじゃなくて、複数引数と複数戻り値なんでしょうね。
Avatar
omochimetaru 4/18/2017 3:20 AM
でも、そこがちゃんと区別されるようになりますよね
3:21 AM
今までは ( (A,B,C) ) -> R が (A, B, C) -> Rと同一視されてたけど
3:21 AM
(3要素タプルを引数に受ける関数 = 3引数関数)
3:21 AM
そこちゃんとわけようぜって方向に進んでる
Avatar
norio_nomura 4/18/2017 3:21 AM
メタデータではタプルになってますね
Avatar
omochimetaru 4/18/2017 3:22 AM
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
3:23 AM
Swift's type system should properly distinguish between functions that take one tuple argument, and functions that take multiple arguments.
Avatar
あれ?↓もできるんだっけ?? class Animal {} class Cat: Animal {} let a: () -> (Int, (String, Cat)) = { (42, ("xyz", Cat())) } let b: () -> (Int, (String, Animal)) = a
3:24 AM
戻り値の一番外側のタプルはともかく、内側でも Covariant なの謎だ。
Avatar
そうそう
3:26 AM
引数も内側のタプルがそうなるんで
3:26 AM
謎だった
Avatar
これもできた。 let c: (Int, (String, Animal)) -> () = { _, _ in } let d: (Int, (String, Cat)) -> () = c
3:27 AM
なるほどー。関数型については、ネストした分も含めて、戻り値ではタプルは Covariant 、引数では Contravariant になってるんだ・・・。
Avatar
それ利用すると、Genericsのinitを関数で受け渡しすることで
Avatar
これ、 swift-evolution に出してもいいんでは? Inconsistent bihavior of tupple variances みたいな。
Avatar
GenericsにCovariant/Contravariantっぽい機能を追加できるようになる
Avatar
このまえやってたやつですね。
Avatar
そうです
Avatar
ネストの内側までこうなってるのって確信犯的ですよね。あえてやってる。
3:29 AM
ということは、普通のタプルでそうなってないのは実装漏れなのかな。
Avatar
で、それを書いてる途中で、またassociatedtypeにtupleを入れてdefault implを書くとコンパイラクラッシュに遭遇した
Avatar
omochimetaru 4/18/2017 3:29 AM
鉄板落ちみたいになってて笑う
Avatar
でも今回は、associatedtypeをBoxingすれば回避できることに気がついたので
Avatar
norio_nomura 4/18/2017 3:30 AM
stdlib内にその挙動を利用した実装があるのかどうか。
Avatar
この実装ができた。 https://github.com/tarunon/Covariancable
Covariancable - Add covariance/contravariance feature on your type-erasure.
3:30 AM
let convarianceAnimalCage = AnyAnimalCage<Animal>(~catCage) // Adding `~` operator, pass compile it! 💪
Avatar
omochimetaru 4/18/2017 3:33 AM
最後のめんどくさい部分を オペレーター定義で簡単にしたのね
Avatar
let foo: () -> (Cat, Int) = { (Cat(), 1) } let foo2: () -> (Animal, Int) = foo のときは -dump-astで (function_conversion_expr implicit type='() -> (Animal, Int)' (declref_expr type='() -> (Cat, Int)' )) だけど
❤ 1
3:33 AM
function_conversion_expr が噛まされているってことですね
Avatar
おー
Avatar
https://github.com/apple/swift/blob/master/lib/Sema/CSApply.cpp#L4427 みると、ASTで tuple を変換する expr が無いからまだ実装出来ないよ的な。
swift - The Swift Programming Language
❤ 1
Avatar
omochimetaru 4/18/2017 3:36 AM
// We need to convert the source element to the destination type. if (!fromTupleExpr) { // FIXME: Lame! We can't express this in the AST.
Avatar
Start factoring out the logic that computes the mapping from one tuple type to another. We're only using it in one place now (the tuple-to-tuple coercion), but it should be picked up by the constra...
❤ 1
Avatar
omochimetaru 4/18/2017 3:36 AM
FIXMEだ。
3:36 AM
てことは、やってないんじゃなくて、まだやってない、説が強くなってきたぞ
Avatar
じゃあ PR 作れば通る可能性も?
Avatar
忘れ去られているだけのような気がしますね。
Avatar
なるほどー。
Avatar
norio_nomura 4/18/2017 3:40 AM
素晴らしい
3:43 AM
この辺りの挙動は未定義で、たまたま今こうなってると。
3:47 AM
他と整合取れた実装にすると tarunon さんの Covariancable は動かなくなる?
Avatar
えっ
3:47 AM
TupleにCovariantが追加されるのが平和で良いのではないでしょうか
Avatar
omochimetaru 4/18/2017 3:47 AM
サブタイピングが効く側に倒れる分には動かなくはならなそうだけど、そもそも不要になりそう
Avatar
不要というか
Avatar
omochimetaru 4/18/2017 3:47 AM
効かない方に統一されたら動かなくなりそうですね
Avatar
中でfunction作って渡してる部分が、tupleでOKになるだけですね
Avatar
omochimetaru 4/18/2017 3:48 AM
あ〜
Avatar
効かない方に統一とか鬼畜の所業、やめていただきたく
Avatar
omochimetaru 4/18/2017 3:48 AM
そっか、taruninのライブラリがやるのはgeneric structのcovarianceの話か
Avatar
そうそう
3:49 AM
他パラメータ渡すのしんどいから~で簡単にする、でそれで受け渡しするのが
3:49 AM
tupleをreturnするfunctionから、tupleを使うだけの素直な実装になる (edited)
Avatar
前に Chris Eidhof が挙げてた Proposal が Review 入りしてる。これできたらうれしい。 https://github.com/apple/swift-evolution/blob/master/proposals/0171-reduce-with-inout.md
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
Avatar
これは欲しい
3:56 AM
これが無いのでDictionaryを外に書かないといけない
Avatar
reduceDictionary 作る時とかだるすぎたから
3:56 AM
ですよね。
Avatar
norio_nomura 4/18/2017 3:59 AM
ASTで tuple を変換する expr が無いからまだ実装出来ないよ的な。
これって、タプルごとキャストが動かないのと同じもの? let anyany: (Any, Any) = (Int(1), Int(1)) if let intint = anyany as? (Int, Int) { print(intint) // 3.0.2: unreachable, 3.1: "(1, 1)\n" } if let int0 = anyany.0 as? Int, let int1 = anyany.1 as? Int { print(int0, int1) // "1 1\n" }
(edited)
4:00 AM
お、3.1で動くようになってた。
Avatar
キャストとはまた違う気がする
4:02 AM
でもキャスト動かなかったんですね、知らなかった
Avatar
norio_nomura 4/18/2017 4:05 AM
別物ですかね。 (edited)
Avatar
関係ありそうな気もしてきた、理解が半端だけど直感的にexpr無しで動かないような気もする。
4:10 AM
どうやって動くようにしたんだろ
Avatar
let a: (AnyObject, AnyObject) = (Cat(), Cat()) let b = a as! (Animal, Animal) みたいなときは、静的なキャストができなくてタプル全体が実行時キャストになるから FIXME のところまで到達しないと思います。 (edited)
Avatar
あー
4:26 AM
なるほど
4:26 AM
なるほど、なるほど
4:26 AM
ありがとうございます
4:26 AM
そうか、こっちはコンパイル時に解決しなくて良いのか
Avatar
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
👍 2
Avatar
Array扱う分にはprefixdropで足りるんですけどね
Avatar
これが通ったらまたRangeファミリーが増えてしまう・・・。
Avatar
omochimetaru 4/18/2017 6:34 AM
ファミリーが多い問題点はconditional conformanceが入れば解決するのでは。
6:34 AM
特定のジェネリックなコードで4回オーバーロードしてるのが辛いって話ですよね (edited)
Avatar
はい。 conditional conformance で解決というのは?
Avatar
omochimetaru 4/18/2017 6:37 AM
1つの定義にできるような気がしてる
Avatar
protocol 作ればできる気がする。
Avatar
omochimetaru 4/18/2017 6:38 AM
あれっ、今ってprotocolすら何もついてないんですね
6:39 AM
今も自分でプロトコル付けたら1個にできるのかも
Avatar
protocol GeneralRange { associatedtype Value: Comparable var lowerBound: Value? var upperBound: Value? } extension Range: GeneralRange {} ... (edited)
Avatar
下限値はどっちも取れるんで上限値をとるのをつければ良さそうですね
6:41 AM
RangeClosedRangeupperBoundの意味が違った記憶
Avatar
単純な subscript だと 4 通りだけど、組みわせになると爆発するから https://github.com/koher/EasyImagy/blob/swift-3/EasyImagy/Image.swift#L78-L92
EasyImagy - Makes it easy to deal with images in Swift
Avatar
omochimetaru 4/18/2017 6:42 AM
/// An interval over a comparable type, from a lower bound up to, and
/// including, an upper bound. >> /// A half-open interval over a comparable type, from a lower bound up to, but /// not including, an upper bound.
6:43 AM
var includingUpperBound: Bool も生やせば解決? (edited)
Avatar
↑は本当は 16 通りある。↑は 2 乗だけど、 TensorSwift とか numsw でやってるようなのだと N 乗になっちゃうから一つにまとめないと実装できない。
6:43 AM
どうせなら 1<..42 とかも作って欲しい。
Avatar
下が開いてるのは需要ないんですかねぇ
6:44 AM
<..<まででてくると気持ち悪そう
Avatar
コーディング上少ないだけで、絶対にあると思うけどね〜。
6:45 AM
<.<<..< か悩ましいな。
Avatar
omochimetaru 4/18/2017 6:47 AM
1個点だともはやレンジ感が無くて謎なので2個がいいな
6:48 AM
僕は一般に範囲を制御する時は (begin, end): begin <= x && x < end とするのが好きで、理由はこれだと連続な直線を過不足なく繰り返し分割できるから
6:50 AM
したがって 4月いっぱいまでのキャンペーン期間を定義する時は 04-30_23:59:59 じゃなくて05-01_00:00:00にしたい (edited)
Avatar
つまり Range で事足りると言ってる?
Avatar
omochimetaru 4/18/2017 6:50 AM
そういう事ですね
6:50 AM
整数直線上で端が欲しい時はendを1個みぎにずらせばいいので。
6:51 AM
SwiftやRubyで記法があるときはまあClosedRange使うけれども別に型として存在して無くて良かった気がしてる
Avatar
それはそうなんだけど、それってそのスタイルが普及してるだけだし、普遍的に a<..b が要らない理由とはならない気が。 (edited)
Avatar
omochimetaru 4/18/2017 6:52 AM
まあそうですね。
6:53 AM
ライブラリのバージョン、みたいな、離散的で計数不能な数の指定において、そういう表現が欲しい可能性はある
Avatar
norio_nomura 4/18/2017 6:57 AM
SwiftPMのPackage.swiftでプレリリースバージョンの指定がうまくできなかったのを思い出す
Avatar
omochimetaru 4/18/2017 7:00 AM
ちょうどSPMのコードを最近眺めてたんで僕もそれを思い浮かべていました
7:02 AM
↑Range2種オーバロード
Avatar
norio_nomura 4/18/2017 7:05 AM
Still needs niceties like custom string conversion, fix out of date tests and add new ones.
Avatar
extension ${Self}: RangeExpression { こんな書き方初めて見た
7:12 AM
いやこれ自体はswiftじゃないのか
Avatar
omochimetaru 4/18/2017 7:13 AM
gypだね
7:13 AM
あっ、gypじゃなくてgybだ!
Avatar
Generate Your Boilerplate
7:14 AM
てっきりGoogleのGYPを流用しているのかと思っていた
7:15 AM
swiftプロジェクト内で作られたツールなんですね
Avatar
norio_nomura 4/18/2017 7:27 AM
swift.orgで配布されているツールチェーンのシンボルデータはgybから生成されたソースコードを指しているので、ツールチェーンのビルドなしにgybを適切な場所へ展開するツールとか作りました。 https://gist.github.com/norio-nomura/10d9790e7b5e414e20ae5ac6e621ef20 (edited)
swift_oss_helper.py helps debugging Swift Standard Library using source code with Swift Toolchain distributed at swift.org.
Avatar
omochimetaru 4/18/2017 7:28 AM
お〜
Avatar
norio_nomura 4/18/2017 7:49 AM
タプル続き class Animal {} class Cat: Animal {} let strinCat: (String, Cat) = ("xyz", Cat()) if let stringAnimal: (String, Animal) = strinCat as? (String, Animal) { print(stringAnimal) } でエラー: Playground execution failed: warning: 20170418-130912.xcplaygroundpage:1:50: warning: conditional cast from '(String, Cat)' to '(String, Animal)' always succeeds if let stringAnimal: (String, Animal) = strinCat as? (String, Animal) { ^ error: 20170418-130912.xcplaygroundpage:1:41: error: cannot express tuple conversion '(String, Cat)' to '(String, Animal)' if let stringAnimal: (String, Animal) = strinCat as? (String, Animal) { ^
Avatar
always succeedsとは
Avatar
norio_nomura 4/18/2017 7:51 AM
warning: conditional cast … always succeeds と言われるので as? から as へ変えると、2番目のエラーだけになる。 (edited)
Avatar
omochimetaru 4/18/2017 7:52 AM
実行時エラーじゃなくてコンパイルエラーですかね
Avatar
norio_nomura 4/18/2017 7:52 AM
です
Avatar
omochimetaru 4/18/2017 7:53 AM
ああ、本当だ、 always successなのに消しても怒られるw
Avatar
つらいw
Avatar
norio_nomura 4/18/2017 7:54 AM
先の FIXME: に引っかかってるぽいです
Avatar
omochimetaru 4/18/2017 7:57 AM
class Animal {} class Cat: Animal {} let strinCat: (String, Cat) = ("xyz", Cat()) print(strinCat) if let stringAnimal: (String, Animal) = strinCat as Any as! (String, Animal) { print("yatta") print(stringAnimal) } これでyattaが出力された・・・ (edited)
Avatar
そういえば、 "always failed" もバグってるんですよね。
Avatar
protocol Integral {} extension Int: Integral {} struct Foo<T> {} extension Foo where T: Integral { func foo() { let zelf = self as! Foo<Int> print(zelf) } } let foo: Foo<Int> = Foo() foo.foo() $ swift AlwaysFailed.swift AlwaysFailed.swift:8:25: warning: cast from 'Foo<T>' to unrelated type 'Foo<Int>' always fails let zelf = self as! Foo<Int> ~~~~ ^ ~~~~~~~~ Foo<Int>() (edited)
Avatar
今はT == Intできるから見なくなったやつですね
Avatar
omochimetaru 4/18/2017 8:10 AM
あー できるときもありえるのに絶対ダメでコンパイルできないのか
Avatar
いや、 warning
8:10 AM
でも、確か FooArray にするとコンパイルエラーになるという謎挙動だったはず。 (edited)
Avatar
extension Array where Element: Integral { func foo() { let zelf = self as! Array<Int> print(zelf) } } swift sandboxで何も言われない
Avatar
いや
8:12 AM
これやろうと思ったら
8:12 AM
unsafeBitCastしなきゃいけなかったはず
Avatar
aliasingとかの話ですか?
Avatar
let zelf = self as! Foo<Int>
8:17 AM
これですね
8:17 AM
ArrayはそもそもunsafeBitCast無理か
8:18 AM
unsafeBitCastはファントムタイプでwarningでなくなるのと無理やり動かせるだけだった
8:18 AM
勘違いス、すみません
👌 1
Avatar
この辺の話(Ty<Some> から Ty<Covariant> への変換) って https://devforums.apple.com/thread/261699 で語られているんですが、 https://devforums.apple.com/message/1102432#1102432 のArrayとかは出来るけど任意の value type には当てはまらないって文脈で > this doesn't apply to every value type (because value types can contain references and not enforce copy-on-write) らしいのですが、どういうケースなんでしょう? (edited)
Avatar
この元の話は variance の話ですよね?
8:40 AM
Farm<Cow>Farm<Animal> として扱えないという。
Avatar
です。
Avatar
で、 SevenTenEleven さんが言ってるのはこの前検証してたみたいな Array<Cow>Array<Animal> として扱っていい理由の話ですが、 CoW はあんま関係ない気がしますね。
8:41 AM
別に代入時にコピーしちゃえばいいだけだから。
Avatar
Farm が struct だった場合に Farm<Cow> as Farm<Animal> できるとして、どういう不整合が発生する可能性があるのかを知りたい。
Avatar
発生しない気がします。
Avatar
Farmの上位のprotocolの規約として、func some(_ t: T) が生えてる場合は困ったことになる気がする
8:44 AM
でもArrayは暗黙的なmapで別に困ってないのか
8:44 AM
ふむー
Avatar
二つ下で Core Team の Dave が func makeAllAnimalsSpeakInFarm(farm : Farm<Animal>) { farm.listenToAnimals() } じゃなくて func makeAllAnimalsSpeakInFarm<A: Animal>(farm : Farm<A>) { farm.listenToAnimals() } でいいんじゃない?って言ってる。この、サブタイピングに頼らずジェネリック関数で解決するの、 Swift 的に正しいと思う。 (edited)
Avatar
実際このCovariantが欲しくなるシチュエーション、Covariantにしなければいけない型の代わりにGenerics宣言するとスッと解決するんですよね (edited)
8:48 AM
ただまぁ、
Avatar
8, 9 割は↑で解決できるからプロトコル型変数自体も作れなくしちゃってもいいんじゃないかと思ってます。
Avatar
func some<T, U> (...) where T: U が書けないので
8:49 AM
引数に入れる側の型にGenericsを書かなければいけなくって、結構ウッてなる
8:49 AM
回りくどい
Avatar
omochimetaru 4/18/2017 8:50 AM
func some<T, U> (...) where T: U ←これのどこらへんが書けない?
Avatar
普通にコンパイル通りませんよ (edited)
Avatar
どういうときに使うんですか?
Avatar
Tがprotocolじゃないって怒られる
Avatar
omochimetaru 4/18/2017 8:50 AM
あ〜
Avatar
なんかでも最近それで怒られた記憶が・・・
Avatar
UIView/UIViewController周りで型パラでなんとかしたい~~ってなって、その辺でSwiftラッパー書いてると
8:51 AM
絶対遭遇しますね
8:51 AM
ラッパー側の汎ゆる場所をGenericsで宣言すればまあ動くんですが
8:52 AM
なので、func some<T, U> (...) where T == U って書いて、Uに束縛される側を、サブタイピングなGenericsで宣言し直す
8:52 AM
これが今のところ一番マシなWorkaround
8:52 AM
超回りくどい
Avatar
Generalized existentials↓を導入する方向性よりも、プロトコル型変数を禁止する方向性の方が、言語がシンプルになってうまくいくような気がしてる。さすがにサブタイピングなくなりすぎできついかな・・・。 https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#generalized-existentials
swift - The Swift Programming Language
Avatar
classが存在する以上、問題はついて回りますね
Avatar
omochimetaru 4/18/2017 8:56 AM
@koher その章の例で示されているように、typealiasしちゃえば、 typealias AnySequence<Element> = Any<Sequence where .Iterator.Element == Element> これって完全にあの書くのがめんどくさいTypeErasureの
8:56 AM
自動生成機能にすぎない気がします
8:57 AM
それともめんどくさい事によって濫用が防がれているのがいいのかな。
Avatar
initしなくていいっていう差はあるんじゃない?
Avatar
omochimetaru 4/18/2017 8:58 AM
あ、なるほど。
Avatar
あでも値型ならコピーするからほぼ変わらないのか
Avatar
omochimetaru 4/18/2017 8:58 AM
あくまで型関係なのか
8:58 AM
あー、うん、実行時モデルではそうなるけど
Avatar
データはともかくポインタは
Avatar
omochimetaru 4/18/2017 8:58 AM
プログラマがコンストラクタは書かなくていい
Avatar
それはそうね
8:58 AM
今は
8:58 AM
AnySequence(array)
8:59 AM
絶対こう
8:59 AM
で、これを利用者側に書かせるのがうんkだから、
Avatar
omochimetaru 4/18/2017 8:59 AM
あー、個人的にはむしろ、そこが大事な気がする・・・
Avatar
init<S: Sequence>(, , , sequence: S) みたいな
8:59 AM
そう言うの毎回作る
Avatar
omochimetaru 4/18/2017 8:59 AM
そこが明示的に変換していることでブリッジオブジェクトを生成しているコストが肌で感じられる
Avatar
APIのUXかな?(計算量の重い操作は使いづらい)
Avatar
omochimetaru 4/18/2017 9:00 AM
そうそう。
Avatar
TypeErasure自体アンチパターン感が。
Avatar
omochimetaru 4/18/2017 9:00 AM
で、この章のように、いらなくなってしまうと、
Avatar
ええーー
Avatar
omochimetaru 4/18/2017 9:00 AM
多分、ライブラリの引数で受けるところとか
9:00 AM
全部これで書きましょうって方向に
9:01 AM
みんな流れていく気がする
Avatar
引数はそのままで、格納するところはこれになるんじゃ
9:01 AM
だからあんまり変わらない気もする
9:01 AM
外見は一緒じゃないかなぁ
Avatar
多分、ライブラリの引数で受けるところとか 全部これで書きましょうって方向に みんな流れていく気がする
そう、こうなるのを恐れてる。
Avatar
omochimetaru 4/18/2017 9:01 AM
List<Integer> xs = new ArrayList<Integer>
Avatar
Java で List<String> とか書くノリで、 [String] じゃなくて AnySequence<String> になってしまいそう。
Avatar
omochimetaru 4/18/2017 9:02 AM
これの世界になってしまうと、値型ベースのSwiftの高速な世界が
9:02 AM
Javaのなんでもメソッドディスパッチコストかかる世界になっちゃいそう
Avatar
Java では次のようなコードが一般的です。 java // Java List strings = new ArrayList(); ArrayList インスタンスを `Arr...
Avatar
omochimetaru 4/18/2017 9:05 AM
引数はそのままで、格納するところはこれになるんじゃ
格納するところがこれになっちゃうと、遅くなるはず。
Avatar
ふむ
9:05 AM
今はAnySequence入れてるけど
9:05 AM
それは遅くならない?
Avatar
omochimetaru 4/18/2017 9:05 AM
今AnySequenceになっちゃってるならそれと同程度に遅い
9:05 AM
Arrayにしたほうが早いはず。
Avatar
ほー
Avatar
norio_nomura 4/18/2017 9:08 AM
これって、中身Arrayになるんじゃないの? (edited)
Avatar
Java 的な List<String> な世界を目指すなら Generalized existentials や Type Erasure はめんどくさすぎますし、サブタイピングに頼らない静的ディスパッチな世界を目指すなら Generalized existentials もプロトコル型変数すらもいらないと思うんですよねぇ。
Avatar
omochimetaru 4/18/2017 9:10 AM
@norio_nomura それは不可能なはずです。 SequenceはmakeIteratorでイテレーターが取れるっていうだけのインターフェースだから、 例えばmakeIteartorのたびに異なる数列を返すイテレーターを返す挙動がありえます。 AnySequenceのコンストラクタは S: SequenceS を受け取るだけだから、 その S の makeIteartorに転送するだけのコードがAnySequenceの実体です
9:11 AM
makeIteartorインターフェースは、無限数列も表現可能なので、そういういみでもArrayにできない
Avatar
norio_nomura 4/18/2017 9:12 AM
これの話だよね? typealias AnySequence<Element> = Any<Sequence where .Iterator.Element == Element> let strings: AnySequence<String> = ["a", "b", "c"] (edited)
9:13 AM
今の AnySequence とは別物では?
Avatar
omochimetaru 4/18/2017 9:13 AM
あ、そっちの話か。すいません。
9:14 AM
そっちの場合は、現状で、 func f <E, S : Sequence> (s: S) where S.Iterator.Element == E とかやったときに、 これを呼び出す時に引数に渡したArrayがSequenceとしてアップキャストされるときと、 同じような仕組みで実現されると思っていて
9:15 AM
その場合、protocol existential 的なものになっていて、 元々のArrayもコピーしてるけど、メソッド呼び出しは いったんprotocol witness tableっていう、仮想関数テーブルを経由する形になります
9:16 AM
9:16 AM
# 導入 Swiftでは通常のプロトコルは変数の型として使用することができますが、 型パラメータ(associated type)を持つジェネリックなプロトコルの変数は作れません。 非ジェネリックな例 ```swift prot...
Avatar
9:18 AM
AnySequenceはmakeIteratorをclosureとして持つ構造じゃないの?
Avatar
omochimetaru 4/18/2017 9:18 AM
今のAnySequenceはそうだけど
Avatar
受け取ったSequenceからmakeIteratorを取り出す時にwitness-tableが要るのか
Avatar
omochimetaru 4/18/2017 9:18 AM
いや、2つのAnySeqneceの話があって
9:18 AM
今実在しているSTDLIBのAnySeqnceはクロージャーでメソッドを転送してるけど
9:19 AM
koherが張ったGenericManifestoで書かれてる typealias AnySequence<Element> = Any<Sequence where .Iterator.Element == Element> Generic Existential + type alias としての AnySequenceは
9:20 AM
クロージャー方式じゃなくて、既存のジェネリック関数で引数のところで現れるメモリ表現になるんじゃないかなあという事
Avatar
AnySequenceが遅いっていうのは
9:21 AM
今のクロージャーを引き回すそれも遅いという事だと受け取ったんだけど
9:21 AM
それは違う?
Avatar
omochimetaru 4/18/2017 9:22 AM
どちらの方式でも遅い、という意見です
Avatar
ふむ
Avatar
omochimetaru 4/18/2017 9:22 AM
クロージャー方式でもwitness-table方式でも
9:22 AM
結局、プロトコルの型としてそのメソッドを呼べるようにするための関数呼び出しと、そこから、中で捕まえてる本当の型の対応するメソッドを呼び出すための、ブリッジするだけの関数の呼び出しが必要だから。
9:23 AM
witness-tableに入ってる関数ポインタの先にある関数の実装は
9:23 AM
結局、中身のArrayをダウンキャストで取り出して、Arrayの本当のメソッドを呼ぶ、っていう構造になってる。
Avatar
9:25 AM
クロージャー方式本当に遅い?
9:25 AM
クロージャーにキャプチャする時点で、関数ポインタの先にある実装を渡しているなら
9:25 AM
それほどクリティカルにならないんじゃね、と思ったんだけど
9:26 AM
_makeIterator = { _ in s.makeIterator() } ←これはクソ遅くなりそうだというのはわかるけど、 _makeIterator = s.makeIterator ←これはセーフでは?
Avatar
omochimetaru 4/18/2017 9:28 AM
AnySequenceの場合: AnySequenceのmakeIterator呼び出し→ _makeItaratorフィールドの関数を呼び出し → 内部でArrayのmakeItarotを呼び出し Arrayの場合: ArrayのmakeItarotorを呼び出し で、手数が増えてる。
Avatar
それは関数1個分のオーバーヘッドで
9:29 AM
tableの探索みたいなO(n)になり得るサムシングではない
Avatar
omochimetaru 4/18/2017 9:29 AM
それはそう
Avatar
遅いと言われたのでO(n)なのかと思った
Avatar
omochimetaru 4/18/2017 9:30 AM
それはJavaのList<Integer>でも同じ話で
9:30 AM
でも、そのオーバーヘッドが無いからこそ
9:30 AM
Swiftは C/ C++ と比肩するスピードが出せる
9:30 AM
設計上のポテンシャルがあるのが
9:30 AM
魅力だと僕は思っているので
9:30 AM
関数1個分とか2個分のジャンプが増えるのが嫌だ。
9:30 AM
という話し。
Avatar
norio_nomura 4/18/2017 9:31 AM
Generalized existentials はビルド時に型が決まれば specialize されたりしないのかな?
Avatar
omochimetaru 4/18/2017 9:31 AM
ジェネリック関数については基本的にspecializeされまくって消去されます。
9:31 AM
でも、外部からリンクしたときのために、柔軟なバージョンがオーバーロードされて残る。
9:31 AM
Generalized Existentialsも同じ事が言えるはずで
9:32 AM
特に型の中のフィールドとかで使われちゃうと
9:32 AM
public な struct とかだったら、無理ですね
9:32 AM
パッケージローカルなstructだったら、 Arrayで使われてる場合は、Arrayにspecializeされた版で動かして・・・という風に消去できれば、
9:32 AM
最高な可能性はあります
9:33 AM
それならC++のtemplate classと同じになりますね。
Avatar
norio_nomura 4/18/2017 9:33 AM
そういうものを目指してるのかと勝手に思ってました。
Avatar
omochimetaru 4/18/2017 9:33 AM
なるほど。
Avatar
norio_nomura 4/18/2017 9:33 AM
実際の実装が出てこないとわかりませんね。
Avatar
ちなみに、現状のstdlibの Any*** はクロージャー方式ではないですよ。
Avatar
ファッ
Avatar
class MyAnyIteratorBoxBase<Element> { func next() -> Element? { fatalError("abstract") } } class MyAnyIteratorBox<I : IteratorProtocol> : MyAnyIteratorBoxBase<I.Element> { var base: I init(_ base: I) { self.base = base } override func next() -> I.Element? { return base.next() } } struct MyAnyIterator<Element> : IteratorProtocol { var base: MyAnyIteratorBoxBase<Element> init<I : IteratorProtocol>(_ base: I) where I.Element == Element { self.base = MyAnyIteratorBox(base) } func next() -> Element? { return base.next() } } こんな感じ。
Avatar
うおお
9:36 AM
IteratorがAnyIteratorにinしてる…
Avatar
クラスのインスタンスメソッドへの動的ディスパッチが入るから、非常に遅い。
Avatar
かなしかった
Avatar
omochimetaru 4/18/2017 9:37 AM
クロージャーより遅くなるのでは
9:38 AM
クロージャーとくらべてvtableの方がis_aを手繰る分1メモリ操作遅い気がしてる
Avatar
Rationaleとしては、クロージャにするとメソッドが多くなったときに、Any*** 変数のMemoryLayout.size が非常に大きくなってしまうから。
9:39 AM
けど、Iterator は next() だけなんだし クロージャにしようよっていう議論がある。
Avatar
omochimetaru 4/18/2017 9:39 AM
なるほどなるほど。
Avatar
Generalized Existentialsのspecializeって難しくないですか?↓みたいな Foo<T> があったときに struct Foo<T> { var ts: Any<Sequence where .Iterator.Element == T> init(_ ts: Any<Sequence where .Iterator.Element == T>) { self.ts = ts } } ↓で作った ab の間で同じ型なのにメモリレイアウトを変えないといけなくなりません? var a: Foo<Int> = Foo(Array([2, 3, 5])) // Arrayにspecializeされる var b: Foo<Int> = Foo(Set([2, 3, 5])) // Setにspecializeされる a = b // どうなる??
Avatar
omochimetaru 4/18/2017 9:41 AM
たしかに。
9:41 AM
それをフィールドに持つ型 に ついては最適化不可能ですね
9:41 AM
ローカル変数とかぐらいなら・・・
Avatar
specializeできるケースって、ジェネリック関数で問題ないケースな気が。
Avatar
omochimetaru 4/18/2017 9:42 AM
ローカル変数ならそもそも生の型でいいんだな
Avatar
うん
Avatar
omochimetaru 4/18/2017 9:42 AM
specializeできるケースって、ジェネリック関数で問題ないケースな気が。
そんな気がしてきた
Avatar
norio_nomura 4/18/2017 9:44 AM
用途としては動的ディスパッチがメインってことですかね。
Avatar
用途としては動的ディスパッチがメイン
そうなるように思います。
Avatar
omochimetaru 4/18/2017 9:57 AM
おー、クリスエイドフが、クロージャーのほうが10%速いんだけど〜って書いてる。
9:58 AM
見てなかったけど swift-dev ML も面白いですね。
Avatar
norio_nomura 4/18/2017 9:59 AM
あれ? Generalized existentials って、今の AnySequence とかの延長なの?
Avatar
あれ? Generalized existentials って、今の AnySequence とかの延長なの?
ちがうけど、Generalized existential があれば AnySequence とかいらなくね?っていう文脈だとおもってます。
Avatar
ちがうけど、Generalized existential があれば AnySequence とかいらなくね?っていう文脈だとおもってます。
ですよね。ありがとうございます。
10:02 AM
swift-dev MLの「9割はCIが失敗した〜」です。
10:04 AM
ああ、AnySequenceの代わりになるなら、AnySequenceと同じ問題にぶち当たるだろう、ってことか。
Avatar
Farm が struct だった場合に Farm<Cow> as Farm<Animal> できるとして、どういう不整合が発生する可能性があるのか
あー、わかった
11:42 AM
class Animal {} class Cow : Animal {} class Sheep : Animal {} class Fence<T> { var animal: T? = nil } struct Farm<T> { var fence: Fence<T> = Fence<T>() } func buySheep(farm: Farm<Animal>) { farm.fence.animal = Sheep() } let farm = Farm<Cow>() buySheep(farm: farm as Farm<Animal>)
11:43 AM
Farm が Generic なクラスを持ってたらだめってことでした。
Avatar
それはfenceも同様にcovariantなら問題ないはず
11:44 AM
swiftのGenericsパラメータが、内部的にTがどのような使われ方をされてるかがわからなくて、多分一番問題になるのは
11:46 AM
struct Farm<T> { var 困る奴: (T)->() }
11:47 AM
こんな感じで、クロージャを持たせて引数にTを置くと、この場合はFarm<Animal>をFarm<Cat>に代入できるはずで、逆は成り立たない
Avatar
うむ。いずれにしても Farm.T を持つリファレンスタイプのプロパティは Farm のコピー時には 普通なら deep copy はされないからですね。 (edited)
Avatar
Tについて、covariantなのかcontravariantなのかが宣言できれば、無理なく機能を追加出来そう。 今やろうとすると、Generics型の変数と関数と場合によってはextensionすらチェックして、covariantかcontravariantなのかを判断することになるのかな、無茶っぽい。
11:55 AM
covariantなら、covariantなGenerics型と変数と返り値がTな関数が通る。 contravariantなら、contravariantなGenerics型と引数がTな関数が通る。
11:55 AM
これであってるだろうか…
Avatar
ああなるほど、Array<T>がいけるのに、任意のFarm<T>がダメなの、完全にクロージャがあり得るからだ
👍 1
12:18 PM
functionならパラメータ書き換えて安全に動くけどクロージャは無理だ
12:23 PM
と言うことは、stored propertyに関してのみ変性を確認すればokなはずで、であれば宣言無しでも現実的な時間に収束し得るかしら?
Avatar
@tarunon >Tについて、covariantなのかcontravariantなのかが宣言できれば、無理なく機能を追加出来そう。 C#やkotlinのdeclaration site varianceがまさにそういう設計ですね class Box<out T> {} みたいに、 Tの前に in か out をつけられる (edited)
Avatar
そうすると、引数のTをコンパイルエラーにできる
Avatar
オーバーライド可能なメソッドの返り値部分はそのままで、引数部分はcovariance/contravarianceが反転する
Avatar
正負の数としてイメージしたら解りやすいな、Out Tで、functionの引数にcontravarianceなTを入れるのはok
Avatar
http://docs.scala-lang.org/tutorials/tour/variances.html class Foo[+A] // A covariant class class Bar[-A] // A contravariant class class Baz[A] // An invariant class
12:46 PM
scalaはまさにそんな雰囲気の文法
12:47 PM
[ ]< > だと思えばOK
Avatar
おおーー超解りやすい
12:47 PM
最高じゃん
Avatar
マジかあw
Avatar
概念的にはまさにこれだ
12:48 PM
俺の脳内イメージにピッタリあったw過去最高に理解できた
Avatar
(マジかあの意図は 僕がkotlin派だからです) (edited)
Avatar
norio_nomura 4/19/2017 3:31 AM
Mirror って積極的に使っても良いものなのだろうか?
Avatar
リフレクションエンコーダーで結構使ってます
😮 1
Avatar
Farm が Generic なクラスを持ってたらだめってことでした。
なるほどー。↓値型のままだとわかりづらいので struct とイミュータブルクラスは等価だから書き変えて、 variance annotation ( out ) を付けて考えると Fenceanimal がコンパイルエラーですね。 setter が許容できない。 class Animal {} class Cow : Animal {} class Sheep : Animal {} class Fence<out T> { var animal: T? = nil // コンパイルエラー } class Farm<out T> { let fence: Fence<T> = Fence<T>() } func buySheep(farm: Farm<Animal>) { farm.fence.animal = Sheep() } let farm = Farm<Cow>() buySheep(farm: farm as Farm<Animal>)
Avatar
↓Kotlinでやってみた。 // Kotlin open class Animal() class Cow : Animal() class Sheep : Animal() class Fence<out T> { var animal: T? = null } class Farm<out T> { val fence: Fence<T> = Fence<T>() } fun buySheep(farm: Farm<Animal>) { farm.fence.animal = Sheep() } fun main(args: Array<String>) { val farm = Farm<Cow>() buySheep(farm) } 予想通り Fenceanimal でコンパイルエラー。 $ kotlinc NestedGenerics.kt NestedGenerics.kt:6:17: error: type parameter T is declared as 'out' but occurs in 'invariant' position in type T? var animal: T? = null ^
Avatar
セッターもそうなるのか
3:51 AM
そうか、そうですね。
Avatar
out な型パラメータは引数でつかえず、 in な型パラメータは戻り値で使えません。
3:51 AM
が、 contravariant なパラメータは反転するので、 Foo<in T> だったときに
Avatar
セッターに関して言うと、外から処理が差し込まれるわけじゃないので
3:52 AM
Arrayと同じような扱いにしてしまっても
Avatar
out T の型の中で Foo<T> を引数として使うことはできます。
Avatar
問題はないのでは、と思っていた
Avatar
引数や戻り値に関数型が来る場合も簡単で、 (T) -> UFunction<in T, out U> と読み替えれば OK です。
Avatar
お、 Swift でも T について covariant な Foo<T>Foo<out T> のように振る舞う)を作ることに成功した。 typealias Foo<T> = () -> T class Animal {} class Cat: Animal {} let a: Array<Foo<Cat>> = [] let b: Array<Foo<Animal>> = a // OK
Avatar
見た目がそれっぽいだけw
Avatar
それっぽいだけですが、 variance の挙動は確認できますね。 class Animal {} class Cow : Animal {} class Sheep : Animal {} class Fence<T> { var animal: T? = nil } typealias Farm<T: Animal> = () -> Fence<T> func makeFarm<T: Animal>() -> Farm<T> { return { Fence<T>() } } func buySheep(farm: Farm<Animal>) { farm().animal = Sheep() } let farm: Farm<Cow> = makeFarm() buySheep(farm: farm) // Fenceがinvariantなのでfarmもinvariantでコンパイルエラー
Avatar
おおー
Avatar
Fence を covariant にしようとして typealias Fence<T> = () -> T? にすると、今度は animalvar にできません( FecceTout である制約が効いていると解釈できる)。
Avatar
OptionalをAnyに突っ込むと、Mirrorでしかnilかどうかチェックできないっていうのもあって、この間うちの人がハマってた
Avatar
値型の variance 、どう考えたらいいのか難しいと思ってたけど、イミュータブルクラスに変換して、 mutating funcstatic メソッドに読み替えれば解釈できそう。 ↓ Array は covariant にできる class Array<out E> { func get(_ index: Int) -> E { ... } static func set<E>(_ this: Array<E>, _ index: Int, newValue: E) -> Array<E> { ... } } けど、 Fence は covariant にできない。 class Fence<T> { var animal: T? = nil } class Farm<out T> { let fence: Fence<T> = Fence<T>() // Fence が T について invariant なのでエラー }
Avatar
CoWだから実際の動きもこれに近いですよね
4:33 AM
Fenceは
4:35 AM
class Fence<out T> { func getAnimal() -> T? { ... } static func setAnimal(_ this: Fence, newValue: T?) -> Fence { ... } } このように定義しておけば、 Farm<out T>も成り立ちそう。
Avatar
↑だと Fencestruct と等価になってしまって、最初の「不整合」なケースの前提が崩れてしまいます。逆に言えば、 Fencestruct なら struct Farm は covariant 的に振る舞っても問題ないということですね。 (edited)
4:38 AM
ちなみに、 Java の配列は variance 周りがぶっ壊れてるので、コンパイルエラーで検出できずに実行時エラーになる。 class Animal {} class Cat extends Animal {} class Dog extends Animal {} public class CovariantArray { public static void main(String[] args) { Cat[] cats = { new Cat() }; Animal[] animals = cats; animals[0] = new Dog(); // 実行時エラー System.out.println(cats[0]); } }
Avatar
private extension Hoge: FugaProtocol {} こういうのできたらいいのになーって思ったことないですか
7:33 AM
'private' modifier cannot be used with extensions that declare protocol conformances
Avatar
omochimetaru 4/19/2017 7:35 AM
FugaProtocolの種類によってはObjCではよく思った
7:35 AM
例えば MainViewController : UITableDataSource みたいなのは、自分で持ってるTableViewに繋ぎこむだけの場合
7:35 AM
UITableDataSourceとして他のところでMAinViewControllerを使われても困るから
7:36 AM
特にそのconformanceを公開したい意図は無い
Avatar
そんなかんじ
Avatar
omochimetaru 4/19/2017 7:36 AM
Swiftの場合もし徹底したければ、そのプロトコルを満たしたAdapterオブジェクトを作ってhas-aにするかな
Avatar
やっぱそれしかないよなあ
Avatar
omochimetaru 4/19/2017 7:36 AM
それで外からは非対応に見える
7:37 AM
ObjCならimplementsを.mの方に書けばそうなった
7:37 AM
C++はprivate継承っていうまさにそれをやる機能があったりする
Avatar
↓はどうでしょう? fileprivate protocol Foo { func foo() -> Int } extension Int: Foo { fileprivate func foo() -> Int { return self } }
Avatar
手元でのケースは、一応複数のVCに対して適合させたいプロトコルなのでプロトコル自体をfileprivateにするのはう〜んってかんじがしますね
7:39 AM
Protocol conformanceをprivateにできたらいいなあというのはそれそのものをprivateにしたいというのとは別に、「プロトコルで実装が強制されるプロパティをprivateにしたい」というのもある
7:39 AM
protocol extensionからprivateが見えないからどうにもならない感じはする
Avatar
omochimetaru 4/19/2017 7:40 AM
プロトコルは外から見た制約だからprivateで満たすっていうは変な感じ
Avatar
プロトコル、外からどう見えるかというのもそうなんだけど、共通の実装を強制するみたいな側面もあると思っていて、そうすると外に見せる必要はないんだけど内部でこのプロパティは必要だから置いておいてねというのができたい
Avatar
omochimetaru 4/19/2017 7:41 AM
あーでも発想としては同じなのかな。Selfスコープだけでみたときにはselfをその型として渡せるって感じかな
Avatar
今プロトコルは internal で、それをある特定のファイルの中だけで満たすよう( fileprivate )にしたいというニーズということですか?
Avatar
omochimetaru 4/19/2017 7:42 AM
共通の実装を強制するみたいな側面
うーんなんかアンチパターンを感じる
Avatar
大体そうです
7:42 AM
koherさん
Avatar
omochimetaru 4/19/2017 7:43 AM
XxxMixIn とか XxxImplHelper みたいな形にしておいて必要部分のクロージャーを受け取るようにしてhas-aで持つとか。 (edited)
Avatar
protocol Hoge {} private protocol PrivateHoge { var xxx, yyy, zzz } extension Hoge where Self: PrivateHoge { ... } (edited)
7:44 AM
こういうのじゃダメなの
Avatar
xxxとyyyとzzzをその適合してるクラスのそとから見えないようにしたいんだけどできるんだっけ
Avatar
あー、そっち側があったか。その xxx とかつけるの逆に考えてて( Hoge につけるの考えてて)、だめだなぁと思ってた。 (edited)
Avatar
private protocol Testable { var test: Int { get } } extension MyVC: Testable { fileprivate var test: Int { return 1 } }
7:46 AM
ここまでならいけるっぽい
Avatar
要は「別ファイルにあるexntensionから見える」というアクセス修飾子があればいいだけな気がしてきた
7:48 AM
またアクセス修飾子の話になってしまった
Avatar
omochimetaru 4/19/2017 7:49 AM
ちょっとぐらい見えすぎても大丈夫だよ!
Avatar
やっぱだめだ。
7:49 AM
private protocol をより広い protocol が継承するのは変だ。
Avatar
継承はしてないっすよ
7:50 AM
広いprotocolはfunctionを定義していて、private protocolはその条件になるあれやこれやを書いていて、その両方をimplしたらメソッドが生える
7:50 AM
それだけです
7:51 AM
逆にprivate protocolがpublic protocolを条件付けしていたほうが、もっとシンプルに書けるかもしれない。
Avatar
元々の要望は Hoge を色んなところで使いたくて、それをある場所では private に使いたいという話だと思うんですが、
7:51 AM
そうすると PrivateHoge から Hoge に流す部分で、
7:52 AM
それを元々 Hoge が使いたかった箇所から可視にすることができない気がします。
Avatar
ああ、本当だ読み間違えていた
7:52 AM
implを中で持つしか無いなぁ
7:54 AM
class MyViewController { class ScrollViewDelegateImpl: UIScrollViewDelegate { let parent: MyViewController } lazy private (set) var scrollViewDelegate: ScrollViewDelegateImpl = { [unowned self] in ScrollViewDelegateImpl(self) }() }
Avatar
SE-0104 Protocol-oriented integers がmasterにマージされたんですね。 https://github.com/apple/swift/pull/3796#issuecomment-294096066 チューニングはこれからやりますと。
Work on integers from @moiseev What's in this pull request? Resolved bug number: (SR-) Before merging this pull request to apple/swift repository: Test pull request on Swift continuous integr...
Avatar
マージされて羨ましい。apple/swiftへのPRが初めてマージされそうなのに、僕の変更と関係ないところでSwift Test and Mergeが通らなくてやきもき。
👍 1
11:55 PM
Swift Test and Merge通ってなさすぎ。 https://ci.swift.org/view/Pull%20Request/job/swift-PR-merge/
Avatar
Protocol-oriented integers には Comparable の変更含まれていないのね。 (edited)
Avatar
omochimetaru 4/20/2017 1:15 AM
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
Avatar
ほしい
Avatar
欲しいなぁ
1:16 AM
webViewからjs叩くとき、こういうのが欲しい
1:16 AM
みんなどうやってんだろ
Avatar
+= でがんばってるんじゃない
Avatar
omochimetaru 4/20/2017 1:17 AM
シェーダーを書くときに欲しい
Avatar
配列でそれっぽく書いてたりしました
Avatar
配列なるほど
Avatar
omochimetaru 4/20/2017 1:31 AM
let str = [ "hello \(name)", "world" ].joined(separator: "\n") 配列はこうかな
👍 1
Avatar
omochimetaru 4/20/2017 1:39 AM
addDisposableToに変わって作られたdisposed(by:)ってAppleのAPI Design Guidelineに則ってなくない?
Avatar
Avatar
omochimetaru 4/20/2017 1:39 AM
@hiragram これめっちゃ気に入ってるんだけどマジ?
Avatar
マルチライン文字列リテラルがレビュー入り
レビュー前からされてなかった? Accepted なのでは?
1:40 AM
The review of SE-0168: "Multi-Line String Literals" ran from April 6...12, 2017. The proposal is accepted with revisions.
Avatar
@omochimetaru 則ってね~じゃんと思っていて https://swift.org/documentation/api-design-guidelines/ の "Name Mutating/nonmutating method pairs" のところ
Swift is a general-purpose programming language built using a modern approach to safety, performance, and software design patterns.
Avatar
omochimetaru 4/20/2017 1:41 AM
swift-evolution-announce] [Accepted] SE-0168: Multi-Line String Literals
1:41 AM
Acceptedだった。
Avatar
ガイドライン通りに読むと hogeDisposable.disposed(by: fuga) は「fugaによってdisposeされたhogeDisposable」が返るってことにならんかなあとおもって
1:42 AM
hogeArray.reversed() と同じ
Avatar
bindToがbind(to:)になったならaddDisposableToもaddDisposable(to:)になるのかなと思って見たらdisposed(by:)とかいうのが追加されてたのを発見したという感じ
Avatar
Accepted with revisions だから修正が必要ってこと?
Avatar
omochimetaru 4/20/2017 1:43 AM
disposeBagによって 後で dispose される だから確かに当てはまってないね、結果的に返り値とかもでないし
Avatar
// Allowed, equal to "foo\nbar" """ foo bar """ // Not allowed """foo bar """ // Not allowed """ foo bar"""
1:45 AM
- The core team also believes that underindentation or inconsistent tab/space usage within the indentation should be an error. Every line inside the literal must begin with the exact sequence of spaces and tabs that precedes the closing delimiter.
1:46 AM
インデントを含まないなら冒頭のスペースどうすんだろうと思ったんだけど、終わりの """ をベースに考えるってことかな?妥当な気がする。 (edited)
Avatar
インデント気持ち悪いと思ったけど変数代入することを考えると悪くないか。
Avatar
むしろインデントが含まれちゃう系のヒアドキュメントとか気持ち悪いと思ってたから良さそう。
Avatar
var x = """ hogehoge """"
1:48 AM
最後の"""は一つ落としたい感じが
Avatar
omochimetaru 4/20/2017 1:48 AM
これは後ろの """ を左に寄せとけば、余計な事しない?
Avatar
最後の"""は一つ落としたい感じが
そうだね。で、それができると。
Avatar
omochimetaru 4/20/2017 1:49 AM
一番左にベタ寄せのほうがコピペ安定性が高くて好きなんだけど
Avatar
これは後ろの """ を左に寄せとけば、余計な事しない?
そうじゃないかな?
1:49 AM
どっちもできるという意味で素晴らしい。
Avatar
omochimetaru 4/20/2017 1:49 AM
そうだと嬉しい
Avatar
Kotlin みたいなキモいことしなくていいのうれしい。 // Kotlin val text = """ |Tell me and I forget. |Teach me and I remember. |Involve me and I learn. |(Benjamin Franklin) """.trimMargin()
1:52 AM
閉じ """ でコントロールっておもしろいなぁ。
Avatar
"""の中なら、"はエスケープしなくても良いのかな、可読性一気に上がりそう
Avatar
omochimetaru 4/20/2017 1:53 AM
assert( xml == """ <?xml version="1.0"?> <catalog> <book id="bk101" empty=""> <author>\(author)</author> <title>XML Developer's Guide</title> <genre>Computer</genre> <price>44.95</price> <publish_date>2000-10-01</publish_date> <description>An in-depth look at creating applications with XML.</description> </book> </catalog> """ )
1:53 AM
提案がこうなってるし DQx2は書けるっぽい
Avatar
サイコーだ
1:54 AM
それも踏まえた上での3つか
Avatar
omochimetaru 4/20/2017 1:54 AM
っぽい
Avatar
norio_nomura 4/20/2017 1:54 AM
// Allowed, equal to "foo\nbar" """ foo bar """"foo\nbar\n" ではなく "foo\nbar" なのか。
Avatar
うん、そこがミソじゃない?
Avatar
omochimetaru 4/20/2017 1:54 AM
@norio_nomura 主流派とは違う感じがしますね
Avatar
あ、 @omochimetaru かと思ったら @norio_nomura さんだったw
Avatar
omochimetaru 4/20/2017 1:55 AM
失礼ですぞ
Avatar
失礼しましたw
Avatar
norio_nomura 4/20/2017 1:55 AM
お?
Avatar
必ず最終行に """ を書かせることでインデントをコントロールできるところがミソかと。
Avatar
後ろで揃える以上強制で\n入るのは微妙そうですしね
Avatar
omochimetaru 4/20/2017 1:56 AM
@t.ae いや、他の言語だと """aaa bbb""" これで "aaa\nbbb" になる。
Avatar
1行目インデント揃えれないの辛そう
Avatar
はい。それでswiftの仕様だとそれができないので
Avatar
うん、なので、 Swift の閉じ """ でインデントと本文を区別させる方式なら
1:57 AM
最後に "\m" を入れるわけにはいかない。最後の "\n" を消す方法がなくなっちゃうから。
Avatar
まさにそれが言いたかったことです。
Avatar
let s = """ abc def """ 今の仕様ならこれで末尾 "\n" が実現できるし。
Avatar
norio_nomura 4/20/2017 1:58 AM
納得
Avatar
Kotlin みたいな trimMargin もいらないし、これはうまい仕様だなぁ。
Avatar
norio_nomura 4/20/2017 1:59 AM
SwiftLintのテストケース書くのが一気に楽になる。
Avatar
いちいちファイル用意しなくて済みますね
Avatar
↓これどゆこと??
- The quoted string should normalize newlines to \n in the value of the literal, regardless of whether the source file uses \n (Unix), \r\n (Windows), or \r (classic Mac) line endings. Likewise, when the compiler strips the initial and final newline from the literal value, it will strip one of any of the \n, \r\n, or \r line-ending sequences from both ends of the literal.
// equal to "foo\nfoo\nfoo\nfoo" """^J foo^M^J foo^J foo^M foo^M """
Avatar
omochimetaru 4/20/2017 2:03 AM
ソースコードの改行コードによらず \n に正規化する
Avatar
^J とか ^M とか何?
Avatar
omochimetaru 4/20/2017 2:03 AM
^M が \r で ^J が \nのエスケープ表記かな?
Avatar
ああ、どっかに書いてあるのか?
Avatar
omochimetaru 4/20/2017 2:03 AM
gitのdiffで見る
2:04 AM
いや、なにかの流派におけるエスケープ表現 シェル系のだと思う
2:04 AM
詳しくは知らない
Avatar
あー、これを書けるようにしようというわけではなく、改行文字を表すためにここに書いてるだけってこと?
Avatar
omochimetaru 4/20/2017 2:04 AM
そう
2:04 AM
見えない文字を表現したくてそうなってる
Avatar
vimで改行コード不揃いのファイル開いた時に見たりする。
🙂 2
Avatar
なるほど。
Avatar
@hiragram disposed(by:)、本当はisDisposed(by:)が正しいんだと思う。
Avatar
omochimetaru 4/20/2017 2:08 AM
@tarunon isつけたらBool返す系になっちゃわない?
Avatar
そう、だからis抜いて意味がわからなくなった
2:09 AM
経緯見てないからわからんな
Avatar
omochimetaru 4/20/2017 2:09 AM
メソッド自体は Disposable を DisposeBagに突っ込む機能だよ
Avatar
Disposableが何を契機にdisposeするのか、とも取れる
2:10 AM
disposeBagはdisposeを発火するための装置、であれば、まあ納得かな
Avatar
omochimetaru 4/20/2017 2:13 AM
ガイドラインには反してないと考える?
Avatar
ガは無理して正しい英語にしなくても…みたいなの書いてなかったっけ?
2:13 AM
それならまあうん
Avatar
omochimetaru 4/20/2017 2:14 AM
Name functions and methods according to their side-effects / Name Mutating/nonmutating method pairs には、変更して新しい値を返すやつは受け身系にしろ、みたいに書いてあるんだけど
2:15 AM
受身形は変更して新しい値を返すやつである、っていう逆方向は明言されてないからセーフ なんじゃないか
2:15 AM
と俺は思った。
Avatar
変更されたprを探してる、iPhoneでgithub漁るの難しい
2:15 AM
あった
2:16 AM
Added I brought up in the Slack channel that the original Disposable API .addDisposableTo(_ bag: DisposeBag) felt out of line with the newly minted Swift API guidelines. Because an Observable retur...
Avatar
@omochimetaru そこの文章ですけど
Avatar
slack見に行かないと議論の内容がわからないw
Avatar
mutating/non mutatingのペアの時にはそうしろって限定されてるんじゃないかと前@koherと話しました
Avatar
omochimetaru 4/20/2017 2:17 AM
@t.ae 片方しか無いなら命令形のまま新しいインスタンスを返しても良い?
2:17 AM
将来的な追加が予測できる以上結局ペアを想定しないといけない気がする (edited)
Avatar
そうですね
2:18 AM
disposed(by: )についてはペアがでてこなそうなのでこれで良い気もする。
2:18 AM
そもそもmutatingな何かじゃないし
Avatar
omochimetaru 4/20/2017 2:18 AM
そもそもこの話の枠外になるよね 同意見
Avatar
それはそれとして、Sequence.filterはどうするんやろ、ってずっと思ってる
2:20 AM
filtered?
Avatar
omochimetaru 4/20/2017 2:20 AM
なんかそこについては例外条項があるって @koher が言ってた
2:20 AM
filter みたいにあまりに有名なやつは特別
Avatar
例外、なるほど
Avatar
omochimetaru 4/20/2017 2:41 AM
うげ〜 SwiftのコードをObjCから見たら、 Error型がNSError型に見えてる
2:41 AM
URLがNSURLに見えるのとかは整合性取れるからいいけど、 ErrorとNSErrorはおかしくねえか・・・
Avatar
Error NSErrorウッ頭が
2:42 AM
全部NSErrorに変換できることになってるからまあわからんでもない
Avatar
ObjC互換のための暗黙的変換だったりするんですかね
Avatar
暗黙的変換(変換できるとは言っていない)ですね
2:43 AM
治ったのだろうか
2:44 AM
8.3.2で確認したけど修正されてるみたいだった
👏 1
2:46 AM
ErrorからNSErrorに強制的にキャストがかかる例のアレは未修正だった
2:46 AM
おこ
Avatar
norio_nomura 4/20/2017 3:10 AM
macOSとLinuxで結果が違った(tarunonさんの検証コード) import Foundation protocol MyCustomErrorProtocol: Error { var hoge: Int { get } } struct MyCustomError: MyCustomErrorProtocol { var hoge: Int { return 1 } } extension NSError: MyCustomErrorProtocol { var hoge: Int { return -1 } } let error: Error = MyCustomError() if let cError = error as? MyCustomErrorProtocol { print(cError.hoge) // macOS: -1, linux: 1 } (edited)
Avatar
omochimetaru 4/20/2017 3:18 AM
LinuxにはNSErrorが無い?
Avatar
norio_nomura 4/20/2017 3:22 AM
あるよ
3:22 AM
Objective-Cが無い
Avatar
omochimetaru 4/20/2017 3:23 AM
なるほど
Avatar
norio_nomura 4/20/2017 3:24 AM
NSErrorがSwiftで実装されてる。
Avatar
omochimetaru 4/20/2017 3:24 AM
ほ〜!
3:24 AM
いや、そりゃ当然の帰結としてそうか
Avatar
norio_nomura 4/20/2017 3:25 AM
swift-corelibs-foundation - The Foundation Project, providing core utilities, internationalization, and OS independence
Avatar
witness tableがいつ作られるのか気になって色々試してたら面白いのみつけた
Avatar
27行目は as Foo なのに FooStandardに準拠してることになってる?
Avatar
FooFatalが消えた
Avatar
それもそうだけど
Avatar
28?
Avatar
あ〜
Avatar
だから
10:59 AM
subclassが噛んだ瞬間にWitness tableが崩壊してるように見えている
Avatar
class Aの実装として extensionが動的に注入されてる?
Avatar
15行目で、より厳しい制約があるので、FooStandardがあるかは問題じゃないはずだが
Avatar
FooFatalのほうが無視されるのは
11:01 AM
静的な拡張としてしか扱われてないからなんじゃないかな
11:01 AM
これ1年前のtryswiftでたるのんが言ってたやつの仲間な気がする
11:01 AM
俺の予想だと
Avatar
それは思う
Avatar
class Aについては、Foo x FooStandardの組み合わせによって、 Aのメソッドとして
11:01 AM
fooが実装されてる
Avatar
てか、
Avatar
class Bについては、fooはオーバライドされてなくて
Avatar
struct B: Foo, FooStandard, FooFatalだと、コンパイルすら通らない
Avatar
FooFatalのwhere付きの静的な条件で、Bの型が見えてるときだけ
11:02 AM
静的ディスパッチでそっちが呼ばれる
Avatar
extensionで実装書くとwitness tableには関係しないのかなーと
Avatar
だから27行目も28行目もas Fooになった時点で、Foo型のexistanceとしてAやBのインスタンスがブリッジされてて
11:03 AM
Bの方はオーバーライドされたわけじゃないから、helloが出る
Avatar
FooStandardは探せるのに、FooFatalが探せてないのが気になる
Avatar
FooFatalは
11:04 AM
型がBとして確定したときしか
11:04 AM
見えない
11:04 AM
FooStandardは見つかってないんだけど
11:04 AM
Fooのfooとして読んでるだけで
11:04 AM
ただその実装がAにインストールされてる
11:04 AM
じゃないかなあ
Avatar
ふーむ
11:04 AM
struct B: Foo, FooStandard, FooFatal {} こっちはコンパイル通らないし
11:04 AM
それはそれとしてなんか普通に壊れてる気がする
Avatar
それだと、FooStandardとFooFatalの両方見つかる結果
11:05 AM
extensionが両方みつかって
Avatar
いやいや
11:05 AM
厳しい方優先すればいいでしょ
Avatar
どっちの実装をぶち込むか決められないんじゃない?
Avatar
extension Foo where Self: FooStandard vs extension Foo where Self: FooFatal
11:05 AM
これならどっち優先かわからない
Avatar
25行目のケースでfatalが出るってことは、
Avatar
あ、ごめん
11:06 AM
privateついてるせいだった
Avatar
厳しい方が優先っていうルール自体は存在してるのか
Avatar
FooFatalにprivateあるせいで
11:07 AM
要らんエラー履いてた
Avatar
a~
Avatar
Structは通った
Avatar
このprivate見てなかった
11:07 AM
てか、private protocol、この前も出てきたけど意味がよくわかってない
11:07 AM
何がprivateになるの
Avatar
ファイルの中でしか使えなくなる
Avatar
ファイルなんだ。
Avatar
一番外側のprivateはfileprivateと一緒
👌 1
11:08 AM
てか
11:08 AM
class Bにprivate protocol生やしても動くのは
11:08 AM
あー見えなくてもいいからか
Avatar
FooFatalをprivateではなくしても
11:13 AM
結果は同じだなあ
11:15 AM
sil_witness_table hidden AAA: Foo module a { method #Foo.foo!1: @_TTWC1a3AAAS_3FooS_FS1_3foofT_SS // protocol witness for Foo.foo() -> String in conformance AAA }
Avatar
作られてない?
11:17 AM
なんとなくそんな気はしたけど
Avatar
AAAのFoo conformanceが↑のテーブルで、fooメソッドとして _TTWC1a3AAAS_3FooS_FS1_3foofT_SS が入ってて それが内部で、 _TFe1aRxS_3FooxS_11FooStandardrS0_3foofT_SS を呼ぶようになってる
11:18 AM
_TFe1aRxS_3FooxS_11FooStandardrS0_3foofT_SS は、 A が // Foo<A where ...>.foo() -> String のwhereを満たしてる時ようのメソッド
11:19 AM
sil_vtable AAA { #AAA.deinit!deallocator: _TFC1a3AAAD // AAA.__deallocating_deinit #AAA.init!initializer.1: _TFC1a3AAAcfT_S0_ // AAA.init() -> AAA } sil_vtable BBB { #AAA.init!initializer.1: _TFC1a3BBBcfT_S0_ // BBB.init() -> BBB #BBB.deinit!deallocator: _TFC1a3BBBD // BBB.__deallocating_deinit }
11:19 AM
AとB自体はメソッドとしては保持してなかった。
11:19 AM
あくまでAがFooとしてアップキャストされるとき用のwitness-tableにfooの実装として hello の実装が入ってる
11:20 AM
FooFatalの方のwitnessは無さそう
11:20 AM
BがFooになるときは、親のAと同じ挙動でFooのExistanceになるっぽい
😳 1
11:21 AM
(FooFatalのprivateは外した状態で試した。わかりやすいようにAAAとBBBにリネームした。
Avatar
やっぱりsubclass絡んだwitness tableは暗黒界だ
Avatar
親クラスが満たすプロトコルとしてのExistanceはサブクラス側では作られないってことじゃないかな
11:22 AM
sil_witness_table hidden AAA: Foo module a { method #Foo.foo!1: @_TTWC1a3AAAS_3FooS_FS1_3foofT_SS // protocol witness for Foo.foo() -> String in conformance AAA } sil_witness_table hidden AAA: FooStandard module a { } sil_witness_table hidden BBB: FooFatal module a { }
11:22 AM
AAAのFooStandard witnessはあるけど、BBBのFooStandardはない
11:22 AM
一方BBBのFooFatalはある
Avatar
むむむむ
Avatar
割りと一貫したルールな気がする
11:23 AM
「あるクラスが定義される時、それが満たすプロトコル全てに対してwitness-tableを作るが、 例外として、親クラスで既にそのプロトコルについてのwitness-tableが作られているときは、作られない」
11:25 AM
1年前のやつは、その時に、クラス側にもメソッド定義があれば、それがvtableエントリに入ってきて、オーバーライドが働くっていうケースも混ざってた
11:26 AM
try-swiftで知り合った @tarunon さんから面白い話を伺いました。 以下、Xcode 7.2.1 (7C1002)の環境での話です。

結論

どうしたらいいかわかりません。。

本題

下記のように、 エクス...
11:26 AM
↑当時のまとめ
Avatar
これ確かバグ報告出した奴だっけか
11:27 AM
なんかこの辺無限に見つけてて、どれがどれかわからん
11:28 AM
これは仕様っぽかったからスルーしたんだ
11:28 AM
ちょいまっち
11:29 AM
アトラシアン💢iPhoneから全く操作できない💢💢💢
Avatar
てか、仕様が明文化されてないから
11:31 AM
コンパイラクラッシュ以外は
Avatar
ああ、これのうち、後ろ2つについて報告したんだ
11:31 AM
親クラスの宣言の有無で切り替わる奴
Avatar
実装が仕様なんじゃね
Avatar
実装が仕様w
Avatar
お返事あった?
Avatar
なんかワイワイやってるっぽい
11:34 AM
Doug Gregor氏がこれはバグだろうけど破壊的変更だからevolutionに乗せないとなみたいなこと書いてる気がする
Avatar
ほんとだ
11:35 AM
エボリューションプロセスで整理するって流れっぽい?
Avatar
最後の書き込みが、「やるけど明日からバカンスだぜ」(悪意のある翻訳)に見える
11:37 AM
4でprotocol周りやるからこれと向き合わないと死体増えそうな気がするけど大丈夫なのかな
Avatar
クラスに関しては open にしない限りサブクラス系の問題はモジュール内で解決できちゃうし、基本 open はよっぽどの理由が無い限り使わないように、ってことになってるので、プライオリティは低い気がしますねぇ。
Avatar
継承周りはおざなりな感じありますね
Avatar
今日 master から 4.0 への無条件マージの期限が 6/1 に切られたので、それ以降に source breaking な変更が4.0に入ることはなさそう。
Avatar
ふむふむ
Avatar
あと1ヶ月ちょいってこと考えると、厳しいと思います。
Avatar
やるなら手前でやるしかないかぁ、6月1日は無理ぽ
Avatar
結局iOSでコード書くと、classと継承は避けては通れないので
11:47 AM
この手の挙動とどう折り合いを付けていってるのか凄い気になる
Avatar
Swiftが最も使われてるのは間違いなくiOSアプリ開発だけど、SwiftはiOSを重要視してない感があるなぁ。値型中心の世界を作ろうとしてるし、SwiftPMはiOSサポートしてないし。
Avatar
まだ見れてないままだけど↓とか気になってる。 https://developer.apple.com/videos/play/wwdc2016/419/
Avatar
-emit-irを使うとメソッドにどのwitness tableが渡されてるかわかるぽい。 callFoo(B()) // hello %112 = call { i64, i64, i64 } @main.callFoo <A where A: main.Foo> (A) -> Swift.String(%swift.opaque* noalias nocapture %111, %swift.type* %21, i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @protocol witness table for main.A : main.Foo in main, i32 0, i32 0)) class C: Foo, FooStandard, FooFatal {} callFoo(C()) // fatal %122 = call { i64, i64, i64 } @main.callFoo <A where A: main.Foo> (A) -> Swift.String(%swift.opaque* noalias nocapture %121, %swift.type* %118, i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @protocol witness table for main.C : main.Foo in main, i32 0, i32 0)) (edited)
Avatar
norio_nomura 4/21/2017 1:52 AM
Swift 4.0のCHANGELOGにこんなのが https://github.com/apple/swift/blob/master/CHANGELOG.md
SR-1529: Covariant method overrides are now fully supported, fixing many crashes and compile-time assertions when defining or calling such methods. Examples:
class Bed {} class Nook : Bed {} class Cat<T> { func eat(snack: T) {} func play(game: String) {} func sleep(where: Nook) {} } class Dog : Cat<(Int, Int)> { // 'T' becomes concrete override func eat(snack: (Int, Int)) {} // 'game' becomes optional override func play(game: String?) {} // 'where' becomes a superclass override func sleep(where: Bed) {} }
(edited)
swift - The Swift Programming Language
Avatar
↑今でも問題なくコンパイルも実行もできる気がします・・・
Avatar
omochimetaru 4/21/2017 2:46 AM
なんかこれおかしくないか?
2:46 AM
Dog is Catだから、 DogのインスタンスはCatとして振る舞えなきゃいけなくて
2:46 AM
CatはsleepメソッドでNookを受け取る (edited)
2:46 AM
DogはSleepメソッドをオーバーライドしてるけど
Avatar
問題ないでしょ?
2:47 AM
引数については contravariant だから。
2:47 AM
より広い値を受ける分には問題ない。
Avatar
omochimetaru 4/21/2017 2:47 AM
せまいですよ
2:47 AM
ああぎゃくか
2:47 AM
親のほうが広いのか
Avatar
それにしても Dog: Cat ってカオスw
Avatar
omochimetaru 4/21/2017 2:47 AM
じゃあ、playがおかしくない?
2:47 AM
いや、これはいいな
Avatar
String? の方が広い。
Avatar
omochimetaru 4/21/2017 2:48 AM
いいのか。Nook < Bed で STring < String?か
Avatar
うん。
Avatar
omochimetaru 4/21/2017 2:49 AM
引数のオーバーライドがちゃんとcontravariantならJavaより正しいな
2:49 AM
でも、広くするってことは
Avatar
これを " Covariant method overrides" っていうのは正式な用語なのかな? Contra な引数に広いものを渡すのは - * - = + で Covariant ってこと?
Avatar
omochimetaru 4/21/2017 2:49 AM
親で func foo(cat: Cat) と func foo(dog: Dog) のとき
2:49 AM
サブで func foo(animal: Animal) としたら
2:49 AM
Cat < Animal と広げたのか Dog < Animalと広げたのか
2:50 AM
曖昧になりそう。両方を同時にオーバーライド?
Avatar
↑Swiftならラベルで区別されちゃうw
Avatar
omochimetaru 4/21/2017 2:50 AM
あ〜そっか。
Avatar
ラベルも同じだったらどうなるんだろ。
Avatar
omochimetaru 4/21/2017 2:50 AM
じゃあ ラベル省略されてるとき。
2:50 AM
その場合はエラーでもまあ
2:50 AM
概ねラベルで分離できるなら困りはしないな
Avatar
オーバーロードがあるとそこややこしいんだよね。
2:51 AM
Java だとオーバーライドで引数を広げようとしたらオーバーロードになるんだっけ?
Avatar
norio_nomura 4/21/2017 3:23 AM
元のissueのコードを試すと確かにクラッシュする。 https://bugs.swift.org/browse/SR-1529
Avatar
norio_nomura 4/21/2017 3:33 AM
import Cocoa class CrasherBase: NSView { var hasRect: Bool = false var rect: CGRect? { return hasRect ? CGRect(x: 0, y: 0, width: 50, height: 50) : nil } override func draw(_ dirtyRect: NSRect) { NSEraseRect(dirtyRect) } } class Crasher2: CrasherBase { override var rect: CGRect { return CGRect(x: 0, y: 0, width: 100, height: 100) } override func draw(_ dirtyRect: NSRect) { NSEraseRect(rect) } }
Avatar
ほんとだ。クラッシュしました。
4:08 AM
あれ?↓はいける。 class Animal { var foo: Int? { return nil } } class Cat: Animal { override var foo: Int { return 42 } } (edited)
Avatar
引数の反変だとoverrideでうまく動くけど返り値の共変だと死ぬのかな
4:09 AM
あー
4:09 AM
setterがあるからそんな単純な話じゃなかった
Avatar
なんで↑はクラッシュしないんだ??
Avatar
そもそも@norio_nomuraさんが貼ったコードの Crasher2#drawを消したらクラッシュしないんですが
4:16 AM
いやゲッタ呼び出し段階の話かな?
Avatar
norio_nomura 4/21/2017 4:16 AM
NSEraseRect(rect) がミソですね
Avatar
ああ、
4:19 AM
たぶん@koherと同じ勘違いしてましたね
Avatar
あー、そっちなのか。
4:22 AM
↓死んだ。 class Animal { var foo: Int? { return nil } } class Cat: Animal { override var foo: Int { return 42 } func useFoo() -> Int { return self.foo * 2 } }
4:25 AM
func でもダメだ。 class Animal { func foo() -> Int? { return nil } } class Cat: Animal { override func foo() -> Int { return 42 } func useFoo() -> Int { return self.foo() * 2 } } (edited)
Avatar
class Animal { func foo() -> Int? { return nil } } class Cat: Animal { override func foo() -> Int { return 42 } } Cat().foo() * 2 ↑外で呼んでもダメですね
4:28 AM
そもそもfooの呼び出しがどうやっても死ぬ
Avatar
あー、確かに昔 Optional とサブタイピングについて調べてたときに踏んだ気がする。継承で戻り値狭められるから FooFoo? のサブタイプ扱いされてますねって話で、でもメソッド定義するだけじゃなくて使おうとしたらすぐ死んでた気が。
Avatar
class Animal { func foo() -> Int? { return nil } } class Cat: Animal { override func foo() -> Int { return 42 } } let f = Cat().foo f() ↑回避できた
Avatar
Cat.foo(f)()だと行けるかと思ったけど死んだ
Avatar
@tarunon さんはよく FooFoo? に暗黙の型変換されるのを邪悪だと言ってますが、オーバーライドで戻り値を Foo? から Foo に狭められるなら FooFoo? のサブタイプでないといけないわけで、それなら Foo? 型変数に Foo を代入するのは暗黙の型変換ではなくアップキャストとみなせるわけですが、それについてはどうですか?
Avatar
うーん、このオーバーライド自体邪悪っぽい気がしていて
4:32 AM
いや、ダメでしょ…という感じがする
Avatar
FooFoo? のサブタイピング自体が邪悪ってことですね。
Avatar
そうです
Avatar
そうなんですよねぇ・・・
4:33 AM
Swift の Optional は Tagged Union なんだから本来サブタイプじゃないはずなんですけど、サブタイプ的にに振る舞わせることで、 Untagged Union で作られた Optional みたいになっちゃってるんですよね。
Avatar
Nullセーフになったのはまあそうなんですが
Avatar
Ceylon とかだと Foo?Foo|Null という (Untagged) Union になってて、当然 FooFoo?` のサブタイプなんですけど、
Avatar
Optionalセーフ?(と言って良いのかわからないけど)の域にはたどり着けない感
Avatar
Swift は Tagged Union だから Foo?? とかもできるわけだし、サブタイプ的に振る舞わせるのが微妙ですよねぇ・・・。
4:35 AM
だから、オーバーライドで Foo?Foo に狭めるのも、代入時の暗黙の型変換も全部なしってのがシンプルな気がする。今更無理だけど。
Avatar
omochimetaru 4/21/2017 4:35 AM
それだなあ。 TaggedUnionだとおかしくなる
Avatar
SwiftのOptionalに関しては、この暗黙のサブタイピングと
4:35 AM
ぶっちゃけSimpleDomainErrorも、それ単体でErrorが解ればいい、でOptionalにしがちだけど、 プログラムって必ず組み合わせて使うんだから単体では単純で良くても組み合わせたときのことを考慮するとErrorを吐くのが妥当、だよなぁ、って。 #swtws
4:35 AM
ここからの一連の議論の内容
4:36 AM
そこさえなんとかなれば
4:36 AM
Optionalを使うことに関して、変に気を使う必要が全くなくなる美しい世界が来ると考えていて
4:36 AM
遥か遠い理想郷
Avatar
omochimetaru 4/21/2017 4:36 AM
C++でOptional自作して使ってるけど、 毎回 Some(x) で包むので特に不便感じない
Avatar
あ、そうだ。それなんですけど、書こうと思ってて忘れてました。 Twitter に書いた方が後から見やすいかもですが、 SimpleDomainErrorthrows じゃダメな理由がわかりました。
4:37 AM
純粋な値がない Optional と Simple domain error が区別されることも意味がありますが、 Simple domain error が Recoverable error と区別されることにも意味がありそうです。
4:37 AM
なぜなら、
4:38 AM
struct SimpleDomainError: Error {} は、当然ですが Simple domain error なので、エラーが発生したという情報しか持たないわけです。
Avatar
全ての型で同じSDE型使ったらカオスにしかならないですが、そこはextension Int { struct SDE: Error {}} とか (edited)
4:40 AM
最低でも何の型でのSDEなのかは区別するべきでは
Avatar
しかし、 throws というのはエラーを合成したり伝播したりして処理するために設計されているんで (edited)
Avatar
RecoverableErrorとの混同より、Optionalとの混同のほうが
4:41 AM
煩雑さが増しますよ、経験則ですが
Avatar
Simple domain error を Error にしてしまうとそういう風に使うことをミスリードしてしまうわけです。
4:44 AM
Simple domain error はエラー情報を持たないためにすぐに処理しないとわけがわからなくなってしまうので
Avatar
であればFatalがそもそも正しいのでは、という気がする
Avatar
Error のまま取り回したり合成したりすることを推奨するのは望ましくないと。
Avatar
Optionalを扱うことにベストプラクティスを議論しなくていい世界観があるはずで、そこに到れるはず
4:45 AM
今日Intのベストプラクティスを議論する人が居ないのと同じように
Avatar
なので、値がないことと Simple domain error を区別するためには、 enum Failable<Value> { case success(Value) case failure }Optional とは別に作るのがいいかもしれません。
Avatar
throw SDE optionalで型分けるんですね
Avatar
はい
Avatar
SDEとRecoverableErrorの区別を、普遍的に人が理解できるところまで到達できれば
4:47 AM
いけそう
4:47 AM
人類進化してくれ
Avatar
ただ、個人的には複雑すぎる気がするし、値がないこととオペレーションの失敗を区別できないこともある気がするので( array.first とか dictionary[foo] とか)
Avatar
紛らわしいのはオーバーロードするなりして欲しいんですよね
4:48 AM
利用者側で決定付けれるはず
4:48 AM
なので
Avatar
ErrorOptional のどっちに寄せるかと言われると、個人的にはすぐ処理することが強制される Optional かなぁと思います。
Avatar
SDEが情報を持ってないのが前提なのも良くない気がしていて
4:49 AM
Error型がそもそも、デバッグ時には発生時のコールスタック持てるとか
4:49 AM
そういう機能を有していれば、まあそれはそれで解決できると思うんですよね
Avatar
Simple domain error を一切作らずに、すべてエラー情報を持った Error にするという世界もあり得るとは思います。 (edited)
Avatar
僕の理想としては、
Simple domain error を一切作らずに、すべてエラー情報を持った Error にするという世界もあり得るとは思います。
これが一番近い
Avatar
値がないかもしれない Optional か、 Error で表す Recoverable error か。
4:51 AM
ただ、 array.first とか array.max とかを Optional にするなら、それで消せるのって Int.init(String) くらいな気もするんですよね。
4:51 AM
純粋な Simple domain error ってほとんどない気がするから・・・。
Avatar
Int8(Int64)とかも
4:51 AM
まあ結構ありますよ
Avatar
まあ、変換系ですよね。
4:51 AM
conversion の失敗くらい?
Avatar
すぐ処理することが強制される Optional
4:52 AM
これがイマイチわからない
4:53 AM
Optionalは別にすぐに処理することを強制してないですよ
Avatar
プロパティに保持するのはいいですが、
4:53 AM
複数の Optional を合成しちゃうと出処がわからなくなって
Avatar
出処がわからなくなったら困る状況になってるのが後手ではないですか?
Avatar
デバッグするときに nil じゃないはずの値が nil になっちゃったときに、どれが元々 nil なんだ?ってのを探るのが大変
Avatar
前も書きましたが、複数のIntを合成して、偶数になるはずが奇数になったのでどれが奇数だったかわからなくて困る
4:54 AM
本質的にはこれと一緒の事を議論している気がしていて
4:55 AM
実際にはそれとは差がある、その差を生んでるのがロジックエラーの混入なわけです
Avatar
複数の Int を足して偶数を期待する状況は稀にしかおこりませんが、
4:55 AM
nil だと起こると思うんですよ。
4:55 AM
たとえば SwiftyJSON を使って JSON をデコードすると
4:56 AM
return curry(User.init) <^> json["name"] <*> json["age"] <*> json["gender"]
4:56 AM
みたいなコードを書いて、結果が nil だった場合にどのパラメータが nil だったんだ?みたいな。
Avatar
それはErrorにするべきものをOptionalにしてるだけでは
4:57 AM
Himotokiはキーパス毎にErrorが出ます、なので困らない
Avatar
でも本質的には同じじゃないですか?
Avatar
いや、だからOptionalにErrorを混ぜると
4:57 AM
そういう問題が起こるんです
Avatar
name: String?age: Int?gender: Gender? があるときに
4:58 AM
それが別に SImple domain error じゃなくて
4:58 AM
別の Optional プロパティからとってきたときかもしれないですよね?
4:58 AM
DB 上任意項目の name, age, gender があって
4:58 AM
そのレコードから取得してるかもしれない
Avatar
発生場所がバラバラなら、発生場所毎にデコード処理なりなんなりあるわけで
Avatar
struct UserRecord { var name: String? var age: Int? var gender: Int? }
Avatar
そこできっちりErrorを生成すればいい
4:59 AM
そもそもUserRecordのそれらの値が
4:59 AM
クライアントサイドの型的にもOptionalが許容されているなら
4:59 AM
合成で問題が起こるはずがない
Avatar
とか、 jsonjson じゃなくて record という Dictionary かも。
5:00 AM
いや、なので本来的には
5:01 AM
guard let name = record["name"] else { throw ... } guard let age = record["age"] else { throw } guard let gender = record["gender"] else { throw } return User(name, age, gender) (edited)
5:01 AM
とすべきだということです。
Avatar
うーん
Avatar
これが Optional をすぐに処理すべきという話。
Avatar
例えばDictionaryの添字アクセスがErrorだったら
5:01 AM
その辺がもう少し書きやすくなるんで
5:01 AM
まあオーバーロードで、用途によってですね
5:02 AM
適切に使えたほうが良いなあということです
Avatar
オーバーロードでというのは、↓みたいなのがほしいということですか? extension Dictionary { subscript(key: Key) throws -> Value { ... } }
Avatar
ですです、
5:05 AM
do { return try User(record["name"], record["age"], record["gender"]) } catch { throw User.Error.decodeFail(error) } (edited)
5:05 AM
こうなりますよね
5:05 AM
スッとする
5:05 AM
tryがある時にErrorになってくれて、それ以外はOptionalみたいな
5:06 AM
まあそういう機能があって、この微妙な境界線をですね
5:06 AM
サーッと解決してくれたら嬉しいなって
5:06 AM
そういう話です
Avatar
そもそもUserRecordのそれらの値が クライアントサイドの型的にもOptionalが許容されているなら 合成で問題が起こるはずがない
これはそうとも言えなくて、アプリ全体では User 各プロパティに nil が許されているけど、特定の機能に関してはすべて非 Optional なプロパティをもった CompleteUser が求められているかもしれないです。そういうときに User から CompleteUser を作るのも同じ話になります。
5:07 AM
僕がすぐ処理すべきと言っているのは値がない意味でプロパティに持つなということではなくて
5:07 AM
それを使う側の関数のローカルスコープで長々と保持するなということですね。
Avatar
うーん
5:08 AM
まあOptionalから値取り出して使うならそうなんですが
Avatar
逆に Optional をローカルで取り回したいケースってどういうときがありますか?
Avatar
OptionalはOptionalとして使うから
5:09 AM
普通にNullableなモデルとして使いませんか?
Avatar
プロパティを nullable にするのはわかりますが、関数ローカルで nullable なまま取り回さないといけないケースって稀だと思うんですよね。
5:11 AM
もしその nullable を合成しちゃったら結局出処がわからない問題になっちゃうし
5:11 AM
合成しないならどうぜ後で処理しなきゃいけないからすぐに処理すればいいし。 (edited)
5:14 AM
Optional な引数に渡す値を作って、可読性のために一度変数に代入したいときとか?
Avatar
omochimetaru 4/21/2017 5:15 AM
ヌルのまま取り回していいのは
5:15 AM
合成結果が意味的にヌルで正しい場合だけで
5:15 AM
途中で出てくる
5:16 AM
その文脈においてエラーであるはずのほうの
5:16 AM
ヌルを混ぜちゃいけない
Avatar
合成結果が意味的にヌルで正しい場合
っていうのは、それを Optional としてそのまま使いたい場合、つまり、何かの引数に渡したい場合ってことであってる?
Avatar
omochimetaru 4/21/2017 5:17 AM
と思う
Avatar
です
Avatar
omochimetaru 4/21/2017 5:17 AM
どういうケースがあるかなあ たとえば、ユーザーがペットを持ってる時に
Avatar
えっと、 Simple domain error の話はとりあえずおいておいて、たとえ「値がない」という意味の Optional であったとしても関数ローカルではすぐにハンドリングすべきというのが僕の考えで
Avatar
omochimetaru 4/21/2017 5:18 AM
ペット?を渡す関数に
5:18 AM
ユーザーがヌルの時もペットがヌルとしちゃっていい場合(表示とか
5:18 AM
まあこれは合成といっても?.で済むけど
Avatar
@omochimetaru つまり、やっぱり引数に渡す場合ってことやんね?
Avatar
omochimetaru 4/21/2017 5:19 AM
たしかに?
5:19 AM
何かの引数に渡さない事ってあるか?
Avatar
引数に渡す場合はあり得ると思う。
5:19 AM
nil かどうかで分岐して何か処理する場合。 < 引数に渡さない場合 (edited)
Avatar
omochimetaru 4/21/2017 5:19 AM
なるほど
5:20 AM
確かにそのような分岐を含んだ関数を定義する意味は無さそうだから呼び出し前の分岐になる
Avatar
普通に、ユーザデータが全部入力されて、そしたらButtonが押せるようになるとかも
5:20 AM
Optionalの合成ですが特に何も考えなくて良い例ですね
Avatar
分岐の中にはエラーを発生させるというのもあって、たとえ「値がないかもしれない」 Optional であったとしても、その値が nil の状態で実行するとその処理としてはエラーとして Errorthrow するとかはあり得る。
Avatar
でもこの場合は入力されてないのはErrorとして扱いたいな
5:22 AM
Validationに食わせる時にErrorになるか
Avatar
普通に、ユーザデータが全部入力されて、そしたらButtonが押せるようになるとかも Optionalの合成ですが特に何も考えなくて良い例ですね
このまえのベストプラクティスに書いたとおり、 Optional の合成は必ずしも悪ではないと考えていますが、それにしてもその合成結果を長々と取り回す必要はなくて、 N 個の Optional を合成後すぐに処理すべきですよね?
Avatar
これはそうですね、実際にはValidationでErrorが生成されているので
5:23 AM
T?ではなくT|Errorだ
5:24 AM
本質的にはその定義が良いが、UIKitのせいでT?になってるか
Avatar
そう考えると、合成した場合でもすぐに処理をしたいわけで、引数に渡す目的で Optional 値を生成するという以外に、 Optional のまま値を取り回したいケースってないような気がするんですよね。
5:28 AM
引数に渡す場合でも、一度作っちゃえば後はそれを渡す以外に使わないから、他のコードとは独立してるし。
Avatar
omochimetaru 4/21/2017 5:30 AM
たとえば
Avatar
最悪なのは↓みたいなコード let foo: Foo? = ... ... let bar: Bar? = foo?.bar(...) ... let baz: Baz? = a.b?.c.flatMap { bar?.baz($0) } ... guard let qux = baz.map { Qux($0) } else { ... }
Avatar
omochimetaru 4/21/2017 5:30 AM
var onComplete: (()->Void))?
5:30 AM
みたいなプロパティは
5:30 AM
必要だと思うけど、 これは、 取り回す場合かつ関数に渡さない場合
5:30 AM
じゃないですか?
Avatar
今話してるのはプロパティの話ではなくて、関数やメソッドローカルの話。
5:31 AM
プロパティの「値がないかもしれない」ことを表すために Optional を使うのは当然あり得ると思います。
Avatar
omochimetaru 4/21/2017 5:32 AM
なるほど
Avatar
うーん
5:32 AM
だから、僕の一番最初に言っていたのは
5:32 AM
プロパティの「値がないかもしれない」ことを表すために Optional を使う
5:32 AM
これが本来的な使い方のはずで、それ以外をOptionalで表現されている現状
5:32 AM
ベストプラクティスを議論せざるを得ない、ということになっている
5:33 AM
っていうところですかね
5:33 AM
プロパティの値がないかもしれないを合成した結果、値がないかもしれないは当たり前で
5:33 AM
別にどれが原因だーなんて気にしなくても良いことが多いので
5:33 AM
Errorメッセージ出してくれという要求があってチェックすることはまああるっちゃあるけど
Avatar
omochimetaru 4/21/2017 5:33 AM
@tarunon 文字列の中から文字を探して、見つかればそのindexを返す関数は、返り値はオプショナル?
Avatar
それは意図によるのでは
5:34 AM
あるかもしれない、ならOptionalだし、なければおかしい、ならErrorであるべき
Avatar
omochimetaru 4/21/2017 5:34 AM
じゃあ
5:34 AM
自分がそういう関数を使いたい時
5:34 AM
どっちが用意されていてほしい?
Avatar
オーバーロードが理想
5:34 AM
それは上にも書いてある
Avatar
omochimetaru 4/21/2017 5:34 AM
どちらかを用意して簡易に変換するのは駄目?
Avatar
tryを書けばErrorが出てきて、書かなければOptionalになるみたいな
5:35 AM
用意して変換するならErrorしかない、try?がある以上その選択になるのでは。
Avatar
omochimetaru 4/21/2017 5:35 AM
なるほど。
Avatar
ただそれは面倒臭すぎるし、Error周りはまだ貧弱だから
5:35 AM
今はOptionalに打ち込まれてる、まあそれはしゃーない
Avatar
omochimetaru 4/21/2017 5:35 AM
いまはtry?による変換もめんどくさいよね 左に書くのが嫌だわ
Avatar
そうなんだよなー
Avatar
うん、それはある。
5:36 AM
try(相当のもの) は右にあるべきだった。 (edited)
Avatar
omochimetaru 4/21/2017 5:36 AM
なるほどなあ
Avatar
記号がですね
5:36 AM
implicitly unwrapに!を使ってしまったので
Avatar
omochimetaru 4/21/2017 5:36 AM
わり同意見だなあ
Avatar
try相当が!だったら……
Avatar
それをいうと Int.init(String) とかも面倒で、 string.toInt() みたいに右にある方が使いやすかった。
Avatar
omochimetaru 4/21/2017 5:37 AM
そもそものSDEの話は考え中
Avatar
string => { Int($0) } ですかね・・・。 (edited)
Avatar
omochimetaru 4/21/2017 5:38 AM
エラーがあったことしかわからないエラー っていう概念を前提に考えればコヒーの意見はわかるけど、 それがそもそもおかしい気がする
Avatar
うん、それがおかしいという意見もありえて、 Int.init(String) 等の conversion 系は throws であるべきというのはあり得る。
5:41 AM
一方で、↑の index とか、 first, minDictionary.subscript がエラーなのかどうかは解釈次第だと思う。 @tarunon さんの言うようにオーバーロードも一つの解なのかもしれないけど、それを正しく使い分けられる人は少なそう・・・。
Avatar
そもそもGenericsすら使いこなせない人もいるから
Avatar
omochimetaru 4/21/2017 5:41 AM
でもそういう解釈を記述できる方が
Avatar
まあそれはそれ、使える人にフォーカスしていいとは思う
Avatar
omochimetaru 4/21/2017 5:41 AM
書ける人にとっては
5:41 AM
より安全で読みやすく
5:41 AM
できてよいよね
Avatar
Optional to throws の簡単な方法があればいいんじゃないかな? (edited)
Avatar
omochimetaru 4/21/2017 5:42 AM
変換の失敗系は、与えられた入力と、 なにからなにへの変換が失敗したのか という情報をもっててほしいなー
Avatar
Anyを書いたらコードレビューで殴るように、不適切にOptionalをオーバーロードしたらレビューで殴る
5:42 AM
それができれば僕は満足かな
Avatar
omochimetaru 4/21/2017 5:43 AM
Resultのdematerializeみたいな?
Avatar
前に Erica さんが swift-evolution で Optional 用の ??? 演算子を提案してて
Avatar
omochimetaru 4/21/2017 5:43 AM
あーなんかそれ俺も似たメール読んだ
Avatar
結局 guard でいいでしょということで終わった。
Avatar
omochimetaru 4/21/2017 5:43 AM
!!と二個ビックリだと例外
5:44 AM
後置ビックリね
Avatar
いやー、 !!! より危なそうに見えるから
Avatar
norio_nomura 4/21/2017 5:44 AM
func f() -> String? { return "Optional<String>" } func f() throws -> String { return "String" } let a = try? f() // "String" let b: String? = f() // "Optional<String>" // ^ 型アノテーションがないと error: ambiguous use of 'f()'
Avatar
omochimetaru 4/21/2017 5:45 AM
オプショナル版はfOrNil()でどうか
Avatar
Recoverable なエラーの throws に対して Logic failure 無視の ! より危険そうな !! を割り当てるのは微妙そう。
Avatar
omochimetaru 4/21/2017 5:45 AM
じゃあ!と!!を入れ替えよう
5:45 AM
いまさらンゴね
Avatar
我々が使える記号がたかだか10個前後くらいしかないのが問題
Avatar
norio_nomura 4/21/2017 5:48 AM
オーバーロードは微妙に思える。
Avatar
omochimetaru 4/21/2017 5:49 AM
のむらさん、もしかしてそれ、
5:49 AM
トップレベルだから
5:49 AM
throws空間の中にいるのが
5:49 AM
関係してますかね?
5:50 AM
throwsが付いてない関数の中からの呼び出しなら
5:50 AM
かわったりする?
Avatar
@omochimetaru それでも try は書かないといけないから同じじゃないかな?
Avatar
omochimetaru 4/21/2017 5:50 AM
あー
Avatar
norio_nomura 4/21/2017 5:51 AM
@koher ああ確かに。トップレベルでしか成り立たない。
Avatar
今は言語レベルでサポートされてないから
5:52 AM
class C { func s() throws -> String { return "a" } func s() -> String? { return "b" } } do { let a: String = try C().s() // a let b: String? = C().s() // b } catch { print(error) }
5:52 AM
まあこうなっちゃいますね、どちらも型明記しないとコンパイルエラー
5:53 AM
オーバーロードは言語サポートが乗った上でのifの話です
Avatar
norio_nomura 4/21/2017 5:53 AM
struct S { func f() -> String? { return "Optional<String>" } func f() throws -> String { return "String" } func nonThrow() { let a = try? f() // "String" let b: String? = f() // "Optional<String>" // ^ 型アノテーションがないと error: ambiguous use of 'f()' } } (edited)
Avatar
そもそもこの場合
5:54 AM
オーバーロードしてるString?はtry?した場合と同じ結果で良いので
5:56 AM
構文とセットで用意されれば理想っぽい
Avatar
うーん、片方から片方に簡単に変換できるのがいい気がする。
5:57 AM
やっぱ ??? があればよかったのかなぁ。
Avatar
omochimetaru 4/21/2017 5:57 AM
情報が減る方向しかないからエラーからOptionalが良さそう
5:57 AM
何も情報がないSDEを受け入れるなら逆も可能だが
Avatar
そうなんだけど、 array.first とかが throws なのはきつい気も。
Avatar
omochimetaru 4/21/2017 5:58 AM
そうかなあ、そうでもないんじゃないかなあ。
Avatar
あー、あと今の Swift 的な話なら、プロパティだと throws にできない問題が。
Avatar
Avatar
omochimetaru 4/21/2017 5:58 AM
むしろそれは良い気がする
Avatar
これらの議論は、Error周りの進化が前提ですよ
Avatar
omochimetaru 4/21/2017 5:58 AM
プロパティは失敗しないべき
Avatar
僕としては
Avatar
いや、 first はプロパティなので
5:59 AM
とすると
Avatar
omochimetaru 4/21/2017 5:59 AM
get/setが同じ型でいったりきたりできる、変数みたいな特性で。
5:59 AM
あ〜〜〜〜〜〜
Avatar
プロパティ版は Optional
5:59 AM
メソッド版は throws とか?
5:59 AM
そんなオーバーロードできんだっけ?
Avatar
omochimetaru 4/21/2017 5:59 AM
プロパティも完全に関数のように修正するのがいいのか
6:00 AM
失敗するfirstは関数に変えるのがいいのか
6:00 AM
なやましい
Avatar
いや、余計曖昧になる? array.firstfirst() のメソッドリファレンスかもしれない・・・
Avatar
それがあり得るので今は動かないと思います
Avatar
最初の要素という意味で first というプロパティがあって、最初の値がないから nil ってのはごく自然な解釈だとも思うんだよなぁ。
Avatar
omochimetaru 4/21/2017 6:02 AM
今まではそう思ってたけど最近はトンチの濫用って感じの気持ち
6:03 AM
無いものは取れない
6:03 AM
「無を取得」を思い出した
Avatar
それって stored な Optional プロパティも否定してない? < 無いものは取れない (edited)
Avatar
「問題ありません」
Avatar
omochimetaru 4/21/2017 6:04 AM
それはnilがちゃんと書き込まれてるから
Avatar
あー
Avatar
omochimetaru 4/21/2017 6:04 AM
なんていうのかな
6:04 AM
Arrayに firstっていうフィールドがあるわけじゃない
6:04 AM
nilをストアできているのと
Avatar
亜空間から.noneを生成してるということ
Avatar
omochimetaru 4/21/2017 6:04 AM
擬似的にnilが空間に出現するのが
6:04 AM
違う感じがする
6:04 AM
そうそう!
Avatar
それはカプセル化された内部表現の話じゃないかなぁ。 < フィールドがあるわけじゃない
Avatar
omochimetaru 4/21/2017 6:05 AM
でも、メンタルモデルとしても
6:05 AM
最初の要素という意味で first というプロパティがあって、最初の値がないから nil ってのはごく自然な解釈だとも思うんだよなぁ。
6:05 AM
これは、内部表現としてストレージがあるイメージではないでしょう
Avatar
うーん、まあたしかにそうかも?
Avatar
omochimetaru 4/21/2017 6:05 AM
Arrayっていうデータ構造抽象から
6:05 AM
想像する話しとしてはヒネリを感じる
Avatar
じゃあ、 birthday: Date? を持ってる User 型に対して、 birthYear を取り出す処理はどっち? (edited)
Avatar
omochimetaru 4/21/2017 6:07 AM
「亜空間none」っていう概念良さそう。
Avatar
実際には
6:08 AM
Optional<Optional<Int>>が正しい型ですよねそれ
Avatar
norio_nomura 4/21/2017 6:08 AM
Optionalthrows のオーバーロードが推測でうまく扱えるようになったとして、じゃあそんなメソッドを書くときは実行速度の観点から Optional 版を書いてそれを throws 版でラップする形になる?
Avatar
?のお陰でネストが解消されてるだけ
Avatar
omochimetaru 4/21/2017 6:09 AM
それは Int? 。空としてのnoneはbirhtdayのストレージのところに実在してるから
6:09 AM
そのnoneが素通しで見えてくるだけで
6:09 AM
亜空間ではない
Avatar
あ、birthYearはIntか、ややこしいな
Avatar
内部構造として birthday: Date? を保持しているのか、 birthYear/Month/Date : Int? を保持しているのかはカプセル化された中の話。
6:10 AM
つまり全部 Optional ってことね。 > @omochimetaru (edited)
Avatar
omochimetaru 4/21/2017 6:10 AM
もちろんカプセル化されてるけど、そういう風に素直に捉えられると思う。
6:10 AM
はい。
6:10 AM
じゃあそんなメソッドを書くときは実行速度の観点から Optional 版を書いてそれを throws 版でラップする形になる?
6:10 AM
内部の実装はそのほうが速くて良さそうですね
6:10 AM
nilだったら情報乗っけたエラーを組み立てる、というコード
Avatar
実際にどういう風にデータを保持しているか、動的に生成されているかには関係なく、メンタルモデルとしてそのような値そのものが存在しているように感じられるか、 first のように一段抽象度の高い概念かどうかだと。
Avatar
omochimetaru 4/21/2017 6:11 AM
そういうことです
6:11 AM
メンタルモデルと実装モデルが実際は真逆ってことはありえるけど
6:11 AM
APIとして見せる時に
6:11 AM
どっちのメンタルモデルをユーザーに伝えたいか、できめる。
Avatar
@norio_nomura 恐らく需要の面からもguard let throwsが言語機能として提供される、という感じになると思います
6:14 AM
そういう意味だと???と同じなのか
Avatar
norio_nomura 4/21/2017 6:28 AM
試しに ??? を実装して使ってみるとか
Avatar
struct OptionalError: Error { let file: String let function: String let line: Int } extension Optional { func `throw`(file: String = #file, function: String = #function, line: Int = #line) throws -> Wrapped { guard let wrapped = self else { throw OptionalError(file: file, function: function, line: line) } return wrapped } } オペレーターで十分な情報を取る方法が思いつかなかった (edited)
Avatar
omochimetaru 4/21/2017 6:38 AM
Optionalに生やすならtryじゃなくてthrowメソッドがいいんじゃないか
6:38 AM
throwあれだったらraiseにするとか
Avatar
あーそうね
6:40 AM
で、これがあると
6:41 AM
あかん、ワンライナーで書いたら全部おなじになる、ザコだなー
6:45 AM
ワンライナーはだめだけど、 do { let user = try User( name: name.throw(), age: age.throw(), gender: gender.throw() ) } catch { throw User.Error.decodeFail(error) } こんな感じにしてサクッと特定できる世界観にはなりますね
Avatar
norio_nomura 4/21/2017 6:54 AM
チェインの途中でどこが nil だったか知りたいみたいなのには応えられるのかな (edited)
Avatar
チェインを1行ずつ分解すればまぁ
Avatar
norio_nomura 4/21/2017 6:57 AM
#line で分岐とかゾッとするので、Mirror とか使うといいのかな (edited)
Avatar
うーん、現行の仕様だと、Wrappedとこの3つぐらいしか情報が取れない気がしていて
6:58 AM
Mirrorって自身の変数名とか知れましたっけ?
6:58 AM
無い気がする
6:59 AM
なのでそのレベルの言語サポートが欲しいよねって感じですね
Avatar
norio_nomura 4/21/2017 7:04 AM
ということは ??? とは別物って感じですね。
Avatar
現状は完全な再現は出来ないと思います
7:04 AM
???のプロポーサルちゃんと読んでないから誤解があるかもしれない
Avatar
norio_nomura 4/21/2017 7:05 AM
ああ、それは僕も読んでないやw
7:12 AM
??? は出てこないけど。
Avatar
Error型を作って差し込む感じか
Avatar
first とかも含めて SDE なんてなくして適切なエラー情報込みで throws にすべきだとして、 ??? はいるんですっけ?現実的に first とかが Optional を返すからってこと?
Avatar
現実の問題としてSDEや曖昧なものが全てOptionalに寄せられていて
7:51 AM
Error型が欲しい人はguard使うけどchaining出来ないし、構文レベルでthrowsへの変換があれば満足できるのではないか、ということだと思いました。 (edited)
Avatar
お、↓ならできました。 extension Array { func first() throws -> Element { guard let value = self.first else { throw EmptyError() } return value } } struct EmptyError: Error {} let array = [2, 3, 5] let a = array.first let b = try! array.first() print(a) // Optional(2) print(b) // 2 (edited)
7:58 AM
なんで array.first は ambiguous にならないんだろう?
Avatar
extensionで分離しているところがポイントっぽい?
8:00 AM
あれ、ダメですね、ライブラリかな
Avatar
↑のコード実行できませんでした??
Avatar
いや、自作の型で同じことをやろうとして
Avatar
プロパティとメソッドのオーバーロード?
Avatar
extensionに分離したけどダメだった→ライブラリでコンパイル済みの型なら通るのでは説
8:01 AM
class C { var s: String? { return "a" } } extension C { func s() throws -> String { return "b" } }
8:01 AM
これですね
Avatar
ほんとだ。謎・・・。
Avatar
ファイルが別でも通る可能性あるな
Avatar
同じパッケージだとダメなんですかね?
Avatar
なんかファイルとかパッケージとか
8:03 AM
そのあたりを分けるとコンパイラパワーが増える(?)というのは確認していて
8:03 AM
通らないはずの型が通るようになったりとかままある
Avatar
なるほど・・・
Avatar
逆に通らなくなるのもあったな、この間のとか
Avatar
ひどいw
Avatar
extension Array { var first: Element? { return nil } } 普通にこれが通るので
Avatar
あー
8:16 AM
Arrayさんを拡張してるからですか
Avatar
他モジュールのメソッドとかはオーバーライド可能ってことになっている。
Avatar
モジュールか
Avatar
@rintaro
他モジュールのメソッドとかはオーバーライド可能ってことになっている。
これの影響範囲はオーバーライドした側のモジュール内にとどまるんですか?
8:32 AM
あと、 func first() throws -> Element はオーバーライドじゃなくてオーバーロードですよね?これが同一モジュールだとできないのにモジュール外だとできるのはなんでなんでしょう??
Avatar
試してないですが、 public にしたら他モジュールからも見えると思います。 // ModuleA public extension Array { public var first: Element? { return nil } } // ModuleB import ModuleA let a = [1,2,3].first とかしたらambigousになると予想。 (edited)
8:35 AM
オーバーライド でも オーバーロード でも モジュール外の「名前」との衝突は一切考慮されないっていう実装ですね。
Avatar
静的ディスパッチはいいとして、動的ディスパッチだと仮想関数テーブルを拡張しないとできないような??
Avatar
witness-table、確かライブラリ超えて拡張できなかった気がする
8:36 AM
UIViewContorllerにXCTestだけprotocol書き換えて、Environment変更しようとしたら失敗したw
Avatar
試してないですが
試しました。ambigous にならずに ModuleA 実装が優先されましたw
Avatar
import ModuleA してなければ元の first が実行されるんですよね? (edited)
Avatar
// ModuleA public extension Array { public var first: Element? { return nil } } // ModuleB public extension Array { public var first: Element? { return self[0] } } // main import ModuleA import ModuleB let a = [1,2,3].first さすがにこれはambigous (edited)
8:48 AM
import ModuleA してなければ元の first が実行されるんですよね?
じゃなかったら大変
Avatar
そこが import でコントロールできるんだったら、 extension メソッドにプレフィックスつけたりネームスペース切ったりするのが流行ってたけど不要?
8:49 AM
両方 import したくて衝突したときに、どっちか指定する方法がないのか・・・。
8:50 AM
foo.bar にせずに foo.rx_bar とか foo.rx.bar みたいなやつ。
Avatar
importした上で元のものを使う手段が無さそう?
Avatar
!!! // ModuleA public extension Array { public var first: Element? { return nil } } // ModuleB import ModuleA public extension Array { public var first: Element? { return self[0] } } // main import ModuleB let a = [1,2,3].first これでambigous。これはまずいんじゃ・・・
8:53 AM
// ModuleA public extension Array { public var first: Element? { return nil } } // ModuleB import ModuleA // main import ModuleB let a = [1,2,3].first これはnil になる。まずすぎる (edited)
Avatar
おお、それはまずそうですね。。。 < ambigous (edited)
8:55 AM
ここは @rintaro さんの出番では?👍
Avatar
バグリポート上げるくらいしかできませんw
8:58 AM
Avatar
っぽいですね。
9:00 AM
コメントw
Old, old bug. 🙂
Avatar
struct Matrix { var elem: [[Float]] } について 可 let a: [[Float]] = [[1, 2], [1.0/2 1.0/3]] _ = Matrix(elem: a) 不可 _ = Matrix(elem: [[1, 2], [1.0/2 1.0/3]])
5:24 AM
なんとかならんのでしょうか
Avatar
_ = Matrix(elem: [[1.0, 2.0], [1.0/2.0 1.0/3.0]]) これもだめですかね
Avatar
SwiftSandboxで警告出てましたねそこ
5:25 AM
それでもだめっぽいです
5:26 AM
ERROR at line 9, col 31: cannot convert value of type 'Double' to expected element type 'Float' _ = Matrix(elem: [[0, 1], [1.0/2.0, 1.0/3.0]]) ~~~^~~~ Float( )
Avatar
nんー
Avatar
XCodeの方で何故かDouble/Intの警告出てなかったです
Avatar
struct Matrix { var elem: [[Float]] } _ = Matrix(elem: [[1.0, 2.0], [1.0/2.0, 1.0/3.0]])
5:27 AM
これで通りましたね、Sandbox
5:27 AM
Xcodeはインスコ中なので動かせない
Avatar
omochimetaru 4/22/2017 5:29 AM
なんかチャンネルふえてるな
Avatar
あれ?同じ文でこちらでは通らないですね…… (edited)
Avatar
Xcodeは通らない
Avatar
僕の方はSwiftSandboxでも通らなかったです
Avatar
おっと…
5:49 AM
Sandbox、3.0だった。
5:49 AM
3.1は通らないですね
Avatar
昔は行けてたとなるとバグの可能性ありですかね?
Avatar
3.0から3.1で型周りで変更結構あるので、間違いなくそれらの影響何だと思いますが、
5:54 AM
バグかと言われるとどっちだろう、という気がする
5:55 AM
でも_ = Matrix(elem: [[1.0, 2.0], [1.0/2.0, 1.0/3.0]]) これが通らないのはバグな気がする
Avatar
一度[[Float]]に代入するところができますからねぇ
Avatar
6:30 AM
/// - Parameters: /// - optional: An optional value. /// - defaultValue: A value to use as a default. `defaultValue` is the same /// type as the `Wrapped` type of `optional`. public func ??<T>(optional: T?, defaultValue: @autoclosure () throws -> T) rethrows -> T
6:31 AM
昨日の話題
6:31 AM
??オペレーター、既に???とのオーバーロードですねこれ
Avatar
omochimetaru 4/22/2017 6:31 AM
intOpt ?? throw HogeError() こう書けるって事?
Avatar
intOpt ?? HogeError() (edited)
6:32 AM
これでおkす
Avatar
omochimetaru 4/22/2017 6:33 AM
それは ?? の右側のオートクロージャーの返り値の型が () -> Tじゃなくて () -> HogeErrorになってコンパイルエラーでは
Avatar
いや、通る
6:36 AM
public func parse(data: Data) throws -> Any { return UIImage(data: data) ?? Error.imageNotFound }
6:36 AM
あーー
6:36 AM
Anyのせいか
Avatar
_ = Matrix(elem: [[1, 2], [1.0/2 1.0/3]]) は master で -Xfrontend -propagate-constraints ていう experimental なフラグ付けたら通りました。
Avatar
https://github.com/apple/swift/pulls?utf8=%E2%9C%93&q=is%3Apr%20is%3Aclosed%20constraint%20propagation%20 このあたりかな。そろそろ enabled by default になりそうな感じなので Swift4 では直ってるとおもわれます。
swift - The Swift Programming Language
Avatar
なるほど。情報ありがとうございます。
Avatar
norio_nomura 4/22/2017 1:14 PM
ほう enum Error: Swift.Error { case unavailable } let dictionary: [AnyHashable:Any] = [:] do { _ = try dictionary["unavailable"] ?? { throw Error.unavailable }() } catch { print(error) // "unavailable\n" } (edited)
Avatar
extension Error { func `throw`<T>() throws -> T { throw self } } struct MyError : Error {} let str = "hoge" do { try print(Int(str) ?? MyError().throw()) } catch { print(error) } いやーw
Avatar
今日一日???導入してコード書いてみたけど結構快適だった
3:42 PM
Error型にthrowでthrows->Tになるの良いですねこれ
Avatar
norio_nomura 4/22/2017 4:25 PM
そうか -> T にしないとダメですね。 try dictionary["unavailable"] ?? { throw Error.unavailable }() みたいに、期待される型が Any だとエラーにならない。
Avatar
norio_nomura 4/23/2017 2:32 PM
extension Swift.Error { func `throw`<T>() throws -> T { throw self } } extension Optional { func `else`<T: Swift.Error>(_ error: @autoclosure () -> T) throws -> Optional { guard case .some = self else { throw error() } return self } func unwrap<T: Swift.Error>(or error: @autoclosure () -> T) throws -> Wrapped { guard case let .some(wrapped) = self else { throw error() } return wrapped } enum Error: Swift.Error { case isNone(String) } func `else`(_ message: @autoclosure () -> String) throws -> Optional { guard case .some = self else { throw Error.isNone(message()) } return self } func unwrap(or message: @autoclosure () -> String) throws -> Wrapped { guard case let .some(wrapped) = self else { throw Error.isNone(message()) } return wrapped } } enum Error: Swift.Error { case unavailable, notInt } let dictionary: [AnyHashable: Any] = ["available": 1] do { let a = try (dictionary["available"] ?? Error.unavailable.throw()) as? Int ?? Error.notInt.throw() let b = try dictionary["available"].unwrap(or: Error.unavailable) as? Int ?? Error.notInt.throw() let c = try dictionary["available"].map({ try ($0 as? Int).unwrap(or: Error.notInt) }).unwrap(or: Error.unavailable) let d = try dictionary["available"].map({ try $0 as? Int ?? Error.notInt.throw() }) ?? Error.unavailable.throw() let e = try dictionary["available"].else(Error.unavailable).map({ $0 as? Int }).unwrap(or: Error.notInt) let f = try dictionary["available"].else("\"available\" does not exists").map({ $0 as? Int}).unwrap(or: "Fail converting to Int") } catch { print(error) } 🤔
Avatar
https://github.com/apple/swift/pull/8939 associatedtypewhere を付けられるようになって、 Sequence.Iterator.ElementSequence.Element になるのはうれしいんだけど、 https://github.com/airspeedswift/swift/blob/8869509174859ca30eeca37001463b3b46e9f7fc/stdlib/public/core/Sequence.swift#L330-L331 associatedtype Element associatedtype Iterator : IteratorProtocol where Iterator.Element == Element こう宣言しなければいけないのは直感的ではないなー。 associatedtype Iterator : IteratorProtocol typealias Element = Iterator.Element で実現できなかった理由はなんなんだろう。
Adds an associatedtype Element to Sequence, then constrains Iterator.Element to match it.
swift - The Swift Programming Language
Avatar
protocolの型をtypeliasで束縛するの、3.1から使えなくなっていて
4:22 AM
ネストしたGenerics型とかの兼ね合いかな~と想像してるんですが
Avatar
直感的ではないなー。
そうでもない気がしてきた。 Element を起点に考えれば当然の帰結か。
Avatar
omochimetaru 4/24/2017 4:24 AM
whereって条件って感じだけどなんでwhereなんだろ?
Avatar
うーん、 Sequence はあくまで Iterator を生成するものなんだから、やっぱ Iterator 起点なのが直感的な気が。
4:24 AM
↓ができるならそっちの方がいい気がする。 associatedtype Iterator : IteratorProtocol typealias Element = Iterator.Element (edited)
Avatar
associatedtype Iterator : IteratorProtocol associatedtype Element where Element == Iterator.Element もできるのかな? (edited)
Avatar
お、できそう
4:26 AM
protocolにtypealias書けないのはまあなんとなく理解できていて
Avatar
それって自由度が何もないのに associatedtype って変じゃないですか?
Avatar
なのでassociatedtypeで実現しようとすると、=だとデフォルト実装になって書き換えれてしまう。
Avatar
omochimetaru 4/24/2017 4:27 AM
typealiasだと意味が曖昧になるケースが出るってことかな
4:27 AM
既存の用法とのカチ合いで
Avatar
@omochimetaru typealias Element = Iterator.Element って既存用法と何か違うっけ?
Avatar
omochimetaru 4/24/2017 4:28 AM
それって、
4:28 AM
もし、Sequenceに親プロトコルがあって
4:28 AM
その親プロトコルがElementっていうassociated typeを持っている場合に
4:29 AM
それを確定させるっていう意味になるのか
Avatar
そうそう
4:29 AM
そういう問題が発生し得るので
Avatar
omochimetaru 4/24/2017 4:29 AM
Sequence自体のネームスペースにElementっていうシンボルであるassociatedtypeを定義するのか
4:29 AM
あいまいにならない?
Avatar
protocolではtypealiasは書けない、としていたほうが
Avatar
omochimetaru 4/24/2017 4:29 AM
ということを思い浮かんだ 多分たるのんもいっしょ
Avatar
一貫性が持てそう
Avatar
omochimetaru 4/24/2017 4:29 AM
それか、classでのその用法と紛らわしい(厳密には衝突はしないけど紛らわしいから避けたい系 (edited)
4:30 AM
本当に今の仕様でぶつかるかは自信無い
Avatar
typealiasprotocol に復活したときに typealias Element = Iterator.Element いけるじゃん!みたいなので騒いでいたのは事実で https://github.com/apple/swift/pull/1610
Split up parsing of typealias and associatedtype, including dropping a now unneeded ParseDeclOptions flag. Then made typealias in a protocol actually valid, which works great except that you can't ...
Avatar
あー、 associatedtype を縛る方は typealias のままだったのか。書くことないから忘れてた。 https://twitter.com/chriseidhof/status/700305519328755712
In Swift 2.2, when using associatedtype, you still have to use typealias to declare an associated type instance:
🙄 1
4:36 AM
これ↑みたいに、縛る方は associatedtype Foo = Bar の方が良くないのかな?何かダメな理由あるっけ?
Avatar
protocolだとassociatedtype Foo=Bar は束縛じゃなくてデフォルト実装なんですよ
4:37 AM
上書き可能
Avatar
@chriseidhof That's probably a common enough mistake to be worth a fixit. Got time to file a bug?
Avatar
マジか
Avatar
associatedtype のデフォルト実装ってどんなときに使うんですか?
4:39 AM
@tarunon いや、 2.2 の頃の話なので、その後どういう話になったのかが気になります。
Avatar
ある型のassociatedtypeが一般的に期待される型があり得る場合ですね、 stdlibでもそこら中にありますよ
Avatar
Joe Groff のツイートは エラーメッセージに fix-it つけてわかりやすいようにすべき。って話ですね。
4:42 AM
束縛を associatedtype でやるっていう話ではない。
Avatar
おお、そうなんですね。勘違いしてました。
4:45 AM
@tarunon そうなんですね・・・。 associatedtype って大体↓みたいな感じで暗黙的に解決されちゃって明示的に指定することがないんで、デフォルト実装がありがたいイメージがありませんでした。 protocol Foo { associatedtype Bar func bar() -> Bar } struct Baz: Foo { func bar() -> Int { return 42 } } (edited)
Avatar
えーと
4:48 AM
一番嬉しいのはですね
4:49 AM
protocol Foo { associatedtype Bar = Void func bar() -> Bar } extension Foo where Bar == Void { func bar() -> Bar {} } struct Baz: Foo { // 書かなくてもBar==Voidが推論される }
4:49 AM
このパターンですね
4:49 AM
書けば推論されるのはその通りなんですが、デフォルト実装を持っている場合は、書かなくて推論されることが嬉しい場合が結構ある
Avatar
omochimetaru 4/24/2017 4:50 AM
C++だとコンテナのメモリ管理をAllocatorっていう型パラに切っておいてデフォルトではmalloc/freeのやつで埋めとくみたいなのありますね
Avatar
@tarunon なるほど。
Avatar
omochimetaru 4/24/2017 4:52 AM
アップルの人もこのPRについてツイートしてた (edited)
Soon you'll be able to say 'T.Element == ...' instead of 'T.Iterator.Element == ...' in your where clauses: https://t.co/hjXqfTpEtY
Avatar
実際にはIterator.Element==Elementでしかないのに、Elementを分けて書いたのが呪いの始まりなのでは?という気もしている
4:53 AM
横着してはいけなかった
Avatar
omochimetaru 4/24/2017 4:56 AM
横着ではなくない?イテレーターはそれ単体で綺麗に独立してるよ (edited)
Avatar
いや
4:56 AM
SequenceがElementを持ってるのはそれはそうだけど
4:57 AM
言語機能としてElement == Iterator.ElementをSequence単体で実現するすべがない状態で
4:57 AM
ElementとIteratorを定義してしまったのはまずかったのでは、という視点 (edited)
Avatar
うーん、 SequenceElement を持ってない気がします。 SequenceIteratorFactory にすぎない気が。
Avatar
omochimetaru 4/24/2017 5:00 AM
あーー
Avatar
Java の Iterable<E>E を指定して Iterator<E> を返すけど、 Swift の SequenceIterator の種類まで決定するという意味で違いがありそうな。
Avatar
omochimetaru 4/24/2017 5:01 AM
シーケンスにおけるエレメントって、ラムダ計算の自由変数なのかな
5:02 AM
プログラミングだと束縛変数しか基本出てこないからシーケンスに暗黙にTが引数として存在するような気分になるけど
5:04 AM
>ラムダ式は自由変数( λ によって束縛されていない変数)を含むこともできる。例えば、入力に関係なく常に y を返す関数を表す式 λx. y において、変数 y は自由変数である。
5:04 AM
うまくいえない・・・
Avatar
この変更でこれが通らなくなりそうです。 struct AlwaysOneIterator : IteratorProtocol { func next() -> Int? { return 1 } } struct AlwaysOneSequence : Sequence { func makeIterator() -> AlwaysOneIterator { return AlwaysOneIterator() } } (edited)
5:16 AM
associatedtype Element が解決できないみたい。
Avatar
typealias Element = Intを書かないといけないのかな
5:22 AM
associatedtype Element associatedtype Iterator : IteratorProtocol where Iterator.Element == Element // ↑これだとElementをIteratorから推論できない associatedtype Iterator : IteratorProtocol associatedtype Element = Iterator.Element where Element == Iterator.Element // ↑この書き方ができるなら、ElementはIteratorから推論可能。
5:23 AM
こういうことかな
5:23 AM
後者のほうが良さそう
Avatar
どっちでも違いなさそうですね。手元のが 3,4日 前のmasterなので、今 pull し直して確認中です。 (edited)
Avatar
むむぅ。件のPR適用してビルドした状態で、これは通らないのに、 protocol MySequence { //associatedtype Iterator : IteratorProtocol //associatedtype Element where Element == Iterator.Element associatedtype Element associatedtype Iterator: IteratorProtocol where Iterator.Element == Element func makeIterator() -> Iterator } struct AlwaysOneIterator : IteratorProtocol { func next() -> Int? { return 1 } } struct AlwaysOneSequence : MySequence { func makeIterator() -> AlwaysOneIterator { return AlwaysOneIterator() } } struct AlwaysOneSequence : MySequencestruct AlwaysOneSequence : Sequence に変えると通るようになる。
Avatar
えw
5:41 AM
悪魔の加護かな
Avatar
今、社内 Slack で Scala の拡張 for 式について話してたんですが、 @tarunon さんあたりは Swift にも Higher kinded type と Haskell の do 記法的なものがほしい派ですか?
Avatar
Haskell doについては
Avatar
何度も Core Team に否定されているので実現は難しそうですが・・・。
Avatar
既存のdo構文が、asyncでも動くようになれば
7:33 AM
殆どの要求は満たせそう
Avatar
モナドの用途はほとんどが ResultPromsie で、 throwsasync があれば <-tryawait で代用できるから、それで大体 OK ってことですか?
Avatar
はい
7:34 AM
用途は殆どが、というとちょっと乱暴だな
7:35 AM
ただ、多くの問題はResultとPromise、これらの複合が発生した場合に
Avatar
Rx 使ってると Opservable もあるかと思いましたが、あれは色んなオペレータ組み合わせて使うし flatMap だけできてもって感じですか?
Avatar
ネストがひどいことになる、それさえdo構文で解決できれば
7:35 AM
いえ、どちらかと言えば
7:36 AM
あー
7:36 AM
まあObservableはそうですね、まだちゃんと思考してないんですが
7:37 AM
組み合わせでオペレーター使いざるを得ないからdoの中で解決するのは出来ないのでは?という気がしています
Avatar
なるほどー。
Avatar
asyncがあれば、うまいことやれば、Observableのかなりの需要を食えるのでは?というのもなんとなく考えてます
7:39 AM
ちょっとちゃんと考えてないのではっきり言えないですが
Avatar
値型のおかげでイミュータブルプログラミングの出番も少ないし、 IO モナドとかもいらないし、 Result, Promise あたりがやっぱメインですよね。
7:40 AM
Observableのかなりの需要を食えるのでは?
これ思います。実は Promise で済むケースが多そう。
Avatar
Higher kinded type
こいつは欲しいんですよねぇ。これがないせいで、型消し使うシチュエーションが多すぎる
7:40 AM
Any<Sequence where>なんちゃらも、この問題を解決出来る…わけではないですよね、恐らくパフォーマンスに影響が出る
Avatar
Higher kinded typeはほしいですねぇ。 Self はあるのに Higher kinded type はないのと、 associatedtype があるとプロトコル型変数作れないのに associatedtype がなければ作れるのは何か中途半端感を感じます。
Avatar
@rintaro 今のmaster, SequenceにElementは定義されてないように見えます。 https://github.com/apple/swift/blob/master/stdlib/public/core/Sequence.swift
swift - The Swift Programming Language
Avatar
swift - The Swift Programming Language
Avatar
omochimetaru 4/24/2017 8:32 AM
> Observableのかなりの需要を食えるのでは? これ思います。実は Promise で済むケースが多そう。
これ僕も思って本気でライブラリ作ってユースケース洗い出してってやっていたら
(edited)
8:33 AM
やっぱりObservableが要るって結論になった。 (edited)
Avatar
ダメか…
8:34 AM
Streamの合成がasync throws funcの合成と等価じゃないから
Avatar
omochimetaru 4/24/2017 8:34 AM
Promiseだけじゃなくて、EventEmitterとVariableは欲しいんですよね
8:34 AM
で、そいつらがObservableとして同じ基盤に乗ってないと、相互接続ができないし、
Avatar
ふーむ
Avatar
omochimetaru 4/24/2017 8:35 AM
たとえば、
8:35 AM
マウスクリックのイベントを受けて、URLリクエストを発火する
8:35 AM
みたいなパターンを考えた時点で
8:36 AM
EventEmitterとPromiseが相互にflatMapできないと
8:36 AM
接続点でボイラープレートみたいなのがワチャワチャでてきちゃうし
Avatar
結局記述量変わらなくなりますよね
Avatar
omochimetaru 4/24/2017 8:37 AM
EventEmitterだとmapしてEE <T> から EE<U>つくったとき on の連鎖どうなんのとか
8:37 AM
・これもできるならあれもできないとおかしい っていうのがどんどんでてきて
8:37 AM
それってRx.Observableの再実装が必要では?みたいになってしまった
8:38 AM
Everything is streamみたいに突き抜けたところまでいかなくても
8:39 AM
EventEmitter, Promiseの2つを使うより素朴にObservable使ったほうが同じことをよりスッキリかけちゃうなあ
8:39 AM
という感じですね
8:40 AM
最近SingleもRxSwiftに入ったから「1個」という観点での型表明も強化されたし
8:40 AM
MaybeとCompletableがある分、Promiseより強いんでは?とも思う
Avatar
うーん、イベント発火する部分がシンプルなfunctionの世界になれば合成はどうにかなるかなぁと思ってたけど
Avatar
omochimetaru 4/24/2017 8:43 AM
それって結局Promiseからはみ出すのと
Avatar
やっぱり無理か、こういうのは書かないと真に理解出来ない。
Avatar
omochimetaru 4/24/2017 8:43 AM
Promiseの、値一個だけっていう概念が邪魔になる
Avatar
連続させるのがいちいち手間で、結局allに包ませることになるのが辛いです
Avatar
omochimetaru 4/24/2017 8:44 AM
Promiseだとキャンセルのしくみも自分で作り込まないといけないんで
8:45 AM
DisposeBagで全部片付けてしまえ〜 みたいな段階にいくまでの積み木が結構たいへん
Avatar
DisposeBagというか
8:52 AM
Completedの概念が非常に優れているんですよね
8:52 AM
最近理解したの、Observableが持つクロージャにリファレンスカウントを増やさせることで
8:53 AM
任意の参照可能なオブジェクトにフィールドを持たせる必要すら無かった。
8:53 AM
CompletedすればObservableが破棄されるのでメモリリークも無い。
Avatar
omochimetaru 4/24/2017 8:53 AM
ん、でもそれはObservableがsubscriberを登録できるっていう仕組み経由でひっかけてるって話ですよね?
Avatar
そうですね
8:53 AM
最終的にはDisposeBagが持っています
Avatar
大域でいらないオブジェクトはオブザーバブル繋ぐメソッドのスコープに置くとかはよくやりますね
Avatar
omochimetaru 4/24/2017 8:54 AM
元をたどればsubscriber の配列をもっている事が、そのカスタマイズ性を提供してる
Avatar
@tarunon さっき話してた、letで自己再帰するやつ、面白いのあるから書いた https://gist.github.com/omochi/945fbf77566ab507dd95783f2f64deae (edited)
😎 1
Avatar
オッ
12:20 PM
Prologみたいだ
Avatar
ML系では実際まさにこれな rec って言語機能があるとかないとか、そんな話を資料で読んだ
12:23 PM
面白いところだけ転載しとこう // let + クロージャー (と小道具)で再帰 let fib3 = rec { (fib: (Int) -> Int, x: Int) -> Int in switch (x) { case 0: return 0 case 1: return 1 default: return fib(x - 2) + fib(x - 1) } }
12:27 PM
38:40 くらいから
Avatar
不動点コンビネータってやつですね
Avatar
@ukitaka あ〜これがそれですね(いつも細かい話は毎回忘れてしまいます
Avatar
この当時ってネストしたローカル関数も再帰できなかった記憶があります。
Avatar
omochimetaru 4/25/2017 1:51 AM
https://developer.apple.com/videos/play/wwdc2014/404/ これを思い出した。 38:40 くらいから
見てきた。メモ化高階関数も対象の関数が自己再帰を含むから同じ形になるんですね。
Avatar
norio_nomura 4/25/2017 4:10 AM
swift-3.1.1-RELEASE 何が変わったのか
Avatar
https://github.com/apple/swift/compare/swift-3.1-RELEASE...swift-3.1.1-RELEASE deinit まわりのメモリ問題とか入っているっぽい。
swift - The Swift Programming Language
Avatar
norio_nomura 4/25/2017 4:18 AM
Xcode 8.3.2がSwift 3.1.1らしいから、Xcodeでも直ってるってことか。
Avatar
Xcode 8.3.2 はまだ Swift3.1 だと思いますが、どうなんだろう。
Avatar
でも最適化の時のバグは治ってましたね
Avatar
norio_nomura 4/25/2017 4:22 AM
https://swift.org/download/#releases には "*Swift 3.1.1 is available as part of Xcode 8.3.2." とあります (edited)
Swift is a general-purpose programming language built using a modern approach to safety, performance, and software design patterns.
Avatar
NSErrorキャストでクラッシュするのと、2重ループのメモリリーク
Avatar
$ swift -version Apple Swift version 3.1 (swiftlang-802.0.53 clang-802.0.42) Target: x86_64-apple-macosx10.9 表記だけの問題?
Avatar
動作的には明らかに 3.1.1 なんだけど #if swift(>=3.1.1) print("3.1.1") #endif これが true にならないのとか、ほんとにイケてない。
Avatar
omochimetaru 4/25/2017 5:15 AM
中身は3.1.1だけど表示だけ3.1だからみたいな
Avatar
中身と表示一致してないのダメでは
Avatar
main.swift でトップレベルで guard した場合って else ブロックに何書けばいいんでしょうか? fatalError とかでなく正常終了したい場合。 return はできないようです。 "swift top level guard exit" とかで軽くググってみたんですがよくわからず・・・。
Avatar
abort() とか?
10:00 AM
Neverなメソッドなら書けるはず
Avatar
@koher さっきわかんないって言ったけどそういえばこんな例はあります https://github.com/apple/swift-package-manager/blob/master/Sources/POSIX/exit.swift
swift-package-manager - The Package Manager for the Swift Programming Language
Avatar
exit(1) abort() fatalError() らへんが使えると思うけど違いは分からない
10:01 AM
正常終了なら exit(0) ?
Avatar
posix的にはそう stdlib.hの EXIT_SUCCESSを使うのがお行儀が良い
Avatar
MAIN: do { // ... guard ... else { break MAIN } // ... }
Avatar
育ちが悪いからexit(0)しちゃう
Avatar
でもCの作法を呼べるってだけでSwiftのやりかたかといわれると微妙
Avatar
うーん、たしかに exit 呼べばいい気がしてきました。 exit ってちゃんと Never になってるんですね。
Avatar
@rintaro ぼくもよく func main() { } main() ってやってます
10:03 AM
@koher C向けのアトリビュートが良い感じに検出されてるっぽい
Avatar
素直に func に突っ込んじゃうのが楽ですよね。
Avatar
__attribute(noreturn)__ だったっけ。 (edited)
10:04 AM
C向けっていうかclang/gcc
Avatar
へえー
Avatar
@hiragram さん、ありがとうございます。
Avatar
いえいえ
Avatar
func main() { } main() ↑これは main() のコールが C とかより冗長で負けた感が・・・。 (edited)
Avatar
トップレベルなんて信じてない
10:05 AM
負けた感はある
10:06 AM
(僕はrubyでもよくdef mainからはじめてる
Avatar
コマンドラインのスクリプト書いてて正常終了したいんだから普通に exit(0) が素直だった。 (edited)
10:07 AM
Never になってるの素晴らしい。
Avatar
exit(EXIT_SUCCESS) も呼べると思います。
Avatar
お、いけました!ありがとうございます。 < EXIT_SUCCESS
Avatar
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
Avatar
ふと気になったんですが、Optionalなクロージャを引数に作ると、@escaping 書けなくなりますよね。どういう扱いなんだろう。 func hoge(_ arg: (() -> ())?) {...} // ←みたいなことをした時に、argがエスケープされるとしてもそれを明記できない。
Avatar
それは
Avatar
Optionalがキャプチャするから常にescapingかな
Avatar
自動 @escaping 扱いです。
Avatar
ただのプロパティだから
10:44 AM
必然的に常にエスケープする
Avatar
ここに書き込んだ瞬間に気がついた
Avatar
Optinalはただの型だから。
Avatar
Foo<() -> ()> と同じですしね。
10:46 AM
? の記号は便利だけど、こういう混乱を招きやすい・・・。
Avatar
そうすると
10:48 AM
引数のクロージャを省略可能にしようとすると
10:48 AM
最適化で不利になる?
Avatar
可能性はありそう。
10:50 AM
Swift コンパイラがすごく賢ければ
10:50 AM
そこも考慮してインライン化してくれたりするかもだけど。
Avatar
今度試してみよ
Avatar
もしかしたら
10:51 AM
func hoge(_ arg: (() -> ())?=nil) {...} func hoge(_ arg: (() -> ())={ _ in }) {...} 後者のほうが強いのかもしれない (edited)
Avatar
インライン化されて完全に消える事を考えるとありえるね
Avatar
呼び出しコストかかるかと思いましたが消えるんですかねこれ
Avatar
llvmir出してみて
10:53 AM
たらわかる
Avatar
SE-0171 ができるようになったらこんな感じかな? let strings = ["a:2", "b:3", "c:5"] let dictionary = strings.reduce(into: [:]) { (r: inout [String: Int], e) in e.components(separatedBy: ":") => { r[$0[0]] = Int($0[1])! } } // ["a": 2, "b": 3, "c": 5] (edited)
10:59 AM
=> は前話してた Kotlin の let 代わり。
Avatar
できそう
Avatar
norio_nomura 4/25/2017 2:59 PM
e.components(separatedBy: ":") => { r[$0[0]] = Int($0[1])! } これの型はどこで決まるの?
Avatar
rから推論できそう
Avatar
omochimetaru 4/25/2017 3:26 PM
=>は中置オペレータで式の評価結果はクロージャの評価結果そのもの
3:26 PM
あれ?Swiftって代入文の評価結果ってVoidじゃなかったっけ
3:26 PM
右辺値だったっけ。
Avatar
あー
Avatar
vogdですね
3:27 PM
void
Avatar
omochimetaru 4/25/2017 3:27 PM
voidか。あ、でもいいのか。 inout版のreduceは
3:27 PM
reducerは返り値voidで、inoutで固定なのか。
3:28 PM
とりあえず、 => の定義 https://github.com/koher/swiflet
swiflet - Provides => like let in Kotlin for Swift
Avatar
kotlin let知ってないと目がぐるぐるする
3:29 PM
🌀
🙃 1
Avatar
inoutじゃないけどvoidを返す場合を考えたけどそんなのなかった
Avatar
なるほど infix operator => public func =><T, U>(lhs: T, rhs: (T) throws -> U) rethrows -> U { return try rhs(lhs) } extension Sequence { func reduce<A>(into initial: A, _ combine: (inout A, Iterator.Element) -> ()) -> A { var result = initial for element in self { combine(&result, element) } return result } } let strings = ["a:2", "b:3", "c:5"] let dictionary = strings.reduce(into: [:]) { (r: inout [Int: String], e) in e.components(separatedBy: ":") => { r[$0[0]] = Int($0[1])! } } error: cannot subscript a value of incorrect or ambiguous type e.components(separatedBy: ":") => { r[$0[0]] = Int($0[1])! } ^~ 型推測しきれないぽい。 (edited)
Avatar
呼び出し側にinto: ラベルが必要です (edited)
Avatar
into: 足してもエラーは変わらず。
Avatar
let dictionary = strings.reduce(into: [:]) { (r: inout [String: Int], e) in e.components(separatedBy: ":") => { r[$0[0]] = Int($0[1])! } } で通りました。[Int: String] じゃなくて [String: Int] でしたね。
Avatar
おお、追加のアノテーションなしでいけるんですね。
Avatar
omochimetaru 4/26/2017 1:06 AM
[Int: String]になってるの全く気が付かなかった
Avatar
あらら💦元のコード修正しました。
1:33 AM
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
1:34 AM
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
Avatar
keyPath acceptからグッと作りやすくなったと思ってたら標準で用意されるのかー
Avatar
4 月上旬の駆け込み Review 祭りの結果が続々と Accept されてる。
Avatar
omochimetaru 4/26/2017 1:37 AM
166,167ってまだ読んでないんですけどざっくりどんな話ですか?
1:37 AM
言語機能としてシリアライズが付く?
Avatar
そう、で、json周りも標準採用
Avatar
omochimetaru 4/26/2017 1:38 AM
JSONもつくのね。珍しいな。
1:39 AM
そうなると細かいところがいろいろ気になるけどそれについては自分で読んでみます。ありがとう。
Avatar
任意のEncoder,Decoderプロトコルを定義出来るのだけど、JSONに関しては標準的な構造が用意されてる、と言うように見える
1:41 AM
plistもあるな
Avatar
(たぶん)3.1 で closure の inout まわりの inference が改善されてるんですね。 let ary1 = [1,2,3] let ary2 = ary1.reduce(into: []) { $0.append($1 + 12) } 非常によい。
✌ 1
2:11 AM
let dictionary = strings.reduce(into: [:]) { r, e in e.components(separatedBy: ":") => { r[$0[0]] = Int($0[1])! } } これも通った 😆
2:14 AM
あー、これだと dictionary: [AnyHashable: Int] になっちゃうのか。
Avatar
omochimetaru 4/26/2017 2:15 AM
$0が Array<String> 確定するから、$0[0]がStringになって String: Intになりそうだけど、保守的な推論になっちゃう? (edited)
Avatar
うそでした。 let dictionary = strings.reduce(into: [:]) { r, e in e.components(separatedBy: ":") => { r[$0[0]] = Int($0[1])! } } だと [String: Int]let dictionary = strings.reduce(into: [:]) { r, e in print(e) e.components(separatedBy: ":") => { r[$0[0]] = Int($0[1])! } } だと [AnyHashable: Int] single expression か否かで変わってくるみたいです。
Avatar
omochimetaru 4/26/2017 2:18 AM
print(e)で変わっちゃうんですか・・・微妙ですね。
Avatar
// If all properties are Codable, protocol implementation is automatically generated by the compiler: これ微妙な気が。
2:27 AM
Codable だった型にプロパティ足したときに気づかずに Codable でなくなってしまう危険があるのでは?
Avatar
omochimetaru 4/26/2017 2:28 AM
それはコンパイルエラーになるんでは?
Avatar
もし明示的に Codable をつけていれば、プロパティを足した瞬間に気付ける。 (edited)
Avatar
omochimetaru 4/26/2017 2:28 AM
使ってるところでCodableが期待されていてそれと衝突する
Avatar
使っているのが外部のモジュールだったら? (edited)
Avatar
omochimetaru 4/26/2017 2:29 AM
外部のモジュールがオブジェクトを受け取るところでCodableとして引数に受けてるから同じでは?
Avatar
ライブラリ AFoo が元々 Codable だったのを、まったく関係ない第三者が使っていて、ある日 Foo が突然 Codable でなくなるとかあり得る。
2:30 AM
しかも、最初から A の作者は FooCodable にするつもりはなかった、とか。
Avatar
omochimetaru 4/26/2017 2:30 AM
ライブラリAのFooにどうやってフィールドを追加するんですか?
Avatar
: Codable 宣言してなかったら Codable にならないんじゃないですか?
Avatar
え?そうなんですか?
Avatar
omochimetaru 4/26/2017 2:31 AM
Aの作者がFooをそうと意識せずにCodableにしている場合か。Aの内部ではCodableを使ってないなら、たしかに困る (edited)
Avatar
implementation が生成されるだけで : Codable は必須ってことか。
Avatar
omochimetaru 4/26/2017 2:31 AM
なんだ
Avatar
@omochimetaru Structural subtyping vs Interface みたいな話になるんじゃないかと思った。
Avatar
omochimetaru 4/26/2017 2:33 AM
まさにそれそのものですね。
Avatar
enum (without associated values)が自動的に Hashable になるのとは違う気がします。
Avatar
omochimetaru 4/26/2017 2:34 AM
ライブラリAの作者Pがenum Eを作っていて、それをユーザーQが辞書のキーに突っ込んでいる時
2:34 AM
PがEにassoc valを付け足すと、ユーザーQのコードが壊れるのか。
Avatar
それはあり得ますねー。
Avatar
omochimetaru 4/26/2017 2:35 AM
知らなかった
Avatar
同じく知りませんでした。
Avatar
omochimetaru 4/26/2017 2:35 AM
未然回避した
Avatar
やっぱ暗黙的に何かを満たすみたいなのはよくない気がする・・・。
2:36 AM
やるなら Structural subtyping までやっちゃう哲学じゃないとどっち付かずで中途半端感が。 (edited)
Avatar
omochimetaru 4/26/2017 2:36 AM
Structural Subtypingで通しても同じように崩壊するだけじゃないのかなあ。 (edited)
Avatar
Go や Crystal やダックタイピングやってる言語は崩壊してるってこと?
Avatar
omochimetaru 4/26/2017 2:37 AM
ライブラリAのFooが何かを満たしていることを永遠に保証できない
2:37 AM
そういうことです
2:37 AM
Rubyはそれが実行時エラーになるCrystalといえるけど
2:37 AM
実際のところドキュメントで
2:37 AM
このクラスはこのインターフェースを満たすっていうのを
2:37 AM
HTMLで書いてるんですよ
Avatar
いや、もちろん問題が起こる可能性はあるんだけど、それを前提にして回ってるわけで、それによって得られてるメリットもあるわけで、そっちを優先するという立場があってもおかしくはない。 Swift にはなじまないと思うけど。
Avatar
omochimetaru 4/26/2017 2:38 AM
あ、違うか、継承は実在するのか
2:39 AM
[PARAM] path: 文字列、または類似のオブジェクトを与えます。 実際には to_str に反応するオブジェクトなら何でも構いません。
2:39 AM
例えばこれとかなんですけど、これって、Swiftできちんと考えると
2:39 AM
class Pathname { init<P: ToStrProtocol>(path: P) { ... } }
2:40 AM
ようするにこういうシグネチャなんですけど
2:40 AM
今ユーザーQがライブラリAの型Fooをこれに渡してる時、
2:40 AM
このToStrProtocolは静的検査されないんで、 ライブラリAがアップデートでそれを削除した瞬間に
2:40 AM
実行時エラーが潜伏することになる
2:40 AM
Crystalならコンパイルエラーになる
2:41 AM
「to_strなんか消さないだろ」みたいなコンセンサスをみんなが守ってるから壊れない。
2:43 AM
そっちを優先するという立場があってもおかしくはない。
それはそうだけど、「徹底しないといけない」理由はよくわからないです。少し入れるのも完全に入れるのも、入ってくるメリットとデメリットが同時に増大するかどうかの違いで、同じことに思います
Avatar
はい、ぶっ壊れるのはわかるんだけど、それを前提に書き心地を優先して Structural subtyping をとるっていうのは、メンテナビリティと書き心地のトレードオフだから、後者を取る立場があってもおかしくはない。
2:43 AM
うーん、程度問題で、 Structural subtyping は許せないけど auto の Hashable は許せるってこと?
Avatar
omochimetaru 4/26/2017 2:43 AM
かき心地のトレードオフっていうのもよくわからないんですよね。このHTMLを日本語で書くの、かき心地いいのかな
2:44 AM
ドキュメント化した時点で矛盾してるような気がしています
Avatar
ドキュメント化しないスクリプトみたいなのが大量に生成されてるんじゃない?
Avatar
omochimetaru 4/26/2017 2:44 AM
それならわかる
Avatar
そういうときに implements Foo とか書きたくないと。
Avatar
今回の enum (without associated values)が自動的に Hashable になるけど、 CodingKey には自動的にはならず opt in ってのは統一感ないのはありますね。
Avatar
ですねー。 Swift は明示的なインターフェースを選んだ言語なわけだし、自動 Hashable は違和感がありますね。
Avatar
omochimetaru 4/26/2017 2:45 AM
simple enumとでも言えば良いのかな、全行読まないとそれが確定しないのユーザーにとって不便ですね
2:47 AM
C++もデフォルトでいろいろやる仕様から始まって、 そのデフォルト生成挙動を把握しろっていうプラクティスが普及して、 デフォルト生成を抑制する構文が追加されて、 デフォルト生成を明記する構文が追加されて、 カオス
2:48 AM
昔に定義された「デフォルト挙動」のせいで、「デフォルト禁止構文」と「デフォルト明示構文」が後から足されて安定した設計に至る話、複数ありそう
Avatar
Swift だとそこで過去を断ち切って非互換アップデートしちゃうからw
Avatar
omochimetaru 4/26/2017 2:49 AM
特にデフォルト明示構文が使われてるときのシュールさがやばいんですよね、わかるんだけど。
Avatar
@nonescaping みたいに
Avatar
omochimetaru 4/26/2017 2:49 AM
たしかに・・・
Avatar
Swift は @objc のデフォルト挙動を無くして 明示の方向に進んでるけど enum: Hashable を無くす議論はまだ無いですね。影響でかすぎるか。
Avatar
omochimetaru 4/26/2017 2:50 AM
いけるいける
Avatar
あー誤解してた。 associated value が Hashable の場合も自動的に、なのかと思った。
enum (without associated values)が自動的に Hashable
2:53 AM
うーん、まあ associated value なしの enum がありの enum に変化するのは、ぜんぜん違うものになってる感があるし仕方ない気も。 (edited)
2:54 AM
両方 enum で書けるってのが変かも?
Avatar
そもそもですねw
Avatar
omochimetaru 4/26/2017 2:54 AM
simple enum みたいな特殊キーワードとかもありかも
Avatar
Tagged union は enum じゃない気がするんですよね。
2:55 AM
enumerate できないし。
2:55 AM
enum じゃなくて union とかでもよかったのかも?
Avatar
omochimetaru 4/26/2017 2:56 AM
unionだとunion typeじゃないのに変な感じ
2:56 AM
C言語の union { } と紛らわしいし。
Avatar
でも今の状態も C の enum とかけ離れてない?
Avatar
omochimetaru 4/26/2017 2:57 AM
そうですねえ
Avatar
開発ツールに https://github.com/apple/swift/tree/master/tools/swift-api-digester ってのがあって、モジュールのAPIを出力してくれるツールで、 stdlib の 破壊的 API 変更をこれで監視しているんですが、これ的なものが SPM に組み込まれるとライブラリ開発者はなかなか助かるかもと思います。
swift - The Swift Programming Language
Avatar
おお
2:57 AM
それを元に自動でバージョニングしてくれるといいですね。
Avatar
omochimetaru 4/26/2017 2:57 AM
ほ〜〜
Avatar
API に変更がなければ patch を、互換性があれば minor を、非互換なら major を上げなさい、みたいな。
Avatar
↓ Swifty じゃなくないですか?引数の型は Encoder でなく T: Encoder であるべきでは? public protocol Encodable { /// Encodes `self` into the given encoder. /// /// If `self` fails to encode anything, `encoder` will encode an empty keyed container in its place. /// /// - parameter encoder: The encoder to write data to. /// - throws: An error if any values are invalid for `encoder`'s format. func encode(to encoder: Encoder) throws }
3:08 AM
↓じゃダメ? public protocol Encodable { func encode<T: Encoder>(to encoder: T) throws }
Avatar
norio_nomura 4/26/2017 3:15 AM
ジェネリックにしてしまうと、ランタイムでの差し替えが出来なくならない?プラグインとか。
Avatar
ジェネリック引数でできないのって具体的にどういうケースですか?
Avatar
norio_nomura 4/26/2017 3:18 AM
Objective-CでのEncoder実装とか?
Avatar
omochimetaru 4/26/2017 3:21 AM
それはジェネリックかどうかではなく、 swiftで定義されてる Encoder protocolが、@objc 互換かどうか、によって決まると思う
Avatar
norio_nomura 4/26/2017 3:22 AM
Encoder にはジェネリックメソッドありますね。じゃあ想定されていないのか。
Avatar
SE-0166 は Java の Serializable とは違って、シリアライズするための抽象的な仕組みを提供するだけなのか。素晴らしい。
Avatar
norio_nomura 4/26/2017 3:28 AM
What's in this pull request? This PR integrates preliminary work in introducing a new Swift-focused archival and serialization API as part of the Foundation framework. This PR focuses on what is av...
Avatar
SE-0167 読んでないですけど、多分 JSONEncoder は標準ライブラリじゃなくて Foundation ですよね? (edited)
Avatar
norio_nomura 4/26/2017 3:31 AM
ですです。
3:31 AM
This implements the JSONEncoder, JSONDecoder, PropertyListEncoder, and PropertyListDecoder types proposed by SE-0167. This pulls all Foundation-specific work out of #8124 for separate integration. ...
Avatar
JSONEncoderJSONSerialization で実装するのおもしろいですね。
Avatar
norio_nomura 4/26/2017 3:33 AM
レイヤー的には Himotoki とかと変わらないわけだ。
Avatar
ですね。でも decode/encode のコード書かなくていいのうれしい。
3:34 AM
Realm とかもこれに準拠することになるのかな?
3:35 AM
Swift 4 出たらこれ使って、 SwiftPM 対応の軽量 DB 書いてみようかなぁ。ずっとほしいと思ってるけど、シリアライズ部分が微妙で思いとどまってる。
Avatar
jsonのキーと合わせるのはkeyPathで出来るのかな
3:35 AM
capitalCaseとかsnake_caseとか、吸収してくれる感じならサイコーだ
Avatar
norio_nomura 4/26/2017 3:41 AM
This implements the JSONEncoder, JSONDecoder, PropertyListEncoder, and PropertyListDecoder types proposed by SE-0167. This pulls all Foundation-specific work out of #8124 for separate integration. ...
Avatar
jsonのキーと合わせるのはkeyPathで出来るのかな
CodingKey でやらないと駄目だと思います。 caseの吸収するなら コンパイラの自動生成に頼らずに自前でCodingKey型作って init(from decoder: Decoder) throws 実装しないとだめっぽいですね。
Avatar
なるほど
Avatar
norio_nomura 4/26/2017 4:14 AM
Mirror使ってシリアライズのデフォルト実装とか少し試してたけど、SE-0166 を待ちたくなった。
Avatar
Mirror 使いたいケース大分減りそうですね。
Avatar
減りますね
4:22 AM
後はOptionalをAnyに入れてしまった、ぐらいだろうか
4:28 AM
なんで let a: Int? = 42 let b: Any = a let c: Int? = b as! Int? はだめなのに enum Box<T> { case value(T) } let x: Box<Int> = .value(42) let y: Any = x let z: Box<Int> = y as! Box<Int> はできるんですか?
Avatar
as! がオプショナル周りで変なことしてるからだと思います
Avatar
(x as? Foo)! 扱いとか? (edited)
Avatar
SE-166 でどうしてもわからないのが サブクラスのデコードの扱いなんですが、 class Base : Decodable { } class Concrete : Base { } struct Foo : Decodable { let obj: Base public init(from decoder: Decoder) throws { self.obj = /* ???? */ } } どうやってデコードするのだろう。 (edited)
Avatar
それは encoder 次第?
Avatar
encode 時に obj のタイプ情報を一緒にエンコードしておくって事ですよね?
Avatar
omochimetaru 4/26/2017 4:32 AM
@koher ここらへんかなあ、Optionalが絡む as! について分岐がある Expr *visitForcedCheckedCastExpr(ForcedCheckedCastExpr *expr) { https://github.com/apple/swift/blob/3d178be169dd42b85f505ee1502232610535e4a3/lib/Sema/CSApply.cpp#L3491
swift - The Swift Programming Language
Avatar
じゃないですかね〜?
4:34 AM
@omochimetaru そのコード 7780 行もあるんだけどw
Avatar
この間の変性の話の続きなんですが
4:38 AM
Decoder<Base>にそれが必要な気がする (edited)
4:40 AM
で、Baseに関して
4:41 AM
struct Foo<B: Base> : Decodable { let obj: B public init(from decoder: Decoder) throws { self.obj = /* ???? */ } } こうするんじゃないかしら (edited)
Avatar
Foo<Base> だとしても Concrete のインスタンスは持てるから、解決できない気がします。
Avatar
あーー
4:45 AM
エンコード時にロストしてしまう
4:45 AM
確かに
4:46 AM
うーん、でも、それは明記された型の範囲でエンコードするのが責任の範囲な気もする
Avatar
Baseopen には出来ないってことですよね。
Avatar
subclassを作るときに、デコード/エンコードの処理を書くことを強制させる仕組みがあれば (edited)
4:48 AM
openに出来る?
Avatar
https://github.com/apple/swift-evolution/blob/master/proposals/0166-swift-archival-serialization.md#inheritance この項をみると class Base : Codable { let color: Color } class Concrete : Base { let name: String } みたいなのがあったときに { name: "FOOBAR" super: { color: "#abc109" } } みたいにエンコードされるように読めて、
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
Avatar
あーーー
4:55 AM
なるほど、なるほど、
Avatar
container.decode(Concrete.self, forKey: .obj) じゃないとデコードできないのはあきらか。
Avatar
ですね
4:56 AM
だから、エンコーダーは、型の定義がBaseの型ならBaseとしてしかエンコードしてはいけないはず。 (edited)
4:58 AM
public protocol Encodable { /// Encodes `self` into the given encoder. /// /// If `self` fails to encode anything, `encoder` will encode an empty keyed container in its place. /// /// - parameter encoder: The encoder to write data to. /// - throws: An error if any values are invalid for `encoder`'s format. func encode(to encoder: Encoder) throws } この生え方だと、自身の宣言がBase型かConcrete型かの区別つかない気がする (edited)
5:01 AM
public protocol Encodable { /// Encodes `self` into the given encoder. /// /// If `self` fails to encode anything, `encoder` will encode an empty keyed container in its place. /// /// - parameter encoder: The encoder to write data to. /// - throws: An error if any values are invalid for `encoder`'s format. staitc func encode(to encoder: Encoder, instance: Self) throws // <- staticなら宣言されてる型から取れる } これなら整合性が取れるかな?
5:02 AM
それとも、実際にはBase.encode: (Base) -> (Encoder) throws -> () を使っていて問題なく動くのだろうか
Avatar
たぶんこんな感じになるんだけど struct Foo : Decodable { let obj: Base public func encode(to encoder: Encoder) throws { let objType: ObjType switch self.obj { case is Concrete: objType = .concrete //... default: objType = .base } container.encode(objType, forKey: .objType) container.encode(obj, forKey: .obj) } public init(from decoder: Decoder) throws { objType = container.decode(ObjType.self, forKey: .objType) let ObjT : Base.Type switch { case .concrete: ObjT = Concrete.self // ... case .base: ObjT = Base.self } self.obj = container.decode(ObjT, forKey: .obj) } } (edited)
Avatar
これだとBaseはopenにできないですね
Avatar
そうなんですよね。
5:08 AM
@objc なら NSClassFromString NSStringFromClass でなんとか.
Avatar
struct Foo<B: Base> : Decodable { let obj: B public func encode(to encoder: Encoder) throws { B.encode(obj)(encoder) } public init(from decoder: Decoder) throws { self.obj = B(from: Decoder) } } これなら、宣言の外の情報は破棄されますが、Bはopenにできそう。
Avatar
マージされたらいろいろ触ってみます。
5:13 AM
class Foo { func foo() { print("Foo") } } class Bar : Foo { override func foo() { print("Bar") } } Foo.foo(Bar())() // -> "Bar" なんで、 なかなか厳しいです。
Avatar
ゲーッ
5:14 AM
encodeをstaticにしないと危険だ
Avatar
let obj: Foo = Bar() Foo.foo(obj)() これでもいっしょ。
Avatar
class Foo { class func encode(obj: Foo) { print("Foo: \(obj)") } } class Bar: Foo { override class func encode(obj: Foo) { print("Bar: \(obj)") } } Foo.encode(obj: Bar()) // Foo: __lldb_expr_.Bar
5:16 AM
こっちですかねぇ
5:17 AM
overrideで引数のFooが書き換えられない…
5:17 AM
ダメな気がしてきた
Avatar
norio_nomura 4/26/2017 5:34 AM
BaseCodable でなければ、型が失われるのは必然に思える。
Avatar
protocol Encodable { static func encode(obj: Self) } class Foo: Encodable { class func encode(obj: Foo) { print("Foo: \(obj)") } } class Bar: Foo { class func encode(obj: Bar) { print("Bar: \(obj)") } } Foo.encode(obj: Bar()) // Foo: Bar.encode(obj: Bar()) // Bar: func encode<E: Encodable>(type: E.Type, obj: E) { E.encode(obj: obj) } encode(type: Foo.self, obj: Bar()) // Foo: encode(type: Bar.self, obj: Bar()) // Foo: いけるかと思ったけどダメだった
5:35 AM
変性周りが蔑ろなのなんとかしないと壁を超えられない気がする
5:36 AM
でなければ、classは割りを食うことになりそう…
Avatar
norio_nomura 4/26/2017 5:38 AM
あいや Base: Codable か。
5:41 AM
DerivedConformanceCodable.cpp とかあるから、コンパイラの自動生成が頑張ってくれると期待。 https://github.com/apple/swift/pull/9004/files#diff-9ceab8e46e5cb79b6cf990fe2b464e21
What's in this pull request? Now that the core types introduced by SE-0166 have been sunk into the Swift standard library, the stdlib and compiler portions of #8124 and #8125 can be combined into o...
5:42 AM
ジェネリックなサブクラスのテストケースとか見当たらないのは心配だけど。
Avatar
norio_nomura 4/26/2017 6:57 AM
Development Snapshotをちょっと使ってみたのだけど、 extension Sequence { fileprivate func grouped<U: Hashable>(by transform: (Iterator.Element) -> U) -> [U: [Iterator.Element]] { return reduce([:]) { dictionary, element in var dictionary = dictionary let key = transform(element) dictionary[key] = (dictionary[key] ?? []) + [element] return dictionary } } }console.log error: redundant conformance constraint 'U': 'Hashable' fileprivate func grouped<U: Hashable>(by transform: (Iterator.Element) -> U) -> [U: [Iterator.Element]] { ^ note: conformance constraint 'U': 'Hashable' inferred from type here fileprivate func grouped<U: Hashable>(by transform: (Iterator.Element) -> U) -> [U: [Iterator.Element]] { ^ なんてエラーが出るようになったのね。
6:59 AM
戻り値が [U: [Iterator.Element]] だから U: Hashable は要らない。
Avatar
かしこい
7:19 AM
これ今ガリガリwhere句書いてるの大幅に削れる
Avatar
結局、SE-0166の public protocol Encodable { func encode(to encoder: Encoder) throws } が↓でない理由ってよくわからないままですっけ? public protocol Encodable { func encode<T: Encoder>(to encoder: T) throws } swift-evolutionとかで聞いてみたらいいのかな?
Avatar
encoderは任意のパスから任意の型を取り出せる抽象であれば良いので、ジェネリックスにする必要は無いのだと思います
1:33 AM
ああ、それはデコーダーだ
Avatar
どっちでもいいならジェネリックメソッドにした方が静的ディスパッチになって速いですよね?
Avatar
あーそれは確かに
Avatar
Swift の標準ライブラリってあまりプロトコル型で引数をとらない印象があったので違和感を感じています。印象だけかもしれませんが。
1:35 AM
DB から大量に読み込みとか考えると繰り返し実行されるから、動的ディスパッチのオーバーヘッドが効いてきそう・・・。(それは decode だけど、同じ話として) (edited)
Avatar
型消しの言語機能化入るのと関連して、protocol周りを暗黙的にGenerics扱いにする隠し球がくる、とかでしょうか
1:37 AM
高望みしすぎかなw
Avatar
「型消しの言語機能化」って Generalized existentials のことですよね?
Avatar
はい
1:38 AM
名前を覚えきれない😫
Avatar
はい、僕も今ググって確認しましたw
1:40 AM
あれって抽象のまま保持しないといけないこともあるし、最適化できない気がするんですよねぇ。というか、最適化できるケースはジェネリック関数/メソッドでいいわけで、それじゃできないことをするときに Generalized existentials を使うことになるんじゃないですかねー?
Avatar
あ、いや
Avatar
という関連で、「暗黙的にGenerics扱いにする」も厳しそうな?
Avatar
Genericsな引数として入ってきたprotocolを、変数に格納するときに関連がありそうだな、と
1:42 AM
素protocolで宣言された引数は、そのままGenerics扱いにしてしまっても問題なくなるかしら?と思ったのです
1:42 AM
(そんなに考えてない)
Avatar
うーん、コーナーケースで問題が出そうな気も?
Avatar
例えば今適当にprotocolで宣言した引数をGenericsに変更して困る事って
1:44 AM
Optionalなどのモナドに包んで推論不可能になることだと思うんですよね
1:44 AM
うーん、でもこれは関係ないか
Avatar
(SomeProtocol) -> SomeProtocol みたいな型の変数に入れるためには抽象のままじゃないといけないけど、関数コールしてる箇所はジェネリック扱いすればよさそうだし、何かあるかな・・・。
Avatar
返り値protocolは、受け手側が具体型じゃないんで、推論不可能
1:45 AM
あー
1:46 AM
そうか、protocolな型を受け取ってそれをそのまま渡す、
1:46 AM
あり得ますね
1:46 AM
これは困る
Avatar
んーでも、 Foo: SomeProtocol があったとして、 func bar<T: SomeProtocol>(_ x: T) -> T { return x } let foo: SomeProtocol = Foo() let foo2: SomeProtocol = bar(foo) のように bar がジェネリック扱いでも問題ないですよね?
Avatar
それはそうなんですが
Avatar
まあ、暗黙ジェネリック化はちょっとやりすぎでなさそうな気がします。何か問題起こりそうだし。
Avatar
それが可能になるためには、全てのprotocol型変数が言語機能によって、型消し相当の具体型に昇華してないといけない
1:50 AM
でもそれが可能なら、全てのprotocol型をGenerics扱いに出来そうだ
Avatar
あ、↓はダメだ。ジェネリック化できない。 func foo(x: Foo<SomeProtocol>) -> Foo<SomeProtocol> { ... } (edited)
1:51 AM
func foo<T: SomeProtocol>(x: Foo<T>) -> Foo<T> { ... } にしたら、 FooT について covariant じゃないから戻り値の型に互換性がなくなっちゃう。
Avatar
func foo<T: SomeProtocol, U: SomeProtocol>(x: Foo<T>)->Foo<U>ですよね元のものは (edited)
1:52 AM
その上で、SomeProtocolで宣言されたものが型消しになるのなら、Okだと思います (edited)
Avatar
↓だとできないですね。 func foo(x: Int) -> SomeProtocol { switch x { case 0: return Foo() case 1: return Bar() case _: return Baz() } }
Avatar
そう。その場合はSomeProtocolが、型消し扱いの具体型になる
1:55 AM
その扱いなら、Generics化が出来ると思います
Avatar
AnySequence 的な型を使えばってことですか?
Avatar
はい
1:56 AM
protocolで宣言された変数がAnyProtocolになって、
Avatar
そもそもよく考えたら、↓をジェネリック化しても大丈夫と主張してるということは、それが真ならこういうケース(引数だけプロトコル型)では自動ジェネリック化も問題を起こさないはずですね・・・。 public protocol Encodable { func encode(to encoder: Encoder) throws }
Avatar
そうですねw
Avatar
そう考えれば自動ジェネリック化もなくはない?
1:58 AM
もしくは、↑をジェネリック化して問題が起こるケースがあるかなぁ・・・。
Avatar
ちょっとまだ考えきれてないんですが、自動Generics化で、推論周りで破綻しないかな、破綻がなければ大丈夫
2:00 AM
Protocol?でnilが推論不可能なのも、AnyProtocol?.noneということにすればよくて
2:00 AM
型パラが必要で推論できない場合も、代表的な具体型を差し込めば良さそうだ
Avatar
うーん、やっぱ Any よくない気がする・・・。
Avatar
そして、Anyがprotocol<>の型消しに帰結する、と、しなきゃいけない
2:01 AM
うーん
Avatar
値型とサブタイピングは相性悪いですね・・・。
2:02 AM
プロトコル型が witness table 使わなきゃいけないのと同じように、 Any にも気持ち悪さを感じる。
2:03 AM
プロトコル型変数も Any も禁止とかしたら、さすがに無理かなぁ。どうしても Any にせざるを得ないケースもあるしなぁ。
2:04 AM
参照型と、参照型とみなせるイミュータブルな値型なら問題ないと思うけど。 (edited)
Avatar
いや、Anyがprotocol<>の型消しであると言う解釈で良ければ
2:04 AM
普通にありえますね
Avatar
でも OptionalAny の問題は値型関係ないか・・・。
Avatar
今思い付く限りでは、Generics化は成り立つんですが、現実的なコンパイル時間に収束するかが全く予想できない
Avatar
でも、最初からジェネリック関数/メソッドだったら大丈夫なわけですよね?暗黙的にオーバーロードされてるという解釈なら問題ないのでは?
Avatar
それはそうですね
2:07 AM
今ちょっと考えてるのは
2:08 AM
protocol型変数を持つ型を、Generics型に昇華出来ないか、と言うことを考えてました
2:08 AM
ちょっと厳しそう
Avatar
それは難しいと思います。
Avatar
protocol型引数が、inoutなのはあり得るんでしたっけ
2:09 AM
これがokだとGenerics化は破綻しそう
Avatar
struct Foo { var bar: BarProtocol }struct Foo<Bar: BarProtocol> { var bar: Bar } にしてしまうと、 extension Int: BarProtocol {} extension String: BarProtocol {} var a = Foo(bar: 123) let b = Foo(bar: "xyz") a = b の最後の行ができなくなってしまう。
Avatar
ですね
2:12 AM
変数は無理と言うかおそらく意味がない、同じ理屈でinoutな引数もダメなはず
Avatar
なので、変換可能なのは、純粋なプロトコル型引数のみの場合ですね。
2:12 AM
inout は引数でもあり戻り値でもあるので、戻り値の場合と同じかと思います。
Avatar
そうすると、1つの型にTとUを重ねるのは無理なので
2:13 AM
これも出来ませんね、かなしい
2:16 AM
inoutを引数と返り値に分解して解釈する過程で差し込めば大丈夫なのかな
2:17 AM
それはさておき、Encoderはジェネリックスじゃないのは気になりますね
Avatar
そうですねぇ。
Avatar
omochimetaru 4/27/2017 2:18 AM
上の方しか読んで無いけど
2:18 AM
型のパラメータでも
2:18 AM
特殊化はされると思う
2:19 AM
encodeを呼び出すときにレシーバーの型が見えてれば。
Avatar
ん?特殊化されるジェネリック関数でなく、プロトコル型引数になってるのはなぜ?って話。
Avatar
omochimetaru 4/27/2017 2:19 AM
encodable.encodeにおいてencoder Eが
2:20 AM
encodable<E>.encodeとなるか encodable.encode<E>となるか
2:21 AM
の違いで、速度的な話なら、前者でも特殊化はされると思うから、同じだと思う
Avatar
Encodableは別にEncoderを型パラとして定義はしていない
Avatar
omochimetaru 4/27/2017 2:22 AM
あれ?そうなのか、勘違いだ
Avatar
任意のEncoderに対してencode関数が使える、というだけ。
Avatar
omochimetaru 4/27/2017 2:22 AM
Encoderはただのプロトコル?
Avatar
omochimetaru 4/27/2017 2:22 AM
assoc typeかと思った。
Avatar
そこがミソ
Avatar
omochimetaru 4/27/2017 2:23 AM
あれ、じゃあ、
2:23 AM
assoc typeの無いプロトコルを
Avatar
なので、Encodableなら、その瞬間にJsonもplistもprotobufも使える
Avatar
omochimetaru 4/27/2017 2:23 AM
ジェネリックでないアレでexistebtialでうける形になってるのか
2:24 AM
だとするとその場合でも特殊化されるのかな・・・?
Avatar
それは、protocol型引数を暗黙的にGenerics化できるということ、そして上の議論
Avatar
omochimetaru 4/27/2017 2:26 AM
method<X:P>(x: X)と method(x:P) Pにassoc tyがない場合にはどちらでも書けるがコンパイル結果がどう変わるか
2:26 AM
というのがコアな謎か。
Avatar
そうね、僕の議論はそこにさらに
Avatar
omochimetaru 4/27/2017 2:26 AM
うん(続きはまだ読んで無かった
Avatar
Generalized existentialsがあれば、成り立つようになるのでは(直感)ってやつ
2:27 AM
associatedtypeありでも。
Avatar
omochimetaru 4/27/2017 2:28 AM
GEがあればアソックありでも同じ議論ができると思うよ。
Avatar
norio_nomura 4/27/2017 2:28 AM
func encode(to encoder: Encoder) throws は自動生成されるというのがポイントのような気がします。 (edited)
2:29 AM
PRの自動生成している箇所 https://github.com/apple/swift/pull/9004/files#diff-9ceab8e46e5cb79b6cf990fe2b464e21R407 // @derived func encode(to encoder: Encoder) throws {
What's in this pull request? Now that the core types introduced by SE-0166 have been sunk into the Swift standard library, the stdlib and compiler portions of #8124 and #8125 can be combined into o...
Avatar
omochimetaru 4/27/2017 2:30 AM
コンパイラに自動生成タイミングがあるから、普通のやつと違って、特別に特殊化をしこむ余地とかがあるかもって事ですか?
Avatar
norio_nomura 4/27/2017 2:32 AM
この @derived というキーワードを apple/swift リポジトリで探すと、 enumEquatable, Hashable, RawRepresentableError_nsErrorDomain などで使われてて、それらは全部ジェネリックでは無い。
2:33 AM
ジェネリックなメソッドを自動生成するのを避けているのかな?と。
Avatar
omochimetaru 4/27/2017 2:35 AM
ふむ。他もそうなってるんですね。
Avatar
norio_nomura 4/27/2017 2:37 AM
ジェネリックの方が良い悪い、ジェネリックでは出来ないケースがある、とかではなく、実装上の理由なのかな?と。
Avatar
omochimetaru 4/27/2017 2:37 AM
なるほど。
Avatar
norio_nomura 4/27/2017 2:38 AM
まあ、PRにコメント書いて聞くのが早い気がしますが。 (edited)
Avatar
func encode(to encoder: Encoder) throws このメソッドって、実際には基本的に外部ライブラリであるエンコーダーから呼ばれるわけで、specialize しようがないと思うんですけど違います?
2:50 AM
encode<T: Encoder>( でだめな理由は無いけど、そうする意味もないのでは?ということです。 (edited)
👍 1
Avatar
自動生成されたencodeが、自身が持つフィールドのencodeを呼ぶことは無いのかな
2:51 AM
それがあるとGenericsにする価値がありそうです
Avatar
omochimetaru 4/27/2017 2:55 AM
let farm = Farm(name: "Old MacDonald's Farm", location: Location(latitude: 51.621648, longitude: 0.269273), animals: [.chicken, .dog, .cow, .turkey, .dog, .chicken, .cow, .turkey, .dog]) let payload: Data = try JSONEncoder().encode(farm) 使い方がこうだから、JSONEncoderが内部でfarmのencodeメソッドを呼ぶのか。
Avatar
基本的に外部ライブラリであるエンコーダーから呼ばれるわけで、specialize しようがない
標準ライブラリのジェネリック関数は標準ライブラリ外から呼んでも specialize されますよね?外部だと specialize できないというわけでもない気が。 @_specialize とかもありませんでしたっけ?
Avatar
omochimetaru 4/27/2017 2:56 AM
マジか
Avatar
@_specialize はライブラリ側につけるのか。
Avatar
omochimetaru 4/27/2017 2:57 AM
そんな謎技術があったのか。
2:57 AM
bitcodeとかってそういうところで活躍してんのか?
Avatar
norio_nomura 4/27/2017 2:57 AM
bitcodeは無関係かと
Avatar
omochimetaru 4/27/2017 2:58 AM
あら。。 (edited)
Avatar
外部でも利用側からリンクするときに specialize されたバイナリを吐けばいいから原理的にはできそうな気が? (edited)
Avatar
omochimetaru 4/27/2017 2:59 AM
JSONEncoderのencodeメソッドの中で、引数で受けたEncodableのencode(encoder)を呼ぶ部分はどうしようも無いですよね
Avatar
ライブラリ外から呼んでも specialize されますよね?
呼び出し側をコンパイルするときはそうですが、この場合呼び出し側であるエンコーダーをコンパイルするときには何も分からないし、func encode をコンパイルするときに encoder が JSONEncoder であるか否かはわからない。
(edited)
3:01 AM
@_specialize(where T == JSONEncoder) func encode<T : Encoder>(to encoder: T) throws { ... } ってしとけばいいかもしれないけど、使っちゃ駄目
Avatar
encode をコンパイルするときは specialize されてない抽象の状態でコンパイルし、呼び出し側をコンパイルするときに encode の specialize 版を生成することはできないですか?
Avatar
norio_nomura 4/27/2017 3:02 AM
それが出来るなら @_specialize は存在しないのでは (edited)
Avatar
現段階での挙動ではなく、理論上可能かどうかという意味でです。
3:04 AM
たとえば、 encode のバイナリにリビルドするのに十分な付加情報を埋め込んでおけば(バイナリ化されたASTとか)リンク時に specialize することはできるはずです。
3:06 AM
そこまでしなくても、プロトコル型引数が抽象表現されているはずなので、それを specialize することってできそうな気がするんですが無理なんでしょうか?ローレベルに詳しくないので想像の話ですが。
Avatar
norio_nomura 4/27/2017 3:06 AM
つまり、stdlibとか全部を含めて whole module optimization する的な話ですか?
Avatar
呼び出し側って ここで言うと 例えば JSONEncoder なので func encode をコンパイルする前に既にライブラリとしてコンパイルされているという認識なんですけど、それは良いですか? (edited)
Avatar
はい、それはよいです。
3:08 AM
コンパイル済みのものを解析して、抽象表現されている部分だけを specialize するのは無理?
3:08 AM
あれ?機械語まで落ちてるのか。
3:09 AM
LLVM レベルでとまってる気がしてたけど、
Avatar
MyType.encode をコンパイルするときに、 specialize 出来たとして、 呼び出し側がその specialize された メソッドをどうやって呼ぶのか想像がつかないです。 (edited)
Avatar
omochimetaru 4/27/2017 3:10 AM
LLVMIRのレベルでも型情報はなくなってますよ
Avatar
じゃあそもそもの話として、GenericsTypeとGenericsFunctionは全然違うのか
Avatar
omochimetaru 4/27/2017 3:12 AM
@tarunon いや、GenericsFunctionは、外部リンクするように抽象的な版のバイナリを吐いていて、抽象的な版はその場限りなGenericsTypeを引数に受けるような挙動ではある
Avatar
型パラはあるけど、中身では具体型として扱えるものではない、ということ
3:14 AM
つまり、<Foo: Protocol>(foo: Foo)においてFooは具体的な型パラだが、fooはProtocol型変数と変わらない状態?
Avatar
omochimetaru 4/27/2017 3:21 AM
回答を書こうとしてるけど曖昧なところが出てきたからちょいまち
Avatar
specialize 云々は抜きにして、前言撤回します。 func foo<T: Encoder>(to encoder: T) の方が良い。
3:26 AM
理由書いてるけどちょっとまってくださいー
Avatar
今って、標準ライブラリのジェネリック関数/メソッドについては外部からコールしても specialize されると思うんですがなぜですか?標準ライブラリだからできる芸当?
3:27 AM
public struct Foo<T> { private let array: [T] public init(array: [T]) { self.array = array } public func map<U>(_ transform: (T) throws -> U) rethrows -> Foo<U> { return Foo<U>(array: try array.map(transform)) } public var count: Int { return array.count } }
Avatar
omochimetaru 4/27/2017 3:27 AM
@tarunon LLVMIRではジェネリックな関数の引数は、 (x, wt, xt) な 3つの引数に展開されてて x: Catなどの具体的な型の値へのポインタ wt: xとセットで使える、Protocolのメソッド定義に準拠したwitness-tableへのポインタ xt: xの元々の型 Cat の 型の型へのポインタ で呼び出されるようになってる。 で、wtからメソッドを引っ張ってくると、 引っ張ってきた関数ポインタは、(x, xt) を受け取るようになっていて、 その関数の内部で、 xに対して Cat に定義されてた本物のメソッド呼び出しがされる。
Avatar
Array.map は specialize されてるっぽい
Avatar
omochimetaru 4/27/2017 3:29 AM
xtの使い所は、 例えばプロトコル型のままコピーとかしてるときに、 値のコピー自体が、xtから取り出された「コピー用の関数」に x を渡す形にコンパイルされる。 これによって、Catがstructの場合は値コピー、classの場合は参照コピー + Retain , みたいな挙動が抽象化される
Avatar
public protocol BAR { func foo() } public func XXXXX<T : BAR>(arg: T) { arg.foo() } public func ZZZZZ(arg: BAR) { arg.foo() } -O -emit-ir 結果 https://gist.github.com/rintaro/8794ecd01e78e6b001fce192b07f2d7d#file-test-sil
Avatar
omochimetaru 4/27/2017 3:30 AM
つまり、<Foo: Protocol>(foo: Foo)においてFooは具体的な型パラだが、fooはProtocol型変数と変わらない状態?
で、 プロトコル型変数 (Existential) は、 (x, wt, xt)の 3 つのフィールドをもつ struct みたいなバイナリになるから、変わらないっちゃ変わらない
Avatar
@omochimetaru wtは、Fooへのテーブル?それともProtocol全般へのテーブル?
Avatar
omochimetaru 4/27/2017 3:31 AM
「Fooは具体的な型だが」については、実行時においては、 xt の形で保持されてる
3:31 AM
ちょっと話題がぶつかってるので #swift-2 で。
Avatar
@omochimetaru の言っている通りジェネリックな方は引数で型情報が渡ってくるので、直接その witness table にアクセス出来るけど、 後者は protocol 値からいろいろ情報抜き出さないといけない分だけ手数が増える。
Avatar
specialize 関係なくジェネリックな方が速いのか。
Avatar
ですね。
Avatar
omochimetaru 4/27/2017 3:39 AM
@rintaro AssociatedTypeが無いprotocolの場合は Protocol Existential 型の値になるけど、それが結局 (x, wt, xt)の3フィールドだから、情報抜き出すところは同じだと思います。
Avatar
norio_nomura 4/27/2017 3:43 AM
呼ぶ側/呼ばれる側のどちらが取り出すか、の違いではない?
Avatar
omochimetaru 4/27/2017 3:45 AM
protocol Hogeable { func hoge() -> Int } func callHogeableHoge(hogeable: Hogeable) -> Int { return hogeable.hoge() } ↑こういうのがあるとき、LLVMIRだと、↓こういう引数になってる。 (x, xt, wt) の3タプルになっている。 %P4main8Hogeable_ = type { [24 x i8], %swift.type*, i8** } define hidden i64 @_TF4main16callHogeableHogeFPS_8Hogeable_Si(%P4main8Hogeable_* noalias nocapture dereferenceable(40)) #0 { ... }
Avatar
SIL 的には open_existential_addr が入っているか否か。 https://github.com/apple/swift/blob/master/docs/SIL.rst#open-existential-addr
swift - The Swift Programming Language
Avatar
omochimetaru 4/27/2017 3:47 AM
protocol Fugable { typealias Element func fug() -> Element } func callIntFugableFuga<F: Fugable where F.Element == Int>(fugable: F) -> Int { return fugable.fuga() } ↑一方こういうのがあるとき、LLVM IR だと↓こうなる define hidden i64 @_TF4main18callIntFugableFugauRq_S_7Fugablezqq_S0_7ElementSi_Fq_Si(%swift.opaque* noalias nocapture, %swift.type* %F, i8** %F.Fugable) #1 { Existentialがないけど、結局、引数として x, wt, xt が並んでる。 (edited)
3:49 AM
あ〜たしかに
3:49 AM
xのサイズが24バイトを超えるかどうかとかで
3:49 AM
直接ペイロードがコピーされてるか 、ポインタ渡しになっているかとかが変わるので
3:49 AM
そこらへんの分岐が、SILのopen_existential_addrがLLVMになる時に
3:49 AM
直接のアドレス操作バイナリにコンパイルされる感じだけど
3:50 AM
間接の場合は引数渡しより遅くなりうるかも??
3:51 AM
あ、でも引数にバラける場合は常にopaqueポインタ渡しになるから、それと同じなのかな、うーん、わからない。
Avatar
@norio_nomura
呼ぶ側/呼ばれる側のどちらが取り出すか、の違いではない?
そうなんですが、呼ぶ側は通常 existential 型で値を持っているわけではないので、generic の場合 existential 型 を生成する必要がない場合がほとんどだと思うのです。
Avatar
omochimetaru 4/27/2017 3:54 AM
そうなんですが、呼ぶ側は通常 existential 型で値を持っているわけではないので、generic の場合 existential 型 を生成する必要がない場合がほとんどだと思うのです。
たしかに!これは同意です、cat型で保持していて、渡す時にプロトコルexistentialにアップキャストするのが代替だから、パック側のコストもありますね。
Avatar
norio_nomura 4/27/2017 3:55 AM
なるほど
Avatar
@koher
標準ライブラリのジェネリック関数/メソッドについては外部からコールしても specialize される
stdlib は特別らしいです。 https://github.com/apple/swift/blob/master/docs/OptimizationTips.rst#advice-put-generic-declarations-in-the-same-module-where-they-are-used
swift - The Swift Programming Language
Avatar
norio_nomura 4/28/2017 1:28 AM
だとすると Encoder のコードも Codable ごとに specialize されうるのかな。
Avatar
Foundation Swift モジュールも特別扱いの対象なら可能性あるかもしれないですね。
Avatar
@rintaro おお、ありがとうございます!
3:14 AM
SwiftPM でソースからビルドした場合はモジュールまたいでも specialize してくれるようになったりするとうれしいですねぇ・・・。
Avatar
どうも特別扱いは -sil-serialize-all っていうオプション付きでモジュールがコンパイルされているか否かによるみたいです。この場合、実装含めた全てのSILが .swiftmodule にシリアライズされるので、caller側はcalleeのSILレベルでの実装を見通して最適化が出来ようになると。
😮 1
3:17 AM
ためしに swift build -Xswiftc -Xfrontend -Xswiftc -sil-serialize-all でビルドしてみたら LLVM ERROR: Invalid abbrev number <unknown>:0: error: merge-module command failed with exit code 1 (use -v to see invocation) 😢
Avatar
お、それは現時点ではできなくても将来的にはできる可能性もあるのでは?
3:20 AM
それがありうるなら encode がジェネリックの方がいい強力な理由になるんですけどね〜。
3:22 AM
そう言えば、昨日言ってた @_specialize を使うべきでないという理由はなんですか?
Avatar
とりあえず encode については質問済みなので回答来たらまた。 https://github.com/apple/swift/pull/9004#pullrequestreview-35266665
What's in this pull request? Now that the core types introduced by SE-0166 have been sunk into the Swift standard library, the stdlib and compiler portions of #8124 and #8125 can be combined into o...
Avatar
ありがとうございます!
Avatar
@_specialize について、 _ で始まるものは本当に使わないほうがいいです。意図的にやっているのかっていうくらい頻繁に仕様が変わります。
Avatar
こういう場合って、 PR でこっちの方がいいねってなったら、 Proposal と違った形で実装されたりするんですか?
Avatar
実質のインターフェイスが変わらない限り evolution 通さずに変更はあると思います。
Avatar
なるほど。
Avatar
@_specialize は実際 Swift3 と 現状の master でインターフェイス変わってます Swift3 @_specialize(Int, String) func foo<T, U>(x:T) -> U master @_specialize(where T == Int, U == String) func foo<T, U>(x:T) -> U
Avatar
@_specialize のインターフェースも変わってるんですね・・・
3:38 AM
@_specialize は代替手段がないから辛いですね。
3:38 AM
とはいえ、どうせ Swift はソース互換性ないからバージョンアップ時は一緒に直してしまえばいい気もw
Avatar
_開始は、マイナーバージョンアップですら保障されてない気がする
Avatar
普通の _Foo は使わないですが、 @_specialize は特殊なのかと思ってました。
Avatar
norio_nomura 4/28/2017 3:49 AM
ためしに swift build -Xswiftc -Xfrontend -Xswiftc -sil-serialize-all でビルドしてみたら
これ、シングルモジュールのパッケージならビルド出来ますね。
Avatar
norio_nomura 4/28/2017 4:00 AM
ビルドできるが、各ソース毎の中間 .swiftmodule は大きくなるけど、パッケージのは大きくならない。
Avatar
omochimetaru 4/28/2017 5:47 AM
どうも特別扱いは -sil-serialize-all っていうオプション付きでモジュールがコンパイルされているか否かによるみたいです。この場合、実装含めた全てのSILが .swiftmodule にシリアライズされるので、caller側はcalleeのSILレベルでの実装を見通して最適化が出来ようになると。
ほ〜〜〜〜〜〜
Avatar
omochimetaru 4/28/2017 7:13 AM
PR0166い途中まで読んでるけどこれめっちゃ頭いいな
7:14 AM
あるstructが:Encodableに準拠してるとき、
7:14 AM
自動的にプロパティ名と同じcase名をもったenumが定義されて
7:14 AM
そのオブジェクトをエンコードする時のコンテナ(JSON Object)とかにあたるオブジェクト
7:14 AM
に、型パラメータとしてCodingKeyが取れるおかげで
7:15 AM
プロパティ名に対応しないキーを間違って使っちゃう可能性が排除される
7:15 AM
public struct Location : Codable { private enum CodingKeys : CodingKey { case latitude case longitude } public func encode(to encoder: Encoder) throws { // Generic keyed encoder gives type-safe key access: cannot encode with keys of the wrong type. let container = encoder.container(keyedBy: CodingKeys.self) // The encoder is generic on the key -- free key autocompletion here. try container.encode(latitude, forKey: .latitude) try container.encode(longitude, forKey: .longitude) } }
7:17 AM
Encodercontainer メソッドが、 K.Type を引数で受けていて、 container の型パラに引き継がれる。 enum CodingKeysはstruct Locationのinner typeで、Locationのために自動定義されたやつだから、プロパティ名とキーが静的に結びつく
Avatar
omochimetaru 4/28/2017 7:58 AM
継承については 親クラス部分をまとめたオブジェクトを super キーにぶら下げるみたいですね
7:59 AM
{ "a": 3, "b": 2, "super": { "c": 1 } }
Avatar
omochimetaru 4/28/2017 8:58 AM
0167も見てるけど、エラー型に [CodingKey] がついて無さそうに見える。
8:59 AM
JSONが壊れてる時、ルートからみてどこが壊れてるのか、デコード時にパスがトレースされるんでそれを例外に保持して、メッセージに出したい
8:59 AM
レビュー期間とっくに終わってるしオシマイ
Avatar
CocoaError投げるみたいなこと書いてるなー
9:44 AM
Errorが役に立た無さそう
Avatar
omochimetaru 4/28/2017 9:44 AM
そのError型になんのassociated valueもないんだよねえ
9:45 AM
Encoder型自体は codingKeys: [CodingKey?] としてパスを保持してるから
9:45 AM
仕組み的にはできるはずなんだけども。
Avatar
Swiftのプロパティとinout参照を組み合わせたときの挙動が面白い on @Qiita https://t.co/pBDyCv6D89
10:37 AM
かいた
Avatar
https://github.com/apple/swift/blob/master/docs/OwnershipManifesto.md#the-law-of-exclusivity によりそういうコードが今後きちんと拒否されるかも。
swift - The Swift Programming Language
Avatar
そうですね、オーナーシップの展開は気になっていて、参照のことが気になって試していました
10:55 AM
この場合だとcatはMainの一部だから、参照をborrowしようとすると、catのborrowの間はMainが不正な状態になっているから、メソッドが呼び出せない?
10:56 AM
Catがクラスの場合でも記事の内容は成立すると思うけど、 その場合はどうなるんだろう。
Avatar
どう処理するのか全然予想がつかないw
Avatar
完全フロー解析すれば、updateIntにcat.ageをborrowしているケースがあるから、updateIntの中でcat.ageをリードするのは不正 って事になるのかな? でも外部モジュールとか跨いでいると無理そうですよね
Avatar
https://github.com/devincoughlin/swift/blob/master/test/SILOptimizer/exclusivity_static_diagnostics.swift とりあえず現状こんな感じのテストケースで実装済みです。
swift - The Swift Programming Language
Avatar
うお!このフォークで試せるんですか?
Avatar
master-enforce-exclusivity=checked つけると試せるです。
Avatar
おお。実はちまちま探してたんだけどそれっぽい実装ロジックが見つからなくてまだお試し実装無いのかと思ってました
11:03 AM
exclusivityってキーワードだったんですね どうやって追っかけているんですか?
11:03 AM
MLのOwnershipスレだけさらってたけど見つけられず。
Avatar
https://github.com/apple/swift/pulls 日常的に追っかけてるだけです
swift - The Swift Programming Language
Avatar
なるほど・・・
11:09 AM
ちょうどゴールデンウィークだし試してみます
Avatar
都合上両側にスペースを置きたくない演算子~~(lhs: Int, rhs: Int)について 1~~-2とかやるとコンパイル通らないので ~~-演算子を定義するという糞ハック
Avatar
norio_nomura 4/29/2017 3:14 AM
encode(to:) の理由を答えてくれてる。なるほど。 https://github.com/apple/swift/pull/9004#discussion_r114044478
What's in this pull request? Now that the core types introduced by SE-0166 have been sunk into the Swift standard library, the stdlib and compiler portions of #8124 and #8125 can be combined into o...
Avatar
なるほど、すっかり忘れてました。これが通らないってこと。 protocol P { func foo() } struct S : P { func foo() { print("S.foo") } } func foo<T : P>(p: T) { p.foo() } let obj: P = S() foo(p: obj)
Avatar
あ、ですです
6:55 AM
これは通らない、通そうとすると、Pの宣言が全て暗黙的にtype-erasure相当の具体型ということにならないといけないはず
6:55 AM
或いは
6:57 AM
AnyかAnyObjectのように、Protocolのまま型パラに入れれるようにならないといけない。
6:57 AM
ところでなんでAnyとAnyObjectは型パラになれるんですか?
6:57 AM
nominaltype(でしたっけ?)と関係あるのかな。
Avatar
Any に関しては <T : Any> は何も書かないのと一緒扱いなのかな? Any = protocol<> でしたし、今もパーサー時点で Any を 空のコンポジションとして AST に入れている。 AnyObjectprotocol P : AnyObject protocol P : class と同義であるみたいに、 class レイアウトであること「だけ」を強制するものとして、コンパイラでの特別扱いがあるので、その絡みだと思いますが、よく分かんないですね。 (edited)
Avatar
なるほど、すっかり忘れてました。これが通らないってこと。
うーん、それはそうなんですが、まだ KeyedEncodingContainer をちゃんと読めてなくて、 public protocol KeyedEncodingContainerProtocol { associatedtype SuperEncoder: Encoder mutating func superEncoder() -> SuperEncoder ... } にできないのかがよくわかってないです。 API 全体で existential を排除できないものなのか・・・。ちょっと時間のあるときにちゃんと読んで理解して考えます。
2:13 AM
話はまったく変わるんですが、↓みたいなのほしくないですか? extension Array { public mutating func update(_ operation: (inout Element) throws -> ()) rethrows { for i in startIndex..<endIndex { try operation(&self[i]) } } } struct Foo { var value: Int } var array = [Foo(value: 2), Foo(value: 3), Foo(value: 5)] array.update { $0.value *= 2 } print(array) // [Foo(value: 4), Foo(value: 6), Foo(value: 10)] (edited)
Avatar
omochimetaru 4/30/2017 2:32 AM
array = array.enumerated().map { $0.0 + $0.1 } // 配列の要素の値に要素番号を足す
2:33 AM
インプレースなmapだと思うけどこういう場合に使えなさそう
2:35 AM
rubyだとmap! がありますね。(!は自己変更オーバーロードの慣習
Avatar
先のinoutなreduceの絡みで、mapよりupdateが欲しい場面が出てきそう
2:37 AM
返り値がvoidである必要があるから、必然的にupdateの方が取り回しやすい
Avatar
omochimetaru 4/30/2017 2:41 AM
そうなんだよなあ inout reduceがあるなら、これもあっていい、っていう議論がたくさん出てきそう
Avatar
あっても良いというか、メモリ効率考えると無いと困るってレベルだと思う
2:42 AM
filter, map, reduce (flatMapも?)こいつらは、自己変更のメソッドも欲しい
Avatar
omochimetaru 4/30/2017 2:43 AM
flatMapは無理じゃ無い?型的に
Avatar
Array<T>に対して返り値がArray<T>かOptional<T>なら大丈夫じゃない?あまり考えてないけど
Avatar
omochimetaru 4/30/2017 2:44 AM
あ、ごめん、そうだった
Avatar
mapとflatMapは基本的にはTからUだけど、自己変更はTからTしか有り得ない
Avatar
omochimetaru 4/30/2017 2:44 AM
flattenと間違えた
Avatar
reduceが、返り値持ってるからVoidで自己変更するわけじゃなく、返り値のUに対して自己変更を強制するから
2:46 AM
こいつだけオーバーロードでも違和感がないように見える、filter, map, flatMapはVoidにしないと成り立たない、オーバーロードは地獄を見そう。名前変更が妥当だけど
2:46 AM
全部updateに詰めればいいかな?
2:47 AM
mapはinout Tで大丈夫だけどflatMapとfilterはまた違うな…
Avatar
@tarunon そのあたりちゃんと整理しようとすると、例の filterfiltered みたいな話になると思うんですよね。ただ、 updatemap に相当するんですが、 map は戻り値の要素の型を変更できるのに対して update はできないんで、 map / mapped は違和感がありますね。 update / updated の方がいいけど、 mapupdated は弊害の方が大きそうだから、 updatemap かなぁと。
Avatar
norio_nomura 5/1/2017 3:52 PM
5月1日時点のmasterからtoolchainをビルドして使ってみたら、想像以上に変更点が多くてちょっと怯んでる…
Avatar
norio_nomura 5/2/2017 1:30 AM
ビルドしたtoolchainのインストーラ欲しい人いるかな?
Avatar
swift-evolutionの"[swift-evolution] [Pitch] Revamp Optional and Throws" スレッドでのJohn McCallのコメント。コアチーム(の中でもエラーハンドリング分野で一番影響力がありそうなJohn)の考えが知れておもしろい。 We've definitely considered including a Result type, but our sense was that in an ideal world almost no code would be using it. It's hard to imagine an ordinary API that ought to be returning a Result rather than throwing, and once you've defined that away, the major remaining use case is just to shift computation around, like with a completion handler. That explicit computation-shifting pattern is something we're hoping to largely define away with something like C#'s async/await, which would leave Result as mostly just an implementation detail of such APIs. We didn't want to spend a great deal of time designing a type that would end up being so marginal, especially if the changing role would lead us into different directions on the design itself. We also didn't want to design a type that would become an obstacle to potential future language changes like, say, typed throws. The downside, of course, is that as long as we lack that async/await design, computation-shifting isn't real great.
1:58 AM
前も書いたけど、↓みたいな感じで async / await 導入されてほしい。 https://gist.github.com/koher/df007741788cb197d65b6babe2acf480
Avatar
norio_nomura 5/2/2017 2:01 AM
async / await って GCD の上に構築されるイメージ?
Avatar
GCD とは直交なイメージです。 GCD は非同期処理を実行するためのもので、 async/await は非同期処理をハンドリングするためのものみたいな?
2:03 AM
僕がイメージしているのは、 throwsResult<T> は相互変換できるので、同じようにして asyncPromise<T> を変換できるというものです。
2:03 AM
なので
2:04 AM
throws : async try : await Result : Promise がすべて同じ関係になるだろうと。
2:04 AM
そう考えると、 rethrows と同じように reasync という概念が必要になるんじゃないかと思ってます。
2:05 AM
let r = await [2, 3, 5].map { (x: Int) async -> Int in ... }
2:06 AM
throws なクロージャが渡された maptry しなきゃいけないように、 async なクロージャが渡された map は↑のように await しなきゃいけないようにしたいと。 (edited)
2:07 AM
reasync がないと、 mapasync なクロージャを渡せなくなってしまいます。
Avatar
asyncにおいて、catch相当のものってあるんですか?
Avatar
catch とはエラーハンドリングの意味ですか?それとも、非同期処理において、エラー処理における catch に対応するものという意味ですか?
Avatar
後者です
2:17 AM
try-catchに対してasync-???
2:17 AM
いや、await-???か
Avatar
↑のGistでは do - defer (このキーワードが適切かは微妙です)で await 前のスレッドに戻ってノンブロッキングな処理を表すのがいいんじゃないかと思ってます。
2:19 AM
// `do` / `defer` for `await` outside `async` functions func onClick() { do { let selectedIndex = await actionSheet([...]) ... } defer // Non-blocking }
Avatar
この場合、deferに渡される値はどういうものが来るんですか?
Avatar
この場合は値は渡されません。
Avatar
あと、deferの中でreturnが可能、つまりyield的な動き?
Avatar
repeat - whilewhile ブロックがないように、 do - defer には defer ブロックがない想定です。
Avatar
norio_nomura 5/2/2017 2:22 AM
C#の await だと、変数間の依存関係も考慮されているみたいだけど、それも含む? func foo(url: URL) async throws -> Foo { let data = await try download(url) let modified = await asyncConvert(data) return Foo(data: modified) }
Avatar
変数間の依存関係とはどういうものを指してますか?
Avatar
norio_nomura 5/2/2017 2:23 AM
http://qiita.com/acple@github/items/8f63aacb13de9954c5da から引用 async Task<string> AsyncMethod2(Uri uri) { using (var client = new HttpClient()) // <- 本当はHttpClientをusingで使っちゃダメ { var response = await client.GetAsync(uri); // <- 「GETせよ」のタスクを開始し、その完了を待機する var text = await response.Content.ReadAsStringAsync(); // 「レスポンスからその本文をstringとして読み出す」タスクを開始し、その完了を待機する return text; // 読み出したtextを返す } } // という「一つのタスク(Task<string>)」を表す。 (edited)
この記事は、
  • Task.Runを書けばとりあえず非同期で動くのはわかる
  • 時々なんかうまく動かなかったりするけどどうして動かないのかはよくわからない
  • よくわからないまま書いてよくわからないまま動いてるけどこれで大丈夫なのか...
2:24 AM
response が返ってくるのを待ってから response.Content.ReadAsStringAsync() を呼んでる?
Avatar
そうなります。
2:25 AM
tryawaitflatMap に対応するので
2:25 AM
(そして PromisethenflatMap と等価なので)
2:26 AM
await を 2 回書くということは then をチェーンして繋いでるのと同じです。
Avatar
tryもそうですよね、なので現状swift-doはResultに対してはHakellのdo構文と同じ
Avatar
はい、そうです。
2:28 AM
なので、 async / await で、 Promise に対する( Haskell の) do のように振る舞えるはずです。
2:29 AM
JS の Promise はエラーハンドリングまで含んじゃってて筋が悪いですが、 async / awaitthrows / try を組み合わせれば、純粋な非同期処理と純粋なエラー処理に分離できるはずです。
2:29 AM
async throws -> T な関数は、 Promise<Result<T>> を返すようなものですね。
Avatar
norio_nomura 5/2/2017 2:30 AM
C#はスレッドで実装されてるぽいけど、Swiftもスレッドでってことは無さそう。
2:31 AM
C#もキューみたいなのあった気もする。
Avatar
throws tryだと、catchすることで純粋なTを取り出すことが可能ですが
Avatar
あー、 Promise ベースで考えてたので、 await 以降がどこのスレッドで実行されるかは async な関数を実装する側次第と考えてましたが、 Promisereturn するのと同じ自由度でそれを書くにはどうするのかよく考えてませんでしたね。
Avatar
async awaitは、同等のことは可能ですか?つまり、yield的な待ち合わせの機能
2:32 AM
deferがそれかな
Avatar
throws tryだと、catchすることで純粋なTを取り出すことが可能ですが
catch じゃなくて try で、じゃないですか? catch の方は Error ですよね?
Avatar
えっと、tryを使ったfuncの返り値をTにするために、catchでError処理をするなりして型を純粋なTにする
Avatar
C#はスレッドで実装されてるぽいけど、Swiftもスレッドでってことは無さそう。 C#もキューみたいなのあった気もする。
これに関しては、大本の非同期化する関数自体が async になって、どれを使うかによって実現されることになると思います。
Avatar
func pureInt() -> Int { do { return try throwAble() } catch { //Error処理 return someValue } }
2:37 AM
こういうの
Avatar
ちがうか。↓みたいなのがあればいいのか。 func makeAsync<T>(_: ((T) -> ()) -> ()) async -> T
2:42 AM
func foo() async -> Int { return await makeAsync { emit in DispatchQueue.main.asyncAfter(deadline: .now + 5.0) { emit(42) } } } (edited)
2:44 AM
現実的にはエラーが起こることも考えて↓かな。 func makeAsync<T>(_: ((T) -> ()) throws -> ()) async rethrows -> T
2:45 AM
@tarunon それってエラーからの回復だから、非同期処理に対応させると同期化だと思うんですよね。
2:46 AM
なので、 do - defer 相当のものは同期化というのがあり得る気がしてるんですが、現実的にはノンブロッキング化する方が必要だろうなと。
2:46 AM
もし同期化であれば
2:47 AM
↓みたいな感じになるのかな・・・。 func pureInt() -> Int { do { return await asyncInt() } wait }
2:48 AM
こっちの方が理論上は catch によく対応してるような気はします。
2:49 AM
ノンブロッキングの方は、そういう関数があればいいだけな気もしますね・・・。 func doAsync(_: () async -> ()) みたいな。 (edited)
Avatar
ノンブロッキングはそもそも
2:50 AM
doの中でコールバック関数呼べば良いだけな気も
Avatar
↓ということですか? func onClick() { do { let selectedIndex = await actionSheet([...]) ... } }
2:52 AM
↑のケースは、( throws / try と同様に) onClickasync でないとコンパイルエラーがいいと思うんですよね。
Avatar
あいや
2:53 AM
話が噛み合ってない気がした、ちょっと考えます
Avatar
norio_nomura 5/2/2017 3:00 AM
async がついたメソッドは await 付きで呼ばなければならず、 await を呼ぶメソッドは do {} で同期化しない限り async としなければいけない。
3:01 AM
throwstry と同じ感じか。
Avatar
はい、そうです。
3:03 AM
理論上も throws -> T-> Result<T> と等価で、 tryflatMap と等価だから、 async -> T-> Promise<T> にも同じ関係が成り立つはずなんですよね。 ResultPromise も同じくモナドなので。
Avatar
norio_nomura 5/2/2017 3:07 AM
await で非同期実行が始まるのは、スコープ内で await 以降に await と無関係なコードが現れた時、って感じかな。
Avatar
// a(), b() は () async -> Int let a = await foo.a() let b = await bar.b() let sum = a + b ...// a(), b() は () -> Promise<Int> foo.a().flatMap { a in bar.b().flatmap { b in let sum = a + b ... } } のような感じですね。 (edited)
3:10 AM
なので、 a に代入するところから非同期に行われます。
Avatar
barはmapでは
3:11 AM
thenならオーバーロードですが
Avatar
let a = foo.a() let b = bar.b() let aa = await a let bb = await b let sum = aa + bb はあるんですかね
Avatar
@t.ae それはないね。
Avatar
async関数がawaitできるだけなら↑ができないきがする
Avatar
@tarunon sum を返しているわけでなく、後続処理があるイメージです。
3:13 AM
@t.ae それはできなくていいと思います。それができるということは、モナドなまま値を取り回すことになるので。それを避けているのが今の Swift の throws / try の構文かと。
Avatar
非同期処理を複数同時に走らせられないのはなんだかなーという気分が。 Promise使えって話ですが。
Avatar
確かに、簡単に複数同時に走らせる方法はほしいね。
3:16 AM
↓の場合、 ab は独立だから、並列して走ってもいいんだけど let a = await foo.a() let b = await bar.b() let sum = a + b (edited)
Avatar
bar.bではaを評価してないので、同時に走れても問題ない気がする
Avatar
あえて a が終わってから b が走ってほしい場合とかもあるから
Avatar
非同期だとこの手の合成問題が出てきますね、try-catchではなかった問題
Avatar
( Web API へのリクエストを同時にたくさん投げたくないとか)
3:18 AM
それを↑レベルの手軽な構文でコントロールするのは、モナドの範疇外になってしまって難しいなぁ。
Avatar
それは非同期を提供するクライアント側が気にすれば良いことで、async-awaitは愚直に並列で実行して良い気がします
Avatar
Promise モナドは「今は値はない、けどいずれ手に入る」を表して非同期的にイミュータブルに振る舞うだけだから、
3:19 AM
↑の例で a()b() が並列に実行されようが順番に実行されようが結果の変わらない世界の話なんだよなぁ。
3:20 AM
@tarunon その場合、 let bar = await foo.bar() let baz = await bar.baz() だと順番に走るんですよね?
3:20 AM
結構わかりづらくないですか?
Avatar
Promise.all的な関数を用意してもらえばそれで良い気がする。
Avatar
asyncで生成された値を評価するなら、待ち合わせが必要
3:22 AM
ですが、それ以外は極力並列に走って貰わないと、パフォーマンスが出なさそう
Avatar
値を使う瞬間に待ち合わせが発生するようにする?
Avatar
そんなイメージです
Avatar
分かりづらくはあるけれどそれで問題が起こるケースが思いつかないですねぇ。
Avatar
値を使わない場合に問題があるなら、それは非同期関数を提供する側が制御すれば良いはず
Avatar
たとえば、 Qaleidospace では Qiita の API を叩いてるんだけど、回数に制限があるから、順序関係のないコールの間でも間隔をコントロールしてて、そういうときにシーケンシャルにつながってほしいとかはある。けど、シンプルな構文でなら @tarunon さんの言うような、待ち合わせが必要な場合だけ待つ方式が良さそうですね。
Avatar
それって、APIClient作って、そっち側に一定時間に何回まで叩けるみたいな
3:27 AM
Queueを内蔵してasyncはそのまま提供すれば
3:28 AM
普通に隠蔽できると思うんですよね
Avatar
とすると、 // a(), b() は () async -> Int let a = await foo.a() let b = await bar.b() let sum = a + b ...// a(), b() は () -> Promise<Int> let a = foo.a() let b = bar.b() a.flatMap { a in b.flatMap { b in let sum = a + b ... } } 相当になりますね。
Avatar
あとはawaitって書いてあるところで待ってないという気持ち悪さが残るだけですね。
Avatar
let bar = await foo.bar() let baz = await bar.baz() ... の場合は foo.bar().flatMap { bar in bar.baz().flatMap { baz in ... } }
3:31 AM
あとはawaitって書いてあるところで待ってないという気持ち悪さ
たしかに
3:32 AM
まったく話は変わるんですが、 Array<Optional<T>> だけに extension 書くとかってかけます?
3:33 AM
extension Array where Element == Optional まで書いて、型パラメータが書けなくて固まった・・・
Avatar
norio_nomura 5/2/2017 3:41 AM
書けそう error: reference to generic type 'Optional' requires arguments in <...> extension Array where Element == Optional { ^ <Any> (edited)
Avatar
<Any>はともかく<Wrapped>はできるんですかね?
Avatar
typealias ArrayO<T> = Array<Optional<T>> extension ArrayO { func foo() -> Bool { return reduce(true) { $0 && ($1 != nil) } } } ↑は書けたけど、普通に Arrayextension になってる・・・
Avatar
norio_nomura 5/2/2017 3:47 AM
ああ OptionalWrapped は型指定出来無さそう
Avatar
@norio_nomura 型指定というか、型を指定せずにプレースホルダーのままにしたいです・・・
Avatar
norio_nomura 5/2/2017 3:48 AM
ジェネリックパラメータを指定できないから無理そうですね
Avatar
1> extension Array where Element == Optional<Any> { 2. func foo() -> Bool { 3. return reduce(true) { 4. $0 && ($1 != nil) 5. } 6. } 7. } 8> let a: [Int?] = [2, 3, 5] 9. print(a.foo()) error: repl.swift:9:7: error: '[Int?]' is not convertible to 'Array<Optional<Any>>' print(a.foo()) ^
3:51 AM
うーん、辛いですね・・・
Avatar
Optional<T>にextension生やしてそれを呼ぶとかでは? 処理によりますが
3:53 AM
reduceか。reduceはだめそうですね
Avatar
実際にやりたいのは Array ですらなくて、 Promise<Optional<T>> についてのみの extension を書きたいのです・・・
3:54 AM
せっかく where T == Foo が書けるようになって、演算子を一掃できると思ったんだけど・・・。
Avatar
norio_nomura 5/2/2017 3:55 AM
protocol HasWrappedType { associatedtype WrappedType } extension Optional: HasWrappedType { typealias WrappedType = Wrapped } extension Array where Element: HasWrappedType { func foo() -> Bool { return reduce(true) { $0 && ($1 != nil) } } } let a: [Int?] = [2, 3, 5] print(a.foo()) let b: [Int] = [2, 3, 5] //print(b.foo()) // error: type 'Int' does not conform to protocol 'HasWrappedType' (edited)
👍 1
Avatar
なるほど・・・
3:57 AM
ワークアラウンドの protocol を外部に露出しないといけないですが、仕方ないですね・・・
3:57 AM
ありがとうございます!
🙂 1
Avatar
norio_nomura 5/2/2017 4:08 AM
StringBidirectionalCollection に変わるので joined() の型も変わってしまう。 var str = [ "Hello, playground" ].joined() type(of: str) // 3.1: String.Type, 4.0: FlattenBidirectionalCollection<Array<String>>.Type
Avatar
このあたりの変換後の型を Array にするのか lazy な型にするのかって難しいですよねぇ・・・
Avatar
norio_nomura 5/2/2017 4:10 AM
extension Array where Element == String { public func joined(separator: String = default) -> String } より extension Array where Element : BidirectionalCollection { public func joined() -> FlattenBidirectionalCollection<Array<Element>> } が優先されてる。
4:11 AM
優先順位の処理、これであってるのかな。
Avatar
ええっ、前者の方が specific に見えるのに、そんなことになるんですか?
Avatar
norio_nomura 5/2/2017 4:11 AM
昨日ビルドしたtoolchainでこうなります。
Avatar
なるほど・・・
Avatar
norio_nomura 5/2/2017 4:14 AM
SE-0166 と SE-0167 を試そうかと。
Avatar
試したいですね。
Avatar
norio_nomura 5/2/2017 4:17 AM
署名したインストーラ作ったけど、使ってみますか?
Avatar
Now that String conforms to the BidirectionalCollection protocol, in the expression let x = [""].joined() the best matching overload for joined is no longer the one returning String. Fixes: rdar://...
👍 1
Avatar
norio_nomura 5/2/2017 4:19 AM
出来立てだw
4:19 AM
4.0 SNAPSHOT そろそろなのかなあ
Avatar
署名したインストーラ作ったけど、使ってみますか?
Swift のインストーラーですか?
Avatar
norio_nomura 5/2/2017 4:19 AM
そそ
4:20 AM
Discordのファイル共有は50MBまでか。
Avatar
ありがとうございます。
Avatar
norio_nomura 5/2/2017 4:32 AM
warning: 'flatMap' is deprecated: This call uses implicit promotion to optional. Please use map instead. とか言われてビビる。
Avatar
ええっ
Avatar
ArrayのOptional flatMapですか?
Avatar
norio_nomura 5/2/2017 4:35 AM
ぽいです
4:37 AM
あいや、違うのかな。
4:39 AM
間違った使い方を指摘してくれてるぽい。
Avatar
おお!
4:39 AM
素晴らしい
Avatar
let a = [1,2,3].flatMap { $0 + 1 } こういうやつ。closure の返値が いったん Optional になるから、効率が わるい 悪かった。 (edited)
Avatar
norio_nomura 5/2/2017 4:42 AM
Due to implicit promotion to optional it is possible to call flatMap with a closure, that does not return an optional. This way the code works, but is unnecessary inefficient. Such uses of flatMa...
Avatar
norio_nomura 5/2/2017 4:51 AM
String を + で連結するとビルドが遅くなる問題って、まだ直ってないですよね。
Avatar
norio_nomura 5/2/2017 6:59 AM
Linux用のテストを返すallTests の定義で throws ではないメソッドを返す時にエラーが出る様になった。 extension ResolverTests { static var allTests: [(String, (ResolverTests) -> () throws -> Void)] { return [ ("testBasic", testBasic), ("testDefault", testDefault) ] // .map { entry in (entry.0, { entry.1($0) }) } // workaround } } … error: cannot convert value of type '(ResolverTests) -> () -> ()' to expected element type '(ResolverTests) -> () throws -> Void' ("testBasic", testBasic), ^~~~~~~~~ (edited)
Avatar
norio_nomura 5/2/2017 8:51 AM
SE-0166 イマイチかも…
Avatar
マジすか。どこがだめですか?
Avatar
お、SE-0166は気になる
🙂 1
Avatar
norio_nomura 5/2/2017 9:04 AM
自前の Encoder を作ろうとしての感想です。 SE-0167で実装された JSONEncoderPlistEncoder をそのまま使うぶんには良いのかもしれません。
Avatar
自前実装のどのあたりでイマイチなことになりましたか? SE-0166 は自前 Encoder / Decoder 実装がうまくいかないと意味がないと思うんですよね。 JSON とかだけでなく、汎用的な仕組みとして作られているのがおもしろいところだと思うので。 (edited)
Avatar
norio_nomura 5/2/2017 9:07 AM
libYAML のラッパーである https://github.com/jpsim/Yams/Encoder にするにはどうしたら良いのか?を前提にコードを眺めていました。
Yams - A Sweet and Swifty YAML parser.
Avatar
なるほど。 YAML だと JSON と同じだからできそうな気がしますが、 JSONEncoderJSONSerialization に渡すための NSMutableDictionary を生成すればいいけど、 Yams 用のインプットを Encoder の仕組みで組み立てるのが難しいとかですか?
Avatar
norio_nomura 5/2/2017 9:17 AM
Node っていうのが Yams での値/コンテナなのですが、これを enumstruct のペイロードで作ってしまっているので、逐次シリアライズした NodeKeyedEncodingContainerProtocol とかの内部情報として持てなくなってしまいました。
9:20 AM
JSONEncoderPlistEncoder はどちらも内部形式は NSMutableArrayNSMutableDictionary で、入れ物を親のコンテナに入れてから参照してる。
Avatar
Node を逐次シリアライズするのではなく、 _JSONEncoderNSMutableDictionary を組み立てるのと同じように、コンテナ経由で Node を組み立てて、最後にシリアライズではうまくいきませんか?
Avatar
norio_nomura 5/2/2017 9:26 AM
うまくいくとは思いますが [AnyHashable: Any] を得るために、PropertyListEncoder とほぼ同じコードを再実装しないといけない感じです。
9:26 AM
PropertyListEncoderData ではなく [AnyHashable: Any] を吐き出す仕組みがあると、幸せになれそう。 (edited)
Avatar
たしかに Encodable で表現できるデータ構造って似たようなものだから、 Dictionary 化するヘルパー Encoder みたいなのがあればその後が楽そうな気もしますね。ちょっとまだ自分で実装してないのでイメージがちゃんとできてないかもですが。 (edited)
9:32 AM
もちろん、 Dictionary を経由することでパフォーマンスを損ねるケースもあるので、 Encoder が提供しているような直接組み立てていくための仕組みは必須ですが。
Avatar
norio_nomura 5/2/2017 9:34 AM
まあでも、参照型の Node を作ればそれなりにいけそうな気もしてきました。
Avatar
norio_nomura 5/2/2017 10:32 AM
ちょっと変な方向から入ってしまったけど、SE-0166普通に使うぶんには簡単で良い感じ。
😋 2
Avatar
昨日の async / await の話、 Swift 5 についての議論が始まったら swift-evolution に投稿してみようかと思うんですが、↓みたいな感じでどう思います?わかりづらいところとか変なところとかあれば。 https://gist.github.com/koher/3e04b4f1b8adbbf0379d38c0ad83a3ea ノンブロッキング化する方法についても書いた方が良さそう。
Avatar
asyncとthrowsを組み合わせた時に何が起こるのかが解りにくい気がします
3:17 AM
1. 入れ子関係は固定なのか (必ずasyncが外側? 2. Errorの扱いがどうなるのか (↑の通りなら () async -> Error になっている? 3. waitとcatchの併用が可能なのか、併用したときのErrorの扱いについて
Avatar
@tarunon ありがとうございます。修正してみます。
11:28 PM
2 はどういうことですか?
Avatar
waitでなければ、catchのタイミングも非同期化しますよね?(あっている?
Avatar
async throws な関数をコールして catch だけするとどうなるのかということですか? (edited)
Avatar
はい
Avatar
そうですね。その場合は catch が非同期化されますね。
11:42 PM
Details みたいな形でそういう説明を足した方が良さそうですね。ありがとうございます。
Avatar
@tarunon#5049 「waitとcatchの併用」については downloadFooSync がそうなってました。また、 nonblock について書き足し、その中で catch しかしない例を追加しました。
3:08 AM
asyncthrows はどの順に書いても async が外側扱いがいいんじゃないかと思っていますが、そのあたりの詳細は ML で議論されればいいのかなと思います。あまり詳細に踏み込むと読むのが大変なのでとりあえず提案を投げるにはこれくらいのボリュームがいいのかなぁと。 (edited)
Avatar
なるほど、それもそうですね。
Avatar
モナドの中でenumを扱うときに、flatMapでassociatedvalueを取り出したくなることありませんか?上手い方法無いのかな
5:12 AM
enum MyEnum { case foo(Int) case bar(String) } func someAction(elements: [MyEnum]) { elements.flatMap { $0.foo } // ← [Int]が欲しい }
5:13 AM
foo: Int?とか生やして誤魔化してるけど流石に増えてくると辛くなってきた
Avatar
うーん、↓とかしか思いつかないですねー。 elements.map { guard case let .foo(foo) = $0 else { fatalError() } return foo }
Avatar
fatalは流石に困るw
6:01 AM
computed var foo: Int? でflatMapが妥当ですかねぇ、しょうがないか
Avatar
ああ、そうか。↓ですね。 elements.flatMap { guard case let .foo(foo) = $0 else { [] } return [foo] } (edited)
Avatar
まあ事実上そうですね
6:04 AM
多分ほぼ全てのモナドはOptional互換ではあるはずなので
6:04 AM
enum側にOptionalのアクセサ用意するのが妥当っぽい、となると言語機能でサポートして欲しいなーとなってくる
Avatar
↑って汎用Eitherがほしいって話な気がします。
Avatar
汎用Eitherというかですね
6:05 AM
Viewとロジックをつなぐのに、大量にイベントエミッター書くのがだるくて
6:05 AM
enumで流してしまえ~と思って public enum Output { case dataSources([Model]) case loading(Bool) } こういうのを書くと
6:06 AM
使う側でswitch書くのがしんどくなってしまった
6:06 AM
caseは大量に増えることもあり得るので、汎用Eitherが、n個のパターンで使えればOKっぽい
Avatar
うーん、n個のケースのそれぞれをflatMapで残したいとすると、やっぱり var foo: Foo? とかをそれぞれ作るしかない気がしますねー。
6:41 AM
case .foo(return) ?? nil みたいな書き方ができればいいんですが。パターンマッチング部分を抽象化できれば関数にできるんですけどね。
Avatar
パターンマッチの抽象化ほしいですね
Avatar
What do you mean Swift doesn’t have mixed-type arithmetic? let (x : Int, y : Double) = (3, 1) let result = Int + Double // 4
12:18 AM
これ動くの謎ですねw
Avatar
えぇ…
Avatar
ん?これって単にラベル付きタプルとして解釈されてるんじゃないですか?
12:26 AM
ラベル xy を持った IntDouble という定数にそれぞれ 12 が代入されてて
12:26 AM
(それらの型は Int です)
12:26 AM
それが足されてるだけに見えます。
12:28 AM
↓のような意味だと思いますが、明示的に型を書くとエラーになりますね・・・。 let (x: Int, y: Double): (Int, Int) = (1, 2) let s = Int + Double
12:29 AM
1> let (x: Int, y: Double) = (1, 2) 2. let s = Int + Double Int: Int = 1 Double: Int = 2 s: Int = 3
12:29 AM
1> let (x: Int, y: Double): (Int, Int) = (1, 2) 2. let s = Int + Double error: repl.swift:1:6: error: tuple pattern element label 'x' must be '_' let (x: Int, y: Double): (Int, Int) = (1, 2) ^
Avatar
let (x:Int,y:Double)←これが型宣言ではないのがポイントっぽい
12:39 AM
でも定数名を型名と同じ宣言したらそれは弾いて欲しいですね
Avatar
うーん、 let (x, y): (Int, Double) = (1, 2) が正しいんでしょうが、ラベル付きタプルを宣言して代入という構文も、何のためにラベルがあるのか意味不明なので、 let (x: Int, y: Double) = (1, 2) とできてもいい気がしますね。
Avatar
そもそもこれができるのが罠ってことですねー どうしてもやりたい場合(って何だ)はバッククオートつければいいだけだし、弾いてほしいですね
Avatar
それはそれとして、ラベル付きならxとyはどこへ…?というのがあって、混乱を生んでいて良くない
1:24 AM
つまり、let (x:y,z:w) =(1,1)でも通るって事ですよね
1:26 AM
1:26 AM
フーム
Avatar
1> let (a: b, c: d) = (1, 2) b: Int = 1 d: Int = 2
1:29 AM
挙動が違う??
Avatar
いや、同じですね
1:30 AM
aとcは存在しない
Avatar
ああ
1:30 AM
代入の後でラベルを使おうとしてエラーですね。 (edited)
Avatar
sandboxもxとzが無なので
Avatar
ラベルはあくまでタプルに紐付いているはずなのでそれはいいとして、ラベルが書けるの自体がミスリーディングですよねぇ。
Avatar
let Int=1 let Double=2 _=(x: Int, y: Double) 実際にはこれと等価
1:53 AM
xとyへの参照は無、IntとDoubleが残る。 tupleの型宣言 typealias Foo=(x: Int, y: Double)と混ざって混乱する
Avatar
あははは
Avatar
でもlintで弾くしか無さそうだ
1:56 AM
例えばネストした型としてローカルなURLを作りたいとか、それが必ずしも型であるとは限らない(メタな挙動をする変数かも知れない)なので、
1:58 AM
とは言えwarningぐらいは欲しいかなw 型名を変数で上書きしてる、と
Avatar
型の上書きよりも、問題は let (foo: x, bar: y) = ... のラベルを書けることじゃないですか?コンパイルエラーでいい気が。
Avatar
それはそんな気がします
2:01 AM
いやーー
2:02 AM
そうか、そうなるか
2:03 AM
let (x,y)=(1,2)これタプルじゃなくて、xとyに1と2を代入、ですね
2:03 AM
じゃあラベル付きは完全にダメだ
👍 1
Avatar
む、タプルじゃないんですね
2:16 AM
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/BasicOperators.html#//apple_ref/doc/uid/TP40014097-CH6-ID60 >If the right side of the assignment is a tuple with multiple values, its elements can be decomposed into multiple constants or variables at once: let (x, y) = (1, 2) // x is equal to 1, and y is equal to 2
2:16 AM
本当だ、左辺は、 "multiple constants or variables" ではあるけどタプルじゃないのかー
Avatar
右辺はタプルで、それを平たく展開するための代入。なのでラベルが使えるのはおかしい、と言うことですね。
👍 1
Avatar
タプルとラベル関連でもう1ネタ
2:54 AM
これ、なんで制限されてるのか合理的な理由あるんでしょうかね
2:57 AM
と思ったけど自己解決 そもそもrequest parametesには括弧が必要だからですね
Avatar
tupleとargumentの境界は4で厳密になるんでしたっけ?今は曖昧ですよね
Avatar
そこらへん関わってそうなproposalsは、 3でimplemented: swift-evolution/0029-remove-implicit-tuple-splat.md at master · apple/swift-evolution https://github.com/apple/swift-evolution/blob/master/proposals/0029-remove-implicit-tuple-splat.md swift-evolution/0066-standardize-function-type-syntax.md at master · apple/swift-evolution https://github.com/apple/swift-evolution/blob/master/proposals/0066-standardize-function-type-syntax.md swift-evolution/0111-remove-arg-label-type-significance.md at master · apple/swift-evolution https://github.com/apple/swift-evolution/blob/master/proposals/0111-remove-arg-label-type-significance.md 4での総仕上げがこれ、ですかねー swift-evolution/0110-distingish-single-tuple-arg.md at master · apple/swift-evolution https://github.com/apple/swift-evolution/blob/master/proposals/0110-distingish-single-tuple-arg.md
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
Avatar
norio_nomura 5/6/2017 4:40 AM
ようやく SE-0166 準拠の YAMLEncoder が最低限動く様になった (edited)
㊗ 4
Avatar
@norio_nomura おお、素晴らしいですね!
🙂 1
2:37 AM
例の async / await について Ray さんが添削してくれたんですが、めっちゃ勉強になりますね。これがネイティブの英語力かぁぁ・・・。原文がほとんど残ってないw https://gist.github.com/rayfix/b5429a061a0fe34fa9326fe358dfdbe7/revisions
GitHub is where people build software. More than 21 million people use GitHub to discover, fork, and contribute to over 58 million projects.
Avatar
表現自体が違いますねw (edited)
😅 1
Avatar
norio_nomura 5/7/2017 1:00 PM
SE-0166 のEncoder & Decoderサポートのコードはこんな感じになりました。 https://github.com/jpsim/Yams/pull/43/commits/68c34b1ec8912688cfb1b0d23049e31ab9daf507 (edited)
Support SE-0166 Swift Archival & Serialization Fixes #38 This uses local built toolchain https://github.com/norio-nomura/swift-dev/releases/tag/20170501a TODOs for merging: Add text encoding dete...
😀 1
Avatar
norio_nomura 5/7/2017 2:02 PM
^SE-0166 対応を一通り実装してみての感想は、イマイチな部分もあるけど Mirror とかでシリアライズを作るよりはずっとマシ、ってところかな。
Avatar
この前ここで話してた SE-0171 の reduce について書きました。 http://qiita.com/koher/items/17636e95e18e529e5b9b
これまでの reduce は次のようなシグネチャでした。 ```swift func reduce( initial: T, combine: (T, Element) throws -> T) rethrows -...
👍 3
Avatar
norio_nomura 5/8/2017 3:50 AM
パフォーマンス云々を言うなら、辞書を init(minimumCapacity:) で作るとかした方が良いと思いました。
Avatar
コメントありがとうございます。キャパシティを確保しても計算量のオーダーレベルでは同じですし、 Before / After および for ループを使った場合との比較なのでキャパシティの話を混ぜるとわかりづらいかなぁと。
Avatar
norio_nomura 5/8/2017 4:04 AM
CoWだと辞書の元のキャパシティは維持されない様に見えるので、inoutだと再割り当てが確実に発生しないのはメリットに思えます。
4:07 AM
CoWで元のキャパシティが維持されない様に見えるのは、この辺り https://github.com/apple/swift/blob/3f68f2876ae6f859f777df638487544ddc62111d/stdlib/public/core/HashedCollections.swift.gyb#L4695
swift - The Swift Programming Language
Avatar
omochimetaru 5/8/2017 4:21 AM
COWでキャパシティが維持されるってどういういみですか?COWによってバッファのコピーが省略されて参照コピーになった際は、ストレージは共有されるけど、キャパシティ自体はストレージ自体に属するパラメータですよね
4:21 AM
実体のバッファコピーが起きた時に、新しく複製されたバッファにおいては、キャパシティが(例えコピー元が余裕のあるサイズになっていたとしても)それを引き継がずにリセットされる、という事?
4:22 AM
だとすると、Copy On Writeはあまり関係なくて、単純に、Dictinaryが実体コピーされたときのコストの話でしょうか
Avatar
norio_nomura 5/8/2017 4:43 AM
reduce へ渡す空の辞書を、生成されるであろう要素数を元に容量確保しておいても、最初のCoW発生時に辞書内の書き込み済み要素数を元に新しい辞書の容量が再計算されている様に見えます。 (edited)
4:48 AM
まあ、コピーされた時のコスト増だとも言えるかもしれませんが、コピーされないことによるメリットは最大限に享受したいなと。 (edited)
Avatar
omochimetaru 5/8/2017 4:51 AM
なるほど。 > メリットは最大限に享受したい
Avatar
仮に CoW でキャパシティが引き継がれるとすると、ループで毎回フルサイズ(最終的なサイズ)のバッファが確保されることになるので、かえって遅くなるんじゃないでしょうか。 inout のおかげで初期値をキャパシティ指定して渡すことの意味があるというのはその通りだと思うので、その点追記しておきます。
Avatar
↓連休中にレビュー入りしてた John McCall による Proposal 。 "This proposal is a core part of the Ownership feature, which was described in the ownership manifesto." らしい。 @omochimetaru が興味ありそう。 https://github.com/apple/swift-evolution/blob/master/proposals/0176-enforce-exclusive-access-to-memory.md
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
Avatar
omochimetaru 5/8/2017 6:28 AM
ちょうど読んでる
Avatar
@norio_nomura minimulCapacity の件、追記しました! http://qiita.com/koher/items/17636e95e18e529e5b9b/revisions/1?type=source (edited)
「Swift 4の新しいreduceが素晴らしいので紹介する」の編集履歴です。
🙂 2
Avatar
omochimetaru 5/8/2017 8:10 AM
struct Cat { var age: Int = 3 var po: Int { mutating get { age = 9 return age } nonmutating set { print(newValue) } } } こんな意味不明な事できた
Avatar
nonmutating 、 Swift が登場してすぐのときに Array の CoW がおかしくて、その関係で調査してたときに一度だけ使ったことある。
Avatar
omochimetaru 5/8/2017 8:12 AM
いま初めて書いたw
👍 1
Avatar
(2014.9.3に追記) 本投稿に書かれているのはbeta 2までの古いSwiftについての情報ですのでご注意下さい 。beta 3以降では、Arrayはletのときに要素が変更できなくなり、[すばらしく生まれかわり...
👀 1
Avatar
@moaible おお、よく発見できましたね!自分の古い投稿は見るのも恥ずかしいですねw
Avatar
norio_nomura 5/8/2017 9:25 AM
2週間以上DEVELOPMENT-SNAPSHOTが出てないけど、近日中に出そう。 https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20170501/004540.html
9:25 AM
Swift 4.0の変更がたくさん入ってるので楽しみ。
🙂 1
Avatar
↓これやっといて、 map[Element] を返すとか一貫性なくないですか?そして、 map についても Mapped を作ろうとしたら、 higher-kinded type がないといけないという・・・。 https://github.com/apple/swift-evolution/blob/master/proposals/0174-filter-range-replaceable.md
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
10:41 AM
最後に書かれてた。 It could be worthwhile to make a similar change to map, but this is beyond the capabilities of the current generics system because map does not preserve the element type
Avatar
mapは変更後の型Tがあるのに対してfilterは必要ないから差があるのか
11:51 AM
higher-kinded typeマジで欲しいですねぇ
🙂 1
Avatar
omochimetaru 5/9/2017 1:52 AM
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
1:52 AM
番号が楽しいことになってる
Avatar
omochimetaru 5/9/2017 1:59 AM
毎回あったのか。初めて見ました。
Avatar
norio_nomura 5/9/2017 2:33 AM
SE-0176は以前rintaroさんが言ってた -enforce-exclusivity=checked のやつか。
Avatar
enumのassocvalueをeither的に、is-a関係を作りたい欲が高まってきた
2:47 AM
protocolとgenerics駆使すれば、現状でも似たことは出来るかしら🤔
Avatar
omochimetaru 5/9/2017 2:47 AM
enumとcaseじゃなくてcaseにぶら下がってるassoc valueと?
Avatar
そう
Avatar
omochimetaru 5/9/2017 2:48 AM
T is Optional<T>.Some と同じ事をユーザ定義したいってこと?
2:48 AM
たるのんそれ嫌いじゃなかったっけ
Avatar
そうそうそう
2:48 AM
まあそうだねw
Avatar
omochimetaru 5/9/2017 2:48 AM
闇に堕ちたんですか
Avatar
えっとですねー
2:48 AM
原初の欲求としては、assoctypeに複数値を持たせたいんですよ
Avatar
omochimetaru 5/9/2017 2:49 AM
昨日話してた可変長ジェネリックか
Avatar
複数種類の型を定義すると、複数種類の実装のオーバーロードで実現される。
2:50 AM
これが出来るとですね、assoctypeで引数を束縛するような、2つの型の関係が
2:50 AM
1:1,1:多しか今は出来ないが
Avatar
omochimetaru 5/9/2017 2:50 AM
Tuple2にある機能はTuple3にも全て欲しい、みたいな?
Avatar
多:多が可能になる
2:50 AM
いや、タプルとは違うな
2:51 AM
Viewから実装を引っぺがして、それをGenericsに作ることで
2:51 AM
NibとGenerics型の共存が出来ないかなと考えてるところから派生してる
2:52 AM
これ自体は上手く行きそうなんだけど、Viewと実装の繋ぎ込みがfuncになっちゃって、型を書くのが怠いから、assoctypeで縛ろうとしたが…
2:52 AM
という感じ、Viewと実装をassoctypeに持つ第三の型を作ればいい気もするけど、登場人物はなるべく増やしたくない
Avatar
omochimetaru 5/9/2017 2:54 AM
よくわからないけど、型Aと型Xの組み合わせのときの処理を静的に定義したい、そのペア自体を型付けしたい?
Avatar
extension View: HasImpl { typealias Impl=Int } ↑これだと、Intしか実装がない。なので、IntかStringを使おうとすると↓ extension View: HasImpl { typealias Impl=Int|String } ↑こういうのが欲しくなる
2:55 AM
そうそう
Avatar
omochimetaru 5/9/2017 2:55 AM
(A/B/C) x (X/Y/Z) のような合成がしたいと
Avatar
そう!
Avatar
omochimetaru 5/9/2017 2:55 AM
で、 (*) x (X) とか (A) x (X) とか (A/B) x (*) の場合における実装を定義したい? (edited)
Avatar
えーっと、そこの掛け算全部書くのは吝かではない (edited)
Avatar
omochimetaru 5/9/2017 2:56 AM
なるほど
2:56 AM
あー、 A / B / C とかは個別の データモデル型とか 個別のViewだから enum にならんのか
Avatar
型を書くのが怠いから、推論機からポンッと出したいよね、という
2:57 AM
ABCは共通のデータモデル使うぞ
2:57 AM
データモデルの側が色々あり得る
Avatar
omochimetaru 5/9/2017 2:57 AM
型は違うんだよね?
Avatar
そこは別に同じでも良い
2:58 AM
えっとね
Avatar
omochimetaru 5/9/2017 2:58 AM
ふむ。
Avatar
これが出来ると、TableViewControllerを一個作っておくと、ユーザ一覧実装と、ツイート一覧実装をぶち込めば
2:58 AM
それぞれの振る舞いが出来るようになる
2:59 AM
CollectionViewControlldrに、同様にbindingの実装を加えれば、こちらにもユーザ一覧やツイート一覧をぶち込むことが可能
2:59 AM
で、そうするとですね、
3:00 AM
実装側は、モデルの型を持っているが、TableViewControllerにモデルの型を含む実装が必要。繋ぎ込むための関数をGenericsベースで作ろうとすると、多対多のassoctype宣言が必要に
3:01 AM
enumで行けないかな?→union!!!
3:01 AM
ってなった次第
Avatar
omochimetaru 5/9/2017 3:05 AM
GenericTableViewController < M : GenericTableViewcontrollerModelProtocol > extension TweetModel : GenericTableViewcontrollerModelProtocol { func bindToGenericTableViewController ... } こういう感じじゃ駄目なの?
Avatar
View自体にGenericsを入れるのはダメ
3:06 AM
Nibは使いたい(ワガママ)
👍 1
Avatar
omochimetaru 5/9/2017 3:06 AM
そこでNibが出て来るの・・・
Avatar
オートレイアウト手書きはやってられない
3:07 AM
多分、どこかprotocolに落として考えれば、通る型が作れるはずだから模索してみるかな
Avatar
何回読んでも超わかりにくい、端的にいうと、associatedtypeでオーバーロードがやりたいって話ですね
7:11 AM
結局unionが欲しいのと一緒だった
7:11 AM
🙄
Avatar
omochimetaru 5/9/2017 7:15 AM
protocol P { associatedtype AT } struct SP<T> : P { typealias AT = T } extension P where AT == Int { func po() { print("AT == Int") } } extension P where AT == String { func po() { print("AT == String") } } let intsp = SP<Int>() intsp.po() let strsp = SP<String>() strsp.po()
7:15 AM
associatedtypeでオーバーロードがやりたい
だけだと、これでできているように見える?
Avatar
Generics無しだと出来ないよね
7:15 AM
つまり
7:16 AM
同一のspからIntとStringでオーバーロードされたfunctionやfieldにアクセス出来る必要がある
Avatar
omochimetaru 5/9/2017 7:16 AM
どっちになるかは何をもって決まるの? (edited)
Avatar
かつ、Pで束縛するときのATがIntとStringどちらでも使えないといけない
7:17 AM
外側の型で束縛される
Avatar
omochimetaru 5/9/2017 7:19 AM
同一のspって、そのspの式の型はPって事?associated typeがあるからそのような変数は作れない
Avatar
norio_nomura 5/9/2017 8:22 AM
こんな感じ? protocol P { associatedtype AT } protocol HasStringProtocol {} protocol HasIntProtocol {} extension P where AT: HasStringProtocol { func po() -> String { return "string" } } extension P where AT: HasIntProtocol { func po() -> Int { return 1 } } struct StringAndInt: HasStringProtocol, HasIntProtocol {} struct S: P { typealias AT = StringAndInt } let s = S() let string = s.po() as String // "string" let int = s.po() as Int // 1
Avatar
@norio_nomura お、近い。これでpoがPの型から見えていればいけそう
9:00 AM
でも多分それ以上は出来ないですね、今の機能で欲しいものは作れない気がしているのであきらめムードです。
Avatar
protocol P { associatedtype T func hoge(t: T) } class MyClass {} extension MyClass: P { typealias T = Int func hoge(t: Int) {} } extension MyClass: P { typealias T = String func hoge(t: String) {} } func foo<MyP: P>(_ arg: MyP) where MyP.P == String {} // <- ここにMyClassを func bar<MyP: P>(_ arg: MyP) where MyP.P == Int {} // <- どっちでも入れれるようにしたい
Avatar
norio_nomura 5/9/2017 9:30 AM
無理ぽ
Avatar
UnionTypeがあれば
9:30 AM
Int|Stringで宣言して多分思い通りのものができそう
Avatar
最近Int|CountabelRange<Int>みたいなのをやろうとして、 結局ContableRangeをprotocolに従わせつつ関数側で型チェックってのになってしまったので Unitonがあると嬉しいですね。
Avatar
norio_nomura 5/10/2017 1:08 AM
subscript が identifier になるらしい。 間違い https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20170508/004549.html init みたいにメソッドとして参照できる様になるのかな。 ならない (edited)
Avatar
びっくりしました。一瞬キーワードが変わるという意味かと思いました。
Avatar
ヘッダー見ないとSubScriptあるの知れないからこれは嬉しそう
Avatar
foo.subscript ができるようになるのはうれしいですね。
1:40 AM
昨日話されてた Union Type については、影響範囲が大きすぎてなかなか難しいですよね・・・。
1:41 AM
Intersection Type はいらないのか、 Union, Intersection とオーバーロードの関係をどうするか、
Avatar
導入だけなら非破壊的な気がしますが
Avatar
サブタイピングがめちゃくちゃ複雑化するし
1:42 AM
Union Type は以前 swift-evolution でも議論されてたけど、概ね否定的な感じでした。
1:43 AM
個人的にはほしいときはありますが、
1:44 AM
基本的には Union みたいな Non-nominal type は必要最小限に留めて使うべきで、
1:44 AM
正しい用法用量を求めるのが難しそう・・・。まあ、それを言い出したらタプルと struct もすでにあるんですが。
1:45 AM
あと、 Smart cast もないと Union Type は使い物にならない。
Avatar
omochimetaru 5/10/2017 1:47 AM
(昨日のたるのんの話結局いまいち目的がわからなかった
Avatar
Intersection はオーバーロードと等価だから、↓みたいな問題も起こる。 func foo() -> Int { ... } func foo() -> Double { ... } // 今 let f: () -> Int = foo // () -> Int の foo が代入される // Intersection があったら let f: (() -> Int)&(() -> Double) = foo let g = foo // ↑と同じ let h: () -> Int = foo // この場合 h の実体は何? () -> Int の foo ?それとも f や g と同じ? (edited)
1:50 AM
あと、 Typed Throws が長い間議論されてるけど、導入するならエラー型を一つに絞るのがいいという話になってるけど、 Union Type があると func foo() throws BarError|BazError -> Foo ができるので複数エラー投げられることになってしまって台無しに・・・。
Avatar
omochimetaru 5/10/2017 1:50 AM
オーバーロードはintersection typeをもつ一つの型とはみなさないのが良さそう fの代入文がエラー
Avatar
@omochimetaru そうかなぁ。 Intersection があるならそれがやりたい気がする。
Avatar
omochimetaru 5/10/2017 1:54 AM
(() -> Int) & (() -> String) って () -> (Int | String) と等価か?
Avatar
Nominal なジェネリック型の型パラによる Variance も導入されてないのに、 Non-nominal な型のサブタイピングが導入されるとかきつそう。
Avatar
omochimetaru 5/10/2017 1:54 AM
いや、ちがうなあ
Avatar
違うね。
Avatar
omochimetaru 5/10/2017 1:55 AM
どちらでもあるんだから () -> (Int & String) と等価か
Avatar
それも違う。
1:56 AM
(Int|String) -> ()((Int) -> ())&((String)->()) は同じに見えるけど (Int|String) -> (Int|String)((Int) -> Int)&((String) -> String) は違う。
Avatar
omochimetaru 5/10/2017 1:58 AM
(Int|String) -> (Int|String) と ((Int) -> Int)&((String) -> String) これはわかる、引数で入れた型が返り値で出てくるっていう依存性が消えてるから違う
Avatar
() -> Int&Stringlet f: () -> Int&String = ... let r: Int&String = f() ができるけど、 (() -> Int)&(() -> String) は↓のどっちかしかできない。 let f: (() -> Int)&(() -> String) = ... let r1: Int = f() let r2: String = f()
Avatar
omochimetaru 5/10/2017 1:59 AM
え、でも、 r1 と r2 を合成して r が作れますよ
Avatar
それは (() -> Int)&(() -> String) を 2 回コールしないとダメでしょ。
Avatar
omochimetaru 5/10/2017 2:01 AM
型としては外からみれば1回のコールに見せかけられるのでは
Avatar
↓とか変じゃない? let f: (() -> Int)&(() -> String) = ... let r: Int&String = f() // 2 回コールされる
2:02 AM
r が二つのインスタンスの合成というのも変
Avatar
omochimetaru 5/10/2017 2:02 AM
型それ自体は本当に入ってる実体の数とは関係ない気がする たとえば Int & Int & String は Int & String だから
2:02 AM
Unionが畳み込めるのと同じような話で
Avatar
Union にせよ Intersection にせよ、複数のインスタンスを一つにまとめて扱うわけじゃなくて
2:03 AM
あくまで一つのインスタンスの性質の話じゃない?
2:04 AM
Intersection がある言語を使い込んだことがないけど、複数のインスタンスを一つのインスタンスのように扱えるものなの?
Avatar
omochimetaru 5/10/2017 2:06 AM
(() -> Int)&(() -> String) この型は () -> Int なんだから、一回呼び出せばIntが返るけど、 それと同時に () -> String なんだから、一回呼び出せば Stringが返るはずで、 それは () -> (Int & String) って事じゃないのかな () -> (Int & String) なら 1回呼び出せばIntが返るとも言えるし 同時に1回呼び出せば Stringが返るとも言える
2:07 AM
1つの値の性質の事だと思っているから、どちらかを呼び出すとか2回呼び出すとかいう話が出てくるほうが変な感じがする
Avatar
いや、 (() -> Int)&(() -> String) はただのオーバーロード。
2:07 AM
戻り値オーバーロードだからわかりづらいだけで
2:08 AM
((Int) -> ())&((String) -> ()) だと考えてみたら自明じゃない?
2:08 AM
foo(42)foo("xyz") ができるだけ。
Avatar
omochimetaru 5/10/2017 2:08 AM
((Int) -> ())&((String) -> ()) == (Int | String) -> () だと思う
Avatar
((Int) -> Int)&((String) -> String) でもいいけど。
Avatar
omochimetaru 5/10/2017 2:09 AM
それは1つの関数型には畳み込めない
2:09 AM
僕が存在すると思ってる型変換規則は2つあって
Avatar
1つの関数型には畳み込めない
このことが & はオーバーロードを表すことを示してるのでは?
Avatar
omochimetaru 5/10/2017 2:10 AM
いや、それはオーバーロードの概念がインターセクションと違う事を示しているだけで
2:10 AM
一般的に拡大するのは違うと思う
2:11 AM
(A -> B) & (A -> C) == (A) -> (B & C) (A -> B) & ( C -> B) == (A | C) -> B の 2つだけが適用できる
2:12 AM
「オーバーロード == 関数型2つのインターセクション」っていう仮定が正しければkoherの意見は一貫してるけど
2:12 AM
その仮定がそもそも違って
2:12 AM
オーバーロードのほうが条件が厳しい合成の概念で
2:12 AM
それをインターセクションと考えるとおかしくなるんじゃないかと思ってる
2:12 AM
SwiftのTagged UnionがUnion Typeよりも厳しくて畳み込んだりできないのと同じように。
2:13 AM
IntersectionTypeがある言語を僕も使ったことはないけど。
Avatar
そもそも二つのインスタンスを一つにまとめた存在というのがあり得るのがおかしい気がする。
Avatar
omochimetaru 5/10/2017 2:20 AM
あーそれは、違うと思います
2:20 AM
型の話とインスタンスの実体のかずがうんたらというのは別で
Avatar
↓ができるってことでしょ? let a: Int&String = 42&"xyz"
Avatar
omochimetaru 5/10/2017 2:20 AM
はい
2:21 AM
でもそれはその aInt を要求するところや String を要求するところ 両方にかけてコンパイルできる
2:21 AM
というだけの話で
2:21 AM
たとえば
2:21 AM
struct IntAndString { var i: Int var s: String } (edited)
2:21 AM
これでも満たせる
2:22 AM
.i.s のメンバアクセスをコンパイラが自動注入すれば
2:22 AM
式としてはそれで成立させられる
Avatar
そもそも何故欲しかったのかの注釈、 protocol Receiver { associatedtype Arguments func foo(_ arguments: Arguments) } protocol Sender { associatedtype Returns func bar() -> Returns } この二つの型を合成して使うことを考える、 Receiver.Argnumentsと、Sender.Returnsが一致していれば合成可能、故に合成関数は次の定義 func combine<R: Reciever, S: Sender>(reciever: R, sender: S) where R.Argnuments==S.Returns
Avatar
omochimetaru 5/10/2017 2:22 AM
Cat is Animal 則を満たす時に暗黙の調整処理が挿入されるのと同じ話だと思います
2:23 AM
ちょっと離席
Avatar
Recieverの実装を持っていて、受け取れる型の幅を増やしたい、unionがあればそれを使えば済む。しかし無い場合、 Recieverの型をenumにしたとして、それはつまり、Senderの型も書き換えないと行けない。
Avatar
@omochimetaru Intersection はあくまで型の合成であって、インスタンスの合成は異なる概念だと思う。
Avatar
で、↑だけど、さっき朝ご飯食べてたら多分天命降りてきたんで無くても辛さ解消できるかも知れない。
Avatar
↓でも Overload のことしか書いてなくて、インスタンスの合成なんて話は出てきてないように見える。
This corresponds precisely to our intended behavior for overloading
http://cs.brown.edu/courses/cs173/2012/book/types.html#%28part._.Intersection_.Types%29
2:31 AM
Union や Intersection はあくまで型の話であって、インスタンスは常に一つで、そのインスタンスがどのように振るまうかという話だと思う。 (edited)
Avatar
the DeclName for subscripts is just the Identifier “subscript”
この話ですけど、今までは subscript が内部的に単なる identifier としてモデリングされていたおかげで、 TypeCheckerで obj.subscript で参照できてしまい、SILではそんなこと意図されてなかったのでクラッシュしていたのが、この修正により 'Foo' has no member 'subscript' としてエラー出せるようになるっていうだけの話なのです。 https://bugs.swift.org/browse/SR-2575
🙏 1
Avatar
おおお、ほんとだ・・・。衝突した。 struct Foo { subscript(i: Int) -> Int { return i } func `subscript`(_ i: Int) -> Int { return i + 1 } } 9> Foo().subscript(42) error: repl.swift:9:1: error: ambiguous use of 'subscript' Foo().subscript(42) ^ repl.swift:2:5: note: found this candidate subscript(i: Int) -> Int { ^ repl.swift:5:10: note: found this candidate func `subscript`(_ i: Int) -> Int { ^ 9> Foo().`subscript`(42) error: repl.swift:9:1: error: ambiguous use of 'subscript' Foo().`subscript`(42) ^ repl.swift:2:5: note: found this candidate subscript(i: Int) -> Int { ^ repl.swift:5:10: note: found this candidate func `subscript`(_ i: Int) -> Int { ^ 9> Foo()[42] error: repl.swift:9:1: error: ambiguous use of 'subscript' Foo()[42] ^ repl.swift:2:5: note: found this candidate subscript(i: Int) -> Int { ^ repl.swift:5:10: note: found this candidate func `subscript`(_ i: Int) -> Int { ^ (edited)
Avatar
class Foo { func `deinit`() {} } が出来なかったのが出来るようになったりするかもしれないけど、その程度。
Avatar
あれ?逆に foo.subscript は今でもできるのかと思ったけど・・・。 1> struct Foo { 2. subscript(i: Int) -> Int { 3. return i 4. } 5. } 6> Foo().subscript(42) Segmentation fault: 11
2:55 AM
1> struct Foo { 2. func `subscript`(_ i: Int) -> Int { 3. return i 4. } 5. } 6> Foo().subscript(42) $R0: Int = 42 7> Foo()[42] Segmentation fault: 11 (edited)
Avatar
この変更で `func subscript subscript がしっかり区別されるようになり、前者は foo.subscript 後者は foo[...]` でしか参照できなくなります。
Avatar
今 Segmentation fault なのも変じゃないですか?
Avatar
はい、それを修正するための変更です。
Avatar
あと、 foo.subscriptsubscript が参照できないと、今の Foo.init とかができるのと一貫性がないような気がします。
Avatar
思想的には subscript はプロパティであるっていうので現状になっている感じがします。
Avatar
なるほど・・・。 Generic だけできるようになって中途半端な状態になってしまいましたね💦引数はとれるし、 Generic にできるし・・・。
3:09 AM
throws もできるようしたらメソッド側に寄せられますが・・・。
Avatar
evolution 洗ったけど foo.subscript できるようにするという議論された形跡みつからず 😥
Avatar
なるほど。ありがとうございます。
Avatar
omochimetaru 5/10/2017 3:33 AM
@koher 僕もそう思っています。 > @omochimetaru Intersection はあくまで型の合成であって、インスタンスの合成は異なる概念だと思う。
Avatar
やりたいことも型合成メインでインスタンスの合成は考えてないですね
Avatar
omochimetaru 5/10/2017 3:35 AM
func combine<R: Reciever, S: Sender>(reciever: R, sender: S) where R.Argnuments==S.Returns
3:35 AM
これのなかみは
3:36 AM
func combine<R: Reciever, S: Sender>(reciever: R, sender: S) where R.Argnuments==S.Returns { receiver.foo(sender.bar()) }
3:36 AM
これであってる?
Avatar
そう
Avatar
omochimetaru 5/10/2017 3:36 AM
なるほどなるほど
Avatar
enumでEither作って、Sender側もEither対応したReturnsにするのが苦痛
3:37 AM
でも、EitherになったSenderを定義してオペレーターで変換して、型推論が頑張ってくれないかな?ってやったら、まあ上手く行ったw
Avatar
omochimetaru 5/10/2017 3:38 AM
あーー T -> Optional<T>.Some のユーザー定義がしたいって
3:38 AM
そういうことかw
3:39 AM
オペレーターじゃなくても
3:39 AM
func combine<R: Reciever, S: Sender>(reciever: R, sender: S) where R.Argnuments==S.Returns { receiver.foo(convertReceiverType(sender.bar())) }
Avatar
それは無理じゃない?
Avatar
omochimetaru 5/10/2017 3:39 AM
ようするにこういう形にして
3:40 AM
convertReceiverTypeが receiverの受け付けられる型のかずだけ
3:40 AM
オーバーロードをしておけばいいんじゃない?
Avatar
combine側をオーバーロードするのか
Avatar
omochimetaru 5/10/2017 3:40 AM
combine自体が複数ないとだめか?
3:40 AM
試してみる
Avatar
でもね、それ、combineを使ってる全ての関数がオーバーロード必要になって
3:40 AM
地獄だな
Avatar
omochimetaru 5/10/2017 3:41 AM
combineじゃなくてあいだにはさんでる convertReceiverTypeだけで
3:41 AM
いけないかなあ
Avatar
できない
3:41 AM
それを実現するにはunionいる、あるならそもやらなくて言い
Avatar
norio_nomura 5/10/2017 4:36 AM
evolution 洗ったけど foo.subscript できるようにするという議論された形跡みつからず 😥
@rintaro 間違った情報を正していただいて、ありがとうございます 🙏
Avatar
結局、ここらへんが落とし所っぽい。 enum Either2<A, B> { case a(A), b(B) } class MyReciever: Reciever { typealias Arguments = Either2<String, Int> } // このままだとStringを吐き出すSenderは使えない class MySender: Sender { typealias Returns = String } // Either変換を含めた魔改造type-erasureを作る class Sender2A<R1, R2> { typealias Returns = Either<R1, R2> init<S: Sender>(_ sender: S) where S.Returns == R1 } class Sender2B<R1, R2> { typealias Returns = Either<R1, R2> init<S: Sender>(_ sender: S) where S.Returns == R2 } // 変換オペレーターを差し込む prefix operator ~ prefix func ~<S: Sender, R>(_ sender: S) -> Sender2A<S.Returns, R> { return .init(sender) } prefix func ~<S: Sender, R>(_ sender: S) -> Sender2B<R, S.Returns> { return .init(sender) } combine(MyReciever(), ~MySender()) // OK!
Avatar
omochimetaru 5/10/2017 4:51 AM
あ、打ち合わせしてた
4:51 AM
connect(IntProvider(), IntOrStringConsumer()) { .lift($0) }
4:51 AM
↑これでどうでしょう
Avatar
やっぱそういうの付けなきゃいけない
4:51 AM
combine側にそれが必要だと、combineを利用するすべての関数で作らないといけない
4:52 AM
負の連鎖になるから、引数の時点で解決したほうが良いかなぁ
Avatar
omochimetaru 5/10/2017 4:53 AM
tarunonがやったほうほうでも ~ をつけるんだから同じじゃない?
4:54 AM
~ は短いけど何が起きてるかあとでわからなくなりそう
Avatar
いや、combineを利用して実装している関数に、機能を追加すること無く使えるのがポイント
4:54 AM
まあ~じゃなくて、.converted()でも良い
Avatar
omochimetaru 5/10/2017 4:54 AM
なるほど
4:54 AM
ようするにこれってモナドの.mapだよね
Avatar
そうそう
4:56 AM
最近Swiftの型でサブタイピング無くて発狂したらなんでもかんでも~で解決する癖がついてきた…
4:58 AM
明示的なサブタイピングの手法と考えれば、~で大体OKだな、という気がする。
5:00 AM
お、俺は間違ってない…間違ってないはずだ… https://github.com/tarunon/Hiyoko/blob/refactoring/viewmodel/Reactor/Sources/Either.swift#L626-L681
Hiyoko - https://www.hiyoko.co.jp, It's a sweets in Fukuoka. But this repo maybe become twitter app for iOS.
5:00 AM
改めて見ると笑うなこれ
Avatar
omochimetaru 5/10/2017 5:02 AM
関数を中にいれるのだと型が定まんないからだめなんだなあ
Avatar
それもそうね
Avatar
omochimetaru 5/10/2017 5:02 AM
オーバーロード探索の前に推論が終わらないといけないのか
5:03 AM
うまくいえないが
5:03 AM
プロトコルさしまくればなんとかなりそうだけどちらかって微妙な感じ
Avatar
全てをGenericsで定義していけば、多分うまくいくのだけど
5:04 AM
今回はViewControllerとViewはStoryboard/Nibを使うからGenericsダメって制限があるので
5:04 AM
そのジョーカーは使えない。
Avatar
omochimetaru 5/10/2017 5:05 AM
Genericsでも Int Or String が表明できないから無理じゃない?
Avatar
あーーー
5:05 AM
それも、そうだ
5:06 AM
この間の返り値のタプルで推論させたのは
5:06 AM
そもそも最初がサブタイピングあるやつだ
5:06 AM
今回は無い
5:06 AM
Avatar
omochimetaru 5/10/2017 5:06 AM
つまり、言語仕様上暗黙の互換性が無いけど、コンバータを通せば渡せるようなケースで、そのコンバータを書きたくないっていうのが
5:06 AM
一般化したやりたい事なんじゃないかな
Avatar
そうそう
5:07 AM
まあ暗黙的にそれを許すのはヤバなので
5:07 AM
オペレーターはかなり良い落とし所
Avatar
omochimetaru 5/10/2017 5:07 AM
で、たまたま今回のケースはその2者が union関係だったから、union typeがあったらよかった、ということで
5:07 AM
String と struct FilePath みたいな2者でも同じ課題があると思う
Avatar
あとコンバーターが、引数に入れてinitすれば済むレベルの単純さ
Avatar
norio_nomura 5/10/2017 5:57 AM
@tarunon TWITTER_CONSUMER_SECRET がコミットされてるけど大丈夫ですか? https://github.com/tarunon/Hiyoko/blame/cf0f137321ef26d20a2940dd8d76de598012d207/Hiyoko/AppDelegate.swift#L13
Hiyoko - https://www.hiyoko.co.jp, It's a sweets in Fukuoka. But this repo maybe become twitter app for iOS.
Avatar
うわーっ
5:57 AM
ありがとうございますw
Avatar
omochimetaru 5/10/2017 5:57 AM
おw
5:57 AM
ツイッタークライアント作ってたのか
Avatar
GW前に丼作ってて
Avatar
omochimetaru 5/10/2017 5:58 AM
mstdn - mastodonクライアントアプリ開発RTA
5:58 AM
RIPしてたw
Avatar
アレは投げたけど実験場は欲しいのでTwitterクライアントの形で継続してる
5:58 AM
w
5:59 AM
キーとシークレットRevokeしました。ありがとうございます! @norio_nomura
🙂 1
6:00 AM
最近まで気を付けてたけどついにやってしまった、適当な.gitignoreに書いたplistから読むようにしよう
Avatar
omochimetaru 5/10/2017 6:00 AM
.swiftでもいいんじゃね
Avatar
コンパイルエラーになってしまうのはヤの感じかなー
Avatar
omochimetaru 5/10/2017 6:00 AM
コンパイルエラーのほうがマシじゃん
Avatar
それもそうか
Avatar
omochimetaru 5/10/2017 6:00 AM
plist書き忘れて何故か動かないより
Avatar
丼はなんか
6:01 AM
コンシュマーキーとシークレット作り放題なんで
6:01 AM
適当にやっててそれを引き継いだのが災いした
Avatar
norio_nomura 5/10/2017 6:04 AM
plist の方が CI で楽できそう
Avatar
CIは多分、HiyokoKitしか見ないんで
6:08 AM
Hiyoko本体がコンパイルできないのは特に問題無さそう
Avatar
norio_nomura 5/10/2017 6:31 AM
2週間以上DEVELOPMENT-SNAPSHOTが出てないけど、近日中に出そう。
swift-DEVELOPMENT-SNAPSHOT-2017-05-09-a パッケージングのCIが完走しそう。 https://ci.swift.org/view/Packages/job/oss-swift-package-osx/3351/console
Avatar
norio_nomura 5/10/2017 7:01 AM
swift-DEVELOPMENT-SNAPSHOT-2017-05-09-a きた https://swift.org/download/#snapshots
Swift is a general-purpose programming language built using a modern approach to safety, performance, and software design patterns.
Avatar
omochimetaru 5/10/2017 7:03 AM
ここで落とせるxcodeって
7:03 AM
xcode-selectでmacの中でスイッチして使える感じですか?
7:03 AM
あ、でも ownership 試す時はビルド自体のフラグを変えないといけないのかな
Avatar
norio_nomura 5/10/2017 7:10 AM
Xcodeの中で切り替えられます。
Avatar
omochimetaru 5/10/2017 7:11 AM
!?
7:11 AM
Simulattors | Documentation しかなかった 2つ以上あると Toolchains が現れるのか
Avatar
norio_nomura 5/10/2017 7:12 AM
ビルド時のtoolchainを切り替える方法は色々あるのですが、 xcode-select では切り替えられなかったはず。 (edited)
Avatar
omochimetaru 5/10/2017 7:13 AM
ふむふむ
7:13 AM
切り替える仕組みがあるなら変に混ざったりしなそうだしダウンロードしてみよ
Avatar
norio_nomura 5/10/2017 7:13 AM
Xcodeの場合エディタサポートかがあるため、起動しているXcode.appインスタンス全体で切り替わります。
7:14 AM
xcodebuildxcrun-toolchain オプションがあったり、TOOLCHAINS環境変数を使ったり。
Avatar
omochimetaru 5/10/2017 7:16 AM
xcrun-sdk は割りとつかいます
Avatar
norio_nomura 5/10/2017 7:17 AM
$ pkgutil --pkgs|grep org.swift org.swift.3020170509a org.swift.31120170421a でインストールしてある swift.org からのスナップショットのIDを探せるので、それを TOOLCHAINS=org.swift.3020170509a swiftxcodebuild -toolchain org.swift.3020170509a … みたいにして使います。 (edited)
7:18 AM
$ xcrun -toolchain org.swift.3020170509a swift Welcome to Apple Swift version 4.0-dev (LLVM 6a9a7bf93b, Clang 288cf0b5d5, Swift 2e09c17818). Type :help for assistance. 1> (edited)
Avatar
omochimetaru 5/10/2017 7:21 AM
ほ〜〜〜〜
7:21 AM
ありがとうございます。
Avatar
norio_nomura 5/10/2017 7:48 AM
swift-DEVELOPMENT-SNAPSHOT-2017-05-09-a 壊れまくりな感じ…
😩 1
Avatar
omochimetaru 5/10/2017 9:00 AM
swift-algorithm-club - Algorithms and data structures in Swift, with explanations!
9:00 AM
Raywenderlichすご・・・
9:02 AM
めちゃめちゃいろんなアルゴリズムのサンプル
9:03 AM
おい
9:03 AM
switch pattern matchじゃない
Avatar
Swift その2 の最後の 3 日が投稿されなかったので 3 連投です。 [当初のアナウンス](http://blog.qiita.c...
Avatar
omochimetaru 5/10/2017 9:04 AM
if i % 5 == 0 { result += (result.isEmpty ? "" : " ") + "Buzz" }
Avatar
PR投げてみようかな
Avatar
omochimetaru 5/10/2017 9:04 AM
3の場合と5の場合が合体してFizz Buzzになるのはそれはそれで良さがある
Avatar
↑多分 @tarunon さんが求めてるもの
Avatar
ですです
9:05 AM
なんかif分岐がいっぱいあるの
9:06 AM
どの場合にどこ通って最終的にどうなるっていうフローを見なきゃいけなくて
9:06 AM
辛いなって思うようになってしまった
Avatar
guard があるせいで else をちゃんとかくってのはありますねぇ
Avatar
omochimetaru 5/10/2017 9:06 AM
var がどうなってるか覚えながら読まないといけないよね
Avatar
そうそう
9:07 AM
siwtch (/*必要なもの全部ここにドーンwww*/) { case /*なんか条件いっぱい*/: return /*結果*/ /*以下繰り返し*/
9:08 AM
マジでこれ脳に優しい
Avatar
3の場合と5の場合が合体してFizz Buzzになるのはそれはそれで良さがある
FizzとBuzzをそれぞれ一度しか書かなくて良いのか
Avatar
omochimetaru 5/10/2017 9:08 AM
@koher そう
Avatar
FizzとBuzzの重複避けるにしてもまだ↓の方がいい。 func fizzBuzz(_ numberOfTurns: Int) { for i in 1...numberOfTurns { var fizzOrBuzz = false if i % 3 == 0 { print("Fizz", terminator: "") fizzOrBuzz = true } if i % 5 == 0 { print((fizzOrBuzz ? " " : "") + "Buzz", terminator: "") fizzOrBuzz = true } if !fizzOrBuzz { print(i, terminator: "") } print() } }
Avatar
omochimetaru 5/10/2017 9:16 AM
まあfizzbuzzはおまけで、文字列探索とかランレングスとか線形回帰とかいろんな木があってすごいって思いました
Avatar
result += (result.isEmpty ? "" : " ") + "Buzz" はさすがにひどい
Avatar
転する時に役に立ちそうなレポジトリですね(直喩)
Avatar
omochimetaru 5/10/2017 9:18 AM
カンニングはいかんぞ
Avatar
ここはチェックするようにしとこ
Avatar
ソースだけじゃなくて解説まで書いてあるw https://github.com/raywenderlich/swift-algorithm-club/tree/master/Quicksort
swift-algorithm-club - Algorithms and data structures in Swift, with explanations!
Avatar
omochimetaru 5/10/2017 9:18 AM
うん 行列のところとか カラフルだった
9:18 AM
9:19 AM
Avatar
数字の組を色とスタイルで表現してるのか
9:19 AM
優しい
9:20 AM
N社も見習ってイカにスクリーントーンいれてくれ!
Avatar
Authors: Rintaro Ishziaki
10:43 AM
オーサーがタイポされとる
Avatar
@rintaro 今ってまだ新しい Proposal が受け付けられてるフェーズなんですか?こういう議論の余地なしで実装ファーストなものだったら OK ?イマイチ swift-evolution の空気がよくわからない・・・。
Avatar
正直 ノリはまったくわかりません 😅
Avatar
おお、 rintaro さんでもわからないんですね 😅
Avatar
まったく根回しとかしてないので、どうなんでしょうねぇ
Avatar
実装もあるし、内容的にもイケそうな気も。
10:53 AM
ってか、そんな仕様だったんですね。むしろバグ?
Avatar
需要は間違いなくあるはず。
Avatar
内容自体は OK で、今の時期に Swift 4 に取り込むのが OK なのかですよね。 (edited)
10:56 AM
まさに↓な感じ。
I hope this makes it through without generating a lot of extra discussion. I would love to have this in Swift 4, or the next regular update of xcode.
Avatar
とりあえず stdlib ではいまのところ #if swift(>=4.0) で enum case 追加みたいなのがないので、微妙なんですが、 https://github.com/apple/swift/blob/master/stdlib/public/core/HashedCollections.swift.gyb#L4348-L4349 の Linux には存在しないはずの case cocoa(CocoaBuffer) の扱いをみてると泣きたくなったので実装しちゃいました。
swift - The Swift Programming Language
😀 1
Avatar
ついこの間# !TARGET_INTERFACEBUILDER出来なくて😇したので凄くタイムリーだ。ありがとうございます!
😀 1
Avatar
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
10:32 PM
ちゃんと読んでないけど Carthage っぽくなるのかな?
10:34 PM
Carthage でも resolve コマンドほしいとずっと思ってた。
10:36 PM
色んな言語の Package Manager が dis られてるw
However, we think that a "lockfile" is a very poor name for this concept
Avatar
omochimetaru 5/11/2017 1:00 AM
ピンは消えたけど常にリゾルブドはできるようになる?
1:03 AM
流し読みじゃよくわからなかったからもう一度読んでみる
Avatar
omochimetaru 5/11/2017 1:22 AM
トップリポジトリに.resolvedが入ってれば同じ環境、ignoreしてればそれぞれその時の指定をみたす最新で解決
1:23 AM
でなんかそれとは別に個別の依存指定をみたすように修正するためにeditで編集モードに入ってなんたらかんたら
1:25 AM
これまでのpin仕様では個別にpinがあってデフォルトがpinされていて、何かやるにはunpinしたりする必要があって、混ざってややこしいから、解決したいのか完全固定したいのかの2つの要望をresolvedの有無で排他的に選択できるようにすればシンプルでいい
1:26 AM
みたいな話が書いてあるけどもともとのpinの仕様をちゃんと知らないからよくわからなかった。
Avatar
昨日の @rintaro さんの Proposal 、 Apple の中の人のコメントでも↓だから、何を evolution に通すべきなのかの明確な基準はなくて、コアチームの判断に委ねられているということかな? I'm in favor, certainly. I'd personally say this wouldn't even need to go through the full evolution process, but I'm not a core team member.
1:34 AM
Joe Groff も Seems reasonable to me. って言ってるしイケそう。
1:40 AM
Core Team メンバー自ら新しい提案を投げてるし、 swift-evolution のステータス謎。 https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170508/036582.html
Avatar
omochimetaru 5/11/2017 1:42 AM
この提案おもしろいな
1:42 AM
Characterは書記素クラスタだからUnicodeScalarの列とみなせるのか
1:42 AM
言われてみればできなきゃおかしいね
Avatar
この Ben Cohen さんって新しく Core Team メンバーになったんだけど、 Airspeed Velocity の中の人だったのか。
1:43 AM
airspeedswift has 9 repositories available. Follow their code on GitHub.
Avatar
Arrayをポインタで走査したい場合にCoWを走らせる方法って無いですかね? isKnownUniquelyReferencedで分岐できると良いんですが使えないようで。
2:12 AM
var a = [Int](repeating: 0, count: 10) var b = a let p = UnsafeMutablePointer<Int>(mutating: b) p.pointee = 100 // aも書き換わる
Avatar
omochimetaru 5/11/2017 2:12 AM
isKnownUniquelyReferencedはArray自体じゃなくて
2:12 AM
Arrayの中にあるバッファ(これは参照型ヒープオブジェクト)
2:13 AM
のはなしだよ。
Avatar
そこは分かってます。
Avatar
omochimetaru 5/11/2017 2:13 AM
はい
2:13 AM
あー、aとbを明示的にコピーしたいのか
Avatar
その上で外側にも使えたらコピーするかの分岐をこちらでできるなと
Avatar
omochimetaru 5/11/2017 2:13 AM
そのコードおもしろいな。
2:13 AM
コピーコンストラクタに渡したらどうですか?
Avatar
var a = [Int](repeating: 0, count: 10) var b = Array(a) let p = UnsafeMutablePointer<Int>(mutating: b) p.pointee = 100 print(a) print(b) [100, 0, 0, 0, 0, 0, 0, 0, 0, 0] [100, 0, 0, 0, 0, 0, 0, 0, 0, 0]
2:14 AM
ん?
2:15 AM
そういえばArray(a[0..<a.count])でもコピーできてないんでした。
Avatar
omochimetaru 5/11/2017 2:15 AM
あれ?CCtorでもだめなのか
Avatar
iterator渡してるだけだから
2:16 AM
ダメなのでは
Avatar
omochimetaru 5/11/2017 2:16 AM
Array(a[0..<a.count]) マジ?ARraySliceからArray化は明示的コピーのはずなのに・・・?
Avatar
ArraySliceが全体を指してる場合のみの振る舞いっぽいですね
Avatar
omochimetaru 5/11/2017 2:17 AM
a
2:17 AM
a.withUnsafeMutableBufferPointer は?
2:18 AM
public mutating func withUnsafeMutableBufferPointer<R>(_ body: (inout UnsafeMutableBufferPointer<Element>) throws -> R) rethrows -> R
2:18 AM
これはmutatingメソッドだからCOWが生じるはず
2:19 AM
ネストしちゃう点についてはクロージャ内の処理だけ別のメソッドに切り出すとか?
2:19 AM
このアプローチならSwiftのセマンティクスとしても変な事はしてない (edited)
Avatar
UnsafeMutableBufferPointerだといけますね。ありがとうございます。
Avatar
var ary = [1,2,3] ary.withUnsafeMutableBufferPointer { buf in print(ary.count) // -> 0 } この挙動おもしろいな。
Avatar
omochimetaru 5/11/2017 2:26 AM
!?
2:27 AM
ほんとうだ・・・
Avatar
body 内でArray操作されないように 一時的に self を書き換えてる。 https://github.com/apple/swift/blob/master/stdlib/public/core/Arrays.swift.gyb#L1758-L1773
swift - The Swift Programming Language
Avatar
omochimetaru 5/11/2017 2:28 AM
おー
2:28 AM
いまオーナーシップマニフェスト読んでる途中なんですけど
2:28 AM
こういうのがまさに
2:28 AM
現状のmutable参照を共有する場合に対する保守的な余計なロジックっぽい
Avatar
https://github.com/apple/swift/blob/master/stdlib/public/core/Arrays.swift.gyb#L1085 initこれですよね、Bufferを渡すときに同型(Array)なら同じものが渡るようになってるのかしら(つまりCoWの範疇になる?)
swift - The Swift Programming Language
2:35 AM
swift - The Swift Programming Language
Avatar
omochimetaru 5/11/2017 3:30 AM
Resilience(レジリエンス)について理解しないといろいろな事が深くわからないなあと最近思っていて
3:31 AM
でもあんまり話題に出ないのと、語としても見慣れない
Avatar
norio_nomura 5/11/2017 3:39 AM
swift-DEVELOPMENT-SNAPSHOT-2017-05-09-a 壊れまくりな感じ…
swift-DEVELOPMENT-SNAPSHOT-2017-05-10-a で直ってた。
(edited)
🙂 1
Avatar
@omochimetaru Proposal の "Effect on API resilience" の Resilience ?
Avatar
omochimetaru 5/11/2017 5:09 AM
そこにも出てきますね
5:09 AM
最近は 既存のコードえの影響とresilienceへの影響が並んでますね。
Avatar
Error Handling Rationale and Proposal の方に出てた Resilience は、修正に対してどれだけ柔軟性(許容性?)があるかみたいな概念だと理解してました。
Avatar
omochimetaru 5/11/2017 5:10 AM
そういう一般的な概念じゃなくて、ABI互換性とかの周辺の具体的な議論な気がしている
Avatar
Proposal の雛形には API resilience describes the changes one can make to a public API without breaking its ABI. Does this proposal introduce features that would become part of a public API? If so, what kinds of changes can be made without breaking ABI? Can this feature be added/removed without breaking ABI? For more information about the resilience model, see the library evolution document in the Swift repository.
5:11 AM
って書かれてる。
5:11 AM
リンクされてるドキュメント( "see the library evolution document in the Swift repository" )は↓ https://github.com/apple/swift/blob/master/docs/LibraryEvolution.rst (edited)
swift - The Swift Programming Language
5:12 AM
アーカイブフォルダのなかにそのまんまな文書もあるけどアーカイブなのが気になる
5:13 AM
resilience model, see the library evolution document < ってかいてあるなら
5:13 AM
そこを読むのがまずは一番良さそうだ。
Avatar
omochimetaru 5/11/2017 3:17 PM
https://github.com/omochi/swift-ownership-jp/blob/master/ownership-manifesto.md オーナーシップマニフェストを読みました。読み飛ばさないでちゃんと読みたかったので、全文を和訳しました。まだ読んでない人は良かったら参考にしてください。あと変なところは僕も自分でよくわからなかった部分なので助けてくれると嬉しいです。
Contribute to swift-ownership-jp development by creating an account on GitHub.
❤ 6
👍 1
Avatar
これコンパイル通るんだな 通らないで欲しい struct Hoge { var fuga: Int { return fuga } } let hoge = Hoge.init() print(hoge.fuga) // <- 無限ループで死
Avatar
omochimetaru 5/12/2017 1:18 AM
たまにやらかすけどスタックトレースですぐわかる
Avatar
fuga以外のところで条件回して終端のある再起を書けるっちゃ書けるので、弾くのは難しいかしら
Avatar
そっかあ
Avatar
omochimetaru 5/12/2017 1:22 AM
fuga自体がループしてることはフロー解析で確定できると思う
Avatar
ループがエンドレスかどうかを証明するのは無理じゃね
Avatar
こんなん書いてて最初なんで死ぬのか気づかなかった private let _event: PublishSubject<Event> var event: Observable<Event> { return event.asObservable() }
Avatar
omochimetaru 5/12/2017 1:23 AM
一般の停止性判定ができないだけで、あるケース単体について証明できる場合はあるよ
Avatar
_eventあぶがないので、eventSubjectとかにした方が良い
Avatar
なるほど
Avatar
つまり、証明できる範囲についてコンパイルを通さない、なら可能か
Avatar
omochimetaru 5/12/2017 1:25 AM
そう。
Avatar
でも中途半端っぽい
Avatar
omochimetaru 5/12/2017 1:25 AM
うん。
1:25 AM
複数のプロパティが絡んだ相互再帰とか
1:25 AM
一見無限再帰してるけど、クラスだからオーバーライドすればカットできるとか
1:25 AM
ちょっと複雑でループするケースとかしない場合があるが実行するとループになるケースとか
1:25 AM
同種のバグで潰せないものはたくさん残る
Avatar
それさ
1:26 AM
証明可能なもの=人間にもすぐ見つけられる
Avatar
omochimetaru 5/12/2017 1:26 AM
でもhirariが踏んでる最も単純なパターンぐらいは対応してもいいかもね
Avatar
だからやる意味ほぼないでは?
1:26 AM
いやこれ、これでも
1:26 AM
単純でもループしない場合あり得そうな気がしていて
1:27 AM
ん?するか
1:27 AM
眠たかった
Avatar
omochimetaru 5/12/2017 1:27 AM
structだからオーバーライドできないからね
Avatar
眠たかったw
Avatar
omochimetaru 5/12/2017 1:29 AM
$ brew info carthege $ brew info carthego
1:29 AM
カルタゴ、スペルがわからなくなるからきらい
Avatar
hageだよ
Avatar
hageで覚える
Avatar
omochimetaru 5/12/2017 1:30 AM
そこ同じ回答来るのかよw
Avatar
ハゲカート
Avatar
omochimetaru 5/12/2017 1:30 AM
ハゲカートw
Avatar
これでおもち君は二度と忘れなくなった
Avatar
omochimetaru 5/12/2017 1:30 AM
そうだね・・・w
1:30 AM
解決した。
Avatar
carthage使う度にアイヴが脳裏にちらつく呪いをかけておこう
Avatar
omochimetaru 5/12/2017 1:31 AM
carthageのhageはアイブの禿か
Avatar
結局カルタゴとカッセージどっちが日本では主流なの
Avatar
omochimetaru 5/12/2017 1:32 AM
これでcartはfor steveの意味なら完璧だな。
1:32 AM
@hiragram ハゲカート主流にしよう
Avatar
気に入りすぎでしょ
Avatar
omochimetaru 5/12/2017 1:33 AM
はい
Avatar
日本人と口頭で日本語で会話するときはカルタゴって言ってて、英語のときはカッセージていってる
1:33 AM
かーせーじかな
Avatar
omochimetaru 5/12/2017 1:34 AM
トマトとトメイトウ
Avatar
タマゴとタメイゴウ
Avatar
😋 1
Avatar
omochimetaru 5/12/2017 1:34 AM
エッグだわ
🍆 1
1:37 AM
ちなみにさっきのコード、今気づいたけど警告出てた。
Avatar
omochimetaru 5/12/2017 1:37 AM
警告全部けそ
1:37 AM
ちゃんとなおして
Avatar
コンパイラが警告してくれてたなら全部人間が悪いな
1:38 AM
滅ぼう
😆 1
Avatar
主な変更内容 GitHub で見やすいように Markdown ファイルを README に変更 オリジナルへのリンクを追加 翻訳元バージョンのコミットへのリンクを追加 ライセンスへのリンクを追加 どこからが本文化わかりやすいように本文開始前の前書きの後ろに水平線を追加
Avatar
omochimetaru 5/12/2017 2:01 AM
お、ありがとうございました。マージした。
Avatar
@omochimetaru 思ったんだけど、元の文書を initial commit にしておけば、今後のオリジナルの変更をそれに対して加えて、それをマージすることで自動的に和訳中の英文も更新できた気がする。
2:16 AM
今からでも、できる気もする。
Avatar
omochimetaru 5/12/2017 2:17 AM
ブランチわけっぱなしにして3点間マージを維持するのか
Avatar
はい
Avatar
omochimetaru 5/12/2017 2:17 AM
基本的に追記しかしてないからうまくいくはずですね
Avatar
original ブランチを作って、そこに原文つっこんで
2:17 AM
originalmaster でマージして master の今のバージョンをそのまま採用して
2:17 AM
ってやればいけそう。
Avatar
norio_nomura 5/12/2017 2:41 AM
おや? swift-4.0-DEVELOPMENT-SNAPSHOT-2017-05-09-a が出てる。
2:42 AM
あいや swift-4.0-DEVELOPMENT-SNAPSHOT-2017-05-11-a だった。
Avatar
norio_nomura 5/12/2017 3:37 AM
Swift 4.0 でこんな変更が必要ぽいのだけど、これって SE-0110 Distinguish between single-tuple and multiple-argument function types https://github.com/apple/swift-evolution/blob/master/proposals/0110-distingish-single-tuple-arg.md の影響なのかな? func run(_ options: NoOptions<SourceKittenError>) -> Result<(), SourceKittenError> { print(version) - return .success() + return .success(()) }
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
Avatar
おおお、面倒だけどわかりやすくはありますね・・・。
Avatar
型としての ()Void にすべき派。
👍 1
Avatar
omochimetaru 5/12/2017 4:33 AM
僕もどっちかといえば空タプルよりVoidのほうが好きです > 型としての () は Void にすべき派。
Avatar
自分は標準ライブラリとかだと () -> Void で定義されてるのでそっちで合わせてました
Avatar
omochimetaru 5/12/2017 4:41 AM
func f11(x: () -> ()) {} func f12(x: () -> Void) {} func f13(x: () -> (Void)) {} func f14(x: () -> ((Void))) {} func f15(x: () -> (((Void)))) {} func f21(x: (Void) -> ()) {} func f22(x: (Void) -> Void) {} func f23(x: (Void) -> (Void)) {} func f24(x: (Void) -> ((Void))) {} func f25(x: (Void) -> (((Void)))) {} func f31(x: ((Void)) -> ()) {} func f32(x: ((Void)) -> Void) {} func f33(x: ((Void)) -> (Void)) {} func f34(x: ((Void)) -> ((Void))) {} func f35(x: ((Void)) -> (((Void)))) {}
Avatar
((Void))は悪意を感じるw
Avatar
omochimetaru 5/12/2017 5:04 AM
@koher Diffにできた https://github.com/omochi/swift-ownership-jp/commit/02a3eab7b6a32bc8d58d963ec8758a7145330df6?diff=split このリポジトリにSE0716の和訳とか後に書くキータ記事も入れようと思ってるのでファイル名はREADMEから戻しました。 (edited)
👌 1
Avatar
norio_nomura 5/12/2017 7:27 AM
午前中に書いたコメントがforce pushの彼方に
Avatar
omochimetaru 5/12/2017 7:28 AM
すいません、何か見逃しちゃったのか
7:28 AM
あ、完全に initial からふっ飛ばしたから
7:29 AM
github上で見る方法がわからない・・・
Avatar
@omochimetaru Initial からやらなくても、孤立 commit 作ってそれを merge すればよかったのに・・・。 (edited)
Avatar
omochimetaru 5/12/2017 7:30 AM
孤立コミットはマージできなかった。
Avatar
え?できるでしょ?
7:30 AM
できないっけ??
Avatar
omochimetaru 5/12/2017 7:31 AM
[omochi@omochi-MB swift-ownership-jp (master=)]$ git merge original fatal: refusing to merge unrelated histories
Avatar
norio_nomura 5/12/2017 7:32 AM
まあ、僕が書いた場所が悪い。
Avatar
--allow-unrelated-histories つけてもダメでした?
Avatar
omochimetaru 5/12/2017 7:32 AM
@norio_nomura あ〜これ less .. than の形が読めてないですね ありがとうございます
🙂 1
7:33 AM
@moaible それは知らなかったです、いかにもできそうな名前
7:37 AM
ここは一個前の require が absolute よりも predictable であることを欲するよって
7:37 AM
話っぽいな
Avatar
Contribute to isolated-commit development by creating an account on GitHub.
7:37 AM
あ、まさにそれやって試してた
7:38 AM
$ git log --graph --all --decorate * commit 8959b3248ca9f6264f36a08d67d47e1cd1271d6f (HEAD -> master, origin/master) |\ Merge: 5494a14 773e8de | | Author: Yuta Koshizawa <koher@koherent.org> | | Date: Fri May 12 16:35:58 2017 +0900 | | | | Merge branch 'original' | | | * commit 773e8defca014cefed7d4aade63b9b22255772f5 (origin/original, original) | Author: Yuta Koshizawa <koher@koherent.org> | Date: Fri May 12 16:34:23 2017 +0900 | | Original | * commit 5494a1445902fcfa7aeaf3708a3f9c939f807647 Author: Yuta Koshizawa <koher@koherent.org> Date: Fri May 12 16:33:23 2017 +0900 Initial commit
7:38 AM
$ git diff original master diff --git a/a.txt b/a.txt index 1802a74..c4f3b1d 100644 --- a/a.txt +++ b/a.txt @@ -1,3 +1,6 @@ aaa +111 bbb +222 ccc +333
Avatar
omochimetaru 5/12/2017 7:38 AM
@koher --allow-unrelated-histories が必要だった?
Avatar
はい。
Avatar
omochimetaru 5/12/2017 7:39 AM
なるほど。
7:39 AM
基本的にforce pushしても
7:39 AM
コードコメントはPRとかについてるから
Avatar
コミット番号さえわかってれば、もう一度 force push して元に戻してもいいかも? (edited)
Avatar
omochimetaru 5/12/2017 7:39 AM
何も失わないと思っていた
7:45 AM
@koher あとでやってみます
Avatar
norio_nomura 5/12/2017 7:46 AM
わかりやすい
Avatar
omochimetaru 5/12/2017 7:51 AM
koherのPRをマージした直後の状態からはじめて、リネームをして、 オリジナルをおいて、その2つをマージして、そこから辻褄をあわせていけばいいのか
Avatar
オリジナルをおいたコミットは再利用できそう
Avatar
omochimetaru 5/12/2017 7:52 AM
あ、たしかに。
Avatar
norio_nomura 5/12/2017 8:08 AM
型としての () は Void にすべき派。
いい機会だから Void に変えようと試したら、ビルドできなかった。 error: member 'success' in 'Result<Void, SourceKittenError>' (aka 'Result<(), SourceKittenError>') produces result of type 'Result<T, Error>', but context expects 'Result<Void, SourceKittenError>' (aka 'Result<(), SourceKittenError>') return .success(Void) ^
(edited)
Avatar
Void はあくまで型なので、そのインスタンスは () しかだめですね。
Avatar
norio_nomura 5/12/2017 8:09 AM
ああ、なるほど。
8:11 AM
return .success(Void()) で通る。
Avatar
omochimetaru 5/12/2017 8:11 AM
知らんかったw
Avatar
Void()できるんだ
Avatar
omochimetaru 5/12/2017 8:11 AM
言われてみればという感じ
Avatar
あれ? Void って typealias じゃないの?
Avatar
できる。 typealias A = (a: Int, b: Int) let a = A(1,2) もできる。
Avatar
おー
Avatar
omochimetaru 5/12/2017 8:12 AM
!?
8:12 AM
なるほど・・・
Avatar
知らんかった
Avatar
でも.initで推薦してくれないですよね
Avatar
なんですよねー > .init
Avatar
推薦してくれたら色々捗る
Avatar
A(a: 1, b: 2) ではないんだ
Avatar
@hiragram どっちもいけるよ
8:13 AM
Tuple、ただただ.initで推薦してくれないのが本当に不便で、結局.initを書く必要がある場合はStruct作れ!ってなってる
Avatar
いけんのか
Avatar
4> typealias A = (a: Int, b: Int) 5> A(a: 2, b: 3) $R0: (a: Int, b: Int) = { a = 2 b = 3 } 6> A.init(a: 2, b: 3) error: repl.swift:6:1: error: type 'A' (aka '(a: Int, b: Int)') has no member 'init' A.init(a: 2, b: 3) ^ ~~~~
Avatar
いけてない?
Avatar
これはinitです
Avatar
おー
Avatar
initは無い。
Avatar
6> let createA: (Int, Int) -> A = A error: repl.swift:6:32: error: cannot convert value of type 'A.Type' (aka '(a: Int, b: Int).Type') to specified type '(Int, Int) -> A' let createA: (Int, Int) -> A = A ^
8:17 AM
.init もダメだし、変数に入れることはできないか・・・
8:17 AM
結局.initを書く必要がある場合はStruct作れ!ってなってる
タプルは用法用量を守って使うのがいい気がするから、本当に一時的なペアでない限り struct がいいと思います。
(edited)
Avatar
typealias A = (a: Int, b: Int) let a = A(a: 1, 2) let b: (x: Int, y: Int) = (1,y: 2) これが出来るのとか含めて、タプルは特別扱いすぎて本当に。
Avatar
norio_nomura 5/12/2017 8:20 AM
とりあえずさっきのは Void に変えるのはやめよう
Avatar
truefalse のノリで void があってもいい気もする。 Void 型のインスタンスが () なのはわかりづらい・・・。
Avatar
let void=Void()って書いておけばまぁ使えますねw
Avatar
かといって、 () 型のインスタンスが () なのも、値と型の区別がつきづらいけど・・・
Avatar
(良いかどうかは別として)
Avatar
ですね。
8:24 AM
うーん、結局 Void のインスタンスを扱わなければならないとき(ジェネリクスの型パラを Void で埋めたときなど)は Void 型のインスタンスを扱う必要があって、そうすると Void()typealias であることを知っている必要があって・・・と考えると、 Void より () と書いている方がいい気がしてきました。
8:25 AM
戻り値 Void はそもそも省略できるから書かないし。
Avatar
ジェネリクス型がVoidの場合に、extensionに引数を省略した関数群を提供するのは一つの手かなと思っています。 (edited)
😍 1
Avatar
なるほどー。 (edited)
8:28 AM
こんな感じで。
Avatar
omochimetaru 5/12/2017 8:28 AM
voidで型パラ埋めてる時は Voidの値 () を無駄に取る事の無い版を付け足すのか
Avatar
Swift 4 ってタプルが区別されるのは引数だけで↓はそのままなんですよね? 6> let a: Int = (((42))) a: Int = 42 7> let b: (((Int))) = a b: (((Int))) = { _value = 42 } 8> b + 1 $R1: Int = 43 (edited)
Avatar
要素数1の括弧はタプルではないのはそのままです。 (edited)
👌 1
Avatar
そうすると、 () -> ()(()) -> () は異なるのに () -> (()) は同じってちょっと気持ち悪い感じが・・・。
8:31 AM
まあしかたないですが・・・。
Avatar
((( ))) -> RetTy |-----| param list |---| paren |-| tuple って感じですね。 (edited)
👍 1
Avatar
paren が入ってくるあたりにも闇を感じますね・・・
8:34 AM
タプルの括弧が () なのよくないよなぁ。やっぱ @tarunon さんの言うように人類には括弧が足りなかった・・・
Avatar
{([<
8:35 AM
どう見ても足りないです本当に
Avatar
<, > も演算子と共用なのがヤバイですしね。
Avatar
「」←彼らをデビューさせましょう(ない)
Avatar
お、それなら 『』, 【】 もいけますねw
8:38 AM
それくらいあれば戦えそうだw
Avatar
問題は、入力可能じゃないところ。。。
Avatar
ASCIIに入ってないと戦力外ですからねぇ・・・
8:40 AM
Array【Int】 とか、可読性だけならアリそう。
Avatar
omochimetaru 5/12/2017 8:40 AM
<<{ }>> <<( )>> <<[ ]>> みたいな合体で意味を変えて増やす
Avatar
@omochimetaru 地獄の始まりでしょw
Avatar
┗( )┛
8:41 AM
イシツブテ
Avatar
┗("o")┛ 顔っぽくなるぞ
Avatar
合体で意味を変えて増やす、Objcのブロック構文の二の舞いだし絶対ダメだと思う
Avatar
このサイトにはお世話になりました http://fuckingblocksyntax.com/
Avatar
以前どこかで初期化なしでFloat配列を作りたいって話で聞いた方法をずっと使ってたんですが 今急にコピーコスト考えるとそっちのが高いんじゃと思って試してみたらやっぱり遅かった…… func testA() { let size = 10_000_000 measure { // 0.013sec let array = [Float](repeating: 0, count: size) } } func testB() { let size = 10_000_000 measure { // 0.034sec let dst = UnsafeMutablePointer<Float>.allocate(capacity: size) defer { dst.deallocate(capacity: size) } let array = [Float](UnsafeBufferPointer(start: dst, count: size)) } }
Avatar
omochimetaru 5/12/2017 9:42 AM
array = のところの右辺のコンストラクタ呼び出しで
9:43 AM
結局全要素をコピーしてる?
Avatar
だと思います
Avatar
omochimetaru 5/12/2017 9:43 AM
UnsafeBufferPointerのまま
9:43 AM
それを配列的につかえば
9:43 AM
そのコストは消せそう
Avatar
うーんでも
9:43 AM
deferで開放されるわけですし
Avatar
omochimetaru 5/12/2017 9:43 AM
UnsafebufferPointerもMutableCollectionじゃなかったっけ。
Avatar
ああそういうことですか
Avatar
omochimetaru 5/12/2017 9:44 AM
Array型を使わないってこと。
Avatar
それは一理ありますね
9:46 AM
ただUnsafeBufferPointer自体をそのまま作ることはできないので開放タイミングがどうすればいいのかさっぱり分からないという
9:46 AM
UnsafeBufferPointerの持ち主のdeinitで開放させるとかになるんですかね
Avatar
omochimetaru 5/12/2017 9:48 AM
/// An UnsafeBufferPointer instance is a view into memory and does not own the memory /// that it references.
9:48 AM
UnsafeBufferPointerはメモリ空間へのビューを提供するだけでそれ自身はメモリ領域を保持しないから
9:49 AM
引数で与えたポインタの所有権はいまだプログラマ側にある
9:49 AM
func testB() { let size = 10_000_000 measure { // 0.034sec let dst = UnsafeMutablePointer<Float>.allocate(capacity: size) defer { dst.deallocate(capacity: size) } let array = UnsafeBufferPointer(start: dst, count: size) } }
9:49 AM
↑さっきのコードで言えばこうするだけ
Avatar
速度自体はこれが圧倒的ですね あとはメモリ管理の煩雑さを受け入れるかどうか……
Avatar
omochimetaru 5/12/2017 9:50 AM
自分で作ればいいんじゃない?
9:50 AM
↑の let dst = を initの中で呼び出して
9:50 AM
defer { } の中を deinit で呼び出す
9:50 AM
structを作れば
Avatar
その考えはなかった
9:51 AM
それでちょっとやってみます。
Avatar
omochimetaru 5/12/2017 9:51 AM
あ、structにはdeinitかけないから、classでかいて structでラップする必要があるね・・・
9:51 AM
まあclassでかいて let で受けてもいいです
Avatar
Contribute to swift-ownership-jp development by creating an account on GitHub.
10:21 AM
というわけで、SE0176も訳しました。こっちのほうがまともな日本語になっている感。 https://github.com/omochi/swift-ownership-jp/blob/master/0176-enforce-exclusive-access-to-memory.md (edited)
Contribute to swift-ownership-jp development by creating an account on GitHub.
Avatar
@t.ae 結局クラスつかうんだったら、 ManagedBuffer のほうが良いと思いますよ。
Avatar
お、そのクラスは知らない
11:02 AM
おお〜〜
Avatar
バッファが ManagedBuffer のオブジェクトの実体の直後に tail allocate されるので、ちょっとだけ効率が良いはず。
Avatar
ポインタジャンプが1回少ないってことですか?
Avatar
これはいいですね。ありがとうございます!
Avatar
ポインタジャンプが1回少ない
のはず。
👏 1
11:12 AM
ただ、オブジェクトの起点から テールアロケートされたところまでのポインタ計算が一回入るはずなので、そんなにパフォーマンスは変わらないかもです。
Avatar
オフセット計算が入るのはそうですが、ヒープアロケーション/でアロケーションが1回減るのは大きいし、アドレスが離れた場合のキャッシュ効率も変わるので結構変わりそう
Avatar
https://developer.apple.com/reference/swift/managedbuffer
Typical usage stores a count and capacity in Header and destroys any live elements in the deinit of a subclass.
サブクラス作ってdeinit呼ぶ必要があるのでは?
Avatar
そうなんですが、 T が Float などの trivial な値だったらそのままでも大丈夫かと。
Avatar
なるほど
11:17 AM
https://gist.github.com/airspeedswift/1fb7d6e3e73e53ce64f6 別の実装見つけてたんですがこっちはGenericだからですね
Array using ManagedBuffer
Avatar
Patient: Doctor doctor, it hurts when I do this. Doctor: Well, don’t do that. On twitter, I wrote: Your reminder that building arrays with reduce, while fun, is accidentally quadratic. I was surpri…
Avatar
ContiguousArray 使えばいいのでは?と思ってしまう。
Avatar
@norio_nomura 大本の僕の目的はArrayの初期化コストを削減したいということなのです
Avatar
Array の初期化コストが hot spot なのですか?
Avatar
今やってるプログラム上でコストが思いかどうかまでは検討してないです。
12:37 PM
ちょっと要点抜き出して書いて確かめてみます
12:41 PM
func testA() { let size = 10_000_000 let src = [Float](repeating: 0, count: size) var one: Float = 1 measure { // 0.020sec var dst = [Float](repeating: 0, count: size) vDSP_vsadd(src, 1, &one, &dst, 1, vDSP_Length(size)) } } func testB() { let size = 10_000_000 let src = [Float](repeating: 0, count: size) var one: Float = 1 measure { // 0.017sec let dst = UnsafeMutablePointer<Float>.allocate(capacity: size) defer { dst.deallocate(capacity: size) } vDSP_vsadd(src, 1, &one, dst, 1, vDSP_Length(size)) } } ほとんど差ないですね
12:42 PM
これなら初期化させていいか……
Avatar
15%も違うなら結構でかいのでは
12:44 PM
ただ、テスト条件が
12:44 PM
あまり現実的じゃないから
12:44 PM
ヒープアロケーションのコストとか
12:44 PM
特性が変わっちゃうのでは
12:44 PM
現実的なサイズの行列を何度も計算した時の
12:44 PM
性能を評価しないと意味なさそう
Avatar
実用でここまでのサイズか微妙ですし、実際はこの他にコストが重そうなところがあるんですよね
Avatar
ふむ
Avatar
func testA() { let size = 10_000 let src = [Float](repeating: 0, count: size) var one: Float = 1 measure { // 0.021sec for _ in 0..<size { var dst = [Float](repeating: 0, count: size) vDSP_vsadd(src, 1, &one, &dst, 1, vDSP_Length(size)) } } } func testB() { let size = 10_000 let src = [Float](repeating: 0, count: size) var one: Float = 1 measure { // 0.012sec for _ in 0..<size { let dst = UnsafeMutablePointer<Float>.allocate(capacity: size) defer { dst.deallocate(capacity: size) } vDSP_vsadd(src, 1, &one, dst, 1, vDSP_Length(size)) } } } これだと倍近い差が
Avatar
大きいね
Avatar
norio_nomura 5/12/2017 1:27 PM
あれ?比較対象は ManagedBuffer を使った型ではないのね。
Avatar
大体同じだと思ったんで というかそこまで気が回ってなかったです
1:30 PM
いちおう試してみましたけどほぼ同じですね
Avatar
norio_nomura 5/12/2017 1:41 PM
なるほど、あとは書いたデータの読み出し?
Avatar
読み出し回数は比較的少なくなる予定です。
1:45 PM
のでO(1)じゃなくても書き込みほど影響は大きくないかと
1:48 PM
逆にシーケンスとかで初期化したいときのコストが気になりそうな
Avatar
norio_nomura 5/12/2017 2:02 PM
Instrumentsで見ると、 var dst = ContiguousArray<Float>(repeating: 0, count: size) dst.withUnsafeMutableBufferPointer { dst in vDSP_vsadd(src, 1, &one, dst.baseAddress!, 1, vDSP_Length(size)) } でもUnsafeMutablePointerとほぼ同じになるぽい。 (edited)
2:05 PM
measure の結果は遅くなるのに。
Avatar
こちらもmeasureで遅くなりました
Avatar
最近swiftのswift-4.0-branchをビルドしようとしてるんですけど下記のエラーでうまくいかないのですが、単に壊れるコミットなのか、それとも何か見逃しているんでしょうか (edited)
12:09 PM
build error
7.71 KB
12:14 PM
あ、 !535 は 535 utils/build-script --skip-ios --skip-tvos --skip-watchos --jobs 2 --skip-test-osx true
Avatar
https://ci.swift.org/view/swift-4.0-branch/ でビルドできてるコミットを使ってみるとか。 (edited)
Avatar
@norio_nomura なるほど!やってみます。
Avatar
あ、スナップショットが出てるから、
12:17 PM
そのタグをビルドしてみるのが良いかな。
Avatar
ふむ
12:18 PM
swift-4.0-DEVELOPMENT-SNAPSHOT-2017-05-11-a
12:18 PM
これか
Avatar
utils/update-checkout --scheme swift-4.0-branch --tag swift-4.0-DEVELOPMENT-SNAPSHOT-2017-05-11-a でチェックアウト
Avatar
gitでswiftのリポジトリをチェックアウトしたあとに utils/update-checkout でも同じですか? (edited)
Avatar
swift以外のリポジトリも同じタグをチェックアウトしないといけないです。
Avatar
あら、連動してチェックアウトするのが utils/update-checkout ってわけじゃないんですね。
12:20 PM
とりあえず、そのコマンドでやってみます
Avatar
オプションなしで utils/update-checkout を実行した結果がどうなるかは知らないです。
Avatar
なるほど。
Avatar
omochimetaru 5/13/2017 1:57 PM
うーむおなじだ
1:57 PM
/Users/omochi/work/swift-source/swift/lib/Basic/Version.cpp:334:5: error: static_assert failed "getCurrentLanguageVersion is no longer correct here" static_assert(SWIFT_VERSION_MAJOR == 4, ^
Avatar
$ utils/update-checkout --clone --scheme master とりあえず master 前提で進めると、これで関連リポジトリ含めて全て clone してきます。 (edited)
2:05 PM
で、今エラー出てるのは、ビルドディレクトリに変なファイルが残っちゃっているからだと思うので
2:06 PM
$ utils/build-script --clean ... のように --clean オプション付けて build-script 実行
2:09 PM
過去にビルドしたことあるなら https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20170424/004482.html でアナウンスされているとおり、 --clean ビルドが必要です。
👍 1
Avatar
norio_nomura 5/13/2017 2:16 PM
ああ、そのエラーどこかで見たと思ったら、そのアナウンス前後だ。
Avatar
omochimetaru 5/13/2017 2:29 PM
やってみます!
Avatar
omochimetaru 5/14/2017 5:14 AM
@rintaro cleanのおかげでビルドできました。ありがとうございます。
Avatar
norio_nomura 5/14/2017 5:44 AM
swift-4.0-DEVELOPMENT-SNAPSHOT-2017-05-13-a が来そうな感じ ダメだった (edited)
Avatar
class A<X> { } class B: A<B.X> { struct X {} } print(B())
9:56 AM
↑コンパイルは通るけど実行時に無限に停止する
9:56 AM
もう報告されてるかな。
Avatar
デッドロックしてるぽいね。 (lldb) bt * thread #1, name = 'test', stop reason = signal SIGSTOP * frame #0: 0x00007ffff6a72a9f libpthread.so.0`__pthread_once_slow + 95 frame #1: 0x00007ffff7c7f96f libswiftCore.so`swift_once + 95 frame #2: 0x0000000000400fef test`type metadata accessor for test.B + 47 frame #3: 0x0000000000401531 test`___lldb_unnamed_symbol7$$test + 17 frame #4: 0x00007ffff6a72ae9 libpthread.so.0`__pthread_once_slow + 169 frame #5: 0x00007ffff7c7f96f libswiftCore.so`swift_once + 95 frame #6: 0x00000000004013df test`type metadata accessor for test.B.X + 47 frame #7: 0x000000000040138e test`type metadata accessor for test.A<test.B.X> + 30 frame #8: 0x0000000000401341 test`___lldb_unnamed_symbol5$$test + 17 frame #9: 0x00007ffff6a72ae9 libpthread.so.0`__pthread_once_slow + 169 frame #10: 0x00007ffff7c7f96f libswiftCore.so`swift_once + 95 frame #11: 0x0000000000400fef test`type metadata accessor for test.B + 47 frame #12: 0x0000000000400f31 test`main + 65 frame #13: 0x00007ffff6ca1830 libc.so.6`__libc_start_main + 240 frame #14: 0x0000000000400e09 test`_start + 41
Avatar
omochimetaru 5/15/2017 1:33 AM
@norio_nomura さんが前言っていたみたいに、自前ビルドのswiftをXcodeのToolchainsに入れるのってどうやるんですか?あと、そういう系の情報ってどの文書に書いてありますか? build-script -h は見たけど書いてなかったのと、ビルドにも時間かかりすぎて試行錯誤ができず・・・
1:33 AM
swift-source/build/Ninja-Release/swift/bin とかにバイナリが入ってるところまではいけたんですが。 (edited)
Avatar
norio_nomura 5/15/2017 1:47 AM
僕は swift/utils/build-toolchain を使いました。このジョブと同じ内容。 https://ci.swift.org/view/Packages/job/oss-swift-package-osx/ (edited)
1:49 AM
ですが、 swift-nightly-install ディレクトリ内にツールチェイン一式が出来ていれば、インストーラパッケージを作れるはず。
1:50 AM
swift/utils/build-toolchain はすべてのプラットフォームのテストを実行するため、めっちゃ時間がかかります。(僕のMacで11時間以上かかった)
Avatar
omochimetaru 5/15/2017 1:50 AM
Job config: swift/utils/build-script --preset="buildbot_osx_package" \ install_destdir="${SWIFT_INSTALL_DIR}" \ installable_package="${SWIFT_INSTALLABLE_PACKAGE}" \ install_toolchain_dir="${SWIFT_TOOLCHAIN_DIR}" \ install_symroot="${SWIFT_INSTALL_SYMROOT}" \ symbols_package="${SYMBOLS_PACKAGE}" \ darwin_toolchain_bundle_identifier="${BUNDLE_IDENTIFIER}" \ darwin_toolchain_display_name="${DISPLAY_NAME}" \ darwin_toolchain_xctoolchain_name="${TOOLCHAIN_NAME}" \ darwin_toolchain_version="${DARWIN_TOOLCHAIN_VERSION}
1:51 AM
これらのパラメータはどうやって決めました? (edited)
1:52 AM
swift-nightly-install というディレクトリは見当たらないです
1:52 AM
iOS向けとかをskipしてると駄目なのかな
Avatar
norio_nomura 5/15/2017 1:52 AM
CIログの前半に、実際のサンプルが出て来ます。 https://ci.swift.org/view/Packages/job/oss-swift-package-osx/3373/consoleText
1:55 AM
^改行入れた
Avatar
omochimetaru 5/15/2017 1:56 AM
ありがとうございます、なるほど、CIの詳細を見ればいいわけですね
Avatar
norio_nomura 5/15/2017 1:56 AM
そそ。
Avatar
omochimetaru 5/15/2017 1:56 AM
↑こういうのはみつかったけどnorioさんがはってるやつはどこからいけるんですか?
1:57 AM
a
1:57 AM
あった
1:57 AM
「プレーンテキスト表示」か
Avatar
norio_nomura 5/15/2017 1:57 AM
そそ
Avatar
omochimetaru 5/15/2017 1:58 AM
おとなしくフルビルドしたら24時間かかりそうなんだよな・・・
Avatar
norio_nomura 5/15/2017 1:59 AM
で、インストーラ作成もCIログを見ればわかりますが、僕はこんなスクリプトにしてます。 https://gist.github.com/norio-nomura/185a61fd93b6a6d275f0445bcb4be6d0
swift/swift-nightly-install からインストーラパッケージを作成
1:59 AM
--skip-test-* なんとかをつけまくれば良いと思います。>テスト (edited)
2:01 AM
Avatar
omochimetaru 5/15/2017 2:03 AM
ふむふむ
Avatar
norio_nomura 5/15/2017 2:04 AM
11時間以上は MacBook Pro (Retina, 13-inch, Late 2013) 2.6 GHz Intel Core i5 8 GB 1600 MHz DDR3 での結果。
Avatar
omochimetaru 5/15/2017 2:04 AM
MacBook (Retina, 12-inch, Early 2015) 1.3 GHz Intel Core M
2:05 AM
だいたいそれの4倍かかるw
Avatar
norio_nomura 5/15/2017 2:06 AM
各プラットフォームのテストが圧倒的に長いので、osxとios simulator以外をスキップすれば、かなり短縮できると思う。
Avatar
omochimetaru 5/15/2017 2:07 AM
なるほど。 --skip-ios --skip-tvos --skip-watchos 現状これで6時間とかです
Avatar
norio_nomura 5/15/2017 2:07 AM
昨日のフルビルド?
Avatar
omochimetaru 5/15/2017 2:07 AM
はい
2:07 AM
4時間かな?
2:08 AM
consoleText、chromeが死ぬので今テキストエディタで開きました。。
Avatar
norio_nomura 5/15/2017 2:09 AM
各リポジトリ間の依存が問題なければ、swiftだけ最新にして、テストもswiftだけにして、他のリポジトリのテストもスキップとかすれば良いのかも。
Avatar
omochimetaru 5/15/2017 2:10 AM
CIログと build-script-impl の冒頭を見比べたらいろいろできそうなのでやってみます
Avatar
norio_nomura 5/15/2017 2:11 AM
あ、僕の11時間はlldbのテスト含んでたので、--skip-test-lldb をつけるとさらに短縮されるかな。
Avatar
omochimetaru 5/15/2017 2:11 AM
skip-test-lldb とかはでかそうですね
Avatar
norio_nomura 5/15/2017 2:12 AM
最新のスナップショットは、lldbのテストが通らないので --skip-test-lldb で出てるはず。
Avatar
omochimetaru 5/15/2017 2:12 AM
そういうこともあるのか・・・
Avatar
norio_nomura 5/15/2017 2:20 AM
Appleのlldbチームの人が大勢やめたとかそんな話を見かけたけど、真偽未確認…
Avatar
omochimetaru 5/15/2017 2:22 AM
フーム
2:22 AM
テスラはSwift関係者引き抜くのやめてほしい
Avatar
いや、 Apple の外に Swift が飛び出すことによって、より広い範囲で使われるようになるかもしれない。
2:27 AM
Swift が汎用メジャー言語になるためには「 Apple の言語」ではダメで、影響力のある会社が何社か iOS 以外の実案件で採用してくれないといけないと思う。テスラがそうなるかはわからないけど。
Avatar
これ、こういうことがしたいんだけど書き方間違ってるか出来ないか分かる人いますか struct Hoge<T> { } extension Hoge where T == [Any] { func fuga() -> T.Element { // <- Error: 'Element' is not a member type of 'T' fatalError() } }
Avatar
omochimetaru 5/15/2017 2:34 AM
答えにはならないけど その場合なら Any って書けば?
Avatar
あー、
Avatar
omochimetaru 5/15/2017 2:36 AM
struct Hoge<T> { } extension Hoge where T: Sequence { func fuga() -> T.Iterator.Element { // <- Error: 'Element' is not a member type of 'T' fatalError() } } これは通るね
2:36 AM
ConcreteTypeでのEquality Constraintの時には左辺値に型定義が伝搬しない・・・?
Avatar
あれ、これだと例えば Hoge<[Int]> にはこのextensionだめ?
Avatar
omochimetaru 5/15/2017 2:36 AM
だめだと思うよ。
Avatar
任意の配列を型パラに持つとき、その配列の要素の型を返すメソッドみたいなのを生やしたいみたいな感じなんだけどにゃあ…
Avatar
omochimetaru 5/15/2017 2:37 AM
それは型パラ付きExtensionが必要だけど今無い、って話しな気がする
2:37 AM
extension定義自体が <T> を取る必要がありそう
Avatar
なるほど。
Avatar
omochimetaru 5/15/2017 2:39 AM
@koher 今影響力の大きい適応範囲だとサーバサイドLinuxとブラウザとAndroidっすね
Avatar
where付きのextensionの中でそのTが[Any]に見えないってことなの
2:40 AM
struct Hoge<T> { } struct Nested { struct MoreNested { } } extension Hoge where T == Nested { func fuga() -> T.MoreNested { // これもだめだった。 fatalError() } }
Avatar
omochimetaru 5/15/2017 2:40 AM
struct Hoge<T> { } extension Hoge where T == Array<Any> { func fuga() { print("fuga!") } } let x = Hoge<[Int]>() x.fuga()
2:40 AM
Playground execution failed: error: HogeGround.playground:5:1: error: 'Hoge<[Int]>' (aka 'Hoge<Array<Int>>') is not convertible to 'Hoge<Array<Any>>' x.fuga()
2:41 AM
あーそうか、理論的にも無理だわな
Avatar
[Any]と[Int]はだめか
Avatar
omochimetaru 5/15/2017 2:41 AM
Array<Int> is Array<Any> だけど、 Hoge<Array<Int>> は Hoge が T について Covariance でないかぎり Hoge<Array<Any>> ではない。
Avatar
↑のNestedとMoreNestedのやつはなんか直感的にそれでいけるもんだと思ってたんだけど行けなかった悲しい
Avatar
omochimetaru 5/15/2017 2:43 AM
まー == はなんか本当に代入されるわけじゃないっぽいね。
Avatar
このチャンネルで 5/2 に @koher さんがそれ的なことをやりたくて @norio_nomura さんによる workaround 出てるので、ログ見てみてください。
Avatar
お、見てみます。
Avatar
まじすか。全然記憶にないw
Avatar
パーマリンク欲しいなぁ。
😐 1
Avatar
omochimetaru 5/15/2017 2:43 AM
structのvarianceの話なんか過去にありましたね
Avatar
たださ、Xcodeちゃん、 -> T. まで打つと NestedType を補完してくるんだよな
Avatar
omochimetaru 5/15/2017 2:44 AM
なめられてるね
2:44 AM
💢
Avatar
あー、けど @koher さんのとはちょっと違うかな。
extension Array where Element == Optional まで書いて、型パラメータが書けなくて固まった・・・
Avatar
それはありましたね。それ書きたい・・・。
Avatar
omochimetaru 5/15/2017 2:48 AM
なるほど。
2:48 AM
やはりパラメータ付きextensionが要るのか。
Avatar
@norio_nomura さんの workaround 今回のに適用すると、 protocol HasElement { associatedtype Element } extension Array : HasElement {} struct Hoge<T> { } extension Hoge where T: HasElement { func fuga() -> T.Element { // 通る fatalError() } } (edited)
2:49 AM
extension<T> Array where Element == T? { var someValues: [T] { var result = [T]() for opt in self { if let value = opt { result.append(value) } } return result } }
2:49 AM
そのものずばり、マニフェストで提示されてる
Avatar
おお、そうなんだ。
Avatar
omochimetaru 5/15/2017 2:50 AM
Parameterized Extension と名付けられているようだ
Avatar
norio_nomura 5/15/2017 2:51 AM
よく覚えてるなあw
Avatar
関連して(ないような気もするけど)↓の動向が気になってる。 extension Array where Element == Int { ... }extension Array<Int> { ... } のように書けるようにするのには何か技術的な難しさがあるの?って質問(ちょっとニュアンス違うけど)。 https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170508/036599.html (edited)
Avatar
その件、ソース確認したんですが、無さそうです。純粋に syntax だけの制限だと思います。 concrete type extension が許可されてなかったから。
Avatar
なるほど。歴史的な経緯でこうなっているんですね。
Avatar
omochimetaru 5/15/2017 7:57 AM
--- Installing swift --- + env DESTDIR=/Users/omochi/work/swift-install/ /usr/local/bin/cmake --build /Users/omochi/work/swift-source/build/build-dir/swift-macosx-x86_64 -- install ninja: error: unknown target 'install', did you mean 'test/all'? utils/build-script: fatal error: command terminated with a non-zero exit status 1, aborting
7:57 AM
朝開始したやつさっきエラーで終わってた
7:57 AM
4.0branchのCI見てみよう
Avatar
@hiragram structのGenericsは見えないけどprotocolのassociatedtypeは見えるから
8:09 AM
例えばこういうコードなら通る struct Hoge<T> { let value: T } extension Hoge where T: BidirectionalCollection { func fuga() -> T.Iterator.Element { return value.first! } } Hoge(value: [1, 2, 3]).fuga() // 1
8:10 AM
って話が上の方にあった
8:10 AM
TをArrayっぽく任意のSequenceからinitしたい、みたいな感じだと
8:11 AM
Arrayのinitは、RangeReplaceableCollectionの実装だから
8:12 AM
extension Hoge where T: RangeReplaceableCollection { }と書いておけば、その中でT.initが使えるようになる
8:14 AM
BidirectionalCollectionはよく使うんだけどなんだったかな、lastが欲しいので使ってた気がする。
Avatar
omochimetaru 5/15/2017 8:20 AM
あ〜いけたかんじがする
8:21 AM
-- が 重要なのか
8:21 AM
$utils/build-script <options A> -- <options B> こうなってて、Aはbuild-scriptのやつ、 Bはbuild-script-implのやつか?
8:22 AM
--- Installing swift --- + env DESTDIR=/Users/omochi/work/swift-install/ /usr/local/bin/cmake --build /Users/omochi/work/swift-source/build/build-dir/swift-macosx-x86_64 -- install ninja: error: unknown target 'install', did you mean 'test/all'? utils/build-script: fatal error: command terminated with a non-zero exit status 1, aborting だめだw
Avatar
omochimetaru 5/15/2017 8:43 AM
あ〜 --reconfigureつけたらビルドしなおしになってしまった 終わり
8:48 AM
あれ、でもなんか中途半端に xctoolchain生成されてるな
Avatar
norio_nomura 5/15/2017 9:03 AM
build-script へ渡すオプションの組み合わせはプリセットとして swift/utils/build-presets.ini の中に記述されています。例えば OSS - Swift Package - OS X (master) で使われている buildbot_osx_package プリセットはこれ。 https://github.com/apple/swift/blob/master/utils/build-presets.ini#L955 (edited)
swift - The Swift Programming Language
Avatar
omochimetaru 5/15/2017 9:04 AM
あーなるほど
9:05 AM
ログの /Users/buildnode/jenkins/workspace/oss-swift-4.0-package-osx/swift/utils/build-script: note: using preset 'buildbot_osx_package', which expands to
9:05 AM
ここで、presetから実引数への展開結果が表示されてるので、展開結果のパラメータを1個ずつ見て移してました (edited)
Avatar
norio_nomura 5/15/2017 9:05 AM
swift/utils/build-presets.ini の代わりに自分で用意したものも --preset-file=… で使えます。 (edited)
9:11 AM
SourceKit for Linuxでのビルドにカスタマイズしたものを作って使ってました。 https://github.com/norio-nomura/swift-dev/blob/sourcekit-linux/build-presets-for-sourcekit-linux.ini
swift-dev - Managing Swift Repositories