Guild icon
swift-developers-japan
main / swift-zatsu
Avatar
Xcode 9.1で4.0.2がリリースされたけど、リポジトリには4.0.1, 4.0.2のリリースタグが付かないですね。 swift-4.0-branch にはバージョン変更入ってるのに。 https://github.com/apple/swift/compare/swift-4.0-RELEASE...swift-4.0-branch
swift - The Swift Programming Language
Avatar
swift-4.0.2-RELEASE来てた。
Avatar
StringStringProtocol だけど NumberNumeric なんですね… https://developer.apple.com/documentation/swift/numeric
Avatar
omochimetaru 11/6/2017 8:49 AM
XxxProtocol は Xxx をそのままプロトコル化したやつで
8:49 AM
Numeric はまた違うんじゃ?
Avatar
なんか微妙に気持ち悪いというかなんというか…?
Avatar
omochimetaru 11/6/2017 8:50 AM
Numericはもととなる型があるわけじゃなくてそれ単体で設計された何かなのでは
Avatar
StringProtocol 以外の XxxProtocol って何があります?
Avatar
NSObjectProtocol
Avatar
Avatar
omochimetaru 11/6/2017 8:52 AM
(早押しクイズかな
Avatar
一番有名で一番邪悪
Avatar
そw
Avatar
NSObjectProtocolこれ入れるとヘッダーには書いてないけど暗黙的にclass扱いになってる気がするんだよね
Avatar
ん?
Avatar
IteratorProtocol 普通にわすれてたw NSObjectProtocol なんてあるのかぁ(白目
Avatar
@tarunon https://developer.apple.com/documentation/objectivec/nsobjectprotocol
An object that conforms to this protocol can be considered a first-class object. Such an object can be asked about its:
Class, and the place of its class in the inheritance hierarchy. Conformance to protocols. Ability to respond to a particular message. The Cocoa root class NSObject adopts this protocol, so all objects inheriting from NSObject have the features described by this protocol.
8:54 AM
クラスとして振る舞うのに必要な要素がNSObjectProtocolに入ってる、って感じかしら
Avatar
んにゃ、NSObjectとして振る舞う、だね
Avatar
ああ、そうね
Avatar
omochimetaru 11/6/2017 8:55 AM
なんちゃらProtocol、意外と無いな
Avatar
暗黙的にclass扱いってどういうことだろう
Avatar
ヘッダーでは public protocol NSObjectProtocol { ってなってるのに、実際の動きは public protocol NSObjectProtocol: class { なんじゃあないのっていうのが各所で浮き出てくる (edited)
Avatar
omochimetaru 11/6/2017 8:56 AM
↑ mutating func とか絡めてみれば確認できそう
Avatar
なお
Avatar
@tarunon 浮き出てくるっていうのは実行時の振る舞いの話?
8:57 AM
コンパイラの振る舞い
Avatar
ああー
Avatar
omochimetaru 11/6/2017 8:57 AM
IteratorProtocol は、 Sequence.Iterator (associatedtype) との Iterator っていう 名前衝突を避けたくてそうなった感があるけどね・・・
Avatar
それは :class を書いたときと同じやつか
Avatar
そう、そうであるべきなのに書いてなくて卑怯だな~~ってなる
Avatar
Kishikawa Katsumi 11/6/2017 8:57 AM
NSObjectProtocolはObjCのプロトコルだからじゃないかな。
Avatar
omochimetaru 11/6/2017 8:57 AM
あ〜
Avatar
UITableVIewDelegateとかも確かそうじゃなかった?
8:58 AM
classって書いてあったっけあれ
Avatar
@objcつけたらclass矯正されるのと同じ感じですかね
Avatar
Kishikawa Katsumi 11/6/2017 8:58 AM
Swift以前からある、
Avatar
omochimetaru 11/6/2017 8:58 AM
objc側からimportされてるプロトコルは全部そうなのか。
Avatar
@objc明示ルール出来たのにNSObjectProtocolはそうじゃないっていうのもね
8:58 AM
卑怯ポイント高い
Avatar
UITableViewDelegateはNSObjectProtocolを継承(?)してた。
Avatar
Basic Arithmetic、日本語でなんてんだ
Avatar
四則演算?
9:01 AM
違うか?
Avatar
omochimetaru 11/6/2017 9:01 AM
> Weblio専門用語対訳辞書での「basic arithmetic operations」の意味 Basic arithmetic operations 四則演算
Avatar
💪 ('ω' 💪 ) (edited)
😯 1
👏 1
Avatar
あー
9:03 AM
継承はExtends、protocolの場合はどれだと思ってたら違うところ見てた。> Inherits こっちかな
Avatar
継承はinheritだね
Avatar
あれれ
Avatar
extendはどっちかというと拡張
9:04 AM
= extension
Avatar
protocolはconformじゃない?
Avatar
英語力の低さが露呈している
Avatar
omochimetaru 11/6/2017 9:04 AM
Relationships Inherits From Equatable, ExpressibleByIntegerLiteral Inherited By BinaryInteger, SignedNumeric
Avatar
プロトコルも継承でいいんでねたぶん
Avatar
omochimetaru 11/6/2017 9:04 AM
ドキュメント的には protocol のページだと inherit
9:05 AM
満たしてるProtocolについては conforms だったと思う
Avatar
プロトコルAと実装Bの関係がB conforms to AでプロトコルAの性質を引き継ぐプロトコルBはB inherits from Aのイメージだなあ (edited)
Avatar
protocolが別のprotocolを継承している場合は inherits、何かの型がprotocolに準拠している場合は conforms、多分これで問題ないかと…?
Avatar
Kishikawa Katsumi 11/6/2017 9:06 AM
Inherit, conform, extend, adoptのどれも同じ意味で使われることありますよ。アップルのドキュメント
Avatar
キビシー
Avatar
Kishikawa Katsumi 11/6/2017 9:07 AM
たぶん決まりはない、、、あるかもしれないけど書く人で変わるくらいのものじゃないかな。
Avatar
omochimetaru 11/6/2017 9:07 AM
https://developer.apple.com/documentation/swift/int あー、僕が言っていたのは文章中の英単語のことじゃなくて、↑の形式のリファレンスの、一番下の方にある機械的に書かれてるっぽいやつのことです
9:07 AM
Relationships セクションの中のサブセクションのタイトル。 (edited)
Avatar
Int は型だから protocolConforms To ですね
Avatar
omochimetaru 11/6/2017 9:08 AM
Conforms To の逆参照が Adopted From として掲載されてるっぽい
Avatar
意味的にもそれがしっくりくるね
Avatar
omochimetaru 11/6/2017 9:09 AM
protocol 同士は Inherited From と Inherited To (edited)
Avatar
Inherits from ですね
Avatar
C#のAbstract Class欲しいなぁと改めて思った https://qiita.com/taketo1024/items/71e3272211f08d7e0cde
社内の「Scala 勉強会」で Phantom Type (幽霊型) という厨二心をくすぐる感じのデザインパターンを教えてもらったので、同じことを Swift でもやってみました。 インスタンスの状態を変数ではなく **型パ...
9:44 AM
この例、Statusabstract class で定義できたらなぁとすごい思う
Avatar
omochimetaru 11/7/2017 9:45 AM
あーなるほど。
9:45 AM
この場合は、 依存型が入ってくれれば、 Status を enum にすればいいですけどね〜
Avatar
Javaのあの依存型ですか?
Avatar
omochimetaru 11/7/2017 9:46 AM
依存型は型パラメータに値が書けるやつです
9:47 AM
例えば・・・ struct StackArray<value Size: Int> { ... }
9:47 AM
みたいなノリ
Avatar
stateパターンというか列挙されたstrategyパターンというか。

環境

  • xcode 9.0
  • swift4 ## 問題

swiftのenumは要素ごとに振る舞いを定義できない

ひたすらswitch文を使...
Avatar
omochimetaru 11/7/2017 9:47 AM
var a = StackArray<2>() a.0 // ok a.1 // ok a.2 // compile error (edited)
Avatar
StackArray 欲しいw
Avatar
omochimetaru 11/7/2017 9:48 AM
↑のtaketoさんの記事なら、 enum Status { case NotReady case Ready } class Something<value T: Status> { /*中身は同じでOK*/ } (edited)
Avatar
編集リクエストを出しては?
Avatar
omochimetaru 11/7/2017 9:50 AM
いまのSwiftには無いですよ
Avatar
ああ、後ろが value T: Status になってるのか。 (edited)
Avatar
Statusprotocol じゃダメなんだっけ? sealed にできない?
Avatar
omochimetaru 11/7/2017 9:52 AM
↑最近のスレ
9:52 AM
protocol だとユーザが追加した値が入れられちゃいますね あ、abstract class でもその点がダメだな
9:52 AM
- Now you can define a “dependent type”, for example ModuloInteger<P>, where P is the integer value that defines the type. - Like this, you’ll have: —> MI<2>: {0, 1}, where 1 + 1 = 0. —> MI<3>: {0, 1, 2}, where 1 + 1 = 2, and 2 • 2 = 1
Avatar
Statusprotocol でもダメってことはないですが、Something<NotReady>.createInstance() で書かないといけないのがイケてないですね
Avatar
omochimetaru 11/7/2017 9:53 AM
↑ P で割ったあまり を表す型 ModuloInteger<P> の例 、型パラのところに2 とか 3とかの 「値」が入る
Avatar
Vector<2> とか Matrix<4, 4> とかやりたい。
Avatar
omochimetaru 11/7/2017 9:53 AM
ですね〜〜〜〜
Avatar
むしろなんでないんだろって思う
9:54 AM
そっちの方がメモリ管理も楽そうなのにな
9:55 AM
reserveCapacity とか考えなくて済む
Avatar
omochimetaru 11/7/2017 9:56 AM
単に優先度っぽいですけどね、具体的なコアチームからの反論はみてない気がする
Avatar
Generics Manifesto にもないよね?当分( Swift 5, 6 あたりで)はなさそうな気が。
9:59 AM
あった!!
10:00 AM
Currently, Swift's generic parameters are always types. One could imagine allowing generic parameters that are values, e.g.,
10:00 AM
struct MultiArray<T, let Dimensions: Int> { // specify the number of dimensions to the array subscript (indices: Int...) -> T { get { require(indices.count == Dimensions) // ... } } (edited)
10:00 AM
例もまさに Vector<N> ですね。
10:01 AM
MayBe セクションだから
10:01 AM
ワンチャンあるで〜
Avatar
てか、 Rust Like な Generic Protocol についても書いてあるな
10:03 AM
対応見込みは Unlikly になっている
10:04 AM
struct Real { ... } extension Real : ConstructibleFrom<Float> { init(_ value: Float) { ... } } extension Real : ConstructibleFrom<Double> { init(_ value: Double) { ... } } サンプルも Rust の From trait と似てる
Avatar
正直長すぎてどの項目がどの項目のサブ項目なのかわからないしOutline機能欲しい…
10:06 AM
せめてFold機能欲しい
Avatar
たしかに。限界を感じます
Avatar
上で出て来たenumstateパターン、無理やりRawValueに振る舞いを実装して見た https://gist.github.com/norio-nomura/65db97c4786851bc368a8d68834fb31b (edited)
Avatar
https://qiita.com/taketo1024/items/71e3272211f08d7e0cde 例のこのPhantom Typeのやつ、extensionで where T: Ready で書くと問題ないけど、where T == Ready で書くと Something.createInstance() の直後でも変換の補完で .shout() が出るのなんで?(もちろんコンパイルエラーにはなるけど…)
社内の「Scala 勉強会」で Phantom Type (幽霊型) という厨二心をくすぐる感じのデザインパターンを教えてもらったので、同じことを Swift でもやってみました。 インスタンスの状態を変数ではなく **型パ...
1:33 PM
これのせいで微妙に辛いのはStatusがstructで作りにくい…
Avatar
@omochimetaru おもちのgysb、他のファイルにあるSwiftのメソッドとか呼べる?
Avatar
omochimetaru 11/8/2017 3:16 AM
呼べません
3:16 AM
呼びたい?
3:17 AM
いまは変換して作られたswiftコードを $ swift generate.swift で実行しているだけなんや。
Avatar
僕が普段gyb使うケース、gybのテンプレートからpythonで書いたSwaggerのyamlのパーサーをimportして使ってるので、それができれば嬉しみって感じ
Avatar
omochimetaru 11/8/2017 3:19 AM
そもそもswiftには隣においてあるファイルを読み込む機能とかないから
3:19 AM
どうやるのがいいか悩むね。
Avatar
インタプリタ実行じゃ無理か
Avatar
omochimetaru 11/8/2017 3:19 AM
gysb側で % include "./hoge.swift" みたいな機能を追加して
Avatar
無理やり展開する?
Avatar
omochimetaru 11/8/2017 3:20 AM
テキストとしてそのままぶち込むのはどうか
3:20 AM
古き良きプリプロセッサ
Avatar
なんとなく動きそうな感じはする
Avatar
omochimetaru 11/8/2017 3:20 AM
issueにしとく いまちょっとパーサーを直さなきゃいけないことに気がついたからあとまわし
3:21 AM
わしもあとでgysbのコードちゃんとよむね
Avatar
omochimetaru 11/8/2017 3:21 AM
いま最新コミット完全にぶっ壊れてるから一個前を見てw
Avatar
Avatar
omochimetaru 11/8/2017 3:21 AM
ちょっと保存するのにうっかりmasterにやっちまった
Avatar
0.1.0のタグ打とう
Avatar
omochimetaru 11/8/2017 3:21 AM
たしかに。
3:22 AM
うった
Avatar
omochimetaru 11/8/2017 3:59 AM
あれ、swift runが壊れた。
Avatar
omochimetaru 11/8/2017 4:14 AM
0.2.0 できた。
4:15 AM
%{ let intTypes = [8,16,32,64] }% % for intType in intTypes { % for sign in ["", "U"] { /// Extension that adds a few additional functionalities to ${sign}Int${intType} extension ${sign}Int${intType} { /// Returns a ${sign}Int${intType} with all ones % if sign == "" { public static var allOnes: Int${intType} { return Int${intType}(bitPattern: UInt${intType}.max) } % } else { public static var allOnes: UInt${intType} { return UInt${intType}.max } % } } % } % }
Avatar
すぐ API のミスに気づいたりするから、とりあえず -alpha とか -beta つけるのオススメ。
Avatar
omochimetaru 11/8/2017 4:16 AM
↑これ綺麗に出力できる モアイさんの例↓ http://moapp.hateblo.jp/entry/2017/06/30/210636
Swift gybの環境構築 ふとSwiftのgybが気になったので環境構築を試して見ました gybとは Swift言語開発の副産物のメタプログラミングツールgybがとても良い— おもちメタル (@omochimetaru) 2017年6月30日 gybは「Generate Your Boilerplate」の略称みたいです(gyb --helpより) 具体的に何かと言うと、Swiftの公式リポジトリの中でSwiftコードの自動生成に使われているPython製のテンプレートエンジンになります gybを導入する qiita.com というわけで、こちらを参考に環境構築して見ました まずgyb自体…
4:17 AM
ふむう > alpha
Avatar
gyb よく知らないけれどマクロ的なやつなのか
Avatar
テンプレートエンジン?
Avatar
omochimetaru 11/8/2017 4:17 AM
↑のモアイさんの記事読むと良いよ
4:18 AM
func readToken() -> Optional<Token> を func readToken() -> Token に変えて、 enum Token に case end を足したらすごく良くなった https://github.com/omochi/gysb/blob/master/Sources/gysb/Token.swift#L18
gysb - Generate your swifty boilerplate
Avatar
よんだ
4:19 AM
なるほど
Avatar
omochimetaru 11/8/2017 4:20 AM
とても良いツールなんだけど
4:20 AM
pythonを書かされるという致命的な問題点があるので
4:20 AM
それを解決したのが拙作のgysbですw
Avatar
なるほどアツい
Avatar
ただ、 Python なのも良いところがあって、 Swift のコードの合間に書かれているときはぱっと見で Python の方が区別しやすいかも?
Avatar
脳のスイッチングコストは結構でかいです
Avatar
omochimetaru 11/8/2017 5:26 AM
まあ僕はガチャガチャ複数言語書くの慣れてるけど
5:26 AM
ひらりとかそもそもパイソン書いたことなかったよね。
Avatar
うん
5:27 AM
gybのために嫌々始めた
Avatar
omochimetaru 11/8/2017 5:27 AM
Avatar
確かに Python を知らない人にとってはハードルが高いな。
5:29 AM
しかも end とか Python じゃないし。
Avatar
イニシャライザちゃんと書かないとプロパティがあったりなかったりするのすごくキツイんだけど何か間違ってるのかもしれない
Avatar
omochimetaru 11/8/2017 5:31 AM
pythonになってるメリットはwindowsとかでも動くことだと思います
Avatar
まあ、 Swift が動かない環境で Swift で書くツールを使おうとしないでしょう・・・。
Avatar
omochimetaru 11/8/2017 5:33 AM
swiftコンパイラ本体の開発は まだ動いてない環境でswiftを動かすタスクだから
5:33 AM
swiftに依存しないでswiftを作らないといけないけど
5:33 AM
たしかに、コンパイラじゃなくてswiftアプリケーションを作る場面なら
5:33 AM
swiftに依存してても問題ないですねw
Avatar
コンパイラ開発であっても、プログラミング言語はある程度固まってきたらセルフホスティングになることも多いし、 gyb レベルならもう Swift でいい気がする。 (edited)
Avatar
omochimetaru 11/8/2017 5:42 AM
セルフホスティングになった言語って
5:42 AM
まだコンパイラをビルドしてない新しい環境に対応するときはどうすんだろ
5:43 AM
昔のC++の実装で、古いバージョンをコンパイルしてから、 その古いバージョンを使って最新のバージョンをセルフコンパイルする?
Avatar
一回でいけるのかな
Avatar
yutailang0119 11/9/2017 1:17 AM
セルフホスティングになると何がメリットなんだろう、コンパイラもSwiftで書かれてるからメンテしやすいとか? Goがセルフホスティングになった時に、話題にはなっていたけど、いまいち理解できてない
Avatar
omochimetaru 11/9/2017 2:13 AM
その言語が、コンパイラを書くのに向いてるのであれば、コンパイラの保守性が上がると思います でも半分はロマンな気がする・・・
Avatar
Kishikawa Katsumi 11/9/2017 2:25 AM
ロマン いつかはセルフホスティングみたいなのはある気がする。
Avatar
この言語自身で効率的にコンパイラを書け、そのコンパイラのパフォーマンスも良いのであれば、その言語のその分野での有効性を示せるとは思います。
2:47 AM
「その分野での」と書きましたが、コンパイラのコードは複雑なのでそれがキレイに書けるのは言語の記述能力の高さを示せそうだし、コンパイラにはパフォーマンスも求められるので、ローレベルからハイレベルまで幅広い範囲で有効性を示そうな気がします。そして、 Swift はまさにそれに向いている言語だと思うので、どこかの段階でセルフホスティングになってほしいですねぇ。まだ時期尚早だとは思いますが。
👀 1
Avatar
omochimetaru 11/9/2017 2:51 AM
Swiftコンパイラのアーキテクチャでいうと LLVM をライブラリとしてガシガシに使っているから
2:51 AM
C++ Interop が実現されるか、もしくは、
2:52 AM
LLVMをSwift化するか・・・
Avatar
https://github.com/trill-lang/LLVMSwift 完全ではないけど、LLVM ラッパ的なプロジェクトはありまっせ。 (edited)
LLVMSwift - A Swift wrapper for the LLVM C API (version 5.0)
Avatar
omochimetaru 11/9/2017 3:10 AM
マジか
3:10 AM
Authors Harlan Haskins (@harlanhaskins) Robert Widmann (@CodaFi)
3:10 AM
コダフィ氏だ
Avatar
ちゃんと SwiftPM 準拠だ。
Avatar
norio_nomura 11/9/2017 4:01 AM
Swift 4.0.2に-swift-version 3を渡してるかどうかは #if swift(>=3.2.2) で判定。 (edited)
Avatar
yutailang0119 11/9/2017 5:37 AM
なるほどw > ロマン
Avatar
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20171106/041072.html
FWIW, I’m getting optimistic about moving to a forum soon.
Ted から久々にフォーラム移行についての言及。まだまだ曖昧。
Avatar
omochimetaru 11/9/2017 7:29 AM
早くしてほしい・・・ ログが調べにくいせいからか話題がループしてるのを感じる
7:34 AM
@hiragram include実装したよ
Avatar
おっ
7:35 AM
@omochimetaru SwiftってJSONは読めるけどYAMLは読めないよね確か
Avatar
omochimetaru 11/9/2017 7:35 AM
なんのこっちゃ
7:36 AM
FoundationにYAMLのなんかがあるかってこと?
Avatar
わしのgybのユースケースでgysbに置き換えるならgysbファイルからincludeした先でSwaggerのymlをパースする必要がある
Avatar
omochimetaru 11/9/2017 7:38 AM
ンゴ・・・
7:39 AM
yamlのライブラリをソースとして隣においておいて
7:40 AM
元のジェネレータで全部includeする形で対応になる
Avatar
なるほろ
7:40 AM
まあSwaggerのymlをjsonに変換しちゃうのもあり
Avatar
omochimetaru 11/9/2017 7:40 AM
それだったらincludeいらないやんけ
Avatar
いやいるよ
Avatar
omochimetaru 11/9/2017 7:41 AM
なんでだっけ
Avatar
jsonをdictionaryにしたとしてそれをそのままテンプレート側で値取ってくるのしんどいでしょ
Avatar
omochimetaru 11/9/2017 7:41 AM
ああ、jsonを取り回すユーティリティがほしいのか。
Avatar
そう
Avatar
omochimetaru 11/9/2017 7:41 AM
理解
Avatar
omochimetaru 11/9/2017 9:04 AM
@hiragram
Avatar
はーい
Avatar
omochimetaru 11/9/2017 9:04 AM
gysb - Generate your swifty boilerplate
9:04 AM
[omochi@omochi-iMac gysb (master *+=)]$ cat Examples/include.swift.gysb %! include_code("libs/*.swift") % aaa=${aaa()} bbb=${bbb()} [omochi@omochi-iMac gysb (master *+=)]$ swift run gysb Examples/include.swift.gysb aaa=999 bbb=777
Avatar
%!
9:05 AM
メタofメタ
Avatar
omochimetaru 11/9/2017 9:05 AM
%! と include_code を追加したのでなんとかなる
Avatar
良い
Avatar
omochimetaru 11/9/2017 9:05 AM
ワイルドカード対応したから
Avatar
おおっ
Avatar
omochimetaru 11/9/2017 9:05 AM
あとは試してみて
Avatar
master *+= ってなんや💢て思ったけどプロンプトだった
Avatar
omochimetaru 11/9/2017 9:06 AM
ほんとだw
9:06 AM
汚いスクショになってしまった。
Avatar
norio_nomura 11/9/2017 9:06 AM
ああ、libYAMLを使ってるYamsは使えなさげ。
Avatar
omochimetaru 11/9/2017 9:06 AM
swiftソースをテキスト展開してるだけなので
9:06 AM
リンクが必要だとダメですね・・・
9:07 AM
%! swift_package("Package.swift") とか定義しておくと SPM の executable として実行するような機能を作ったら対応できそう。
Avatar
%{...}の中にimportは書けないのか
Avatar
どんどん大掛かりになってる・・・
Avatar
omochimetaru 11/9/2017 9:10 AM
%{...}の中にimportは書けないのか
Swiftのimportは書けるよ。
9:10 AM
import Foundation とかはできる。
9:10 AM
swift コマンドで何もしないでも import できるものはimportできるってこと
9:10 AM
[omochi@omochi-iMac gysb (master=)]$ swift run gysb --compile Examples/include.swift.gysb func write(_ s: String) { print(s, terminator: "") } func aaa() -> Int { return 999 } func bbb() -> Int { return 777 } write("aaa=") write(String(describing: aaa())) write("\n") write("bbb=") write(String(describing: bbb())) write("\n")
9:11 AM
swiftc みたいに、途中の段階で実行を止める機能を作ったので
9:11 AM
たのしいです
9:11 AM
--parse , --macro , --compile , --render と4ステージあります
9:14 AM
swift コマンドの -Xlinker だけ指定できれば libYAML はいけるかな・・・?
Avatar
norio_nomura 11/9/2017 9:14 AM
gysbがライブラリになっていて、.gysbインプットから.swiftStringを作れるAPIがあると、swift testの度に.swiftを生成する事ができる様になります。 (edited)
Avatar
omochimetaru 11/9/2017 9:14 AM
MSVCがソースファイルのなかに #comment(lib, "GL.h") ってかいてリンク指定できるみたいな。 (edited)
Avatar
norio_nomura 11/9/2017 9:15 AM
Yamsは*.cをパッケージ内に持ってて、SwiftPMにClangモジュールとしてビルドしてもらってます。
Avatar
omochimetaru 11/9/2017 9:16 AM
いまここが、コンパイラのstdout / stderr を、そのまま垂れ流しにしちゃっているので
9:16 AM
ここをキャプチャしてやれば
.gysbインプットから.swiftのStringを作れるAPI
もいけそうです
9:17 AM
あー、Cソースも持っているのか。それはもうSPMとして全体を実行する以外無理そうだなあ
9:17 AM
ひらりの要望だけで無限にシステムが複雑になったw
Avatar
norio_nomura 11/9/2017 9:18 AM
w
Avatar
いいぞいいぞ〜❗
Avatar
omochimetaru 11/9/2017 9:18 AM
効率悪いのが、一個のテンプレートの処理のたびに spm package つくることになっちゃって
9:18 AM
依存ライブラリを取り直しまくることになるんだよなあ
9:18 AM
いまは トップレベルで printするSwiftソースとしてコンパイルしているけど
9:18 AM
ひとつのファイルの処理結果を得る関数をもったSwiftソースとしてコンパイルして
9:19 AM
入力のテンプレートファイル全部を関数としてまとめて一個のバイナリにした上で
9:19 AM
それぞれ出力する、みたいな形にすると、それ系をまとめられるが・・・・
Avatar
norio_nomura 11/9/2017 9:22 AM
Xcodeで使う分にはRun Script Phaseを使えるからCLIでいいけど、SwiftPMはビルドプロセスに入れられないのがネックだね。
Avatar
omochimetaru 11/9/2017 9:23 AM
あ、そもそも、 gysb を SwiftPM のビルドに差し込めない問題の話ですか。
9:24 AM
そこはもう gysb と 変換先の swift を両方コミットしてもらうしかないっすねえ・・・
9:25 AM
まあそれは今のgyb使ってるやり方でも同じことで(Vapor Cloudにデプロイするのに vapor build の手前に処理を差し込む方法ないのって問い合わせたらねえって言われた (edited)
Avatar
omochimetaru 11/9/2017 9:27 AM
vapor build ってコマンドで全てを発火するの?
Avatar
ん?
9:28 AM
vapor cloud deploy するとリモートでチェックアウトして vapor build が動くんだけどその手前でコードジェネレータ動かしてもらわないと成果物コミットしてないから当然コンパイル通らない
Avatar
omochimetaru 11/9/2017 9:28 AM
んーっと vapor build は 内部で swift build をする、みたいな感じかなと
Avatar
そう
Avatar
omochimetaru 11/9/2017 9:28 AM
あー リモートでデプロイするためのコマンドが手前側にあって
9:28 AM
リモートはvapor build をするのか
Avatar
そうそう
Avatar
omochimetaru 11/9/2017 9:28 AM
うわ〜 それだと何もさせないね
9:29 AM
せめてローカルのvapor build ならオレオレbuildを叩くようにすれば手前にはさめたけど
9:29 AM
向こう側はどうしようもなさ
Avatar
コミットするしかないんやろかとなって一旦デプロイ周りは棚上げしといた
Avatar
omochimetaru 11/9/2017 9:29 AM
でもそれだと、CSS Spriteとか
Avatar
VaporのSlackで聞いたら「今は無いけど将来やりたいねそれ」って言ってた
Avatar
omochimetaru 11/9/2017 9:29 AM
なんか他にもいろんな前処理したいときにできなくね?
9:29 AM
あ、そういうのはコンパイル後だからなんとかなるのかな?
Avatar
そもVaporアプリ自体のコンパイルに必要でなければあとでも良い気がする。
Avatar
omochimetaru 11/9/2017 9:30 AM
リソースはvapor buildとは別に用意したらいいのか。
Avatar
そね
10:53 AM
テストできるようになりました。
👍 1
🎊 1
Avatar
環境変数を使ってPackage.swiftの内容を切り替え、GYSB=1 swift testでコード生成し、swift testで生成したコードを利用する方法を思いついた。
Avatar
あー たしかにテスト実行中にソースを書き出せば、、、
Avatar
テストターゲットを生成用と利用用に分ける方法も考えたけど、swift test --filter Generateとテストするモジュールを制限しても全てをビルドしようとするから、未生成なコードに依存する部分がビルド出来なくてダメだった。
Avatar
そうか、テストターゲットじゃないと、実行ができないのか
Avatar
// swift-tools-version:4.0 import PackageDescription import Foundation let package: Package if ProcessInfo.processInfo.environment["GYSB"] != nil { package = Package( name: "Generate", dependencies: [ .package(url: "https://github.com/omochi/gysb.git", .branch("master")), ], targets: [ .testTarget(name: "Generate", dependencies: ["GysbKit"], path: "Tests/GenerateTests") ] ) } else { package = Package( name: "Example", products: [ .library(name: "Example", targets: ["Example"]), .library(name: "Generated", targets: ["Generated"]), ], targets: [ .target(name: "Example", dependencies: ["Generated"]), .target(name: "Generated", dependencies: []), .testTarget(name: "ExampleTests", dependencies: ["Example"]), ] ) }
11:19 AM
$ tree . ├── Package.resolved ├── Package.swift ├── README.md ├── Sources │   ├── Example │   │   └── BuildPhase.swift │   └── Generated │   └── vector.swift └── Tests ├── ExampleTests │   └── ExampleTests.swift ├── GenerateTests │   └── GenerateVectorTests.swift └── LinuxMain.swift こんな感じ (edited)
11:22 AM
あ、テンプレートを別の場所に置かないとダメだ。
Avatar
norio_nomura 11/9/2017 1:31 PM
Package.swiftYamsをビルドして、それを.gysbの中でインポートしようとしてるのだけど、うまくいかないな。
1:32 PM
Test Case '-[GysbWithYamsTests.GysbWithYamsTests testExample]' started. process execution failure path=[/usr/bin/swift] arg[0]=[/var/folders/kt/2mwy9b_56_7993x190pl_1fh0000gn/T/vector_49IokLMk.swift] arg[1]=[-L] arg[2]=[/Users/norio/github/GysbWithYams/.build/x86_64-apple-macosx10.10/debug] statusCode=[1] stderr= /var/folders/kt/2mwy9b_56_7993x190pl_1fh0000gn/T/vector_49IokLMk.swift:4:9: error: no such module 'Yams' import Yams ^ Test Case '-[GysbWithYamsTests.GysbWithYamsTests testExample]' passed (0.438 seconds).
Avatar
omochimetaru 11/9/2017 1:32 PM
$ /usr/bin/swift /var/folders/kt/2mwy9b_56_7993x190pl_1fh0000gn/T/vector_49IokLMk.swift
1:32 PM
↑これを実行しているだけだから、フレームワークサーチパス的なところで
1:33 PM
ビルド済みのYamsが見えていないと
1:33 PM
見つけられないです
Avatar
norio_nomura 11/9/2017 1:33 PM
とりあえずこんな感じで起動してます。 return try execCapture(path: swiftPath, arguments: [path, "-L", "/Users/norio/github/GysbWithYams/.build/x86_64-apple-macosx10.10/debug"]) (edited)
Avatar
omochimetaru 11/9/2017 1:34 PM
ああなるほど。
1:34 PM
ほんとだ、よくみてなかった。
1:34 PM
とりあえず、直接swiftコマンドで実行できるコマンドを
1:34 PM
見つけるのが良さそう
1:34 PM
-F <value> Add directory to framework search path
1:35 PM
.frameworkならこっちですよ。
1:35 PM
static libarryなら、 -L <value> Add directory to library link search path -l<value> Specifies a library which should be linked against これらの併用がひつよう
1:35 PM
フレームワークの場合に -l も必要だったかはよくわからない
Avatar
norio_nomura 11/9/2017 1:45 PM
-I…,-L…,-F…つけても、YamsのPackage.swiftでライブラリtypeを.static.dynamicにして-lYamsつけてもダメだ。 path=[/usr/bin/swift] arg[0]=[/var/folders/kt/2mwy9b_56_7993x190pl_1fh0000gn/T/vector_NwwoI7hu.swift] arg[1]=[-I] arg[2]=[/Users/norio/github/GysbWithYams/.build/x86_64-apple-macosx10.10/debug] arg[3]=[-F] arg[4]=[/Users/norio/github/GysbWithYams/.build/x86_64-apple-macosx10.10/debug] arg[5]=[-L] arg[6]=[/Users/norio/github/GysbWithYams/.build/x86_64-apple-macosx10.10/debug] arg[7]=[-lYams] statusCode=[1] stderr= /var/folders/kt/2mwy9b_56_7993x190pl_1fh0000gn/T/vector_NwwoI7hu.swift:4:9: error: no such module 'Yams' import Yams (edited)
Avatar
omochimetaru 11/9/2017 1:46 PM
うへえ
Avatar
norio_nomura 11/9/2017 1:47 PM
ああ、ソースコードのパスを引数の最後に持ってきたら通った。
Avatar
omochimetaru 11/9/2017 1:48 PM
おお。
Avatar
norio_nomura 11/9/2017 1:59 PM
Yamsのlibrary typeを.dynamicにして、以下のオプションをswiftに渡したらいけた。 return try execCapture(path: swiftPath, arguments: [ "-I", "/Users/norio/github/GysbWithYams/.build/x86_64-apple-macosx10.10/debug", "-L", "/Users/norio/github/GysbWithYams/.build/x86_64-apple-macosx10.10/debug", "-lYams", path, ])
Avatar
omochimetaru 11/9/2017 1:59 PM
-I と -L は両方そこでいいんですね
Avatar
norio_nomura 11/9/2017 2:00 PM
テンプレートはこんな感じ % import Foundation % import Yams % guard let yaml = try Yams.compose(yaml: String(contentsOf: URL(fileURLWithPath: "TestResources/vector/vector.yml"))) else { fatalError() } % let vars = yaml.array().flatMap { $0.string } % for n in 2...4 { struct Vector${n} { % for i in 0..<n { var ${vars[i]}: Float % } } % }
Avatar
omochimetaru 11/9/2017 2:00 PM
これは、アプリのプロジェクトのPackage.swiftで、Yamsとgysbの両方を依存させていて、 swift run gysb が通る状態?
Avatar
norio_nomura 11/9/2017 2:01 PM
// swift-tools-version:4.0 import PackageDescription let package = Package( name: "GysbWithYams", dependencies: [ .package(url: "https://github.com/omochi/gysb.git", .branch("master")), .package(url: "https://github.com/jpsim/Yams.git", .branch("master")), ], targets: [ .testTarget( name: "GysbWithYamsTests", dependencies: ["GysbKit", "Yams"]), ] ) class GysbWithYamsTests: XCTestCase { func testExample() { do { let driver = Driver.init(path: "TestResources/vector/vector.swift.gyb") let actual = try driver.render(to: .render) print(actual) } catch { print(error) } } static var allTests = [ ("testExample", testExample), ] } (edited)
Avatar
omochimetaru 11/9/2017 2:02 PM
なるほど
Avatar
norio_nomura 11/9/2017 2:07 PM
SwiftPMはライブラリプロダクトのtypeが未指定でもリンクしてくれますが、この使い方の場合、libYams.alibYams.dylibが無いとダメですね。
2:08 PM
type: .staticでも本当はいけると思うのですが、swiftcがクラッシュしてしまいダメでしたが。
Avatar
omochimetaru 11/9/2017 2:08 PM
なるほど〜
2:09 PM
SwiftPMのデフォルトは .static なんですか?
Avatar
norio_nomura 11/9/2017 2:10 PM
Swift 4からデフォルトではライブラリを生成しなくなりました。
Avatar
omochimetaru 11/9/2017 2:10 PM
ほう
Avatar
norio_nomura 11/9/2017 2:10 PM
ライブラリを構成する.o達を直接リンクします。 (edited)
Avatar
omochimetaru 11/9/2017 2:10 PM
マジか
2:10 PM
あーシンボルはパッケージで切ってるからいいじゃんってか
2:11 PM
Cとはちょっと違う世界に進みつつありますね
Avatar
norio_nomura 11/9/2017 2:11 PM
swift test -vとかしてみるとコンパイラの起動オプションを見られます。
2:15 PM
type: .dynamicにするとswift build --static-swift-stdlibとかしてもそれらのライブラリはダイナミックリンクされるみたいだから、今後は使い勝手が悪くなると避けられるんじゃないかな? (edited)
Avatar
omochimetaru 11/9/2017 2:18 PM
うーむ、そうなんですかね Swiftが出てきたころから基本dynamic frameworkとembeddedだったから (edited)
2:18 PM
てっきりそういう思想なのかと思っていたけど
2:18 PM
最近static系のサポートも強くなってきていますね
Avatar
norio_nomura 11/9/2017 2:37 PM
.dynamicなライブラリを同じパッケージ内のexecutableターゲットから使う場合は問題ないのですが、依存しているパッケージから使った場合、それらはフルパスでリンクされてしまい、ポータブルなexecutableではなくなってしまいます。 $ otool -L ./.build/x86_64-apple-macosx10.10/debug/gysbClient ./.build/x86_64-apple-macosx10.10/debug/gysbClient: /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1445.12.0) /Users/norio/github/GysbWithYams/.build/x86_64-apple-macosx10.10/debug/libGysbKit.dylib (compatibility version 0.0.0, current version 0.0.0) /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.0.0) (edited)
Avatar
omochimetaru 11/9/2017 2:38 PM
ふむ
Avatar
前も書いたけど、 gyb でなくても Swift で Multiline String Literal が追加されたから、↓みたいな感じで大体いける気がする。これならなんでもフルに Swift の機能使える。 prefix operator > prefix func >(value: String) { print(value) } let intTypes = [8, 16, 32, 64] for intType in intTypes { for sign in ["", "U"] { >""" /// Extension that adds a few additional functionalities to \(sign)Int\(intType) extension \(sign)Int\(intType) { /// Returns a \(sign)Int\(intType) with all ones """ if sign == "" { >""" public static var allOnes:Int\(intType) { return Int\(intType)(bitPattern: UInt\(intType).max) } """ } else { >""" public static var allOnes:UInt\(intType) { return UInt\(intType).max } """ } >""" } """ } } (edited)
2:56 PM
元の gyb は↓。 %{ intTypes = [8,16,32,64] }% % for intType in intTypes: % for sign in ['','U']: /// Extension that adds a few additional functionalities to ${sign}Int${intType} extension ${sign}Int${intType} { /// Returns a ${sign}Int${intType} with all ones %if sign == '': public static var allOnes:Int${intType} { return Int${intType}(bitPattern: UInt${intType}.max) } %else: public static var allOnes:UInt${intType} { return UInt${intType}.max } %end } %end %end
Avatar
gysb - Generate your swifty boilerplate
😎 1
Avatar
SwiftPM対応できた
5:52 AM
%! swift_config("gysb_swift_config.json") %{ import Foundation import Yams let yamlPath = URL.init(fileURLWithPath: "data.yml") let yamlStr = try! String(contentsOf: yamlPath, encoding: .utf8) let yaml = try Yams.compose(yaml: yamlStr)! let fields: [String] = yaml.array().map { $0.string! } }% struct Data { % for field in fields { var ${field}: String % } }
5:53 AM
json { "packageDependencies": [ { "url": "https://github.com/jpsim/Yams.git", "requirement": { "identifier": "0.5.0", "type": "exact" } }, ], "targetDependencies": [ { "name": "Yams" } ] }
Avatar
おお、すげー!
Avatar
実行時に複数ファイル指定した場合は、一つのSwiftPMターゲットにまとめるから、Yamsの取得やビルドは共有される ただし、 %! swift_config() の指定は1ファイルだけがする。
Avatar
@omochimetaru 使う側はどこで Package.swift 指定するの?コマンドオプション?
Avatar
↑にはったjsonを書く。
Avatar
ああ、↓に書くのか。 %! swift_config("gysb_swift_config.json")
Avatar
昨日僕が無理やりswiftのコマンドラインオプションでやってたことを、全部SwiftPMへ丸投げしたということですね。 👍
Avatar
ですね SPMのワークスペースを作って、execターゲットのmain.swiftを生成するようになりました
Avatar
@omochimetaru Package.swift 的に、 gybs.json をディレクトリにおいておけば自動的に反映とかが良くないかな?そうすれば gysb ファイルに余計なものを追加しなくて良くて、gyb を Swift にしただけという体を保てそう。 (edited)
6:02 AM
ただし、 %! swift_config() の指定は1ファイルだけがする。
これも結構罠になりそう。
6:02 AM
a と b で同じライブラリが必要だけど、 a だけ、 b だけ、 a と b 同時に、って gysb に渡すときに全部サポートすることができなさそう🤔
Avatar
ディレクトリにおいておくっていうのが悩ましくて source/fooModule/foo.swift.gysb source/barModule/bar.swift.gysb ってなってるときに $ gysb source/fooModule/foo.swift.gysb って指定すると、 gysb.json はどこにあるんだ?ってなっちゃうんですよね
Avatar
source/fooModule/gybs.json じゃないかなぁ
6:05 AM
それか、Package.swift と同じ階層におくことにするか。
Avatar
それは場合によっていて、 source/ ** / * .gysb をドカンとツリー変換したい場合もあるだろうから
Avatar
%! import("https://github.com/jpsim/Yams.git") とかするとswift_config()に渡すjson相当のものが自動で生成される様にするとか。
Avatar
$ gysb --config source/gysb.json source/fooModule/foo.swift.gysb こういう感じはできるけどコマンドラインを長くしたくない・・・
Avatar
↑それだとファイルとライブラリの関係を示せない
Avatar
これも結構罠になりそう。 a と b で同じライブラリが必要だけど、 a だけ、 b だけ、 a と b 同時に、って > gysb に渡すときに全部サポートすることができなさそう
configが同じファイルならOKにするか
Avatar
利用側がどの gysb.json を使えばいいかわからないから
Avatar
同じconfigになっているソースがまとめて指定される限りOK
6:07 AM
これだとソースが自己言及的にできる
Avatar
対象となる gysb ファイルから遡って、 Package.swift と同じ階層までの gysb.json を適用するとかどう? (edited)
6:08 AM
ああ
6:08 AM
そうか
6:08 AM
別に Swift 限定じゃないから
Avatar
%! import("https://github.com/jpsim/Yams.git") とかするとswift_config()に渡すjson相当のものが自動で生成される様にするとか。 これの問題点は、パッケージ名からターゲット名がわからないこと
6:08 AM
そう、あと、生成テンプレートはSwiftに依存させたくないから
6:08 AM
Package.swiftを探すとかは マッチしない場合も多そう
Avatar
なるほど。
Avatar
gyb って import 使えるんだっけ?
6:09 AM
使えるなら参考にできるかも?
Avatar
つかえます
Avatar
gybは使えますね、pythonの言語機能のimportが使える。
Avatar
たとえば、パスの通ってるところに
Avatar
Swiftのimportはファイルパス的なしくみじゃないからできない。
Avatar
Foo.framework を置いてある前提にするとか?
6:10 AM
あー,
6:10 AM
Swift PM に乗っかって実行してるんだっけ?
Avatar
そうそう。
Avatar
それなら無理か。
6:10 AM
お、じゃあ
Avatar
libSwiftPMが気軽に使えれば「リポジトリからPackage.swiftを解釈して〜」とか簡単に出来そうなのに… https://github.com/apple/swift-package-manager/blob/master/Package.swift#L19
swift-package-manager - The Package Manager for the Swift Programming Language
Avatar
gysb を実行したディレクトリが対象となるファイルの先祖ディレクトリの場合、
6:11 AM
対象ファイルのディレクトリからカレントディレクトリまで遡って探すとかは?
Avatar
SwiftPMにgysb機能を載せた方が早そうな気がしてきた。
Avatar
そうすれば SwiftPM 対応のリポジトリで、リポジトリのルートに gysb.json おいて一括実行とかもできる
Avatar
現状の仕様で、テンプレート側から
6:13 AM
gysb.json を指定していれば
6:13 AM
それでスッキリしてません?
6:13 AM
探索するとかは、Swift以外の利用時に無駄な処理になるし
6:13 AM
カレントディレクトリの影響をうけずにコマンドラインだけで一貫した結果がいい
Avatar
@omochimetaru これを swift リポジトリ本体に組み込むことを目指すなら、できるだけ gyb に寄せておいた方が受け入れられる気がして、余計なものを付けない方がいいかなぁと。
6:14 AM
↓この記法一つで議論の余地がいくらでもあると思うので。 %! swift_config("gysb_swift_config.json")
Avatar
Swift本体に組み込む事は目指してなかったですね、Swiftソース以外の生成も前提にしているから、そこで設計方針がかみあわないのか
6:15 AM
個人的にはC++の生成にも使いたいのです
Avatar
Swiftのコンパイル時にSwiftが必要になるから、gybの代替にはなれない気がする
Avatar
セルフホスティングはまだ早いと思いますが、gyb 程度の用途だったらいけそうな気も。
Avatar
Swift本体とは独立したテンプレートエンジンとして存在してもらうほうが使う側としては嬉しみ
Avatar
↓この記法一つで議論の余地がいくらでもあると思うので。
そうですねえ、ここにマイクロ言語が必要になっているのは微妙ではある
Avatar
独立して使えるけど、それを swift リポジトリでも使うという状況を想定してます。
Avatar
brew install gysbできる様になると良いね。
Avatar
いま %! swift_config 以外に %! include_code っていうマクロ命令もあって
Avatar
それはしたい < brew
Avatar
それで他のSwiftソース(テンプレートロジックの方)を取り込んだりできるんですが
6:18 AM
この機能のためにどうしてもミニ言語が必要に。
Avatar
include_code はカオス度が増しそうだなぁ。
6:18 AM
↑例
6:19 AM
"libs/*.swift" に書いてある func aaa() {} と func bbb() {} がここにテキスト展開される。
Avatar
色々な機能を入れると混沌とするから、必要最小限なものをシンプルに保つのが良さそうな。サードパーティライブラリが使いたいのはわかるから、そこはなんとかするとして。
Avatar
Swiftがスクリプティングサポートを充実して
6:20 AM
ソースコードの相対パスimportができれば
6:20 AM
こんなものはいらなかったんだ
Avatar
gysb の実行を Swift PM に依存しない方法はないかな?
Avatar
さっきのYamsの例(Swift製YAMLライブラリ)だけみても
6:21 AM
かなりきついですね
6:21 AM
Cソースとかも絡んでいるので。
Avatar
swift コマンドで Framework のパス指定して実行できなかったっけ?
6:21 AM
ライブラリのビルドは Swift PM でやるとして
Avatar
その辺り、昨夜僕が試しました。
Avatar
gysb が生成したコードの実行を Swift PM に依存しない
Avatar
Frameworkがdynamicかstaticかで渡し方が変わったり
Avatar
結論としては、ライブラリの配布元でのPackage.swiftによりswiftコマンドラインオプションの指定方法とか変わってくるので、めんどい。
Avatar
あと、>ライブラリのビルドは Swift PM でやるとして SPMの.buildから生成物を手で取ってくるっていうのは不便だと思います
Avatar
うーん、それならやっぱり gysb.json を gysb ファイルと同じ階層においておくだけってのはわかりやすいと思うけどなぁ。
6:24 AM
一括実行は諦めるか、 SwiftPM 対応リポジトリの場合だけ Package.swift と同じ階層も見るとか。
6:25 AM
あとはコマンドラインオプションで指定もできるくらいかなぁ。
Avatar
一括実行を諦めると
6:25 AM
Yamsなどの重い依存を
6:25 AM
何回も取得・ビルドすることになって
6:25 AM
かなり動作が遅くなってしまう
Avatar
えっと、それは swift_config 書く場合と同じで
6:26 AM
gysb.json は各ディレクトリに置くけど
6:26 AM
一度に実行した場合はビルドは一度とかでいいんじゃない?
6:27 AM
指定を gysb ファイルの中に書くか json ファイルの有無でやるかだけの違い。
6:27 AM
gysb Sources/Foo/*.gysb Sources/Bar/*.gysb
Avatar
たとえば src/foo/a.swift.gysb src/foo/b.swift.gysb src/foo/gysb.json src/bar/c.swift.gysb src/bar/d.swift.gysb src/bar/gysb.json こうなってるときに $ gysb src/ こう実行したら
6:28 AM
ああ、これは衝突するから一緒にはできませんよって
6:28 AM
今と同じルールにするということか
Avatar
うん。解決ルールは今と変わらないはず。
Avatar
src/fooとsrc/barをまとめて変換したければsrc/gysb.jsonをおくと
Avatar
設定が同じ場合、 gysb をすべてのディレクトリにコピーしてまわるか、すべてのファイルの先頭の行に書くか程度の違い。
6:29 AM
gysb src/ で再帰的にgysb さがすの??
Avatar
はい それはまだ対応してないけどやるつもり
Avatar
再帰は gysb -r src/ とか明示的にした方が良さそうな気も。
Avatar
ああ、そうですね。
6:30 AM
$ gysb --source-dir src
6:30 AM
こういうイメージ
Avatar
再帰指定のときはその過程の gysb.josn も全部適用で良さそう。 (edited)
Avatar
あ〜
6:31 AM
gysb.jsonごとに実行を分割すればいいのか
6:31 AM
ていうかそれファイル複数のときでも一緒だな
6:32 AM
入力されたファイルごとに対応するgysb.jsonがあって、gysb.jsonごとにグルーピングしてそれぞれ実行すれば良いのか。
Avatar
うーん、それってでも複数 gysb.json で同じライブラリが指定されてた場合、多重ビルドにならない?そこは頑張って回避?
Avatar
複数gysb.jsonをマージしてビルドすることは考えてなかった
Avatar
ん?だって gysb Sources/Foo/*.gysb Sources/Bar/*.gysb みたいなことがしたいんじゃないの?
Avatar
↑の例なら、 Sources/gysb.json が置いてあればうまく動くけど
6:34 AM
Sources/foo/gysb.json と Sources/bar/gysb.json が置いてある場合
6:34 AM
一つのビルドにはできない
6:34 AM
という想定でした
6:35 AM
実際、違うライブラリだけど同じターゲット名、とかが出てくるとマージしようもないし。
Avatar
マージして重複排除でライブラリビルドして、実行はディレクトリ単位にすれば競合があっても解消できそう。
6:35 AM
親と子で競合したらダメだけど。
Avatar
実行はディレクトリ単位っていうのはどういう意味です?
Avatar
ディレクトリの gysb.json を見る方式だと、ディレクトリ単位でしか指定できないから。
Avatar
ディレクトリ単位にした時点で実際のSwiftPMワークスペースがばらばらになるから
6:36 AM
ライブラリが共有できないです
Avatar
swift_config を導入せずに gysb.json を置く方式にするのであれば、一つのディレクトリの中で設定を切り替えることはできないという意味です。
6:37 AM
逆に言うと、同じディレクトリの gysb ファイル同士では設定(ライブラリ)が競合することはない。
Avatar
マージして重複排除でライブラリビルドして、
6:37 AM
このマージするっていうのは
6:38 AM
同じgysb.jsonファイル同士を (edited)
6:38 AM
同じものと検出するってことを言っている?
Avatar
複数の gysb.json の中に書かれた同じバージョンに解決される同じライブラリを重複ビルドしないようにするということを言ってます。
6:39 AM
あー、でもバージョンの解決は Swift PM がやるから無理か。 (edited)
6:39 AM
完全一致くらいなら排除できそうだけど・・・
Avatar
Sources/foo/a.swift.gysb Sources/foo/b.swift.gysb Sources/foo/gysb.json Sources/bar/x.swift.gysb Sources/bar/y.swift.gysb Sources/bar/gysb.json こうなっているときに
6:40 AM
a.swift.gysb と b.swift.gysb を、 一つのPackage.swift でビルド x.swift.gysb と y.swift.gysb を 一つのPackage.swiftにして ビルド (edited)
6:40 AM
っていうふうにすることを考えているけど
6:41 AM
foo/gysb.json と bar/gysb.json をマージして、ライブラリをまとめてビルドするのだとして、
Avatar
Package.json は Package.swift の間違い??
Avatar
その場合、Package.swift は1つで、そこに、a.swift.gysb , b.swift.gysb , x.swift.gysb, y.swift.gysb が所属して、コンパイルするってイメージですか? (edited)
6:43 AM
その考えはわかって、最初そういう意味だと思ったんですけど
実行はディレクトリ単位にすれば競合があっても解消できそう。
その場合この「実行はディレクトリ単位」の概念がわからなかった。
Avatar
そうかー、ビルドを Swift PM に依存してる時点で同一ライブラリであっても Package.swift 間で共有できないのか。 .build 以下をコピーする処理をいれれば共有できるかもだけど。
Avatar
ああ、異なるPackage.swiftがあるけど依存ライブラリのバイナリは再利用することを想定していたんですね
6:44 AM
それはSwiftPMの仕様上うまくできなそうと考えています (edited)
Avatar
そうです < 異なるPackage.swiftがあるけど依存ライブラリのバイナリは再利用することを想定していたんですね
Avatar
SwiftPMは結構細かいことを中でいろいろやっているので
6:45 AM
あんまり途中成果物のバイナリを触って何かするっていう系は
6:45 AM
うまくいかなそうだなあと思ってます
6:46 AM
昨日 @norio_nomura がいろいろ試した結果もそう思った
Avatar
そもそも依存ライブラリの作りによっては、ライブラリのバイナリが生成されない。 (edited)
Avatar
ああ、それもありましたね。
6:46 AM
それが一番ビックリしたんだった。
Avatar
うーん、そしたら、
Avatar
foo/gysb.json と bar/gysb.json でそれぞれ Package.swift 作って2回ビルドでいいと思いますよ。
Avatar
↓ 2 回実行 Sources/Foo/gysb.json Sources/Bar/gysb.json
Avatar
Sources/gysb.json だけにしてけば 1回ビルドにできるのだし。
Avatar
Souces/gysb.jsonSources/Foo/gysb.json をマージ、 Souces/gysb.jsonSources/Bar/gysb.json して 2 回実行 Souces/gysb.json Sources/Foo/gysb.json Sources/Bar/gysb.json
6:49 AM
(差分だけを Foo/gysb.json 等に記述することを想定)
6:50 AM
Foo, Bar 以下のすべての gysb ファイルに対して 1 回で実行 Souces/gysb.json
6:50 AM
とかかなぁ。
6:50 AM
もちろん recursive 指定の場合。
Avatar
そもそもそんなにSources/gysb.json と Sources/Foo/gysb.json で何か分割定義したいと思わないと思うんですよ
6:51 AM
あくまでメタプログラミングのためにつかうライブラリだから
Avatar
そうですね・・・
Avatar
FooではYAMLを読むしBarではXMLを読むからっていって
6:52 AM
別に Sources/gysb.json で YAML と XML 両方のライブラリぶち込んでおいて
6:52 AM
それでFooの管理上困るってことも無いと思う。
6:53 AM
それは要望が出てきてから考えるとして、とりあえずは gysb.json 一個に対して 1 Package.swift で良いと思う
6:54 AM
それはそれとして、 %! swift_conifig はやめてディレクトリ遡り探索の gysb.json にしようと思います
6:55 AM
そのほうが 同じgysb.json 配下の gysbテンプレート達に対して、特定のファイルだけ変換するってことができる。
6:55 AM
swift_config 方式だと全部にその指定を書かないといけないからめんどくさい
Avatar
お、いいですね < %! swift_conifig はやめてディレクトリ遡り探索の gysb.json にしようと思います
6:55 AM
include も廃止?
Avatar
include は必要だと思う。
Avatar
むー
Avatar
ちょっと共通のメタプログラミング用の関数とかは生える事が結構あって
6:56 AM
でもそれをわざわざSPMパッケージにしてリポジトリをわけるのは
6:56 AM
面倒な場合があるだろうから、その場で結合できたほうが良さそう
6:56 AM
あ、でもあれか
6:56 AM
gysb.json で
6:57 AM
結合するファイル達として指定できるようにするという手はあるな。
6:57 AM
同じ理由でincludeを全部に書くのは面倒だから。
Avatar
その方が %! という複雑性を持ち込まなくてよさそう。
Avatar
そうですね
Avatar
どちらかというと include したいのはテンプレートそのものの include だと思うけど
6:58 AM
( HTML 生成するときのヘッダー、フッターとか)
6:58 AM
それも関数化して gysb.json で指定でできるかな?
Avatar
テキストのinclude 、 コード ( % { } の内側 ) のinclude、テンプレートのinclude
6:59 AM
の3種類がありえるとおもったので今は include_code () だけがあるんですが
6:59 AM
テンプレートのincludeにした場合、それ自体は、 %{ } で包まれた中にswiftコードを書いたファイルになるんですが
7:00 AM
それが swift ファイルにならない (構文上) .swift.gysb になってしまう
Avatar
↓とかできるんだっけ? % func foo() { FooFooFoo % } % for _ in 0..<3 { % foo() % }
Avatar
というのが微妙だなあと思っていて
7:00 AM
できますね
Avatar
↓結果 FooFooFoo FooFooFoo FooFooFoo
Avatar
そうなるはず。
7:00 AM
で、swift.gysb になっちゃうと、再帰実行とかで巻き込まれるんですよね・・・
Avatar
よくわかりません・・・
Avatar
gysb.jsonの中に記述できる様にしてしまうとか。
Avatar
jsonの中にswiftを書くのは辛いと思います
Avatar
yamlならいけるかな
Avatar
えっと、 include_code で取り込まれるファイルは
7:03 AM
それ単体でvalidなswiftソースです
Avatar
yaml ならいけるかもしれませんが、 gysb の実行に YAML パーサが必要になって依存が生まれてしまいそう・・・
Avatar
func taxRate() -> Float { return 1.08 }
7:04 AM
とかこういうファイルなわけです。
Avatar
なるほど、何でもテキストを展開するというわけではないのか。
Avatar
でも、 @koher のいうように、 テンプレートをインクルードする機能だとしたら
7:04 AM
%{ func taxRate() -> Float { return 1.08 } }
7:04 AM
こういうファイルを用意することになって・・・
7:05 AM
このファイル名は metalib.swift.gysb とかになる。
7:05 AM
で、さっきの Sources の例でいえば
7:05 AM
Sources/foo/a.swift.gysb // こいつが それを読みに行く Sources/foo/metalib/metalib.swift.gysb
7:05 AM
たとえばこういうファイルツリーにしたくなると思います。
7:06 AM
で、さっきまでの議論を前提に考えて、 $ gysb --source-dir Sources を実行すると・・・
7:06 AM
Sources/foo/metalib/metalib.swift.gysb が 処理対象になって、 自分を自分の上部にincludeしようとして、無限ループして壊れる。
Avatar
そういうことか。
Avatar
これは困ったな、という話です。
7:07 AM
今の仕様であれば、インクルードするのはテンプレートではなくでコードなので、 Sources/foo/metalib/metalib.swift が置かれているけど、これはgysbの実行には関与しないのでうまくうごく。
Avatar
foo/gysb.json に metalib の include を記述とか?
Avatar
再帰探索で metalib.swift.gysb が見つかったときに、これはinclude用だから処理対象からはずそう、 っていう制御をするってことですか?
Avatar
うーん、 gysb から読み込む swift ファイルおくとかは Swift PM で壊れたりしないかな?ディレクトリ分けておけば Package.swift でコントロール可能?
7:09 AM
@omochimetaru はい。 include 用のディレクトリを明記するとか。
Avatar
ターゲットを分けちゃうと public にするとかいろいろ出てきて面倒なんで、シンプルにテキストとして結合されるのが便利な気がします
7:10 AM
いま想定してるのはさっきの func taxRate() みたいな、ちょっとしたやつ。
Avatar
Swiftファイルを読み込むってのは微妙そう。インクルードされるファイルは gysb でも swift でもないべきでは?
7:12 AM
gysb.gysb とか?
Avatar
テンプレートだけどインクルード用としてわかるようにする、っていう手はありますね
7:12 AM
拡張子を gysbi にするとか。
Avatar
ネスト数が必要かと思ったけど、起点を gysb にすればいいだけだから特に問題ないか。
7:13 AM
gysbi が gysbi を include するような場合でも
Avatar
それは大丈夫ですね。
Avatar
でも gysb だとマズイよね。ディレクトリで再帰的に指定されるような場合、インクルード用ファイルも単独で展開されちゃう。
Avatar
gysbi が gysbi を include する
これは、ファイルの中に include 命令が書けるってことになってるとは思うけど・・・
7:14 AM
拡張子が gysb だと面倒なことになりますね
7:14 AM
gysbi が良さそうだなあ。
7:15 AM
template の include なのであれば
Avatar
テキストで include する機能だったら、どのラインに展開するかも重要だから %! 的な構文は避けられなさそう。
Avatar
テキストを注入する効果もあるわけなので
7:15 AM
そうそう。
Avatar
ってか、 gysb 以外なら拡張子なんでもいいのか。
Avatar
まあそうです。
7:15 AM
includeを考えていくと %! から逃げられないですね
7:15 AM
まあgybはそれはできないですけど。
Avatar
%! include("path/to/file") の行をそのファイルの中身で展開するだけ。
Avatar
gybはメタpythonとしてのimportがあるだけだからテキストのincludeはできない
Avatar
Jekyll の include の構文は↓ {% include footer.html %}
7:18 AM
このパスに変数使えたりする {% include {{ page.my_variable }} %}
7:18 AM
ここまで来るとさらにメタになるけどカオスかな?
7:18 AM
んー、でも
7:19 AM
↓とかもあり得る? % for i in 0..<10 { %! include("file\(i).gysbi") % }
Avatar
現状は %! のマクロ言語はテンプレート処理系の前段にあるとしています
7:20 AM
CコンパイラとCプリプロセッサの関係と一緒
7:20 AM
現実的に↑は無理で、なぜなら、
7:20 AM
Swiftとしてのコンパイルをして実行して
7:20 AM
でてきたものを再びテンプレートとして処理するっていうふうに
7:21 AM
Swiftコンパイル実行が何回も繰り返されるモデルになるので
Avatar
include を関数として実装できないかな?
Avatar
実行も遅いし変なことになったときわけがわからなくなりそう。
7:21 AM
テキスト注入する関数としては実装できますが
Avatar
ファイルを読み込んでその内容を write する
Avatar
いまやりたいのはSwiftのメタライブラリを提供するシナリオだから
7:21 AM
includeをコンパイルする時点でコンパイルエラーになって駄目ですね
Avatar
そうだなぁ。
Avatar
include_text: Swift上で実装できる include_template: Swiftコンパイル前に処理しないといけない
Avatar
Swift の関数を読み込むことはできないけど、テンプレートを読み込むことはできるんじゃない? gysbi ファイルに対して gysb を実行して得られた文字列を挿入すれば。
7:25 AM
Jekyll はそっちの挙動だと思う。
Avatar
gysbコマンドを実行して結果を注入するってことですか?
Avatar
はい。
Avatar
それはまあできるけど、Swiftの関数を読み込みたい・・・
Avatar
関数読み込みは gysb.config で記述できそう。
7:26 AM
個別に Swift ファイルのパスを指定するだけで。
Avatar
そうですね。
7:26 AM
機能としては現状の %! include_code を
Avatar
Swift ファイルは gysb じゃないから無限再帰問題もないし。
Avatar
jsonにgysb.jsonに書くようにするってことですね
Avatar
はい。
Avatar
それはありだと思います。
7:27 AM
テンプレートを読み込みたいっていったのは @koher だし・・・
Avatar
テンプレートエンジンとしてはその機能はほしいかと思ったけど、とりあえずなしでいいと思います。複雑化するし。
7:27 AM
そうすれば %! も排除できる。
Avatar
そうですね > %!
7:29 AM
しばらく離席します
Avatar
brewのバイナリ配布、sourceryがSwiftPMでビルドしたものを使ってる。 https://github.com/Homebrew/homebrew-core/blob/master/Formula/sourcery.rb
homebrew-core - 🍻 Default formulae for the missing package manager for macOS
7:32 AM
実行環境のSwiftバージョン依存を減らせるから、バイナリ配布はそのうち必要。
Avatar
@mono さんも LicensePlist を brew で配布してたような。 (edited)
Avatar
PR来て途中まで対応しつつ、実はまだ対応できてないです( ´・‿・`)
🙃 1
7:35 AM
Issue: #52 I hope I can install this library with CocoaPods. I tried installing with CocoaPods by referring to SwiftLint etc. I did not actually register with CocoaPods, so I can not confirm whethe...
Avatar
配布手続きはそれほど難しくないです。 (edited)
Avatar
PR や issue で音信不通悲しいですね😂
Avatar
分かれば簡単そうとは思いつつ、初めてだとそれなりに手間取りそうと思って敬遠しちゃっていました 🐶
7:37 AM
その後1回も突っついてないだけなので、何かしらアクションすれば続きできそうですが(あるいは自分で続きやっても良いですが)
7:38 AM
あ、完全に勘違いしていました。
7:38 AM
brewはやってます。
7:39 AM
CocoaPods配布が途中でした 🐶
7:40 AM
でも、brewもバイナリ配布ではなくビルド必要な形式にしちゃっています。 https://qiita.com/mono0926/items/c32c008384df40bf4e41 (edited)
mono0926/LicensePlist という、Carthage・CocoaPodsおよび手動指定ライブラリから、iOS設定アプリに載せられ...
👍 1
Avatar
LicensePlist は CocoaPods でインストールしているライブラリのライセンス情報の生成には対応しているけど、 LicensePlist 自体の CocoaPods でのインストールが未対応ってことですか?
Avatar
そうです。
Avatar
SwiftPM や Carthage と比べると複雑ですよね・・・
Avatar
Homebrewでのバイナリ配布は途中までやりかけたものの少し面倒そうと感じていたところに ishkawaさんからこうリプライいただいて、省略しちゃいました。 https://twitter.com/_ishkawa/status/863662412196597760?ref_src=twsrc%5Etfw&ref_url=https%3A%2F%2Fqiita.com%2Fmono0926%2Fitems%2Fc32c008384df40bf4e41
@_mono それは試したことないですね。自分はbrewで入ればなんでも良いか〜って思ってCarthageの真似で済ませちゃいました。
Avatar
Swift 界隈以外に使ってもらうためのツールならバイナリ配布した方がいいかも?
Avatar
成果物がiOSアプリ用なので、その辺りはあまり問題ないかもです。
Avatar
LicensePlist は大丈夫そうですね。 gysb はバイナリも要りそう。
Avatar
あ、なるほど、そちらはそうですね。
7:47 AM
あと、LicensePlistの場合は、Swift 4対応するとまだXcode 8メインで使っている人がビルドできなくなっちゃうのでそのケアのためにまだ3のままです 🐶
Avatar
ああ、tapにしたのですね。>ビルド必要な形式
Avatar
tapかどうかってビルド必要とは関係なかったような?? bottles対応を省いたからビルド必要、という認識でした。
Avatar
bottles対応ってオプトインだったかな?勝手にビルドされてた様な…
Avatar
bottles do ... end にバイナリの置き場所書けば対応で、省略すればインストール先でビルド必要な認識でした。 (edited)
7:52 AM

はじめに

Homebrewは自作のライブラリを公開することが割と楽な機能を提供してくれている。しかしながら、その作業全体についてちゃんと書いてくれているブログが少ないので、備忘録として自分の作業を晒しておく。なお、自分のgi...
Avatar
gysbはテンプレート言語がswiftで、テンプレートを描画するためにswiftのビルド実行をしているので
7:52 AM
gysb自体がビルドできない環境ではgysbを使うことができないと思います
Avatar
gysbをビルド出来るswiftバージョンと扱うテンプレートに書かれたswiftバージョンが違う場合に、バイナリ配布だと回避できるよね、と。
Avatar
たしかに・・・
Avatar
https://github.com/Homebrew/homebrew-core/ へのformula PRは、CIがビルドに成功したらボトリングしてくれます。まあ、tapでも自前でボトリングすればバイナリ配布は出来るのかな。
homebrew-core - 🍻 Default formulae for the missing package manager for macOS
Avatar
あ、なるほど、前者を知らなかったです。 後者でやろうとして面倒で一旦省略しました。
Avatar
[swift-evolution] update on forum Ted Kremenek via swift-evolution The decision to move to a forum was announced a while ago, and it hasn’t appeared yet. I think we will be making the move soon and I wanted to provide some reasons why it was delayed and what comes next. ... My hope is that process will start in December.
Avatar
@koher gysb.json と include_files 機能できました。マクロ機能を排除できました。アドバイスありがとうございました。
👍 1
Avatar
yaml ならいけるかもしれませんが、 gysb の実行に YAML パーサが必要になって依存が生まれてしまいそう・・・ 一応書いておくと、YamsはCodableをサポートしたYAMLパーサです。Yams自身には外部ライブラリ依存はなくて、利用実績としてはSwiftLintが.swiftlint.ymlのパースに使っています。
Avatar
gysb.jsonではなくgysb.ymlも書けたほうが良いですかね? 手書き想定ファイルだしそうかな
Avatar
@norio_nomura gysb から Yams 等への依存が生まれるという意図でした。依存自体は悪くないんですが、なくせるならなくした方が望ましいとは思うので。
👍 1
Avatar
CIができたから次はHomebrewじゃい、と思ったが、monoさんの記事読んで、なんかめんどくさそうだな・・・って気分
🐶 1
Avatar
改めてmonoさんの記事を読んだけど、tap作る手順は面倒いね。homebrew-coreへPR出す方が簡単なのでは…
👀 1
Avatar
それぞれの長所短所あまり把握し切らず、何となく最近のはtapが多いかな??と思いつつそっちにしました。 (edited)
12:09 PM
Vaporとかもtapですね( ´・‿・`)
Avatar
とりあえずtapならオレオレで勝手にできるから楽そう
Avatar
@_mono 初回は苦戦した記憶がありますが、1度やれば簡単だった気がします。参考になるかわかりませんが、当時のメモを貼っておきますね。 https://t.co/OBZtRlwl1S
12:15 PM
そういえば、あまり深く考えずにこれをベースにした、というのがtapにした大きな理由でした( ´・‿・`)
Avatar
なるほど
Avatar
やべえ・・・
12:16 PM
ちょっと変えるだけでタグのプッシュとtarのDLとハッシュの計算が必要や・・・
Avatar
LicensePlist - A license list generator of all your dependencies for iOS applications
12:18 PM
そのあたり苦手ですが、がんばって書きました🐶
Avatar
https://github.com/Homebrew/homebrew-core/fork を開いてforkして、remote登録: $(brew --repository homebrew/core) git remote add omochi https://github.com/omochi/homebrew-core.git したら、次のコマンドでformula作成: brew create https://github.com/omochi/gysb/archive/0.8.6.tar.gz して、出来たgysb.rbdepends_on, def install, test dohttps://github.com/Homebrew/homebrew-core/blob/master/Formula/sourcery.rb 辺りを参考に設定して、 brew install --verbose --debug gysb でインストールテストして、 cd $(brew --repo homebrew/core) git checkout -b gysb git add Formula/gysb.rb git commit git push https://github.com/omochi/homebrew-core/ gysb してPR、って感じかな?
GitHub is where people build software. More than 25 million people use GitHub to discover, fork, and contribute to over 71 million projects.
homebrew-core - 🍻 Default formulae for the missing package manager for macOS
👀 1
12:18 PM
Makefileとか不要。
12:19 PM
class Gysb < Formula desc "Generate your swifty boilerplate" homepage "" url "https://github.com/omochi/gysb/archive/0.8.6.tar.gz" sha256 "139fd7225442c74e943b32716158a3ea5bd438241372a3cf913fd5313793248e" depends_on :xcode => ["9.0", :build] def install system "swift", "build", "--disable-sandbox", "-c", "release", "-Xswiftc", "-static-stdlib" bin.install ".build/x86_64-apple-macosx10.10/release/gysb" end test do # `test do` will create, run in and delete a temporary directory. # # This test will fail and we won't accept that! For Homebrew/homebrew-core # this will need to be a test that verifies the functionality of the # software. Run the test with `brew test gysb`. Options passed # to `brew install` such as `--HEAD` also need to be provided to `brew test`. # # The installed folder is not in the path, so use the entire path to any # executables being tested: `system "#{bin}/program", "do", "something"`. system "true" end end
Avatar
bin.install はなんですか?
Avatar
https://docs.brew.sh/Formula-Cookbook.html を見ると大体わかる。
🍺 The missing package manager for macOS
👀 2
12:23 PM
PR開くとチェックリストがテンプレートに載ってるので、追加でそれらに載ってるテストが必要。
Avatar
ユーザー増えてきたら本家入り考えることにします
Avatar
一度掲載されたら、次回バージョンアップからはコマンドライン1発でPR開くところまでいけたはず。 https://github.com/realm/SwiftLint/blob/master/Makefile#L114
SwiftLint - A tool to enforce Swift style and conventions.
Avatar
なるほど。それは楽だ。。
12:35 PM
上で書いたFormulaはtest dosystem "true"とか書いたけど、そこは真面目に書き換えないといけない。
12:36 PM
テストはsandbox環境下で行われるので、sandboxで動かない機能をテストしたりすると失敗する。
12:38 PM
sourceryの場合は期待したバージョンをsourcery --versionで返すかどうか、かな。
Avatar
ふむふむ
Avatar
あ、sourceryはsandboxのせいで、本来のテストが出来てないみたいだな。 本来のテストは真面目にコード生成してる。 https://github.com/Homebrew/homebrew-core/blob/master/Formula/sourcery.rb#L32-L54
homebrew-core - 🍻 Default formulae for the missing package manager for macOS
12:47 PM
gysbのテスト記述はこれを参考に出来そう。
Avatar
なるほど brew と ruby の道具で書いてありますね
Avatar
この辺りが自前tapリポジトリを使ったとしても通用するのかどうかは知らないです。
12:52 PM
homebrew-coreもtapなので、いけそうな気もしますが。
Avatar
そういえばSSSやってる人はみんなVaporとかKituraとかPerfectとかどれでやってますか?
Avatar
#server-side チャンネルがいいかも
Avatar
あったそんなチャンネル!
Avatar
swift - The Swift Programming Language
Avatar
朝見たけどまだ何もなさそうだった
Avatar
何が起こるんだろう・・・
Avatar
Android対応とかですかねえ
Avatar
うーん、 Android は Kotlin 採用したし、 Swift だと JVM で動かないし、違いそうな気がするなぁ。 Chris Lattner がらみかな?
Avatar
GoogleのSwift fork、本家に Fuchsia OS 対応のプルリク投げてる https://t.co/jPsh9Kvi0h
Avatar
Fuchsia is a capability-based, real-time operating system (RTOS) currently being developed by Google. It was first discovered as a mysterious code post on GitHub in August 2016, without any official announcement. In contrast to prior Google-devel...
Avatar
https://bugs.swift.org/browse/SR-6103 この前投稿した LoE のバグが解決された よかった
Avatar
ズル
Avatar
tarunonのバグは・・・
Avatar
なんだと
3:44 AM
返事がほしいでござる
Avatar
@omochimetaru Assignee 担ってるけど、何かアクションを求められてるの?
Avatar
あれ、ほんとうだ
Avatar
勝手に直せやだったらウケる
Avatar
いま resolved だけど、 closed に俺がするんか?
3:45 AM
コメント欄で聞いてみる
Avatar
僕の唯一のResolvedは担当者無しやで
3:48 AM
適当なんちゃう?
3:48 AM
そもそもそれも明らかに治ってるのに音沙汰なかったからこれ治ってるよね?って聞いたら解決済みになったやつ
Avatar
6126は CC joe groff ついたけど 6304については完全に無だね
Avatar
感情が消えた
Avatar
投票しておいた
Avatar
6126はそもそも変性のルールがほこ×たてしてるからなぁ
3:50 AM
ほこたてで変換したら変なのでた
Avatar
動作確認はしたの?>Assignee
Avatar
いや、まだです
3:53 AM
Tracking internally as rdar://35215926. ↑こうなっちゃった時点で
3:53 AM
それについて再現テストがたされたのかとか
3:53 AM
よくわからんのですよね
3:54 AM
僕が確認することより再発防止のためにテスト追加することが一番大事だと思うんですけど・・・
Avatar
PRではテストが追加されてるみたいだけど。
Avatar
ですね。ちょうど今見てました。
3:57 AM
+struct ParameterizedStruct<T> { + mutating func takesFunctionWithGenericReturnType(_ f: (Int) -> T) {} +} これがArrayに相当してるのか
Avatar
とりあえず、issueに載せたコードを動かしてみるといいのでは?w
Avatar
そうですね、マージされてるし、あとでsnapshot落としてきて試してみます。
Avatar
あ、まだこのPRを含むsnapshotは無いみたい。
Avatar
あれ、でもmaster に merged だから
4:07 AM
a
4:07 AM
November 15, 2017
Avatar
git tag --contains cf9a09e18dba7a7fe0506381589fbf0f4bb99a98 で何も出ない。
Avatar
mergeされたのが17日か
4:08 AM
dailyが15日以降まだ来てないんですね。CIがコケてるのかしら。
Avatar
swift-DEVELOPMENT-SNAPSHOT-2017-11-21-a出てる。
Avatar
DL中
Avatar
#beginner-help_archived が別の話題が進んでるんで、こちらで質問させてください。Swift で C++ の const 引数みたいなことって method / closure でできるんですっけ?
Avatar
method / closureでできるの意味がいまいちわからないですが
Avatar
inoutじゃない値型は全部copyなので実用上constになる気がします
Avatar
すいませんわかりづらい書き方でした。引数で渡す class をその method 内で変更しないことを示せるのかな?と思って。
Avatar
classはあきらめて
Avatar
ですが、そもそも class に non mutating な method が定義できないので、const 性を保証できないのでそれはおかしいというツッコミを受けました(報告)
Avatar
残当
🙏 1
😭 1
Avatar
struct にすれば > inoutじゃない値型は全部copyなので実用上constになる気がします < このとおり
8:12 AM
あとは class なら親クラスを readonly な type にして サブクラスで mutating なメソッドを一通り実装すれば・・・
8:12 AM
引数で渡す class をその method 内で変更しないことを示せる
これじたいはできるよ。
Avatar
readonlyをprotocolで表現してprotocol型で渡した方が良いですね
8:13 AM
流石にclassは面倒すぎるしlet propertyをvarでoverrideできな…できるの?!
8:14 AM
iPhoneなので試せない
Avatar
たしかにprotocol横付けが楽ですね、ジェネリックだったら 😇
Avatar
今回はジェネリックじゃないので protocol 案でいけそう
8:19 AM
🙏
Avatar
ジェネリックでもassoctypeつけて関数をジェネリックにすれば動くから出来るまで頑張ろう
Avatar
ああこの状況なら <X: Proto> でいいのか
Avatar
そう
Avatar
なるほどなるほど
Avatar
たしかに別にプロパティに保管するわけじゃないからいけるのか
Avatar
プロパティに保管するならその時にerasureを使うぞ
Avatar
無駄Optional警察だ!👮
Avatar
www
8:47 AM
そこかいw
Avatar
代入テストで雑にそうしました… 🙏
Avatar
あとこれclassはそのままclassなんで意味なくないですか
Avatar
processPoに渡すクロージャの中ではsetterが呼び出せないから意味あると思うよ (edited)
Avatar
あ、これはPoについてConstにしたいのか
8:49 AM
Elementについてと勘違いしてた
Avatar
そうです。Po を Const にしたかった
Avatar
型パラが妙に多いな
8:50 AM
func processPo<X: ConstPo>(po: X, process: (X.Element) -> Void) { これでok
Avatar
なるほど!
Avatar
本当はElementとかも含めて再帰的にConst化したいと思うんですが、今日のswiftではそれをシュッとやるのは無理ですね
8:54 AM
structつかおう (edited)
Avatar
たしかに再帰は…
8:55 AM
うーんなるほど
9:00 AM
あ、でも今回は露出するプロパティが値型なので完全に目的を達成できそう
9:01 AM
ありがとうございました
Avatar
これって const の場合と違って、型ごと CostoPo を満たさないといけないの微妙そう。
Avatar
そこなんすよね
Avatar
struct じゃダメ? Swift の class は二級市民だと思ってる。
Avatar
そうですね
Avatar
抽象クラスとかもないし。
Avatar
View なのでうーん…
Avatar
再起でできるためにはConstableみたいな不毛なprotocolが必要になって、class to type-erasure structな記述をやる羽目になる
Avatar
View に対応した ViewModel を struct で作って渡すとか?
Avatar
structだとvar/letですむのに
Avatar
View 自体を操作する関数だとダメだけど。
9:04 AM
(でも const にしたいくらいだから View から情報をとりたいだけに見える)
Avatar
そうですね
Avatar
caseでenumから値とるやつ、ここまとめられるの知らなかった。 enum Hoge { case fuga(Int) case piyo(Int) var count: Int { switch self { case .fuga(let count), .piyo(let count): // <- ここ return count } } }
Avatar
えっ、どうなってんの、それ
Avatar
protocolはまとめられないよん
Avatar
同じ let count だからいける?
Avatar
同じ具体型なら変数そろえて同一視できる
Avatar
ワオー知らなかった
Avatar
tarunonのいうとおりこれはエラーなった protocol ProtocolA {} enum Hoge { case fuga(ProtocolA) case piyo(ProtocolA) var count: ProtocolA { switch self { case .fuga(let count), .piyo(let count): return count } } }
9:25 AM
Playground execution failed: error: MyPlayground.playground:5:24: error: matching a protocol value in multiple patterns is not yet supported; use separate cases instead case .fuga(let count), .piyo(let count): ^
Avatar
前はコンパイラが破壊された
9:25 AM
僕の報告一覧にあるよ
9:25 AM
一応コンパイルエラーになったから解決なのかな
Avatar
おもしろ記法みつけたと思ったら過去にtarunonに破壊も報告も修正もされてるのなんか悔しい
9:26 AM
悔しい💢
Avatar
そんなおこらんといてや
Avatar
Swift おもしろ記法 探検隊
Avatar
@tarunon これなら通りそうなもんだけど、これもだめなんか protocol ProtocolA {} enum Hoge<T: ProtocolA> { case fuga(T) case piyo(T) var count: T { switch self { case .fuga(let count), .piyo(let count): return count } } }
Avatar
パターンマッチ関連のおもしろ記法と言えば前に教えてもらった↓かなぁ。 let a: Int? = 42 if case let a? = a { print(a) }
9:28 AM
Optional Binding よりも意味がわかりやすい。
Avatar
でた 左辺ハテナw
Avatar
あれそれIterator.next()が粉砕されるやつでは
Avatar
これって C で int *a = ...; *a = 42; って書くのと似てるよね。 (edited)
Avatar
@hiragram そのTが通らないのは謎やね
Avatar
だよね。
Avatar
見た目だけは似てますね・・・ > *a = 42
Avatar
いや、 *aint 型というのと、 a?Int 型というのが。
Avatar
a? は Int 型ではないですよね
Avatar
あ、これはInt型だから虐殺文法ではなかった
Avatar
代入文の左辺に書けるだけで a? は Optional<Int> だからこそ a の部分だけが Int
9:33 AM
この言い方だとCもそうだけど・・・
9:33 AM
Cは中身と外見が先にあってデリファレンスするけど、 Swiftのさっきの式は中身がそこで産まれるから逆な感じがする。
Avatar
逆か。 a?Int?aInt か。
9:35 AM
C は *aintaint *
Avatar
さっきのTが通らないの、Tにprotocol入れられたら壊れるからと思ったけど、今はconditionalな型パラはそもそもprotocol入らないので益々謎だ
9:37 AM
その条件付けサボってるのかな
9:39 AM
それか将来的にprotocolが来る可能性があって意図してそうやってるか
Avatar
抜けてるだけじゃねって印象
9:43 AM
@tarunon プロパティじゃなくてメソッドにしたらエラーメッセージがなんか愉快なことになったよ protocol ProtocolA {} enum Hoge<T: ProtocolA> { case fuga(T) case piyo(T) func value<T>() -> T { switch self { case .fuga(let value), .piyo(let value): return value } } } error: MyPlayground.playground:6:20: error: cannot convert return expression of type 'T' to return type 'T' return value ^~~~~ as! T
Avatar
9:44 AM
報告しよう
Avatar
as! Tいれると其の行はエラー消えるけどcase文の行がまたさっきのエラーでるんだけどね
9:44 AM
つまりvalueはTとして認識できてるんだからそのままコンパイル通ってもいいようなきがするんだけどそういうわけではない?
Avatar
不思議なエラーだ
Avatar
意図的に止めてそう
9:45 AM
protocol型で其れが出来ないのは、実際にはprotocol型そのものではなく存在型として振る舞ってることが関係してそうで
9:46 AM
型パラは常にprotocolが当てられることを想定した振る舞いになってる
9:46 AM
TとTが違うよは意味分からんけどprotocolのそれを踏まえて考えると然もありなん
Avatar
文脈的に1個目のTと2個目のTが違う型の可能性ある可能性あるからってことよね
Avatar
だね
9:49 AM
ただまあエラーメッセージは適切ではないから報告はしといてよさそう、回答も貰えるといいね
Avatar
どっから報告するんだっけ。
Avatar
bugs.swift.org
Avatar
あとで暇みつけて書いておく
9:50 AM
こっちの書き方はちゃんとやってくれてうれしい typealias Tuple = (Int, String) enum Hoge { case fuga(Int) case piyo(Tuple) var value: Int { switch self { case .fuga(let value), .piyo((let value, _)): return value } } }
9:54 AM
piyoにくっついてくる値がIntのプロパティをもつようなstructで、caseまとめて書く記法のなかでそのstructのIntのプロパティ取り出せたら便利かと思ったけどそこまでごちゃごちゃしてるならcase分けるわな
Avatar
struct のプロパティとかをパターンで抽出するの、昔 swift のソースに無効化された状態であったけど、やらない雰囲気だからって消された覚えがあります。
Avatar
おおっ
Avatar
別件で Array の要素とマッチさせるのは evolution に何度か上がってた記憶ありますね。
9:59 AM
case let [first, second, third]: みたいな。
Avatar
おー。
10:02 AM
この場合要素数が2だったらこのcaseにマッチしなくなるのか (edited)
Avatar
そんなのがあったのか〜
Avatar
error: MyPlayground.playground:6:20: error: cannot convert return expression of type 'T' to return type 'T' return value ^~~~~ as! T これは真っ当なエラーでは…
Avatar
というか、タイプの T使うなら func はこの場合Genericsにすべきでないですね。
Avatar
見逃してた
11:14 AM
<T>ついてるw
Avatar
あ、ほんとだ。
Avatar
あっ
11:14 AM
ごめんなさい 🙏
11:15 AM
↑それさっきやらかした
Avatar
タイプの型パラshadowしたら警告出すとか有用なのかも。
Avatar
↑の例は Event と T だからshadowでもないんですよね・・・w
😇 1
11:17 AM
Array.Elementも結構引数で受けるときはT, U で書いちゃうし
11:18 AM
逆にそのような警告を出す機能があったら、ちゃんとした名前をいつでも使うように心がけるようにはなりそうだ。
Avatar
この余分なTあるとnever使えなくなって訳わからなくなるよね
Avatar
推論がコケるんだよねw
11:21 AM
すぐ気づけて良かった・・・
Avatar
ハマると、一度ハマった経験がないと気づけなくなる
Avatar
https://bugs.swift.org/browse/SR-1420 既に上がっていました。<型パラshadow警告
Avatar
要望っぽいものも上がってるんですね
Avatar
sublime text の syntax カラーリング わかってきた
3:59 PM
しかし既存の Swift プラグインは残念ながら tmLanguage 形式で
4:02 PM
これとがんばって連携していくか、 sublime-syntax 形式での対応を1からやるか・・・
Avatar
ほうほう、tmLanguage って TextMate のシンタックス定義なんですね。
Avatar
そのようです。SublimeText2まではそっちだったけど、SublimeText3から、tmLanguageも使えるけど、独自のsublime-syntaxを使おうねって感じ
4:04 PM
スタック付きの正規表現ベースのオートマトンみたいな仕組みっぽい
Avatar
Swiftのパーサ周りを読んでいたら、 TokentokTok が出てきて、
3:10 AM
Tok の定義が全然見つからないと思ったら Token 型のフィールド名が Tok だった・・・
3:12 AM
ちなみに tok は enum
Avatar
フィールド名を UpperCamelCase にするのは LLVM 文化特有なんですかねー。
Avatar
Googleは snake_case_ ですね、他のC++プロダクトをそんなに読んでないのでわからないですが
Avatar
やっぱりxcodeでリーディングしようと思ってclone,update,build-script --xcodeしてxcodeで開いて、
1:18 PM
プロジェクトのソースツリーのカオスさに笑ってる
Avatar
ソースツリー役に立たないから検索ばっかしてる
Avatar
Swift がオープンソースになってしばらく経ちます。 コンパイラや標準ライブラリの開発に手を出してみたいけど、リポジトリを落とした後どうしていいかわからない!という方のために、まずは開発環境の構築方法をご紹介します。基本的には[RE...
1:19 PM
この記事のスクショとすこし違ってる(Sourcesが無い)
1:21 PM
ひらりがこの前言ってた、ファイル名あいまいジャンプできるやつ
1:21 PM
役に立ちそう
Avatar
⌘⇧Oと⌘⇧Fめっちゃ使うけど結構迷子になるからソースツリー+差分と履歴も使う
1:24 PM
ソースツリーの下の検索ボックスの横に時計とgitマークあるので、onにすると最近見たファイルとか差分のあるファイルで絞り込めてソースツリーが使い物になるようになる
Avatar
なるほど
1:26 PM
あ、あった、ここらへんだ
1:26 PM
swift/lib/XXX のディレクトリごとに対応するターゲットがあった
Avatar
え、、、
1:27 PM
俺は一体今まで何を、、、、
Avatar
上から60%ぐらいのところに
1:28 PM
swiftIndex , swiftIDE, swiftIRGen, swiftParse
1:28 PM
などのグループがあって、それぞれの中に、SourceFilesとHeaderFilesが入ってて
1:29 PM
1:29 PM
ここらへんの lib/ XXX / CMakeList と対応してるっぽいね
Avatar
なんか、グループの作られ具合、CMakeのバージョンによっても違うのかも。
Avatar
CMakeList一個が一個のターゲットになってて、Xcodeに噛み合わないやつは、そのままCmakeをたたくだけのスクリプトターゲットになってて、 オプション違い?もバラバラに生成されるから、こんなカオスなのだな
1:31 PM
xcodeprojの生成自体は完全にcmake側の機能に任せてるんですかね?
Avatar
そのはずですね。 CMake -G Xcode
Avatar
なるなる
1:34 PM
おっしゃー
1:34 PM
Tok でジャンプできたぞw
1:34 PM
1日消えたw(途中で寝落ちしてた (edited)
Avatar
--release-debuginfo --xcode でビルドしたら
4:43 PM
clang: error: no such file or directory: '/Users/omochi/work/swift-source/build/Xcode-RelWithDebInfoAssert/cmark-macosx-x86_64/src/Debug/libcmark.a' と出ていて (edited)
4:43 PM
実際には /Users/omochi/work/swift-source/build/Xcode-RelWithDebInfoAssert/cmark-macosx-x86_64/src/RelWithDebInfo/libcmark.a
4:43 PM
が生成されているので
4:44 PM
--release-debuginfo なのに cmark は --debug で参照しちゃっててうまくいってないみたいなんですけど
4:46 PM
--xcode は作業用、 ninja でビルド するのが良いのか? release-debuginfo があまりメンテナンスされていないので、 release にするのが良いのか? とか、どうなんでしょう
Avatar
あら、 Releaseでやっても同じところでコケた
Avatar
あっ!
7:17 PM
なるほど、build-scriptに渡したconfigurationとは別に、xcode側のいつものconfigurationをちゃんと設定しないといかんのか。
Avatar
スナップショットの出てるコミットでやってるけど、下記でコケてしまうので、 --xcode のせいなのか、そうでないのか調べるために ninja でもやってみます。 /Users/omochi/work/swift-source/build/Xcode-ReleaseAssert/swift-macosx-x86_64/Release/bin/swiftc -apinotes -yaml-to-binary -o /Users/omochi/work/swift-source/build/Xcode-ReleaseAssert/swift-macosx-x86_64/Release/lib/swift/macosx/x86_64/ScriptingBridge.apinotesc -target x86_64-apple-macosx10.9 /Users/omochi/work/swift-source/swift/apinotes/ScriptingBridge.apinotes
Avatar
いけた。
Avatar
下記がエラーになる件、 /Users/omochi/work/swift-source/build/Xcode-ReleaseAssert/swift-macosx-x86_64/Release/bin/swiftc -apinotes -yaml-to-binary -o /Users/omochi/work/swift-source/build/Xcode-ReleaseAssert/swift-macosx-x86_64/Release/lib/swift/macosx/x86_64/ScriptingBridge.apinotesc -target x86_64-apple-macosx10.9 /Users/omochi/work/swift-source/swift/apinotes/ScriptingBridge.apinotes 出力先 /Users/omochi/work/swift-source/build/Xcode-ReleaseAssert/swift-macosx-x86_64/Release/lib/swift/macosx/x86_64 が存在してなかったが、 /Users/omochi/work/swift-source/build/Xcode-ReleaseAssert/swift-macosx-x86_64/Release/lib/swift は存在していたので、 mkdir してやったら、いけました。
Avatar
あれっ
3:47 AM
同じ問題が再現したら報告しようとおもって改めて別マシンでやっていたのだけど
3:47 AM
ビルドできてしまった。
3:48 AM
snapshot 11/22から11/23に変更したのが良かったのか、 最初からschemeをちゃんとReleaseにしたのが良かったのか、わからんけど・・・
Avatar
#swift スレの話題がエッジな概念ばかりでてきてて笑うw
Avatar
has-a パターンを作るときに、機能Xをhas_aで合成する事を表すプロトコルも一緒に定義すると、
3:48 AM
エクステンションも併用するとフィールド定義するだけで一通りのプロパティとメソッドが自動的に生える
3:48 AM
って事ができて便利だなってなってる
3:49 AM
class ViewBindingHelper<Model> { ... } protocol ViewBindingHelperUser { associatedtype Model var helper: ViewBindingHelper<Model> { get } } extension ViewBindingHelperUser { 追加される機能 }
3:49 AM
こうしておいて
3:50 AM
class ProductListTableView : NSTableView, ViewBindingHelperUser { let helper: ViewBindingHelper<ProductList> = .init() } (edited)
3:50 AM
使う側ではこうやって1行書くともろもろ生える
Avatar
これやると諸々のフィールドが他のhas_a関係のprotocoolのフィールドと名前がかぶって…となってとてもつらい (edited)
Avatar
名前がかぶっちゃうシチュエーションでは User の方のプロトコルコンフォーマンスは解除して、 .helper.method でヘルパ名をネームスペース代わりにするしか無さそう。
Avatar
でもまあこのやり口めちゃくちゃ便利なのはそうで
Avatar
ヘルパオブジェクト以外にも依存メソッドがある場合はどうしようもないね、helperのinitにクロージャで注入しようとかになるね
Avatar
subviewとかで使うと捗る場面が結構ある
Avatar
継承したカスタムビュークラス複数で共通の機能とか?
Avatar
そうそう
Avatar
カスタムビューだと継承で親クラスが注入できないからか。
Avatar
Viewだとclassなのでmix-inみたいなことはできなくて
3:55 AM
protocolベースで定義してそれをhas-a関係でprotocolでガチャガチャ組み立てていくと、mix-inみたいな感じで書ける(読めるとは言っていない)
Avatar
わかるなあ
Avatar
protocol MyViewProtocol { var button: Button { get } } protocol HasMyViewProtocol: MyViewProtocol { associatedtype MyView: MyViewProtocol var myView: MyView { get } } extension HasMyViewProtocol { var button: Button { return myView.button } }
3:57 AM
こんな感じだ
3:58 AM
そうするとMyViewをsubviewとして持つ全てのImplementationが、buttonにアクセスできるし、functionの実装をextension MyViewProtocol に置けば全部使えるようになる
Avatar
あ〜HasXそれ自体もXにするのか
Avatar
「Swiftの暗黒面」じゃない?🤔 https://qiita.com/tarunon/items/844958accc4391097d97

はじめに

SwiftのOptionalを取り巻くあれやこれやについて考えを整理しつつ書きます。 多くの人にとっては役に立たない雑多な話題かもしれません。差し当たりSwift EvolutionのDraftのDraftぐらいの話でし...
Avatar
立派な暗黒面ですよ
7:14 AM
このままABI安定化とかいい出したらオシマイです
Avatar
タイトルが「Swiftの暗黒面」になるのかと思ってました🙃
Avatar
いつもの話のまとめなので、ここの人たちには新鮮味が無さそうなのはちょっと申し訳ないですね 🙏
Avatar
むしろ、ここで話されたことをまとめていくのが大事な気がしてます。
Avatar
それはそうw
7:20 AM
ディスコまとめ人いない問題
Avatar
パーマリンク無いと無理無理…
Avatar
まあ、 iOSDC や try! Swift で発表していくのがいいかと。
7:21 AM
あ、 Swift Tweets もありますよwよかったらどうぞ🙂
Avatar
We already have the ability to quickly go through pinned messages and recent mentions that bring us towards a certain position in the chat to view that message. And even more recently got the new search feature that is an even more powerful version of that. It would be nice if we can have the ability to obtain and post a permalink of a message where people can click on it and will directly be brought to the position of the original message, instead of having us to manually get users to search for an older message we want them to see.
7:21 AM
みんなも!さあ!
Avatar
omochimetaru 12/7/2017 7:21 AM
@koher Discord Offline登壇のために東京来る予定ありませんか
Avatar
Kishikawa Katsumi 12/7/2017 7:22 AM
投票しました。
🙆 4
Avatar
@omochimetaru 出張と重なるのが理想的です。
Avatar
omochimetaru 12/7/2017 7:22 AM
そうですよね、なんかいい出張予定があるといい
Avatar
今年は会社の忘年会やらずに新年会やるらしいからそのとき行くかもだけど、さすがに Discord Offline の開催間隔が狭すぎる気が。 (edited)
Avatar
@Kishikawa Katsumi すみませんダブリだった。こっちにもお願いします https://feedback.discordapp.com/forums/326712-discord-dream-land/suggestions/17828437-msg-id-jump
Transform <#msg_id> links into "jump to message" button (like in pins). Alternatively, an inline quote (with a jump button). Right-click a message to extract said id.
Avatar
Kishikawa Katsumi 12/7/2017 7:24 AM
そっちも投票済みです 💯
💯 3
Avatar
omochimetaru 12/7/2017 7:26 AM
なるほど>しんねんかい
Avatar
投票しました ( ・`ω・´)
🙏 2
Avatar
norio_nomura 12/8/2017 1:57 AM
Swift 4.1で-swift-version 3を使うとSwift 3.3になるぽい。 $ TOOLCHAINS=org.swift.4120171207a swift -swift-version 3 Welcome to Apple Swift version 4.1-dev (LLVM 67b9a8e8c2, Clang e617c83242, Swift 65b4172032). Type :help for assistance. 1> #if swift(>=4.1) 2. let versions = "swift-4.1" 3. #elseif swift(>=4.0.3) 4. let versions = "swift-4.0.3" 5. #elseif swift(>=4.0.2) 6. let versions = "swift-4.0.2" 7. #elseif swift(>=4.0) 8. let versions = "swift-4.0" 9. #elseif swift(>=3.3) 10. let versions = "swift-3.3" 11. #elseif swift(>=3.2.3) 12. let versions = "swift-3.2.3" 13. #elseif swift(>=3.2.2) 14. let versions = "swift-3.2.2" 15. #else // if swift(>=3.2) 16. let versions = "swift-3.2" 17. #endif 18. versions: String = "swift-3.3" 18> (edited)
👀 3
Avatar
@tarunon RxSwiftのBehaviorSubjectから値を取り出すとき subject.value() がthrowsなのってなんでなんだろ
Avatar
Errorを購読したらそれ以降はErrorだからやね
Avatar
omochimetaru 12/8/2017 4:50 AM
BehaviroSubjectってそうなのか〜
Avatar
subject.onErrorか
4:50 AM
あー。
Avatar
omochimetaru 12/8/2017 4:50 AM
なるほど〜
Avatar
なるほど。
4:51 AM
VariableはObserverじゃないからErrorにはなりえないけど、BehaviorSubjectはありうるってことか
Avatar
そやね
4:51 AM
今後はBehaviorRelayをつかおう
Avatar
RxSwiftアップデートせなな…
Avatar
BehaviorSubject でやってしまったマン
Avatar
RxSwift。。。とてもムズカシイです😱
Avatar
#swift の裏番組になりますが、assertやpreconditionを「落ちたり落ちなかったりするチェック」として使ったことなかったなー
Avatar
#swift-2 の分解能の話で思い出したけど、AVAudioFile もなぜか AVAudioFramePositionInt64 なのに AVAudioFrameCount は逆に UInt32 しかないという不可解な現象 https://qiita.com/lovee/items/8bdf7b58d96d683d31b9
この記事はゆめみ Advent Calendar 2017 の 1 日目の記事です。 また、本記事は実は下書きのまま 1 年近く寝かされ...
Avatar
↑それは AUAudioFrameCount で自分が上げたのは AVAudioFrameCount なんですよな…
9:03 AM
それにcountがuint32でpositionがint64になっている現象についての説明もありません
Avatar
This alias is type `uint32_t` for impedance-matching with the pervasive use of `UInt32` in the Audio Toolbox framework and the C Audio Unit framework APIs, as well as the `AVAudioFrameCount` data type. (edited)
Avatar
AU じゃなくて AV か。
Avatar
じゃあpositionはなぜInt64なのか
Avatar
ん、ちょっとまって、
9:06 AM
AVAudioFramePosition: Int64 A position in an audio file or stream. (edited)
9:06 AM
UInt64のこっちは ファイル or ストリームだからバイトオフセットで
9:06 AM
AVAudioFrameCount: UInt32 A number of audio sample frames. (edited)
9:07 AM
こっちはサンプルフレームの数
9:07 AM
だから、良いんじゃないですか?
9:08 AM
いや、不自然か?
9:08 AM
8bitステレオオーディオなら1フレーム2バイトだから
9:08 AM
あ、でも、 var length: AVAudioFramePosition { get } AVAudioFileの長さ自体は Int64の方の型ですね
9:09 AM
AVAudioFrameCountは小さいチャンクを扱うときにしか使われてないとかじゃないでしょうか
9:09 AM
リアルタイムAPIで0.2秒分の波形が来る、とかそういう時のフレーム数を表現する用で
9:09 AM
長い曲データの先頭からの完全なオフセットを数える型ではないとか。
Avatar
そもそもpositionはcountを超えたり負になったりする可能性ってあります?
Avatar
非圧縮のWAVファイルで44.1kHZなら 97,391秒だから 27時間分の録音データとかならありえるのでは
9:13 AM
iOSなら死んじゃうけどもともとMacのAPIだし。
Avatar
positionもバイト数のオフセットじゃなくてフレームのポジションなのでそもそも取りうる範囲は0..<countになるはずなんじゃないかと思うのですが…
Avatar
ファイルの長さは 0..<count じゃなくて 0..<length みたいですよ length The number of sample frames in the file.
9:13 AM
lengthの型は var length: AVAudioFramePosition { get }
9:14 AM
↑ここをみてます
9:16 AM
AVAudioFrameCount (32bitの方の型 ) が出て来るAPIは func read(into buffer: AVAudioPCMBuffer, frameCount frames: AVAudioFrameCount) throws があるみたいです、こっちはバッファに一部を読み取る命令だからサイズが全体より小さくてもおかしくないと思う。
Avatar
var length: AVAudioFramePosition The number of sample frames in the file. typealias AVAudioFrameCount A number of audio sample frames. この説明がすでに色々理不尽な気が…(CのAPIに合わせてるのなら逆にじゃあなぜCではcountだけが32bitなのか…
Avatar
まあその2行だけ見ると意図が不明ですね
9:18 AM
AppleのローレベルなAPIにはよくある・・・
9:20 AM
ComponentResult AudioUnitRender( AudioUnit ci, AudioUnitRenderActionFlags* ioActionFlags, const AudioTimeStamp* inTimeStamp, UInt32 inOutputBusNumber, UInt32 inNumberFrames, AudioBufferList* ioData ) inNumberFrames The number of frames to be rendered. (edited)
Avatar
SInt32 startBufferOffset これだけ読むとやはりCでは両方32bitにしてるけどAVFoundationがなぜかpositionだけ64bitにしてるんですよね… (edited)
Avatar
startBufferOffset The starting point of the event, after the beginning of the render.
Avatar
64bit化したNSFileManagerあたりとの連携のため?
Avatar
これは曲ファイル全体でのオフセットではなくて
9:21 AM
あ、いや、そうなのか?
9:21 AM
beggining of renderはプレゼンテーションの開始時刻か
9:22 AM
27時間で壊れそう
Avatar
あ多分再生位置のオフセットはこれかな? UInt32 bufferOffset; bufferOffset Where in the current buffer the event should occur (edited)
Avatar
↓ちょっと違うけどひどいと思うやつ。 GL_PROJECTION // Int32 glMatrixMode(GLenum(GL_PROJECTION)) // Obj-C (C) ではそのまま渡せた (edited)
Avatar
ああー
9:25 AM
それ、 static var GL_PROJECTION: GLenum ってオーバレイ用意してほしいですね。
Avatar
うん (edited)
Avatar
もともと #define だったマクロがそのまま Int32 としてポーティングされてしまっている
Avatar
#defineの数値リテラル?は全部基本Int32になるよね (edited)
Avatar
そのままだとそうっぽいですね
Avatar
そういうことなんだ。じゃあ 32 ビット整数で表せないリテラルがあったら壊れる?↓みたいなの。 #include <stdio.h> #define BIG_NUMBER (0xffffffffffffffff) void printHex(unsigned long long number) { printf("%llx\n", number); } int main(void) { printHex(BIG_NUMBER); return 0; }
Avatar
そもそも #define NAME "aaa" みたいなのもありえるので
9:45 AM
なぞです
9:45 AM
とりあえず収まる整数だけInt32としてインポートしてくれるのかも?
Avatar
単純な #define は型を判定してるのかな?
Avatar
たぶんそうだと思います
Avatar
式が書いてあったりしたらどうしてるんだろ?
Avatar
見えないとか、静的に計算できるなら見えるとか?複雑なルールがある気がしている
9:48 AM
clang-importerの領域だと思う
Avatar
Appleのドキュメント、ヘッダファイル内のコメント拾えてないな。
10:02 AM
AVFoundation.framework/Frameworks/AVFAudio.framework/Headers/AVAudioTypes.h /*! @typedef AVAudioFrameCount @abstract A number of audio sample frames. @discussion Rationale: making this a potentially larger-than-32-bit type like NSUInteger would open the door to a large set of runtime failures due to underlying implementations' use of UInt32. TODO: Remove rationales. */ typedef uint32_t AVAudioFrameCount;
🙏 1
Avatar
つまり将来的には64bitになるっと
Avatar
うーん、そうは書いてないんじゃないかな。
Avatar
そもそも、データ全体をメモリにマップしなくて済む様にするバッファのサイズを指定するものっぽいから、音声データのビットレートが劇的に上がったりしない限りは32bitで済みそうな気がする。
Avatar
TODO: Remove rationales. は具体的に何を指しているのか… 🤔
Avatar
誰かと思ったら @lovee さんのアイコンが変わってた・・・
Avatar
いつまでも勉強会のスライドで版権イラスト載せるのはまずいと思って… 😇
2:29 AM
それでちょうど冬コミに本出すのに表紙イラストをココナラで頼んだからそれをアイコンにすることに
🙂 4
Avatar
Java で intdouble に暗黙の型変換されてて、 double c = a / b;ab が Android の API のコールで int が返される)の精度が落ちてしまっている事例が社内で発覚した。やっぱり数値間ですら暗黙の型変換を許さない Swift の方向性は正しかったんだ〜😂 (edited)
😭 4
Avatar
そのバグ何度も踏んできたから / 書く時はトラウマが呼び起こされてミスしない体になった
7:56 AM
Swiftだと c の型を書かずに let にしていた結果、 Int のまま以降の行まで型推論が伝搬していって、
7:56 AM
渡すところで Double で明示的変換するんだけど、除算はずっとまえに書いてるからやっぱり気づけ無い
7:56 AM
みたいなパターンもあって
7:57 AM
/ 書く時は周囲に型をだいぶ明示的に書きたくなる
7:58 AM
let t = 1 / 2 ... なんか処理 ... TimeInterval(t)
7:58 AM
↑コンパイル通るし 0 の TimeInterval ができちゃう
Avatar
オーバーロードが終端だと全く気づくチャンスがないのか…
Avatar
そうなんだよねえ
8:03 AM
言語によっては / は常に実数除算への昇格で、 整数のあまり切り捨て除算は別の演算子になってることもあるね。
Avatar
Python はそうだね。
Avatar
pythonがそうでしたっけ
Avatar
$ python Python 3.6.1 (default, Apr 19 2017, 14:30:24) [GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.41)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> 3 / 2 1.5 >>> 3 // 2 1
Avatar
おお。 // があった気がしてたけどpythonか。
8:13 AM
pythonはコメントが # だからいけるのかw
Avatar
JSONEncoderconvertToSnakeCase myURLPropertymy_url_propertyに変換するのだけれど、JSONDecoderconvertFromSnakeCasemy_url_propertymyUrlPropertyへ変換するので、デコードに失敗する。 https://bugs.swift.org/browse/SR-6629
Avatar
きびしそう
Avatar
あれ?
11:35 AM
プロパティ名のほうは固定だからどちらでも生じるのは myURLProperty -> my_url_property の変換かとおもってた
11:36 AM
プロパティが myURLProperty, JSON上では my_url_property って関係性は静的に固定できてると
Avatar
convertFromSnakeCaseの実装がまずい。既存CodingKeysstringValuelowercasedとJSONのキーから_を削除した文字列を比較して、一致するCodingKeysメンバを決定しないといけない。 (edited)
Avatar
CodingKeys の stringValue から、 encoder側の convertToSnakeCase と同じ変換をかけてから
11:40 AM
そのキーで JSON のバリューを読めば、ストレートな処理になりませんか?
11:40 AM
KeyedContainer にいったん変換する過程で情報が失われちゃう?
Avatar
ああ、そっちの方が良いかも。
11:42 AM
やっぱりStringに汎用のsnake_casedプロパティとかあった方が良さそう。
Avatar
CodingKeys の stringValue から、 encoder側の convertToSnakeCase と同じ変換をかけてから そのキーで JSON のバリューを読めば、ストレートな処理になりませんか? 今の実装のconvertFromSnakeCaseが色々な表記ゆれをサポートしてるせいで、その方法で上位互換にするのは無理かも。 (edited)
Avatar
表記ゆれは中でサポートせずに外で指定する形にしないと解決でき無さそう
Avatar
ウウム・・・
Avatar
YAMLDecoderで試しに実装してみた。 https://github.com/jpsim/Yams/pull/92
#84 This uses different algorithm on KeyDecodingStrategy from apple/swift#12779 that exprimenting to fix SR-6629.
3:55 AM
#84 This uses different algorithm on KeyDecodingStrategy from apple/swift#12779 that exprimenting to fix SR-6629.
Avatar
「CodingKeysのString から JSONでのキー表現への変換」をする関数を EncoderとDecoderに渡せれば(つまり、convertToSnakeCase などの モードの custom クロージャ版)、1:1対応は全部いけそう。
3:58 AM
今のJSONDecoderは同時に一つのプログラムで、1つのプロパティにたいして複数の文字列表現を受け付けられるわけだけど
3:58 AM
個人的にはその需要は無いと思う。
3:59 AM
それって読み込もうとしてるJSONがそもそも同じ値を表現するために2種類以上のキー表現をバラけて使うということなんで
3:59 AM
そんなん起こらんと思う・・・
3:59 AM
もし起こったらシコシコ init(from decoder) 書けば良いし。
Avatar
そうなんだよね。今のJSONDecoderの実装は無駄に凝りすぎだと思う。
Avatar
同じオブジェクトを表すJSONの形式が複数ある場合は考えられるけど、それはデコーダで対応するんじゃなくて、そのそれぞれのJSONに対応した型を定義して、その先で変換したほうが良い
4:01 AM
そうじゃないと絶対ぐちゃぐちゃになる
4:04 AM
まあFoundation/JSONEncoder/JSONDecoder は、困った事があったら自作や他人の実装使えばいっか、って思ってます
Avatar
objcで定義されたenumに対してswitchをSwiftで書いたとき、どれにもマッチしないときには最初のcaseにマッチしたように動いているようですが、これってSwiftの言語仕様で定義された動作ですかね? typedef NS_ENUM(NSInteger, State) { StateHoge = 0, StateHuga = 1, }; Swift: let state = State(rawValue: 100)! switch state { case .hoge: print("hoge") // ★↑これが実行される case .huga: print("huga") }
Avatar
State(rawValue: 100)nil にならないところが Swift 的に変で、そこのチェックが漏れてるのかもしれませんね。
Avatar
https://developer.apple.com/library/content/documentation/Xcode/Conceptual/RN-Xcode-Archive/Chapters/xc6_release_notes.html objcのenumを非定義の値で初期化できるのは、Swift Language Fixesの3つ目を見た感じ、意図した動作のようではあるのです。
9:37 AM
Imported NS_ENUM types with undocumented values, such as UIViewAnimationCurve, can now be converted from their raw integer values using the init(rawValue:) initializer without being reset to nil. Code that used unsafeBitCast as a workaround for this issue can be written to use the raw value initializer.
Avatar
@rikusouda state.rawValue100 ですか? 0 ですか?
Avatar
100です (実際には少し違うコードでやっていますがenumに定義していない値がrawValueで保持されています)
Avatar
予想ですが、そういう状況で switch で何が起こるかは仕様として決まってないんじゃないかと思います。
Avatar
バグでいいんじゃないかと。 enums.h #include <Foundation/Foundation.h> typedef NS_ENUM(NSInteger, State) { StateHoge = 0, StateHuga = 1, }; main.swift public func foo(state: State) -> Int { switch state { case .hoge: return 1 case .huga: return 2 } } let s = State(rawValue: 100)! print(foo(state: s)) 実行 $ swift -import-objc-header enums.h main.swift 1 $ swift -O -import-objc-header enums.h main.swift 2 (edited)
9:55 AM
-O 有無で結果が違うのはちょっと受け入れられない。
Avatar
未定義動作なんでしょうね。。。
9:56 AM
未定義というか、バグで不定の動作をしてしまっている。
Avatar
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
Avatar
当面はなんらか回避する必要がありそうですね。。。
Avatar
ありがとうございます🙏
Avatar
Numeric って ExpressibleByIntegerLiteral を継承してるのに Int のイニシャライザに Numeric を受けるやつないのか…?
4:49 PM
IntにできないNumericってあるのか?
Avatar
// Integer literals are limited to 2048 bits. というコメントが。 https://github.com/apple/swift/blob/0cf1b52452f56b3bbdf2f2305cc10fef42bdff8b/stdlib/public/core/Policy.swift#L99 (edited)
swift - The Swift Programming Language
Avatar
@hiragram 整数から生成できることと整数に変換できることは別じゃないですか?
1:07 AM
たとえば、複素数は整数から生成できるけど整数には変換できない。
Avatar
レス遅れてすみません。複素数の例でだいぶ納得しました。
1:54 AM
"整数にできる" (=確実にIntにできる) みたいな意味のNumeric関連のプロトコルってなさそうですよね
1:58 AM
NumericExpressibleByIntegerLiteral なのはよくわかんないですよね。行列とかで使えなくなっちゃいますし。
1:58 AM
まあ、 number じゃないから numeric じゃないのかな?
Avatar
行列って "数" 扱いなんですか?数学的に
1:58 AM
"数値" か
Avatar
数が実数を指すなら数じゃないですね・・・
1:59 AM
Numeric よりも、群・環・体 https://qiita.com/taketo1024/items/733e0ecf12da359db729 みたいなプロトコルほしいですよね。
どうも、佐野です。前回の記事 で整数は「環」、有理数・実数・複素数は「体」であるという話をしました。今回は「群・環・体...
👍 1
Avatar
プリミティブな"数値" ではないんじゃないかなーというイメージがありました
Avatar
もしくは、 Addable, Multipliable とかの方がプログラミング的には使い勝手がいいのかも?
Avatar
割り算で変な別れ方になってるしそっちのほうがいっそ良いかも
2:05 AM
現状だとBinaryIntegerFloatingPointで分けて実装してるのが一本化できる
Avatar
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
Swift の String って subscript { set } ができないからイミュータブルなのかと思ってたけど違った。 1> var s = "ABC" s: String = "ABC" 2> s.removeLast() $R0: Character = { _representation = smallUTF16 { smallUTF16 = 67 } } 3> print(s) AB
7:55 AM
普通にappendありますよ
Avatar
うん、そっちも見つけた。
8:04 AM
subscript { set } ができないのは、 Character が何バイトか定まらないから O(1) で実現できないからか。
Avatar
あ、ああ、 subscript { set } ができない って事を知っていたんですね、そっちを知らなかった。
Avatar
EasyText みたいな方式にしないと O(1) の subscript { set } を実現できない。
8:07 AM
append とか removeLast とかって MutableCollection についてるのかと思ってたけど違った。で、 subscript { set } がないから StringMutableCollection じゃないだろう→ appendremoveLast もないだろうと思って勘違いしてた。 https://developer.apple.com/documentation/swift/mutablecollection (edited)
8:08 AM
確かに末尾に追加・削除なら String でも平均 O(1) で実現できて問題ないのか。 (edited)
11:56 AM
faillthroughで遊んでたけど、実際Swiftにおいてどんなユースケースがあるんだろう。
Avatar
Kishikawa Katsumi 12/22/2017 12:08 PM
faillthrough のユースケース?それとも^のコードですか?
Avatar
ユースケースです。上のコードが想定された挙動だということは理解できたんですけど、実際failthrough書くことあんまりないなと思ってまして。 (edited)
Avatar
Kishikawa Katsumi 12/22/2017 12:11 PM
failthroughを使うことはあまりないと思いますよ。だからこれまでのC言語系の文法だとデフォルトがfailthroughだったのをやめたわけで。
12:13 PM
func tokenize(source: String) -> [Token] { let state = State(input: source) for character in state.input { switch state.mode { case .plain: switch character { case "'": state.mode = .symbol case "\"": state.mode = .string case "\n": state.mode = .newline state.storage = "" case "(", ")", ":": state.tokens.append(Token(type: .token, value: String(character))) case " ": break default: state.mode = .token state.storage = String(character) }
👍 1
12:13 PM
^ こういうのとか使うかもしれないけど、caseにカンマで区切ってもかけるから、結局書かない。
12:14 PM
滅多に使わないので下手に使ってfailthroughを見落として下に抜ける方が罠っぽくなるし。 (edited)
12:14 PM
と思います。
Avatar
昔ってカンマ区切り書けなかったんでしたっけ?カンマ区切りあるから本当に出番少ないよなぁという印象です
Avatar
Kishikawa Katsumi 12/22/2017 12:16 PM
Swift 2あたりでデフォルトで下に抜けなくなってfallthroughが入ったんじゃなかったでしたっけ? (edited)
Avatar
そこはさいしょからだったような🤔
Avatar
Kishikawa Katsumi 12/22/2017 12:17 PM
最初からっぽいですね。
Avatar
確か最初からだったはず。さっきはった画像みたいな挙動してほしくないなー。
Avatar
Kishikawa Katsumi 12/22/2017 12:18 PM
Swiftにfallthroughいらないんじゃないというのは同意です。
Avatar
ですね。
Avatar
原因不明だけどなんかスターが急に40-50くらい増えた🤔 https://github.com/koher/EasyImagy
EasyImagy - Makes it easy to process images in Swift
🌟 7
Avatar
以前アドバイスをいただいたMVVMのリファクタリングの記事を公開できました!ありがとうございました!https://qiita.com/Kuniwak/items/015cddcf37e854713a2e
この記事は、RxSwift が提供する公式のサンプルである RxExample で行き詰まった方向けに、実践的な対処方法を紹介します。具体的には RxExample にある MVVM (Model-View-ViewModel) を真...
👏 4
Avatar
This PR changes post increment (and decrement) to pre increment for simple increment case. I think that it is helpful for other new contributors to avoid small fix such like #13572 (comment) . In t...
😅 1
Avatar
2 分w
Avatar
EasyImagy - Makes it easy to process images in Swift
⭐ 2
7:12 AM
これまで CI サボってたけど、スター増えてるからビビって Travis の設定した。 https://github.com/koher/EasyImagy/blob/dev-0.4.0/.travis.yml
EasyImagy - Makes it easy to process images in Swift
7:14 AM
gysb - Generate your swifty boilerplate
AnyObjectConvertible - Convert your own struct/enum to AnyObject easily.
Himotoki - A type-safe JSON decoding library purely written in Swift
APIKit - Type-safe networking abstraction layer that associates request type with response type.
Stencil is a simple and powerful template language for Swift.
Avatar
Swift on the Server continues to evolve. Since the launch of Swift@IBM in 2015, we’ve seen a lot of changes in the Swift language. As part of our collaboration with the server-side Swift community, we created tools like Swift Sandbox, enabling hundreds of thousands of developers to experiment with Swift on Linux. We also built the Swift …
😱 2
Avatar
Today, we announce the deprecation of Swift Sandbox and Swift Package Catalog, to take place in January of 2018.
Avatar
えー、 Swift Sandbox 便利なのに・・・。
7:21 AM
Apple 公式で Swift のオンライン実行環境作って欲しい。
Avatar
wandbox使うと良いかも https://wandbox.org
Avatar
Swiftにもこれ欲しいですね〜〜 https://play.rust-lang.org/
Avatar
Try Kotlin right in the browser.
7:31 AM
↓に色んな言語のオンライン実行環境のリストが。 https://qiita.com/koher/items/e4835bd429b88809ab33
この数年で null 安全 [^99] は一気に浸透したように思います。ざっと思いつくだけでも、次のプログラミング言語で null 安全 が採用されました。 | 言語 | null 安全 に関する公式の記述 | ...
7:31 AM
golangなんかトップページw
Avatar
Ceylon https://try.ceylon-lang.org/ や Crystal https://play.crystal-lang.org/ ですらあるのに・・・。
Avatar
Self hosted and embeddable Swift Playground solution with a third-party module support baked in.
2:28 AM
公式ではないですが。
Avatar
omochimetaru 1/10/2018 2:29 AM
#swift でも出てましたね 助かる
👀 1
Avatar
@tarunon RxBlockingをproductionで使うのってどうおもう
Avatar
場合によっては必要でしょ
Avatar
全部リアクティブプロパティにしておいて局所的に同期的に取りたいならRxBlocking使えばええやんの思考になってるんだけどさ
Avatar
できるだけ使わなくて済むようにするけどどうしようもないこともある
Avatar
でもreadmeには本番で使うなよって書いてるしなーみたいな
Avatar
あー
9:01 AM
まあそういう場合はBehaviorRelayが適切かね
Avatar
使うのをためらう理由、readmeに使うなって書いてある〜以外ないんだけど
9:01 AM
BehaviorRelayってバージョンいくつから使えるんだっけ
Avatar
4かな
Avatar
omochimetaru 1/10/2018 9:01 AM
Rxとか関係なくって非同期処理を同期的に待つのはバッドプラクティスだと思うけど。
Avatar
それはそうだけど、同しようもない場合があるにはあって
Avatar
omochimetaru 1/10/2018 9:02 AM
その間メインスレッドがフリーズしてUIが固まっちゃうよ。
Avatar
でもデリゲートメソッドなどで同期的にreturnしないといけないとことかあるやん
9:02 AM
同期的に取れるはずのところで取れなかったらエラーで落ちていいとおもってる
Avatar
結局それNSRunLoop使ったりしてたことを考えるとうーんという
9:02 AM
インジケータくるくる回って操作できないのと画面フリーズは本質的には同じやし、そういう体験は極力なくしていくのがベネ
Avatar
omochimetaru 1/10/2018 9:02 AM
同期的に取れるはずのところで取れなかったらエラーで落ちていいとおもってる
ん?これは
9:02 AM
ちょっと話しの前提が違う気がする
9:03 AM
それだったら、常に 即座に正常系が進むか、 即座にエラークラッシュするかだから、OKだと思う。
Avatar
うん
Avatar
omochimetaru 1/10/2018 9:03 AM
ブロッキングしてない。
Avatar
IUOみたいなもんだと思ってる
9:03 AM
あー。
Avatar
うん、それはBehaviorRelayやね
Avatar
Observableから値を同期的に取り出す手段としてRxBlockingをプロダクションに導入することの是非、を聞きたかったのが最初。
Avatar
そもRelayじゃなくてSubjectでもいいけど
Avatar
値が無かったら待つのではなくて普通に落ちてほしい
Avatar
じゃあBlockingの出番はない
9:04 AM
でー、初期値なしだとBehaviorSubjectは取り回しが悪いので、ReplaySubject(1)がおすすめかな
Avatar
omochimetaru 1/10/2018 9:04 AM
ReactiveEmitter - Lightweight observable in Swift seen from EventEmitter in JavaScript.
Avatar
RxSwift4系全然キャッチアップできてないのでせねばな〜
Avatar
omochimetaru 1/10/2018 9:05 AM
型としてはTだけど read before write がクラッシュする。 IUO と同じやね。 (edited)
9:05 AM
RxSwiftには BehaviorRelayとBehaviorSubjectとReplaySubject(1) があるのか・・・
Avatar
初期値適当に入れるのは嘘だから避けたいよねという話、ありますあります
Avatar
できればsubjectでも無い方が嬉しいんだよな
Avatar
えっと
Avatar
onNext()を勝手に手で呼べないでほしい
Avatar
Subject(Errorある)とRelay(Errorない)があって
Avatar
そうすると、Signal です?
Avatar
SubjectはPublish, Behavior, Replayがある。RelayはReplay以外がある。
9:06 AM
そうするともう一個自分で型をラップして作るのが良いと思うよ
Avatar
自分で言っておいてなんですが、Signal だと利用範囲が少なすぎますね・・・
Avatar
SignalってRACのSignalですか?
9:07 AM
Rx4でそういうのがはいったのかな
Avatar
いえ、RxSwift の Signal です
Avatar
RxSwiftのSignalはReplay, Error無しのHot川 (edited)
Avatar
Replayナシだと同期的に取れないすな
Avatar
あと Driver と同じくメインスレッドです
Avatar
結局やりたいこと事態は安全なオレオレVariableを作りたいぜって話っぽくって
9:08 AM
そのためにBlocking注入は些か乱暴な気がするな
Avatar
なるほど、パッと聞くと BehaviorRelay ですけど、read only にしたいのであれば tarunon さんのおっしゃる通りラップするのが適当に思いますね
Avatar
あー
9:09 AM
もしかしてオペレーターで適当に加工した値も同期的に取りたい、とかそういう意図もあるのか?
Avatar
それはないな
9:10 AM
なんというか
Avatar
一応、DriverとBehaviorRelayを使って丁寧に組めば出来るね。
Avatar
ふむ
9:10 AM
いいからとりあえずRxSwiftを3から4に上げろという話だな
Avatar
それはそうやね
9:11 AM
てかそれSwift3やろw
9:11 AM
Swift4つかお?
Avatar
RxSwift3 でも Variable のラッパーでもいい気がするのですが、そうでもないです?
Avatar
omochimetaru 1/10/2018 9:12 AM
PublishSubject, BehaviorSubject, ReplaySubject, PublishRelay, BehaviorRelay Publish: onで入れるとすぐ流れる、現在値無し Behavior: .valueに入れるとすぐ流れる、現在値として1個残る、valueのgetterで同期的に取れる、初期値が必要 Replay: 内部的に現在値として1個残る、getterインターフェースは無い、初期値は不要 Subject: next | error | compl が流れる Relay: next しか流れない これであってる?
Avatar
Replay:  はキャッシュする最大数を初期値で与えることが出来る
Avatar
omochimetaru 1/10/2018 9:13 AM
で、BehaviorRelay だと良さそうだけど駄目なのは、
  • 初期値が必要だけど初期値を使っちゃうシナリオはバグにしたい
  • 型的に on による書き込み口も見えちゃう
9:13 AM
の2点が ひらりの不満点?
9:13 AM
ああ、ReplayのNはN=1のときだけ考えた。
Avatar
あいや
9:13 AM
そもBehaviorRelayはぼくまだそれがある世界に居ないので不満などは無感情
9:13 AM
onが見えるのは嫌
Avatar
omochimetaru 1/10/2018 9:14 AM
で、ヒラリが考えてるのは、 onが見えるのが嫌だから、Subjectの型じゃなくて、Observableで外に出したいけど、 そうするとgetterインターフェースも消えちゃうから、 見かけ上subscribeすることになってしまうが、 そのsubscribeの実態は即座に現在値を返す「はず」 をコードで表明したい
Avatar
あ〜〜〜、それは思ったことありますね
Avatar
omochimetaru 1/10/2018 9:14 AM
あってる? @hiragram
9:15 AM
BehaviorRelay が無い世界の目線も考慮するのややこしいぞ・・・
Avatar
即座に返すことをコードで表明したい、というよりはIUOっぽく扱いたいなーくらいのライトな願望
Avatar
omochimetaru 1/10/2018 9:16 AM
protocol ValueProducer { associatedtype Value var value: Value { get } } ↑これ自作してさ
9:16 AM
BehaviorRelayをextensionでconformanceさせて AnyValueProducer<T> で返せば?
9:16 AM
protocol ValueProducer : ObservableConvertible { associatedtype Value var value: Value { get } }
9:17 AM
こうかな。(ObservableConvertibleを足した)
Avatar
RxBlockingのほうがなんか乱暴というのはわかって、まあやろうとしてることは乱暴(ストリームから同期的にその瞬間値を得ようとしている)だから適切に乱暴に見えるRxBlockingでいいんじゃないかなーみたいな気分に一周回ってなってきた
Avatar
BehaviorRelayを使ってラップすると冗長なので、ラップするならBehaviorSubjectをラップしたほうが良いかな
Avatar
サーバーサイドSwiftのプロジェクトにはRxBlockingガンガン使いまくってて結構感触いいのでアプリ側もこれ入れちゃっていいんじゃねみたいなのが最初の発言のきっかけです
Avatar
omochimetaru 1/10/2018 9:20 AM
RxBlockingを入れちゃうと
9:20 AM
あれってextensionで同期的に現在値取るメソッドとか生やすよね
9:20 AM
同期的でない普通のストリームにうっかり使っちゃうバグを差し込む恐れが無い?
Avatar
Observable.just(1).toBlocking().first
9:20 AM
toBlockingで明示的に変換しないと同期的に取れない
9:21 AM
それもこみでうっかり使っちゃうバグはまああるかも
Avatar
omochimetaru 1/10/2018 9:21 AM
あ、あとさ、
Avatar
やったこと無いけどタイムアウト設定できた気がするので同期的に取れなかったらerrorにするみたいなことできるはずなんだよね
Avatar
omochimetaru 1/10/2018 9:21 AM
toBlockingの内部ってNSRunLoop回してくれんのかな
Avatar
というと?
Avatar
タイムアウトはある
Avatar
omochimetaru 1/10/2018 9:21 AM
接続されてるタスクがメインスレッドに投入する非同期処理の場合にデッドロックしそう (edited)
Avatar
ハマったこと無いから明確に調べたことなかったけどありそう
9:22 AM
ちゃんと読んでないけど名前見る感じ大丈夫ぽ
Avatar
omochimetaru 1/10/2018 9:22 AM
iOS/MacOSの裏技で同期待ちをRunLoop回しながらやるとそれが消化できるけどエグいスタックトレースになる技がある
Avatar
ポ〜
Avatar
omochimetaru 1/10/2018 9:23 AM
RunLoop回しながらタイムアウト付きか、なるほど・・・
9:23 AM
じゃあ今言ったパターンのデッドロックの心配は無さそう。
9:24 AM
それもこみでうっかり使っちゃうバグはまああるかも
型付けしておけば同期的に取れないものに使っちゃう恐れは無くせる。
Avatar
後続の処理はブロックするけどスレッド全体をブロックすることはないってことでおk?
Avatar
omochimetaru 1/10/2018 9:25 AM
根っこがBehaviorSubjectとかならその型情報がどんどん伝搬してくる感じ。 あ、でも、mapとかしてたら無理だな。
Avatar
そこは高階型がないからね
9:25 AM
高階型あってもできないわすまん
Avatar
確かあれって実行された時の RunLoop にしか作用しなかった気がします
Avatar
omochimetaru 1/10/2018 9:25 AM
mapしたところでObservableに降格しちゃう
9:25 AM
@Kuniwak 違うRunLoopはそもそも回り続けてるから大丈夫?
9:26 AM
RunLoop A から wait して A を回しながらもそのタスクが RunLoop B 上のタスクを同期的に待つ、
Avatar
だと思います。スレッドごとにRunLoopが一つあったと思うので、それのいずれかが止まるという認識でした。ただ、あの辺りまとまったドキュメントがなくてはっきりと断言できないです
Avatar
omochimetaru 1/10/2018 9:26 AM
みたいな相互同期のケースとかで死ぬのかもしれん
Avatar
Observableに降格しちゃうはそうで、なので型で縛るというよりは見た目も込みで乱暴なことをここでしているんだぞという主張をしてほしいのほうが願いとしては強いかも
Avatar
omochimetaru 1/10/2018 9:26 AM
スレッドごとにRunLoopが一つあったと思うので
そこはそうですね
Avatar
try!で落とすのかtry?でデフォルト値にフォールバックするのかはそのへんの局所の都合に任せたい感じ
Avatar
omochimetaru 1/10/2018 9:27 AM
Observableに降格しちゃうはそうで、
うーむまあそうだよねえ
Avatar
BehaviorRelayとか上手に駆使してスマートなコードに見えちゃうほうが困るかも
Avatar
omochimetaru 1/10/2018 9:28 AM
スマートというかシンプルに見えると思ったけど降格があるので駄目だな
Avatar
その辺り、SharingStrategy みたいに Observable と別物にするとなると実装範囲がやばくて死にますよね (edited)
Avatar
Operator全部自分で生やす事になる
Avatar
omochimetaru 1/10/2018 9:28 AM
そこは高階型がないからね 高階型あってもできないわすまん
高階型があれば map とかを自身の型を返すように定義して一発でいけんのか?
(edited)
Avatar
イケる気がしたけどBehaviorRelayはObserver側もあるので
9:29 AM
MapはContraMapとのセットでないといけなくなるから色々破綻する
Avatar
omochimetaru 1/10/2018 9:29 AM
あー、そういうあれか
9:30 AM
それについては同期的に返せる方の型にいったん変換しないと駄目かもね
9:32 AM
@tarunon SubjectとRelayで思ったんだけど
9:32 AM
その話って、Subject<T, Error> になってて、 Never が bottom type なら、 Relay は Subject<T, Never> で表せるっていう @inamiy さんが言ってるやつかな
👀 1
9:33 AM
で、 Observable<T, Error, Sync> で Sync = Async | Sync なら
Avatar
いや、RelayとSubjectはCompleteの有無でも性質が異なるので
Avatar
omochimetaru 1/10/2018 9:33 AM
いまいった、同期的に取れるか、っていう情報も型パラで統合できる?
9:33 AM
extenstion でSync == Sync なら .first が生えるようにする。 (edited)
9:34 AM
Completeの有無
じゃあそれも必要になるな
Avatar
そもそもそのレベルで性質が違うものを型パラに統合する事の意義は…という (edited)
Avatar
omochimetaru 1/10/2018 9:34 AM
それだけだと使いにくいけどデフォルト型パラが言語機能にあれば見た目は隠せるんよな
Avatar
あー
Avatar
omochimetaru 1/10/2018 9:35 AM
統合する事の意義
そうすれば 「実装範囲がやばくて死」を回避できる
Avatar
デフォルト型パラがあれば現実的な実装になるのかな
Avatar
omochimetaru 1/10/2018 9:35 AM
共通の部分は共通で、 map してても、「同期的に結果が取れる川」って性質は型パラで渡していける
Avatar
確かにそれあるとすごい嬉しいですね
Avatar
それが可能なら、そもそもSharedSequenceとObservableの統合も出来るんじゃないかしら
Avatar
だと思います
Avatar
omochimetaru 1/10/2018 9:36 AM
(まあ気持ちは懐疑的です・・・)
9:37 AM
Completableの有無はあれか、ストリームが有限である保証の有無って感じか。
9:37 AM
来ないやつは無限抽象。
Avatar
Completable まで型パラメータにすると、決定不能なパターンがある気がします
Avatar
それ昔考えたんだけど
Avatar
Not Completable から take すると Completable になるかどうか問題みたいなニュアンスです
Avatar
それはthrowsの有無、catchErrorで.errorを返したかどうかとか含め
Avatar
omochimetaru 1/10/2018 9:39 AM
RxSwiftってSingleもあるよね、1個なやつ、だからCompletableがあるかどうかというより個数に関する型パラになるのかな。
Avatar
色々発生するので全部カバーする必要があります
9:39 AM
Completable、Maybeもあるよ
Avatar
omochimetaru 1/10/2018 9:39 AM
SingleがfilterでMaybeになるのはビビった
Avatar
え❗
9:39 AM
そうなの
Avatar
賢いですね
Avatar
そりゃそうでしょ
Avatar
へー
Avatar
omochimetaru 1/10/2018 9:40 AM
1だからfilterすると1か0になる。
9:40 AM
オーバーロードしてあって、ファントムタイプで・・・
Avatar
その辺全部カバーして全てが型で保証されて
9:40 AM
まあその結果、コンパイル時間が莫大になるのは想像に難くない
Avatar
SingleをflatMapでCompletableにするみたいなのできないのはなんでなん
Avatar
出来ないんだっけ
Avatar
直接はできないはず
9:41 AM
SingleのflatMapはSingleを返さないといけなかった
Avatar
Maybe返したらMaybe、Completabale返したらCompletableになって良い気はするが
9:42 AM
議論あったっけ?この辺カバーしないといけない範囲が尋常じゃないので
9:42 AM
触られていない可能性もあるよ
Avatar
いつもSingleをasObservableしてflatmapの中でCompletableをasObservableしてその後ろでasCompletableしている
9:42 AM
無駄だな〜と思いながら
Avatar
omochimetaru 1/10/2018 9:43 AM
www
Avatar
いやてか
9:43 AM
Single→asObservable→flatMap to Never type→asCompletableでよくない
9:43 AM
flatMapの中にCompletableはいらなさそう
Avatar
あ、まあ
9:44 AM
completableはどっかから持ってきたりする。
Avatar
そういうことね
9:44 AM
議論はIssueにあるかもしれない。flatMapに関してはゆるい方向にいけるはずだから
9:44 AM
Single -> Single, Maybe, Completable Maybe -> Maybe, Completable Completable (flatMapはない) になると思う (edited)
Avatar
そうだね
Avatar
⚠️ If you don't have something to report in the following format, it will probably be easier and faster to ask in the slack channel first. ⚠⚠️ Please take you time to fill in the fields below. If...
Avatar
andThen使えって書いてありますね
Avatar
omochimetaru 1/10/2018 9:46 AM
これっぽい
Avatar
andThen❗
Avatar
それ、最終的にこのIssueになったはず。 https://github.com/ReactiveX/RxSwift/issues/1248 (edited)
Short description of the issue: Some transforming and combining operators needs to be added to PrimitiveSequence, and some should be removed because they have no effects on some traits, such as Fla...
9:49 AM
andThenは T が受けられないからちょっと違う?
Avatar
そうね
9:50 AM
単に順番に実行するだけならできるけど、上流のnextを引数にCompletableを作るみたいなのはflatMapでしかできなそう。
Avatar
頻出するならとりあえずオレオレFlatMap作ったほうが絶対いいよ
9:52 AM
こっちはこっちで議論しなきゃいけないにしても
Avatar
あれ結局まだないのかな。。。
Avatar
オレオレflatMap了解
Avatar
MaybeのFlatMapでSingle返したらMaybeになるはずだ(はずだ)
9:59 AM
じゃあ @hiragram 議論頑張って、Sinkから実装もチャレンジしてくださいb
10:00 AM
あでも実態は普通のflatMapだからSinkはいらないか
Avatar
すげえ締め方されてた
10:23 AM
Sinkわからないとなという気持ちはあったので宿題のつもりでやってみようかな
Avatar
@koher: もしかして Swift って HashDoS の脆弱性がある?
#if _runtime(_ObjC)でのStringhashValueはそもそも文字列全体を使わないはずです。
Avatar
norio_nomura 1/12/2018 1:47 AM
「使わないはずです」ではなく「使いません」だった。 import Foundation let first32Char = repeatElement("f", count: 32) let middle32Char = repeatElement("m", count: 32) let last32Char = repeatElement("l", count: 32) let a = (first32Char + ["ab"] + middle32Char + ["ab"] + last32Char).joined() let b = (first32Char + ["bc"] + middle32Char + ["bc"] + last32Char).joined() a == b // false // Foundation a.hash // -4528083392938427260 b.hash // -4528083392938427260 // Swift.Hashable a.hashValue // -8957072229412966235 b.hashValue // -8957072229412966235
Avatar
omochimetaru 1/12/2018 1:48 AM
ほえ〜〜〜〜
Avatar
norio_nomura 1/12/2018 1:49 AM
Linuxでもhashは同じ。
Avatar
omochimetaru 1/12/2018 1:49 AM
まあ確かにHashの要件自体は満たす・・・
Avatar
norio_nomura 1/12/2018 1:49 AM
そう。
Avatar
ムズムズするw
Avatar
omochimetaru 1/12/2018 1:49 AM
面白い・・・😟
Avatar
norio_nomura 1/12/2018 1:51 AM
SwiftLintでhashをファイル変更検知に使ってバグってたことがあった時に調べた。 https://github.com/realm/SwiftLint/issues/1184#issuecomment-274744331
We have just updated to 0.16 in our codebase and I'm working through the new rules. First up it's sorted_imports. For this, we have a build phase which runs ${PODS_ROOT}/SwiftLint/swiftlint as per ...
😰 1
Avatar
omochimetaru 1/12/2018 1:52 AM
なるほど・・・
1:52 AM
まあ全長で使っていたとしても、辞書のキーに使う事を想定したハッシュと、処理時間をかけてもよく散らばらせる暗号論的ハッシュ関数では、後者を使う方が設計上よろしいでしょうね
Avatar
enum HogeType: Int { case aaa = 1 case bbb case ccc } ↑ この書き方嫌いなんですけど、意外と賛同してくれる人少ないんだろうかと思ってるんですがどうですか enum HogeType: Int { case aaa = 1 case bbb = 2 case ccc = 3 } IntのrawValueつけるなら全case明示してほしい。
Avatar
omochimetaru 1/12/2018 7:04 AM
C++だと上の書き方よくやる
7:04 AM
Swiftでもできるの知らんかった。
Avatar
case並び替えとか発生したときにデータ壊したくないから全部書きたい
Avatar
そうそう
Avatar
欠番とかもあり得るし
Avatar
omochimetaru 1/12/2018 7:05 AM
整数値が外部APIにつながってるとそうだよね
Avatar
caseの定義順って普通のプロパティの定義順と同じくらいどうでもいいものだと思うんだよね
Avatar
omochimetaru 1/12/2018 7:05 AM
内部的な都合なら手書きだと重複する事故があるから自動列挙のほうがいい場合もありそう
Avatar
重複はコンパイルエラーにならなかったっけ?
Avatar
omochimetaru 1/12/2018 7:06 AM
Avatar
内部的なやつなら普通にswitchとかパターンマッチ使えばいいケースしか無い気がする
Avatar
omochimetaru 1/12/2018 7:06 AM
なるほど
Avatar
外に出すのに値が必要だからrawValueつける場合ばっかじゃないかな
Avatar
omochimetaru 1/12/2018 7:06 AM
そんな気も
Avatar
重複は Raw value for enum case is not unique というエラーが出た
Avatar
Raw value for enum case is not uniqueって出るからオッケー
7:07 AM
コンパイルエラー起こしたら始末書みたいなクソ現場じゃない限りは大丈夫ですね
Avatar
case一個消したらそれ以降全部ずれるし
Avatar
omochimetaru 1/12/2018 7:07 AM
コンパイラ偉いなあ
Avatar
話逸れますが、= hoge を省略した場合って non-frozen との整合性どうなるんでしょう
Avatar
同じ理由でenumのhashValueを使ってたらレビュー通さないとおもう
Avatar
omochimetaru 1/12/2018 7:09 AM
fragile enum周りのevolution全然追ってない
Avatar
おなじく
Avatar
SE-0192 シュッと見た感じ言及はなさそう…?
7:12 AM
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
Avatar
omochimetaru 1/12/2018 7:12 AM
jrose氏なのか
Avatar
読むと苦肉の策感高い Proposal です
Avatar
omochimetaru 1/12/2018 7:13 AM
めちゃくちゃながいw
7:14 AM
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
7:14 AM
レビュー入りしたほうだとexhaustiveっぽい
7:14 AM
Status: Active Review (December 19, 2017...January 3, 2018)
終わってた
Avatar
やはり言及がないですね… 😰
Avatar
class A { weak lazy var hoge: B? = nil } class B {} これなんか変なコンパイルエラーなった
5:09 PM
Playground execution failed: error: cannot convert return expression of type 'B?' to return type 'B?' error: cannot assign value of type 'B?' to type 'B??' error: cannot assign value of type 'B?' to type 'B??'
5:10 PM
lazy なくすとエラーなくなるんだけど、 lazy ってその変数の型には影響しないよね
Avatar
weak + lazy ? が参照持てないし使えないのかなと思ったり
5:12 PM
エラーメッセージ がよくわかりませんが。。
Avatar
lazyって参照持てないんだっけ
Avatar
いや、weak が です
Avatar
retain countは増えないけど、参照は参照ですよね
Avatar
ああ、言葉が悪かったです retain count が増えないのが問題なのかなと思いました ってうまく説明できそうな気がしたが感覚でしかわかってないな。。。
Avatar
lazyがあると cannot assign value of type 'B?' to type 'B??' で、lazyが無いとそのエラーが消えるということは、lazyのあるなしでそのプロパティの型が実は変わっているようなきがする
Avatar
コンパイル通したいってわけではなくて、 型がかわっているかどうか知りたいって感じか
Avatar
あいや普通にコンパイルは通って然るべきコードなのではと思っています
5:17 PM
weakとlazy、別に互いに干渉するようなものじゃないと思うんだけどな
Avatar
class A { weak lazy var hoge: B? = B() } class B {} でもこれはこれですぐ解放されるので あまり通って欲しくもない気がする
Avatar
それはコードがhogeが具体的にどのように与えられるかによるのでコンパイラの責務では無いような。
5:20 PM
そのコードも、僕が貼ったコードも型のルールの上でコンパイル通らない理屈は無いと思うんですよね
Avatar
class A { weak lazy var hoge: B = B() } class B {} nil になるならまだいいんですけど これだとなおわからない気がする
Avatar
weakはOptionalじゃないとダメですよ
Avatar
あ、確かに
Avatar
それは別にlazy関係ないはず
Avatar
ですね
Avatar
To demonstrate this problem, I made a vanilla Cocoa project. Here is the AppDelegate.swift: import Cocoa @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { weak lazy var
5:26 PM
SOあった。
Avatar
あれ、Swift4からって最後 nil になっちゃうんですね class A { lazy var hoge: B! = B() } class B {} let a = A() a.hoge a.hoge = nil a.hoge あー、じゃあ、僕の会話していた時の頭の中が古かった 前まではもう一度初期化されていたはずだから weak + lazy ??? ってなってました
Avatar
もう一度初期化ってどういうことですか
Avatar
Swift4 let a = A() a.hoge // B a.hoge = nil // nil a.hoge // nil Swift3 let a = A() a.hoge // B a.hoge = nil // nil a.hoge // B こういうこと
Avatar
nilの時アクセスしたらってこと?
Avatar
ですです
Avatar
えー
5:29 PM
Swift3そうだったっけ…。
Avatar
3.2でビルドするとなるかな。。。 3.1まではそう書いて動いていた気がするが
Avatar
3.2では最後の行はnilですね
Avatar
あれま
Avatar
lazyは最初にアクセスするまで初期化を遅延させるものなので値がnilかどうかなどは関係ないような
5:33 PM
もやもやするので3.1以前で確認してもらいたいですね
5:35 PM
3.1ってXcodeいくつが必要なんだっけ…
Avatar
これだから正解ってわけじゃないんですが https://image.slidesharecdn.com/cocoakansailazyvar-160404013001/95/lazy-var-cocoakansai-cswift-57-638.jpg?cb=1459743921 熊谷さんが試してくれていた
Avatar
これいつの資料だろ。
Avatar
が、結構前だな 2016/4
Avatar
Swift3からIUOの扱いが変わったのでそれまではそんな動きしてたのかなあ
5:37 PM
2 系かな?
Avatar
この時はそうですね まあ 3.1 かどうかは置いておいてこういう時代があったんですよね
lazyは最初にアクセスするまで初期化を遅延させるものなので値がnilかどうかなどは関係ないような
これはそうあって欲しくて、今の仕様の方がわかりやすいですね
(edited)
Avatar
召喚された
Avatar
まってたぜ
Avatar
weakとlazy組み合わせた場合かー
5:40 PM
bug report はあった
5:41 PM
Resolved
Avatar
@tarunon lazyのあるなしでエラーメッセージによるとhogeが B?? と解釈されてるかどうかが変わっているきがするんだけどどう
5:42 PM
そもエラーがどのファイルのどの行って示せていないので、なんかがおかしいのは確定だと思うんだけどな
5:44 PM
class A { weak lazy var hoge: B? = { return B??.none }() } class B {}
5:44 PM
Playground execution failed: error: cannot convert return expression of type 'B?' to return type 'B?' error: MyPlayground.playground:4:30: error: cannot convert value of type 'B??' to specified type 'B?' weak lazy var hoge: B? = { ^ error: cannot assign value of type 'B?' to type 'B??' error: cannot assign value of type 'B?' to type 'B??'
5:44 PM
もっとポンコツっぽくなった
Avatar
いやそれは、B??はB?には変換できないでしょ
Avatar
エラーメッセージおかしくね
Avatar
行数指定されてるエラーはまとも、それ以外は前と一緒かな
Avatar
結局内部的(?)にはhogeはB?なのかB??なのかどっちになってるんだろう
Avatar
ひらり的には何がやりたいの
5:46 PM
1. これを使って解決したい問題があった 2. 興味本位
Avatar
さいしょ1だったけどいま2
5:48 PM
factory initをこのまえ知って使ってみたくなって、「ViewModelを返すクロージャを引数に受けるViewControllerのイニシャライザ」を作ったんだけど
5:49 PM
let articlesVC = ArticlesViewController.init { return ArticlesViewModel.init(dataProvider: ArticlesAPIDataProvider.init()) } 本番のコードなんで文脈なくてすまんやけど
Avatar
lazyは内部的にOptionalを使っているコンピューテッドプロパティであると解釈するなら、
5:49 PM
weakと組み合わせたときにぶっ壊れてそれがチラ見できるようになったということかもしれないね
Avatar
VMのイニシャライザにVCを渡したくなったけど循環を回避するためにweakにして、更にarticlesVCの初期化処理の中でarticlesVCを使えないのでlazyにして初期値を uninitialized() にすればいけんちゃうみたいな
5:50 PM
uninitialized() は中身fatalErrorの func uninitialized<T>() -> T
Avatar
うーん
5:51 PM
weakにした時点でOptionalなんだから初期値nilでよくって
5:51 PM
lazyを使う必要がなくならないか?
Avatar
vcの参照は必須にしたいんよね
Avatar
じゃあIUOで
Avatar
get before set は落としたい
5:51 PM
やっぱそうなるよね〜〜〜〜〜〜〜
Avatar
あとはー、そうだねぇ
Avatar
何かIUO使わなくていいなら使いたくないので、lazyで行けるっしょと思ったら行けなくて悲しかったってかんじ
Avatar
class VC {} class VM { private weak var _vc: VC? = nil var vc: VC { get { return _vc ?? undefined() } set { _vc = vc } } }
5:53 PM
ほれ
5:53 PM
これでもIUO無しでやりたいことはできるゾイ (edited)
Avatar
別の変数に置いとけばまあ、ってかんじか
5:54 PM
まあ ってかんじだな
Avatar
自前Lazy
5:54 PM
これを表現するLazyWeak型を作ればスッとできないかな
Avatar
ぱっとみ大仰なのでIUOのほうがやりたいことがわかって良いかもしれない
5:54 PM
おっLazyWeak
Avatar
class LazyWeak<T> { private weak var _value: T? = nil private func undefined() -> T { fatalError() } var value: T { get { return _value ?? undefined() } set { _value = value } } } class VM { var vc = LazyWeak<VC>() } こういうイメッジ
5:56 PM
使いやすいかはしらん
Avatar
クラッシュするのはweakってよりunownedっぽいね
Avatar
unownedならそもlazy使えるんじゃね
5:58 PM
unownedってプロパティに使えたっけ
5:58 PM
オッダメだw
5:58 PM
同じErrorすね
Avatar
class A { unowned lazy var hoge: B = B() } class B {}
5:59 PM
Playground execution failed: error: cannot convert return expression of type 'B' to return type 'B' error: MyPlayground.playground:4:32: error: cannot convert value of type 'B' to specified type 'B' unowned lazy var hoge: B = B() ^~~ error: cannot assign value of type 'B' to type 'B?' error: cannot assign value of type 'B' to type 'B?'
5:59 PM
hoge: B! だとなんか違う怒られする
Avatar
それはそもそもクラスじゃなくなるから
Avatar
あ、そか
6:00 PM
なる
Avatar
unownedはクラス型、weakはOptional<クラス>
Avatar
unownedはIUOじゃないの
6:00 PM
クラス!にならん?
Avatar
ならんくね?
Avatar
アレ?
Avatar
アクセス失敗後の世界は無いはずなのだからIUOになる意味がないと思う
Avatar
それってSwiftのエラー的には何になるん
6:03 PM
unownedあんまり意識してつかったことないからてっきりweakはOptionalでunownedはIUOになるもんかと思ってたけど
Avatar
SIGABRT (edited)
Avatar
うわー
6:04 PM
ホントだ
6:04 PM
型そのまんまだ
6:05 PM
class A { var block: (() -> ()) = {} func hoge(block: @escaping (() -> ())) { self.block = block block() } } class VC { func viewDidLoad() { let a = A.init() a.hoge { [unowned self] in print(self) } } } VC.init().viewDidLoad()
6:05 PM
__lldb_expr_98.VC
6:05 PM
↑printの結果
6:06 PM
weakだとOptional<~~~~>になる
Avatar
ケース的には、weak + IUOがベター、IUOがどうしても嫌ならLazyUnowned型作るのが良いと思った
6:07 PM
(もっと個人的な思想の話をするとVCとVMの循環参照そのものをやめたほうが良い気がするけど)
Avatar
その思想はわいもそうなんだけど
6:08 PM
UITableViewCellに乗っけてるAdmobのバナーViewがUIViewControllerのインスタンスを要求してきて、そのセルはVMのRxDataSourcesで作られているみたいなアレで仕方ないかなあみたいな
6:08 PM
アレです
Avatar
Cellに渡すデータだけをViewModelで作るようにしたら
6:09 PM
あー
Avatar
セルに渡すデータにVCも含まれているのよ
Avatar
configureCellの在処
Avatar
configureCellの実態どこにおいてる?
Avatar
個人だと例のごとく丸っとアレだけど
Avatar
どっかのバージョンからdataSourceのイニシャライザに渡すようになってからふ〜んこいつはVMに置くべきなんやなあとおもってVMに書いてるけど
6:10 PM
使ってないんだっけお兄さん
Avatar
型合わせゲーム解決したらセルが生えてくる例のアレだす
Avatar
でた
6:11 PM
全然覚えてないけど
Avatar
Admobうんこやん、そいつTableViewの外に置けないの?
Avatar
多分VCの一番下端に貼っつけるのが想定ユースケースなんだろうなってのはドキュメントからすごい伝わってきた
6:12 PM
けどそれ嫌いなのでテーブルの中に紛れさせたい
Avatar
スクロールしたら怒られると思うよ
Avatar
怒られるのかなあ
6:12 PM
うげー
Avatar
ガイドラインにスクロールで領域外に隠すな💢みたいなのは見た記憶がある
6:13 PM
えっとね
6:13 PM
AdViewController作ってそれはコンテナVCにして、Childに綺麗な世界を作ることを強くおすすめします
6:14 PM
広告sdkは大体良くないからね、世界を分けよう
Avatar
他の画面はもうそうなってんのよね
6:14 PM
うぐー
Avatar
omochimetaru 1/12/2018 6:14 PM
おきた
Avatar
おは
Avatar
なんかTableに混ぜる系の広告sdkはそれ専用のapi群があって(使い勝手がよいわけではない)みたいなイメッジ
Avatar
omochimetaru 1/12/2018 6:15 PM
lazyってSILレベルでは存在しない気がする
6:16 PM
computed propの実装になってそう
Avatar
広告導入して循環参照追加することになりましたとか、敗北もいいところなのでsdkを床に叩きつけたいなw
6:16 PM
決闘だ
Avatar
omochimetaru 1/12/2018 6:16 PM
そこで一回りオプショナルがつくのと
6:16 PM
weakの辻褄合わせにバグがあるのかと
Avatar
ネイティブ広告出せるイマドキインターフェースもってる広告SDKおしえて
Avatar
ダヨネ
6:17 PM
そんなものは…
6:17 PM
広告sdkは残念ながら
Avatar
とりあえずFirebaseで計測できるってからAdmob入れてるけど
Avatar
広告sdkは、「兎に角仕様を変更しない」がKPIのひとつになるので、今時インターフェースってのは難しいと思う (edited)
Avatar
かなしい
Avatar
例の Delegate でゴニョゴニョ実験していたやつの結果が出ました: https://github.com/Kuniwak/DelegateKit
DelegateKit - Operators and Utilities for Delegates
👏 1
4:04 AM
まず、Delegate を protocol SomethingDelegate: class {} という形式で宣言できなくなりました。いちいち Type Erasure 書くのを避けるための苦渋の選択ですが、最悪です
DelegateKit - Operators and Utilities for Delegates
Avatar
omochimetaru 1/15/2018 1:37 AM
Delegateのオブジェクトへの弱参照+呼び出されるメソッド群 っていう構造を、associted valueのあるenumとしてまとめて一つの型にして、デリゲートの通知を直接のオブジェクトとして取り扱うってアイデアは良さそうですね RxCocoaでUIButtonとかに .rx が 生えてるやつでできることを、それ単体だけ Rx 全部を導入しないで採用できないか、ってのがコアアイデアですかね?
Avatar
RxCocoaでUIButtonとかに .rx が 生えてるやつでできることを、それ単体だけ Rx 全部を導入しないで採用できないか、ってのがコアアイデアですかね?
はい、それを狙っています。
1:55 AM
Rx の中でも一番有望だと思っていたのは throttle/debounce ですね。Delegate でも使いたいシーンは結構あるので…
Avatar
AnyDelegate無しでなんとかならないかな
Avatar
これ誕生の経緯が結構あるので説明長くなるんですよね。。。
4:50 AM
class DelegateHolder { weak var delegate: SomethingDelegate? } let holder = DelegateHolder() // これは弱参照で持ってほしい。 holder.delegate = SomethingDelegateImpl() // これは強参照で持ってほしい。なぜなら、これを弱参照にすると map の戻り値の参照を誰も保持してないのですぐに回収されてしまうから。 holder.delegate = SomethingDelegateImpl() .map { a in a * 2 } // この差異を吸収するために、weak と strong の両方を持てるインターフェースを持つ必要があった。これを実現しているのが AnyDelegate。
Avatar
Rxだとその辺はDisposeBag側から参照持つ形で解決してますね。
Avatar
その方法も検討したのですが、これを導入すると Delegate の頃にはなかった subscription の概念が入ってしまうので避けたという経緯があります
5:05 AM
UIKit などの Delegate のように、subscription は delegate プロパティへの代入で実現されるのを目指した形になりますね。その辺りは実装者の好みも入っています(weak が書けなくなるか、subscription を入れるかの二択のうち、前者を選択したので)。
Avatar
ふむ
Avatar
omochimetaru 1/16/2018 8:01 AM
雑なエラー型ってどうしてます?絵文字投票可能にして聞いてみる。
  • 1⃣ GenericError みたいな型を定義する
  • 2⃣ Error を定義する。言語仕様の方のやつと衝突しちゃうのでそっちを使う時は Swift.Error と完全名で記述する
  • 3⃣ NSError を使う
  • 4⃣ 絶対に雑なエラー型は作らない(ライブラリやそのクラスや関数に起因したエラー型を定義する)
  • 5⃣ その他
(edited)
1⃣ 5
4⃣ 3
2⃣ 1
8:02 AM
僕はもともと[1]だけど微妙に思えてきて[2]に乗り換えたけどこれも面倒になってきて[3]を検討しているところ (edited)
Avatar
雑なError is
Avatar
omochimetaru 1/16/2018 8:03 AM
とりあえずエラーメッセージをthrowしたくてとりあえずそれ以上詳細なパラメータはcatch側で必要ないようなやつ。
Avatar
オッ
Avatar
Kishikawa Katsumi 1/16/2018 8:03 AM
ライブラリ名Errorみたいなやつですよね。
Avatar
その他かな
8:04 AM
雑なエラーが発生するクラス.Errorを作る
Avatar
Kishikawa Katsumi 1/16/2018 8:04 AM
CarthageErrorみたいな
Avatar
omochimetaru 1/16/2018 8:04 AM
じゃあ[4]?
Avatar
4かこれw
Avatar
omochimetaru 1/16/2018 8:04 AM
CarthageError は [1] かな〜
Avatar
なんだろう
Avatar
omochimetaru 1/16/2018 8:04 AM
Carthage 自体がパッケージを作ると考えて Carthage.Error としていてパッケージの中では Error なのであれば [2]
8:05 AM
@tarunon そうするといろんなクラスでその Class.Error 実装するのがめんどくさい コンストラクタ書いて :CustomStringConvertibleかいてdescripton書いて・・・
Avatar
protocol DescribedError: Error, CustomStringConvertible { }
8:05 AM
こういうの用意してそれでマッチするようにしてる
Avatar
omochimetaru 1/16/2018 8:05 AM
なるほど。
8:06 AM
それって typealias DescribedError = Error & CustomStringConvertible とかでもいいのかな。
Avatar
ライブラリ外に投げる場合は雑なエラーではなく、ライブラリ.Errorなかなり具体性を持たせてラップして投げる必要があると思う
8:06 AM
asキャスト使えるっけ?
Avatar
omochimetaru 1/16/2018 8:06 AM
無理だね nominal でないから
Avatar
じゃあダメだ
Avatar
omochimetaru 1/16/2018 8:07 AM
(すごい勢いで流れていってアンケートが死んだw
Avatar
使う時に enum Error: DescribedErrorって書きたいから
Avatar
omochimetaru 1/16/2018 8:10 AM
extension String : Error {} func a() throws { throw "error message" } do { try a() } catch let e { print(e) // "error message\n" }
Avatar
それはやばい
Avatar
omochimetaru 1/16/2018 8:10 AM
これできるのか・・・😅
Avatar
最悪でもRawRepresentableにしよう!
Avatar
omochimetaru 1/16/2018 8:11 AM
悪魔召喚感
Avatar
使ってるの見たら 👮 する
Avatar
guard句に引っかかってelseの中を通って処理が終了したときになんかそれに気づける&&どこのguardで引っかかったかprintしてくれたりしたらうれしいなーみたいなことを思ったんですが
3:24 AM
それはコンパイラに手を入れるしか無い?
Avatar
omochimetaru 1/18/2018 3:25 AM
print書けばいい・・・?
Avatar
全部のguardに書くの現実的ではない
Avatar
omochimetaru 1/18/2018 3:26 AM
全部のguardでそれやるのそもそも微妙じゃない?
3:26 AM
必ずしもエラーケースとは限らないじゃん、正しく脱出することもあるから
3:26 AM
拾いたくない普通にたくさんおきるguardでログが膨大に発生してしまう
Avatar
コンパイラのオプションかなんかでそのへんオンオフできたらいいなって
Avatar
omochimetaru 1/18/2018 3:28 AM
自分の場合はブレークポイント貼ってだいたい解決してるなあ
3:28 AM
似たような話で
3:28 AM
guardの中でも特に異常系での脱出は
3:28 AM
throw してるので
3:28 AM
throw全部でブレークする設定ができるから
3:28 AM
俺の場合はそれで拾えてる
3:29 AM
それで駄目なケースはguardの中で、returnで脱出するケースだね
Avatar
そういうコードがいっぱいある
Avatar
omochimetaru 1/18/2018 3:29 AM
それって普通のif文のフローも全部トレースしたいって言ってるのと同じ気がするけど・・・
3:30 AM
それはコンパイラに手を入れるしか無い?
コンパイラに手を入れるアプローチだったら
3:30 AM
guard文をSILに変換する時に
3:31 AM
else本文の先頭の生成部で print を生成すればできそう
3:31 AM
SwiftSyntaxが完成すれば、AST変換で実装するのもできそう
Avatar
guardでの異常脱出はthrowで、って結構目からウロコだったんだけどthrowsばっかになって辛いみたいなことないんすかね
Avatar
omochimetaru 1/18/2018 3:32 AM
guard文の句構造は (guard キーワード、評価式部分、 elseキーワード、LBrace、制御部、RBrace)だから、制御部にprint文を注入するだけかな
3:32 AM
それが異常ならthrowsで表現しといた方がうまくいくと思う
3:33 AM
returnの場合は void関数で処理をスキップした場合と、 型があってデフォルト値に畳み込んだ場合だよね
Avatar
うん
3:34 AM
throwするようにしてわかりやすくしても結局try?で握りつぶされまくる未来が見えるな
Avatar
omochimetaru 1/18/2018 3:34 AM
それらのケースは仕事を呼び出し側に押し付けてるだけだからあんまり意味が無い
3:34 AM
意図を表現するために skip 関数と makeDefault 関数 みたいなのを作っておいて、それを使ってコーディングするようにしておいて
3:35 AM
skip関数とmakeDefault関数の中でprintするように書き換えれば
3:35 AM
Swiftだけでその目的果たせそう
3:35 AM
一般の return を全部捕まえるのは既存の方法では無理だと思う
Avatar
まあ新しくguardを書くときはそうなのかもしれん
Avatar
omochimetaru 1/18/2018 3:36 AM
SwiftSyntaxでコード変換するのが良いんじゃないかなあ
3:36 AM
現バージョンならguard文とかもいけるんじゃねえか 知らんけど
3:37 AM
それだったら Swiftソースから Swiftソースへの加工だから
3:37 AM
で、加工処理自体もSwiftで書けるから
3:37 AM
ハードルは低いと思う
Avatar
今はもうそこそこそ大きくなってしまったコードベースの中でデータ不整合チックなことを検出するguardでお手軽returnしてなにもしないみたいな感じになっておりデバッグが大変つらいのでguardに引っかかりましたよ一覧のログがごっそりあってそこでおかしなのを探すみたいなアプローチができたら嬉しいのかなというアレでした
3:37 AM
SwiftSyntaxしらべてみるか
Avatar
omochimetaru 1/18/2018 3:38 AM
try! Swift is an immersive community gathering about Swift Language Best Practices, Application Development in Swift, Server-Side Swift, Open Source Swift, and the Swift Community taking place around the world in Tokyo, New York, and Bangalore.
3:38 AM
トライスイフトで岸川さんが教えてくれるよ
Avatar
わいやったらこの不整合preconditionFailureで落とすぞみたいなのもしれっとreturnして何事もなかったかのようにアプリは生き続けて不具合のきっかけがどこかわからんみたいなのがある
😫 1
3:38 AM
期待
Avatar
omochimetaru 1/18/2018 3:38 AM
いつのまにか普通に import SwiftSyntax できるよになってたしハードル下がってきた (edited)
Avatar
Kishikawa Katsumi 1/18/2018 3:39 AM
まあguard節のことは全然考えてなかったけど、そういうアスペクト指向みたいなものを実現するようなものを考えてます。
Avatar
omochimetaru 1/18/2018 3:39 AM
わいやったらこの不整合preconditionFailureで落とすぞみたいなのもしれっとreturnして何事もなかったかのようにアプリは生き続けて不具合のきっかけがどこかわからんみたいなのがある
例外握りつぶしてて異常系のトレーサビリティーが死んでるやつだ
Avatar
そう
Avatar
omochimetaru 1/18/2018 3:40 AM
そういうのはやっぱコード変換が良さそうだなあ
3:40 AM
腐ってるソースファイル全部をバコッと変換して
3:40 AM
実行すればいろいろわかる、みたいな。
3:41 AM
コンパイラでやっちゃうと、正しくguardを使ってる場所も余計に捕まえちゃうから
3:41 AM
そのフックをかける範囲をいろいろコントロールできたほうがデバッグしやすいから
Avatar
null safety や検査例外は本来いいものだけど、握りつぶすと最悪なことになる・・・。
Avatar
guard return警察するしか
4:04 AM
地に足をつけて生きていくしかないのだ
Avatar
omochimetaru 1/18/2018 4:04 AM
ヒラリが言ってるのは既存コードだから
Avatar
既存コードに警察権を行使しよう
4:05 AM
つまりPRだな
Avatar
omochimetaru 1/18/2018 4:05 AM
その作業めっちゃ時間かかるじゃんw
Avatar
やらないならやらないでそれは未来に問題を先送りしてるだけだから
Avatar
omochimetaru 1/18/2018 4:05 AM
その時間を省略してとりあえず今でてるバグをつぶしたいという話でしょ
Avatar
どこかで解決しないと
Avatar
Kishikawa さんが SwiftSyntax やめて -dump-ast ににしてしまったので、チーム一同悲しんでおります 😇
😢 1
Avatar
Kishikawa Katsumi 1/18/2018 4:11 AM
PowerAssertには型の情報が必要なんですよね😥
Avatar
ですよねー。まあ SwiftSyntax はまだ早いというのは分かります。
Avatar
Kishikawa Katsumi 1/18/2018 4:13 AM
だいぶ色々なコードが動くようになったので、デモサイトを作りました。
👀 2
Avatar
omochimetaru 1/18/2018 4:14 AM
XCTAssert(max(a, b) == c) | | | | | 7 4 7 | 12 false XCTAssert(a + b > c) | | | | | 4 | 7 | 12 11 false XCTAssert(john.isTeenager) | | | false Person(name: "John", age: 42) XCTAssert(mike.isTeenager && john.age < mike.age) | | | | | | | | | false | | 42 | | 13 | | | | Person(name: "Mike", age: 13) | | | false | | Person(name: "John", age: 42) | false Person(name: "Mike", age: 13)
4:14 AM
お〜〜〜
Avatar
すごい・・・
Avatar
Kishikawa Katsumi 1/18/2018 4:15 AM
仕組みはすぐできたんだけど明け方からずっとSSLにしたくてがんばってたけどなんか無理だった。
4:17 AM
実際のCLIの方は
Avatar
これってこの前のオンライン Playground ですよね?
Avatar
Kishikawa Katsumi 1/18/2018 4:17 AM
swift-power-assert xctest -Xxcodebuild test -workspace <workspacename> -scheme <schemeName> -sdk iphonesimulator -destination "name=iPhone X,OS=11.2"
4:18 AM
こんな感じでxcodebuildやswift testの前にコマンドを足したらいい感じにラップするようになってます。
4:18 AM
@koher そうです。
Avatar
EC2 か何かの上で動かしてるんですか?
Avatar
Kishikawa Katsumi 1/18/2018 4:19 AM
DigitalOceanの一番安いやつです。
👀 2
4:20 AM
とりあえず、動かす所まで試そうと思って昨日やってました。
Avatar
↓で Swift Sandbox を当てにしてたので悲しいことになってしまい、自分で環境作ろうかと思ってたところです😭 https://github.com/swift-quest/swift-quest/blob/master/print-and-arithmetic/first-step.md
Contribute to swift-quest development by creating an account on GitHub.
Avatar
Kishikawa Katsumi 1/18/2018 4:22 AM
OnlineSwiftPlaygroundは入出力を生のテキストを簡単なJSONでラップしてやりとりしていて、基本的にそのままswiftcに渡してるだけですね。
Avatar
sandbox 化とか、リソースの分離とかしてくれるんでしょうか?
Avatar
Kishikawa Katsumi 1/18/2018 4:23 AM
Macで実行する場合は標準のサンドボックス機構を使うように書かれてるけどLinuxホストの場合は何もなし。
Avatar
なるほど・・・
Avatar
Kishikawa Katsumi 1/18/2018 4:23 AM
なので、コマンドインジェクションがたぶん可能。
4:23 AM
そこはDockerで実行するとかでいいんじゃないかと。
Avatar
そこまでするなら OnlineSwiftPlayground じゃなくてもいい気がしますねぇ・・・。
Avatar
Kishikawa Katsumi 1/18/2018 4:26 AM
DockerfileもあるんでDocker build & runが一番簡単ですよ。
Avatar
そうなんですね。
Avatar
omochimetaru 1/18/2018 4:27 AM
DockerにすればSwiftのバージョン切り替えとかも実現しやすそうですね
Avatar
Kishikawa Katsumi 1/18/2018 4:27 AM
まあ仕組みは超簡単なのでフロントエンドが好きなら全然自分でも作れる。 (edited)
4:28 AM
これに乗っかると、NodeやSwiftを修正して、docker build & runて感じだから、最初試すぶんには良いと思います。
Avatar
なるほど。ありがとうございます。
Avatar
Kishikawa Katsumi 1/21/2018 12:25 AM
https://swift-power-assert.kishikawakatsumi.com/ 細かいところが気になったので作り直した。Nodeを使ったのでPure Swiftじゃなくなってしまった。
12:25 AM
SSLにもした。
12:28 AM
作ってみると、意外にオンラインのREPLをSwiftで作るのは難しくないということと、IBMの以外にもSwiftのREPLを提供しているところは結構あるんだなということがわかりました。
12:29 AM
👌 1
Avatar
ワンドボックスすき
Avatar
Kishikawa Katsumi 1/21/2018 12:58 AM
Swiftがあるとは全く思ってなかった。LLVMファミリだからだろうか。
1:03 AM
Dockerがあるからマルチプラットフォームで動かすことは全然大変じゃないけど、MacとLinuxで同じコードではダメなことが結構あるのが大変ですね。
Avatar
omochimetaru 1/25/2018 4:33 AM
You and I both want to be able to use fixed key sets, and you and I both think arbitrary string literals should be supported too. So please consider taking my position on this proposal—that it should be accepted in its current form and that we should later extend the feature to support fixed key sets in addition to ExpressibleByStringLiteral types. I really think SE-0195 could be an important step towards our goal.
4:33 AM
クリスラトナー、 Chris_Lattner3 とかいう、めっちゃアカウント生成トラブった感じの名前になってるけどw
Avatar
Kishikawa Katsumi 1/25/2018 4:34 AM
先に誰かが取っちゃったとかでもなさそうですね。
Avatar
多分、apple.com nondot.org google.com の3アカウントあるのだと思います。
Avatar
norio_nomura 1/25/2018 4:35 AM
複数のメールアドレスでMLに投稿してそれらにユーザー名が自動生成されて、最初の投稿のメールアドレスを使えなくて変えられないのでは。 (edited)
Avatar
omochimetaru 1/25/2018 4:36 AM
このアドレスは404なんだなあ。 https://forums.swift.org/u/Chris_Lattner2/summary
Avatar
norio_nomura 1/25/2018 4:40 AM
アクティベートしないとユーザーページは現れないとか?
Avatar
omochimetaru 1/25/2018 4:41 AM
「取ってあるけどまだ見えない」はありそうですね。
4:41 AM
>複数のメールアドレスでMLに投稿してそれらにユーザー名が自動生成されて、最初の投稿のメールアドレスを使えなくて変えられないのでは。 ああなるほど
Avatar
おお、これ Proposal 化されてレビュー入りしてたのか。 Swift で機械学習できるようになるの楽しみだ。 https://github.com/apple/swift-evolution/blob/master/proposals/0195-dynamic-member-lookup.md (edited)
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
Avatar
omochimetaru 1/25/2018 4:42 AM
はい、いまレビュー期間ですね
Avatar
まあ、この Proposal だけじゃ Python 連携までは長い道のりなのか?
Avatar
omochimetaru 1/25/2018 4:44 AM
とりあえずこれだけあれば、あとはライブラリで結構いけるんじゃないですか?
Avatar
Python.framework 使ってた気がするけど、それが Python 2 じゃないかという心配も・・・。
Avatar
omochimetaru 1/25/2018 4:45 AM
Python3.frameworkってないのかな?
4:46 AM
importでどっちも使えそう。
Avatar
omochimetaru 1/25/2018 4:46 AM
そうですね、そっちがない間は関数呼び出しのところは冗長。
Avatar
norio_nomura 1/25/2018 2:09 PM
Release_Notes_for_Xcode_9.3_beta.pdf より ## Known Issues in Xcode 9.3 beta ### Swift Compiler - Conditional conformances are unsupported when performing a dynamic cast (with is or as). これってSwift 4.1リリースでも直らないんだよね? (edited)
Avatar
CondconfはExistentialにcastできない?
Avatar
それを理由に最初フラグ指定しないと使えやいようにしてましたね(今ではフラグなしで使えるようになったけど。
Avatar
norio_nomura 1/25/2018 2:13 PM
exampleを引用 protocol P { } extension Int: P { } // Fully supported: Set unconditionally conforms to P extension Set: P { } // Not supported in dynamic casts: Array conforms to P // only when its element conforms to P extension Array: P where Element: P { } func castToP(_ value: Any) { if value is P { print("\(type(of: value)) conforms to P"); } else { print("\(type(of: value)) does not conform to P") } } castToP(Set([1, 2, 3])) // unconditional conformances // are supported: // prints "Set<Int> conforms to P castToP([1, 2, 3]) // unsupported conditional conformance: // incorrectly prints "Array<Int> does not // conform to P" castToP([3.141593, 2.71828]) // unsupported conditional conformance: // correctly prints "Array<Double> does not // conform to P" (edited)
Avatar
さすがに4.1では無理そう
Avatar
norio_nomura 1/25/2018 2:18 PM
コードによっては、Conditional Conformanceを使った型を食わせるテストが必要になりそう。
Avatar
norio_nomura 1/27/2018 3:04 AM
flatMapのdeprecationはSwift 4.1とSwift 3.3両方だから、4.0.xと3.2.x互換を維持する場合のcompactMap定義は #if (!swift(>=4.1) && swift(>=4.0)) || !swift(>=3.3) extension Array { public func compactMap(_ transform: (Element) throws -> String?) rethrows -> [String] { return try flatMap(transform) } } … みたいに書く必要があるのか。 (edited)
😵 1
Avatar
version という comparable なものを使っているのに、 3 系と 4 系で独立して deprecated とか微妙ですね☹ それならグラフ構造で表さないと・・・。
Avatar
norio_nomura 1/27/2018 1:21 PM
ちょっと修正、#if (!swift(>=4.1) && swift(>=4.0)) || !swift(>=3.3)だった。
Avatar
public protocol Po { func doHoge() } extension Po { public static func getDefaultInstance() -> Po { return DefaultPo() } } internal class DefaultPo: Po { func doHoge() {} } // let po = Po.getDefaultInstance() <- Compile error let po = DefaultPo.getDefaultInstance() なのに今さら気づいた… Protocol は適合する対象であって型としては存在はしないんだなぁというのを実感した
Avatar
それもそうだし、Genericsで<X: Po>ってやってXにPoを入れようとすると実感できるぞ
Avatar
なんかそこもスッとつながって、型としての実体がないから func hoge(po: Po) // dame func hoge<X: Po>(po: X) // OK なのも実感として納得がいった (edited)
Avatar
Bugs覗くと兄貴達がGenericsのそれにキレてるのをよく見る
10:25 AM
<X: class>で死ぬのが一番多くてな
Avatar
いやでもこれ Protocol の実在性について納得するとすごく自然に感じるし、むしろ
Avatar
故にErasure作ろうね!っていう話を
10:27 AM
するんだな
Avatar
あー、<HogeProtocol: class> してしまうのはありそう
Avatar
AnyClassValueっていうオレオレType-erasureを作って解決するのが、一番賢いと思うのだけど
10:27 AM
中々ね
😭 1
Avatar
omochimetaru 1/30/2018 4:41 AM
Swiftでスクリプティングをするための基盤環境ツール、こんなのあるんですね。 https://github.com/JohnSundell/Marathon https://github.com/yonaskolb/mint
Marathon makes it easy to write, run and manage your Swift scripts 🏃
Mint - A package manager that installs and runs Swift command line tools
4:42 AM
ついでに、定義ファイルをSwiftで書くmakeとかもあった。名前が酒で良い。 https://github.com/xcodeswift/sake
sake - A make-like build utility for Swift.
Avatar
assertpreconditionにクロージャ渡せたらループチェックとかかきやすくて良いんじゃないかと思うんですがどうですかね? もとの定義が@autoclosureなのでそれはずしたのをオーバーロードするだけで行けると思うんですが。
6:45 AM
あとドキュメント読んでて気付いたんですがassertpreconditionは最適化によってconditionを評価しないだけで呼出し自体が消えるんじゃないみたいですね。 ずっと勘違いしてました。
Avatar
消えるかどうかは最適化に委ねられてて、消えてる可能性もあるという認識です。確認したことはないけど。
Avatar
omochimetaru 2/2/2018 6:59 AM
@t.ae ループチェックって何?
Avatar
/// - Parameters: /// - condition: The condition to test. condition is not evaluated in /// -Ounchecked builds.
とあったのですが呼び出しが消えるのは別にされてるかもしれませんね。
7:00 AM
@omochimetaru 配列の全要素チェックです
Avatar
@t.ae In -Ounchecked builds, condition is not evaluated, but the optimizer may assume that it always evaluates to true. Failure to satisfy that assumption is a serious programming error.
Avatar
omochimetaru 2/2/2018 7:01 AM
@t.ae ああ。 precondition(items.all { $0 >= 0 }) これでいいじゃん
Avatar
基本それで良いんですけど複雑だと可読性が悪いですし、 問題なさそうでもコンパイル時間が長かったりするので
Avatar
omochimetaru 2/2/2018 7:02 AM
クロージャが渡せたら楽になる、というのがよくわからない
7:02 AM
結局ここはBoolを返す式じゃないといかんので。
Avatar
mapやcontainsが絡んでいるとそれらを分解できませんよね? クロージャで渡すならそれらを別々に呼べる
Avatar
omochimetaru 2/2/2018 7:03 AM
全然わからない・・・
Avatar
let a = [0, 2, 4, 6] assert({ // all even for e in a { guard e % 2 == 0 else { return false } } return true }())
Avatar
omochimetaru 2/2/2018 7:03 AM
どういうコードが書けるような状態を想像しているかサンプルが見たい。
Avatar
最後の () を消したいってこと?
7:04 AM
あとは trailing closure にできるか。
Avatar
そうですね。というかこれ書いて()の有無しか変わらないなと気付いたんですが
Avatar
omochimetaru 2/2/2018 7:05 AM
まさにそう思うし、↑の例だったら、 func allEven(_ x: [Int]) -> Bool を定義しておけば assert(allEven(x)) で良いよ
7:05 AM
複雑な式になった場合に、それがロジックとして展開されている状態は、別に何もわかりやすくなってなくて
7:05 AM
関数名つけたほうがいいんちゃう
Avatar
チェック用の関数を別に用意しとくわけですね。たしかにそっちのほうが良い気がしてきました……
Avatar
omochimetaru 2/2/2018 7:06 AM
まあ、本当にその関数でしか使わない概念のチェックなら名前切り出さない方が統治されてるのかもしれないけど、そのケースは { }() の形で書けばいいいと思う。
Avatar
お知らせ: CountableRange を無くすPRがマージされました https://github.com/apple/swift/pull/13342 (edited)
Based on groundwork by @natecook1000 Not yet ready for commit until we figure out the source compatibility/migration story. Tests are mostly fixed up, except for things like hard-coded mangled name...
🎊 2
Avatar
omochimetaru 2/2/2018 8:11 AM
Avatar
スッキリしてる
Avatar
diff を検索した限りでは typealias CountableRange がなかったんですが、 4.1 でそれを突っ込むと結構大きめの破壊的変更になる気が。これは 5 で入る PR ですか?
8:20 AM
まあ typealias でも破壊的か。オーバーロードとか死ぬし。 (edited)
Avatar
omochimetaru 2/2/2018 8:21 AM
条件付きのtypealiasって書けるんでしたっけ
Avatar
書けるけど壊れたような
Avatar
この変更は4.1 には入らないと思います。 https://github.com/apple/swift-source-compat-suite/pull/131 実際 互換性問題出てますね。
apple/swift#13342 uses conditional conformance to make Range a Collection when its Bound is Strideable. For compatibility, CountableRange is still available as a type alias. There is one source com...
Avatar
omochimetaru 2/2/2018 8:23 AM
swift-source-compat-suite こんなリポジトリあったっけ
Avatar
この間Optionalでなんかガチャガチャやった時に、条件付きtypealiasでぶっ壊した記憶があるんだけど
8:24 AM
typealias O<X> = Optional<X> where X: Sequence O<String>.some("a") O<Int>.some(1) // Error 壊れなくなった可能性がある
Avatar
Kishikawa Katsumi 2/2/2018 8:25 AM
Souce compat suiteはSwiftのアップデートでソースコードレベルの互換性が失われていないかどうかのテストに協力するプロジェクト。 https://swift.org/blog/swift-source-compatibility-test-suite/
We are pleased to announce the release of a new Swift source compatibility test suite as part of the effort to maintain source compatibility in future Swift releases.
👀 1
8:25 AM
私も1つプロジェクトを登録してて、なんかあったら連絡が来る、はず。
Avatar
思い出した、Extensionが壊れるんだった
Avatar
omochimetaru 2/2/2018 8:25 AM
APRIL 24, 2017
知らなかった
Avatar
typealias O<X> = Optional<X> where X: Sequence O<String>.some("a") //O<Int>.some(1) // Error extension O { func foo() { print("foo") } } Optional<Int>.some(1).foo() //????
Avatar
Kishikawa Katsumi 2/2/2018 8:26 AM
登録するの簡単だからやっとくとSwiftプロジェクトの助けになるはず。
8:26 AM
Pull Request Description KeychainAccess is a simple Swift wrapper for Keychain API that works on iOS, watchOS, tvOS and macOS. KeychainAccess framework being added here is licensed under MIT. Accep...
Avatar
omochimetaru 2/2/2018 8:26 AM
そう言えばSwiftコアで最近CIが野良ライブラリの性能評価テストをやっとるなと思ったけどそういうのがあったんですねえ
8:27 AM
@tarunon ほんとだ、壊れてる 作りかけ感あるね
Avatar
@Kishikawa Katsumi compat suite なんかあったら連絡きます?ソース互換性保つのがミッションで、何かあったらコンパイラ側を直すのが基本なので、連絡来ないとおもってました。 実際その運用で Jesse と JP がブチ切れてた件。 https://spec.fm/podcasts/swift-unwrapped/99551
The source compatibility suite has been useful in catching compatibility issues before official Swift releases are cut, but it leaves much to be desired especially around communication with project maintainers outside Apple.
Avatar
条件満たしてれば↓こんな感じで登録できるんですね。 https://github.com/apple/swift-source-compat-suite/pull/39/files
Pull Request Description KeychainAccess is a simple Swift wrapper for Keychain API that works on iOS, watchOS, tvOS and macOS. KeychainAccess framework being added here is licensed under MIT. Accep...
Avatar
Kishikawa Katsumi 2/2/2018 8:29 AM
@rintaro 来てないけど、何かあったら連絡するって書いてあったから連絡来るもんだと思ってました。
8:29 AM
書いてなかったかな。。。
Avatar
In the event that Swift introduces a change that breaks source compatibility with a project (e.g., a compiler bug fix that fixes wrong behavior in the compiler), project maintainers are expected to update their projects and submit a new pull request with the updated commit hash within two weeks of being notified.
https://github.com/apple/swift-source-compat-suite#maintaining-projects ありました。
swift-source-compat-suite - The infrastructure and project index comprising the Swift source compatibility suite.
Avatar
Kishikawa Katsumi 2/2/2018 8:32 AM
そうそう、そこ。within two weeks of being notified.って書いてあるので、登録するときはメール見逃さないようにしないと、と思った記憶があります。
Avatar
なるほど、私も MirrorDiffKit 登録してみたいですね(頻繁に壊れるので)
1:35 AM
Mirror, ほんとマイナーバージョン上がってもかなり壊れるのでつらいです
Avatar
Kishikawa Katsumi 2/3/2018 1:35 AM
頻繁に壊れるプロジェクトははとても役立つのではないでしょうか。
1:36 AM
ランタイムのエラーはともかく、ソースコードのBreaking Changeはバグだと言われてるので、Swiftが修正されるべきですよ。
Avatar
なるほど、要件満たしてるかどうかみてきます
1:36 AM
Ensure the project builds successfully at a chosen commit against Swift 3.0 GM
って書いてあるんですが、これ今もこの条件なんでしょうか…
Avatar
Kishikawa Katsumi 2/3/2018 1:37 AM
それはどうでしょうね。
Avatar
https://summerofcode.withgoogle.com/organizations/4739935060361216/ https://swift.org/project-ideas/ GSoC 通ったみたいです。興味ある学生の方は是非!
Swift is a general-purpose programming language built using a modern approach to safety, performance, and software design patterns.
Avatar
omochimetaru 2/13/2018 2:32 AM
Google Summer of Code (GSoC) は2005年の5月から8月に初めて開催され、その後毎年行われているイベントで[1]、Googleが指定したフリーソフトウェアやオープンソースのプロジェクトでその夏の間に課題をクリアした数百人の学生に賞金を支払う制度である。参加資格は18歳以上の学生で、これを補完する Google Highly Open Participation Contest は18歳未満を対象としている。
2:32 AM
Swift compiler integration with external tools Potential mentors Rintaro Ishizaki
Avatar
mentor まじか、って感じですよねぇ 😇
👀 1
2:34 AM
昨日 #swift-2 で出てた libSyntax の今後も見えますね。
Avatar
norio_nomura 2/13/2018 2:40 AM
おおw ## Swift compiler integration with external tools ## Integration of libSyntax with the rest of the compiler pipeline. ### Potential mentors Rintaro Ishizaki (edited)
Avatar
Kishikawa Katsumi 2/13/2018 3:37 AM
^ SNSでシェアするボタン無いのかな。。。
3:38 AM
無さそう。自分でやろう。
4:03 AM
Google Highly Open Participation Contest
こっちはSwiftやってないんですか?
Avatar
そっち知らないです。検索したところ、2007から2008にかけてだけだったんじゃ無いかな。 https://en.wikipedia.org/wiki/Google_Highly_Open_Participation_Contest
The Google Highly Open Participation Contest was a contest run by Google during 2007-2008 aimed at high school students. The contest was designed to encourage high school students to participate in open source projects. It was succeeded by Google...
Avatar
今はもうないのか…
Avatar
omochimetaru 2/13/2018 4:11 AM
@Yuta Saito 君年齢足りないスゴイな
😱 1
Avatar
https://developers.google.com/open-source/gsoc/faq What are the eligibility requirements for participation? ・You must be at least 18 years of age
😇 1
Avatar
数え年で19なので実はセーフ?
Avatar
もし本当に興味があってやりたいと思うなら
4:16 AM
ゴネれば年齢制限が下な分はなんとかなる…んじゃないかな
4:16 AM
ならないかもしれない
4:17 AM
なってほしいけど
Avatar
興味はあるので試してみます
😁 4
Avatar
これは楽しそうだ
Avatar
iOSでSwiftのStaticLibraryを作る/使うときのデメリットって何かありますか?ちょっと考えたけど、ライブラリ提供者側がターゲット追加するのが面倒くさい以外思いつかなかった。 (edited)
Avatar
omochimetaru 2/15/2018 4:28 AM
それは、Dynamicとの対比で?
Avatar
Kishikawa Katsumi 2/15/2018 4:29 AM
どうだろう。基本的にはiOSの場合はStaticの方がメリットは多いと思いますね。
Avatar
omochimetaru 2/15/2018 4:29 AM
Xcodeでちゃんと設定すればいけるのか。Staticのほうが起動が早いって話を見るよね。技術的にもデメリットは無さそう。どうせ毎回バンドルされちゃってるので。
Avatar
Kishikawa Katsumi 2/15/2018 4:30 AM
デメリットはまだ一般的ではないとかですかね。
Avatar
なるほど
4:30 AM
ありがとうございます!
Avatar
omochimetaru 2/15/2018 4:30 AM
Swift関係なく Static と Dynamic の絡んだ時の問題はあって
Avatar
Kishikawa Katsumi 2/15/2018 4:30 AM
サードパーティのライブラリを使うとかで考えると、Staticにするのは自分でやることになるわけなので。
Avatar
omochimetaru 2/15/2018 4:30 AM
Static-A , Dynamic-B, Dynamic(App)-C があるときに
Avatar
あー
Avatar
omochimetaru 2/15/2018 4:31 AM
B -> A の依存と C->A の依存があると、 AのシンボルがB経由とC経由の両方でやってきて Cにリンクするときに衝突したりしなかったりとか
4:31 AM
そういうのはある。
Avatar
3つくらいリファレンスのあるライブラリを引くとぶつかるのが
4:31 AM
思い出した
4:33 AM
前にSwiftからCか何かのライブラリを入れようとしておもちが踏んで話題に出してたのを思い出した
Avatar
omochimetaru 2/15/2018 4:34 AM
根っこの仕組み上はDynamicにくっついてるStaticはかぶっててもDynamic間の接続でシンボルが露出しなければ大丈夫(バージョンが違う同じstaticlibを埋め込めるという意味でもある) なはずなんだけど、リンカーの挙動だかなんだかで中のstaticのシンボルも検査して衝突したり、上書きされたり、 よくわかってない、そこらへんのエクスポート挙動とかも本当はコントロールできるのかもしれない
Avatar
なるほど
Avatar
omochimetaru 2/15/2018 4:35 AM
前にSwiftからCか何かのライブラリを入れようとしておもちが踏んで話題に
これはたんにprebuiltなCライブラリをリンクするのがSwiftPMだとシンドイ( -Xlinker を付けまくる)って話かも?
4:36 AM
現行のSwiftPMは何もかもstaticにして最後に一気に実行ファイルのdynamicにリンクする感じだからうまくいくっぽいけど、途中で明示的にdynamic指定できるしそういうのどうなるんだろうなあ。
Avatar
スコープをなるべく短くするためにdoを使うのってどう思いますか
Avatar
Kishikawa Katsumi 2/15/2018 6:52 AM
テストケースに書くことはよくありますけど、プロダクションのコードには大抵はもっといい方法があると思います。
Avatar
Kishikawa Katsumi 2/15/2018 6:53 AM
そもそもメソッドを分けるとか。
Avatar
do使う場合は変数多くてメソッド分けたくない場合な気がしますね
Avatar
例えばviewDidLoadで2つの複雑なObservableをmergeしたものをsubscribeしたいとなったときに、let hogeObservablelet fugaObservable をこねこね作って、Observable.merge(hogeObservable, fugaObservable) みたいに書きたい時に、 hogeObservablefugaObservable というローカル変数はなるべくスコープを短くしたい
Avatar
Kishikawa Katsumi 2/15/2018 6:54 AM
まあ、それがベターな場合もあると思いますけど常用することはほとんどないですね。
Avatar
メソッド分けたくない理由もあって、「絶対に1回しか呼ばれないでほしい」ということがあります
Avatar
viewDidLoadの中でfunction作って
6:55 AM
最後はそれを纏めて呼ぶからスッキリ終わるとか
Avatar
func派か
Avatar
Kishikawa Katsumi 2/15/2018 6:55 AM
そっすね。inner functionかクロージャに閉じ込めるかな。
Avatar
或いはそのための型を作るとか
Avatar
Kishikawa Katsumi 2/15/2018 6:56 AM
2つの変数は戻り値で受け取るか、そのまま渡す。
6:56 AM
的な。
Avatar
  • catch無しのdo { }
  • inner func
  • 無名クロージャ のどれかかと思って、doが一番ラクかなと思っていました。
Avatar
Kishikawa Katsumi 2/15/2018 6:56 AM
まあでもそこかしこにあるんじゃなかったらdoでもいいと思いますよ。
6:56 AM
そこかしこに書かないというだけで。
Avatar
僕は 一回しか呼ばれない 内部func 作るくらいなら do の方が良いと思います。
Avatar
funcだと実装と実際に呼ばれるところが違うので処理が追いづらそうと思います
Avatar
後ろ2つは呼び出しのオーバーヘッドありますよね?最適化できえるのかな
Avatar
doなら上から下に読めばおわりなので。
Avatar
ただ do にラベル付けた方が良い。
Avatar
あー最適化まわりは明るくないので、教えてほしいです。
Avatar
ラベル付きDO!
Avatar
doにラベル
Avatar
よさそう
Avatar
やばい知らなかった
Avatar
Kishikawa Katsumi 2/15/2018 6:57 AM
一回しか呼ばれないもののオーバーヘッドは考慮する必要ないかな。
Avatar
breakとcontinueができるようになる奴でしたっけw
Avatar
Kishikawa Katsumi 2/15/2018 6:58 AM
どっちが速いかよりもどっちが読みやすいかのようが優先度が高いです。 (edited)
Avatar
内部で一回でも全体として複数回呼ばれることはあるので……
Avatar
breakとcontinue が出来るのはたしかにそうですが、しなくても ラベルあった方がわかりやすい。
Avatar
「1回しか実行されてほしくない」というニーズもあるので、そうするとやっぱdoかな
Avatar
Kishikawa Katsumi 2/15/2018 6:59 AM
全体として複数回呼ばれるとしてもdoブロックとFunctionの呼び出し速度が問題になるケースはほとんどないはずです。
6:59 AM
それくらい呼ばれないと差は出ない。
7:00 AM
hogeFugaSubscription: do { ... }
7:00 AM
こう書けるのかラベル付きdo
7:01 AM
良さそう。
Avatar
viewDidLoad自体のオーバーヘッドのほうが大きすぎて、その中がfunctionかどうかは問題にならないですね
7:02 AM
この場合だと
Avatar
viewDidLoadだと全くそうですね
Avatar
昔struct使ってstatic funcの真似事するワークアラウンドあったと思うんですけど、1時代
Avatar
「この処理はうっかり2回呼んじゃうのは防ぎたい」というシーンが結構多くて、そうするとviewDidLoadとかdidSetがどんどん長くなるんですが、個別のスコープは短く保ちたいので,
7:04 AM
toiu
7:04 AM
というニーズがあった。
Avatar
型作るのが良いと思う
Avatar
絶対1回しか実行されない型?
Avatar
ViewDidLoadのライフサイクルで実行するための型
Avatar
まだ全然わかんないけど気になる
Avatar
うーんだめか、一回しか呼ばれないを担保出来るものではないぽい
Avatar
話に加わり損ねましたが、僕も do 派です。ローカル関数やクロージャ式にすると実行順がコードの記述順と入れ替わる可能性があり、それを意識しないといけないのが難点だと思います。
7:11 AM
クロージャ式即呼び出しは入れ替わらないか。
Avatar
同意見です。
Avatar
けど、 { ... }() はわかってればいいけど可読性的に微妙かなと。
7:12 AM
あと、 do だと内部から break 等できるけど、ローカル関数やクロージャ式だとできないというのもあります。
Avatar
あーそうだそうだ。それもあったんだった。
7:13 AM
個別のスコープでguardに引っかかったりして早期離脱したときに、そのdoだけスキップして次のdoをやってほしい、っていうのが
7:13 AM
viewDidLoadをreturnで抜けてほしいわけじゃないんだよな〜というのが。バグを生みそう。
7:13 AM
なのでやっぱりdoがしっくりくる
7:14 AM
(for inじゃなくて頑なにforEachを使うのも同じ理由)
Avatar
Kishikawa Katsumi 2/15/2018 7:14 AM
私は{ ... }() の方が読みやすい感覚があるんですよね。do{}はパッと見てtryか、と思ってしまうので。
Avatar
無名クロージャだとselfって書かなきゃいけないのが地味に面倒ですね (edited)
Avatar
あと、最近↓みたいなコード書いたことがあります。が、これ自体は可読性低いよなぁと感じて、単純に終了処理 2 回書いた方がいいか迷ってます。 do { ... // 開始処理 defer { ... // 終了処理 } guard ... { ... break } ... }
Avatar
あれ
7:15 AM
escapingならselfいらないんじゃ
Avatar
あそっか
7:16 AM
即実行ならいらないか
7:16 AM
escapingならself必須では 逆
7:16 AM
言いたいことはわかった
Avatar
逆だ
Avatar
koherさんのdeferのやつは、自分も迷いますね
7:17 AM
guardがいっぱいあるとか、dono
7:17 AM
doの中身が長いとかだったら全然ありだと思います。
Avatar
↑のは do の後も続いてて
Avatar
util作って可読性高めてもいいけど、あんまやると魔界化するからなぁ
Avatar
do を抜けるタイミングで終了処理を挟み込みたかったんですが、早期脱出もしたかったので、両方の終了処理を共通化しようとしたらこうなったけど、可読性は低いよなぁと。共通化を諦めて個別に書いた方がいい気もしてます。 while ... { do { ... // 開始処理 defer { ... // 終了処理 } guard ... { ... break } ... } ... }
Avatar
Kishikawa Katsumi 2/15/2018 7:20 AM
UIKitでしょうがないケースはあると思うけど、基本的に長いとかは適当な単位でメソッドなり関数なりに分割するのがシンプルに良いと思いますね。
7:21 AM
^ の例のwhileは状態をもってループするオブジェクトがあったらいいんじゃないですかね。
7:21 AM
while自体をなくす
Avatar
基本的に長いとかは適当な単位でメソッドなり関数なりに分割するのがシンプルに良いと思いますね。
これは僕もそう思います。基本的には do より関数やメソッドに分割が望ましいと思います。
Avatar
これちゃんとラベル使って
7:22 AM
breakで何を脱出するのかラベル付して明示すればわかりやすくなる
Avatar
可読性が第一なのは全員同意として、単純に実験してみました。 public func AAAAAAA(x: Int) { func step1() { /* ... */ } func step2() { /* ... */ } step1() step2() } public func BBBBBBB(x: Int) { ({ // step 1 /* ... */ })() ({ // step 2 /* ... */ })() } public func CCCCCCC(x: Int) { STEP1: do { /* ... */ } STEP2: do { /* ... */ } } /* ... */ に十分長い処理を書いて試したところ、-O でも 内部 func と クロージャはインライン化されなかったです。ちょっと意外。
👀 1
Avatar
LOOP: while ... { ACT1: do { ... // 開始処理 defer { ... // 終了処理 } guard ... { ... break ACT1 } ... } ... } こうかな
Avatar
Kishikawa Katsumi 2/15/2018 7:23 AM
^ のwhileループは二次元の構造をループするとかかな。
7:23 AM
そういうので長くなってしまうのをどうしたものかというのは何度か悩んだことがあります。
Avatar
自分で言ってて矛盾してる気がしてきた。ローカル関数より do を使うといいながらメソッドに切り出した方がいいというのは変だ・・・。
Avatar
Kishikawa Katsumi 2/15/2018 7:24 AM
読みやすいのはAAAAAAAじゃないですかね。ぱっと見の印象。
Avatar
内部func、overload出来ないし何やら色々途中な匂いがしてます
7:24 AM
そういえば内部func使うと検知するのがクソ難しいメモリリーク出来る気がする
Avatar
再利用できる必要が無いのにスコープを分割するためにメソッドに切り出すのは僕はあんまり好かないですね
7:25 AM
@tarunon 内部funcの中でselfを使ってそれをクロージャの代わりにどっかに渡すとうっかりselfのretain countが増えるとか そういう? (edited)
Avatar
Kishikawa Katsumi 2/15/2018 7:25 AM
func step1() {の定義は自然に読み飛ばすので、私の目には step1() step2() だけに見える。
Avatar
↑のは僕は CCCCCCC が読みやすいですね。
Avatar
@hiragram そんな感じ
Avatar
Kishikawa Katsumi 2/15/2018 7:25 AM
それ以外のBとCはstepの中身を読まされるのがちょっと、って感じですね。
7:25 AM
必要なければ中身は読みたくない、という印象。
Avatar
この例だとstepAとBだからわかりやすいけど、個別の実装が何をしていて、更にそれがどういう順番でどこで呼ばれてるのか、っていうのを前知識ゼロから読むのはコストが高いと感じます
Avatar
自分で言ってて矛盾してる気がしてきた。
この気持を見つめ直してみたら、ステートレスでインプットとアウトプットがはっきりしていて処理の名前が付けやすいものは関数に切り出すとテストもできるしいいんだけど、もう少しコンテクストに依存していて(ごちゃごちゃローカル変数にアクセスしてたり)次の行で使うだけのローカル変数のスコープを短くしたいだけみたいなときは do を使いたいという気持ちでした。
Avatar
Kishikawa Katsumi 2/15/2018 7:27 AM
1箇所からしか呼ばれないメソッドというのは全く問題ないと思います。意味をつけるためにメソッドや関数にするというのは基本的だと思います。
7:27 AM
^ 上の例に限らず。 (edited)
Avatar
意味の付け方がdoのラベルかメソッド名か、ということだと思うので、そうするとメソッドに切り出すことによって再利用可能性という別にいらない性質を獲得してしまうのは考えなきゃいけないことを増やしているだけに感じます
Avatar
Kishikawa Katsumi 2/15/2018 7:28 AM
まあしかし、すごい簡単な例でも実際にコードがあった方が議論しやすいですね。
Avatar
↓みたいなのとか。 let a = ... let b: B do { let t = ... // ちょっと複雑な式 b = foo(t, a) } let c = ...
Avatar
↑僕が最初に言いたかったのはまさにそういうことです。 (edited)
7:29 AM
fooの引数にそのtを導出する式を直接書くのは見づらいことがおおいけど、tはそこでしか使わないからスコープは短くしたい。
Avatar
一箇所からしか呼ばれないことは僕も問題がないと思います。切り出すことでテストも書けますし。
7:30 AM
↑のは無理すれば tfoo() の中に書けるけど、可読性のために変数に入れて名前を付けたくて、かといってそれを長々と生かしたくないみたいなケースです。
Avatar
Kishikawa Katsumi 2/15/2018 7:30 AM
^ の例の話なら、そのdoはない方がいいんじゃないかな。tのスコープが長いのは別に問題ないです。
7:30 AM
tの名前が足りない場合はしょうがない。
Avatar
あーそうなんですか
7:31 AM
うーん
7:31 AM
そうすると短いスコープなら t で済む一時変数にどこで何に使われてるかわかる説明的な名前を付ける必要が出てきませんか
Avatar
Kishikawa Katsumi 2/15/2018 7:31 AM
それが本当にtという名前をつけるならdo {}を使いますね。
Avatar
なんだろ
7:32 AM
導出が複雑な工程を関数に切り出すのは自然なことで
7:32 AM
もしかして、「それを複数回呼ばれたら崩壊する」方が問題なのでは?
Avatar
Kishikawa Katsumi 2/15/2018 7:32 AM
そうじゃなくてtとかは例で、長い式を一旦変数においているという意味で、実際はもうちょっとちゃんとした名前があるということならdo {}はない方が読みやすいです。 (edited)
7:33 AM
もしかして、「それを複数回呼ばれたら崩壊する」方が問題なのでは?
Avatar
ObservableごちゃごちゃやってHotとColdでトンチンカンみたいになってるんじゃないかしら
Avatar
@tarunon 手でNSLayoutConstraintを貼るとか、selfのDisposeBagにsubscriptionをつめつめするとか、そういうのもそうじゃない?
Avatar
Kishikawa Katsumi 2/15/2018 7:33 AM
まあこの条件がなければシンプルかもしれないですね。
Avatar
本当に t という名前を付けることを意図したわけじゃないですが、僕はそのコンテクストでできるだけシンプルな名前を使うのが好きなので、後続処理と名前がかぶって困るということは結構ある気がします。
Avatar
そこで2回呼ばれても大丈夫なためのボイラープレートを書くなら、1回しか呼ばれないことが明らかな書き方をシンプルに書くほうが好きかな
Avatar
3 行くらいなら僕も do なくてもいいんですが、 10-20 行くらいになってくると一度スコープ切っておきたいですね。
Avatar
Subscription作るところは複雑だけど、Bagにつめるのは複雑にはならないはず。
Avatar
Kishikawa Katsumi 2/15/2018 7:34 AM
NSLayoutConstraintのコードはまあひとかたまりでdo{}ブロックを作りつつ、長いviewDidLoadでいいと思います。
Avatar
手でLayoutConstraintは気持ちはわかるけどちょっと考えたほうが良いのがワイの自論
Avatar
Kishikawa Katsumi 2/15/2018 7:36 AM
どう違うのかというと、UIのコードはメソッドに分けて名前をつけてももわかりやすくもならないのでdoや空行で分けるくらいで十分、Swiftならdoでしょう、ということですね。
Avatar
Subscription複雑問題も、複雑なのはObservable組み合わせて川作る部分だけで
7:36 AM
結局それってsubscribeしないと無害なはずだから、そこで分ければなんとかなると思うけど
7:37 AM
Observableの時点で副作用バキバキなのは、もうちょっと頑張ったほうがいい
Avatar
分割したメソッドの中でsubscribeするんじゃなくて、Observableを返すようにしようやということだよね
Avatar
せやな
Avatar
まあ
7:38 AM
チームメンバーがみんなそういうコード書ければ…
👮 1
Avatar
警察業務がんばろ
Avatar
という感じなので誰の目にもあきらかな見た目のほうがいいんじゃね?と。
Avatar
func これこれこういうイベントで発火するObservableだよ() -> Observable<E> func viewDidLoad() { これこれこういうイベントで発火するObservableだよ() .subscribe { 期待した結果やで } .disposed(by: disposeBag) }
7:39 AM
イケルと思うけどなぁ
Avatar
func setupこれこれこういうイベントで発火する奴() { viewModel.hoge.subscribe().disposed(by: bag) } こうなってるのがいっぱいある。
7:40 AM
わかる。
Avatar
因果が逆転している
Avatar
Kishikawa Katsumi 2/15/2018 7:41 AM
後者の方は基本的にfragileなのでまあ微妙といえば微妙だけど。
7:43 AM
func これこれこういうイベントで発火するObservableだよ() -> Observable<E> <= これ自体は何回呼んでも、いつ呼んでもいいわけですよね?
7:43 AM
前者の方。
Avatar
です。
Avatar
Kishikawa Katsumi 2/15/2018 7:43 AM
そういう風に書くのがいいんじゃないですかね。
7:44 AM
さらにstatic funcにして余計な状態を間違って変更しないようにしてしまう。
Avatar
あ、最初の話ちょっと変わっちゃうんですが、↑こういうインスタンスメソッドである必要がなくなった時にstaticにするのはよくやるんですけど、これが型のstaticプロパティにすら依存していないものだったら型の外にprivate funcとして書くのってどう思いますか
Avatar
Kishikawa Katsumi 2/15/2018 7:47 AM
それをやりたいのは型名を省略できるからですかね。
Avatar
その型の役割ですら無いメソッドのとき って感じですね
Avatar
Kishikawa Katsumi 2/15/2018 7:48 AM
いいと思いますね。
Avatar
omochimetaru 2/15/2018 7:48 AM
追いついた
Avatar
ようこそ
Avatar
omochimetaru 2/15/2018 7:48 AM
型に逃がす派の意見はあったかしら
Avatar
@tarunon がありそうだけど無理じゃねって自己解決してた
Avatar
やりたいことは出来ないなぁ→やりたいことがおかしいでしょ(完)
Avatar
シンプル
Avatar
omochimetaru 2/15/2018 7:49 AM
func outer() { var state1 = ... var state2 = ... func inner1() { } func inner2() {} inner1() inner2() } ↑これ系のスタイルは
7:50 AM
class HogeSetUpHelper { var state1 var state2 func inner1() func inner2() func setUp(...) } func outer() { HogeSetUpHelper().setUp(self) }
7:50 AM
こういうふうに逃がせるはずで
Avatar
ワイのイメッジはまさにそれだった
Avatar
omochimetaru 2/15/2018 7:50 AM
これだと、部分処理をメソッドに切り出した結果、関係ないところから2回目の呼び出しがされちゃう問題は
7:50 AM
回避できるし
7:51 AM
Helperを書くところで、依存・参照するシンボルははっきりわかるようにできる
7:51 AM
(↑の例だとself渡しちゃてるけど、必要なものをずらずら渡すと、より見通しがよくなる)
Avatar
関係ないところからはやられないんだが、 HogeSetUpHelper().setUp(self)
8:00 AM
↑こいつを複数回呼び出されることは封印できない
Avatar
omochimetaru 2/15/2018 8:00 AM
それはviewDidLoadの場合でも2回呼ばれる可能性は残ってるからねえ。 (edited)
Avatar
実際はそうなんだけどね
8:00 AM
viewDidLoad明示呼び出しとかはさすがにLintingでなんとか出来るけど
8:01 AM
これ系いっぱいあるとLintでは難しい、それ用に型作ればまあいけるかなぁ。
Avatar
vc.viewにnil突っ込んだとき以外に2回目呼ばれるときあるけ?
Avatar
昔はだな…
Avatar
愚か者が明示的に呼ぶのも覗いて
Avatar
omochimetaru 2/15/2018 8:01 AM
いや、愚か者の話
Avatar
Kishikawa Katsumi 2/15/2018 8:01 AM
今はないです。
Avatar
2018年にvc.viewにnil突っ込むことってある?
Avatar
みんなが好きな昔の viewDidLoadviewDidUnload の話だ。
Avatar
Kishikawa Katsumi 2/15/2018 8:02 AM
理由がないならやる必要はないです。
Avatar
omochimetaru 2/15/2018 8:02 AM
クラス名に HogeOnetimeSetUpHelper とでもしておけば。
Avatar
viewDidUnloadがあった(?)時代のこと僕全然知らないんですよねえ
Avatar
Kishikawa Katsumi 2/15/2018 8:04 AM
さすがにアプリ内のメソッドを複数回呼ぶことについて対策するのは徒労だと思いますね。
8:05 AM
そこまでチームが信用できないというのはそっちの方が問題。
Avatar
まあ人間というか、来週の自分すら信用できないので「おっ便利メソッドあるやんけ、ここでも呼んだろ」となりたくてもなれない仕組みを模索しているんですよね
Avatar
人間は信用できないわかる
Avatar
Kishikawa Katsumi 2/15/2018 8:07 AM
いやまあでもキリがない話じゃないかなあ。
Avatar
omochimetaru 2/15/2018 8:07 AM
2回呼べるという事が問題というより、メソッドとして同じレベルに並んじゃうと
Avatar
キリがないは、仰る通りです。
Avatar
Kishikawa Katsumi 2/15/2018 8:07 AM
viewDidLoadは直接呼ばないでください、みたいなのと同じに聞こえますね。
Avatar
二回目呼んだら激おこ型作って、それでAssertすると多少は安全になるかもしれない
Avatar
omochimetaru 2/15/2018 8:07 AM
グループ感がなくなってしまって、全部いっぺんに読むときの見通しが悪いというのがある
8:08 AM
Helperクラスに切り出してあれば、グループであることはよくわかる。
Avatar
さっきのsetupperはVCのプロパティにいれて、一回までsetup呼べますみたいな
8:08 AM
lazy var使えばちょっとシステマチックにそういうの出来るかもしれないけど考えるの面倒臭くなってきた
Avatar
omochimetaru 2/15/2018 8:10 AM
おもちがコードの見通しにグルーブ感が無くなるとか言ってて流石に何言ってんだろって思ったけどグルーブじゃなくてグループだった。
Avatar
話題の本質でないからTwitterに書いたんだぞ
😋 1
Avatar
あーーーーーー
8:21 AM
class X { lazy var setup: Void = { // only 1 time call here }() }
Avatar
どうやって呼ぶの
8:22 AM
_ = setup ?
Avatar
_ = もいらないよ
Avatar
omochimetaru 2/15/2018 8:22 AM
しぶいねw
8:22 AM
8:22 AM
Voidだからかw
Avatar
それwarningでない?
8:22 AM
あー
Avatar
Voidだからね
Avatar
うわあ
Avatar
omochimetaru 2/15/2018 8:22 AM
また変な技が・・・
Avatar
え?Functionみたいにしたいって?
8:22 AM
しょうがないにゃぁ
Avatar
いきいきしてきたな
Avatar
class X { lazy var setup: () -> Void = { print("a") return { } }() } let x = X() x.setup() ほらよ (edited)
Avatar
omochimetaru 2/15/2018 8:23 AM
嘘の () だ・・・
Avatar
嘘の()w
Avatar
ウケる
Avatar
や、うーん?
8:24 AM
2個目のだと2回目の実行できん?
Avatar
やってみろ
Avatar
omochimetaru 2/15/2018 8:24 AM
いや、嘘だからだいじょうぶ
8:24 AM
printは1回w
Avatar
8:24 AM
うわあ
8:24 AM
うわあ。
😫 2
Avatar
Kishikawa Katsumi 2/15/2018 8:24 AM
おもしろい
Avatar
脳内コンパイルにすっげえ時間かかった
Avatar
今evolutionでワイワイやってる実行可能な型が実現すれば (edited)
8:25 AM
もうちょいスッと書けるようになりそう
Avatar
return { }
Avatar
www
Avatar
虚無だ…
Avatar
無を生成するコード
8:28 AM
func nop() { } typealias Setup = () -> Void class X { lazy var setup: Setup = { // 1回だけ return nop }() } 少し見た目をマシにしてみた
😇 2
Avatar
omochimetaru 2/15/2018 8:29 AM
let setup = once { } こういう高階関数作れそうじゃない?
8:29 AM
関数じゃなくてクロージャになっちゃうけど。
Avatar
onceいいすね
Avatar
「無を生成するコード」で思い出したけど、ちょっと話がそれるけど、この前 fooLoop { (`break`: () -> Never) in ... } みたいな break を作りたかったけどできなくて悲しくなった。
Avatar
lazy 内 で self 参照出来るっていうのは正式にOKになったんだっけか。
Avatar
omochimetaru 2/15/2018 8:30 AM
おお 良さそうだけどできないのか・・・ (edited)
8:30 AM
たしかにbreak文ってそのループで見たらNever式だ。
Avatar
ウェイ func nop() {} func once(_ f: () -> Void) -> () -> Void { f() return nop } class X { lazy var setup = once { print("1time?") } } let x = X.init() x.setup() x.setup()
8:31 AM
こんなことしてる場合じゃないわ
Avatar
omochimetaru 2/15/2018 8:34 AM
public func once<T, R>(_ f: @escaping (T) -> R) -> (T) -> R { var done: Bool = false return { (t: T) -> R in guard !done else { fatalError("do not twice") } done = true return f(t) } } (edited)
Avatar
そのonceだと引数0がVoidでしか出来なくて
8:45 AM
setup(())になるからオーバーロード欲しいすね
Avatar
omochimetaru 2/15/2018 8:52 AM
gysb?
8:56 AM
func once<R> func once<T1, R> func once<T1, T2, R> ...
Avatar
よさそう
Avatar
(気になってひさびさに開きましたがやっと追いついた..) tarunon が書いた lazy var のパターンを最初の方の once にまとめた方に置き換えたことありますね.
10:16 AM
置き換え前のコード, イディオム感があって, 本当に一度しか実行されないのかぱっと見で分かりづらかったり, lazy var の最初の方と後の方のパターンが混在していて, 他のメンバーが混乱し気味だったので (書いてもらう場合も once に突っ込んでもらえば良いので楽). 後, 他の lazy var と見分けづらいとか云々.
10:17 AM
おもちさんの方の once は思いつかなかった. done 掴んでるんですねこれ.
Avatar
>追いついた どこからスタートしたんだろう🤔
Avatar
そう、doneをキャプチャしてる
Avatar
ちょっと境目がわからなかったので, do, inner func かどうかかのあたりから, もっと前はさすがに読めてない (edited)
Avatar
public func once<T, R>(_ f: @escaping (T) -> R) -> (T) -> R { var done: Bool = false return { (t: T) -> R in guard !done else { fatalError("do not twice") } done = true return f(t) } } public class Cat { public init(name: String) { self.name = name self.onBorn() } public var name: String public func onBorn() { _onBorn(self) } private let _onBorn: (Cat) -> Void = once { `self` in print("\(self.name)がうまれた") } } Cat(name: "tama")
10:23 AM
onBorn を let にしたかったけど self がキャプチャできなかったので func onBornlet _onBorn に分かれてしまう。
10:25 AM
public class Cat { public init(name: String) { self.name = name self.onBorn() } public var name: String public lazy var onBorn: () -> Void = once { [unowned self] in print("\(self.name)がうまれた") } }
10:27 AM
lazyだと使えるのか。でもこれじゃ駄目だなあ
Avatar
おもちさんのonce動かないのでは。
Avatar
まだ動かしてなかった
Avatar
public func once<T, R>(_ f: @escaping (T) -> R) -> (T) -> R { var done: Bool = false return { (t: T) -> R in guard !done else { fatalError("do not twice") } done = true return f(t) } } class Cat { let born = once { () in print("mew") } } let c = Cat() c.born(()) c.born(())
10:34 AM
動いてるように見える
Avatar
これが動いてないだけだった。 public class Cat { public init(name: String) { self.name = name self.onBorn() } public var name: String public lazy var onBorn: () -> Void = once { [unowned self] in print("\(self.name)がうまれた") } }
Avatar
メソッドの呼び出しの間はselfが生きてないといけないからそれダメなんすよね かといって強参照したら循環だし
Avatar
iOSDCで僕が言ったアレだ
10:45 AM
「Closureではメソッドの完全な代替は出来ないんですよ」
Avatar
@bannzai さんのコレの質疑ね https://speakerdeck.com/bannzai/xiang-jie-objective-c
iOSDC 2017でお話しする内容です https://iosdc.jp/2017/node/1364 Objective-Cについて熱く語ります
Avatar
それそれ
10:48 AM
[weak self] _ in guard let `self` = self else { return } これで (edited)
10:48 AM
実行した瞬間にキャプチャ生まれないかな
Avatar
weakだから間に合わない
Avatar
呼び出したときだけだわ
10:50 AM
アカン
Avatar
SwiftのARC生成のタイミング次第だけどキリキリに生成されたらダメ
Avatar
これdeinitちゃんと呼ばれるのね。 func once(_ f: () -> Void) -> () -> Void { f() return {} } public class Cat { public init(name: String) { self.name = name self.onBorn self.onBorn } public var name: String public lazy var onBorn = once { print("\(self.name)がうまれた") } deinit { print("deinit") } } do { Cat(name: "test") }
Avatar
クロージャ自体のインスタンス化は、(Cat.init時ではなく)lazyアクセス時なので、クロージャがどこにも参照残らなければ大丈夫ですね。 (edited)
Avatar
あれ?なんでだ?
Avatar
onBornがキャプチャしてるのは、無なので
11:32 AM
セーフ
Avatar
あ、よくみたら、onceの実装が。
11:33 AM
そゆことか、lazy varの右辺を使う たるのん方式の 嘘クロージャのパターンか。
11:33 AM
自分が書いたやつだとリークした。
Avatar
キャプチャ対象は無で、クロージャはキャプチャされないので。
Avatar
onceVoidではなく() -> Voidを返すのも地味に良い。
Avatar
それ嘘ですけどね
Avatar
Voidだとlazyの受け側に型指定がないとwarningが出るので。
Avatar
lazyself参照出来るようになったのはSwift 4.0から?
Avatar
それ自体はだいぶ前から出来たけど、中途半端で、正式には https://github.com/apple/swift/pull/9920 だと思います。
Avatar
Swift 3.1.1までは public struct S { init() {} public lazy var p = self.f() func f() -> String { return "f()" } } var s = S() s.perror: use of unresolved identifier 'self' public lazy var p = self.f() ^~~~ になります。 (edited)
12:23 PM
そのPRはswift-4.0-DEVELOPMENT-SNAPSHOT-2017-06-06-a以降ですね。
Avatar
norio_nomura 2/17/2018 4:33 AM
if caseパターンって、キャスト?もされるのね。知らなかった。 import Foundation enum MyErrorEnum: Error { case message(String) } struct MyErrorStruct: Error {} class MyErrorClass: Error {} extension String: Error {} func check(error: Error) { if case MyErrorEnum.message = error { print("expected error: \(error)") } else { print("unexpected error: \(error)") } } check(error: MyErrorEnum.message("error")) check(error: NSError(domain: "custom error", code: -1, userInfo: nil)) check(error: MyErrorStruct()) check(error: MyErrorClass()) check(error: "StringError") expected error: message("error") unexpected error: Error Domain=custom error Code=-1 "(null)" unexpected error: MyErrorStruct() unexpected error: __lldb_expr_90.MyErrorClass unexpected error: StringError (edited)
Avatar
norio_nomura 2/17/2018 4:42 AM
これのおかげで、associated valueは無視して期待するError enumが投げられるかどうかのテストを XCTAssertThrowsError(try YAMLDecoder().decode(Sample.self, from: invalidYaml)) { error in if case DecodingError.typeMismatch(_, _) = error {} else { XCTFail("unexpected error: \(error)") } } の様に記述できる。 (edited)
Avatar
if case、局所的なパターンマッチなのでいろいろ出来る。後置なので補完効かないのがつらい。
Avatar
omochimetaru 2/17/2018 8:34 AM
補完効かないソレな
Avatar
Kishikawa Katsumi 2/21/2018 4:44 AM
AppCodeは switch x { case 0: break case 1: print(y) print(z) default: print(y) print(z) } こういう複数のcaseを1行に書いたら構文エラーをレポートする。コンパイルはswiftcだからビルドはできる。独自Parserがあるんだな。
Avatar
うわぁ、これは swiftc はエラー出すべきですね。
Avatar
Kishikawa Katsumi 2/21/2018 4:48 AM
あ、そっちが間違いです?じゃあ調べてバグレポートしますかね。
Avatar
Consecutive statements on a line must be separated by ';' になっちゃうと思いますが。
4:49 AM
このエラー大嫌い。
Avatar
Kishikawa Katsumi 2/21/2018 4:50 AM
それぞれのcaseラベルはstatementじゃないんじゃないですかね。
Avatar
確かに "statement" ではないですね。
Avatar
Kishikawa Katsumi 2/21/2018 4:53 AM
あ、なので構文としては正しいのかなと思っていまして。見る限り曖昧な部分もないですし。
Avatar
構文として case 1 の時に print(y);print(z) の動作ですか?
Avatar
Kishikawa Katsumi 2/21/2018 4:54 AM
そうです。
Avatar
なるほど
4:55 AM
確かに読むと case 1 見落としやすいので構文エラーにして欲しい感 is ある 🤔
Avatar
Kishikawa Katsumi 2/21/2018 4:55 AM
文は適当なので動かしてないから違うかもしれないですけど、そう動くように見えます。
Avatar
あいまい性がないのはそうですが、 func foo() {} func bar() {} これも曖昧ではないけどエラーになるので、同じポリシーで行くべきだと思います。
Avatar
omochimetaru 2/21/2018 4:57 AM
なるほど
Avatar
Kishikawa Katsumi 2/21/2018 4:58 AM
確かにそれとかclass A{}; protocol B {};とかはセミコロン必要ですよね。
4:58 AM
構文エラーでよさそうです。
5:01 AM
話変わるんですけど if value==1 {}はOKだけどif velue!=1 {}これがダメなのは理解できるけどわかりにくいから演算子は全部スペース必要でいいんじゃないかと思ったりしてます。
Avatar
omochimetaru 2/21/2018 5:03 AM
たしかに、二項演算子のスペース無しは無くても良さそう。
5:04 AM
両方ともスペースあけるか、両方ともつけないかしか許さないようになってるけど、 後者そもそもいるのか
Avatar
.. とか ..< は?
Avatar
omochimetaru 2/21/2018 5:05 AM
うっ、たしかに、それはくっつけたいw
Avatar
Kishikawa Katsumi 2/21/2018 5:05 AM
そうですね。
Avatar
そうなんですよ。これだけスペースあけないのも変な気がしつつ、くっつけたいやつなんです。
Avatar
でもオペランドに式書く場合はくっつけたくないんですよね〜 a ... (b + foo(c)) とか。 (edited)
👍 1
6:30 AM
なので全部くっつけないというのもありなのかもと思ってます。
Avatar
omochimetaru 2/21/2018 6:30 AM
丸括弧つかうときでも僕はくっつけてた 0..<(n*2) (edited)
Avatar
全部離すと単項演算子の.....<と変わるのが微妙そうですね
Avatar
omochimetaru 2/21/2018 6:31 AM
離しても単項にはならないよ
6:31 AM
1 + 2 の + は 二項
Avatar
いや0 ..< 3..<3で違うスペースの入れ方が強制されるのは微妙だなと
Avatar
omochimetaru 2/21/2018 6:33 AM
ああ、 ..<3 は許されるのに 1..<3 が許されないのは揃ってないということか
Avatar
逆に今..< 3が許されてないのはいいんかという話にもなりかねませんが
Avatar
omochimetaru 2/21/2018 6:33 AM
確かに。
Avatar
protocol A { associatedtype B associatedtype C where C == B.Hoge } struct D: A { typealias B = String typealias C = String } where C == B.HogeHogeという型がBに無いのにコンパイルが通ってしまった。
8:48 AM
そしてそこのwhere句の制約は無視されるようになってしまいました
Avatar
omochimetaru 2/21/2018 8:48 AM
protocol HasHoge { associatedtype Hoge } protocol A { associatedtype B: HasHoge associatedtype C where C == B.Hoge } struct D: A { typealias B = String typealias C = String } 健全な形はこうか。
Avatar
それです
Avatar
omochimetaru 2/21/2018 8:49 AM
B.Hoge って書いてある時点でエラーになりそうなのに確かに通るね
8:49 AM
シンプルすぎて逆に謎・・・ バグか・・・?
Avatar
Xcode9.3 beta だとエラーになりますね。
Avatar
omochimetaru 2/21/2018 8:49 AM
8:49 AM
こちら Version 9.2 (9C40b) 古い
Avatar
Avatar
こんなにシンプルなのに修正が結構最近なんですね〜
Avatar
assoctypeをwhere句で縛れるようになったのは4以降だから
3:18 AM
バグ修正のタイミングとしては妥当に見える
3:19 AM
でも報告自体は結構昔から有るのか
Avatar
kateiくんが見つけたの、まだ4に移行してないプロジェクトなんだよな
Avatar
SomeType: SomeProtocol みたいなジェネリクスはもちろん必要だけど、逆に SomeType: !SomeProtocol みたいなジェネリクスも地味に欲しいよな…
Avatar
ある
2:05 AM
直感的にはスッと出来ないのでは?という気がしている
Avatar
「ある」って
2:06 AM
あるのか?
Avatar
Kishikawa Katsumi 2/23/2018 2:06 AM
もうあるのかと思った。
Avatar
欲しい→わかる
2:06 AM
すません😇
Avatar
Kishikawa Katsumi 2/23/2018 2:06 AM
いや、またなんかHackが出てくるのかなーと思って
Avatar
期待値www
Avatar
型制約としては無理じゃない?Anyとしてしか扱えないし
Avatar
Kishikawa Katsumi 2/23/2018 2:07 AM
コードが貼り付けられるのを待っていました。
Avatar
assoctypeにホンモノの実装への参照を当ててこいつをデフォルトVoidにすることで
2:07 AM
なんちゃってやることはあるかな
2:07 AM
そしてVoidはハイダメーみたいな感じにする
Avatar
<T: FooEnum> where T != case .foo> みたいなこともしたい・・・。
2:10 AM
原理的に無理か。
Avatar
↑見返したら何もわからんかった、移動したらコード張ります
Avatar
実行時にきまるしなー
Avatar
でも case の一部を禁じたいこと多い。
2:11 AM
Kotlin だったら継承関係持たせてグルーピングできるんだけど・・・。
2:12 AM
enum じゃなくて sealed class で) (edited)
Avatar
なんかenumの部分集合のピッチだかありましたよね?それ入れてくれればいいのでは
Avatar
それ見てないな。でも自然な感じでできるのかなぁ?
Avatar
omochimetaru 2/23/2018 2:13 AM
public class Holder<T> {} extension Holder { public func ho() { print("ho1") } } extension Holder where T == String { @available(*, unavailable) public func ho() { print("ho2") } } let a = Holder<Int>() a.ho() // これでいけるかと思ったら ho1 が出力された・・・ let b = Holder<String>() b.ho() 作戦失敗 (edited)
Avatar
部分集合じゃなくて継承だったかな? ぱっと見見つからない https://forums.swift.org/t/enum-inheritance/9933
Pitch: allow enums to inherit cases. Is this idea sound? Is this even possible given the current compiler implementation? Would this be a complex feature to implement for someone who isn’t familiar with the compiler’s codebase? Example: enum NetworkError: Error { case timedOut case cannotFindHost case notConnectedToInternet } enum MyAPIError: NetworkError { case responseInvalid case sessionExpired case notEnoughMinerals case insufficientVespineGas } func didRece...
Avatar
omochimetaru 2/23/2018 2:14 AM
enumのcaseは全部同じenumの型になるから駄目じゃない?
Avatar
sealed class的な話かしら
Avatar
うーん。変数に入ってることを考えるとそうですね。
Avatar
↑の forum の、さすがに↓は壊れてるのでは? enum NetworkError: Error { case timedOut case cannotFindHost case notConnectedToInternet } enum MyAPIError: NetworkError { case responseInvalid case sessionExpired case notEnoughMinerals case insufficientVespineGas } (edited)
Avatar
omochimetaru 2/23/2018 2:16 AM
そうですか?僕はアリだと思った 互換性は満たしていますよ
Avatar
これができたら外部から case を追加できちゃわない?
Avatar
omochimetaru 2/23/2018 2:17 AM
集合 A = (a1, a2) , 集合 B = (a1, a2, b1, b2) なら A is B
Avatar
non-exhaustive enum が導入されればアリですね。
Avatar
omochimetaru 2/23/2018 2:17 AM
ん?
2:17 AM
追加された集合は別の名前。
2:17 AM
NetworkErrorが増えたわけではないです
Avatar
: NetworkError だけど、 NetworkError として扱えるわけではない?? (edited)
Avatar
メソッドやなんかについては議論してますね
Avatar
omochimetaru 2/23/2018 2:18 AM
あ〜たしかに?記法が変だな・・・
2:18 AM
当然互換性は無いと思ってたけど継承と同じだからなんかそう見えますね・・・
Avatar
@rintaro non-exhaustive enum でも、アップデートで追加されるのと、アップデートを伴わずに自由に後付できるのは意味合いが違うような。 (edited)
Avatar
omochimetaru 2/23/2018 2:19 AM
単に、 MyAPIError に対して NetworkError を代入できるって話だと思ってた。
Avatar
まあでも enum Foo: IntInt に入れられるわけじゃないからいいのかな?
Avatar
omochimetaru 2/23/2018 2:19 AM
それは .rawValue 取れば絶対入れられる
Avatar
でも直接突っ込めはしない。
2:20 AM
サブタイプではない、という意味で。
2:20 AM
ただ、この場合は突っ込めることも保証されないから、 : Foo に新たな概念を追加することになるのか・・・。
Avatar
omochimetaru 2/23/2018 2:21 AM
enum MyAPIError { spread case NetworkError case responseInvalid case sessionExpired case notEnoughMinerals case insufficientVespineGas } ↑こんな記法だったら良さそう。 (edited)
Avatar
>アップデートで追加されるのと、アップデートを伴わずに自由に後付できるのは意味合いが違うような たしかに。 むしろ non-exhaustive enum とコンフリクトするかも。
Avatar
@omochimetaru それなら良さそう。
2:22 AM
むしろ struct でもほしい。
2:22 AM
サブタイピングを伴わない継承。
Avatar
すごい、コードとちょっと戦ってたらこんなに熱い議論にw
Avatar
omochimetaru 2/23/2018 2:23 AM
@koher 手間はかかるけどprotocolとextensionを仕込めば、結構簡単にできますよ
Avatar
ちなみに今一番切実に欲しいのは T: !Optional ですねw
Avatar
Kotlin だと↓ですね。 < T: !Optional fun <T: Any> foo() (edited)
Avatar
SwiftだとOptionalもAnyに入るからな…
Avatar
ジェネリックなのを作って個別のをdeprecateとか
Avatar
omochimetaru 2/23/2018 2:27 AM
// 親?クラス struct Animal { var name: String func speak() -> String { return "I am \(name)" } } // トリックここから protocol AnimalExtend { var animal: Animal { get set } var name: String { get set } func speak() -> String } extension AnimalExtend { var name: String { get { return animal.name } set { animal.name = newValue } } func speak() -> String { return animal.speak() } } // トリックここまで // ユーザー例 // プロトコル指定は継承指示 struct Cat : AnimalExtend { // コンパイルエラーがでるのでこれを定義 var animal: Animal // 必然的にこれも書くことになる init(name: String) { animal = Animal(name: name) } } print(Cat(name: "tama").speak()) // ok
2:27 AM
こうやる。
Avatar
Kotlin は Any? がトップタイプですからねぇ。 Any で縛れば nullable を弾けますが、 Swift の Optional は union じゃないから同じことはできないんですよねぇ。
Avatar
その代わりSwiftは Optional<Optional<T>> ができるのは魅力的ですが
2:30 AM
難しいですね仕様
Avatar
Optional のネストはほしいですね。つい最近もやっぱいるよなと思ったけど何だったかな・・・。
Avatar
(JavaのOptionalを使えばいいのでは?)
Avatar
KotlinでJavaのOptional使うのは苦痛な気が。Java書いててもあまり使う気になれないのに。
2:34 AM
@omochimetaru それをやるのが面倒なんよねぇ・・・。
😟 1
2:35 AM
逆に、拡張はできない( Stored Property を追加できない)サブタイピングする struct の継承もほしい。
2:36 AM
struct Path: String { // パス操作のための便利メソッド }
2:36 AM
Path を型として分離できるし、 String として使いたいときはそのまま代入できる。
Avatar
omochimetaru 2/23/2018 2:37 AM
うっかり?stored propertyを追加しない制約ってことですか?
Avatar
値型だからメモリレイアウトが同じじゃないといけないから、 Stored Property は追加できない。
Avatar
omochimetaru 2/23/2018 2:38 AM
transparent struct Path: String { } みたいな。 (edited)
2:38 AM
なんかその話題は昔MLで見た気がする
Avatar
Path is String であるためには。
Avatar
omochimetaru 2/23/2018 2:39 AM
ん?別に is String を取るだけなら
Avatar
ここ(か Slack )で話したこともある気がする。
2:39 AM
let s: String = path ができたい。
Avatar
omochimetaru 2/23/2018 2:39 AM
func asString() -> String が 自動で is や as で呼び出されれば大丈夫
2:39 AM
型変換が暗黙に呼ばれたら良い
2:40 AM
String is Path も取りたいなら駄目ですけどね
Avatar
暗黙の型変換じゃないところがいいところだと思うんだけどなぁ。
2:40 AM
String is Path だと意味がない。
Avatar
omochimetaru 2/23/2018 2:40 AM
うーん、そういうのは明示的な方が良いと思います
Avatar
Path のところに String 渡せてしまうから。
Avatar
omochimetaru 2/23/2018 2:40 AM
.asString() で。
Avatar
いや、暗黙じゃないんよね。サブタイピングだから。
Avatar
omochimetaru 2/23/2018 2:41 AM
それだったらstored propertyが増えても良くないですか?
Avatar
Path はあくまで String なんだけど、 Path として扱っているときは String を突っ込まれたくない。
2:41 AM
StringPath は入れたいけど PathString は入れたくない。
Avatar
omochimetaru 2/23/2018 2:41 AM
1. メモリが全く同じ、互換性は両方向にある 1-2. メモリは全く同じだけど暗黙な変換は Path is String の片方だけ 2. stored propertyが増えても良い 暗黙に Path is String 3. 現在の仕様で、随時 asString で明示的にアップキャスト (edited)
Avatar
メモリが全く同じだけど互換性を片方向にしたい。
2:42 AM
typealias Path = String だと PathString を突っ込めてしまうけど
Avatar
omochimetaru 2/23/2018 2:42 AM
1-2を希望というのはなんか不自然なような・・・
Avatar
String を引数にとる関数に Path を渡すときにいちいち変換したくない。
2:43 AM
いや、 StringPath で話してるからわかりづらいのかも。
2:43 AM
struct Age: Int {}
Avatar
omochimetaru 2/23/2018 2:43 AM
AgeInt とか
2:43 AM
ダブった
Avatar
同じ例をww
Avatar
omochimetaru 2/23/2018 2:43 AM
ですよね
2:44 AM
asInt 派です
2:44 AM
FloatをDoubleに渡すときとかと一緒 (edited)
Avatar
えー
2:44 AM
Weight: IntHeight: Int から BMI 計算するときに
Avatar
omochimetaru 2/23/2018 2:44 AM
あ、ちなみにですけど
Avatar
いちいち変換するか、それとも演算子定義しないといけないよ。
Avatar
omochimetaru 2/23/2018 2:45 AM
protocol IntConvertible { func asInt() -> Int } extension Age : IntConvertible {} こうしておいて、X: IntConvertibleで受ければ
2:45 AM
Ageをそのまま渡せる場所を明示的に指定できます
Avatar
FloatDouble はメモリレイアウトが違うし別の型だけど
2:46 AM
AgeInt の用途を絞りたいだけだから、
2:46 AM
Age is Int は OK だと思うんよね。
Avatar
omochimetaru 2/23/2018 2:46 AM
あ〜aliasである意識が強いのか。
2:47 AM
いちいち変換するか、それとも演算子定義しないといけないよ。
BMI計算はそこの変換がむしろ大事だと思っている
2:48 AM
WeightとHeightが一緒の式に混ざるのが非常に危険で
2:48 AM
そういうところで明示的に数字にアップするのが大事
2:48 AM
ああそうか、 そういう型が二種類あって、合流する時が
2:48 AM
中途半端で危険だなあ
2:49 AM
Age is Intの例の方がまだ同意できて、むしろ Weight とHeightが一緒くたの式がかけるのは、ヤバイと思う (edited)
Avatar
うーん、でも今身長や体重を扱うなら Float とかにするわけでしょ?
Avatar
omochimetaru 2/23/2018 2:50 AM
いや、場合によりますね
Avatar
struct Weight { let value: Float } とか作って区別するっていうならわかるけど。
Avatar
omochimetaru 2/23/2018 2:51 AM
それがアプリケーションでたくさん出てくるならちゃんと定義してます
Avatar
なるほど。
Avatar
omochimetaru 2/23/2018 2:51 AM
なんかサーバーからとってきてちょっと表示するだけ、とかなら、危険が無いからFloatでサボるけど。
2:52 AM
個人的にやって良かったと思うのは MoneyAmount とか TimePoint, TimeInterval(これはFoundationにもあるけど) とか
2:52 AM
Date(Foundationのやつじゃなくて、時刻部分を持たない日付だけの型) とDateTimeとか
Avatar
typealias TimeInterval = Double じゃない?独自に作ったってこと?
Avatar
omochimetaru 2/23/2018 2:53 AM
密に計算対象になったりするような場合、ちゃんと明示的な境界で守ってやると、あ〜よかった〜〜ってなることが多い
2:53 AM
はい、そうです
2:53 AM
例えばメディアプログラミングだと時間軸は有理数で扱いたいので。
Avatar
それはまた別の用途な気が。 < 有理数 (edited)
Avatar
omochimetaru 2/23/2018 2:54 AM
浮動小数だと frameInterval * frame が FPS60でちゃんとかけても1.0秒にならなかったり。
2:54 AM
いや
2:54 AM
Rational型じゃなくて
2:54 AM
ちゃんとTimeInterval型にしたってところが
2:54 AM
ポイントですね。
Avatar
なるほど。
Avatar
omochimetaru 2/23/2018 2:54 AM
TimePointとTimeIntervalは明示的にRationalにもっていってから計算対象になる。
Avatar
単位計算みたいなことを考えると、安易に Float にアップキャストされない方がいいような気もしてきた。
Avatar
omochimetaru 2/23/2018 2:55 AM
ああ、そうだった、単位計算の文脈がこれなんだ。自分の中では Unit Type って呼んでた。
Avatar
↓こういうのがあるといいのかも https://qiita.com/nushio/items/7d534a08e5c30bae32d0
事情により二日ばかし遅延評価となってしまい申し訳ありませんm( )m 次元付き計算がいかに重要か ==== 皆さん、量の計算をするうえで、単位を間違えちゃいけないよ、って教わったと思います。 180cm + 55kg = 2...
Avatar
omochimetaru 2/23/2018 2:57 AM
durationは、2つの時間の間隔を表現するための型である。
2:58 AM
C++のchronoパッケージもそんなのがある ratio型の値として secondsとか milliseconds って値がある。
Avatar
1999年、NASAの火星探査衛星マーズ・クライメート・オービターは、制御プログラムの力の単位にポンド重とニュートンが混在していたために、計画よりはるかに低い軌道に投入されてしまい、火星大気との摩擦により墜落してして失われてしまいました。
Avatar
omochimetaru 2/23/2018 2:58 AM
アメリカの単位系のせいで事故る宇宙開発の話題いくつかありますよね
Avatar
単位計算のルールを型システムにエンコードできれば、コンパイル時にすべての単位エラーを検出できるはずです。
3:00 AM
単位系じゃないけど、アポロがジンバルロックで事故りかけたみたいな話もあった気が。
Avatar
Kishikawa Katsumi 2/23/2018 3:04 AM
ビットコインのライブラリを書いてるときに、基本的にリトルエンディアンで送受信するんだけどポート番号とか一部だけネットワークバイトオーダーが混ざってるという感じなので、Int8〜UInt64のそれぞれのリトルエンディアン型を最初作ったんだけど、変換が面倒でやめてしまった。ただ型として別になってて変換が面倒な方がたぶん良いという印象。いずれそういうふうに戻したい。
3:05 AM
これは色々試行錯誤しながら書いてるときには邪魔だったというだけの話です。 (edited)
Avatar
omochimetaru 2/23/2018 3:05 AM
エンディアンはシリアライズ先の型とみなせますよね
Avatar
なるほど。サブタイプじゃない方が良いような気持ちになってきました。 (edited)
Avatar
型の扱いは別にして、ラッパー struct を簡単に定義出来る方法が欲しいというのはわかります。
Avatar
omochimetaru 2/23/2018 3:06 AM
エスケープとかも同じように型付けすると良いんじゃないかと時々思います (%エンコーディングとか)
Avatar
RawRepresentableはちょっと面倒ある
Avatar
すると enum と同じように、 struct Path: String したら、 path.rawValueString が得られるとかでいいのかも?わざわざ構文増やさなくても、↓書けばいいだけかな・・・。 struct Path { let rawValue: String }
Avatar
omochimetaru 2/23/2018 3:09 AM
initをpublicにするためにinitを書かないといけないですね
3:09 AM
あれ、public struct だったら自動定義のやつも public init だっけ
Avatar
いや、 public init の実装必須のはず。 (edited)
3:10 AM
という意味では : String の意味はあるか?
3:11 AM
必要性が弱すぎてとても通ると思えない・・・。
Avatar
すごい乗り遅れましたが、一回だけ実行したいやつで無を生成するコードにするのって実は公式テクなんですよね https://swift.org/migration-guide-swift3/dispatch_once で検索すると出てくる
Swift is a general-purpose programming language built using a modern approach to safety, performance, and software design patterns.
Avatar
omochimetaru 2/23/2018 3:59 AM
The free function dispatch_once is no longer available in Swift. In Swift, you can use lazily initialized globals or static properties and get the same thread-safety and called-once guarantees as dispatch_once provided. Example
(edited)
3:59 AM
let myGlobal = { … global contains initialization in a call to a closure … }() _ = myGlobal // using myGlobal will invoke the initialization code only the first time it is used.
Avatar
あー
4:00 AM
そういえばstatic letはlazyだった
Avatar
omochimetaru 2/23/2018 4:00 AM
本当だ。因果が逆だったのか。
4:00 AM
dispatch_once探してたけど、それがなくなったのはこれが言語機能にあるからか。
Avatar
でもこの間のは値ごとにやりたい感じだったからstatic letは使えない。
Avatar
staticのletがinstanceのlazy varに当たるので、インスタンスでやりたいならlazy varで無を生成する。 自然な帰結になりましたね
Avatar
omochimetaru 2/23/2018 4:05 AM
なるほど。
Avatar
This will generate commands to build gyb files if they're present in a Swift target. Currently, there are no customization available and the gyb compiler will be looked up in the environment variab...
Avatar
omochimetaru 2/23/2018 7:59 AM
おおおおおおお
Avatar
おお!
Avatar
omochimetaru 2/23/2018 7:59 AM
アツい
7:59 AM
ひさびさにワイルドな話題を見た
8:00 AM
良いのかソレw
Avatar
これ、 iOS でも対応してくれないと Carthage と両対応とかのときにまずそう?
Avatar
CarthageはxcodeprojのTarget走らせるだけなんで、各位中でgyb走らせればオッケーなのでは (edited)
Avatar
omochimetaru 2/23/2018 8:03 AM
ん〜?
8:03 AM
gybによって生成されたファイルをターゲットに入れる必要があるけど
8:03 AM
静的に決まってるからいけるか。
8:03 AM
実行前は真っ赤になってるxcodeprojになるね。
Avatar
いやなんか
8:04 AM
生成済みソースコードは最初から入れておく感じになるのでは (edited)
Avatar
omochimetaru 2/23/2018 8:04 AM
8:04 AM
自動生成が対応するのであれば、生成物はコミットしたくないけどなあ
Avatar
それは理想的にはそうなんだが、まあ結局全部入れてる
8:04 AM
なんか前にその手の話した時に、
8:04 AM
あーーー
Avatar
omochimetaru 2/23/2018 8:05 AM
このPRによって理想に近づくってはなしかと
Avatar
それはspmが対応してないから入れなしゃーないなって感じだった
Avatar
omochimetaru 2/23/2018 8:05 AM
おもったのだ
8:05 AM
そうそう。
Avatar
spm対応したらコミットせんでええな
Avatar
omochimetaru 2/23/2018 8:05 AM
そこが解決するわけでしょ。 (edited)
Avatar
ええやん
Avatar
omochimetaru 2/23/2018 8:05 AM
うむ
Avatar
でもそこまでやるんだったらこう
8:05 AM
もうちょっとgybを見える場所においてくれというお気持ち
Avatar
ま、
I am not sure if this is something we should actually land.
なんで、とりあえず作ってみた、的な。
Avatar
omochimetaru 2/23/2018 8:07 AM
ハート付けといた
Avatar
ObjectEncoderにJSONEncoderJSONDecoder互換のクラスを追加してみた。 https://github.com/norio-nomura/ObjectEncoder/pull/18
12:18 AM
stdlibで使われてるKeyStragety以外のテストは通る。
Avatar
任意の型にStrategyを設定できるObjectEncoderの機能を利用して、JSONSerializationへ渡す/から受け取るobjectをエンコード/デコードしてる。
Avatar
そういえば昨日のPre try!Swiftで @tarunon さんと話しましたけど、この記事の classの場合 のコードがうごくのはおかしいよねっとw https://qiita.com/noppefoxwolf/items/a9d2a103d54b2b1ea415
Avatar
これ関連で最近思ってるんですが、 class でも self を書き換え可能な mutating func がほしいなぁと感じてます。
Avatar
これ extension の init は通ってないんじゃないかな。
Avatar
今それやりたいなら static func で違う Self 返すしかないですね
1:47 AM
@rintaro それがなぜかビルド通ってしかもちゃんと動くんですよ、なぜか
Avatar
イミュータブルクラス Foo に対して func update(foo: Foo, ...) -> Foo { ... }class Foo { func update(...) -> Foo { ... } } があって、 (edited)
1:48 AM
var foo = ... foo = update(foo: foo, ...) foo = foo.update(...) と書くのを
Avatar
class User: Initializable { var id: Int = 1000 /* 暗黙の */ init() {} } extension Initializable { init() { self = Factory.make(type: Self.self) } } User() で、暗黙の User.init() に直接ディスパッチされていると思います。 (edited)
Avatar
func update(foo: inout Foo, ...) { ... } のように inout にして update(foo: &foo, ...) はできるけど、 mutating func がないので対応するメソッド版 update を作れないです。
1:50 AM
mutating funcselfinout に持つ関数という文脈で)
Avatar
スレッド機能欲しいw
Avatar
すみません、チャネル分けるべきでしたw
Avatar
@rintaro そうですね、そして Accountid の初期値をなくすと、それもそのままコンパイルできちゃってStackOverflowになります
Avatar
Account の暗黙init が init(id: Int) になるので Initializable.init()Factory.make(type:) で無限再帰ですね。
Avatar
そしてそのままPlaygroundで動かすと下手するとXcode強制終了させないとMacが固まる危険性がw
1:57 AM
ですね
Avatar
昨日議論したのは、Factory.makeが、Initializable.initを呼ぶときに、witnesstable無いのに具体型のinit引っ張ってくるのがおもろいねという話
Avatar
ところが確かに読み直してみるとそもそも Factory.make が呼ばれてなかったことに気づく
Avatar
もしかしてprotocol extensionに生えてるだけのfuncでもwitnesstable作られるようになった?昔はそこの挙動に差があって、おもちとワイワイやった記憶
2:01 AM
ああ、そういうことか
Avatar
Initializable.initを呼ぶときに、witnesstable無いのに具体型のinit引っ張ってくる
ということでは無い。ということです。
Avatar
じゃあそもそもそこが勘違いなので全体的に正しい
Avatar
まあそれはそうとして、昨日初めて @tarunon さんの実在が確認できてよかったです(おい
Avatar
想定通りの動きですね。コンパイラもこの手の無限ループ検知はしんどいから
2:02 AM
非実在説。まあ今度のtry!で皆さん確認できますよw
Avatar
omochimetaru 2/27/2018 2:15 AM
読んできた
2:15 AM
謎フローに見えるけどそもそも普通のinitになっただけ?
Avatar
User.initだと暗黙宣言されたinitの方が強いからそっちを使う
Avatar
omochimetaru 2/27/2018 2:16 AM
あー、protocol側にはinitの宣言が無くて、真の型が見えてるパターンだから、そうなのかな
Avatar
Protocol側をpublicにして、ライブラリの外からinitすると死ぬパターンとか色々作れるよ
Avatar
omochimetaru 2/27/2018 2:29 AM
これ元記事にはツッコミ入れた方が良いのでは
2:30 AM
筆者が誤認してると思う
Avatar
業務が落ち着いたら追記します
Avatar
追記しときますた
Avatar
omochimetaru 2/27/2018 3:38 AM
クレジットどうもw
Avatar
@tarunon さん、 @rintaro さんと @omochimetaru さんと議論して パワーワードだw
Avatar
日本のiOS界隈四天王の3人が揃った感じですね(嘘w
🙃 1
🤔 1
🐸 1
Avatar
メンツからどこで議論されたのかが容易に割れるのが草
Avatar
https://github.com/apple/swift/pull/11869 お、無限再帰検知のPRがマージされた。限定的かもしれないけど、嬉しい機能追加。
Add a new warning that detects when a function will call itself recursively on all code paths. Attempts to invoke functions like this may cause unbounded stack growth at least or undefined behavio...
👀 1
😆 1
Avatar
↑のがバレるようになるかしら
Avatar
omochimetaru 2/27/2018 9:32 AM
気になってたやつだ
9:33 AM
↑のinitのややこしいやつもちゃんと動くかな
9:34 AM
動くはずなのに無限ループだと間違ってエラーになるのが一番困るねw
Avatar
これでも検知できなかった 😢 。直接の自己再帰だけかな? func bar() { foo() } func foo() { bar() } (edited)
Avatar
ありゃー
Avatar
前見たときは相互再帰は対応してないよってテストケースのコメントに書いてあった。
Avatar
どっちか片方に @_transparent つけると、先に展開されてからの検知になるので、警告してくれましたが。
Avatar
おお
Avatar
おもしろい
Avatar
それが検出できないってことは多分これもできないんじゃないですかね? func generate() -> UInt32 { let a = arc4random_uniform(10) if a > 10 { return a } else { return generate() } }
Avatar
それはarc4randomの仕様知識が必要だからかなり厳しいね、せめて↓の形でないと func generate() -> UInt32 { let a = arc4random() % 10 if a > 10 { return a } else { return generate() } }
Avatar
ですね
10:08 AM
やはりビルド時の無限再帰検出は難しいですね
Avatar
あんまりやりすぎるとビルド時間爆発しそう
Avatar
ObjC やC++の場合、そういうのはAnalyzeビルドの時だけよね
Avatar
あった
10:10 AM
ObjCの時あったな、便利だった
Avatar
norio_nomura 3/1/2018 10:23 AM
4.1の次は5.0ではなく4.2なのか。 https://swift.org/blog/4-2-release-process/
This post describes the goals, release process, and estimated schedule for Swift 4.2.
Avatar
takuro_mizobe 3/4/2018 11:19 AM
@omochimetaru これってなんでgit submodule使ってないのかな? >これら複数のリポジトリの管理は、git submoduleなどの一般的な仕組みではなく、swiftコンパイラプロジェクトで独自に提供される管理操作用のスクリプトを用いて行います。 https://qiita.com/omochimetaru/items/fd485185bcd07c21b49f
この記事では、swiftコンパイラ開発における作業環境構築の知見を紹介します。

リポジトリ構成

swiftコンパイラプロジェクトは、複数のリポジトリから構成されています。その中で主役となるのが[apple/swift](htt...
Avatar
omochimetaru 3/4/2018 11:32 AM
さあー? でも、このやり方なら、llvmのバージョンとswiftのバージョンを疎結合にできて、楽そう
11:32 AM
サブモジュールだと外側は必ずコミットしなきゃいけないからそれだけのプルリクとか必要になるし
11:33 AM
少し古いllvmでもビルドできるのに、外側に引っ張られてチェックアウトしなきゃいけなかったら、 llvmもリビルドしなきゃいけなくて待ち時間が伸びる
Avatar
takuro_mizobe 3/4/2018 11:34 AM
なるほど
Avatar
norio_nomura 3/7/2018 7:04 AM
なぜambiguousなのだろう? $ swift Welcome to Apple Swift version 4.1 (swiftlang-902.0.43 clang-902.0.37.1). Type :help for assistance. 1> Optional(1).map(dump) error: repl.swift:1:17: error: ambiguous reference to member 'dump(_:to:name:indent:maxDepth:maxItems:)' Optional(1).map(dump) ^~~~ (edited)
Avatar
dump関数って
7:05 AM
1引数関数じゃなくて、n引数関数で幾つかがデフォルト
Avatar
norio_nomura 3/7/2018 7:05 AM
1> :type lookup dump @discardableResult @_inlineable @_semantics("optimize.sil.specialize.generic.never") func dump<T>(_ value: T, name: Swift.String? = default, indent: Swift.Int = default, maxDepth: Swift.Int = default, maxItems: Swift.Int = default) -> T @discardableResult @_inlineable @_semantics("optimize.sil.specialize.generic.never") func dump<T, TargetStream>(_ value: T, to target: inout TargetStream, name: Swift.String? = default, indent: Swift.Int = default, maxDepth: Swift.Int = default, maxItems: Swift.Int = default) -> T where TargetStream : TextOutputStream
Avatar
今ってクロージャに関数を渡すタイミングでデフォルト引数を埋めた関数オブジェクトを生成、みたいなことは出来ないんですよね
7:06 AM
mapが要求するのは1引数関数なのでダメ
Avatar
norio_nomura 3/7/2018 7:06 AM
デフォルト未設定なパラメータの数って見てくれないんだっけ?
Avatar
駄目です
Avatar
omochimetaru 3/7/2018 7:06 AM
なるほど。
Avatar
norio_nomura 3/7/2018 7:06 AM
なるほど。
Avatar
omochimetaru 3/7/2018 7:06 AM
{ }でつつんで$0を渡すなら
7:06 AM
埋まるよね
Avatar
そうそう
7:07 AM
関数オブジェクト生成時に足りないパラメータを渡す~みたいなのはない
Avatar
omochimetaru 3/7/2018 7:07 AM
じゃあ { } で包まないオシャレ記法はデフォルト引数に頼ってる時は駄目なんだなあ
Avatar
オシャレ記法、やろうと思えば出来ないことはないんだけど
7:07 AM
そういうのって#lineとか使っててマクロがないSwiftでは詰む
7:08 AM
あれ?できないか、ごめん嘘付いた
Avatar
norio_nomura 3/7/2018 7:11 AM
Playgroundのissueナビゲータには"Found this candidate (swift.dump)"ってのが2つ並ぶので「どちらか決定できない」的なエラーなのかと勘違いしたけど、そもそもどちらも使えないのか。 (edited)
Avatar
嘘っぽい
7:12 AM
なんかその辺のエラーメッセージ嘘があった気がする
7:13 AM
あでも複数あるのは本当ですね
Avatar
norio_nomura 3/7/2018 7:13 AM
そう。
Avatar
とりあえずdumpをオレオレで高階関数化して、デフォルト引数を先に埋めてTの1引数関数を生成するようにすれば
7:15 AM
func dump<T>(name: String?=nil, indent: Int=0, maxDepth: Int=0, maxItems: Int=0) -> (T) -> Void { return { value in dump(value, name: name, indent: indent, maxDepth: maxDepth, maxItems: maxItems) } } (Int?.none).map(dump())
7:16 AM
やりたいことは出来るようになるっす
7:16 AM
このindentとかどうやって取ってきてるんだろ (edited)
Avatar
Kishikawa Katsumi 3/7/2018 7:17 AM
再帰的に呼ぶ時に+1するんじゃないですかね。内部で。
🙆 1
Avatar
これ似たようなテクを使うとGenerics関数を関数オブジェクトとして取り出すみたいな事ができる
7:18 AM
例えばArray.mapは関数オブジェクトとして取り回せないけど…
Avatar
omochimetaru 3/7/2018 7:19 AM
任意の関数 f(a, b, c, d) に対して 好きな引数を埋めた関数を得る操作があると便利か?
Avatar
デフォルト引数の扱いが関数毎に違うので一般化は出来ないと思う
7:25 AM
extension Array { func mapSpecialized<U>(_ type: U.Type=U.self) -> ((Element) -> U) -> [U] { return { self.map($0) } } } こういうの作るとmapを取り回せるようになる
7:25 AM
なんかArray.mapはrethrowsが悪さしてる気がしてきた。まあそれはおいといて
7:25 AM
こんな感じのコード書いて悪さをしてるとXcodeがよく死ぬ
Avatar
Swift ↓ちゃんとできてるなぁ。 var a = [2, 3, 5] var b = a a.withUnsafeMutableBufferPointer { $0.baseAddress!.pointee = -1 } print(a) // [-1, 3, 5] print(b) // [2, 3, 5] var a = [2, 3, 5] var b = a a.withUnsafeBufferPointer { UnsafeMutablePointer(mutating: $0.baseAddress!).pointee = -1 } print(a) // [-1, 3, 5] print(b) // [-1, 3, 5]
3:27 AM
一瞬前者でも CoW が働かないんじゃないかと思ってヒヤッとした。 (edited)
Avatar
omochimetaru 3/8/2018 3:28 AM
前者はwith...Mutable... で、 後者は with... だからか。
Avatar
withUnsafeMutable~~は実行した瞬間コピーされてるんですかね? 中身で書き換えるかどうかまで判断してたら相当賢そうですけど
Avatar
omochimetaru 3/8/2018 3:29 AM
瞬間コピーでしょう
3:29 AM
CoWはそもそもそういうもの
Avatar
中身書き換えるところは無理じゃないかな。ポインタ経由だから。
Avatar
omochimetaru 3/8/2018 3:29 AM
mutatingな関数の冒頭でuniqueでなければclone
Avatar
書き換えないなら withUnsafeBufferPointer 使えばいいわけだし問題はなさそう。
Avatar
まぁそうですよねぇ
3:31 AM
前に自前Array書いた時書き換え判断できたら凄そうだなと思ったので
Avatar
omochimetaru 3/8/2018 3:32 AM
要素ごとの比較だから計算量がでかくなりますよ
3:32 AM
non-uniqueならclone、は、カウンタ見るだけだからO(1)
Avatar
ああ、もちろん実行時に必要が出て初めてコピーできたら です
Avatar
omochimetaru 3/8/2018 3:34 AM
ポインタじゃなくてgetter/setterを渡すインターフェースならできますね。
Avatar
UnsafeMutablePointerpointee に参照型のインスタンス set するとリファレンスカウント増える??増えないと思ってた。 extension Array { mutating func update(_ body: (inout Element) throws -> ()) rethrows { let count = self.count try withUnsafeMutableBufferPointer { var pointer = $0.baseAddress! for _ in 0..<count { try body(&pointer.pointee) pointer += 1 } } } } class Cat { let name: String init(_ name: String) { self.name = name } deinit { print("deinit: \(name)") } } var a = [Cat("a"), Cat("b"), Cat("c")] a.update { $0 = Cat("\($0.name)2") } deinit: a deinit: b deinit: c
Avatar
omochimetaru 3/8/2018 3:53 AM
増えますよ
3:53 AM
増えないとやばくて
3:53 AM
もともと入ってる値が消えることを考えるとわかりやすいかと。
3:53 AM
そっちはreleaseされないといけないですよね。
Avatar
はい。なので参照型入れるときは明示的に色々やんなきゃいけないのかと思ってた。
3:55 AM
UnsafeRawPointer としてコピーとかすると壊れるのか。
Avatar
omochimetaru 3/8/2018 3:55 AM
そうですね
Avatar
そうすると↑の update は問題なさそうだけど、これより速い実装ってあるかな?
Avatar
omochimetaru 3/8/2018 4:00 AM
改善点は思いつかないです
Avatar
最初、 count が無駄かと思ってポインタを比較してループ回してたけど
4:02 AM
計測したら↑の方が速かった。
Avatar
norio_nomura 3/8/2018 4:02 AM
DispatchQueue.concurrentPerformを使ったconcurrentUpdateとか。
Avatar
↓みたいな感じ。 extension Array { mutating func update(_ body: (inout Element) throws -> ()) rethrows { let count = self.count try withUnsafeMutableBufferPointer { var pointer = $0.baseAddress! let end = pointer + count while pointer != end { try body(&pointer.pointee) pointer += 1 } } } }
4:04 AM
@norio_nomura なるほど。でも Dispatch に依存したくないですねぇ。。。 < concurrentUpdate (edited)
4:06 AM
いや、違うのかな。↑はインデックス操作がなくなってるところがポイントだけど、 concurrent だとそれができない?それでも並行になると速くなりそうだけど。
4:07 AM
領域を N 分割すれば並行でもポインタ操作でできるか。 (edited)
Avatar
議論を見ていて思ったのですが、 getBase() ..< getBase() + countgetBase() 一回で綺麗に書く構文って現状ありましたっけ?
4:16 AM
for pointer in $0.baseAddress! ..< $0.baseAddress! + count { try body(&pointer.pointee) } をもっと短く書きたい。
Avatar
omochimetaru 3/8/2018 4:22 AM
string[string.index(string.startIndex, offsetBy: 3) ..< string.index(string.startIndex, offestBy: 6)] これも短く書きたい (edited)
Avatar
Kishikawa Katsumi 3/8/2018 4:22 AM
わかる
4:23 AM
まあ現状そうなってる理由も納得できるけど
Avatar
string[offset: 3..<6] の議論はどんな感じなんだっけな。
Avatar
omochimetaru 3/8/2018 4:25 AM
ありましたねそのスレ、現状の理由とかスルーしてとりあえず気持ちが書いてある感じがしたから流したけど、発展したかな
Avatar
This seems like another case that would be well served by an operator ..<+ hack: infix operator ..<+ extension Strideable { static func ..<+ (lhs: Self, rhs: Stride) -> Range { return lhs..
Avatar
..<+ 良さそう。
4:35 AM
$0.baseAddress! ..< $0.baseAddress! + count できるの知らなかったー😣
Avatar
今まったく同じ ..<+ 書いてた…
🙃 1
4:38 AM
The objection is going to be: 5..< +10 which means something else.
4:38 AM
なるほど
Avatar
似たケースで+じゃなくて-の問題を変な回避法してたのを思い出した。 https://github.com/t-ae/ndarray/blob/master/Sources/NDArray/Core/Indexing.swift#L75-L102
ndarray - Float NDArray library for Swift, accelerated with Accelerate Framework
Avatar
なんかすごい演算子がいっぱいだ・・・
4:47 AM
infix operator ~> : StridePrecedence prefix operator ~> infix operator ~>- : StridePrecedence prefix operator ~>- infix operator ...~> infix operator ...~>-
Avatar
このへんが笑いどころ public func ~>-(range: CountableRange<Int>, stride: Int) -> NDArrayIndexElement { return range ~> (-stride) }
Avatar
omochimetaru 3/8/2018 4:49 AM
a~>-ba ~> (-b) なのね
Avatar
operator の上書きが出来ることを初めて知った。 ~> は stdlib で既に定義されているので、
Avatar
omochimetaru 3/8/2018 4:50 AM
マジ
Avatar
あれ?別であるんですね。
Avatar
norio_nomura 3/8/2018 11:53 PM
大喜利みたいだ>Shorthand for Offsetting startIndex and endIndex https://forums.swift.org/t/shorthand-for-offsetting-startindex-and-endindex/9397/172 (edited)
If we’re going to start using symbols, then clearly this is a job for emoji. I recommend arr[🔜(1)..<🔚(2)]. Like @DeFrenZ, I don’t understand this desire to avoid words, which everyone understands.
😆 1
Avatar
XcodeもSlackとかみたいに :soon: 入れると勝手に 🔜 出してくれるようになって欲しい(嘘 (edited)
Avatar
omochimetaru 3/9/2018 2:45 AM
このスレ2/1からなのに170もレスあるのか・・・
Avatar
今日のAfter talks用のサンプル(クソ)アプリ作ったので皆さん遊んでみようぜw https://github.com/el-hoshino/zundoko brewで入れられるので、こんな感じでインストールできます: brew tap el-hoshino/zundoko brew install zundoko そして使い方は zundoko の後に適当に何か英文章書きます、何が出力されるかはEnter押してからのお楽しみw zundoko try! Swift is Good
zundoko - A joke program that outputs random words from your command arguments each at a time. If eventually it output the words in the correct order, it will output the sentence again adding ! a...
Avatar
4ワードは長いw
5:32 AM
↑今日、めっちゃ仕事が忙しいので、さっそくbrewでインストールしてみましたw
5:58 AM
まあ長い文だとものすごい実行時間長いですね、仕方ないですw
Avatar
sil出したい時いつもswiftc --emit-silと書いてしまう
Avatar
omochimetaru 3/9/2018 9:11 AM
ハイフンが一個多いってこと?
Avatar
java -version さんパターンだ
Avatar
それです。
9:35 AM
javaのバージョンを調べたいことは一生に何度もないので問題ないんですが
Avatar
環境ガチャガチャしてると時々調べたくなってキレてる
😇 1
9:39 AM
java 9 でついに邪悪なのが --version になるよみたいな話を観た気がしてウキウキして java 9 いれて --version してそんなオプションネーヨと言われた気持ち
java 1
Avatar
ここでJava邪悪というのは卑怯なのでTwitterでやろう
Avatar
はい
9:46 AM
にしてもなんで swiftc も 1 個ハイフンにしちゃったんだろ
Avatar
KillSequence - A proposal to do away with Swift's Sequence protocol
Avatar
omochimetaru 3/11/2018 1:06 AM
うーん、よくわからなかった
1:07 AM
シングルパスと無限長を言ってるけど、最小の定義がそれだと思うし、 Collectionがあるんだから困る時はそっち使えば良いし・・・
Avatar
norio_nomura 3/11/2018 1:12 AM
なんとなく気持ちが悪いのはわかる気がするけど、どうなってると今より良いのか?はわからないな。
Avatar
do try 文だとネストが深くなるから、guard try let error {as XxxError} 文欲しくなった今日の今頃
Avatar
Kishikawa Katsumi 3/12/2018 5:17 AM
それはtryの処理はdo tryとネストのレベル一緒じゃないんですか?
Avatar
omochimetaru 3/12/2018 5:17 AM
どういう挙動?
Avatar
単純に guard try? else と同じような挙動で、guard と同じ階層で正常系を描く処理ですね、ただ guard try?error を消すけどこちらは消さない
Avatar
1個関数作ったら解決しそう
Avatar
omochimetaru 3/12/2018 5:19 AM
Xxxエラーの場合、else節でそれをハンドルして脱出 他のエラーの場合throwが飛んで行く か
Avatar
guard let player = try AVAudioPlayer(name: name) catch let error as NSError { print(error) // エラーハンドリング return } catch let error { return } player.play() みたいな (edited)
5:20 AM
1個関数作ったら解決しそう
確かに…? 🤔
Avatar
Kishikawa Katsumi 3/12/2018 5:21 AM
do { try ... } catch { print(error) // エラーハンドリング return }
Avatar
Voidで握りつぶすのはあんまり好きな感じではないんですが、型を変えたErrorを投げるパターンならなんとかなりそう
Avatar
Kishikawa Katsumi 3/12/2018 5:21 AM
^ これとあまり変わらない気がするんですよね。
Avatar
要は do の中で書くとネストが深くなるのがちょっと微妙に嫌ですね
Avatar
Hello dear Swift community, this proposal might seem like some new syntax sugar, but it also aims to escape the 'do { }' scope from the 'do try catch‘ mechanism while making the existing error handling more powerful. Lets assume we have some ...
Guard statements interact with pattern-matching to ensure that control flow cannot continue unless a pattern is matched. This is a very convenient way to introduce non-optional variables from optional-valued expressions:     // func foo() ...
Avatar
おおそういう議論上がってるんですね!
Avatar
Kishikawa Katsumi 3/12/2018 5:26 AM
Adrianさんのいうcatchしたあとは早期脱出を強制させられるというメリットは少し理解できる。 (edited)
Avatar
理論上は guard let Type = Type?guard let Type = try Type も同じようなものだと思うんですよね、どちらも「確実な Type が欲しい」というわけで
Avatar
Amazing proposal, I love it and thinking back there's plenty of times where I would have used the guard-catch instead of the non-swifty (to me) do-catch. A guard-catch construct still allows to handle errors explicitly, with the added convenience...
Avatar
Kishikawa Katsumi 3/12/2018 5:39 AM
この提案はまさに @lovee さんの欲してるものそのままって感じですね。
5:40 AM
ネストを嫌ってるところも。
Avatar
ですね、個人的には是非通って欲しいです
Avatar
議論止まっているので何らかアクション起こさないと動かないと思いますよ。
Avatar
つまりReplyすべき、と
Avatar
むしろ Proposal と実装まで行ってしまいましょうYO!
Avatar
Proposal自体は上がってるのではないんですか?この場合 🤔
5:45 AM
マージ?されてないけど
Avatar
一度上がったことはありますが、review 前に reject されています。 https://github.com/apple/swift-evolution/pull/734
This pull request adds a proposal for a guard/catch construct for the language. It would allow code to use throwing functions and handle errors fully, without straying from a happy path. do/catch c...
5:48 AM
あとこれ、 Parse, TypeChecker, SILGen まで影響与えるので、現時点で実装者見つけるのは厳しいかもしれないですね。
Avatar
ふむふむ、ProposalはImplementationがないからRejectされた、という感じですねコメント読む限り
5:49 AM
(つまりImplementがあればワンチャンあると 💪
Avatar
ParseからSILGenまで通しでやるのアツい
Avatar
あとこれ、 Parse, TypeChecker, SILGen まで影響与えるので、現時点で実装者見つけるのは厳しいかもしれないですね。
厳しそうですね
Avatar
https://forums.swift.org/t/guard-catch/6264 現状の最新議論はこれでした。
I’d like to propose a guard/catch construct to the language. It would allow code to use throwing functions and handle errors fully, without straying from a happy path. do/catch can be a bit heavy-handed sometimes, and it would be nice to be abl...
Avatar
あのリジェクトされたProposalのPRを出した人のですね
Avatar
A really cool "hidden" feature of UserDefaults is that it contains any arguments that were passed to the app at launch! 🚀 Super useful both in Swift command line tools & scripts, but also to temporarily override a value when debugging iOS ...
Likes
171
12:39 AM
しらなかった。
Avatar
さすがだw
Avatar
Kishikawa Katsumi 3/13/2018 12:42 AM
^ これね。Cocoaの起動時引数は恐ろしいほど複雑な処理をしている。
12:43 AM
たかだか起動時引数でPlist, XMLをParseするとか(悪い意味で)頭おかしいんじゃないかと思っている。
😆 1
Avatar
「悪い意味で」w
Avatar
Kishikawa Katsumi 3/13/2018 1:12 AM
いやあ、この仕様は明らかに無駄に複雑で、便利は便利なんだけどそれだったら1種類のフォーマットを受け付けておけば良いはずで、 -plistArg '{"foo" = bar; "array" = ("foo", {"bar" = "baz"; } ); }'-xmlArg "<dict><key>foo</key><string>bar </string><key>baz</key><string>qux</string></dict>" をフォーマットを事前に指定することもなく、両方使えるようにするとか普通に考えておかしいなあと。
1:14 AM
まあでも引数をUserDefaultsに食わせるだけみたいな実際の実装は意外とシンプルなのかな。 (edited)
Avatar
norio_nomura 3/13/2018 1:44 AM
swift-corelibs-foundation - The Foundation Project, providing core utilities, internationalization, and OS independence
Avatar
とりあえずPropertyListSerializationに丸投げしているんですね。
Avatar
Kishikawa Katsumi 3/13/2018 1:47 AM
実際に行われることは複雑だけどその部分に限って言えばシンプルで必要最小限のコードですね。
Avatar
norio_nomura 3/13/2018 1:48 AM
実際(Darwin)の実装はswiftではないと思いますが、大きくは違わないと思います。 (edited)
Avatar
Kishikawa Katsumi 3/13/2018 1:49 AM
そうでしょうね。その形で実装するのが普通だと思います。
1:51 AM
これを調べてる過程で勘違いしたのは、ProcessInfoで取れる起動時の引数とUserDefaultsに渡されるのものはそもそも互いに独立なので、不完全なPlistを渡した場合はUserDefaultsにはもちろん渡らないのだけど、起動時引数としては普通に取れる。
1:51 AM
調べてる最中に起動時引数が意図せず失われるんじゃないか、とか色々考えてしまった。
Avatar
protocol HasCodingKeys: Codable {} extension HasCodingKeys { func encode(to encoder: Encoder) throws { fatalError() } init(from decoder: Decoder) throws { fatalError() } } struct A: HasCodingKeys { private typealias Keys = CodingKeys // Use of undeclared type 'CodingKeys' } Codableinit(from decoder: Decoder)func encode(to encoder: Encoder) をprotocol extensionに実装すると、Aの中でCodingKeys がundeclaredになるんですが、どういう仕組みになってるんですかね。 (edited)
Avatar
omochimetaru 3/13/2018 9:59 AM
普通のinitとfuncだったら大丈夫なんだっけ。
Avatar
あ、proto extension 関係ないか
10:07 AM
initとfunc両方実装されている時に使えない
Avatar
ふむ
10:26 AM
いやどうだろ
Avatar
struct A: HasCodingKeys { typealias Keys = CodingKey }
10:38 AM
通ったよ。タイポでは
Avatar
struct A: Codable { struct B {} let b: B typealias Keys = CodingKeys } これを通したかったみたいでした。 (edited)
10:44 AM
そりゃ無理だ
Avatar
CondingKeyとCondingKeysわからなくなる
Avatar
XMLをパースするのにCodingKeyを無理やり使おうみたいなことをしていて、ハマりました。 https://github.com/kateinoigakukun/IBLinter/blob/812f9ccb34323df3fb4d5240c4f24dc8156e0a59/Sources/IBLinterCore/Models/Controllers/ViewController.swift
IBLinter - A linter tool for Interface Builder
Avatar
norio_nomura 3/15/2018 1:08 AM
プロパティのセッタだけ@available(*, unavailable)って出来ない?
Avatar
できなかった気がしますね
1:10 AM
外側に付けたら怒られますけど内側につけても何も言われず実行できますね
Avatar
norio_nomura 3/15/2018 1:10 AM
ありがとうございます。
Avatar
setterだけじゃなくgetterの場合もなんですよね。 以前subscriptsetterだけ定義したくて試してだめだったので
1:40 AM
var _x: Int = 0 var x: Int { @available(*, unavailable) get { return _x } @available(*, unavailable) set { _x = newValue } } print(x) // 0 x = 100 print(_x) // 100 (edited)
Avatar
norio_nomura 3/15/2018 1:42 AM
それは@availableだけの話では無いですよね。private(get)も無いから。
Avatar
確かに
Avatar
セッタのアクセスレベルがゲッタより低くしか設定できないとは明文化されてるんですけど具体的な根拠はあるんですかね。 現状で見えてる変数ライクなものが読み取れないパターンが無いのでそういうルールになっているんじゃないかという気もしますが。
Avatar
norio_nomura 3/15/2018 2:01 AM
ゲッタが無くても構わないものは、subscriptやプロパティである必要がない、ってことなのではないかと思います。 (edited)
Avatar
そうですね、多分みなさんこんな風にやってるんじゃなかと private var privateValue = 0 func setValue(_ value: Int) { privateValue = value }
2:03 AM
現実世界で言うといわゆる投函ボックスみたいな書き込み権限オンリーのアクセス権欲しい時 is よくある
Avatar
読み出しと書き込みで別の型を使いたいとかたしかそんなシチュエーションだった気がする
Avatar
それもありそうですね、外にはパブリックな型で暴露してるけど内部処理ではもうちょっと高度なプライベートな型で処理したいときとか 🤔
Avatar
https://github.com/apple/swift/pull/15102 deprecated は実装されそう。 (edited)
This handles the case where just one accessor is deprecated but not the other, which does come up sometimes in Apple's frameworks. Not included in this pull request: fixing availability checki...
❤ 1
2:12 AM
セッタのアクセスレベルがゲッタより低くしか設定できないとは明文化されてるんですけど具体的な根拠はあるんですかね。
foo.bar.baz = 1 で、foo の getter の方が絞られていると bar がそもそも取り出せないので、変な感じになってくるとかはありそうですね。
(edited)
Avatar
それですね。setHogehoge(~)があってgetHogehoge()がないのはそこまで違和感を覚えない
Avatar
readonly readwriteはあるけどwriteonlyがないのと同じっぽい
2:14 AM
というか書き込み専用はそれ実質1引数Functionだから、普通にFunctionとして書いて良いんじゃないかなとか思ったり (edited)
Avatar
norio_nomura 3/18/2018 5:42 AM
累乗関数が欲しくて、パフォーマンスをチェックしてた。 import XCTest @testable import pow let lhs = 10 let rhs = 10 let count = 1000000 let expect = Int(pow(Double(lhs), Double(rhs))) final class powTests: XCTestCase { func test0() { var x: Int = 0 measure { for _ in 0..<count { x = power0(lhs, rhs) } } XCTAssertEqual(x, expect) } …
5:45 AM
ここでexpectの算出に使ってるInt(pow(Double(lhs), Double(rhs)))の速度も測ろうと考え func test_() { var x: Int = 0 measure { for _ in 0..<count { x = Int(pow(Double(lhs), Double(rhs))) } } XCTAssertEqual(x, expect) } を追加したら、10000倍くらい速かった。
5:46 AM
しかしこれはコンパイラが賢くて、x = expectに書き換えてただけだった…コンパイル時に定数になってた。 (edited)
Avatar
コンパイラは pow が参照等価であることをどうやって知ってるんですか?
Avatar
同じファイルのグローバルスコープにlet expect = Int(pow(Double(lhs), Double(rhs)))ってのがあって、テストtest_()内でそのexpectを参照してるのと、Int(pow(Double(lhs), Double(rhs)を別モジュールの関数にした場合と速度差がありすぎることから、x = expectにしているという僕の推測です。 (edited)
10:12 AM
test_()内のループカウンタをどれだけ増やしても実行時間が変わらないので、ループ自体が無くなってるのかも?
Avatar
swift のベンチマークでは、 @inline(never) public func blackHole<T>(_ x: T) {} に食わせて、最適化を防いでますね。
10:16 AM
measure { for _ in 0..<count { blackHole(Int(pow(Double(lhs), Double(rhs)))) } }
10:19 AM
あー、けど x = expect になってるんだったら blackHole(expect) になるだけだから防げないか。 (edited)
Avatar
echo 'import Foundation; let lhs = 10, rhs = 9, count = 10000000, expect = Int(pow(Double(lhs), Double(rhs))); func test() { var x: Int = 0; for _ in 0..<count { x = Int(pow(Double(lhs), Double(rhs))) }; print(x == expect) }; test()'|swiftc -emit-assembly - -O|xcrun swift-demangle (edited)
10:32 AM
どうやらpowの呼び出し自体がなくなってるぽい。
10:33 AM
-Ononeにするとcallq _powが2箇所現れる。
10:34 AM
x = expectにしてるわけでは無く、コンパイル時に定数になってるぽい。 movq $10, _main.lhs : Swift.Int(%rip) movq $9, _main.rhs : Swift.Int(%rip) movq $10000000, _main.count : Swift.Int(%rip) movq $1000000000, _main.expect : Swift.Int(%rip) callq _main.test() -> () (edited)
10:35 AM
そりゃ速いわ。
Avatar
SILの時点ではpowの呼び出しが残ってる。
Avatar
LLVM IR の時点で llvm intrinsic の @llvm.pow.f64 に置き変えですか? (edited)
Avatar
-emit-irpowは無くなって定数1000000000になってますね。 define i32 @main(i32, i8** nocapture readnone) local_unnamed_addr #0 { entry: store i64 10, i64* getelementptr inbounds (%TSi, %TSi* @main.lhs : Swift.Int, i64 0, i32 0), align 8 store i64 9, i64* getelementptr inbounds (%TSi, %TSi* @main.rhs : Swift.Int, i64 0, i32 0), align 8 store i64 10000000, i64* getelementptr inbounds (%TSi, %TSi* @main.count : Swift.Int, i64 0, i32 0), align 8 store i64 1000000000, i64* getelementptr inbounds (%TSi, %TSi* @main.expect : Swift.Int, i64 0, i32 0), align 8 tail call swiftcc void @main.test() -> ()() ret i32 0 }
Avatar
ああ、 emit-ir はLLVM最適化後でした。 https://twitter.com/rintaro/status/963754184494350336
@orga_chem @omochimetaru Optimizationパス通した後の出力なので、最適化済みだと思いますよ。 https://t.co/1wx2exme0d
11:13 AM
-disable-llvm-optzns をフロントエンドに渡してあげると見えるかもしれない。
Avatar
$ echo 'import Foundation; let lhs = 10, rhs = 9, count = 10000000, expect = Int(pow(Double(lhs), Double(rhs))); func test() { var x: Int = 0; for _ in 0..<count { x = Int(pow(Double(lhs), Double(rhs))) }; print(x == expect) }; test()'|swiftc -frontend -emit-ir -primary-file - -target x86_64-apple-darwin17.4.0 -enable-objc-interop -sdk /Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -O -color-diagnostics -disable-llvm-optzns -module-name main -o - |xcrun swift-demangle
Avatar
$ echo 'import Foundation; let lhs = 10, rhs = 9, count = 10000000, expect = Int(pow(Double(lhs), Double(rhs))); func test() { var x: Int = 0; for _ in 0..<count { x = Int(pow(Double(lhs), Double(rhs))) }; print(x == expect) }; test()' | swiftc -O -emit-ir -Xfrontend -disable-llvm-optzns -
Avatar
define i32 @main(i32, i8**) #0 { entry: %2 = bitcast i8** %1 to i8* store i64 10, i64* getelementptr inbounds (%TSi, %TSi* @main.lhs : Swift.Int, i32 0, i32 0), align 8 store i64 9, i64* getelementptr inbounds (%TSi, %TSi* @main.rhs : Swift.Int, i32 0, i32 0), align 8 store i64 10000000, i64* getelementptr inbounds (%TSi, %TSi* @main.count : Swift.Int, i32 0, i32 0), align 8 %3 = call double @pow(double 1.000000e+01, double 9.000000e+00) pow残ってる。
Avatar
define i32 @main(i32, i8**) #0 { entry: %2 = bitcast i8** %1 to i8* store i64 10, i64* getelementptr inbounds (%TSi, %TSi* @_T04main3lhsSivp, i32 0, i32 0), align 8 store i64 9, i64* getelementptr inbounds (%TSi, %TSi* @_T04main3rhsSivp, i32 0, i32 0), align 8 store i64 10000000, i64* getelementptr inbounds (%TSi, %TSi* @_T04main5countSivp, i32 0, i32 0), align 8 %3 = call double @pow(double 1.000000e+01, double 9.000000e+00) %4 = bitcast double %3 to i64 ... declare double @pow(double, double) #1 この時点ではまだ 普通のpowですね。
Avatar
ちなみに僕の用途では、最適化で定数化されないpowは単純なforループ版より3~9倍遅かった。
Avatar
@norio_nomura
x = expect にしているという僕の推測です。
関数を同じ引数で複数回呼び出したときに同じ結果が返されるとは限らないので、 pow が参照等価であることをコンパイラが知らないと x = expect とすることができないんじゃないかと思ったんですが、そもそもコンパイル時に展開されているということは pow が特別扱いされてそうですね。
Avatar
llvmはそういう情報を持っている様です。 https://github.com/apple/swift-llvm/blob/stable/include/llvm/Analysis/ConstantFolding.h#L140-L142 /// canConstantFoldCallTo - Return true if its even possible to fold a call to /// the specified function. bool canConstantFoldCallTo(ImmutableCallSite CS, const Function *F);
Contribute to swift-llvm development by creating an account on GitHub.
11:59 PM
Contribute to swift-llvm development by creating an account on GitHub.
12:02 AM
Constant folding and constant propagation are related compiler optimizations used by many modern compilers. An advanced form of constant propagation known as sparse conditional constant propagation can more accurately propagate constants and simu...
Avatar
switch のパターンマッチに ? 使えるの知らなかった😇 if case let だけかと思ってた。 let a: Int? = 42 switch a { case let x?: print(x + 1) // 43 default: print("nil") }
Avatar
omochimetaru 3/30/2018 2:24 AM
そういうケースはよく .some(let x) って書いてた。
Avatar
うん、ずっと .some(let x) にしてた。
Avatar
後置letになってる👀
Avatar
omochimetaru 3/30/2018 2:25 AM
xcode補完に流されている・・・
Avatar
以前の rintaro さんの意見を聞いて以来、後置派になりました。
Avatar
omochimetaru 3/30/2018 2:27 AM
x?. の時は ?. だけど x?: の時は x? : なのが紛らわしいな。
2:27 AM
: は演算子には使えない文字なんだっけ。
Avatar
switch (open, close) { case (let open?, let close?): return "\(open)〜\(close)" case (let open?, nil): return "\(open)〜" case (nil, let close?): return "〜\(close)" case (nil, nil): return "" } 最近こんなん書いたけど、?ついてるからややこしいなーと (edited)
Avatar
たしかに .some の方が可読性高い?
Avatar
omochimetaru 3/30/2018 2:28 AM
慣れの問題かもしれんけど見づらいな
Avatar
? ついてると一瞬脳が Optional と認識してしまいそうかも?
2:30 AM
でも if case let a? = aOrNil はうまい表現だと思うんだよなぁ。宣言しているのはあくまで a? が剥がされてる感が。
2:30 AM
本当は Optional Binding も if let a? = aOrNil にしてほしい。
Avatar
Optionalの変数2つをnil or someでパターン網羅したい場合は、if文だとひたすらelse ifでかかなきゃならない?
Avatar
omochimetaru 3/30/2018 2:34 AM
網羅する時はswitchのほうがええでしょうね、網羅性チェックも効くし。
Avatar
だよね
Avatar
omochimetaru 3/30/2018 2:35 AM
if case の1行表記が欲しい
2:35 AM
1行というか式になるやつ。
Avatar
Bool で結果を得たいということ?
Avatar
omochimetaru 3/30/2018 2:40 AM
一番多いのは
2:41 AM
enum Animal { case cat(Cat) case dog ... } ↑で animal: Animal から Cat? を取り出したい (edited)
2:42 AM
現状だと1行で書こうとしても↓これだけかかる run { if case .cat(let x) = animal { return x } else { return nil } } (edited)
Avatar
Cat? を取り出しても、大抵のケースでは結局その後で分岐することになるのでは?
2:44 AM
button.isEnabled = ... みたいなときに Bool がほしいのはある気がする。
Avatar
omochimetaru 3/30/2018 2:44 AM
例えばそれを Observable<Animal> から Observable<Cat>` に変換する時とかにほしいんですよ
2:44 AM
Array<Animal> から Array<Cat> に compactMap するとかでもいいですね。
Avatar
うーん、それは switchif case して return するしかなさそうだなぁ。 (edited)
Avatar
omochimetaru 3/30/2018 2:50 AM
I wanted to circle back to this comment from @Joe_Groff: Has there been any recent discussion about this? I’d love for enums to be a bit more ergonomic via optional-chaining. Key path support would be a nice, free bonus! I can imagine it work...
2:50 AM
enum個別のケースとしては今議論されてる
2:51 AM
マッチング式は今のところ気配が無いけどとりあえずこれが来るとニーズの一つは解消するので助かる
2:51 AM
スレかなり伸びてるなあ
Avatar
conditional conformance は struct に対してだけで protocol に対しては使えないんですね。
3:50 AM
conditional conformance を public にしようとすると 'public' modifier cannot be used with extensions that declare protocol conformances と言われるんですが、なぜそうなってるんでしょう?(でも外からはちゃんと認識されてるっぽい)
3:51 AM
とりあえず多項式環が、係数が体のときにユークリッド環型になるというのができました👍 extension Polynomial: EuclideanRing where R: Field {
👍 1
Avatar
conditionalかに限らずprotocolに制約の後付けはできないはずですね。 https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#conditional-conformances-via-protocol-extensions
swift - The Swift Programming Language
Avatar
仮にprotocolに制約の後付けができるようになるとしたら、それはexistentialに対して行う操作になるのでは (edited)
Avatar
ふむふむ
Avatar
omochimetaru 3/31/2018 4:05 AM
掛け算ができるやつを多項式にすると、余り付き割り算ができるやつが、書けたのか
Avatar
そうです!
Avatar
omochimetaru 3/31/2018 4:10 AM
プロトコルに後付けするんじゃなくて、 絞ったwhere付きのプロトコルを別名で定義するのがやりたい事?
Avatar
今まではそのために係数が割り算ができることを要請しないといけなかったので、整数係数多項式ができなかったんです👍(とても嬉しい)
4:12 AM
protocol に対してもできるのかとナイーブに考えてて、できなかったので「あ、できないのか」と思った感想を呟きましたw
4:12 AM
public にできないのは何故なのか素朴に気になります。
Avatar
omochimetaru 3/31/2018 4:12 AM
あー、プロトコルに対して書いておくと、それに合致するときに満たしてるやつらが自動的に満たすってかきたいのか
Avatar
はい
4:14 AM
抽象論として環をイデアルというもので割るとまた環ができるのですが、このイデアルが「極大イデアル」だと体になるというのがあって、それを書こうとしてできなかったですw
4:15 AM
例えば整数全体を 12 の倍数で割ると時計のような環ができるのですが、割る数が 3 とか 5 とかの素数だと(対応するイデアルが極大になって)割り算もできる体になるんです。
4:16 AM
これをプロトコルのレベルでやろうとしたのですが、できなかったです😂
Avatar
omochimetaru 3/31/2018 4:16 AM
あっ、なんかそれやったことある気がする・・・素数だとうまいことズレて重ならなくて・・・みたいな
👍 1
4:17 AM
うーんそうか基本的にプロトコル準拠はノミナルな型に対して明示的に定義される形になるのか
Avatar
protocolを定義する時に protocol Collection: Sequence みたいに書くのとはまた違う感じでしょうか?
Avatar
omochimetaru 3/31/2018 4:18 AM
例えばOptionalとArrayの、中身がEquatableなときにそれ自体もEquatableであるやつとか、 個別に書かないといけない
Avatar
あー
4:19 AM
一般には出来ないわけか
4:19 AM
Ok
Avatar
omochimetaru 3/31/2018 4:19 AM
両方のモナドに対して、集合をたたみこむ特性をプロトコル化して、一気に共通定義するみたいなことを
😃 1
4:20 AM
タケトさんの発想だとできるが、 現仕様だとできなそう
Avatar
あ、ですです。
Avatar
subprotocol作ってassoctypeがあるならそこに制約入れて…みたいな感じを逐一やっていくしかないですね
Avatar
なるほどなるほど。
Avatar
omochimetaru 3/31/2018 4:24 AM
ジェネリックマニフェストには将来的トピックとして書いてあるのかな? 考えたことないテーマだったけど理解不足で取りこぼしてるかも
4:24 AM
直感的にはそれを許しちゃうと言語の柔軟性にユーザーの頭がついていかない気はする
4:25 AM
IDEが良きに説明してくれたらいいんかな。
Avatar
なんか直感的には出来ない気がしてきたけどまだちゃんとわからん
Avatar
omochimetaru 3/31/2018 4:26 AM
cc @ukitaka
Avatar
ふむふむ、とりあえず僕がやりたかったことは subprotocol を作る方法で行けそうです。ありがとうございます😆 (edited)
Avatar
確かに protocol を自由に拡張できちゃうとめちゃくちゃになりそうですね。
Avatar
protocolのconform自体はできないけど、同じ名前の関数生やしておけば定義だけすれば使える、という感じにはなりそう
Avatar
既出かもしれませんが、エイプリルフールプロポーザル出てますねw https://github.com/CodaFi/swift-evolution/blob/3571229e07a03d8e3a037224267fe6525ff33ed1/proposals/NNNN-lolcode-literals.md
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
Avatar
omochimetaru 4/1/2018 2:23 PM
LOLCODEの文法やばw
Avatar
@swiftbot func bar(foo: int) { func inner(arg: int = foo) {} print(inner()) } bar(foo: 3)
Avatar
swiftbot BOT 4/2/2018 2:24 AM
Swift version 4.1 (swift-4.1-RELEASE) Target: x86_64-unknown-linux-gnu
2:24 AM
/usercode/main.swift:1:15: error: use of undeclared type 'int' func bar(foo: int) { ^~~ /usercode/main.swift:2:21: error: use of undeclared type 'int' func inner(arg: int = foo) {} ^~~
Avatar
@swiftbot func bar(foo: Int) { func inner(arg: Int = foo) {} print(inner()) } bar(foo: 3)
Avatar
swiftbot BOT 4/2/2018 2:25 AM
Swift version 4.1 (swift-4.1-RELEASE) Target: x86_64-unknown-linux-gnu
2:25 AM
swift: /home/buildnode/jenkins/workspace/oss-swift-4.1-package-linux-ubuntu-16_04/swift/lib/SILGen/SILGenGlobalVariable.cpp:64: bool isGlobalLazilyInitialized(swift::VarDecl *): Assertion `!var->getDeclContext()->isLocalContext() && "not a global variable!"' failed. /usr/bin/swift[0x3f24d54] /usr/bin/swift[0x3f25096] /lib/x86_64-linux-gnu/libpthread.so.0(+0x11390)[0x7f15d2b98390] /lib/x86_64-linux-gnu/libc.so.6(gsignal+0x38)[0x7f15d12d7428] /lib/x86_64-linux-gnu/libc.so.6(abort+0x16a)[0x7f15d12d902a] /lib/x86_64-linux-gnu/libc.so.6(+0x2dbd7)[0x7f15d12cfbd7] /lib/x86_64-linux-gnu/libc.so.6(+0x2dc82)[0x7f15d12cfc82] /usr/bin/swift[0xc929db] /usr/bin/swift[0xc6a1e3] /usr/bin/swift[0xc6af00] /usr/bin/swift[0xc7448c] /usr/bin/swift[0xc69ee4] /usr/bin/swift[0xcc47f6] /usr/bin/swift[0xc91f8d] /usr/bin/swift[0xc2e86b] /usr/bin/swift[0xc2c51b] /usr/bin/swift[0xc2b847] /usr/bin/swift[0xcc1225] /usr/bin/swift[0xcc106e] /usr/bin/swift[0xc8fec5] /usr/bin/swift[0xc33515] /usr/bin/swift[0xc2ba85] /usr/bin/swift[0xc30f7b] /usr/bin/swift[0xc31c46] /usr/bin/swift[0xc3221d] /usr/bin/swift[0x4c27c4] /usr/bin/swift[0x4beecc] /usr/bin/swift[0x4778c4] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f15d12c2830] /usr/bin/swift[0x475179] Stack dump: 0. Program arguments: /usr/bin/swift -frontend -interpret /usercode/main.swift -disable-objc-interop -module-name main 1. While emitting SIL for 'bar(foo:)' at /usercode/main.swift:1:1 2. While silgen emitFunction SIL function "@_T04main3barySi3foo_tF". for 'bar(foo:)' at /usercode/main.swift:1:1 3. While silgen emitDefaultArgGenerator SIL function "@_T04main3barySi3foo_tF5innerL_ySi3arg_tFfA_". for expression at [/usercode/main.swift:2:27 - line:2:27] RangeText="f" Aborted (core dumped)
Avatar
壊れた
Avatar
omochimetaru 4/2/2018 2:25 AM
コンパイラこわれた
2:26 AM
Assertion !var->getDeclContext()->isLocalContext() && "not a global variable!"' failed. (edited)
2:27 AM
innerのfooがローカルコンテキストではないと期待してるけど、実際には外側のbarのローカル変数だから
2:27 AM
アサーションがこける?
Avatar
omochimetaru 4/2/2018 2:30 AM
bugs行きで良いと思います
Avatar
🙆
Avatar
omochimetaru 4/2/2018 2:31 AM
その上で、そのあたりのコードを読んで、適切な修正を試みると楽しいかもしれない・・・
Avatar
楽しそう
Avatar
Taketo Sano 4/2/2018 2:36 AM
conditional conformance 使ってガシガシ重複コードを削ってくと、いよいよ generic な extension が欲しくなってきますね🤓 (edited)
Avatar
条件付きでprotocolにconformするprotocolだと思う
2:38 AM
昨日一日考えたのですが、コンパイルが終わらなくなるケースがあって難しそうだなと思いました
Avatar
omochimetaru 4/2/2018 2:40 AM
これはできる・・・ struct Stone {} extension Stone { func aaa<T>(_ t: T) {} }
Avatar
protocol A {} protocol B {} protocol C {} extension A: B where Self: C {} extension B: C where Self: A {} extension C: A where Self: B {}
2:41 AM
仮にできたとして、↑が解けなくなりそう
2:43 AM
あれっ
2:43 AM
genericなextensionになってるw
2:43 AM
違う話かな
Avatar
omochimetaru 4/2/2018 2:43 AM
@Taketo Sano 欲しい記法を詳しく教えてくださいw
Avatar
Kishikawa Katsumi 4/2/2018 2:54 AM
@swiftbot versions
Avatar
swiftbot BOT 4/2/2018 2:54 AM
Available Swift versions: 2018-03-31-a 4.1 4.0.3 3.1.1 3.0.2
Avatar
Kishikawa Katsumi 4/2/2018 2:54 AM
@swiftbot —version 2018-03-31-a func bar(foo: Int) { func inner(arg: Int = foo) {} print(inner()) } bar(foo: 3)
Avatar
swiftbot BOT 4/2/2018 2:54 AM
Swift version 4.1 (swift-4.1-RELEASE) Target: x86_64-unknown-linux-gnu
2:54 AM
swift: /home/buildnode/jenkins/workspace/oss-swift-4.1-package-linux-ubuntu-16_04/swift/lib/SILGen/SILGenGlobalVariable.cpp:64: bool isGlobalLazilyInitialized(swift::VarDecl *): Assertion `!var->getDeclContext()->isLocalContext() && "not a global variable!"' failed. /usr/bin/swift[0x3f24d54] /usr/bin/swift[0x3f25096] /lib/x86_64-linux-gnu/libpthread.so.0(+0x11390)[0x7f6befe6f390] /lib/x86_64-linux-gnu/libc.so.6(gsignal+0x38)[0x7f6bee5ae428] /lib/x86_64-linux-gnu/libc.so.6(abort+0x16a)[0x7f6bee5b002a] /lib/x86_64-linux-gnu/libc.so.6(+0x2dbd7)[0x7f6bee5a6bd7] /lib/x86_64-linux-gnu/libc.so.6(+0x2dc82)[0x7f6bee5a6c82] /usr/bin/swift[0xc929db] /usr/bin/swift[0xc6a1e3] /usr/bin/swift[0xc6af00] /usr/bin/swift[0xc7448c] /usr/bin/swift[0xc69ee4] /usr/bin/swift[0xcc47f6] /usr/bin/swift[0xc91f8d] /usr/bin/swift[0xc2e86b] /usr/bin/swift[0xc2c51b] /usr/bin/swift[0xc2b847] /usr/bin/swift[0xcc1225] /usr/bin/swift[0xcc106e] /usr/bin/swift[0xc8fec5] /usr/bin/swift[0xc33515] /usr/bin/swift[0xc2ba85] /usr/bin/swift[0xc30f7b] /usr/bin/swift[0xc31c46] /usr/bin/swift[0xc3221d] /usr/bin/swift[0x4c27c4] /usr/bin/swift[0x4beecc] /usr/bin/swift[0x4778c4] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f6bee599830] /usr/bin/swift[0x475179] Stack dump: 0. Program arguments: /usr/bin/swift -frontend -interpret /usercode/main.swift -disable-objc-interop -module-name main 1. While emitting SIL for 'bar(foo:)' at /usercode/main.swift:1:1 2. While silgen emitFunction SIL function "@_T04main3barySi3foo_tF". for 'bar(foo:)' at /usercode/main.swift:1:1 3. While silgen emitDefaultArgGenerator SIL function "@_T04main3barySi3foo_tF5innerL_ySi3arg_tFfA_". for expression at [/usercode/main.swift:2:27 - line:2:27] RangeText="f" Aborted (core dumped)
Avatar
Kishikawa Katsumi 4/2/2018 2:59 AM
@swiftbot --version=2018-03-31-a func bar(foo: Int) { func inner(arg: Int = foo) {} print(inner()) } bar(foo: 3)
Avatar
swiftbot BOT 4/2/2018 2:59 AM
Swift version 4.2-dev (LLVM 0d52728a8a, Clang 1d3cad1e6b, Swift 6c42bcccbd) Target: x86_64-unknown-linux-gnu
2:59 AM
swift: /home/buildnode/jenkins/workspace/oss-swift-package-linux-ubuntu-16_04/swift/lib/SILGen/SILGenGlobalVariable.cpp:64: bool isGlobalLazilyInitialized(swift::VarDecl *): Assertion `!var->getDeclContext()->isLocalContext() && "not a global variable!"' failed. /usr/bin/swift[0x411c854] /usr/bin/swift[0x411cb96] /lib/x86_64-linux-gnu/libpthread.so.0(+0x11390)[0x7f64a8588390] /lib/x86_64-linux-gnu/libc.so.6(gsignal+0x38)[0x7f64a6cc7428] /lib/x86_64-linux-gnu/libc.so.6(abort+0x16a)[0x7f64a6cc902a] /lib/x86_64-linux-gnu/libc.so.6(+0x2dbd7)[0x7f64a6cbfbd7] /lib/x86_64-linux-gnu/libc.so.6(+0x2dc82)[0x7f64a6cbfc82] /usr/bin/swift[0xcb8bb3] /usr/bin/swift[0xc8d123] /usr/bin/swift[0xc8dde3] /usr/bin/swift[0xc9e360] /usr/bin/swift[0xc8cef4] /usr/bin/swift[0xcecb34] /usr/bin/swift[0xcb8091] /usr/bin/swift[0xc4fb59] /usr/bin/swift[0xc4d64f] /usr/bin/swift[0xc4c878] /usr/bin/swift[0xce96b5] /usr/bin/swift[0xce94fe] /usr/bin/swift[0xcb5f5b] /usr/bin/swift[0xc54c84] /usr/bin/swift[0xc4cb25] /usr/bin/swift[0xc525bb] /usr/bin/swift[0xc53266] /usr/bin/swift[0xc5385d] /usr/bin/swift[0x4d820d] /usr/bin/swift[0x4d4b9c] /usr/bin/swift[0x48a26d] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f64a6cb2830] /usr/bin/swift[0x487ac9] Stack dump: 0. Program arguments: /usr/bin/swift -frontend -interpret /usercode/main.swift -disable-objc-interop -module-name main 1. While emitting SIL for 'bar(foo:)' at /usercode/main.swift:1:1 2. While silgen emitFunction SIL function "@$S4main3bar3fooySi_tF". for 'bar(foo:)' at /usercode/main.swift:1:1 3. While silgen emitDefaultArgGenerator SIL function "@$S4main3bar3fooySi_tF5innerL_3argySi_tFfA_". for expression at [/usercode/main.swift:2:27 - line:2:27] RangeText="f" Aborted (core dumped)
Avatar
Kishikawa Katsumi 4/2/2018 3:00 AM
最新のスナップショットでも同じか。iPhoneからだとダブルハイフンがダッシュに変わってしまう。。。
Avatar
最新のスナップショットが手軽に試せるの最高ですね
Avatar
そっかiPhoneからでも試せるのか…
Avatar
Kishikawa Katsumi 4/2/2018 3:06 AM
コードを全部入れるのは大変だけど、元になるのがあればコピーペーストできるから簡単。
Avatar
@omochimetaru 多分↓これのことじゃない? < 欲しい記法 https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#parameterized-extensions (edited)
swift - The Swift Programming Language
Avatar
omochimetaru 4/2/2018 3:14 AM
それっぽい
Avatar
これほんとにほしくて、 func foo<T>(_ array: [T?]) -> [T] { ... } はできるのに↓ができないのは、関数よりもメソッドを優先する Swift としては明らかな言語仕様的不足。 extension<T> Array where Wrapped == T? { func foo() -> [T] { ... } }
Avatar
omochimetaru 4/2/2018 3:21 AM
あーたしかに・・・
Avatar
omochimetaru 4/2/2018 3:33 AM
ワイもOptionalConvertible.swift書いてある
Avatar
OptionalProtocol 、昔は where T == Int? とかでも必要だったけどこれは解消してマシになったんですけど、まだ == T? が書けないんですよねぇ。
3:44 AM
これがないから compactMap の Proposal に書かれてる compact も実装できない・・・。 https://github.com/apple/swift-evolution/blob/master/proposals/0187-introduce-filtermap.md
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
Avatar
Taketo Sano 4/2/2018 3:58 AM
@koher それです!!!
3:58 AM
Parameterized extensions という名前だったんですね、適当な呼び方してしまってすいません😉
Avatar
omochimetaru 4/2/2018 3:59 AM
↑のOptionalProtocolでのワークアラウンドみたいにすることで
3:59 AM
taketoさんのユースケースで目的が果たせる可能性があります (edited)
Avatar
Taketo Sano 4/2/2018 3:59 AM
ふむふむ?
Avatar
omochimetaru 4/2/2018 3:59 AM
↓これは書けないけど extension<T> Array where Element == T? { func foo() -> [T] { ... } } (edited)
Avatar
Taketo Sano 4/2/2018 4:00 AM
Wrapped は Element のことです?
Avatar
omochimetaru 4/2/2018 4:00 AM
これは書けるので使い勝手としては同じ事ができます extension Array where Element: OptionalConvertible { ... } extension Optional : OptionalConvertble { ... } (edited)
4:00 AM
あ、ですね
Avatar
Taketo Sano 4/2/2018 4:01 AM
OptionalConvertble というのは?
Avatar
omochimetaru 4/2/2018 4:02 AM
public protocol OptionalConvertible { associatedtype _Wrapped func asOptional() -> Optional<_Wrapped> } extension Optional : OptionalConvertible { public func asOptional() -> Optional<Wrapped> { return self } }
Avatar
Taketo Sano 4/2/2018 4:05 AM
すいません、これが必要となるケースがあまりわかってないです🤔
Avatar
omochimetaru 4/2/2018 4:06 AM
あとで整理しますね
Avatar
Taketo Sano 4/2/2018 4:06 AM
すいません🙏
4:09 AM
ちなみに自分がやろうとしてできなかったのは、cond. conf. + typealias でできるだけ新しく型を作るのを抑えようとしていたのですが、 public protocol EquivalenceRelation { .. } public struct QuotientSet<X, Rel: EquivalenceRelation>: SetType where X == Rel.Base { .. } public struct ModSubgroupRelation<H: Subgroup>: EquivalenceRelation { .. } public typealias QuotientGroup<G, H: Subgroup> = QuotientSet<G, ModSubgroupRelation<H>> where G == H.Super extension QuotientGroup: Group where X: Group, Rel: ModSubgroupRelation<H> // あっ
4:10 AM
typealias するときに型を包むと、包んだ後のものについては cond. conf. が使えないということに気づいたのでした。 (edited)
4:15 AM
抽象化するとこうなると思います: protocol A {} struct X<T: A> {} struct B<S>: A{} typealias Y<S> = X<B<S>> extension<S> Y where T == B<S> { .. } // コレ (edited)
4:16 AM
generic に typealias した Y を新しい型だと思いたいのですが、そうすると extension できないという。
Avatar
こんな感じでしょうか? protocol A {} struct X<T: A> {} struct B<S>: A{} typealias Y<S> = X<B<S>> protocol BProtocol: A { associatedtype _S var bValue: B<_S> { get } } extension B : BProtocol { var bValue: B<S> { return self } } extension X where T : BProtocol { // これがやりたい }
Avatar
Taketo Sano 4/2/2018 4:33 AM
おぉ…😲
4:34 AM
これが上の Optional のと同じことをしてるんですね…(まだ飲み込めてない
Avatar
extension<S> Y where T == B<S>extension<S> X where T == B<S> と同じ意味になると思います。
Avatar
Taketo Sano 4/2/2018 4:34 AM
そうですね。
Avatar
さっきの Optional の話と合わせると BProtocolBConvertible とした方がよかったかもしれません。
4:35 AM
BProtoclB に変換できるので実質的に B のように扱えます。
Avatar
Taketo Sano 4/2/2018 4:36 AM
B<S> に対応する protocol を一段かませばいけるってことか!
4:36 AM
ちとやってみます🤓👍 (edited)
🙂 1
Avatar
Taketo Sano 4/2/2018 4:45 AM
public protocol _ModSubgroupRelation: EquivalenceRelation where Base == Sub.Super { associatedtype Sub: Subgroup } public struct ModSubgroupRelation<H: Subgroup>: _ModSubgroupRelation { public typealias Base = H.Super public typealias Sub = H ... } public typealias QuotientGroup<G, H: Subgroup> = QuotientSet<G, ModSubgroupRelation<H>> where G == H.Super extension QuotientGroup: Group where Rel: _ModSubgroupRelation, X == Rel.Base { ... } できたっぽいです!
Avatar
おおっ😀
4:47 AM
あ、多分 _ModSubgroupRelation プロトコルから ModSubgroupRelation を取り出すメソッドかプロパティをつけないといけないと思います。 (edited)
Avatar
Taketo Sano 4/2/2018 4:56 AM
そうですね、なんか今上手く行ってないですw
4:57 AM
あ、いや、大丈夫でした。
4:57 AM
ModSubgroupRelation は static method を一個持ってるだけで、インスタンスとして使われることのないものです。
4:58 AM
同値関係を型で与えて QuotientSet に埋め込むという。
4:59 AM
しかしこの書き方が分かりやすいかは怪しい気がしてきたので、ここはいくつかで実装を分ける方向で行こうかなと思います😅アドバイスありがとうございました!
Avatar
@Taketo Sano 現状の Swift でうまく抽象化できずに類似コードを何度も書かないといけないケースでは、僕らは gyb (という Swift コンパイラでも使われている)ツールを使ってコードジェネレーションに逃げてることが多いですね😅 https://qiita.com/omochimetaru/items/422ddd04e95c55dd3833#gyb

メタプログラミングとテンプレートエンジン

プログラミングにおいて、そのプログラミング言語の機能だけではプログラムを書くのが大変だったり難しいときに、外部のツールな...
Avatar
Taketo Sano 4/2/2018 5:28 AM
なるほどなるほど。
Avatar
Taketo Sano 4/2/2018 6:56 AM
protocol P{} struct A<T> {} extension A: P where T == Int {} extension A: P where T == String {} // error: redundant conformance of 'A<T>' to protocol 'P' 異なる条件でも同じ protocol への conformance はできないんですね…🙍 (edited)
Avatar
それやろうとすると
7:00 AM
protocol IntOrString {} extension Int: IntOrString {} extension String: IntOrString {} extension A: P where T: IntOrString {} みたいに回り道が必要になりますねぇ
Avatar
Taketo Sano 4/2/2018 7:00 AM
ですよね😿
Avatar
Taketo Sano 4/3/2018 2:17 AM
こういうのもエラーになることが分かりました。 @swiftbot protocol A {} protocol B: A {} protocol C: A {} protocol D: B, C {} struct X<T>: A{} extension X: D where T == Int { // Type 'X<T>' does not conform to protocol 'B' }
Avatar
swiftbot BOT 4/3/2018 2:17 AM
Swift version 4.1 (swift-4.1-RELEASE)
2:17 AM
/usercode/main.swift:7:1: error: type 'X<T>' does not conform to protocol 'B' extension X: D where T == Int { // Type 'X<T>' does not conform to protocol 'B' ^ /usercode/main.swift:4:10: note: type 'X<T>' does not conform to inherited protocol 'B' protocol D: B, C {} ^
Avatar
Taketo Sano 4/3/2018 2:18 AM
こうしないと行けない @swiftbot protocol A {} protocol B: A {} protocol C: A {} protocol D: B, C {} struct X<T>: A{} extension X: B where T == Int {} extension X: C where T == Int {} extension X: D where T == Int {}
Avatar
swiftbot BOT 4/3/2018 2:18 AM
Swift version 4.1 (swift-4.1-RELEASE)
Avatar
Taketo Sano 4/3/2018 2:18 AM
エラーメッセージがこれと気づきにくいので時間が溶けがち😔
2:21 AM
D で B の要求を C を使って protocol extension で実装する、というようなことがこれだとできない☹
2:24 AM
@swiftbot protocol A {} protocol B: A {} protocol C: A {} protocol D: B, C {} struct X<T>: A{} extension X: B, C, D where T == Int {}
Avatar
swiftbot BOT 4/3/2018 2:24 AM
Swift version 4.1 (swift-4.1-RELEASE)
Avatar
Taketo Sano 4/3/2018 2:25 AM
これでいけることが明らかになりました😆
2:25 AM
ちゃんと継承の順番通りに並べて書けばいいらしい。
Avatar
Taketo Sano 4/3/2018 3:30 AM
だいぶ慣れて来ました👍 extension BilinearMap: VectorSpace, BilinearMapType where Domain: ProductSetType & VectorSpace, Domain.Left: VectorSpace, Domain.Right: VectorSpace, Codomain: VectorSpace, Domain.CoeffRing == Codomain.CoeffRing, Domain.CoeffRing == Domain.Left.CoeffRing, Domain.CoeffRing == Domain.Right.CoeffRing {
Avatar
すごい Constraints だ・・・
Avatar
Taketo Sano 4/3/2018 3:42 AM
parametrized extension ができるようになればもっとシンプルに書けるんですが…w
3:43 AM
extension <V1: VectorSpace, V2: VectorSpace, W: VectorSpace> BilinearMap: BilinearMapType where Domain == ProductVectorSpace<V1, V2>, Domain.CoeffRing == Codomain.CoeffRing { } これで済むと思います。
🙄 1
Avatar
はやくサポートされてほしいですねぇ。昨日 parameterized extension がないと対応しようがない問題にぶち当たって(サポートする型を列挙しようがない)、トリッキーな方法で回避しないといけませんでした・・・。
Avatar
Taketo Sano 4/3/2018 3:45 AM
誠に待ち望ましいです😂
Avatar
メソッドではなく関数なら問題ないので、数学なら演算子で逃げるという手もあるかもしれませんね。
Avatar
Taketo Sano 4/3/2018 3:47 AM
それは結構辛い感じになりそう…
Avatar
extension<T> Array where Element == Optional<T> { func compact() -> Array<T> { ... } } の代わりに func compact<T>(_ array: Array<Optional<T>>) -> Array<T> { ... } になりますが、関数だと記述順が辛いところを
3:48 AM
演算子だと instance operator parameter の順に書けるのでメソッドっぽくなります。
3:48 AM
ただ、その操作に数学で一般的な演算子の記号がないと辛いことになりそうですね😅
3:49 AM
(一般的な演算子の記号があるならすでに演算子で実装されてますよね・・・) (edited)
Avatar
omochimetaru 4/3/2018 3:51 AM
関数後置演算子という魔法・・・
Avatar
Taketo Sano 4/3/2018 3:51 AM
読むの不可能なコードができあがりそうですw
Avatar
omochimetaru 4/3/2018 3:51 AM
func |> (a, b) { return b(a) }
Avatar
Taketo Sano 4/3/2018 3:54 AM
上の大量の constraint つきのコードビルドしたら Segmentation fault になりました 😂
😂 3
Avatar
Taketo Sano 4/3/2018 4:05 AM
これが原因らしい… 🔪 public typealias BilinearForm<V: VectorSpace> = BilinearMap<V, V, AsVectorSpace<V.CoeffRing>> extension BilinearForm: BilinearFormType where Domain: ProductSetType & VectorSpace, Domain.Left: VectorSpace, Domain.Left == Domain.Right, Domain.CoeffRing == Domain.Left.CoeffRing, Codomain == AsVectorSpace<Domain.CoeffRing> { }
Avatar
typealias に対して extension を書かない方がいいかもしれませんね。
Avatar
Taketo Sano 4/3/2018 4:22 AM
元のものに戻してもダメでした 😫
😣 1
Avatar
コンパイラクラッシュはなんにせよバグなので、最小際限ケースがわかればバグレポートするのがいいのですが・・・(誰かが直してくれる可能性がある)
Avatar
Taketo Sano 4/3/2018 4:26 AM
SegFault の原因を探るのってどうしたらいいんでしょう?w
4:26 AM
Contribute to SwiftyAlgebra development by creating an account on GitHub.
Avatar
僕は徐々にコードをシンプルにしていきながら問題が発生する限界を見極めますが、もっと良い方法があるかもしれません。
Avatar
Taketo Sano 4/3/2018 4:27 AM
該当部分を消せばコンパイルが通るので、原因は確実にそれなんですが…
Avatar
既存プロジェクトでやると大きすぎて原因特定が大変なので、似たようなコードを単独の swift ファイルで作成し、同じ状況を作り上げるところから始めて、徐々にコードを削りながらバグが際限する最小ケースを探すという手順が良いんじゃないかと思います。
4:31 AM
(そこまでするかどうかですが😅
Avatar
Taketo Sano 4/3/2018 4:47 AM
上のはやりすぎに思えてきたので、諦めて途中段階の struct をもう一個作ることにしましたw
🙂 1
Avatar
元々特殊化された generic タイプ に対する extension は認められていないので、 typealias も extension 付けられません。
5:15 AM
@swiftbot class C<T> {} typealias IntC = C<Int> extension IntC {}
Avatar
swiftbot BOT 4/3/2018 5:15 AM
Swift version 4.1 (swift-4.1-RELEASE)
5:15 AM
/usercode/main.swift:3:1: error: constrained extension must be declared on the unspecialized generic type 'C' with constraints specified by a 'where' clause extension IntC {} ^ ~~~~
Avatar
https://bugs.swift.org/browse/SR-4875 でも generic パラメータ付きの typealias が素通りしてしまうバグがあります。
Avatar
Taketo Sano 4/3/2018 5:53 AM
なるほど、バグなんですね!
5:53 AM
素通りするから認められてるものと思っていました。
5:54 AM
ありがとうございます🙏
Avatar
ただ、このバグは generic パラメータが無視されるだけなので、 segfault はまた別のバグですね。
Avatar
norio_nomura 4/5/2018 2:28 AM
@swiftbot #if swift(>=4.1.0) let version = "4.1.0" #elsif swift(>=4.0.3) // it should be `elseif` let version = "4.0.3" #endif
Avatar
swiftbot BOT 4/5/2018 2:28 AM
Swift version 4.1 (swift-4.1-RELEASE)
2:28 AM
/usercode/main.swift:3:9: error: expected expression #elsif swift(>=4.0.3) // it should be `elseif` ^ /usercode/main.swift:4:17: error: invalid redeclaration of 'version' let version = "4.0.3" ^ /usercode/main.swift:2:17: note: 'version' previously declared here let version = "4.1.0" ^
Avatar
norio_nomura 4/5/2018 2:30 AM
@swiftbot --options=-swift-version 3 #if swift(>=4.1.0) let version = "4.1.0" #elsif swift(>=4.0.3) // it should be `elseif` let version = "4.0.3" #endif
Avatar
swiftbot BOT 4/5/2018 2:30 AM
Swift version 4.1 (swift-4.1-RELEASE)
2:30 AM
error: failed to launch REPL process: process launch failed: 'A' packet returned an error: 8
Avatar
norio_nomura 4/5/2018 2:30 AM
@swiftbot --options="-swift-version 3" #if swift(>=4.1.0) let version = "4.1.0" #elsif swift(>=4.0.3) // it should be `elseif` let version = "4.0.3" #endif
Avatar
swiftbot BOT 4/5/2018 2:30 AM
Swift version 4.1 (swift-4.1-RELEASE)
Avatar
norio_nomura 4/5/2018 2:31 AM
-swift-version 3が付いた時に#elsifってのがそのまま通ってしまうぽい?
Avatar
#if から #endif の間が swift(>=4.1.0) じゃないので、パースの対象外になるので、
2:34 AM
無視されますね。
Avatar
norio_nomura 4/5/2018 2:34 AM
なるほど…
Avatar
手元のplaygroundsでも通りましたけどversionが参照できなかったです
Avatar
norio_nomura 4/5/2018 2:36 AM
このtypoに気づけなくて、何か対策コードを書けないかと思ったのだけれど、難しそう。 https://github.com/realm/SwiftLint/pull/2143/commits/2ab42cdec10ae6c3ff5839d498500103a92b932c
Avatar
そのあとに_ = version書いとけば判定はできそうですね。 一般的には使えなそうですが。
Avatar
norio_nomura 4/5/2018 2:39 AM
SourceKitへ渡すソースなので、コンパイルされない文字列なのですよね。 (edited)
😫 1
Avatar
パースの対象とするか否かを、現在の言語モードではなく、コンパイラの対応バージョンで決定するべきだ。という主張は出来ると思います。
2:41 AM
つまり -swift-version 3 でも 4.2 対応のコンパイラなら swift(>=4.1.0)false だけども内容はパースする。
Avatar
norio_nomura 4/5/2018 2:43 AM
その場合、canImport()とかの新しい条件が含まれてた時にエラーになったりしないですかね。
Avatar
そういうのも含めて考慮すべき点はいくつかあると思います。
Avatar
norio_nomura 4/5/2018 2:45 AM
Swiftのドキュメントを確認しようとしたらリンク切れになってた。 https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/index.html
2:47 AM
The definitive guide to Swift, Apple’s programming language for building iOS, macOS, watchOS, and tvOS apps.
Avatar
norio_nomura 4/5/2018 2:56 AM
つまり -swift-version 3 でも 4.2 対応のコンパイラなら swift(>=4.1.0) は false だけども内容はパースする。 コードが想定する対応バージョンのコンパイラでちゃんとテストしろ、で済んでしまう問題ではあるのですよね…
Avatar
fatalErrorとpreconditionFailureって明確なルールをもって使い分けてる方いたらどういうふうにやってるか知りたいです
Avatar
omochimetaru 4/9/2018 7:43 AM
完全には明確じゃないけど
7:43 AM
preconditionFailureってそもそもあんまり使わなくて
7:43 AM
preconditionで書けるならそのほうがいいから(削除時に分岐ごと消えるカラーとして
7:43 AM
preconditionFailure自体の使い所にあまり出会わないけど
7:44 AM
使う場合はやっぱりそこに突入するのが事前条件違反での死の場合で (edited)
7:44 AM
fatalErrorはそこで死ぬ事自体が関数の機能な場合に使うようにしてる
Avatar
ふむ
7:45 AM
僕はおもちが「それは強制アンラップでいい」って言いそうなシーンでfatalErrorを使って、アプリ固有のロジック上ここにはいることはありえないみたいな時にpreconditionFailureを使うようにしてる
Avatar
omochimetaru 4/9/2018 7:46 AM
あ、まさにそれだ
7:46 AM
extension Optional { public func unwrap(_ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) -> Wrapped { guard let value = self else { let m = message() fatalError("Optional unwrap failed" + (!m.isEmpty ? ": " + m : ""), file: file, line: line) } return value }
7:46 AM
↑今使ってるやつだけど、強制アンラップだと、ヒント情報が付けられないのが気に食わないのでこれを使ってて
7:46 AM
これは違反時に死ぬ事自体が明確な機能だからfatalErrorで書いてるわ
Avatar
guard let tableView = tableViewController.tableView else { fatalError("UITableViewControllerじゃなくなった?") }
7:47 AM
とか
Avatar
omochimetaru 4/9/2018 7:47 AM
let tableView = tableViewController.tableView.unwrap("UITableViewControllerじゃなくなった?") ↑こうかいたほうがよくない?
Avatar
あまり差はなく感じる
Avatar
omochimetaru 4/9/2018 7:47 AM
1行と3行
Avatar
これはguardであるということは主張しておきたい
7:47 AM
って前もこんな話したなw
Avatar
omochimetaru 4/9/2018 7:48 AM
それがノイズなんだよね
7:48 AM
えっと、
7:48 AM
guardであることをコードリーダーが「読むたびに」把握するべきことなのか
7:48 AM
「問題発生時に解析可能であればいい」のか
7:48 AM
の違いだと思ってて
7:49 AM
一般的なguard(returnするケース)は、アプリケーションロジックだから
7:49 AM
コードで表されたアプリケーション仕様だから、把握しておく必要があるんだけど
7:49 AM
!とか、死ぬケースっていうのは、把握しておく必要はないはずなんだよね
7:49 AM
なぜなら書いた時にそれが起こらない事が「検証済みなはず」で
7:49 AM
それについてはもう忘れて良いはずだから。
7:50 AM
で、それについて思い出すのは、テストして落ちた時でいい。
Avatar
それはそのメソッドの実装者も利用者も一人だけのときでないと無理じゃない?
Avatar
omochimetaru 4/9/2018 7:50 AM
いや、そんなことないでしょ
7:50 AM
「メソッドの利用者はメソッドの前提条件を知らねばならない」から。
7:51 AM
どんな使い方のメソッドなのか理解してから使うものでしょ。
Avatar
何らかの改修があったときに機能まで検証済みだった前提が壊れてないかをチェックするのにguardキーワードはあってほしいけどなあ
Avatar
omochimetaru 4/9/2018 7:51 AM
その前提がおけなくて、「型検査で通る呼び出しはなんでもされうる」っていうシナリオなら、まあそうだけど、それって厳しいケースがたくさん出てきそう
7:52 AM
そういうパターンは
7:52 AM
そもそも実行テストで洗い出さないといかんやん。
Avatar
ふむ〜
7:53 AM
非同期処理とか絡んでくると全パターン完全に網羅するの無理だとおもうんだよなあ
Avatar
omochimetaru 4/9/2018 7:54 AM
無理だからこそ
7:54 AM
頭で把握しようとしても無理なので
7:54 AM
どうせ実行テストしないといけなくて
7:55 AM
実行テストで洗い出せるようになってれば、 コードとしては3行じゃなくて1行にすませてスッキリさせといたほうが
7:55 AM
読みやすい分お得
7:55 AM
みたいな。
7:55 AM
あ、でもそもそも
7:56 AM
!相当のクラッシュとかは、メソッド冒頭に集めてあるイメージではある
7:56 AM
うーんまあそれは関係ないか?
Avatar
まあ早期離脱やでな
Avatar
omochimetaru 4/9/2018 7:58 AM
fatalErrorで殺す場合を想定してる、 returnで脱出場合はguard書くよ(ってかメソッドにできないし
7:59 AM
てかもともとの fatalError vs preconditionFailure の話でいうと、 (edited)
7:59 AM
さっきみたいに unwrap メソッドにしちゃうと
7:59 AM
それがprecondition的呼び出しかどうかはわからないせいで
7:59 AM
fatalErrorになっちゃうって問題はあるんだよね
8:00 AM
func preconditionNotNone<T>(_ t: T?) -> T
8:00 AM
これ作ったこともある。これは内部で preconditionFailureで死ぬ。
Avatar
Taketo Sano 4/9/2018 1:40 PM
四元数の掛け算の一部: let x = a.x * b.x - a.y * b.y - a.z * b.z - a.w * b.w が Expression was too complex... と言われて辛い😵 なぜかこうすると通るようにはなる… let x = a.x * b.x - (a.y * b.y + a.z * b.z + a.w * b.w)
1:41 PM
Swift3 の頃は true && true && true とかやるだけで出てた気がするのでだいぶ良くはなったんだと思いますが🙄
Avatar
Kishikawa Katsumi 4/9/2018 1:41 PM
これは演算子のオーバーロードですかね。
Avatar
Taketo Sano 4/9/2018 1:41 PM
はい、そうです。
Avatar
Kishikawa Katsumi 4/9/2018 1:41 PM
まあ、辛さはわかります。
😥 1
Avatar
Taketo Sano 4/9/2018 1:41 PM
でもここに出てくる a.x たちの型は決まってるものなので、そう複雑でもないように人間の目には見えるんですが。 (edited)
Avatar
演算子のoverloadの解決が、二要素の総当たりで型を推論して、それが重なりあったときに冪乗で計算量が増えてしまう、だった気がする
Avatar
Kishikawa Katsumi 4/9/2018 1:43 PM
演算子は結構難しいと思うんですよね。カッコをつけたら通るというのは型もそうですけど結合順位の解決が大変なんじゃ無いですか。
Avatar
==と&&もそんな感じでおそい
Avatar
結合順位って演算子ごとに決まってないですっけ?
Avatar
ここがConditionalConformanceでワンチャンはやくなるのでは?と思ってるんですが試してないな (edited)
Avatar
Kishikawa Katsumi 4/9/2018 1:44 PM
コントロールできたでしょ。
1:44 PM
違ったっけ。
Avatar
Taketo Sano 4/9/2018 1:44 PM
演算子ごとに固定だと思います(カスタム演算子は自分で設定できる)
Avatar
Kishikawa Katsumi 4/9/2018 1:45 PM
なるほど、+ とか-は変更できないのか。
1:45 PM
じゃあなんだろ。型なのかな。
Avatar
x, y, z, w の型が定まってるなら組み合わせなさそうですけどねー🤔
1:46 PM
リテラルだと ExpressibleByXxxLiteral で組み合わせ爆発するけど(ここが Swift 特有の問題だと思ってます)、この場合はどうしてだろう・・・。 (edited)
Avatar
局所的には複数の演算子にマッチし得て、式全体を通してみると一意に決定されるとか? (edited)
Avatar
Taketo Sano 4/9/2018 1:49 PM
𝐑 * 𝐑 は一通りしかないはずなんですよね…
1:50 PM
𝐑 * M みたいな感じで係数になりうるケースはあるので、その辺がマッチしちゃってるんだと思うんですが…
Avatar
𝐑 の正体は何者ですか? Double
Avatar
Taketo Sano 4/9/2018 1:51 PM
Double を wrap した struct です。
Avatar
うーん、プロトコルじゃないんですね。なら一意に定まりそうですねぇ。
1:53 PM
𝐑 * 𝐑 は一通りしかないはずなんですよね… 𝐑 * M みたいな感じで係数になりうるケースはあるので、その辺がマッチしちゃってるんだと思うんですが…
𝐑 * 𝐑 ではなく𝐑 * ? で探索始めちゃってるんですかねぇ?コンパイラの内部の挙動を確認しないとわからなさそう・・・。
Avatar
@ukitaka
1:53 PM
型推論の優先順位を見れるのがありましたよね、あれに通すと何かわかるかも
Avatar
Taketo Sano 4/9/2018 1:54 PM
おぉ、そんな機能が
Avatar
あってるかわかりませんが
2:01 PM
public static func -(a: 𝐑, b: 𝐑) -> 𝐑 { return 𝐑(a.value - b.value, a.error + b.error) }
2:01 PM
を付け加えたら通りました
😲 1
Avatar
Taketo Sano 4/9/2018 2:01 PM
Avatar
@@
Avatar
Kishikawa Katsumi 4/9/2018 2:04 PM
つまり、 (a.x * b.x )- (a.y * b.y) - (a.z * b.z) - (a.w * b.w)- を探し続けてたってこと? (edited)
2:04 PM
ちょっと式の意味変わっちゃってるけど。
Avatar
( もう解決してそうですが、型推論の挙動自体はswift -frontend -typecheck -debug-constraints ファイル名.swift で見れます )
Avatar
Kishikawa Katsumi 4/9/2018 2:05 PM
こうか。
Avatar
(ukitakaくんありがとう)
Avatar
Taketo Sano 4/9/2018 2:07 PM
ちなみに 2項 - は AdditiveGroup というプロトコルで + と単項 - を使ってこう定義してます: public extension AdditiveGroup { public static func -(a: Self, b: Self) -> Self { return (a + (-b)) } } https://github.com/taketo1024/SwiftyMath/blob/master/Sources/SwiftyMath/Abstract/AdditiveGroup.swift#L12
SwiftyMath - Pure Math in Pure Swift.
2:07 PM
今から上の方法試してみます。
Avatar
なるほど、数学的だ
👍 1
Avatar
Taketo Sano 4/9/2018 2:11 PM
おぉ、ほんとだ、通るようになった😂
2:11 PM
でもこれは普通に通っといて欲しい笑
Avatar
zと同じように
2:13 PM
let x = a.x * b.x + -a.y * b.y - a.z * b.z - a.w * b.w
2:14 PM
とすると通りますね
2:14 PM
2項の - を削除しても
Avatar
これって、デフォルト実装だと探索順位が変わってる(低い)ってことですか?? (edited)
Avatar
Taketo Sano 4/9/2018 2:15 PM
@masakihori そうなんですよね…是非そんなへんな書き方はしたくないですw
2:16 PM
@koher ってことなんですかねぇ…
Avatar
Kishikawa Katsumi 4/9/2018 2:17 PM
swift -frontend -typecheck -debug-constraints って簡単なコードでもすごい大量の出力がありますね。
2:17 PM
200MBくらいになったところで止めた。
Avatar
Taketo Sano 4/9/2018 2:18 PM
えげつなく出てきますねw 僕もいま該当の部分だけのファイル作ってるとこでしたw
Avatar
お、際限できたかも
Avatar
Kishikawa Katsumi 4/9/2018 2:20 PM
あ、そもそもリテラルでToo complexになるものにかけたので問題はそこです。組み合わせが大量にあって解決できないわけだから当然かと。
Avatar
けどもう新幹線おりなきゃ
Avatar
Kishikawa Katsumi 4/9/2018 2:20 PM
だから普通のコードでやるぶんには大丈夫。
Avatar
protocol FooProtocol { static func +(lhs: Self, rhs: Self) -> Self static func -(lhs: Self, rhs: Self) -> Self static prefix func-(value: Self) -> Self } extension FooProtocol { static func -(lhs: Self, rhs: Self) -> Self { return lhs + -rhs } } struct Foo : FooProtocol { static func +(lhs: Foo, rhs: Foo) -> Foo { return lhs } static prefix func-(value: Foo) -> Foo { return value } } let a = Foo() let b = a + a - a + a - a + a - a + a
2:21 PM
これで明示的な実装を付けたらどうなるか試したいけどもう新幹線下りるので後で・・・
Avatar
Kishikawa Katsumi 4/9/2018 2:22 PM
@swiftbot protocol FooProtocol { static func +(lhs: Self, rhs: Self) -> Self static func -(lhs: Self, rhs: Self) -> Self static prefix func-(value: Self) -> Self } extension FooProtocol { static func -(lhs: Self, rhs: Self) -> Self { return lhs + -rhs } } struct Foo : FooProtocol { static func +(lhs: Foo, rhs: Foo) -> Foo { return lhs } static prefix func-(value: Foo) -> Foo { return value } } let a = Foo() let b = a + a - a + a - a + a - a + a
2:24 PM
^ このコードだけ見るとコンパイラをいじめるだけのコードにしか見えないけど、佐野さんの例を見ると、これがコンパイルできる必要があるんだなあと。
😁 1
Avatar
いじめるだけのコードw
2:26 PM
どこかにoverloadのタネが埋まってるのかなと思ったけどそうでもないですね
Avatar
このあたりのオーバーロードの解決を軽くする改善されてたよな〜と思ったら... いつのまにかRemove されてた 😂 https://github.com/apple/swift/pull/14581
The current implementation isn't really useful in the face of generic overloads. It has never been enabled by default, and isn't useful to keep around if it is disabled. If we ever want to ...
😇 1
Avatar
↓だと大丈夫でした。 protocol FooProtocol { static func +(lhs: Self, rhs: Self) -> Self static func -(lhs: Self, rhs: Self) -> Self static prefix func-(value: Self) -> Self } extension FooProtocol { static func -(lhs: Self, rhs: Self) -> Self { return lhs + -rhs } } struct Foo : FooProtocol { static func +(lhs: Foo, rhs: Foo) -> Foo { return lhs } static prefix func-(value: Foo) -> Foo { return value } } extension Foo { static func -(lhs: Foo, rhs: Foo) -> Foo { return lhs + -rhs } } let a = Foo() let b = a + a - a + a - a + a - a + a
2:30 PM
やっぱり明示的に実装されているか、デフォルト実装かで推論の優先順位が変わってそう。
Avatar
Taketo Sano 4/9/2018 2:30 PM
infix - を明示的に入れるか否かの違いってことですね🙄
Avatar
これって推論のバグなんじゃないのかなぁ・・・。
Avatar
Taketo Sano 4/9/2018 2:31 PM
protocol extension のありがたみが… 😆
Avatar
ところで+と-で動きが違うのは
2:31 PM
-はprefixがあるからなのかな?
Avatar
- はデフォルト実装だからじゃないですか?
2:32 PM
あー、 prefix の可能性もあるのか。
Avatar
Taketo Sano 4/9/2018 2:32 PM
prefix あると思います。
Avatar
SwiftyMathのほうは+もデフォ実装です
2:32 PM
AddativeSubgroupにありますね
Avatar
でも prefix と解釈したらパースに失敗しそうな?
Avatar
Taketo Sano 4/9/2018 2:32 PM
そうなんですよねぇ
Avatar
ん?? +- かどっちかは明示的な実装が必要でないですか?
Avatar
Taketo Sano 4/9/2018 2:34 PM
infix + と prefix - が必要で、それを使って infix - がデフォルト実装されるようになってます。
2:35 PM
@tarunon AdditiveSubgroup は、整数全体の中の偶数全体のように、親の演算をそのまま子供が引き継げるケースで使うやつです。
Avatar
let x = a.x * b.x - a.y * b.y - a.z * b.z// - a.w * b.w
2:35 PM
これなら通る
Avatar
RはAddaptiveと思ってたけど見間違いかしら
Avatar
なので推論に使える「深さ」があってそれをオーバーしたのでtoo complexで諦めた?
Avatar
↑↑はあってる、で、どちらもprotocol extensionの実装
2:38 PM
具体型のimplだと通るのはそれがoverloadで静的に見つかるからと思う、witness-tableから引いてるわけではなさそう
Avatar
Taketo Sano 4/9/2018 2:40 PM
Additive というのは演算が加法的 + という意味です(のことではなく?)
2:41 PM
加法的な演算に乗法的な演算が加わって環(Ring)というものになります。
Avatar
僕の言っているのは、+も-もinfixは全部protocol extensionの実装になっているので、この場合は+がコンパイル可能だが-は不可能、その差はprefix operatorの有無では?と言う話です。そのprotocol extensionの宣言はAddativeSubGroupが持ってますよね? (edited)
Avatar
Taketo Sano 4/9/2018 2:43 PM
+ のデフォ実装は基本的にはないです、
2:44 PM
AdditiveGroup の subprotocol に AdditiveSubgroup というのがあって、sub の方は super が演算を引き継げるようになってます。
2:47 PM
(意図をくめてなかったらすみません🙏
Avatar
あでもRealNumberは+の定義も持ってた!
2:47 PM
すみません、ここは僕の読めてなかったところだ
Avatar
Taketo Sano 4/9/2018 2:47 PM
引き算と割り算が省略できる作りになってます。
Avatar
RealNumber > SubField > Subring > AddativeSubgroup
2:49 PM
ここで、AddativeSubgroupはSuperの+を使えるので、それならコンパイラから見たら同じprotocol extensionじゃないかな?と思った次第
2:49 PM
実際はちゃんと静的な定義がありました
Avatar
Taketo Sano 4/9/2018 2:49 PM
あっ、確かにそうでした😵
2:51 PM
a - b を a + -b って書き直すと通るようになったりするんで、- が infix なのか prefix なのかをコンパイラが判断できなくなってる感じがします…
Avatar
↓でもダメなんで、やっぱりデフォルト実装の問題だと思います。 protocol FooProtocol { static func +(lhs: Self, rhs: Self) -> Self static func -(lhs: Self, rhs: Self) -> Self } extension FooProtocol { static func -(lhs: Self, rhs: Self) -> Self { return lhs + rhs } } struct Foo : FooProtocol { static func +(lhs: Foo, rhs: Foo) -> Foo { return lhs } } let a = Foo() let b = a + a - a + a - a + a - a + a
Avatar
オッ RealNumberの+の実装外したらいろんなところが転けましたね
2:57 PM
これはprefix関係なさそう
3:01 PM
これで転けるとすると、、ConditionalConformanceで==と&&の組み合わせの改善は…出来てなさそうな気がしてきましたねぇ
Avatar
バグレポートしてみました。 https://bugs.swift.org/browse/SR-7389
👍 4
Avatar
thumbsupの隣にthumbsdownがあってドキドキしながら押すの、UXよくないですよね
3:04 PM
(関係ない)
Avatar
Kishikawa Katsumi 4/9/2018 3:05 PM
一度つけた絵文字って消せない。。。?
Avatar
もう一回押すと消せますけど、それでもドキドキしちゃう
Avatar
Kishikawa Katsumi 4/9/2018 3:06 PM
あ、消せた。
3:06 PM
まあ 👎🏻 これいらないですよね。
Avatar
サムズダウンしたら勝手にサムズアップにしてくれて、もう一度やり直すと本当にサムズダウンになる、みたいな
Avatar
Kishikawa Katsumi 4/9/2018 3:08 PM
Botの出番か。
Avatar
あとなんか、ディスコードのよく使う絵文字、バグってるのかここ最近固まってしまって使い勝手が悪い
Avatar
Kishikawa Katsumi 4/9/2018 3:10 PM
マジメな話、 👎🏻 いらないというのは非常に合理的だと考えていて、というのも基本的に不特定多数の集まるネットではポジティブよりネガティブなリアクションにつきやすい偏りがあるからです。
Avatar
omochimetaru 4/9/2018 4:11 PM
prefix operatorの場合は演算子をオペランドに密着させないといけないから
4:11 PM
そこの探索は生じないのじゃない?
Avatar
それは勘違いでした
4:12 PM
+と-の差がprefixの有無だと初見では思っていたが、実際は静的実装の有無だった
Avatar
@Kishikawa Katsumi さんのコミュニケーション論とか評価論、興味深いです。iOSDC飲みのときにされてたStackOverflowが唯一評価付けに成功してるという話とか。まとめが読んでみたいです🙂
😅 1
Avatar
最初は両方ともprotocol extensionに実装があったのでそれかな?と思った。静的実装は見逃していた
Avatar
みなさんありがとうございます!bug report にコメントもついてますね:
Operations that work on concrete types are always going to be simpler for the compiler to reason about than those involving protocols, but we'd still like to do better here.
Avatar
Unfortunately type-checking performance related to generics is not yet optimal (but we are working on it), because unlike for concrete types, we can't attempt bindings for arguments until all of the operator overloads are applied which leads to exponential behavior. So I would suggest for time being and if it's possible add new operator overloads only with concrete types.
2:47 AM
うーん、解決できないわきゃないと思うんだけどなぁ。
2:47 AM
オペランドの型が定まってるんだから。
Avatar
実プロジェクトで起きている問題だということをアピールすれば優先順位あげてもらえるかも。
Avatar
むしろ PR チャンス?いきなりこんなところに突っ込むと死ぬかな・・・?
😂 1
Avatar
setterで@availableを使える様にしてもらった。 https://bugs.swift.org/browse/SR-7201
👏 6
Avatar
アプリターゲットが別のアプリターゲットをtestable importするのってだめなんですかね
Avatar
Kishikawa Katsumi 4/13/2018 4:11 AM
プロダクションコードでってことですよね?
Avatar
えーっと、リリースするアプリがtestable importするのではないです。
Avatar
omochimetaru 4/13/2018 4:12 AM
そもそもアプリターゲットってリンクできるんか?
4:13 AM
.app 形式にうまくパッケージされない気が
Avatar
「MainAppターゲットに入ってるViewControllerのインスタンスを作って、順番に画面に表示していくTestApp」を作って、TestAppのUITest+fastlaneでスクショを集めるみたいなことをしたくて。
Avatar
omochimetaru 4/13/2018 4:14 AM
そもそも普通にライブラリとして作るのがいいんじゃない?
Avatar
TestAppのtarget dependenciesにMainAppを入れて、@testable import MainApp したらMainApp側の型がコード補完上見れるようになったところまではやった
Avatar
Kishikawa Katsumi 4/13/2018 4:14 AM
何となくわかる。可能ならそれは別にいいと思います。
Avatar
@omochimetaru どゆこと
Avatar
omochimetaru 4/13/2018 4:14 AM
ちゃんとpublicにしたほうがいいとおもう。
Avatar
Kishikawa Katsumi 4/13/2018 4:14 AM
多分ダイナミックリンクではなさそう。
Avatar
omochimetaru 4/13/2018 4:15 AM
@hiragram アプリターゲットじゃなくてFrameworkターゲットにする
Avatar
どっちを?
Avatar
omochimetaru 4/13/2018 4:15 AM
えーっと、ぜんぶで3つになる
4:15 AM
アプリの実質的なコード全部が入ったFrameworkと、 それをアプリとしてリリースするためのガワだけのアプリターゲットと、 それぞれの画面のスクショを撮るためのアプリターゲット。
Avatar
MainApp側が特殊なことをしたくないんだよね
4:16 AM
MainAppはどうテストされるかとかそういうのは一切考えなくて良いようにしたい
Avatar
omochimetaru 4/13/2018 4:16 AM
いずれにしても
4:16 AM
testable importするんじゃなくて
4:16 AM
例えば UserProfileViewControllerが
4:16 AM
public classなら
4:16 AM
普通のimportでいいじゃん?
Avatar
Kishikawa Katsumi 4/13/2018 4:17 AM
あと現状はコンパイル通ってるのかもしれないけどうまくいかないと思いますね。
Avatar
omochimetaru 4/13/2018 4:17 AM
僕もそれが気になってます>動くのかどうか
Avatar
Kishikawa Katsumi 4/13/2018 4:17 AM
スクリーンショットが目的ならTestAppいらないと思います。
Avatar
omochimetaru 4/13/2018 4:18 AM
Appのexecutableはdylibとしてリンクできないだろうしxibとかのリソース周りを含めたバンドルアセットが
4:18 AM
パッケージできないんじゃないか・・・?
Avatar
Kishikawa Katsumi 4/13/2018 4:18 AM
UITestのコードを書きたくないんじゃないかと思うんですけど、たぶんUITestのコードを書いた方が簡単。
Avatar
omochimetaru 4/13/2018 4:18 AM
あ、それか普通に、MainAppの中にスクショ取るための画面を作ったら良いのでは。
4:18 AM
一番最初のAppDelegateで最初の画面出すところとかでBundleIDとか見て分岐しちゃえば。 (edited)
4:19 AM
あーでもそれだといろいろと2重に登録しないといけないかあ。
4:20 AM
出荷版にスクショモードへのルーティングを含めたくないよね。
4:20 AM
まあなんかアプリ側で持ってるデバッグスイッチとかあるだろうしそれでいいか。
Avatar
Kishikawa Katsumi 4/13/2018 4:21 AM
MainAppと99%同じビルド構成のTestAppというターゲットを作るのがベターかな。
4:21 AM
MainAppで分岐するより。
Avatar
omochimetaru 4/13/2018 4:21 AM
最初そうおもったんですけど、それだとVCとかXIBとか何もかも全部ぶち込むってことですよね?
Avatar
それはちょっと
Avatar
omochimetaru 4/13/2018 4:22 AM
元々それが嫌で最初のアイデアになってるのかなと思った。
Avatar
Kishikawa Katsumi 4/13/2018 4:22 AM
たぶんTestAppの方はxcconfigでMainAppの構成を継承しつつ、一部Excludeで簡単にできると思います。
Avatar
omochimetaru 4/13/2018 4:23 AM
いけそうなきもしてきた
Avatar
Kishikawa Katsumi 4/13/2018 4:24 AM
TestAppには EXCLUDED_SOURCE_FILE_NAMES=AppDelegate.swift と書きつつ、 TestAppDelegate.swift というのだけ追加すればいいのではないかしら。 (edited)
Avatar
UITestのコードを書きたくないんじゃないかと思うんですけど、たぶんUITestのコードを書いた方が簡単。
これについては、これをやりたいんです https://qiita.com/tamaki/items/0c2ca2ee3b222321749b
先日iOSDCに個人スポンサーとして参加して来ました、いやー最高でしたね。毎年あってほしい。 非常に興味深い発表ばかりで刺激たっぷり、そこで得た知見なりを活かしたいと考え...
4:26 AM
今のMainAppのViewControllerたちは呼び出し元から渡された値のみで動作するので、スクショ取る用のモックを差し込んだVCのインスタンスを作って、その画面を直接表示する、ということができるVCなんですが、UITest側でそれができなくてこまっているので
4:26 AM
じゃあ1段テスト用のアプリを作ればええやん、testable importでMainApp突っ込めばアクセスできるはずやん、となった
4:27 AM
いまの進捗としては、MyAppのinternalなViewControllerは使えた。MyAppのinternalなprotocolのメソッドなどを使おうとするとリンカエラーになって困っている、という感じです
Avatar
Kishikawa Katsumi 4/13/2018 4:27 AM
まあその目的であれば、動くのであればTestApp側にtestable import書くのは別に問題ないと思います。
Avatar
omochimetaru 4/13/2018 4:27 AM
使えたっていうのは、実際に画面出たの?
Avatar
使えたというのはコンパイル通せたということ
Avatar
Kishikawa Katsumi 4/13/2018 4:28 AM
アプリに関していうとpublicとinternalはほとんど同義なので、publicにしてもいいと思います。
Avatar
omochimetaru 4/13/2018 4:28 AM
なるほど。コンパイルはできると思うんだけど、画面出るところまでいけなさそう。
Avatar
プロトコルのメソッド経由でinstantiateするコードが含まれてるとリンカエラーになってるので、直接initよびだして作ってみようかな
4:28 AM
それは試してないのでやります
Avatar
Kishikawa Katsumi 4/13/2018 4:29 AM
総論でいうと、UITestはそもそもテスト対象をプログラム的に触れないのが当たり前なので、普通にUITest側でUIを操作して画面を作っていくことをお勧めします。 (edited)
Avatar
それは同意です
Avatar
omochimetaru 4/13/2018 4:35 AM
@hiragram Qiitaの記事ざっと読んだんだけど > 「MainAppターゲットに入ってるViewControllerのインスタンスを作って、順番に画面に表示していくTestApp」を作って、TestAppのUITest+fastlaneでスクショを集めるみたいなことをしたくて。 これって一通りの画面を出す画面が、MainAppに入ってたらそれ + UITest でできない? (edited)
Avatar
Kishikawa Katsumi 4/13/2018 4:36 AM
うん、同じイレギュラーだったらとりあえずシンプルな方法にしといたらいいと思いますよ。
Avatar
omochimetaru 4/13/2018 4:36 AM
MainApp + TestApp + UITest(snapshot) じゃなくて MainApp + UITest(snapshot) にする。
4:37 AM
その場合の問題点はMainAppに「画面を並べた画面」の実装が入っちゃうことだけど、 Qiita記事みたいに起動オプションでAppDelegateでルーティングするなら、本番リリースではそのパラメータが来ても無視するように別途設定機能をもっといて封印したら良いと思う。 (edited)
Avatar
Kishikawa Katsumi 4/13/2018 4:38 AM
それかUITestじゃなくてUnitTestで、ビューを画像にレンダリングした方がいいんじゃないかな。。。?
4:41 AM
let viewController = ... let window = UIWindow() window.backgroundColor = .white window.rootViewController = viewController window.makeKeyAndVisible() RunLoop.main.run(until: Date(timeIntervalSinceNow: 0)) viewController.view.layer.render() ^ みたいなことをした方が簡単。
Avatar
omochimetaru 4/13/2018 4:42 AM
あ〜
4:42 AM
HostAppのあるUnitTestって結局プロセス内だからUIWindowつくってmakeKeyAndVisibleできるのか。
😀 1
Avatar
Kishikawa Katsumi 4/13/2018 4:46 AM
^ のやり方で、プレーンなViewControllerとNavController, TabBarControllerにそれぞれEmbedした場合で適切にcontentInsetsが設定されているか、などを確認しているのが https://github.com/kishikawakatsumi/SpreadsheetView/blob/master/Framework/Tests/ViewTests.swift <= このテストケースで、参考になるんじゃないかな。
SpreadsheetView - Full configurable spreadsheet view user interfaces for iOS applications. With this framework, you can easily create complex layouts like schedule, gantt chart or timetable as if y...
Avatar
omochimetaru 4/13/2018 4:48 AM
SpreadsheetView - Full configurable spreadsheet view user interfaces for iOS applications. With this framework, you can easily create complex layouts like schedule, gantt chart or timetable as if y...
4:48 AM
お〜 このテクニックおもしろい
Avatar
Kishikawa Katsumi 4/13/2018 4:49 AM
動かすとよく分かりますよ^^
Avatar
ios-snapshot-test-case - Snapshot view unit tests for iOS
Avatar
これって一通りの画面を出す画面が、MainAppに入ってたらそれ + UITest でできない?
テスト用のモックもそっちに置かなきゃいけないのはなんかいや
Avatar
omochimetaru 4/13/2018 4:52 AM
そう・・・
4:52 AM
アプリにデバッグメニューとか作ってないの?
Avatar
まだないお
Avatar
omochimetaru 4/13/2018 4:53 AM
俺はよくいろんな画面にいける画面とかAPI叩いたり内部データ書き換える画面作ってるから
4:53 AM
どうせそういうのがあるならいいじゃんって思った。
Avatar
Kishikawa Katsumi 4/13/2018 4:53 AM
iOSSnapshotTestCaseを使うと、ビューを画像にする部分がより簡単になります。
Avatar
omochimetaru 4/13/2018 4:54 AM
こんなライブラリあるのか
4:54 AM
iOSSnapshotTestCase (previously named FBSnapshotTestCase)
4:54 AM
もともとFacebookなの・・・?
4:54 AM
uber/ だけど・・・
Avatar
Kishikawa Katsumi 4/13/2018 4:54 AM
もともとFacebookが作っててDiscontinuedになってUberに引き継がれた。
Avatar
omochimetaru 4/13/2018 4:55 AM
へぇ〜〜
Avatar
Kishikawa Katsumi 4/13/2018 4:55 AM
AsyncDisplayKit => Textureも似たような感じ。
4:55 AM
Facebook => Pinterest(だったかな?)
Avatar
ですです。 snapshottestcase好きで使ってたんですがFBがやめてしまって暫くどうしよっかなと思ってたらいつの間にかUberが引き取ってました (edited)
Avatar
omochimetaru 4/13/2018 4:56 AM
ほ〜〜
Avatar
これ使うと差分検出のためにリファレンスの画像が必要になるんですが、それによってPRに変更箇所の画像も含まれるようになるので副次的効果としてレビューしやすくなるのも気に入ってます。一旦FBがアーカイブしたタイミングでXCUITestでスクショ取る方法に移してたんですがUberが引き継いだならやっぱこっちに戻そうかなとか最近考えてます。
Avatar
Swiftコンパイラボットを作成する過程で、Processで起動した子プロセスの出力をキャプチャする際にはDispatchGroupで待つと良いという知見を得た。 https://github.com/norio-nomura/SwiftCompilerDiscordappBot/blob/master/Sources/SwiftCompilerDiscordappBot/execute().swift#L27-L31
SwiftCompilerDiscordappBot - Swift Compiler Discordapp Bot
11:06 AM
パイプが64KB以上バッファしてくれないので、親側でパイプから逐次読み出さないでいると、子プロセスからの出力が64KBを越えた時点でパイプへの書き込み待ちになり、子プロセスが終了しなくなる。
11:07 AM
なので、プロセス終了待ちと標準出力受け取りと標準エラー受け取りを全部並列で実行する必要がある。
Avatar
Conditional Conformance使ってObjcDelegateに一部のGenericsのときだけConformしようとしたらコンパイル出来なかった
👀 1
Avatar
Kishikawa Katsumi 4/17/2018 2:35 AM
Avatar
omochimetaru 4/17/2018 2:36 AM
fuckingってわりに内容は使い方解説?
Avatar
Kishikawa Katsumi 4/17/2018 2:37 AM
これはいわゆるツンデレってやつですね。
🤔 1
Avatar
omochimetaru 4/17/2018 2:37 AM
なあるほど。
2:37 AM
これな〜 式にしたいことが多いんだよなあ。
Avatar
ifcase、補完出てこなくて辛いのでswitchcasedefaultやりがち
Avatar
Kishikawa Katsumi 4/17/2018 2:39 AM
f○cking~.com シリーズはたぶん4つ目くらい。たぶん初代は f○cking block syntax. 初代をリスペクトしつつ、いろんな人がわざわざドメインとって作ってるっぽい。 (edited)
Avatar
f*ckingではないが https://www.wtfautolayout.com もありましたね
Make sense of cryptic Auto Layout error logs.
Avatar
Why The Failure...
Avatar
Kishikawa Katsumi 4/17/2018 2:57 AM
普通に便利なやつ。
Avatar
omochimetaru 4/17/2018 2:58 AM
うおすげえw
2:58 AM
これアドレス見比べてヘロヘロになるんだわこれは便利
Avatar
UITableViewCellやUICollectionViewCellでコンストラクタDIを行いたい場合ってみなさんどうされていますか? 通常はdequeueReusableCell(withReuseIdentifier:for:)でインスタンス化を行うため、そもそもコンストラクタのカスタマイズはできないものなのでしょうか?
Avatar
セルの内側にViewを入れる前提で作って、CellのViewプロパティがnilならViewを生成する、その時にViewに対してConstructorInjectionは出来ますね (edited)
Avatar
セルはコードベースで生成しているので、xibなどは利用してないです。 現在は以下のようにセッターインジェクションでDIしています。 let cell = collectionView.dequeueReusableCell(with: FilterCell.self, for: indexPath) cell.configure(image: image, name: name) 内包する案もよさそうですね、ありがとうございます
Avatar
Cellに直接コンストラクタDIする方法はないのだろうか🤔 (edited)
Avatar
そもそもcellはreuse前提のapiなので基本的には無いのが正しいと思います
😀 1
Avatar
確かに、初期化コストを抑える(初期化回数を減らす)ために再利用してますもんね
Avatar
registerでReuseIdentifierを設定していますが、dequeueを実行せずにカスタムイニシャライザを呼ぶと実行時クラッシュしてしまうようです *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'the cell returned from -collectionView:cellForItemAtIndexPath: does not have a reuseIdentifier - cells must be retrieved by calling -dequeueReusableCellWithReuseIdentifier:forIndexPath:'
Avatar
はい、同様のエラーでした
Avatar
Kishikawa Katsumi 4/19/2018 2:20 AM
UICollectionViewは無理だと思います。
2:21 AM
UITableViewはindexPath引数を取らないdequeue〜については自分で作って返すことができる(レガシー)けどUICollectionViewはその仕組みは無くなりました。
👍 2
Avatar
いえいえ、できないことも知れてよかったと思ってます!ありがとうございます
Avatar
norio_nomura 4/22/2018 7:07 AM
なぜ message2でだけas [String : Any]が必要だと言われるのだろう? @swift-4.1.3 let content = "" let fields = [["name": "stdout.txt", "value": ""]] let message1 = fields.isEmpty ? ["content": content] : ["content": content, "embed": ["fields": fields]] let message2 = ["content": content, "embed": ["fields": fields]]
Avatar
exit status: 1 with stderr:main.swift:4:16: error: heterogeneous collection literal could only be inferred to '[String : Any]'; add explicit type annotation if this is intentional let message2 = ["content": content, "embed": ["fields": fields]] ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ as [String : Any]
Avatar
norio_nomura 4/22/2018 7:08 AM
message1も同じ型になるのに。
Avatar
↑の方でお話があった「UITableViewCellやUICollectionViewCellでコンストラクタDI」の件、 コンストラクタDI とは異なりますが、 Token型を作って保証するという方法を以前 kuniwa/k 氏がお話していたので使えるかもしれません(要望と全然ずれていたらすみません) https://speakerdeck.com/orgachem/ios-detesutorong-yi-nashe-ji-wo-shi-xian-surutamefalsedezainpatan?slide=133
Avatar
norio_nomura 4/24/2018 3:23 AM
dynamicMemberLookup 把握。subscript(dynamicMember:)の実装を必要とするアトリビュートなんだね。 @swift-4.2.4 @dynamicMemberLookup indirect enum UID: CustomStringConvertible { case root(String) case leaf(parent: UID, String) subscript(dynamicMember member: String) -> UID { return .leaf(parent: self, member) } var description: String { switch self { case .root(let string): return string case .leaf(let parant, let string): return "\(parant).\(string)" } } } let root = UID.root("root") print(root.a.b.c)
Avatar
root.a.b.c
Avatar
conditional conformance で Codable の auto-synthesize が効かないのはちと残念ですね…(いずれ対応されるのかしら) extension Matrix: Codable where R: Codable { //Implementation of 'Decodable' cannot be automatically synthesized in an extension
Avatar
cond confというかextensionでauto-synthesizeされない〜ですね
Avatar
あ、なるほど 🤥
Avatar
Codable は touple とあんまり相性よくないんですね 🤥
Avatar
タプルは non-nominal なので、そうですね。タプルを Codable にしたいと思った場合は、大抵は struct を作れば解決する気がします。
😀 2
Avatar
ふむふむ、なるほど。
6:51 AM
しかし cond. conf. がなかったら上のようなケースで codable にしようとするのは絶望的なのでありがたいですね👍
6:52 AM
generic な行列を json 化できました👍
Avatar
JSONSerialization を使ってキャストまみれになる頃のことしか知らなかったので、テンション上がります 🙂
Avatar
Swift 4.1 で ArrayElementCodable なときだけ Codable になりました🙂 extension Array : Codable where Element : Codable { ... }
Avatar
今ちょうどこれができるのを確認して 👍 ってなりました👍 (A, R: Codable で extend してる) let elements = try container.decode([A : R].self, forKey: .elements) (edited)
👍 1
Avatar
CGAffineTransform の逆行列は transform.inverted() なのに、 ARKit 等で使う simd の matrix_float4x4 の逆行列は matrix.inverse になってる・・・😂 (edited)
8:34 AM
CGAffineTransform はかけ算も concatenating だし、基本的に行列として扱わないネーミングなのかな? (edited)
Avatar
1. Library A の中で Vector2Codable にして JSON に変換すると {"x":2,"y":3} のように出力させる実装をする 2. Library A の中で Vector2 を持つ struct Foo : Codable を作る 3. Library A を使う App B を作る 4. App B のあるファイルで Library A を import せずVector2Codable にして JSON に変換すると [2, 3] のように出力させる実装をする 5. App B の別のファイルで Library A を import して Vector2 を JSON に変換すると [2, 3]Foo を JSON に変換するとその中の Vector2{"x":2,"y":3} というのができた。 (edited)
9:21 AM
つまり、 Vector2 に二通りの Codable の実装をして、それぞれ呼び分けることができた。なんとなくできない気がしてたけど、問題なかった。 (edited)
Avatar
スコープで参照するwitness table切り替えれるのすごいな
Avatar
衝突しそうと思ってました。
9:28 AM
↑に限らず、 importCodable の実装を切り替えたりできそうですね。
9:29 AM
Codable に限りませんが)
Avatar
protocol extensionがどのすこーぷにあるか、で、確かに優先順位が変動することがあったから
9:29 AM
この動きは可能だし妥当に思えてきた
9:30 AM
参照外のwitnesstableは見れてないなというのを思い出した
Avatar
omochimetaru 4/24/2018 9:32 AM
LibraryAをimportしないでもVector2が使えるってことはVector2はまた別のパッケージに入っている?
Avatar
in LibA import LibX has Vector2 in AppB import LibX, LibA ということでは
Avatar
Vector2 は別パッケージです。
Avatar
omochimetaru 4/24/2018 9:35 AM
なるほど。
Avatar
おや、さっきまで動いてたのに突然 redundant conformance だってエラーが出たぞ。あやしい・・・。
Avatar
omochimetaru 4/24/2018 9:37 AM
AnyXxxのerasureを使えば
9:37 AM
同じ型の値だが異なるwitness-tableを参照するオブジェクトを
9:37 AM
まぜこぜにできるってことか。
9:38 AM
AnyXxxに閉じ込めるときに解決されたconformanceが残る。
Avatar
ビルドできなくなった😂
9:40 AM
えー、ビルドのゴミ(?)が残ってる状態でのみたまたまうまく動いたのかなぁ・・・。
9:41 AM
また、今 iOS アプリで Carthage 経由でインストールしてるのもややこしい。 SwiftPM で試した方が良さそう。
Avatar
omochimetaru 4/24/2018 9:42 AM
単一パッケージの中で fileprivate で conform して実験しようとしたけど protocol が internal だから internalでconformしなさいというエラーが出てしまった。 実験するにはマルチパッケージな構成にしないといけないけどめんどくさいのでやめた。
9:43 AM
あ、SPMのソースディレクトリでターゲットをわければ簡単か?
Avatar
そう、それが面倒でこれまで検証してなかったけど、今たまたまそういう状況ができて、 import LibraryA をせずに Vector2 を持つ structCodable にしようとしたらエラーになったから、これはと思って試したんだけど
Avatar
今日だけで三回もカネパったし、結構いろいろありそうな気がしてる
Avatar
なぜか今は import LibraryA せずに Vector2 を持つ structCodable にできるようになってしまった。逆に Codable を付けようとすると redundant でエラーになる・・・。 (edited)
9:46 AM
SPMのソースディレクトリでターゲットをわければ簡単か?
これと、別リポジトリになってるときに本当に同じなのかがイマイチ確信が持てないんだけど気にしなくていいのかな?
Avatar
omochimetaru 4/24/2018 9:51 AM
できた
Avatar
omochimetaru 4/24/2018 9:58 AM
[omochi@omochi-iMacPro k (master=)]$ cat Sources/App/main.swift import Nature import Japan import US var animals: [AnimalProtocol] = [] animals.append(createJapanCat()) animals.append(createUSCat()) animals.forEach { animal in print(animal.speak()) } [omochi@omochi-iMacPro k (master=)]$ swift run にゃあ meow
9:58 AM
Contribute to swift-cross-module-conformance development by creating an account on GitHub.
10:01 AM
これと、別リポジトリになってるときに本当に同じなのかがイマイチ確信が持てないんだけど気にしなくていいのかな?
import とか public とか internal とかの振る舞いを見てると同じように見えるから同じだと思ってます。
Avatar
なんとなく罠がありそうな気がするけど、まだ見つかっていない。
12:51 PM
@koher さんの import せずに…ていうのが気になります。
Avatar
時間ができたらシンプルなプロジェクトで再現できるか試してみます。
🙏 1
Avatar
TestTarget の build-config を Release にした場合、本体も Release build されるんでしょうか?それとも Test の部分のソースコードだけ? (edited)
Avatar
全部 release になるっぽいですね
Avatar
Int 演算の overflow を catch したい… 🤥
Avatar
‘&+’?
11:26 AM
&+ ならオーバーフローしても落ちないです
11:27 AM
I was writing a program in C++ to find all solutions of ab = c, where a, b and c together use all the digits 0-9 exactly once. The program looped over values of a and b, and ran a digit-counting ro...
11:28 AM
例外投げる演算子は無いから、↑こういう感じでチェックしてはみ出すならthrowsする演算子を自分で定義するとか。
11:30 AM
こんなのあった。
11:30 AM
func addingReportingOverflow(_ other: Int) -> (partialValue: Int, overflow: Bool)
Avatar
addWithOverflow の名前が変わったんですね 🙄
11:32 AM
adding reporting って🐒
Avatar
まあこれも関数なので、これをラップして例外を投げる演算子にするのが良さそう
11:33 AM
演算子って例外投げれるのか?
Avatar
そうですねぇ 🙄
Avatar
@swiftbot infix operator %+ struct E : Error {} func %+(a: UInt32, b: UInt32) throws -> UInt32 { let c = a.addingReportingOverflow(b) if c.overflow { throw E() } return c.partialValue } try UInt32(0x80_00_00_00) %+ UInt32(0x80_00_00_00)
🛠 1
Avatar
Swift version 4.1 (swift-4.1-RELEASE)
11:35 AM
/usercode/main.swift:11:27: warning: result of operator '%+' is unused try UInt32(0x80_00_00_00) %+ UInt32(0x80_00_00_00) ~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~ Fatal error: Error raised at top level: main.E(): file /home/buildnode/jenkins/workspace/oss-swift-4.1-package-linux-ubuntu-16_04/swift/stdlib/public/core/ErrorType.swift, line 191 Current stack trace: 0 libswiftCore.so 0x00007f8e1fc285c0 _swift_stdlib_reportFatalErrorInFile + 221 1 libswiftCore.so 0x00007f8e1f9973dc <unavailable> + 1369052 2 libswiftCore.so 0x00007f8e1fbd1222 <unavailable> + 3703330 3 libswiftCore.so 0x00007f8e1fbd2689 <unavailable> + 3708553 4 libswiftCore.so 0x00007f8e1f996ad6 <unavailable> + 1366742 5 libswiftCore.so 0x00007f8e1fbd0feb <unavailable> + 3702763 6 libswiftCore.so 0x00007f8e1f996ad6 <unavailable> + 1366742 7 libswiftCore.so 0x00007f8e1fb03f79 <unavailable> + 2862969 8 libswiftCore.so 0x00007f8e1f9d4960 swift_errorInMain + 318 10 swift 0x0000000000fed1ce <unavailable> + 12505550 11 swift 0x0000000000ff1692 <unavailable> + 12523154 12 swift 0x00000000004d9076 <unavailable> + 888950 13 swift 0x00000000004c35d3 <unavailable> + 800211 14 swift 0x00000000004beecc <unavailable> + 782028 15 swift 0x00000000004778c4 <unavailable> + 489668 16 libc.so.6 0x00007f8e22141740 __libc_start_main + 240 17 swift 0x0000000000475179 <unavailable> + 479609 /usr/bin/swift[0x3f24d54] /usr/bin/swift[0x3f25096] /lib/x86_64-linux-gnu/libpthread.so.0(+0x11390)[0x7f8e23a17390] ...
11:35 AM
2.55 KB
Avatar
できた。
Avatar
おぉw
Avatar
でも計算性能がだいぶ落ちそうだなぁ・・・
Avatar
ですねぇ…w
11:37 AM
元々そのために入れてないっぽいですしね。
Avatar
@Taketo Sano
Int 演算の overflow を catch したい…
やりたいことにもよりますが、一般的には演算の overflow は Logic failure なので catch すべきでないと思います。
Avatar
omochimetaru 4/26/2018 2:11 AM
実際にものすごい数が出て来る計算をさせてるんかなと思ってそこはスルーしてた
Avatar
Swift において overflow が Logic failure なのは、パフォーマンス上のメリットもありますが、 array[i] などと同じく API 設計上の意図的なものだと思うので。 (edited)
Avatar
はい、大量の計算を高速にやる中で、全部に範囲チェックを入れるのはパフォーマンスに支障がありそうなので避けたい、というケースでした。
Avatar
https://stackoverflow.com/questions/39815054/how-to-include-assets-resources-in-a-swift-package-manager-library/39878338 Swift PM はまだライブラリにリソースを一緒に入れるのには対応してないんですかね。 (edited)
I would to ship my library usign Apple's Swift Package Manager. However my lib includes a .bundle file with seveal strings translated in different languages. Using cocoapods I can include it using ...
10:58 AM
実行時に json を読み込む、というようなことがしたいのですが 🙄
Avatar
対応してないですね
11:07 AM
jsonなら文字列として入れる手もあります。トリプルダブルクォートで。
11:32 AM
ちなみに今はこんな感じにやってますw
11:33 AM
10_129 まである 😵
Avatar
そこまでリテラルでかいとコンパイル遅くなりませんか?
Avatar
そうなんですよw
Avatar
ww
Avatar
なのでテキストデータとしておいておきたいなぁと 🤥
Avatar
文字列リテラルでjson持ちましょう
Avatar
それがよさそうですね、ありがとうございます。
Avatar
swift - Swift for TensorFlow documentation repository.
Avatar
let o1 = tanh(x ⊗ w1 + b1) 内積演算子(テンソル積演算子?)、どうやって入力するんだろう.. (edited)
Avatar
import TensorFlow let x = Tensor<Float>(shape: [1, 2], repeating: 0.1) let y = Tensor<Float>(shape: [3, 4], repeating: 0.1) let matmul = x ⊗ y print(matmul) test.swift:5:16: error: internal error generating TensorFlow graph: Dimensions must be equal, but are 2 and 3 for 'op.test.swift.5.16' (op: 'MatMul') with input shapes: [1,2], [3,4]. let matmul = x ⊗ y (edited)
11:08 PM
これがちゃんとコンパイルエラーになってくれる
👀 1
Avatar
良いですねえ
Avatar
norio_nomura 4/27/2018 1:05 AM
@swift-tensorflow import TensorFlow let x = Tensor<Float>(shape: [1, 2], repeating: 0.1) let y = Tensor<Float>(shape: [3, 4], repeating: 0.1) let matmul = x ⊗ y print(matmul)
Avatar
swiftTensorflow BOT 4/27/2018 1:05 AM
exit status: 1 with stderr:main.swift:4:21: error: internal error generating TensorFlow graph: GraphGen cannot lower a 'receive' from the host yet let y = Tensor<Float>(shape: [3, 4], repeating: 0.1) ^
😀 1
Avatar
omochimetaru 4/27/2018 1:06 AM
もうボットになったの
Avatar
Kishikawa Katsumi 4/27/2018 1:06 AM
Tensorflowボットできとる
1:06 AM
わしもimport
1:06 AM
できるようにしよう。
Avatar
omochimetaru 4/27/2018 1:06 AM
たしかにバージョンの1つなのかw
Avatar
norio_nomura 4/27/2018 1:07 AM
😀 1
Avatar
@Taketo Sano 巨大な array literal や dictionary literal は重いですが、 JSON にしなくてもリテラルを分割すればビルドは軽くなるんじゃないかと思います。
Avatar
Swift for Tensorflow の macOS 用ビルドって裏で Metal 使って GPU 使ってくれたりしないのかな? CPU のみ?
2:56 AM
swift-tensorflow チャネルが必要な気がしてきた。
Avatar
omochimetaru 4/27/2018 3:00 AM
#swift-tensorflow_archived 作りました
👍 5
7:47 AM
弊ライブラリでも ⊗ 使ってて、入力を楽にするために CodeSnippet を作りました👍 (edited)
😀 1
7:47 AM
https://github.com/taketo1024/SwiftyMath/blob/master/CodeSnippets/885A162B-C94C-4085-A858-99634B46259C.codesnippet @kenmaz. 👆これを ~/Library/Developer/Xcode/UserData/ に入れればすぐ出ます。 (edited)
SwiftyMath - Pure Math in Pure Swift.
😀 1
7:48 AM
もっといい方法があったら教えてください 🙏
Avatar
⌥も⌥⇧にも入ってないのか
8:06 AM
の方がまだ入力しやすい
Avatar
で自分で再定義すればいいのでは
Avatar
Kishikawa Katsumi 4/27/2018 8:13 AM
⌘+⌃+Space、「Circled times」で検索、、、かな。
8:14 AM
まあコードスニペットの方が楽そう。
Avatar
function  (lhs ... ) { ... }
Avatar
norio_nomura 5/3/2018 10:59 PM
Keyに略語などで全部大文字な単語とかが含まれると、JSONEncoder.KeyEncodingStrategy.convertToSnakeCaseJSONDecoder.KeyDecodingStrategy.convertFromSnakeCaseが非対称となる問題のスレッドがSwift Forumではじまりました。 https://forums.swift.org/t/handling-edge-cases-in-jsonencoder-jsondecoder-key-conversion-strategies-sr-6629/12384 import Foundation struct S: Codable { var myURLProperty: String } let encoder = JSONEncoder() encoder.keyEncodingStrategy = .convertToSnakeCase let data = try encoder.encode(S(myURLProperty: "property")) let decoder = JSONDecoder() decoder.keyDecodingStrategy = .convertFromSnakeCase let decoded = try decoder.decode(S.self, from: data) // "No value associated with key CodingKeys(stringValue: \"myURLProperty\", intValue: nil) (\"myURLProperty\"), converted to my_url_property." 上記コードはLinuxでは動きません。 (edited)
@hartbit recently revived some discussion about this topic in a PR by @norio_nomura, and I figured that instead of restricting the discussion to the PR, this would be a perfect opportunity to solicit some community feedback. As such: Hi all, I...
👀 4
Avatar
danger-swift使ってる人いますか?brew経由で入れようとすると依存解決に失敗してインストールできないんですけど僕の環境が悪いんだろうか
1:36 AM
Failing to resolve dependencies. What can I do? Is this due to my local environment? $ brew install danger/tap/danger-swift ==> Installing danger-swift from danger/tap ==> Downloading https:/...
Avatar
swiftの標準入力へソースコードを渡して実行させる時、-以降をCommandLine.argumentsとして取り出せるのね。 $ echo 'dump(CommandLine.arguments)' | swift -Onone - -verbose ▿ 2 elements - "-" - "-verbose"
Avatar
便利そう
Avatar
Kishikawa Katsumi 5/10/2018 1:28 PM
@swiftbot $ echo 'dump(CommandLine.arguments)' | swift -Onone - -verbose
Avatar
swiftbot BOT 5/10/2018 1:28 PM
▿ 2 elements - "-" - "-verbose"
Avatar
Kishikawa Katsumi 5/10/2018 1:28 PM
なるほど。
Avatar
norio_nomura 5/10/2018 2:42 PM
LinuxでのUserDefaults.argumentDomainサポートは4.2から。 @swift-4.1.3 @swift-4.2.4 - -param1 yes import Foundation print(CommandLine.arguments) print("param1: \(UserDefaults.standard.bool(forKey: "param1"))")
Avatar
["-", "-param1", "yes"] param1: true
Avatar
["-", "-param1", "yes"] param1: false
Avatar
Kishikawa Katsumi 5/10/2018 2:43 PM
LinuxのUserDefaultsってどこに保存されるんですかね。
Avatar
norio_nomura 5/10/2018 2:54 PM
どこだろう?
Avatar
Kishikawa Katsumi 5/10/2018 2:57 PM
デフォルトはplistなんですかね。BSDじゃないシステムにplutilとか入ってるのかな。
Avatar
Google が swift フォーマッタ開発していることが暗に公開されている。
Alex is the tech lead of Google’s Swift Language Support team, the primary maintainer of google/swift, and responsible for various open-sourced and to-be-open-sourced Swift tools such as swift-format
http://swiftfest.io/schedule/#session-030
The most community driven Swift conference!
👀 1
2:59 AM
これですかね
Avatar
おー、もうフォーク上で開発進めてるのですね。
3:03 AM
https://google.github.io/swift/ これも初めて知りました。
Google's Swift style guide.
Avatar
それ(スタイルガイド)今見てました。 GitHub のやつとかは昔話題になりましたけど、それは知りませんでした。
Avatar
すごいしっかりしたドキュメント、、
Avatar
@swiftbot protocol A{} struct S<X> {} extension S: A where X == Int {} extension S: A where X == String {}
🛠 1
Avatar
swiftbot BOT 5/30/2018 2:32 PM
Author icon
taketo1024
protocol A{} struct S<X> {} extension S: A where X == Int {} extension S: A where X == String {}
Version:
swift-4.1.1-RELEASE
Output:
Error:
/usercode/main.swift:4:14: error: redundant conformance of 'S<X>' to protocol 'A' extension S: A where X == Int {} ^ /usercode/main.swift:5:1: note: 'S<X>' declares conformance to protocol 'A' here extension S: A where X == String {} ^
Avatar
異なる条件で同一の protocol を confirm させるのってできないんですね…😟
Avatar
あ、それできないんですよ
Avatar
実務でもこれやりたいケース多そうな🙄
Avatar
なので、IntとStringをそれぞれ共通のprotocolに対応させて、共通protocolでエイヤとやります
2:35 PM
まさに、Addableみたいなのを作って適合して、Addableでcondconfする、みたいな感じになります
Avatar
omochimetaru 5/30/2018 2:37 PM
protocol IntOrString {} extension Int : IntOrString {} extension String : IntOrString {} extension S: A where X: IntOrString {}
Avatar
condconfのために、勝手に適合できないprotocolを作りたい、みたいな要求はありそう
Avatar
omochimetaru 5/30/2018 2:38 PM
↑べた書きすればこういう感じです。実際にはIntOrStringではなくこのIntとStringが満たしたい共通の性質を表したもっとよい名前のほうがいいですね。
Avatar
なるほど…😕ちと自分のケースだと難しそうです…😓
Avatar
いやなんとかなるはず
Avatar
多分厳しいですw
Avatar
enum AorB { case a(A) case b(B) } protocol AorBProtocol { var _value: AorB { get } } extension A: AorBProtocol { var _value: AorB { return .a(self) } extension B: AorBProtocol { var _value: AorB { return .b(self) } extension Array: Foo where Element: AorBProtocol { func fooFunc() { forEach { switch $0._value { case .a(let a): // write a case here case .b(let b): // write b case here } } } } (edited)
2:42 PM
一般化
2:42 PM
これをNに拡張すればOK
Avatar
それはわかるんですが、
Avatar
Generics持ちかな
Avatar
継承関係が複雑で無理っぽいです
Avatar
フーム
2:44 PM
基本的に否定以外の条件付けは全部なんとかなる認識なんですが、否定が入ってるのかな
Avatar
protocol A1 {} protocol A2: A1 {} protocol A3: A2 {} struct C<R>: A1 extension C: A2, A3 where R == X extension C: A2 where R == Y (edited)
2:47 PM
複素数体を generic な Complex<R> にして、複素数体 C = Complex<Real> と ガウス整数環 Complex<Int> を共通化しようとしまして、 (edited)
Avatar
@swiftbot protocol XorY {} struct X: XorY {} struct Y: XorY {} protocol A1 {} protocol A2: A1 {} protocol A3: A2 {} struct C<R>: A1 { } extension C: A2 where R: XorY { } extension C: A3 where R == Y { }
🛠 1
Avatar
swiftbot BOT 5/30/2018 2:47 PM
Author icon
tarunon
protocol XorY {} struct X: XorY {} struct Y: XorY {} protocol A1 {} protocol A2: A1 {} protocol A3: A2 {} struct C<R>: A1 { } extension C: A2 where R: XorY { } extension C: A3 where R == Y { }
Version:
swift-4.1.1-RELEASE
Output:
Error:
Avatar
うーん、まぁ、ちょっと厳しそうですw
Avatar
@swiftbot protocol XorY {} struct X: XorY {} struct Y: XorY {} protocol A1 { func a1() -> String } protocol A2: A1 { func a2() -> String } protocol A3: A2 { func a3() -> String } struct C<R>: A1 { func a1() -> String { return "a1\(R.self)" } } extension C: A2 where R: XorY { func a2() -> String { return "a2\(R.self)" } } extension C: A3 where R == Y { func a3() -> String { return "a3\(R.self)" } } print(C<X>().a1()) print(C<X>().a2()) // print(C<X>().a3()) // compile error print(C<Y>().a1()) print(C<Y>().a2()) print(C<Y>().a3()) シンプルな例ならイケそうな雰囲気はありますが…もしかしたら別のところでダメなのかも (edited)
🛠 1
Avatar
swiftbot BOT 5/30/2018 2:50 PM
(edited)
Author icon
tarunon
protocol XorY {} struct X: XorY {} struct Y: XorY {} protocol A1 { func a1() -> String } protocol A2: A1 { func a2() -> String } protocol A3: A2 { func a3() -> String } struct C<R>: A1 { func a1() -> String { return "a1\(R.self)" } } extension C: A2 where R: XorY { func a2() -> String { return "a2\(R.self)" } } extension C: A3 where R == Y { func a3() -> String { return "a3\(R.self)" } } print(C<X>().a1()) print(C<X>().a2()) // print(C<X>().a3()) // compile error print(C<Y>().a1()) print(C<Y>().a2()) print(C<Y>().a3())
Version:
swift-4.1.1-RELEASE
Output:
a1X a2X a1Y a2Y a3Y
Error:
Avatar
やりたいの事がダメだとわかった状態のコミットってありますか? @Taketo Sano
Avatar
いまプッシュします
Avatar
オッシャ
Avatar
EuclideanRing というのはあまりつきの割り算ができる環で、
2:59 PM
Ring > EuclideanRing > Field と継承されるのですが、
2:59 PM
Field というのは 0 でない数は逆数を持つ体で、余は常に 0 になるような特別な EuclideanRing となってます。
3:00 PM
複素数 ComplexNumber は Field で、ガウス整数は EuclideanRing なのですが、
3:01 PM
余りつき割り算のやり方が全然違うので共通化できなそう(できても可読性が著しく下がりそう)という感じでした…🙄
3:02 PM
複素数の実部と虚部を整数に制限したのがガウス整数です。
3:02 PM
複素数平面上の格子点。 (edited)
Avatar
omochimetaru 5/30/2018 3:03 PM
なるほど
3:05 PM
実装は共通化しなくてよくて、さっきのIntOrString等から、もともとのIntやStringをenum経由で取り出すメソッドをもたせちゃえばいいので
Avatar
なるほど…
Avatar
本質的に
3:07 PM
Complex: EuclideanRing, Field, NormedSpace であるためのRの条件ってなんですかね
3:08 PM
R: EuclideanRing, Field, NormedSpace ?
Avatar
R == 𝐑 です
3:09 PM
ちと記号がややこしいですがw、太字 𝐑 が実数で、 R は一般のジェネリック型です。
Avatar
omochimetaru 5/30/2018 3:09 PM
public typealias 𝐑 = RealNumber
3:09 PM
太字のRは Real.swift にあった。
Avatar
日本語が悪かった。具体型としてRealNumberではなく、なんの性質があればそれぞれどれが成り立ちますか?
Avatar
それは難しい問題ですね…🙄
Avatar
Complex: EuclidenRingはR: EuclidenRingであればなりたつ?
Avatar
一般論はちょっと分からないです
Avatar
なるほど。。。
Avatar
というのも GaussInt が EuclideanRing であるのも、R == Int であることをかなり強く使うので…
3:11 PM
もしかしたら統一的な一般論があるのかもしれませんが、僕は知らないです😣
Avatar
omochimetaru 5/30/2018 3:11 PM
突き詰めると Int の満たす性質みたいになっちゃって、数学的な議論が一段抽象化しちゃうことになりそう。
Avatar
統一的な一般論があれば、Intをその統一した型に適合して完了だと思ったのです
Avatar
例えば体上の一変数多項式環は EuclideanRing なのですが、これに i をつけたものが EuclideanRing になるかは分からないです🙄
Avatar
omochimetaru 5/30/2018 3:12 PM
git cloneが全然落ちてこない・・・
Avatar
はい、それで難しそうかなと思いました。
3:13 PM
enum AorB { case a(A) case b(B) } protocol AorBProtocol { var _value: AorB { get } } すいません、こちらはちょっと理解が不十分でした、
Avatar
結構大きいですよね、そしてコンパイルも時間かかるw
Avatar
enum も protocol も新たに作るってことだったんですね。
Avatar
omochimetaru 5/30/2018 3:13 PM
ですね、そのconformanceを無理やりやるためにadhocに記述するという感じです
Avatar
とりあえず一般論は無理ということで、RealNumberとIntだけでも満たしてみますか
Avatar
あぁ、最近実験用データを 1GB 近く別ブランチに入れたのでそのせいかもです。
Avatar
1GBw
Avatar
omochimetaru 5/30/2018 3:14 PM
githubって1リポジトリ1Gまでじゃなかったっけ。。
3:15 PM
We recommend repositories be kept under 1GB each. This limit is easy to stay within if large files are kept out of the repository. If your repository exceeds 1GB, you might receive a polite email from GitHub Support requesting that you reduce the size of the repository to bring it back down.
3:15 PM
まずいっすねw
Avatar
omochimetaru 5/30/2018 3:15 PM
ww
Avatar
3:18 PM
ああ、大丈夫か
3:19 PM
いやこれむずいすねw
Avatar
共通化するなら ComplexType みたいな protocol を作って、struct は別々に定義するのがいいんですかね。
Avatar
もうちょいでいけそう
Avatar
omochimetaru 5/30/2018 3:24 PM
こちらclone 14%
Avatar
うち1GBPS回線になったから割とぱっと落ちてきた
Avatar
omochimetaru 5/30/2018 3:26 PM
あくまでComplex<R>がEuclidenRingになるRってことだから
3:27 PM
protocol MakeComplexEuclideanRingHack (edited)
3:27 PM
とかやっとくと余計なこと考えなくて良いかも・・・
Avatar
いやー
3:28 PM
それがFieldとかと循環してる構造になってるのが難しい
Avatar
omochimetaru 5/30/2018 3:28 PM
ほう
Avatar
FieldならEuclidenRingの実装が自明になる
Avatar
omochimetaru 5/30/2018 3:32 PM
あーそゆこと
3:32 PM
R == RealNumber のときには
3:32 PM
Complex : Field のconformanceから
3:33 PM
Complex : EuclideanRingのconformanceは自動実装されるから
3:33 PM
EuclideanRingのconformanceをadhocに作っちゃうと
3:33 PM
Fieldからの経路が潰れるのか。
Avatar
そうなんです
Avatar
なんか気がついたんですが
3:35 PM
これDiagnos出てくるとRとZが崩壊しますね
Avatar
あぁ、そうなんですよねw
3:35 PM
謎の三角みたいなのが出てくるw
Avatar
omochimetaru 5/30/2018 3:35 PM
Avatar
とりあえず素朴に public protocol ComplexType: Ring { associatedtype Base: Ring init(_ x: Base) init(_ x: Base, _ y: Base) static var imaginaryUnit: Self { get } var realPart: Base { get } var imaginaryPart: Base { get } var inverse: Self? { get } var conjugate: Self { get } } ってして、 protocol extension つける方向で行こうかと思います😅
Avatar
omochimetaru 5/30/2018 3:37 PM
Complexをジェネリクスにするのを諦めて ComplexRealNumber : ComplexTypeとGaussInt : ComplexType にするってことですか?
Avatar
はい。
Avatar
omochimetaru 5/30/2018 3:37 PM
なるほど・・・素朴にはそれで逃げれますね
Avatar
さっきの enum もクールではありますが、そこまでトリッキーなことやるほどこういうケースがわんさか出てくる訳でもないので(勉強にはなりました、ありがとうございます 🙇
Avatar
あとちょっとなんじゃが
Avatar
どうすればできるのかは見て見たいですw
Avatar
これ実際に動いてるかチェックする簡単な式はありますか?
Avatar
おぉ
3:39 PM
ComplexNumber 用のテストはあります。
Avatar
めっちゃ苦しい上にForceCastもFatalErrorも出てきて敗北って感じがするw
3:51 PM
しんどすぎ、2項演算のせいでenumのcaseがはみ出すわ、返り値がSelfなので型として復元不能になるわでめちゃくちゃです
Avatar
omochimetaru 5/30/2018 3:52 PM
where付きextensionの中にenum定義できるんだw
Avatar
あとなんか、FieldなのにFieldに定義されたdefault implが参照されなくって結果全部分解した割り算を平たく各羽目に
3:52 PM
typeはprotocol内以外はどこでもかける
Avatar
omochimetaru 5/30/2018 3:53 PM
急にclone終わったから俺もやってみよ
Avatar
この間shield classをswiftでやるみたいなのやってたよね
3:55 PM
あれ応用したら少しはましになるかもしらん
Avatar
omochimetaru 5/30/2018 3:55 PM
shieldじゃなくてsealedね
3:55 PM
それもカッコいいけど
3:58 PM
==同士が衝突するのは定義の優先度が等しいからなのかな
Avatar
==どこや
Avatar
omochimetaru 5/30/2018 3:59 PM
whereの R==RealNumberと R==Zが
3:59 PM
ぶつかるそもそもの話
Avatar
condconfがなぜできないか、か
Avatar
omochimetaru 5/30/2018 4:00 PM
うん
4:00 PM
複数のがあっても、 == と : だったら
4:00 PM
衝突しないで強い方で解決するよね
Avatar
そうだっけか
4:01 PM
@swiftbot extension Array: Equatable where Element==Int {} (edited)
🛠 1
Avatar
swiftbot BOT 5/30/2018 4:01 PM
(edited)
Author icon
tarunon
extension Array: Equatable where Element==Int {}
Version:
swift-4.1.1-RELEASE
Output:
Error:
/usercode/main.swift:1:18: warning: conformance of 'Array<Element>' to protocol 'Equatable' was already stated in the type's module 'Swift' extension Array: Equatable where Element==Int {} ^ Swift.Array<Element>:1:11: note: 'Array<Element>' declares conformance to protocol 'Equatable' here extension Array : Equatable where Element : Equatable { ^
4:01 PM
Avatar
だめじゃないすかねこれ
4:02 PM
あたいぽ
Avatar
omochimetaru 5/30/2018 4:02 PM
wheseになってるよ
Avatar
ダメみたいだ
4:03 PM
えっとあとは
4:04 PM
@swiftbot extension Array: Equatable where Element==Never { static func == (lhs: Array, rhs: Array) -> Bool { return true } } (edited)
4:04 PM
あっ、リプじゃないと編集は反応しないか
4:05 PM
@swiftbot extension Array: Equatable where Element==Never { static func == (lhs: Array, rhs: Array) -> Bool { return true } }
🛠 1
Avatar
swiftbot BOT 5/30/2018 4:05 PM
Author icon
tarunon
extension Array: Equatable where Element==Never { static func == (lhs: Array, rhs: Array) -> Bool { return true } }
Version:
swift-4.1.1-RELEASE
Output:
Error:
/usercode/main.swift:1:18: warning: conformance of 'Array<Element>' to protocol 'Equatable' was already stated in the type's module 'Swift' extension Array: Equatable where Element==Never { static func == (lhs: Array, rhs: Array) -> Bool { return true } } ^ /usercode/main.swift:1:63: note: operator function '==' will not be used to satisfy the conformance to 'Equatable' extension Array: Equatable where Element==Never { static func == (lhs: Array, rhs: Array) -> Bool { return true } } ^ Swift.Array<Element>:1:11: note: 'Array<Element>' declares conformance to protocol 'Equatable' here extension Array : Equatable where Element : Equatable { ^
Avatar
だめじゃないすかねこれ
Avatar
色々ありがとうございます!
4:37 PM
ひとまず寝ます 😴
5:40 PM
本質的にたるのんと同じ状態
5:40 PM
CondConfの現実装の限界がわかってきた
5:46 PM
あれ、勘違いしてた、 Complex<GaussInt> じゃないわ
Avatar
これ割り算無限ループしなかった?
Avatar
実行してない
Avatar
norio_nomura 6/6/2018 2:34 AM
@swift-4.2.4 -swift-version 4 #if swift(>=4.2) print("swift-4.2") #elseif swift(>=4.1.50) print("swift-4.1.50") #elseif swift(>=4.1.2) print("swift-4.1.2") #endif
Avatar
swift42 BOT 6/6/2018 2:34 AM
swift-4.1.50
Avatar
omochimetaru 6/6/2018 2:36 AM
あれ?
2:36 AM
@swift-4.2.4 --version (edited)
Avatar
swift42 BOT 6/6/2018 2:36 AM
Swift version 4.2-dev (LLVM a38ff55b31, Clang 5272858825, Swift defc3e9073) Target: x86_64-unknown-linux-gnu (edited)
Avatar
norio_nomura 6/6/2018 2:38 AM
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
Avatar
omochimetaru 6/6/2018 2:39 AM
introducing a new compiler directive that is syntactically equivalent to the swift directive but checks against the version of the compiler,
2:40 AM
難しいですね
Avatar
Kishikawa Katsumi 6/6/2018 9:58 AM
自分の中で2周くらい回って @lovee さんのNotAutoLayoutはだいぶセンスがあるなという気になってきました。 これがAutoLayoutが出る前に作られていたら世界を席巻したんじゃないかなあ。
9:59 AM
持って回った言い方をしてるけど皮肉でもなんでもなくて、よく考えて作ってあるなあという気持ちです。
Avatar
omochimetaru 6/6/2018 10:03 AM
ほほ〜
Avatar
@Kishikawa Katsumi ありがとうございます 🙇 ここまでくるとなんか逆に名前がふざけてるようにしか見えなくて改名すべきか悩むんですよね 🤔
Avatar
Kishikawa Katsumi 6/6/2018 1:13 PM
まあそうですねえ。こういう分かりやすさは当然反発も生むので。
1:14 PM
一般論として。
Avatar
ちなみに次の予定は @omochimetaru さんの gysb でテンプレでコード生成したい気分です
😃 1
Avatar
Kishikawa Katsumi 6/6/2018 1:14 PM
あとまあどうしてもキワモノっぽく見えるというのはありますね。
Avatar
いちいち全部直でレイアウトプロパティー作ると大変だしバグりやすいし
1:14 PM
ですね
1:15 PM
正直当時なんも考えてなかったからな 😇 最初は「ManualLayout」にしたかったけどGitHubで検索してみたら既に同じ名前のがあったので考えるのだるかったからNotAutoにした訳でそろそろ4.0の時に名前考え直さないと…
Avatar
Kishikawa Katsumi 6/6/2018 1:16 PM
NotAutoLayoutはある程度の違反はコンパイルエラーになるというのが良いです。 (edited)
Avatar
やっぱり静的型付けは間違ったらコンパイルエラーが出るのがとても助かると思いますので
1:18 PM
石川先生の言葉ですね、「いい設計とは、間違った用法をコンパイルエラーにする」
Avatar
Kishikawa Katsumi 6/6/2018 1:19 PM
読む負荷はあまり変わらないかな?個人的には。 どっちも大変。
Avatar
コンパイルエラーにできるものはその分テスト書かなくて済むというメリットもあるかと()
Avatar
Kishikawa Katsumi 6/6/2018 1:23 PM
どうかなあ。ビューのOutputは失敗ケースの範囲がさまざまだし、Inputも安定しないから、コンパイルエラーになるケースを弾いても
1:23 PM
。。。
1:24 PM
それほど安心できない。
Avatar
ああ、今のは単純に一般論的な話で、例えばSwiftだとOptionalの仕組みがあるのでObj-Cの時みたいに至る所で nil パターンのテスト書かなくて済むメリットがあるのかなという意味です
Avatar
Kishikawa Katsumi 6/6/2018 1:26 PM
ああ、それはその通りですね。
Avatar
NotAutoLayout 、名前がわかりやすくていいと思いますけどね〜 (edited)
1:23 AM
結構浸透してるのでリネームはもったいないかも?
Avatar
ふざけてるように見えるのが難点ですよね、あと英語的に「Why Not Auto Layout」と「Why NotAutoLayout」が真逆の意味なのに全く同じに聞こえるのも地味に痛い気が
Avatar
w > 「Why Not Auto Layout」と「Why NotAutoLayout」
Avatar
Kishikawa Katsumi 6/7/2018 4:44 AM
仕組みは利用者にとっては重要じゃないので、その観点でいうともっと良い名前はあると思いますね。
Avatar
Why Not Auto Layout? で、「そうなんだけど Auto Layout こういうのクソじゃん〜」からの Why NotAutoLayout で NotAutoLayout の良さを説明する、的な
Avatar
DirectLayoutとかどうでしょう 🤔
Avatar
NonAutoLayout とか?
Avatar
NonもNotもイメージ的にあんまり変わらないですね 😇
Avatar
¬AutoLayout
👍 1
Avatar
『「Why Not Auto Layout」と「Why NotAutoLayout」』問題は解決できるかと🙃 < NonAutoLayout
6:53 AM
AntiAutoLayout とかw
Avatar
omochimetaru 6/7/2018 6:53 AM
AbsoluteKiller
Avatar
物騒なライブラリーだなw > AbsoluteKiller
Avatar
omochimetaru 6/7/2018 10:18 AM
絶対殺すマンで定着しているので・・・
🍀 2
Avatar
¬AutoLayout は多分そもそもGitHubでリポジトリ作れないしCartfileとかで指定できなさそうな気が 🤔
Avatar
別にAuto Layoutの逆になってるわけでもなくて、実は素直なレイアウトエンジンなんですよねー。
Avatar
Pureとか思いついたけどもうあったマン
Avatar
Kishikawa Katsumi 6/7/2018 10:45 AM
そう、動機はそうかもしれないけど、それはもはや関係ないし、利用者にとってはもっと関係ない、と思います。
Avatar
DescribableLayout
10:56 AM
DeclarativeLayoutとかSwiftyLayoutとかは当たり前のごとくすでにある・・・
Avatar
単純にLayoutっていう名前では🤔
Avatar
Layout って名前 つよい
Avatar
@swiftbot let f = Float.nan let a = [f] let b = [f] print(f == f) // false print(a == a) // true print(a == b) // false
🛠 1
Avatar
swiftbot BOT 6/12/2018 7:32 AM
Author icon
t.ae
let f = Float.nan let a = [f] let b = [f] print(f == f) // false print(a == a) // true print(a == b) // false
Version:
swift-4.1.1-RELEASE
Output:
false true false
Error:
Avatar
これでいいんでしたっけ?
Avatar
omochimetaru 6/12/2018 7:33 AM
@swiftbot print(Float.nan == Float.nan) (edited)
Avatar
あー、バッファが同じ場合は比較を省略してるのか。
Avatar
@swiftbot let f = Float.nan let a = Optional(f) let b = Optional(f) print(f == f) // false print(a == a) // false print(a == b) // false
🛠 1
Avatar
swiftbot BOT 6/12/2018 7:35 AM
Author icon
t.ae
let f = Float.nan let a = Optional(f) let b = Optional(f) print(f == f) // false print(a == a) // false print(a == b) // false
Version:
swift-4.1.1-RELEASE
Output:
false false false
Error:
Avatar
Arrayだけおかしい気がする
Avatar
DictionarySet もおかしくなるんじゃない?
Avatar
omochimetaru 6/12/2018 7:36 AM
ああ、 a== a のところがおかしいって言いたいのか。
Avatar
です。
Avatar
Optional は中身が一つしかないからそれの == を使うだろうけど、 DictionarySet だと Array と同じショートカットが行われてそう。
Avatar
omochimetaru 6/12/2018 7:37 AM
うーん・・・
Avatar
Setもおかしいですね。
Avatar
omochimetaru 6/12/2018 7:37 AM
そもそもFloatがEquatableの規約に違反してそう。
7:37 AM
規約なんて無いけど
Avatar
これは Array のバグなのか、 Float の(というか IEEE の)問題なのか。
Avatar
omochimetaru 6/12/2018 7:37 AM
Arrayが要素に期待する前提条件が
7:37 AM
常に a == a であるとして設計されてそうだし
7:37 AM
そうあっていいと思う
Avatar
こういうの考えても浮動小数点数の nan の仕様っておかしいよね。
Avatar
omochimetaru 6/12/2018 7:38 AM
同値性
7:38 AM
反射律。 (edited)
7:39 AM
Equatableがここでいう「同値関係」を規定するのかによると思うけど
7:39 AM
そうでないとしんどいよね。
Avatar
Equatable なのに equality じゃなくて equivalence なのか・・・。英語むずい・・・。
Avatar
バッファが同一ならequalというショートカットは要素の反射率を前提にしてますね。 ショートカット必要なんだろうか
Avatar
omochimetaru 6/12/2018 7:41 AM
あったほうがいいでしょ。
7:42 AM
プロパティが1万個ある構造体とかならでかいよ。
Avatar
かといって、 Float== を変えるのも難しいよね・・・。
7:43 AM
1. この結果を受け入れる 2. Array 等のショートカットをやめる 3. Float 等の == を変える だけど。結局 1 にしかならなさそう。
Avatar
バッファが同一のときしかショートカットできないのでどのくらい働くのか微妙な気がしますが。
Avatar
omochimetaru 6/12/2018 7:44 AM
@swiftbot var d: [Float: String] = [:] d[.nan] = "a" d[.nan] = "b" d[.nan] = "c" print(d.count) print(d[.nan]) print(d == d)
🛠 1
Avatar
swiftbot BOT 6/12/2018 7:44 AM
Author icon
omochimetaru
var d: [Float: String] = [:] d[.nan] = "a" d[.nan] = "b" d[.nan] = "c" print(d.count) print(d[.nan]) print(d == d)
Version:
swift-4.1.1-RELEASE
Output:
3 nil true
Error:
/usercode/main.swift:6:7: warning: expression implicitly coerced from 'String?' to Any print(d[.nan]) ^~~~~~~ /usercode/main.swift:6:8: note: provide a default value to avoid this warning print(d[.nan]) ~^~~~~~ ?? <#default value#> /usercode/main.swift:6:8: note: force-unwrap the value to avoid this warning print(d[.nan]) ~^~~~~~ ! /usercode/main.swift:6:8: note: explicitly cast to Any with 'as Any' to silence this warning print(d[.nan]) ~^~~~~~ as Any
Avatar
いや、 3 もありな気がしてきた。
Avatar
時間かかるのが全要素equalのときなので自分自身との比較が一番時間かかることになってしまいますが (edited)
Avatar
omochimetaru 6/12/2018 7:44 AM
バッファが同一のときしかショートカットできないのでどのくらい働くのか微妙な気がしますが。
コピーして回してる間にそうなることはあると思う
Avatar
いまって Int+ とかも純粋にハード的に計算してるわけじゃなくてオーバーフローチェックとか入れてるんだから
☝ 1
Avatar
omochimetaru 6/12/2018 7:45 AM
例えば user.items = user2.items if user.items == user2.items { } とか。 (edited)
Avatar
&== を IEEE 754 に従った素の計算にして、 == だと反射率を満たすようにすればいい気が。
Avatar
&== 入れるなら == がIEEEに従う じゃないですか?
Avatar
==Equatable で規定されるものだから、 Equatable== が反射率を満たす必要があることを明記して
7:47 AM
&==&+ 等と同様の余分なオーバーヘッドのない計算をしてくれる演算子でいいのでは?
Avatar
バッファチェック=オーバーヘッドか。それはそうですね。
Avatar
omochimetaru 6/12/2018 7:49 AM
==でnanを比較したら死ぬとかは?
7:49 AM
死ぬ分には定義を満たすことになる。
Avatar
普通に true でいいんじゃないかなぁ
Avatar
omochimetaru 6/12/2018 7:49 AM
まあ == .nan とかかけたら便利か。
Avatar
他言語から来た人が死にそうだw (edited)
Avatar
omochimetaru 6/12/2018 7:50 AM
他言語から来た人は == .nan 書かずに isNaN() を使うから大丈夫では
7:50 AM
わかったうえで a != a を手書きするタイプの人だけ死にますね (edited)
Avatar
== .nan を見て、このコードバグってんぞ→バグってなかった!ってなりそう
Avatar
omochimetaru 6/12/2018 7:51 AM
問題は
7:51 AM
NaNにほぼならないとわかっているケースで
7:51 AM
NaNチェック付きの実装になってしまうことで
7:51 AM
パフォーマンスが落ちそうなことですね
Avatar
いや、それを言い出したら
7:51 AM
Int+ だってそうでしょ?
7:52 AM
FloatDouble== より Int+ を使う機会の方がずっと多いのでは?
7:52 AM
CG とかだとそうとも限らない?でも +* は使っても == はそんなに使わなさそう。
7:52 AM
だし、そもそも GPU 上で計算されてるか。
Avatar
omochimetaru 6/12/2018 7:53 AM
オーバーフローするかどうかは足し算と同時にCPU命令一発で実行されるけど
Avatar
FloatDouble で、 CPU 上で計算してる時点でパフォーマンスにこだわるケースじゃなさそう。
Avatar
omochimetaru 6/12/2018 7:53 AM
isNaNの自動チェックはコードで外側でやることになるから
7:53 AM
その分の差がありそうだなと思って。
Avatar
Kishikawa Katsumi 6/12/2018 7:53 AM
Equatableは反射律を満たしていたらOKなんですか?推移律は不要?
Avatar
オーバーフローするかどうかは足し算と同時にCPU命令一発で実行される
そうなのか・・・。
Avatar
omochimetaru 6/12/2018 7:53 AM
はい、変なレジスタで結果が返ってくる。
Avatar
@Kishikawa Katsumi 全部満たしてないといけないと思います。
Avatar
omochimetaru 6/12/2018 7:54 AM
ただ、いずれにせよ「計算後」に その、オーバーフローフラグを見る制御ロジックはSwiftレベルで実装されてるから
Avatar
Kishikawa Katsumi 6/12/2018 7:54 AM
だとするとNan == Nanをtrueにすると推移律を満たさなくなるんじゃないかな。
Avatar
omochimetaru 6/12/2018 7:54 AM
それを前にやっているだけで結局かわらない気もする
Avatar
例がnanだったので反射率を上げただけですね
Avatar
Kishikawa Katsumi 6/12/2018 7:55 AM
結果Nanになるけど同じではないものはけっこうあるんじゃないか。
Avatar
(nan == nan) and (nan == nan) iff (nan == nan)では?
Avatar
omochimetaru 6/12/2018 7:55 AM
それはnanを構成する式の段階との話ですかね
Avatar
Equatable はあくまで計算結果の値についてなので、成り立つように思います。
Avatar
ああ計算過程の話ですかね?
Avatar
Kishikawa Katsumi 6/12/2018 7:57 AM
NaNに関しては、NaNになるXとYがあるとき、X == Yではないことはけっこうあるんじゃないか、ということです。
Avatar
omochimetaru 6/12/2018 7:58 AM
NaNになるX の X が、 Float型の値じゃなくて、なんらかの計算式を想定しているなら、間違っています。
7:58 AM
(10 / 2 ) == (20 / 4) なのに 10 と 20 は違う値だ 、みたいな。
Avatar
「 10 と 20 は違う値だ」より、「 10 / 2 と 20 / 4 」は異なる式だ、かな。
8:01 AM
Equatable はあくまで値についての性質なので、どのような式で nan が導かれても推移律は満たされることになるかと。
Avatar
Kishikawa Katsumi 6/12/2018 8:02 AM
それでいい気もしますね。
Avatar
@t.ae evolution に投げてみては?
Avatar
問題提起レベルでも投げていいんですっけ
Avatar
↑の三つの選択肢があると思うけどどう思う?くらいで Pitch として投げるならいいんじゃないかな?
8:11 AM
こんな問題見つけたよ、だとバグレポートな気がするけど。
8:12 AM
「どう思う?」というか、「修正が必要じゃない?」くらいのスタンスかな? (edited)
Avatar
じゃあちょっと書いてみます
👍 1
Avatar
調べてみたら似たようなのありますね。 https://forums.swift.org/t/rationalizing-floatingpoint-conformance-to-equatable/6861 a == aのケースについて話されてるかはこれから読みます。
Ben Cohen asked to continue this conversation on swift-dev-- Included in PR #12503 is a small tweak to accommodate so-called "exceptional values" (such as NaN) in comparisons of array equality. Currently, Array.== first looks to referential equality of underlying buffer...
8:27 AM
Currently, Array.== first looks to referential equality of underlying
buffers, then (if false) compares elementwise equivalence as defined by Element.==. As a consequence, an array of NaN compares equal to another array of NaN if they share the same buffer, but otherwise false. This is an undesirable outcome. 頭から書いてあった🙃
👌 1
Avatar
The last time that this topic was brought up, competing demands voiced by different people were not possible to reconcile: 1) Equatable `==` must be a full equivalence relation. 2) Floating-point types must conform to `Equatable` and not to some alternative such as `PartiallyEquatable`. 3) Floating-point `==` must be IEEE-compliant (at least in the concrete context), and therefore *not* a full equivalence relation. 4) IEEE-compliant floating-point equivalence must be spelled `==` and not some alternative such as `&==`. 5) Behavior of `==` must not change between generic and concrete contexts.
Avatar
Swift runtimeでConditional Conformanceをサポートしてない問題なのですが、今後の対応予定とかってどこで見れるのでしょうか?🙇 protocol A { static func hoge() } struct B: A { static func hoge() { print("B") } } extension Optional: A where Wrapped: A { static func hoge() { print("Optional") } } struct F<T> { static func fuga() { switch T.self { case is A.Type: (T.self as! A.Type).hoge() default: fatalError() } } } F<B>.fuga() // B // warning: Swift runtime does not yet support dynamically querying conditional conformance F<B?>.fuga() // fatalError (edited)
Avatar
SE-0143はSwift 4.2をもってImplementedとなっていて、ランタイムチェックも4.2で実装されてます https://github.com/apple/swift-evolution/blob/master/proposals/0143-conditional-conformances.md
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
2:09 PM
実装されたのは https://github.com/apple/swift/pull/14368 これで2月ですね
When evaluating whether a given type conforms to a protocol, evaluate the conditional requirements and pass the results to the witness table accessor function. This provides the ability to query co...
2:10 PM
https://github.com/apple/swift/commit/87f7b4e5fb58cc32fd33144e5e4207d53d2e5745 このマージコミットを見ればどのタグから入っているか分かりますね
2:11 PM
^ @Nonchalant
Avatar
@ikesyo ありがとうございます!すでに実装されてたんですね...探し方も教えていただいてありがとうございます!
2:11 PM
swift-4.2-DEVELOPMENT-SNAPSHOT-2018-04-23-a
2:12 PM
ここから入っているのか
2:12 PM
Xcode 10で試してみます!
Avatar
それは4.2のsnapshotが作られ始めたタイミングだと思うので、DEVELOPMENT-SNAPSHOTにはもっと前からあるはず
2:13 PM
Xcode 10 beta 1では間違いなく入ってるはずです
Avatar
ありがとうございます!🙇
Avatar
こんにちは! 自己宣伝で申し訳ないんですが、テスト用のダミーデータを作ってみるライブラリとそれに関する記事を書いてみました。Swift初心者なので、ぜんぜんアレかもしれませんが、感想を頂けたらすごくうれしいです。 https://qiita.com/yyu/items/e8f1b4a17dac4f9108a5
👀 4
Avatar
@yyu おもしろかったです😀こういうことを学ぼうとすると読みなれないHaskellとかでやることになるので、自分が親しんでいる言語で読めてとてもわかりやすかったです。 (edited)
Avatar
おお。ありがたいですー。
Avatar
Swift だと HListHConsHNil に限定できないのが辛いですね。 enum でも書けなさそうだし・・・。
7:40 AM
普通の List なら↓みたいに書けるんですけどね〜。 enum List<Element> { case `nil` indirect case cons(Element, List<Element>) } let a: List<Int> = .cons(2, .cons(3, .cons(5, .nil))) (edited)
Avatar
そうですね。enumが型パラメータを取れないと無理なんですよね……。
Avatar
ぬうう、canImportimportの様にシンボルを使う事は出来ないのか…。 @swift-main import Foundation let killSignals: [Int32] = { var signals = [SIGILL, SIGTRAP, SIGABRT, SIGFPE, SIGBUS, SIGSEGV, SIGQUIT] #if canImport(Glibc.SIGSYS) signals.append(Glibc.SIGSYS) #endif return signals }() (edited)
Avatar
swiftNightly BOT 6/19/2018 12:14 PM
exit status: 1 with stderr:<stdin>:4:5: error: unexpected platform condition argument: expected identifier #if canImport(Glibc.SIGSYS) ^ (edited)
Avatar
omochimetaru 6/29/2018 7:54 AM
diffライブラリを自作して、 値型の配列がdidSetで更新されると、差分がUIViewに適応されるパターンを組んでみました。 Reactの最小の手動実装のような感じです。 https://github.com/omochi/SdiftExample
Contribute to SdiftExample development by creating an account on GitHub.
👍 4
Avatar
public struct Uniform { var base: RandomNumberGenerator init(base: RandomNumberGenerator) { self.base = base } /// Returns a value from uniform [low, high) distribution. public mutating func next(low: Float, high: Float) -> Float { let uint32: UInt32 = base.next() return (high - low) * (Float(bitPattern: uint32 >> 9 | 0x3f80_0000) - 1) + low } } extension RandomNumberGenerator { public var uniform: Uniform { return Uniform(base: self) } } こういうの作ろうと思ったんですがRNGがstructだと内部状態コピーされるから微妙ですね…… (edited)
Avatar
next(range: Range<Float>)RandomNumberGenerator に生やすとか?
Avatar
normalもセットで作りたかったのでuniformに切り出したんです
Avatar
それも extension で追加してもいい気も (edited)
Avatar
next(range: Range<Float>)next(mu: Float, sigma: Float)だと分かりづらくないですかね?
Avatar
そうかな?そっちの方が使いやすそうな気も
2:00 AM
RNGがstructだと内部状態コピーされる
これの問題はどこでしょう?コピーコスト?状態が複製される点?
Avatar
分布について引数からしかわからないのが微妙かと思うんですが。 他言語だとrandとrandnに分けたりしてますがRNGのインターフェースに合わない……
2:02 AM
2つunifrom rngを作ったら内部状態がコピーされるので同じ乱数列が出てくるところですね (edited)
Avatar
まず、デフォルトの Randomstruct だけどそれは起こらないのと、
Avatar
Randomはそうですね。
Avatar
それが起こる RNG を実装した struct の場合
2:03 AM
var a = FooRandom() var b = a a.next() == b.next() // true になるんだから、 Uniform もそれでいいんじゃないかな?
2:04 AM
あー
Avatar
もともと気をつけてつかってねってのがstruct RNGなのを前提としても uniformでコピーされるところがわかりにくいんじゃないかと
Avatar
var a = FooRandom() print(a.uniform.next(...) print(a.uniform.next(...) これで同じのが出るのが嫌か。
Avatar
omochimetaru 7/2/2018 2:06 AM
実際には同じものが出ないような?
Avatar
メルセンヌ・ツイスタとかだと出るはずです
Avatar
uniformget set なプロパティにして
2:07 AM
Booltoggle とかと同じように元の struct に変更を反映できない?
Avatar
その発想はなかった。ちょっとやってみます
Avatar
setbaseself に代入すればいいのか。 (edited)
Avatar
omochimetaru 7/2/2018 2:10 AM
そだね>MT (edited)
Avatar
うーんうまくいかない?
2:15 AM
setで代入してるところには行ってるみたいなんですが
2:17 AM
あ、うまくいってました。0, 1, 2...を生成するダミーを使ったからFloatにして[0, 1)区間だとprintしても全部0に見えてただけでした (edited)
🙂 1
Avatar
あーやっぱりだめでした。 書き戻しで何か変なことになってそう
2:31 AM
@swift-4.2.4 swift public struct Uniform { var base: RandomNumberGenerator init(base: RandomNumberGenerator) { self.base = base } /// Returns a value from uniform [low, high) distribution. public mutating func next(low: Float, high: Float) -> Float { print("base before; \(base)") let uint32: UInt32 = base.next() print("base after; \(base)") return (high - low) * (Float(bitPattern: uint32 >> 9 | 0x3f80_0000) - 1) + low } } extension RandomNumberGenerator { public var uniform: Uniform { get { return Uniform(base: self) } set { print("before set: \(self)") self = uniform.base as! Self print("set self: \(self) \(uniform.base)") } } } struct DummyRNG: RandomNumberGenerator { static var `default` = DummyRNG.init() var state: UInt32 = 0 mutating func next<T>() -> T where T : FixedWidthInteger, T : UnsignedInteger { state += 123456789 return T(state) } } print(DummyRNG.default.uniform.next(low: 0, high: 1)) print(DummyRNG.default.uniform.next(low: 0, high: 1)) print(DummyRNG.default.uniform.next(low: 0, high: 1))
Avatar
swift42 BOT 7/2/2018 2:31 AM
base before; DummyRNG(state: 0) base after; DummyRNG(state: 123456789) before set: DummyRNG(state: 0) set self: DummyRNG(state: 0) DummyRNG(state: 0) 0.02874446 base before; DummyRNG(state: 0) base after; DummyRNG(state: 123456789) before set: DummyRNG(state: 0) set self: DummyRNG(state: 0) DummyRNG(state: 0) 0.02874446 base before; DummyRNG(state: 0) base after; DummyRNG(state: 123456789) before set: DummyRNG(state: 0) set self: DummyRNG(state: 0) DummyRNG(state: 0) 0.02874446
Avatar
setに入ってくるuniformが変化前のになってる?
2:33 AM
あ。馬鹿だ。uniformじゃなくてnewValue使わないと
2:33 AM
大丈夫でした。
Avatar
完成品がこちらになります。 https://github.com/t-ae/rng-extension
rng-extension - Swift extension for RandomNumberGenerator
Avatar
プロトコル型で持たずに Uniform<Random : RandomNumberGenerator> にした方が Swifty じゃないですか?
Avatar
いままさにそれ考えてたんですけどextensionでself渡すところできるんですっけ?
6:53 AM
RandomNumberGeneratorに生やすとそれ自体が適合してなくて云々みたいになるとおもうんですが
6:55 AM
あれ?普通にできそうだな
Avatar
ジェネリックにしてみました。特定のRNGでextensionを生やせるようになって良い感じに
👍 1
Avatar
@t.ae basefileprivate にする PR 送ろうかと思ったら、逆に 1.0.0 から 1.0.1internalpublic な変更がされてるんですが、この意図は何でしょう?
8:28 AM
あと、この変更は後方互換のある API の変更なので、 sem ver 的には 1.0.01.1.0 の変更だと思います。
Avatar
https://github.com/t-ae/xorswift/blob/swift4.2/Sources/Uniform.swift 外部に高速実装を生やすためにbaseを参照できるようにしました。 基本見えても問題ないはずなので…… (edited)
xorswift - Xorshift pseudorandom number generator library for Swift.
8:29 AM
masterじゃなくて4.2ブランチだった
Avatar
そして、作った直後はこういう微妙な変更が発生しがちなので、しばらくは -alpha-beta, -beta.2 等を付けておくのがオススメです。
8:30 AM
(あと、 1.0.0 から始めずに 0.1.0 から始めた方が気軽に破壊的変更しやすいです。)
Avatar
アルファつけるの忘れてましたねぇ。x.x.15とかいってるのもあるので覚えておくようにします。
Avatar
patch は API の変更はないバグ修正なので、 API の修正は互換性があってもマイナーを、互換性がないとメジャーを上げないといけないので辛いです・・・。
8:32 AM
↓これも base を外部から使ってなくないですか? https://github.com/t-ae/xorswift/blob/swift4.2/Sources/Uniform.swift
xorswift - Xorshift pseudorandom number generator library for Swift.
Avatar
0.0.xでいつもはやってたんですけどね、いつまでも1にならないので……
8:33 AM
base.xとかが出てきます
Avatar
あるあるですねw < いつまでも 1 にならない
8:33 AM
しかし、 1.0.0 というのはそれだけの重みがあることの裏返しな気も
8:34 AM
Swift の 1.0 はおかしかったけど、 Kotlin とかずいぶん長い間 1.0 にならなかったし。
8:35 AM
あー、 .base で検索してた😅
Avatar
ある程度安定してから1.0.0にするのが良かったですね。今回は思いつきで他のライブラリと統合したのでタイミングが悪かった感じです
Avatar
あらためてRandomのプロポーザル見てるとFloat.random(in:)がありましたね。 normalもこっちの形式に揃えるほうがいいんだろうか……
Avatar
Qiita で通知が来て 2014 年のコメントが発掘されたけど、何もかも古くておもしろかった。 https://qiita.com/Kenya/items/dced88c4508302786f24#comment-a88dbd8e88cf31abf996
俺の名はケンヤ。難事件をいくつも迷宮入りさせたニート。しかし ある時謎の組織に入社し薬を飲まされ身体が縮んで Braian になっちゃった。 ##mapを使用した変換 ``` var numbersString: [St...
Avatar
omochimetaru 7/5/2018 6:54 AM
toInt
Avatar
今だったら strings.compactMap(Int.init) で、 flatMap 以前なので 3 週古くて(リネーム前の flatMapArray を返す flatmapreduce
6:55 AM
reduce 使うにしても今だったら reduce(into:_:) だし。
Avatar
@swiftbot let a = [[2], [3 ,5]] for var (i, numbers) in a.enumerated() { numbers.append(3) print("\(i): \(numbers)") }
🛠 1
Avatar
swiftbot BOT 7/5/2018 8:46 AM
Author icon
koher
let a = [[2], [3 ,5]] for var (i, numbers) in a.enumerated() { numbers.append(3) print("\(i): \(numbers)") }
Version:
swift-4.1.1-RELEASE
Output:
0: [2, 3] 1: [3, 5, 3]
Error:
/usercode/main.swift:3:10: warning: variable 'i' was never mutated; consider changing to 'let' constant for var (i, numbers) in a.enumerated() { ^
Avatar
↑の warning 出なくする方法ってありますか? numbersvar に、 ilet にしたい。
8:48 AM
あー、ちがう
8:48 AM
これはできる
8:49 AM
@swiftbot let a = [[2], [3 ,5]] for (i, var numbers) in a.enumerated() { numbers.append(3) print("\(i): \(numbers)") }
🛠 1
Avatar
swiftbot BOT 7/5/2018 8:49 AM
Author icon
koher
let a = [[2], [3 ,5]] for (i, var numbers) in a.enumerated() { numbers.append(3) print("\(i): \(numbers)") }
Version:
swift-4.1.1-RELEASE
Output:
0: [2, 3] 1: [3, 5, 3]
Error:
Avatar
↓こっち。 Optional binding で varlet に bind したい。 @swiftbot let a = [[2], [3 ,5]] var iterator = a.enumerated().makeIterator() if var (i, numbers) = iterator.next() { numbers.append(0) print("\(i): \(numbers)") }
🛠 1
Avatar
swiftbot BOT 7/5/2018 8:52 AM
Author icon
koher
let a = [[2], [3 ,5]] var iterator = a.enumerated().makeIterator() if var (i, numbers) = iterator.next() { numbers.append(0) print("\(i): \(numbers)") }
Version:
swift-4.1.1-RELEASE
Output:
0: [2, 0]
Error:
/usercode/main.swift:4:9: warning: variable 'i' was never mutated; consider changing to 'let' constant if var (i, numbers) = iterator.next() { ^
Avatar
if case (let i, var numbers)? = iterator.next() {
Avatar
あー、なるほど! case にしちゃえばいいのか。ありがとうございます!
Avatar
https://github.com/apple/swift/blob/master/stdlib/public/core/Integers.swift.gyb#L2939-L2956 このアンスコ付き_random()random(in: UnboundedRange)にしたら?って提案しようかと思うんですがこういう細かい&そもそもまだ固まってない内容もフォーラムにスレッド立てていいんですかね? RandomUnificationのスレはちょっと古くて……
swift - The Swift Programming Language
Avatar
@t.ae Random Unification はすでに implemented だから別スレで問題ないんじゃないでしょうか。 random(in: UnboundedRange) は新しい API の提案だし、 reduce(into:_:)togglecompactMapValues を考えると、単独の API の提案は全然ありな気がします。
1:24 AM
最終的には FixedWidthInteger に限らず検討することになるかもしれないにしても、 pitch は気軽に投げていいんじゃないでしょうか。
1:25 AM
swift-evolution - This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
Avatar
On master branch, we have FixedWidthInteger._random() function for sampling random numbers from full range. I think we should have FixedWidthInteger.random(in: UnboundedRange) for this purpose. There is FixedWidthInteger.random(in: Range) function. So adding UnboundedRange...
2:23 AM
Discussionタグは割とラフに提案できそうだったのでそれで
Avatar
<.. がほしくなった。
1:13 AM
↓がしたくなったら struct Foo { var bar: Bar { mutating get { ... } } } ↓に書き換えた方がいいでしょうか? struct Foo { mutating func bar() -> Bar { ... } }
Avatar
目的によると思いますが、キャッシュ的なものですか?
Avatar
get されてから lazy に読み込んでキャッシュしたいケースです。
Avatar
var foo1 = Foo() var foo2 = foo1 var bar = foo2.bar というときに、foo1 にキャッシュが共有されないというのが許容出来る場合、僕なら mutating func bar() にします。
1:28 AM
許容できないなら class にするか、グローバルにキャッシュを持つしかない。
Avatar
素直にclassにした方が良さそうな気はします
1:30 AM
class+lazy varがシンプルに感じる
Avatar
キャッシュが共有されないこと自体はいいんですが、今のケースではクラスにしないとまずい気がしてきました。
Avatar
なかなかファニーなエラーが出るのですが、これ何が原因なんでしょう。基本的には健全なコードだと感じますが: protocol P { associatedtype T func f(_ g: @escaping (T) -> Void) } class C<S>: P { typealias T = S private let _f: ((S) -> Void) -> Void init<Q: P>(q: Q) where Q.T == T { // Error: cannot assign value of type '((S) -> Void) -> Void' to type '((S) -> Void) -> Void' self._f = { g -> Void in q.f(g) } } func f(_ g: @escaping (S) -> Void) { self._f(g) } }
🍰 1
Avatar
protocol P { associatedtype T func f(_ g: @escaping (T) -> Void) } class C<S>: P { typealias T = S private let _f: (@escaping (S) -> Void) -> Void init<Q: P>(q: Q) where Q.T == T { // Error: cannot assign value of type '((S) -> Void) -> Void' to type '((S) -> Void) -> Void' self._f = { g -> Void in q.f(g) } } func f(_ g: @escaping (S) -> Void) { self._f(g) } }
11:14 AM
どぞ
Avatar
あ、そこも escaping つくのか。。。
11:15 AM
ありがとうございます、明白だと勘違いしてました
Avatar
cannot assign value of typeのエラーわかりにくい問題、最新のXcodeだと治ってて一発でわかりますよ
Avatar
お、なるほど
11:16 AM
あー、9.4.1 でした
11:16 AM
ということは、Beta の方ですか?
Avatar
すんませんぱちこいた
11:16 AM
なんで俺は一瞬で見抜いたんだ
Avatar
ww
Avatar
何度試しても同じエラーです、なんでわかったんだ。。。
Avatar
天のお告げ
Avatar
omochimetaru 8/6/2018 11:17 AM
ディスコで既出だからでは?
Avatar
既出だったっけ
Avatar
omochimetaru 8/6/2018 11:17 AM
うん。
Avatar
ざっくり見たことある気はするけど、にしても@escaping入れなきゃいけない位置を秒で特定できたのはちょい謎
Avatar
_f が escaping なの明白だからという流れで、引数側も明白だと勘違いした感じですね… 引数は明白じゃないのは落ち着いて考えないとわからなかったです
Avatar
いや、@escaping必要だって、、わいのXcodeは表示したんや…そのはずや…
Avatar
omochimetaru 8/6/2018 11:19 AM
改善のコントリビュートしよう
Avatar
これは、どこでしょうね。エラーの文字列化のときに escaping の表示が外れてる匂いがしますが、コード追ったことないんで見に行ってきます
🚗 1
11:30 AM
このトピック #swift-contrib 感あるので移動します
Avatar
最近気付いたんですが、self の再宣言で LLDB 壊れますね class Example { func ok() { let f = { [weak self] in guard let strongSelf = self else { return } // Set a breakpoint at here print(strongSelf) } f() } func error() { let f = { [weak self] in guard let `self` = self else { return } // Set a breakpoint at here print(self) } f() } } Example().ok() Example().error()
😲 1
6:16 AM
(lldb) br set --file example.swift --line 7 Breakpoint 1: where = example`closure #1 () -> () in example.Example.ok() -> () + 111 at example.swift:7, address = 0x00000001000017df (lldb) br set --file example.swift --line 18 Breakpoint 2: where = example`closure #1 () -> () in example.Example.error() -> () + 111 at example.swift:18, address = 0x00000001000019cf (lldb) r Process 6298 launched: '/Users/yuki.kokubun/Development/self-self-lldb/example' (x86_64) Process 6298 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 frame #0: 0x00000001000017df example`closure #1 in Example.ok(self=0x0000000100802b30) at example.swift:7 4 guard let strongSelf = self else { return } 5 6 // Set a breakpoint at here -> 7 print(strongSelf) 8 } 9 10 f() Target 0: (example) stopped. (lldb) po self ▿ Optional<Example> - some : <Example: 0x100802b30> (lldb) c Process 6298 resuming example.Example Process 6298 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1 frame #0: 0x00000001000019cf example`closure #1 in Example.error(self=0x0000000100a01030) at example.swift:18 15 guard let `self` = self else { return } 16 17 // Set a breakpoint at here -> 18 print(self) 19 } 20 21 f() Target 0: (example) stopped. (lldb) po self error: warning: <EXPR>:12:9: warning: initialization of variable '$__lldb_error_result' was never used; consider replacing with assignment to '_' or removing it var $__lldb_error_result = __lldb_tmp_error ~~~~^~~~~~~~~~~~~~~~~~~~ _ error: <EXPR>:18:5: error: value of type 'Example' has no member '$__lldb_wrapped_expr_2' $__lldb_injected_self.$__lldb_wrapped_expr_2( ^~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
6:17 AM
この場合、fr var は下のようになるので単純な名前ベースでの解決をしようとすると死ぬのが原因…? (lldb) fr var (@lvalue example.Example?) self = 0x0000000100a01030 (example.Example) self = 0x0000000100a01030 {}
Avatar
これは strongSelf の方がデバッグしやすくていいなぁ、とか思いました
Avatar
Kishikawa Katsumi 8/9/2018 6:39 AM
簡単なものだったらself?. で書くか、 クロージャの中で必要な変数をそれぞれguardでアンラップする、って感じに最近はしてますね。
6:40 AM
guard let `self` = self else { return } ^ のところをselfじゃなくて、selfの先を3〜4つアンラップする感じd。
6:40 AM
それかあらかじめローカル変数に受けるだけどそれは使えないことも多い。
😃 1
Avatar
必要な変数をunwrap、良いんですがfunctionがきつい…と思ったけどfunctionもアンラップ出来るのでは!?
6:41 AM
guard let fooMethod = self?.fooMethod else
6:41 AM
動きそう
Avatar
omochimetaru 8/9/2018 6:41 AM
その左辺のfooMethodが内部でselfをキャプチャしてるのがちょっと怖い (edited)
Avatar
此奴を又貸ししたら崩壊しますね
Avatar
omochimetaru 8/9/2018 6:42 AM
うむ。岸川さんのやつだと、又貸しセーフなので。
Avatar
まあでも結局それってmap(fooMethod)が崩壊するいつものやつで
Avatar
Kishikawa Katsumi 8/9/2018 6:43 AM
guard let self = self else { return } <= これは見た目美しいけどトラブルが多いので良くない、 strongSelf <= これは人によって色々だしどう書いても美しくない、
Avatar
こっちもコンパイラで防ぐ仕組みはいってないからどうしようもないかなぁ
Avatar
omochimetaru 8/9/2018 6:43 AM
(まあ又貸し先でselfは消えたけど又貸ししたオブジェクトは生きてて処理続行が正なのかは微妙だけど)
Avatar
functionの是非はさておき、書き味めちゃくちゃ良いです。知れて良かった、ありがとうございます。
Avatar
Error のインスタンスが手元にあるときに、それでクラッシュさせる ( try! に失敗したのと同じ状態にする)簡単な方法ってありますっけ? fatalError("\(error)") でもいいのかもしれませんが、 Error から String に情報が落ちてしまってますし。
Avatar
omochimetaru 8/9/2018 8:13 AM
try! throw error
Avatar
try ! { throw error }() だと Never でないので guard で使えないですし。
Avatar
omochimetaru 8/9/2018 8:13 AM
おおなるほど
Avatar
try! throw errorthrow が関数じゃないからできなくない?
8:15 AM
internal func fatalError<E: Error>(with error: E) -> Never { try! { throw error }() fatalError("Never reaches here.") } という微妙なユーティリティ関数を作ろうとしたけどもっといい方法はないかなと。
Avatar
omochimetaru 8/9/2018 8:15 AM
↑自分の知見もそこまでです
Avatar
Java だと throw new RuntimeException(exception); とかでいいんだけど。
8:18 AM
( Swift でも Logic failure なら fatalError じゃなくて preconditionFailure がいいかな。 precondition なのか微妙だけど。)
Avatar
https://github.com/apple/swift/blob/d30aa32001227a860706d4b475352c46fc57b4dc/stdlib/public/core/ErrorType.swift#L180-L186 っちゅうわけなので、String(reflecting: error) で同等みたいです。
swift - The Swift Programming Language
🙏 1
Avatar
omochimetaru 8/9/2018 8:20 AM
_unexpectedError の返り値の型は Never ではないのですね
8:21 AM
swift_unexpectedError が呼ばれる命令が直接 emit されるのかな
Avatar
invoke って call と同じような意味かと思ってたけど、 "Invoked by the compiler" ってことは、ランタイム時にコンパイラ関係ないから、コンパイラが使う(コンパイル時にこの関数を呼び出すコードを差し込む)というようなニュアンス?
Avatar
一周回ってよくわからなくなった。 call にしても、関数を呼び出す主語は何だろう?プログラマ?コード?(その関数を呼び出す行が書かれている)関数?実行しているプログラム?
Avatar
CMSampleBuffer ってメソッドが何もなくて https://developer.apple.com/documentation/coremedia/cmsamplebuffer
9:40 AM
CMSampleBufferGetImageBuffer(_:) みたいな関数群があるけど https://developer.apple.com/documentation/coremedia/1489236-cmsamplebuffergetimagebuffer
9:41 AM
これらをひたすら呼び出す extension を作ってメソッド化して↓に突っ込めば良い? https://github.com/apple/swift/tree/master/stdlib/public/SDK/CoreMedia
swift - The Swift Programming Language
Avatar
EvolutionのReview開始ってAnnouncementsに流れなくなったのかな? https://forums.swift.org/c/evolution/announce
This category is for announcements of Swift evolution proposal reviews and results, as well as other administrative announcements. Creation of new topics in this category is by site admins and Swift Core Team members only, although anyone can reply to topics once created.
10:41 AM
SE-0223, SE-0224, SE-0225の開始がAnnouncementsに流れてなくて気づかなかった。
10:47 AM
あれ?Review開始は随分前からAnnouncementsに流れてなかったのか。気づいてなかった…
Avatar
そういや、すごい基本的なところお伺いしたいんですが、DispatchQueue 経由でメインスレッド以外の処理を実行するコードがあったとして、そのスレッドを breakpoint で止めたとき、この thread がどこのコードによって生成されたかってわかるのでしょうか?
Avatar
omochimetaru 8/24/2018 6:42 AM
Xcode+DispatchQueueだと表示されてますね
6:42 AM
asyncメソッドに投入する側の、投入するまでのスタックトレースが
6:42 AM
繋がって表示されます。
Avatar
なるほど、
Avatar
omochimetaru 8/24/2018 6:42 AM
仕組みはよく知らないです。
6:43 AM
あ、スレッドが生成されたかどうかは、わからないですね。
Avatar
JS でも似たような問題があって処理系が超頑張ってた覚えがあるのですが、Swift も同じような感じなのかな
Avatar
omochimetaru 8/24/2018 6:43 AM
原理的には
6:43 AM
投入するメソッドでスタックトレースを読み取って
6:44 AM
投入先のスレッドのスレッドローカルストレージとかに
6:44 AM
それをしまっておけばできる・・・?
Avatar
やっぱそんな感じになりますよね
Avatar
omochimetaru 8/24/2018 6:44 AM
多重に往復した場合にもうまくいくようになんか工夫が必要そうですが、
Avatar
Apple の NSTread のドキュメント見た感じだと、普通に触るところには露出してなさそうだったので諦めてました
Avatar
omochimetaru 8/24/2018 6:44 AM
あー
6:45 AM
Xcodeのその仕組に対応したスタックトレースをまたいでつなげるやつを
Avatar
あ、NSThread じゃなくて普通に Thread だった
Avatar
omochimetaru 8/24/2018 6:45 AM
自前の非同期機構に搭載する方法は謎ですね。
Avatar
あ、今回は DispatchQueue のやつなので、自前ではないんです
Avatar
omochimetaru 8/24/2018 6:46 AM
それならDispatchqueueの仕組みで自然と対応されません?
Avatar
DispatchQueue.global(qos: .default).async { // この中で [NSException raise] が呼ばれていて、 // breakpoint set -S raise で止まった状態を想定してください。 // ここで、この doSomething を呼び出す task を誰が追加したのか // 追跡したい感じです。 doSomething() }
6:48 AM
一応認識合わせのためにコード書いて見ました
6:49 AM
Xcode では試してないのですが、AppCode では pthread 生成のコードが callstack の底にあったので、呼び出し元がわからない感じになってました
Avatar
omochimetaru 8/24/2018 6:53 AM
stack
6:53 AM
Xcodeだとこういう感じです。
Avatar
うぉ、ほんとだ
6:53 AM
ちなみに、この時の (lldb) th b の結果はおそらく上だけな感じですよね?
6:54 AM
これどうやってるんだ、、、
Avatar
omochimetaru 8/24/2018 6:54 AM
(lldb) th backtrace * thread #3, queue = 'com.apple.root.default-qos', stop reason = breakpoint 1.1 frame #0: 0x000000010e89e001 libobjc.A.dylib`objc_exception_throw frame #1: 0x000000010f2090b9 CoreFoundation`-[NSException raise] + 9 * frame #2: 0x000000010df90ea6 StackChain`doInnerSomething() at ViewController.swift:8 frame #3: 0x000000010df90e19 StackChain`doSomething() at ViewController.swift:4 frame #4: 0x000000010df910c9 StackChain`closure #1 in ViewController.onButton() at ViewController.swift:14 frame #5: 0x000000010df910fd StackChain`thunk for @escaping @callee_guaranteed () -> () at ViewController.swift:0 frame #6: 0x000000011359b7ab libdispatch.dylib`_dispatch_call_block_and_release + 12 frame #7: 0x000000011359c7ec libdispatch.dylib`_dispatch_client_callout + 8 frame #8: 0x00000001135a1619 libdispatch.dylib`_dispatch_queue_override_invoke + 1451 frame #9: 0x00000001135a836c libdispatch.dylib`_dispatch_root_queue_drain + 664 frame #10: 0x00000001135a8076 libdispatch.dylib`_dispatch_worker_thread3 + 132 frame #11: 0x0000000113ac7169 libsystem_pthread.dylib`_pthread_wqthread + 1387 frame #12: 0x0000000113ac6be9 libsystem_pthread.dylib`start_wqthread + 13 (lldb)
6:54 AM
ほんとですね。
Avatar
てことは Xcode が何やら裏側でやっているのか。。。
Avatar
omochimetaru 8/24/2018 6:54 AM
lldbの外でやってるのか。
Avatar
む、、、これよくみたら frame #3 に変なの載ってますね。StackChain って語感からすると、別スレッドの退避された環境を戻すためのもの…?
Avatar
omochimetaru 8/24/2018 7:07 AM
StackChain、というのは僕がつけたプロジェクト名です
Avatar
あ、なるほど w
7:08 AM
これ、UI を main thread 以外で触って怒られた時のデバッグで頻出するパターンなんですが、AppCode でやりづらいのはつらいので機能要望をあげておきます
Avatar
norio_nomura 8/24/2018 9:37 AM
thread backtrace -e trueでEnqueued from…の内容も見られますね。
Avatar
(lldb) h th b Show thread call stacks. Defaults to the current thread, thread indexes can be specified as arguments. Use the thread-index "all" to see all threads. Use the thread-index "unique" to see threads grouped by unique call stacks. Syntax: Command Options Usage: thread backtrace [-c <count>] [-s <frame-index>] [-e <boolean>] -c <count> ( --count <count> ) How many frames to display (-1 for all) -e <boolean> ( --extended <boolean> ) Show the extended backtrace, if available -s <frame-index> ( --start <frame-index> ) Frame in which to start the backtrace
9:42 AM
なんと、超便利オプションだ…
9:42 AM
@norio_nomura ありがとうございます
🙂 1
Avatar
omochimetaru 8/24/2018 9:42 AM
extended backtrace!
Avatar
まったく存在に気づいていなかったw
Avatar
norio_nomura 8/24/2018 9:43 AM
/usr/lib/system/introspectionを使った機能みたいです。
Avatar
$ ls /usr/lib/system/introspection libdispatch.dylib* libsystem_pthread.dylib*
9:44 AM
なるほど、これは
9:46 AM
* @discussion * These hooks are only available in the introspection version of the library, * loaded by running a process with the environment variable * DYLD_LIBRARY_PATH=/usr/lib/system/introspection
9:46 AM
なるほど、LD_PRELOAD 的なので差し込まれるのか
9:46 AM
ありがとうございます
Avatar
norio_nomura 8/24/2018 9:50 AM
Xcodeは勝手に面倒を見てくれますが、ターミナルからlldbを直接起動する場合とかは自分で設定する必要があるみたいです。
Avatar
あー、なるほど
9:52 AM
そして AppCode では話題にも上がっていないっぽいw
9:52 AM
てことは、Scheme の環境変数に自前で追加してあげないとダメっぽいですね
9:53 AM
一応後で AppCode の LLDB で target module list かけてみて libdispatch.dylib が本物っぽいかどうかだけ確認してみます
9:54 AM
もし面倒見てくれてたら別なの見てると思うので
Avatar
norio_nomura 8/24/2018 9:55 AM
試しにprocess launch -v DYLD_LIBRARY_PATH=/usr/lib/system/introspection/usr/lib/system/introspection/libdispatch.dylibをロードしただけでは、thread backtrace -e trueは意図した通りに動きませんでした。 🤔
Avatar
なるほど、なんでしょうね、まだ必要な操作があるのか…
Avatar
/Applications/Xcode.app/Contents/Developer/usr/lib/libBacktraceRecording.dylibってのをlldb-rpc-serverは使ってるけど、lldbplugin load /Applications/Xcode.app/Contents/Developer/usr/lib/libBacktraceRecording.dylib してもダメだった。 (edited)
Avatar
process launch -v DYLD_LIBRARY_PATH=/usr/lib/system/introspection -v DYLD_INSERT_LIBRARIES=/Applications/Xcode.app/Contents/Developer/usr/lib/libBacktraceRecording.dylib でイケた。
Avatar
norio_nomura 8/28/2018 3:44 AM
swift -frontend -replなんてのがあったのね。 $ swift -frontend -repl *** You are running Swift's integrated REPL, *** *** intended for compiler and stdlib *** *** development and testing purposes only. *** *** The full REPL is built as part of LLDB. *** *** Type ':help' for assistance. *** (swift) :help Available commands: :quit - quit the interpreter (you can also use :exit or Control+D or exit(0)) :autoindent (on|off) - turn on/off automatic indentation of bracketed lines :constraints debug (on|off) - turn on/off the debug output for the constraint-based type checker :dump_ir - dump the LLVM IR generated by the REPL :dump_ast - dump the AST representation of the REPL input :dump_decl <name> - dump the AST representation of the named declarations :dump_source - dump the user input (ignoring lines with errors) :print_decl <name> - print the AST representation of the named declarations :print_module <name> - print the decls in the given module, but not submodules API documentation etc. will be here eventually. (swift)
Avatar
omochimetaru 8/28/2018 3:45 AM
$ swift のときに突入するのがそれだと思ってました (edited)
Avatar
norio_nomura 8/28/2018 3:46 AM
普通のREPLには無い機能ばかりです。lldbを使わないので、--privileged無しのdockerでも使える。
Avatar
omochimetaru 8/28/2018 3:46 AM
そうなのか!
3:47 AM
lldbを使わないので、--privileged無しのdockerでも使える。
これ地味にいいですね。
Avatar
norio_nomura 8/28/2018 3:48 AM
Herokuが--privileged無しdockerなので、Herokuで動いてるSwiftボットでも、修正すれば使える様になりそう。
Avatar
swift -deprecated-integrated-repl がそれですね。
Avatar
omochimetaru 8/28/2018 3:48 AM
deprecatedw
3:49 AM
[omochi@omochi-iMac-PC43 bne-loci (master *+=)]$ swift -deprecated-integrated-repl *** You are running Swift's integrated REPL, *** *** intended for compiler and stdlib *** *** development and testing purposes only. *** *** The full REPL is built as part of LLDB. *** *** Type ':help' for assistance. *** (swift) ^D [omochi@omochi-iMac-PC43 bne-loci (master *+=)]$ swift Welcome to Apple Swift version 4.2 (swiftlang-1000.0.36 clang-1000.0.4). Type :help for assistance. 1> ^D [omochi@omochi-iMac-PC43 bne-loci (master *+=)]$ swift -frontend -repl *** You are running Swift's integrated REPL, *** *** intended for compiler and stdlib *** *** development and testing purposes only. *** *** The full REPL is built as part of LLDB. *** *** Type ':help' for assistance. *** (swift) ^D
3:50 AM
-frontend -repl のほうが -deprecated-integrated-repl か・・・
Avatar
norio_nomura 8/28/2018 3:50 AM
使えて意味がありそうなのはprint_declprint_moduleくらいだけど、どれも出力が大きくなるからボットで使えてもありがたみが薄いかな?
Avatar
norio_nomura 8/28/2018 4:55 AM
@swift-4.2.4 -frontend -repl :print_decl Equatable
Avatar
protocol Equatable { static func == (lhs: Self, rhs: Self) -> Bool } extension Equatable { @inlinable static func != (lhs: Self, rhs: Self) -> Bool }
Avatar
norio_nomura 8/28/2018 4:55 AM
-frontend -replサポート出来た。
Avatar
norio_nomura 8/28/2018 9:37 AM
https://swift.org/download/#snapshotsswift-DEVELOPMENT-SNAPSHOT-2018-08-26-a があるけど https://github.com/apple/swift/tags にタグが無いな。gitで見ても無さげ。
Swift is a general-purpose programming language built using a modern approach to safety, performance, and software design patterns.
The Swift Programming Language. Contribute to apple/swift development by creating an account on GitHub.
9:39 AM
新しいツールチェインの検出をGitHubのAPIに頼ってるから、swift.orgだけに現れても検出できない…
Avatar
Go 2 のエラーハンドリングのドラフト、 Swift のエラーハンドリングについても言及されてる。 https://go.googlesource.com/proposal/+/master/design/go2draft-error-handling-overview.md
😀 1
Avatar
結構よさそう
Avatar
omochimetaru 8/29/2018 2:51 AM
Swiftのtryオペレータみたいにcheck命令を書くんですね
2:51 AM
handleスコープをメソッド冒頭にもかけるのはSwiftに無い機能だな
Avatar
Genericsもあるらしいんですがこれであってますかね? https://go.googlesource.com/proposal/+/master/design/go2draft-contracts.md
Avatar
omochimetaru 8/29/2018 2:52 AM
これはprotocolみたいなやつじゃない?
2:52 AM
Generics名乗ってはいるんですよね
2:52 AM
overviewは↑だった
Avatar
omochimetaru 8/29/2018 2:53 AM
ただのGenericsだと、
2:53 AM
その型パラメータに何ができるのってことがわからないから
2:53 AM
型パラメータの型を制約して呼び出せるメソッドとかを宣言しないと意味がなくて
2:53 AM
Javaだと T: Hoge みたいに書けるけど、
2:54 AM
その継承縛りだけだとできない事も出てくるからSwiftのprotocolみたいなものが必要になってきて
2:54 AM
それがGoだとcontractなのではなかろうか
2:54 AM
C++も同様の問題があって concept という言語機能が検討されている
Avatar
ふむふむ
Avatar
動的型付言語から静的型付言語に揺り戻しが来たように、暗黙的エラーから明示的エラーに揺り戻しが来てんのかな。 Java が面倒過ぎた反動で動的・暗黙的に偏りすぎたけど、本来的には必要なものだったから改善して戻ってきたみたいな? (edited)
Avatar
omochimetaru 8/29/2018 2:55 AM
Goにちゃんとした型制約が提案されてるのは意外だけど。
2:55 AM
もっとやるとしてもC++ライクな適当なジェネリクスというかコンパイル時ダックタイピング的なものになるかとおもた
2:56 AM
あーでもジェネリッククラス自体をコンパイルするときにはヒントが足りないからこういう宣言機構がやっぱり必要なのかな。
2:57 AM
どうなんでしょう、Goはもともと明示的エラーハンドリングが強く推奨されていたから
2:57 AM
揺り戻すというよりGoはもともとそうだったという感じがします
Avatar
Go がというよりも、暗黙的一辺倒だったのが最近明示的が増えてきたことに対して。
3:00 AM
この冒頭に handle 書くの、気持ち悪い気がしたけど defer 的な気持ちで見れば良いのか。
3:02 AM
全体を do/catch で囲まなくてよいのでネストが深くならないのが良い?
Avatar
omochimetaru 8/29/2018 3:03 AM
Guidelines for using language features to write maintainable code.
3:03 AM
フラッタ〜に採用されとるDart2を見てるけど
3:03 AM
動的例外な気がする
Avatar
finally を採用せずに defer にしたんだったら、この handle みたいなのの方が理に適ってる気がするけどどうだろう? (edited)
Avatar
omochimetaru 8/29/2018 3:05 AM
個人的にはcatchするとdoが必要でネストするのが嫌いなのでこのネストしないhandleは良いなと思ったけど
3:05 AM
deferがあるなら、という理由で理に適ってるという理屈はよくわからないです
3:05 AM
特に、catchスコープの後ろに文が書けるけど、handleだとそれができなそう。
Avatar
これコードブロックの解析面倒くさそうだなって思ったんですが、swiftよろしく同一func内に複数handleを書こうとすると、それは無理だったりするのかな
Avatar
omochimetaru 8/29/2018 3:10 AM
このhandleはfunc内のエラーを全部捕まえそうに見える
Avatar
都度handleで綺麗な状態にするのは無理がある気はする、人間が変数の有効期限を認知できない
3:10 AM
だよね
Avatar
omochimetaru 8/29/2018 3:11 AM
あ、もしかしたら、
3:11 AM
ifの中のスコープにhandleをかけば
Avatar
swiftのdoって無名funcよろしく振る舞えるのだけど、そういうのは無理そうだな
Avatar
omochimetaru 8/29/2018 3:11 AM
そのifスコープの範囲で捕まえるのかな?
Avatar
スコープが明示的に切れてその上で出来るなら
3:11 AM
かなり良さそうですね
3:11 AM
そして #other-lang でないことに気が付く
Avatar
omochimetaru 8/29/2018 3:12 AM
Goは空スコープ作れたっけな・・・
Avatar
handle とスコープについては、 Go の defer はスコープ関係なく関数単位だったはずだから、 handle はどうなんだろう?とさっきから思ってる。
3:13 AM
そして #other-lang でないことに気が付く
最初は Swift に言及されてるよ、だったので😅 #other-lang 行きますか。
11:46 AM
こういう感じのグラフを生成できるいい感じの Swift 製ライブラリってありますかしら? (edited)
Avatar
@tarunon privateな行なのにいじると問答無用でフルビルドが始まるみたいなのってどういう状況で起こるんだっけ
Avatar
AがBをimportしているとき、Bの型の構造が少しでも変わるとAはフルビルド
11:35 AM
ABIまだだから残当な気もしている
😯 1
Avatar
それってobjc関係してるんだっけ
12:47 PM
「型の構造」っていうのは外から見た可視性は関係ない?
Avatar
objcのブリッジングがコンパイル時間の重きを占める上に本体に存在してあらゆる場面で発火するから結構ストレス
12:47 PM
経験則的に可視性関係なくメソッド変わったら発火する
12:48 PM
internalなクラスを増やしたり、overrideちょっと変えたりしても大体アウト
Avatar
AがBをimportしているとき、Bの型の構造が少しでも変わるとAはフルビルド
これはどっちかがobjc含んでたらみたいな話なんだっけ?
Avatar
swiftだけでも起きるかもだけど、被害に遭うのはアプリ本体で、往々にしてそこにobjcブリッジングがある。
12:51 PM
swiftだけで発生するかは確認していない
Avatar
モジュール分割を推し進めていくと食らう可能性があるよね
Avatar
いや、そもそも可視性関係なくswift書き換えたらobjcブリッジングが発火するのは本体アプリオンリーでも起きる
Avatar
importっていうのはそういうことか
12:53 PM
モジュールの話かと思った
Avatar
頻度の問題で、 1. 開発速度が間違いなく向上する 2. Frameworkはswiftオンリーなのでobjc書かない と言う二つの事象でswiftを書く頻度が確実に上がる
12:54 PM
これがビルドに対するストレスとして顕在化するんじゃ
Avatar
うーん
Avatar
後もう一個、 3. 全体で底上げされるのでマージ&フルビルドも増える
Avatar
norio_nomura 9/25/2018 1:14 PM
#uikit で出てたStringからNSStringへの暗黙変換が起きる条件って何だろう?
1:16 PM
例えばNSString.character(at:)は、Linuxでは4.2から起きる。 @swift-4.0.3 @swift-4.1.3 @swift-4.2.4 -frontend -repl import Foundation "test".character(at: 0) (edited)
Avatar
// r0 : unichar = 116 (edited)
Avatar
stderr:<REPL Input>:1:1: error: value of type 'String' has no member 'character' "test".character(at: 0) ^~~~~~ ~~~~~~~~~ Swift.String:42:16: note: did you mean 'characters'? public var characters: String.CharacterView { get set } ^ (edited)
Avatar
stderr:<REPL Input>:1:1: error: value of type 'String' has no member 'character' "test".character(at: 0) ^~~~~~ ~~~~~~~~~ Swift.String:10:16: note: did you mean 'characters'? public var characters: String.CharacterView { get set } ^ Swift.String:8:16: note: did you mean '_characters'? public var _characters: String._CharacterView { get set } ^ (edited)
Avatar
norio_nomura 9/25/2018 1:19 PM
macOSだと起きない。 $ echo 'import Foundation; "test".character(at: 0)'|swift -frontend -repl -sdk `xcrun --sdk macosx --show-sdk-path` <REPL Input>:1:20: error: value of type 'String' has no member 'character' import Foundation; "test".character(at: 0) ^~~~~~ ~~~~~~~~~ Swift.String:10:16: note: did you mean 'characters'? public var characters: String.CharacterView { get set } ^ Swift.String:8:16: note: did you mean '_characters'? public var _characters: String._CharacterView { get set } ^
Avatar
現状の master のソースを見る限り、1) 元のタイプが Swift.String であり、2) Swift.String_ObjectiveCBridgeable であり、 3) lookupするメンバー名が Swift.String に生えておらず、 4) ブリッジ先タイプにはそのメンバーが存在し 5) 存在するモジュールが Clang モジュールの Foundation 以外のとき。 っていう条件なので、 corelibs-foundation は 5 の条件をすり抜けて見えちゃっている感じっぽいですね。 (edited)
1:43 PM
The Swift Programming Language. Contribute to apple/swift development by creating an account on GitHub.
Avatar
なるほど。Swift 4.2でNSStringにインスタンスメンバーを追加すると、Stringからも使えてしまうと。 @swift-4.0.3 @swift-4.1.3 @swift-4.2.4 -frontend -repl import Foundation extension NSString { func hoge() -> String { return "hoge" } } "test".hoge()
Avatar
// r0 : String = "hoge"
Avatar
stderr:<REPL Input>:1:1: error: value of type 'String' has no member 'hoge' "test".hoge() ^~~~~~ ~~~~
Avatar
stderr:<REPL Input>:1:1: error: value of type 'String' has no member 'hoge' "test".hoge() ^~~~~~ ~~~~
Avatar
https://swift.org/blog/swift-4-2-released/ でSupport for batch mode compilation resulting in faster build timesと言及されているものについて。 この件はWWDC 2018のセッションでも紹介がありました: https://developer.apple.com/videos/play/wwdc201...
2:40 AM
「複数ファイル単位でコンパイル」って具体的にどういうことなんだろう
2:40 AM
1コアごとに1ファイルずつ順番にコンパイルしてたのが、ってことだと思うんだけど、ピンとこないです
Avatar
omochimetaru 9/28/2018 2:40 AM
コンパイラが複数のファイルを同時に受け付けて
2:41 AM
コンパイルするか
2:41 AM
一つのファイルを受けて一つのオブジェクトを吐くか
Avatar
一時期あった「ソースコードを全部1ファイルにまとめるとコンパイル速いじゃん」と同じような話なのかなと思ったんだけど
2:42 AM
違う?
Avatar
omochimetaru 9/28/2018 2:42 AM
1つのswiftコマンドの呼び出しに
2:42 AM
いくつのソースファイルがコマンド引数として渡されているか
2:42 AM
という話です
Avatar
あーピンときた
2:43 AM
今までは1ファイルしか渡せなかったのが複数渡せるようになったってことか
Avatar
omochimetaru 9/28/2018 2:43 AM
デバッグモードに関してはそう。
Avatar
ふむ
Avatar
omochimetaru 9/28/2018 2:43 AM
リリースモードはもともと複数渡しだった。
Avatar
なるほどー
Avatar
omochimetaru 9/28/2018 2:43 AM
リリースモードは複数渡しにすることで
2:43 AM
whole module optimization
2:44 AM
つまり、「モジュールの中にサブクラスが一個も無いから実質ファイナル」とか
2:44 AM
そういう最適化ボーナスがついてたけど
2:44 AM
そのためには全部のファイルを渡さないといけないから
2:44 AM
開発中にそれをやると毎回のビルドが時間がかかってしまうから
2:45 AM
デバッグモードでは1コマンド1ファイルにして
2:45 AM
変更されたものだけビルドしてた
2:45 AM
今回のアップデートで、 変更されたいくつかのファイルを1コマンドでビルド っていう新しい挙動が実現されたんじゃないかな?
Avatar
あー
2:46 AM
インクリメンタルビルドと組み合わせて美味しさが増したって感じかあ
Avatar
omochimetaru 9/28/2018 2:46 AM
良いとこ取りって感じだと思う
Avatar
いいね
2:46 AM
「Xcode10にしたらビルドがめっちゃ速くなった」という事実だけ体感していてなんでやと思ってたけど納得した
Avatar
以前が1ビルド1ファイル渡しっていうのは ちょっと正確ではなくて、今までも全部のファイルを渡していました。 が、コンパイル対象は一つだけ。他のファイルはCにおけるヘッダファイル的に宣言のみが使われていました。当然それらの宣言のタイプチェックも必要なので、仮に3ファイルあるとすると、3回のコンパイルで、のべ9ファイル分のタイプチェックが走っていたので効率が悪かったのです。
Avatar
omochimetaru 9/28/2018 2:54 AM
あれ?そのタイプチェクした結果は、.swiftmodule ファイルとしてキャッシュされないですか?
Avatar
インクリメンタルビルドにおいて、ファイル毎.swiftmodule は依存の解決には使われていなかったと思うのですが、記憶違いかも。 (edited)
Avatar
omochimetaru 9/28/2018 2:58 AM
The Swift Programming Language. Contribute to apple/swift development by creating an account on GitHub.
2:58 AM
前にこのへんを読んでいて、SwiftPMの挙動は確認したんだけど、
2:58 AM
xcodebuildはよくしらべてない・・・
2:59 AM
And some build systems (coughXcodecough) want to individually track persisted output files, instead of dumping them into a temporary directory. Trying to specify the outputs for every input file on the command line would be awkward and ridiculous, so instead we use an output file map.
(edited)
2:59 AM
ここらへんで いくつかのビルドシステム(コホン Xcode コホン) のために
2:59 AM
依存ツリーをダンプしたファイルを作ってうんたらかんたら
Avatar
ちょっと挙動確認してからまた書きますね。
Avatar
盛り上がってる〜 Batch Modeの挙動・実装を正確に追うのはちょっと時間なかったので、ある程度ぼかして書いていました
Avatar
omochimetaru 9/28/2018 3:15 AM
SwiftPMならまだなんとか調べられるんだけど、xcodebuildだとSDKとかいろいろ渡されすぎてて気が遠くなるw
Avatar
やっぱりインクリメンタルビルドでファイル毎 .swiftmodule は出力されるものではありますが、他ファイルのコンパイル時に参照されて使われる物ではないですね。A.swift,B.swift, C.swiftあったときにクリーンビルドだと swift -frontend -c -primary-file A.swift B.swift C.swift swift -frontend -c A.swift -primary-file B.swift C.swift swift -frontend -c A.swift B.swift -primary-file C.swift の 3 フロントエンド実行されて、frontend に -primary-file じゃないファイルの .swiftmodule があったらそれに読み替えるみたいな機能はないので。
Avatar
norio_nomura 9/28/2018 3:31 AM
Xcode 10からデフォルトになったNew Build Systemは、SwiftPM同様にllbuildマニフェストを使います。 Xcodeはマニフェストを ${PROJECT_TEMP_ROOT}/XCBuildData/*-manifest.xcbuild に生成します。 それらをSwiftPMの.build/debug.yamlとかと比較すると違いを調べやすいかも? (edited)
Avatar
omochimetaru 9/28/2018 3:38 AM
なるほど〜〜
Avatar
$ cat A.swift @available(*, introduced: 1) public func funcA() { print("funcA") } $ cat B.swift public func funcB() { print("funcB") funcA() } $ cat C.swift public func funcC() { print("funcC") } $ cat output.json { "A.swift": { "object": "Derived/A.o", "swiftmodule": "Derived/A~partial.swiftmodule", "swift-dependencies": "Derived/A.swiftdeps", }, "B.swift": { "object": "Derived/B.o", "swiftmodule": "Derived/B~partial.swiftmodule", "swift-dependencies": "Derived/B.swiftdeps", }, "C.swift": { "object": "Derived/C.o", "swiftmodule": "Derived/C~partial.swiftmodule", "swift-dependencies": "Derived/C.swiftdeps", }, "": { "swift-dependencies": "Derived/buildrecord.swiftdeps" } } $ mkdir -p Derived な状態から、 $ xcrun swiftc -v -incremental -output-file-map output.json A.swift B.swift C.swift -module-name MyModule -emit-library -emit-module -o Derived/MyModule.dylib でとりあえずクリーンビルドして、Derived ディレクトリの中身見たり、A.swift@available消して同コマンド実行して何が起こってるか確認したりすると面白いです。 (edited)
👀 1
3:48 AM
で、 swiftc コマンドに -enable-batch-mode 追加してあげるとXcode10の挙動と同等に。 (edited)
Avatar
norio_nomura 10/1/2018 3:31 AM
ソースコードに何も変更はなく、新しい機能を使っているわけでもないのに、メジャーバージョンを上げてまでSwift 4.2に変えたい理由って何だろう? https://github.com/antitypical/Result/pull/271
Bump swift version to 4.2 and also increment pod version.
Avatar
omochimetaru 10/1/2018 3:36 AM
個人的には最新版でビルドしてない時点でライブラリは使いたくないです
3:36 AM
技術的な理由というより開発者が放置してるんじゃないか?って思ってしまう
3:36 AM
4.2にする必要はなくても、将来5.0になったときに互換性の問題が出るかもしれなくて
3:37 AM
そういうときに備えて、常に最新に対応する姿勢が見えないと
3:37 AM
後のバージョンの対応が迅速じゃないかもしれない、って心配になる。
3:38 AM
まあ、Resultぐらいなら、最悪そのときは自分でフォークして直すのも簡単だし使いますけど。
3:38 AM
あと、プロジェクトの中で、あるモジュールは4.1、あるモジュールは4.2でビルドしてからリンクします、 みたいなやつ、動くのかもしれないけど信用ならないから心配。
Avatar
Kishikawa Katsumi 10/1/2018 3:39 AM
^ に限らず、大抵のSwift 4.2対応ってくるPRはこんな感じなんですけど、
個人的には最新版でビルドしてない時点でライブラリは使いたくないです
これは使うほうが4.2のツールチェーンでビルドすればいいだけなので、ライブラリ側で互換性を崩す必要はないと思います。
Avatar
norio_nomura 10/1/2018 3:39 AM
Swift 4.2でCI通すだけで良いと思うのですよね。
Avatar
omochimetaru 10/1/2018 3:40 AM
Swift 4.2でCI通すだけで良い
ああ、READMEのところとかに、 [swift 4.2] みたいなバッジがついてたりしたら、安心です
3:40 AM
4.2で問題がないことを確認していることがわかるので。
3:41 AM
実際に問題がないかどうかじゃなくて、問題がないことをチェックしているか、がきになる。
3:41 AM
それがないと、自分の環境でビルドはできても、実行時にはなにか変なことが起きるかもしれないし。 Resultぐらいシンプルなソースだとそれも考えにくいですが。。。
Avatar
norio_nomura 10/1/2018 3:48 AM
あと、プロジェクトの中で、あるモジュールは4.1、あるモジュールは4.2でビルドしてからリンクします、 みたいなやつ、動くのかもしれないけど信用ならないから心配。 むむ、これって何かトラブルの事例ってあるのですか?
Avatar
omochimetaru 10/1/2018 3:49 AM
いや、見聞きした事例はないです
3:49 AM
個人的に、本当にちゃんと動くのかな・・・って思っているだけ (edited)
Avatar
norio_nomura 10/1/2018 3:49 AM
なるほど。
Avatar
omochimetaru 10/1/2018 3:50 AM
単純に、最も安全確実でクリーンだと思われるのが、関連ソース何もかもが最新ビタビタで揃ってる事なので。
3:50 AM
あ、昔で言えば、ライブラリがbitcode対応していないのに引きずられて、それをリンクするアプリもbitcode対応できない、とかありましたね。
3:51 AM
bitcodeが初出のバージョン間ではそういうこともありました。
Avatar
Kishikawa Katsumi 10/1/2018 3:53 AM
Swiftはちょっと特殊だから難しいですけど、 最も安全確実なのはそれなりに使われているコードなのでいまでいうとSwift 4.0か4.1だと思いますね。 (edited)
Avatar
omochimetaru 10/1/2018 3:53 AM
なるほど。
3:53 AM
たしかに、少し前のメジャーで全部揃えるのが一番安心か・・・。
Avatar
Kishikawa Katsumi 10/1/2018 3:55 AM
で、ライブラリ提供側だと、常に最新というポリシーもありだし、 使用者が選べるというのもありで、私は後者の考えを持っています。
4:00 AM
あと、できるだけ古いツールチェーンもサポートすべきと思っていて、それはそっちの方が良いはずという意図があります。自分のリポジトリは。
Avatar
norio_nomura 10/1/2018 4:05 AM
あれ?Xcode 9.xって、SWIFT_VERSION = 4.2になっててもswiftcへは-swift-version 4って渡すのかな?
Avatar
9.xだとSwift 4.2という言語バージョンは知らないと思うので、4.1の指定したときと同じで4を渡す気がします (edited)
4:11 AM
ResultでXcode 10でのCIは別PRがあるので安心してほしい https://github.com/antitypical/Result/pull/269
👍 1
Avatar
norio_nomura 10/1/2018 4:13 AM
project.pbxprojSWIFT_VERSION = 4.2になってても過去のXcodeでビルド出来るなら、SWIFT_VERSION = 4.2にしてしまっても良い様な気がしてきた。
4:20 AM
それだとbreaking changeにもならないよね。
Avatar
norio_nomura 10/1/2018 5:13 AM
project.pbxprojSWIFT_VERSION = 4.2になってても、Xcode 9.0.1, 9.1, 9.2, 9.3.1, 9.4.1はswiftc-swift-version 4を渡すのを確認した。
Avatar
norio_nomura 10/1/2018 9:24 AM
XcodeプロジェクトでSWIFT_VERSION = 4.2にしてもbreaking changeにならないとしても、podspecのswift_versionはどうなんだろう?
9:30 AM
ドキュメント読んでもよくわからないな… https://guides.cocoapods.org/syntax/podspec.html#swift_version (edited)
The Dependency Manager for iOS & Mac projects.
Avatar
Kishikawa Katsumi 10/1/2018 9:43 AM
pod_specのswift_versionはあったらそのバージョンの固定、っていう動作だからむしろ書かないほうが良いと思うんですよね。 書いてなければビルド環境に応じて4.2になるけど4.1って書いてしまったら4.1になる、はず。
Avatar
そうすると、4.2をそのままだとビルドできないライブラリがあった時に(4.2が出るまでそれが分かっていなかった時)、ユーザーがアプリターゲットを4.2にしたと同時にライブラリも4.2でビルドされようとして、突然ビルドが壊れだして、ライブラリのユーザーもメンテナーも疲弊するなーという印象です。せっかくターゲット毎に異なる言語バージョンが使えるので、できる限り安定的にビルドできる状態を保証しておきたいと個人的には思います。 (edited)
10:18 AM
まあみんなbetaの時からCI回してどの言語バージョンでもビルドできるようにしておいて、podのswift_versionを固定しないでおくのが理想的ではあると思いますが、なかなかそのリソースがないですよね (edited)
10:22 AM
Xcode 10だと、3, 4, 4.2の3モードがあるので、swift_versionを指定しない場合は理想的にはそのすべてをサポートしておく必要がありそう。
10:24 AM
Carthageだとライブラリ側のターゲット定義で言語バージョンを決められるけど、CocoaPodsだとユーザーのアプリの言語バージョン指定に引きづられてしまう(swift_versionを指定していない限り)ので難しさが増す、ということですね。 (edited)
Avatar
こうしたケースを回避しようとすると、ユーザーが各自でpost_installフックで特定のライブラリのSWIFT_VERSIONを変更しなくてはいけない。その問題を解決するためにspec.swift_versionが追加された、という認識です。
Avatar
Kishikawa Katsumi 10/1/2018 10:40 AM
固定したほうが良い場合ももちろんあります。 ただ、ResultsとかUIKit
10:41 AM
使ってなかったら4.0-4.2はだいたい互換性があるはずなんで、
10:41 AM
そういうのはむしろ固定しない方が良いと思うんですよね。
Avatar
Swift 4以上の言語機能を使っている場合はSwift 3はサポート不可なので、指定しないわけにはいかない気がしますが、どうでしょうか?Xcode 10でユーザーのアプリがSWIFT_VERSION=3だとPodのターゲットもSwift 3になってしまうと思うので。
Avatar
Kishikawa Katsumi 10/1/2018 10:45 AM
3もサポートするならコード内で分岐ですね。 まあどこかで諦めることにはなりますよ。
Avatar
ResultくらいならSwift 3サポートも頑張れなくはないと思います(リソースさえあれば……)
Avatar
Kishikawa Katsumi 10/1/2018 10:46 AM
例えば良くある例でいうとflatMap => compactMapの書き換えとか5が出るまでやりたくない感じじゃないですか?
10:47 AM
下のバージョンに向けてはエイリアス的なものを提供するっていうのもアリですけど。
Avatar
そういうAPIの差は、僕も実際によくエイリアスで対応してますね。
Avatar
@tarunon さんに教えてもらったメモリリークテストのヘルパー実装してみました! https://github.com/Kuniwak/UIKitTestable/blob/e977532c81a97998a4c776b2d1b70c167eb73841/UIKitTests/UIKitTests/MemoryLeakDetector.swift レポートもそこそこ親切にできたので、いい感じになりそうです: https://github.com/Kuniwak/UIKitTestable/blob/master/UIKitTestableTests/UIKitTestableTestsTests/MemoryLeakDetectorTests.swift 次は、UIViewController に適用するパターンですね。UIViewController の viewDidDisappear あたりまでを実行してから、UIViewController を解放するイメージで考えてますが、検証のタイミングが若干難しそうな気配が…
Make project using UIKit testable. Contribute to Kuniwak/UIKitTestable development by creating an account on GitHub.
Make project using UIKit testable. Contribute to Kuniwak/UIKitTestable development by creating an account on GitHub.
Avatar
おっ見てみます👀
5:04 PM
因みに何ですけど
5:04 PM
lazy varが.storageかつOptionalに化けるとか、Optionalを探索するのにsomeが生えるとかで問題があったりするので
5:04 PM
意外とやる事は多いw
Avatar
そのケースは考えてなかったw
5:05 PM
Optional は Mirror#children で拾えそうな気がしてるのですが、そう簡単な感じではなかった感じですか?
Avatar
拾えるんですけど、パスを生成するときにMirrorを雑に参照してlabel使っちゃうと (edited)
5:06 PM
雑なパスになってしまいますw
Avatar
あー、なるほど。理解しました
5:07 PM
しかし Mirror 側から lazy かどうかを判定するすべはなさそうなので、some が生えちゃうのは仕方なさそうなイメージですね
Avatar
いや、判定できます
5:07 PM
labelがfoo.storageみたいになるのでこれがlazyの本体 (edited)
Avatar
お、それは初めてみました。ちょっと試してみますね
5:12 PM
(indirect.storage -> some -> value)
5:12 PM
あー、なるほどw
Avatar
寝ながらデータ構造でひとつ直した方がいいところに気づいたので後で直します。循環参照の参照経路をだすだけより、リークしたオブジェクトの型や文字列表現、与えられたオブジェクトからの参照経路も併せて出した方がいい気がします
Avatar
参考までに弊社Internalのものの出力ですが
Avatar
お、見たいです!
Avatar
Found 2 object leaking children[0].viewModel: SomeViewModel children[0].textField: UITextField
2:48 AM
こんな感じで出てきます
Avatar
おー、確かにこっちの方が直感的ですね。真似します
2:50 AM
Reference.Path.Component を enum にすればいけるかな
2:53 AM
このメモリリーク判定機能、単体で切り出した方が有益そうな気配するな… UIKit 依存のあるプロジェクトにいれるのはもったいない
Avatar
Mirrorの変更で死ぬ場合があって(ついこの間死んだ)、メンテするのキビシイので会社のossとして出すのは難しいなと思っていました。出したい気持ちもあるんですがw
2:56 AM
単体の方が有益はそれはそうと思います
Avatar
Mirror は頻繁に死にますねw 私も頻繁に苦しめられてます https://github.com/Kuniwak/MirrorDiffKit/blob/master/Sources/TupleRepresentationDetector.swift
Graduation from messy XCTAssertEqual messages. Contribute to Kuniwak/MirrorDiffKit development by creating an account on GitHub.
Avatar
Summary: Found 2 leak objects Leaked objects: 0: Description: Node Type: Any Location: .linkedNodes[0] 1: Description: Node Type: Any Location: (root) Circular reference paths: 0: .linkedNodes[0].linkedNodes[0]
10:53 AM
いい感じになってきました
Avatar
iPhone5(c)などの32 bit CPUの端末の実機 でクラッシュするコードを発見したっぽいのですが既知のバグだったりしますか? Enumのassociated valueに沢山プロパティが生えたオブジェクトを渡して参照するとクラッシュするっぽい挙動です (Xcode9.4でも起きてたのですがdebugビルドでしか再現してなくて、Xcode10でreleaseビルドでも再現するようになり発覚しました...) https://gist.github.com/ainame/04b07621112484b1d6a8b2bb791fcf74
Crashed on iPhone5(c). GitHub Gist: instantly share code, notes, and snippets.
Avatar
完全にやばそう
10:38 AM
Optional壊れた話ってもしかしてこれかな
Avatar
EXC_BAD_ACCESSでメモリ周りが壊れているっぽい
Avatar
お〜
Avatar
compactMapValuesの説明書つくった https://twitter.com/d_date/status/1049618894585921537
資料です。ありがとうございました! https://t.co/OTHQuJnFmn #potatotips
👍 3
Avatar
長さが一定より小さくならない配列の型をつくって遊んでたんですが、gyb 結構簡単で便利ですね https://gist.github.com/Kuniwak/5296bef20ae923bf0c96a70d7bd16c07
GitHub Gist: instantly share code, notes, and snippets.
9:44 AM
そしてこの ArrayLongerThan1 とか ArrayLongerThan3 とか普通に便利でした
9:47 AM
悲しいのは Sequence に適合できないことですね… ArrayLongerThanN の map や enumerated は長さが変わらないことがわかっているので、戻り値を ArrayLongerThanN にしたいんですが、こうすると Sequence の定義と衝突するんですよね
9:48 AM
一応、Sequence として扱いたい用途のために ArrayLongerThanN.sequence があるのですが、まああんまりいけてない…
Avatar
@Kuniwak この前↓について話してたときって Kuniwak さんいましたっけ? https://forums.swift.org/t/implement-nonempty-collections/14246
https://github.com/pointfreeco/swift-nonempty — For when a collection is guaranteed to have at least one value.
Avatar
げ、すでにそんなものが
Avatar
swift evolution ではこれは Pitch レベルだと思います。 (edited)
1:26 PM
リンク先のライブラリは SequenceCollection ?)を型パラメータにとるのがおもしろいですね。 https://github.com/pointfreeco/swift-nonempty (edited)
🎁 A compile-time guarantee that a collection contains a value. - pointfreeco/swift-nonempty
1:27 PM
🎁 A compile-time guarantee that a collection contains a value. - pointfreeco/swift-nonempty
1:27 PM
おや、自分ができなかったことをやっている…
1:29 PM
戻り値の型だけ違うメソッドって定義できないという認識だったんですが、どうして Sequence.map と戻り値だけが異なる map を定義できるだろう
Avatar
衝突はしますが、できるとは思います。多分オーバーロードになるのかと。
Avatar
あ、これできるんですか…
Avatar
Kishikawa Katsumi 10/13/2018 1:29 PM
呼び出すときに区別する必要があるので使い勝手は良くないですがオーバーロードできます。
Avatar
てことは、自分のときの型エラーは init の誤判定な気がしてきました
1:30 PM
あー、なんかわかりました。これ NonEmpty のネストでやられそう
Avatar
僕も Image<Element>: Sequence を作ってますが Image to Imagemap ができてるので。 Sequence 由来のと曖昧になりそうな気がするんですが、 Image to Image の方が優先されてますね。
1:31 PM
protocol のデフォルト実装は優先順位が低いのかな??
Avatar
これ、NonEmpty の C 側に NonEmpty 入れると動きがやばくなりそうな予感が
Avatar
Sequencemap とかついてるのほんと微妙ですよねぇ。 makeIterator だけの純粋な Sequencemap とかを分離してほしい・・・。
Avatar
わかります
1:33 PM
そしてついでに map の戻り値を [T] じゃなくて Self にしてほしい(過激派)
Avatar
これ、NonEmpty の C 側に NonEmpty 入れると動きがやばくなりそうな予感が
その場合は Collection として扱われるので Collectionmap が呼ばれるんじゃないですか?↓とかですよね? public func map<T>(_ transform: (Element) throws -> T) rethrows -> NonEmpty<[T]> { return try NonEmpty<[T]>(transform(self.head), self.tail.map(transform)) }
Avatar
ですです
1:34 PM
なので、2要素以上配列とかを扱うとき相当不便になるのではないかと
Avatar
そしてついでに map の戻り値を [T] じゃなくて Self にしてほしい(過激派)
これ [Element][T] に変換するんで Self じゃなくて、 higher-kinded type がないとできないんですよねぇ・・・。
Avatar
確かに…
Avatar
2要素以上配列とかを扱うとき相当不便になるのではないかと
ここがよくわかってないです・・・
Avatar
NonEmpty を使った2要素以上配列は下のようになるという予想をしていて、 NonEmpty<Element, NonEmpty<Element, C>>
1:38 PM
あ、いや、なんとかなるのかな… ちょっと前に出くわしたエラーの原因に別の心当たりができました
Avatar
NonEmpty<Element, NonEmpty<Element, C>> は考えてませんでしたが(それぞれの struct を実装するイメージしてました)、多分うまくいきそうな気がします。その場合だけ init(Element, Element, C)extension で生やせると便利そうですね〜。
Avatar
まさに自分の実装は typealias ArrayLongerThan2<Element> = PrefixedArray<Element, PrefixedArray<Element, PrefixedArrayEnd<Element>>> となっていて、これで flatMap とかの実装が衝突して死んだみたいなエラーに出くわして、ウワァ、ダメなのかみたいに引き返したんです (edited)
1:43 PM
他にもいくつか不可解なエラーに出くわしていて(typealias だと動かないが、typealias を展開したものを使うと動くみたいな)、いろいろと辛い感じではありました
1:44 PM
あ、safeFirst 、なるほど。。。
1:44 PM
これも衝突してましたが、こういう風に逃げたのか…
1:44 PM
1:45 PM
いや、定義できるんですね、これちょっと前にどこかのチャンネルで話題になってた気がする
Avatar
@swift-4.2.4 protocol NonEmptySequence: Sequence { var first: Element { get } } struct NonEmptyArray<Element>: NonEmptySequence { private var array: [Element] init(_ array: [Element]) { precondition(!array.isEmpty) self.array = array } var first: Element { return array[0] } func makeIterator() -> Array<Element>.Iterator { return array.makeIterator() } } (edited)
Avatar
no output (edited)
Avatar
@swift-4.1.3 protocol NonEmptySequence: Sequence { var first: Element { get } } struct NonEmptyArray<Element>: NonEmptySequence { private var array: [Element] init(_ array: [Element]) { precondition(!array.isEmpty) self.array = array } var first: Element { return array[0] } func makeIterator() -> Array<Element>.Iterator { return array.makeIterator() } } (edited)
Avatar
no output (edited)
Avatar
@swift-4.0.3 protocol NonEmptySequence: Sequence { var first: Element { get } } struct NonEmptyArray<Element>: NonEmptySequence { private var array: [Element] init(_ array: [Element]) { precondition(!array.isEmpty) self.array = array } var first: Element { return array[0] } func makeIterator() -> Array<Element>.Iterator { return array.makeIterator() } }
Avatar
no output
Avatar
あれ? firstSequence じゃなくて Collection なのか。
Avatar
あ、そうですね。Sequence は makeIterator しか要求しないです
Avatar
extension でも生えてないんですね。 map とかは生えてるのに・・・。
2:40 PM
@swift-4.1.3 protocol I { init() } protocol P { associatedtype A: I } extension P { var bar: A? { return nil } } protocol Q: P {} extension Q { var bar: A { return A() } } struct S<T: I>: Q { typealias A = T let value: T var bar: T { return value } } extension Int: I { init() { self = 0 } } let s = S(value: 42) print(s.bar) (edited)
Avatar
42 (edited)
Avatar
safeFirst って何ができなかったんですか? Optional を非 Optional で満たすことができなかったとかではなく??
2:46 PM
これは 4.2 でもできない。 @swift-4.2.4 protocol P { associatedtype A var a: A? { get } } struct S<T>: P { typealias A = T let value: T var a: T { return value } } let s = S(value: 42) print(s.a)
Avatar
exit status: 1 with stderr:<stdin>:7:8: error: type 'S<T>' does not conform to protocol 'P' struct S<T>: P { ^ <stdin>:10:9: note: candidate has non-matching type 'T' var a: T { return value } ^ <stdin>:4:9: note: protocol requires property 'a' with type 'S<T>.A?'; do you want to add a stub? var a: A? { get } ^
Avatar
あれ、不思議ですね。なんであのコードでコンパイルが通るんだろう…
Avatar
taru non さんからアイデアを教えていただいた Memory Leak のやつ、それなりに形になってきました https://github.com/kuniwak/memoryleaktestkit
Contribute to Kuniwak/MemoryLeakTestKit development by creating an account on GitHub.
2:52 AM
どうでもいいんですが、Hacker News でいう ShowHN みたいなチャンネルがあるとこういうの投げやすいですね…
Avatar
Hacker News でいう ShowHN
を知らないのでよくわからないですが、なんてチャンネル名があればいいですか?
2:53 AM
チャンネル概要(チャンネル名の右に出る文字列)も、もしあったら指定してくれればつけます。
Avatar
ShowHN は、自分の作った成果物を Hacker News で投稿する場所なんですよね https://news.ycombinator.com/showhn.html
2:55 AM
ただ、論点もあると思っています
Avatar
なるほど。じゃあそのままのコンテキストなら #show ですかね、でも知らない人に伝わりにくいかも?
Avatar
はい
2:55 AM
例えば、成果物を適当なチャンネルに投げてもそんなうざくないなら、チャンネル作らなくても OK だと思いますね
Avatar
話題になるし普通にむしろ歓迎だと思います
Avatar
であれば、それ用のチャンネルはいらない気がしますね。例えば Metal 系のライブラリとかなら #metal とかに投げたほうがより良いと思いますし
Avatar
OKです
Avatar
Kuniwakさんのリークテストは、detectLeaksで参照グラフをスキャンして、循環を見つける設計なんですね
Avatar
いえ、循環は純粋にデバッグのための付加情報です
Avatar
createSomething() の中でリークしていても見つけられるんです?
2:58 AM
let target から到達できなかったらどうにもならない気が。
Avatar
その場合はちょっと変わった表示が出るはずです
2:59 AM
なお、やり方としては、オブジェクトグラフをたどっていって、 それぞれを weak で写しとって、weak の中身がちゃんと回収されているかみるという感じですね
2:59 AM
なので、回収自体は Swift の RC の仕組みに乗っかってます
Avatar
むむ (edited)
Avatar
循環参照が見つからない場合は 2 つの可能性が考えられるので、次のようなエラーメッセージが出ます: https://github.com/Kuniwak/MemoryLeakTestKit/blob/master/Sources/MemoryLeakTestKit/LeakedObject.swift#L47-L51
Contribute to Kuniwak/MemoryLeakTestKit development by creating an account on GitHub.
3:01 AM
Contribute to Kuniwak/MemoryLeakTestKit development by creating an account on GitHub.
3:02 AM
あ、テストケースのコメント間違ってる。。。
Avatar
リークするかどうか検査したい関数があるとして、 1. オブジェクトを全部スキャンする 2. 検査したい関数を実行する 3. スキャンしてあるweak参照の先に生きてるオブジェクトが無いことを確認する (edited)
3:02 AM
この3ステップが必要だと思うんですけど
3:02 AM
let target = createSomething() let memoryLeaks = detectLeaks(target) XCTAssertTrue( memoryLeaks.leakedObjects.isEmpty, memoryLeaks.prettyDescription )
3:03 AM
↑のUsageだと、createSomethingが「検査したい関数」で、detectLeaksがスキャンだとすると、 createSomethingの中で発生したリークが、わからないと思ったのですが、なにか僕が勘違いしてますか (edited)
Avatar
えと一点確認させて欲しいのですが、createSomething のなかで発生したリークは、具体的にどのような感じを意図されていますか
3:04 AM
可能ならこういうオブジェクトグラフですみたいなのがあれば
Avatar
class Cat { var parent: Cat? } func createSomething() -> Cat { let cat1 = Cat() let cat2 = Cat() let cat3 = Cat() cat2.parent = cat3 cat3.parent = cat2 return cat1 }
Avatar
あるいは、RC での回収タイミングの話です?実はちょっとそこ自信のない(ただしテストは通ってしまった)場所ではあります
3:06 AM
なるほど、そのケースはテストを見るかぎり捉えられています
Avatar
やってみます
3:09 AM
これ README 間違ってますね
3:09 AM
💀
3:10 AM
え、しかもテストも妙な感じだ。。。
3:11 AM
Summary: Found 0 leaked objects Leaked objects: (empty)
3:11 AM
leak してない、、、だと?
3:11 AM
あ、そりゃそうだ
3:11 AM
cat1 から cat2 と cat3 を辿れないので、そもそも参照を得られてないからですね
Avatar
はい、そうなると思ってて。
Avatar
なので、この場合は cat2 と cat3 の leak は捉えられないです
3:12 AM
戻り値のオブジェクトから辿れるものだけがわかる、みたいな感じでしょうか
Avatar
そうすると検出できるリークって、「targetから到達できて循環してる部分」になると思うんですが
3:17 AM
なお、やり方としては、オブジェクトグラフをたどっていって、 それぞれを weak で写しとって、weak の中身がちゃんと回収されているかみるという感じですね なので、回収自体は Swift の RC の仕組みに乗っかってます
1. weakで写し取る 2. Swiftのしくみで回収された後で・・・ 3. 写し取ったweakがnilになっているか確かめる
Avatar
そうすると検出できるリークって、「targetから到達できて循環してる部分」になると思うんですが
あー、これは正確にもうちょっとだけ範囲が広いです。というのも、さっきの cat2 や cat3 から cat1 への参照があった場合、cat 1 からの参照に循環参照はありませんが、cat1 が回収されないので
3:18 AM
これは検知できます
Avatar
あ、なるほど。
Avatar
ただ、概ねは omochi さんのご理解で正しいとは思います
Avatar
class Cat { var parent: Cat? var child: Cat? } func createSomething() -> Cat { let cat1 = Cat() let cat2 = Cat() let cat3 = Cat() cat2.parent = cat3 cat3.parent = cat2 cat2.child = cat1 return cat1 }
3:19 AM
この場合ですね
3:21 AM
あら
3:22 AM
detectLeaksはオブジェクトを受け取ると思ってたけど () -> T を受け取るのか。
3:23 AM
これ README 間違ってますね
そういうことか
3:24 AM
クロージャで受けてるから、detectLeaksの内部で、 「weakで全部保持」 「検査したいユーザコードの実行」と「Swiftのスコープ解放の完了待ち」ができて 「weakで保持したもののチェック」 ができるのか。
3:24 AM
Tを受け取ると思っていたので引っかかっていたけど納得しました
Avatar
そうなんですよ、すみませんでした。。。
Avatar
README 直しました 🙇
🙂 1
Avatar
let json = """ [{ "id": 0, "mode": "high" },{ "id": 1, "mode": "middle" },{ "id": 2, "mode": "moddle" },{ "id": 3, "mode": "low" }] """ enum Mode: String, Decodable { case high case middle case low } struct Object: Decodable { let id: Int let mode: Mode } let objects = try! JSONDecoder().decode([Object].self, from: json.data(using: .utf8)!) print(objects) ↑のような時に、Jsonのデコードを失敗とせずid:0,1,3のObjectの配列を返すような実装がしたい場合Arrayのラッパーみたいなものを書く感じになるのでしょうか?
Avatar
Mode を optional にして compactMap で再構成するのはめんどいです?
Avatar
enum Mode: String, Decodable { case high case middle case low } struct Object: Decodable { let id: Int let mode: Mode? } do { let decoder = JSONDecoder() let data = json.data(using: .utf8)! let objects = try decoder.decode([Object].self, from: data).compactMap({ $0.mode != nil }) print(objects) } catch { print(error) }
6:43 AM
こういうことですか? どうもキーがあるとModeのDecodeで失敗するとthrowされてしまってそうです…
Avatar
@swift-4.2.4 import Foundation let json = """ [{ "id": 0, "mode": "high" },{ "id": 1, "mode": "middle" },{ "id": 2, "mode": "moddle" },{ "id": 3, "mode": "low" }] """ enum Mode: String, Decodable { case high case middle case low } struct Object: Decodable { let id: Int let mode: Mode? enum CodingKeys: CodingKey { case id, mode } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.id = try container.decode(Int.self, forKey: .id) self.mode = try? container.decode(Mode.self, forKey: .mode) } } let objects = try! JSONDecoder().decode([Object].self, from: json.data(using: .utf8)!).filter { $0.mode != nil } print(objects)
Avatar
[main.Object(id: 0, mode: Optional(main.Mode.high)), main.Object(id: 1, mode: Optional(main.Mode.middle)), main.Object(id: 3, mode: Optional(main.Mode.low))]
Avatar
ありがとうございます!いけました、CodingKeyでマニュアル操作しないといかんのですね 何かCompactDecodableやCompactJSONDecoderのようなアプローチで実装できたら使いやすいかなと思ったのですが良い方法が思い浮かばず
Avatar
@noppe @swift-4.2.4 import Foundation let json = """ [{ "id": 0, "mode": "high" }, { "id": 1, "mode": "middle" }, { "id": 2, "mode": "moddle" }, { "id": 3, "mode": "low" } ] """ enum Mode: String, Decodable { case high case middle case low } struct Object: Decodable { let id: Int let mode: Mode init(id: Int, mode: Mode) { self.id = id self.mode = mode } } struct FailableBox<T> : Decodable where T : Decodable { init(from decoder: Decoder) throws { self.value = try? T.init(from: decoder) } var value: T? } let objects: [Object] = try! JSONDecoder() .decode([FailableBox<Object>].self, from: json.data(using: .utf8)!) .compactMap { $0.value } print(objects)
Avatar
[main.Object(id: 0, mode: main.Mode.high), main.Object(id: 1, mode: main.Mode.middle), main.Object(id: 3, mode: main.Mode.low)]
Avatar
@noppe こんなやりかたはどうでしょう
Avatar
元のモデルのインターフェイス変わらないので良さそうです!
Avatar
もしJSONツリー全体でそのような制御をしたい場合は、JSONDecoderを自作しちゃうのが早いと思います。
Avatar
そこ気になっていたのですが、JSONDecoder自作でこの辺りって制御できるのでしょうか?
Avatar
できると思うけどやってみないとはっきりといえないですね、確信度70%
Avatar
ここ出来ると使い勝手良さそうなので作ってみますー!ありがとうございます!
Avatar
他にも、デフォルトのJSONEncoderだと、
12:22 PM
Optionalがnoneになってるときはキーごと消えてしまうけど
12:22 PM
キーは常に出力して null を与えるとかも
12:22 PM
自作だとできるんじゃないかな
Avatar
あー、肝心のJSONをデコードしている部分はInternalなんですね
Avatar
ですね。Codableが提供するのは一般的な構造へのマッピングAPIだけで
1:21 PM
JSONとしてどうなるかっていうのはCodableと関係なくって
1:21 PM
そっちはJSONEncoderのoutputFormatプロパティとか、そういう個別の設定機能で調整するしかない
Avatar
なるほど、カスタマイズ性が許容されている箇所以外を弄ろうとするといきなりやること多くなってしまうんですね
Avatar
ですね
1:24 PM
できることならそういうのは要件ごと踏み倒して対応しないのがコスパ良い
1:24 PM
が、JSON使うシーンはだいたい外部システムの都合があったりするので・・・ (edited)
Avatar
Codable側で個別に対応するのが良さそうですね CodingKeysとか諸々バチっとハマるJSONなら書くことがほぼ無くなる設計になっているから、イニシャライザ一つ書くのにも楽に出来無いかと思ってしまいがちですねこの辺は (edited)
Avatar
ですね、キーのsnakeCase化とか、微妙に小回りがきいたりもする。
Avatar
@swift-4.2.4 import Foundation enum Result { case win case lose case none } var results: [Int : Result] = [:] results[0] = .win results[1] = .lose results[2] = .none if results[2] == nil { print("result.2 is nil") }
Avatar
result.2 is nil
Avatar
知らなかった
Avatar
Optionalのnoneだと思われてるわけですね、これは危険だ… 😱
Avatar
@swift-4.2.4 import Foundation enum Result { case win case lose case none } var results: [Int : Result] = [:] results[0] = .win results[1] = .lose results[2] = .some(.none) if results[2] == nil { print("result.2 is nil") }
Avatar
no output
Avatar
Optional暗黙変換の悲劇だ
Avatar
一瞬意味わからなかったけど Dictionarysubscript-> Value? だからかぁ。
1:12 AM
getset で、 getOptional だけど setOptional でなくしたいケース、ときどきある気がしてる。
Avatar
@swift-4.2.4 enum Result { case win case lose case none } func foo(_ resultOrNil: Result?) { print(resultOrNil as Any) } foo(.win) foo(.lose) foo(.none) foo(Result.none)
Avatar
Optional(main.Result.win) Optional(main.Result.lose) nil Optional(main.Result.none)
Avatar
Dictionaryの例はインパクトがあるけど、それ以外でも普通に起こるので、enumのメンバに none は避けるようにした方が無難そうですね。 (edited)
Avatar
暗黙変換の歪みは色んなところに出てきますねぇ・・・
Avatar
Kishikawa Katsumi 10/21/2018 1:41 AM
Dictionaryの例はたぶん削除が呼ばれてるんですよね。 削除はnilリテラルだけを対象にするのが良いと思うんですよね。
Avatar
削除は removeValue(forKey:) だけにして、 subscript set を非 Optional にしてほしいです・・・。
Avatar
Kishikawa Katsumi 10/21/2018 1:43 AM
^ それがベスト。
1:44 AM
そもそも削除って便利構文を用意しなければならないほどの頻度でやらないんですよね。
Avatar
ただ、たとえ今から set で非 Optional 化できるようになっても、互換性の問題で Dictionarysubscript set をなくすのってできないかもですね😂
1:45 AM
僕は、 dict[key] = nil って便利構文なんじゃなくて、 subscript の仕様制約上 set を非 Optional にできなかったため仕方なくついてるものだと思ってました。 (edited)
Avatar
Kishikawa Katsumi 10/21/2018 1:46 AM
なるほど。確かにget/setのペアで型がそろってないとダメですよね。
😭 1
1:50 AM
互換性を考慮すると、現在nilリテラルの代入で削除以外が起こることはないはずだから、nilリテラルの代入以外のOptionalの代入をコンパイラか別のLinterが警告する というのが妥当か。
Avatar
printOptional 警告はあるから、 Dictionarysubscript set でもその線が妥当そうですね。
Avatar
Kishikawa Katsumi 10/21/2018 1:53 AM
話外れちゃうけどString Interpolationの警告は良いけどprint()の警告は別にいらないですけどね。
Avatar
確かに不便なだけのことが多いですね。 String Interpolation の方は Optional(2018)年 問題回避に役立ちますけど。
1:56 AM
String Interpolation も、僕は CustomStringConvertible 以外できなくしちゃってもいいと思うんですよね。
Avatar
Kishikawa Katsumi 10/21/2018 1:56 AM
print()の話で思いついたけど、nilを受け取れるようにするしかないけど正常ケースとしてはあまり受け取りたくない/考えてない、というケースに警告を出せる @nilWarning 属性みたいなものをつけられるといいのか?
Avatar
そうですね。 Optional 暗黙変換問題はどこででも起こりうるので、そういうのがあると良いのかも?
Avatar
Kishikawa Katsumi 10/21/2018 1:57 AM
コンパイラの範疇を超えてるかな、Linterでやれって感じもする。
Avatar
うーん、でも警告を出したいかは API によるから、 @discardableResult とかと同じで Attribute 付けるとかしないとできなくないですか?
Avatar
Kishikawa Katsumi 10/21/2018 1:59 AM
あ、それはそうですね。
1:59 AM
メソッドに何らかの表明する手段が必要。。。コンパイラでやってくれるといいですね。
2:00 AM
nil以外にも「外部の入力そのまま渡してるよ」っていう警告を出したりとか言語やLinterによってあるから、そういう仕組みかな。 型以外の情報で狭める表明。
Avatar
@swift-4.2.4 -frontend -repl enum Result { case win case lose case none } let result: Result? = .none これは暗黙変換ではなく Optional<Result>.none を入れてるだけですよね。
Avatar
// result : Result? = nil
Avatar
そっちは暗黙変換じゃないですが、 .some の方が暗黙変換で、それと並べると .none も同じように見えてしまうという問題かと思います。
👍 1
Avatar
@swift-4.2.4 import Foundation enum Computer { case win case mac } enum Result { case win case lose case none case some(Computer) } func foo(_ resultOrNil: Result?) { print(resultOrNil as Any) } foo(.win) foo(.lose) foo(.none) foo(.some(.win)) print("") foo(Result.some(.win))
Avatar
Optional(main.Result.win) Optional(main.Result.lose) nil Optional(main.Result.win) Optional(main.Result.some(main.Computer.win))
Avatar
まあこんなことになるのは少なそうだけど 🙂
Avatar
caseに乗ってるassoc valueがNeverだったらswitchにそのcaseなくてもコンパイル通るの初めて知った enum Hoge { case waiwai case mu(Never) } let hoge = Hoge.waiwai switch hoge { case .waiwai: print("わいわい") }
😮 2
Avatar
↓ですね。 Result<Foo, Never>switchcase .failure 書かなくても網羅的になるはず。 https://discordapp.com/channels/291054398077927425/291054454793306112/336463567039496192
Avatar
大昔に議論されてた。
Avatar
検索したら色々出てきて楽しいです。
Avatar
正規表現書いてるとRawString早く欲しくなるなあ
Avatar
Kishikawa Katsumi 10/25/2018 4:21 AM
"([0-9a-fA-F]+)\\.\\.([0-9a-fA-F]+);([a-zA-Z]+)" そうですねえ。
Avatar
@ikesyo ↓の swiftenv の 4.2 サポート版がリリースされないままなのって何か理由があるんですか? https://github.com/kylef/swiftenv/commit/a949ff6ab8d1386f1bc99219da1ba860ea7de35a
👌🏼 1
Avatar
反応遅れました💦 特に理由はない気がします。kylefがやる気になったらリリースなのかも。
🙏 1
12:28 AM
これがなくてもswiftenv-api経由で4.2の情報は取られてダウンロードはできるはずではありますね
Avatar
↓のようなパターンで、 ielement の片方を let 、片方を var にする方法ってありますか? let array = [2, 3, 5] for var (i, element) in array.enumerated() { print("\(i): \(element)") }
9:01 AM
普通にできた。
Avatar
omochimetaru 11/8/2018 9:01 AM
え、できました?
Avatar
@swift-4.2.4 let array = [2, 3, 5] for (i, var element) in array.enumerated() { element += 1 print("\(i): \(element)") }
Avatar
0: 3 1: 4 2: 6
Avatar
omochimetaru 11/8/2018 9:02 AM
@swift-4.2.4 let array = [2, 3, 5] for (i, var element) in array.enumerated() { i += 1 element += 1 print("\(i): \(element)") }
Avatar
exit status: 1 with stderr:<stdin>:4:6: error: left side of mutating operator isn't mutable: 'i' is a 'let' constant i += 1 ~ ^
Avatar
omochimetaru 11/8/2018 9:02 AM
ほんとだ。
Avatar
これって、普通の変数/定数宣言ではできない?
Avatar
omochimetaru 11/8/2018 9:03 AM
なんか似たようなことをやろうとしてできなかったことがあった気がしたけどなんだろう・・・
Avatar
あと、 Optional Binding とか。
Avatar
omochimetaru 11/8/2018 9:03 AM
if var hoge = hogeOpt はいけます
Avatar
それはできるけど、
9:03 AM
タプルの片方だけ var
Avatar
omochimetaru 11/8/2018 9:04 AM
そうそう。タプルになっちゃうから無理という気がしてた。
Avatar
↓これしたい。 (let a, var b) = (2, 3)
Avatar
omochimetaru 11/8/2018 9:05 AM
そうだ、それだ
Avatar
var (x, y) = (0, 0) y = 190 print(x, y) この形だとx is never mutatedの警告すら出ないですね
Avatar
え?そうだっけ? > @t.ae
9:06 AM
それなら諦めて var にするのがいいのかな。
Avatar
僕の手元では少なくとも出てないですね
Avatar
let x: Int var y: Int (x, y) = (0, 0) 一応これは可能です。
9:10 AM
あと、statement condition であれば、 let point: (Int, Int)? = nil if case (let x, var y)? = point { print(x, y) }
Avatar
@rintaro なるほどー!ありがとうございます!
Avatar
static subscript って作れないのか。 @swift-4.2.4 struct S { static subscript(i: Int) -> Int { return i + 1 } }
Avatar
exit status: 1 with stderr:<stdin>:3:12: error: subscript cannot be marked 'static' static subscript(i: Int) -> Int { return i + 1 } ~~~~~~~^
Avatar
omochimetaru 11/9/2018 3:49 AM
へえ〜
Avatar
Replace this paragraph with a description of your changes and rationale. Provide links to external references/discussions if appropriate. Resolves SR-NNNN.
1:44 AM
クラスメタデータが動的に初期化されるようになるかも。 Windows対応関係でこの手のメタデータのリンクについてずっとトラブってたみたいなんだけど、 その辺の対応?の中で、Windowsをそうしてその次は他でもそうするってslavaが書いている。 定数として定義が吐き出されないケースが増えるとLLVM-IRが読みにくくなりそう? (edited)
Avatar
VWTを埋めるだけならほとんどの部分は静的なテンプレートで済みそう
2:13 AM
あー、でもVWTに依存してる奴があるのか…
Avatar
同期して初期化する関数にラップされるだけで、テーブルの中身自体は定数に出てるみたいな感じならまあ。
Avatar
type metadata自体のオフセットがすでにfull type metadataからズレてるのに、さらにテンプレートでズレると読むのがしんどそう
Avatar
こんばんは〜 class Container<Content> { init(a: Content) { // イニシャライザA fatalError() } init<T>(b: T) where T == Content { // イニシャライザB self.init(a: b as! Int) } } (edited)
11:37 AM
@swift-4.2.4 class Container<Content> { init(a: Content) { fatalError() } init<T>(b: T) where T == Content { self.init(a: b as! Int) } }
Avatar
exit status: 11 with stderr:<stdin>:7:27: error: same-type requirement makes generic parameters 'T' and 'Content' equivalent init<T>(b: T) where T == Content { ^ #0 0x000000000410ac94 PrintStackTraceSignalHandler(void*) (/usr/bin/swift+0x410ac94) #1 0x0000000004108b22 llvm::sys::RunSignalHandlers() (/usr/bin/swift+0x4108b22) #2 0x000000000410ae42 SignalHandler(int) (/usr/bin/swift+0x410ae42) #3 0x00007fdc32623390 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x11390) #4 0x00000000016b1b09 swift::FunctionType::get(swift::Type, swift::Type, swift::AnyFunctionType::ExtInfo const&) (/usr/bin/swift+0x16b1b09) #5 0x00000000017fde74 swift::GenericFunctionType::substGenericArgs(swift::SubstitutionMap const&) (/usr/bin/swift+0x17fde74) #6 0x00000000017fdd02 swift::GenericFunctionType::substGenericArgs(llvm::ArrayRef<swift::Substitution>) (/usr/bin/swift+0x17fdd02) #7 0x000000000147abe0 swift::UncurriedCandidate::UncurriedCandidate(swift::ValueDecl*, unsigned int) (/usr/bin/swift+0x147abe0) #8 0x000000000147f346 swift::CalleeCandidateInfo::CalleeCandidateInfo(swift::Type, llvm::ArrayRef<swift::constraints::OverloadChoice>, bool, swift::constraints::ConstraintSystem&, bool) (/usr/bin/swift+0x147f346) #9 0x0000000001466f19 (anonymous namespace)::FailureDiagnosis::visitApplyExpr(swift::ApplyExpr*) (/usr/bin/swift+0x1466f19) #10 0x000000000144d4d6 swift::ASTVisitor<(anonymous namespace)::FailureDiagnosis, bool, void, void, void, void, void>::visit(swift::Expr*) (/usr/bin/swift+0x144d4d6) #11 0x0000000001446642 swift::constraints::ConstraintSystem::diagnoseFailureForExpr(swift::Expr*) (/usr/bin/swift+0x1446642) #12 0x000000000144cb76 swift::constraints::ConstraintSystem::salvage(llvm::SmallVectorImpl<swift::constraints::Solution>&, swift::Expr*) (/usr/bin/swift+0x144cb76) #13 0x0000000001352138 swift::TypeChecker::solveForExpression(swift::Expr*&, swift::DeclContext*, swift::Type, swift::FreeTypeVariableBinding, swift::ExprTypeCheckListen
Avatar
なんか where T == Content はダメだよって正しいエラーを吐いたあとにセグフォで死ぬのを見つけた
Avatar
b as! Intは変なのでは
Avatar
それは変。
11:38 AM
エラーはちゃんと処理してコンソールに吐いたあとに死ぬのってフェーズ的にはなにで死んでるんでしょうね
11:41 AM
イニシャライザBの中でイニシャライザAを呼び出してる時点でselfの型はContainer<T>に決まっているのでその時点で T しか受けないことが決まっているイニシャライザAに T ではない Int を渡せちゃってる?
11:42 AM
Stack dump: 0. Program arguments: /Applications/Xcode_10_1.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -interpret Development/MyPlayground.playground/Contents.swift -enable-objc-interop -sdk /Applications/Xcode_10_1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -color-diagnostics -module-name Contents 1. While type-checking 'init(b:)' at Development/MyPlayground.playground/Contents.swift:6:5 2. While type-checking statement at [Development/MyPlayground.playground/Contents.swift:6:38 - line:8:5] RangeText="{ self.init(a: b as! Int) }" 3. While type-checking expression at [Development/MyPlayground.playground/Contents.swift:7:9 - line:7:31] RangeText="self.init(a: b as! Int)" fish: 'swift Development/MyPlayground.…' terminated by signal SIGSEGV (Address boundary error)
11:42 AM
久々にセグフォ引いてテンション上がってしまったよ
Avatar
@swift-main class Container<Content> { init(a: Content) { fatalError() } init<T>(b: T) where T == Content { self.init(a: b as! Int) } }
Avatar
swiftNightly BOT 11/16/2018 12:04 PM
exit status: 1 with stderr:<stdin>:7:27: error: same-type requirement makes generic parameters 'T' and 'Content' equivalent init<T>(b: T) where T == Content { ^ <stdin>:8:14: error: cannot invoke 'Container<Content>.init' with an argument list of type '(a: Int)' self.init(a: b as! Int) ^ <stdin>:8:14: note: expected an argument list of type '(a: Content)' self.init(a: b as! Int) ^ <stdin>:7:5: error: designated initializer for 'Container<Content>' cannot delegate (with 'self.init'); did you mean this to be a convenience initializer? init<T>(b: T) where T == Content { ^ convenience <stdin>:8:14: note: delegation occurs here self.init(a: b as! Int) ^
Avatar
正しそう
Avatar
おっ
12:12 PM
なおってんのか
Avatar
for i in 1... { print(i) } これ無限ループになるんですね、終端値無くてもrangeになるんだ
Avatar
無限なんですか?
5:18 AM
2^63-1がでかすぎて、実質無限なだけかも?
Avatar
無限かどうか検証出来てないので実質無限かも
Avatar
あ、違うのか、終端が無いのだから、最大値が定義されていなくて、本当に無限なのかな?
5:20 AM
ちなみにその記法自体は結構便利で func eatBuffer() { self.buffer = Array(self.buffer[self.pos...]) self.pos = 0 } ↑ストリーム処理を書いているときにこれをよくやります
👏 1
Avatar
確かにbytesのlength確認せずに読めるの便利ですね
Avatar
です
Avatar
enumerated()ではないindexが欲しい時にも zip(0..., arraySlice)
Avatar
SwiftLintのルールをSwiftSyntaxを使って実装し直してみたというお話。 https://twitter.com/simjp/status/1065772315189727233 現状のSourceKitを使った場合と同等の速度が出る様になるまでどれくらいかかるかな。 (edited)
tl;dr; Implementing SwiftLint using SwiftSyntax instead of SourceKitten would make it run over 20x slower 😭
Avatar
20倍・・・
Avatar
もう少しマシになったらしい。 https://github.com/realm/SwiftLint/pull/2480
This is a follow-up to #2476 but using SourceKitten's syntaxTree request instead of invoking the swiftc process for each file. Early results are promising but it's still significantly slowe...
12:28 AM
あ、これはswiftcの代わりにSourceKitを使うSwiftSyntaxだ。
12:32 AM
swiftc -> JSON -> SwiftSyntax -> SwiftLintFramework が SourceKit -> JSON -> SwiftSyntax -> SwiftLintFramework になってる。 (edited)
12:33 AM
SourceKitネイティブのデータ構造を使う、現状の SourceKit -> SwiftLintFramework の方が速いのは当たり前だな。 (edited)
12:36 AM
あいや、ネイティブとは違うか。
Avatar
SourceKitとSwiftSyntaxとの間がByteTreeになれば、今SwiftLintが使ってる[String: Any]ベースよりも速くなる可能性があるな。 https://github.com/apple/swift-syntax/blob/master/Sources/SwiftSyntax/ByteTreeDeserialization.swift
SwiftPM package for SwiftSyntax library. Contribute to apple/swift-syntax development by creating an account on GitHub.
Avatar
Package.resolvedをコミットしていないリポジトリにいつの間にかPackage.resolvedが生成されたり、知らないうちにPackage.resolvedが更新されたりしてたりしたのが不思議だったのだけど、SourceKit-LSPを入れたVSCodeでワーキングコピーを開いてたからだった。
Avatar
VSCodeがpackage updateするんですか?
Avatar
SourceKit-LSPがビルドするんじゃないかな。
Avatar
ああ、なるほど。
9:56 AM
普通のSourceKitやXcodeはSwiftPMと一切反応しないから、
9:56 AM
SourceKit-LSPはちょっと違う設計思想になってそう
Avatar
Package.swiftの中身がLinux向けとmacOS向けで依存するライブラリが違ってて、リポジトリにはLinux向けに生成されたPackage.resolvedがコミットされてて、それをmacOSのVSCodeで開くとPackage.resolvedが更新される。
Avatar
それは地味に面倒ですねw
Avatar
Swiftボットに使ってるSwordっていうライブラリがそんなヘンテコな構成になってる。
10:29 AM
脱Swordしたい。
Avatar
いつからか分からないけど、swift-5.0-DEVELOPMENT-SNAPSHOT-…のmacOS版でStringのUTF16関連がぶっ壊れてるぽい。 (edited)
Avatar
違った。Data.withUnsafeBytes(_:)がクロージャへコピーされた一時メモリを指すポインタを渡すように変わったからだった。
Avatar
@swift-4.2.4 import Foundation let data = "test".data(using: .utf8)! dump(data) data.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in dump(bytes) } (edited)
Avatar
▿ 4 bytes - count: 4 ▿ pointer: 0x00000000079af0d0 - pointerValue: 127594704 ▿ bytes: 4 elements - 116 - 101 - 115 - 116 ▿ 0x00000000079af0d0 - pointerValue: 127594704 (edited)
Avatar
macOSだとpointerValueが違う。 $ xcrun --toolchain org.swift.5020181225a swift swift_oss_helper command enabled. Welcome to Apple Swift version 5.0-dev (LLVM c351ac7354, Clang aadec4ff83, Swift 5cfc2e7ba9). Type :help for assistance. 1> import Foundation 2. let data = "test".data(using: .utf8)! 3. dump(data) 4. data.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) in 5. dump(bytes) 6. } ▿ 4 bytes - count: 4 ▿ pointer: 0x00007ffeefbff818 - pointerValue: 140732920756248 ▿ bytes: 4 elements - 116 - 101 - 115 - 116 ▿ 0x00007ffeefbffb30 - pointerValue: 140732920757040 (edited)
Avatar
norio_nomura 1/13/2019 6:30 AM
SwiftのCodableは便利ですが、FoundationJSONEncoder, JSONDecoderを使っていて微妙に不便に感じる事があります。自分がいろいろな案件をこなしたり、他人の困り事を聞いてきた上で、...
Avatar
omochimetaru 1/13/2019 6:30 AM
お。ありがとうございます
Avatar
norio_nomura 1/13/2019 6:31 AM
けど、LinkedListObject周りリークしまくりでは。
Avatar
omochimetaru 1/13/2019 6:35 AM
あ、たしかに。nextとprev両方ともstrongじゃダメだ。
Avatar
omochimetaru 1/13/2019 7:46 AM
XCTestにLeaksをかけてみたんですが
7:46 AM
Leaksがサイクル検出をする前にプロセスが終了しちゃうみたいで
7:46 AM
良い方法ってありますか?
Avatar
LinkedListObject.IndexLinkedListObject.Node?にしたらシンプルになるのでは?と試してたのだけど、public typealias Index = Optional<Node>を定義してもCollectionにconform出来ていないと文句を言ってくる。
12:22 PM
Collection.IndexにはOptionalを使えないのかな。
Avatar
extension Optional: Comparable where Wrapped: Comparableになってなかった。
Avatar
そのcomparableが厄介なんですよね
12:13 AM
Collectionに準拠するために実装してあるけど、func <がO(n)になっちゃってる
12:14 AM
O(1)にしろとは書いてなかったから、セーフだと思うけど、気持ち悪い
12:15 AM
たしかにNode?がcondconfしてればIndex型を無くせますね
Avatar
その場合nilが末尾なのであらゆるものより大きくなるのかしら
Avatar
そう
12:16 AM
いまのIndexもプロパティでNode?を持ってて、まさにそうなってるよ
Avatar
ウウーンそのルールをConditionalConformに追加するのは
12:16 AM
今のswiftだとキツそう
12:17 AM
キツいというのは、出来るけど汚染が
Avatar
やるならWrapped==Nodeのピンポイントcondじゃない?
12:17 AM
できないんだっけ?
Avatar
出来るけど、OptionalのComparableが他で拡張できなくなる
Avatar
あーー
Avatar
かと言ってWrappedがComparableの時にnilをmax扱いは
Avatar
Optional:Comparableが占有されちゃうんか。
Avatar
ちょっと乱暴の気がするよね
Avatar
そうしたく無い人もいそうだね。
Avatar
素直にIndex作るのが良いだと思いました
12:18 AM
急がば回れ
Avatar
condconfが進化したら
12:19 AM
その時に削除できるね
Avatar
そういえばcondconf汚染した2つのframeworkをimportしたらどうなるんやろ
12:21 AM
コンパイルエラーかな
Avatar
たしかに
Avatar
NodeSequenceにすると、func <が少し簡単になる。
Avatar
あー、イテレーションしてるところですか?
Avatar
nextfollowingに変えてる。 public static func < (lhs: LinkedListObject.Node, rhs: LinkedListObject.Node) -> Bool { if lhs == rhs || lhs.previous == rhs { return false } for following in lhs where following == rhs { return true } return false }
Avatar
おお素晴らしい
12:26 AM
そこ境界がゴチャゴチャして何回かバグったのです
12:26 AM
ていうかforってwhereつけれたんだ。
Avatar
僕もpublic typealias Index = Node?案はやはり却下という結論に至った。
Avatar
冒頭のpreviousは、隣接してるときは常にo(1)にしたいから?
Avatar
そう。
Avatar
なるほど。
Avatar
func copyoldIndicesに書き戻してるところは、何に使うつもりで書かれてたのですか?
Avatar
removeとかで使ってますよ
12:29 AM
structの方で。
12:29 AM
copyonwriteによるLinkedListObjectのクローンがおきたとき (edited)
12:29 AM
Indexはクローン前のリストのノードになってるので
12:30 AM
クローン先のノードに向けてやらないと続きの処理ができないんです
Avatar
ふむ。
12:35 AM
なるほど、ようやく分かりました。
Avatar
最初その問題に気がついて萎えて値型はやめたんですが、やっぱり値型で使いたかったので、苦渋の設計でそうなってますw
Avatar
norio_nomura 1/14/2019 2:02 AM
NodeCollectionに。 extension LinkedListObject.Node: Collection { public enum Index: Comparable { case node(LinkedListObject.Node), none public static func < (lhs: Index, rhs: Index) -> Bool { switch (lhs, rhs) { case (.node(let lhs), .node(let rhs)): return lhs < rhs case (.node(_), .none): return true default: return false } } init(_ node: LinkedListObject.Node?) { self = node.map(Index.node) ?? .none } var node: LinkedListObject.Node? { guard case .node(let node) = self else { return nil } return node } } public var startIndex: Index { return .node(self) } public var endIndex: Index { return .none } public subscript(position: Index) -> LinkedListObject.Node { guard let node = position.node else { preconditionFailure("Index out of range") } return node } public func index(after i: Index) -> Index { guard let node = i.node, let nextIndex = node.next.map(Index.node) else { return .none } return nextIndex } }
2:03 AM
そしてLinkedListObject.Node.IndexLinkedListObject.Indexに。
Avatar
omochimetaru 1/14/2019 2:13 AM
なるほど・・・?自身からendまでのコレクションとしてNodeだけで振る舞える?
2:13 AM
Bidirectinalは自身で止まっちゃうからダメかな?
Avatar
norio_nomura 1/14/2019 2:15 AM
BidirectionalCollectionLinkedListObject</