Guild icon
swift-developers-japan
main / other-lang
Swift以外の言語
Avatar
omochimetaru 6/1/2017 4:09 AM
JavaScriptのArray.concatが T または Array<T> の可変個の引数で、型付けが面白い TypeScriptでのシグネチャ https://github.com/Microsoft/TypeScript/blob/master/lib/lib.d.ts#L1006-L1010 MDNのリファレンス (動作例3) https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/concat
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
concat() メソッドは、配列に他の配列や値をつないでできた新しい配列を返します。
Avatar
↓がぶっ壊れてる。TSの辛いところ。 const a: Array<Array<string>> = [["a"]]; const b: Array<Array<string>> = a.concat(["b"]); console.log(b); [ [ 'a' ], 'b' ]
Avatar
omochimetaru 6/1/2017 4:22 AM
そうなりますね
Avatar
やっとできた・・・。 // Ceylon T[] concat<T>(T[] array, T[]|T values) { if (is T[] values) { return concatenate(array, values); } else { return concatenate(array, [values]); } } String[][] a = [["a"]]; String[][] b = concat<String[]>(a, ["b"]); print(b); [[a], [b]]
4:46 AM
Union のあるそれなりに有名な静的型付け言語、 Ceylon 以外にないのかな。
Avatar
omochimetaru 6/1/2017 5:39 AM
Ceylonだと実行時に 何の配列なのかわかるから分岐できるのか
5:39 AM
JSだと配列は配列で何の配列かはわからないからダメと
Avatar
Ceylon の方はオーバーロードにしたら静的に解決できるけどね。
Avatar
omochimetaru 6/1/2017 6:43 AM
オーバーロードならうん。
Avatar
TS でも型の上では Ceylon のように動作することが期待されるけど(戻り値の型が Array<Array<String>> だし)実際にはぶっ壊れた挙動になる。
6:44 AM
ただ、 Ceylon でも <String[]> がないと正しく推論してくれなかったのが謎。
Avatar
omochimetaru 6/1/2017 6:45 AM
返り値から一意に推論できそうですけどね
Avatar
その辺りTypeScriptで辛くなってきたのでKotlin to JSを試し出してるこの頃です
2:57 PM
訳あってGASをTSで書いてたんですが、GASで動くかと思ってPromise使うとコケるので諦めてKotlinのコルーチンで非同期なんとかならないかワンチャン試し中...
Avatar
omochimetaru 6/5/2017 3:09 PM
Promiseはポリフィル入れたらいいんでは?
3:10 PM
pure jsなライブラリでW3C仕様互換なやつがあるんで
3:10 PM
JSとしてぶち込めば
3:10 PM
lib.d.tsの型定義で動きますよ
Avatar
ポリフィルいれてみたんだけど、なぜかsetTimeoutをグローバル変数に突っ込むところでRefference errorになるのでそもそもGAS自体がダメなのではという気もしてます
Avatar
omochimetaru 6/5/2017 3:12 PM
ふむ~ それについては知識が無くてわからないです
Avatar
Kotlinのコルーチンで吐くJSがダメなら潔く諦めます(´・ω・`)
Avatar
omochimetaru 6/5/2017 3:13 PM
僕はTypeScriptやるときは生JSでどうやるのかを同時に意識してやってます
Avatar
吐かれるJS割と綺麗ですもんね、interfaceとか頑張って定義しても実は全スルーなのは少し乾いた笑いが出ました
3:16 PM
Swiftに慣れてるとprotocol extensionが欲しくなる...
Avatar
omochimetaru 6/5/2017 3:26 PM
Prototypeにメソッド注入すれば一応できますよ
Avatar
確かにObservableはclassだからprototypeいじれば拡張できますね interfaceでも同じ挙動なんでしたっけ
Avatar
例えばこういうinterfaceが定義されてたとして、 interface URLRequest<T> { baseURL(): string; path(): string; method(): string; parameters(): { [index: string]: string; }; headers(): { [index: string]: string; }; parseResponse(response: HTTPResponse): T; } さらに用途に合わせたHogeAPIRequestとしてURLRequestを継承させたinterfaceをbaseURLだけは固定のものを返したい、みたいな時に返せなくてprotocol extension欲しいな、となりました (edited)
Avatar
omochimetaru 6/5/2017 3:51 PM
なるほど interface に対しては実体が無くて不可能ですね
😂 1
Avatar
Python の round が予想外の挙動なんですが何か知ってる人いませんか? >>> a = round(3.14) >>> print(a) 3 >>> type(a) <class 'int'> >>> b = round(np.float64(3.14)) >>> print(b) 3.0 >>> type(b) <class 'numpy.float64'>
8:46 AM
返り値は 1 引数で呼ばれたなら整数、そうでなければ number と同じ型です。
https://docs.python.jp/3/library/functions.html#round
Avatar
In [1]: a = np.round(3.14) In [2]: a Out[2]: 3.0 In [3]: print(a) 3.0
8:46 AM
あ、npじゃなかった
8:47 AM
ふつうにintになりました
Avatar
一般の Python オブジェクト number に対して、round(number, ndigits)number.__round__(ndigits) に移譲します。
(edited)
8:47 AM
__round__ メソッドが定義されているって話ではなくてですか?
Avatar
おお、次の行を読んでませんでした・・・
8:48 AM
すみません、ありがとうございます。
🙂 1
Avatar
omochimetaru 6/14/2017 4:20 AM
@335g 記法の問題だけでしょうかね。Rustのtraitが高階型をサポートしているなら、明確な優位性だと思います。
4:21 AM
この会話見て調べていたんだけど
Avatar
Avatar
omochimetaru 6/14/2017 4:21 AM
Rustのtraitには Swift みたいな Associated Type と、Scalaみたいな Generic Parameterの両方が使える
Avatar
この両者の違いはなんだ
Avatar
omochimetaru 6/14/2017 4:22 AM
associated-types.html の方に書いてある
4:23 AM
で、高階型については、redditで、今のRustじゃ無理だよ、っていう回答が出てる。2年前だけど。 https://www.reddit.com/r/rust/comments/2av5tv/why_does_rust_not_have_a_functor_trait/
I know that Rust has some useful methods for everything that implements the Iterator trait...
Avatar
遠そう
Avatar
omochimetaru 6/14/2017 4:23 AM
ただそこにあるのは、 ある型が trait Functor を満たす時、 その型の Self だけ T からバラして対応とる必要があるんだけど
4:24 AM
Swiftの Self が Associated Type こみこみで具象化されるために それができないのと同様に
4:24 AM
Rust の self も同じ仕様でできないんじゃい、という感じがする
4:24 AM
scala だと trait Functor [ F [_] ] ってやって、パターンマッチで Fだけを取れるんだけど
4:25 AM
相当する構文機能が無さそう 。 Redditの回答も同じ話しをしてるっぽい。
4:26 AM
Self (the F from the definition above) is a type parameter parametrized by another type parameter, which means Self has kind * -> * (the currently impossible part).
Avatar
_強いなぁ
Avatar
omochimetaru 6/14/2017 4:27 AM
traitの基本自体は、 ある型 T が あるTrait P を満たす事を、 Tの定義とは分離して impl P for T って書くので、Swiftと似とる
Avatar
Genericsは正直、Assoctypeの劣化版じゃないかと思っていて
4:28 AM
まあ互換で書けると嬉しいのは、嬉しいのかな
Avatar
omochimetaru 6/14/2017 4:28 AM
https://rust-lang-ja.github.io/the-rust-programming-language-ja/1.6/book/trait-objects.html この記事の「トレイトオブジェクト」は、Swiftの protocol witness existential と全く同じ話しをしてる気がする。
4:30 AM
AssocとGeneric両方ある状態だと、それをどうやって使い分けているかを学ぶ事で、それぞれのpros-consがわかってきそう。
Avatar
Genericsのprosがちょっと書きやすい以外になさそうな気がする、具象化が楽、とか?
Avatar
omochimetaru 6/14/2017 4:34 AM
Protocol<T>::Hoge(); みたいな、static methodは <> じゃないと定義できないよね
Avatar
それは記法の問題で
4:35 AM
Any<Sequence where .Element=String>が出来るようになれば解決する
Avatar
omochimetaru 6/14/2017 4:36 AM
まあでもそれを言い出すと、Genericsに対しても、 GenericProtocol<A, B, C> に対して、 func f <X : GenericProtocol> ( x: X, a: X.A) とか書ければいいって
4:37 AM
ことになっちゃわね?
Avatar
それはそうだな
Avatar
omochimetaru 6/14/2017 4:38 AM
Rustのtraitのメソッドは明示的な &self を引数に取る fn として書くんだなあ。
4:38 AM
&self が無いものは trait自体に定義されたstatic methodのように見えるようだ (edited)
Avatar
具体的な実装からtraitのデフォルト実装を実行することは可能なのか? (edited)
Avatar
omochimetaru 6/14/2017 4:43 AM
trait Foo { fn is_valid(&self) -> bool; fn is_invalid(&self) -> bool { !self.is_valid() } }
4:44 AM
これ?
Avatar
traitの実装側で、is_invalidを改造して、その条件の中にsuper.is_invalidを使うみたいな
Avatar
omochimetaru 6/14/2017 4:44 AM
Foo::is_invalid(self) って明示的にやればできそう
Avatar
ほー
Avatar
omochimetaru 6/14/2017 4:45 AM
わからんけど。
Avatar
出来るならそれは明確な利点だね
Avatar
omochimetaru 6/14/2017 4:45 AM
あ、すげえ、これ[ run] おしたらエディタひらいた
4:46 AM
ためせそう
Avatar
omochimetaru 6/14/2017 4:57 AM
あ〜できなさそうだなあ
4:59 AM
impl Foo for Cat の中で Foo::aaaa(&self) ってやっても、再帰してるよって言われて
4:59 AM
デフォルトのほうじゃなくて結局 cat.aaaa() を呼んでる扱いっぽかった
Avatar
うーん、じゃあ個人的にはトントンな感じだ
Avatar
@omochimetaru まとめありがとうございます
Avatar
omochimetaru 6/14/2017 8:45 AM
あ、どうも
Avatar
もともとは https://rust-lang-ja.github.io/the-rust-programming-language-ja/1.6/book/error-handling.html のFrom trait見てて、Swiftだとどう書くのが良いのかなって思ったんですよね
Avatar
RustだとVoidがNoneと等価でError型なる区分は特に無くてResultを使う、のか
8:48 AM
あでもError traitもあるな
Avatar
omochimetaru 6/14/2017 8:49 AM
impl<'a, E: Error + 'a> From<E> for Box<Error + 'a>
8:49 AM
この実装では、 Error を実装した 全て の型は、トレイトオブジェクト Box<Error> に変換できると言っています。
8:50 AM
これって、Conditional Conformance ですね
Avatar
Box<Error>がErrorならそうだけど、そうなの?
Avatar
omochimetaru 6/14/2017 8:51 AM
型E が E is Error であるときに限り、 型 Box は From <E> である
Avatar
''' trait From<T> { fn from(T) -> Self } ''' みたいにTからSelfを作るような
Avatar
ほー
Avatar
omochimetaru 6/14/2017 8:51 AM
Swiftだとできないと思う
Avatar
fromは生やせるけど、fromを型として定義できない。
Avatar
associatedType固定しないといけないですよね
Avatar
omochimetaru 6/14/2017 8:52 AM
extension <E> Box<E> : From<E> where E : Error { } (edited)
8:52 AM
conditional conformance と、 parameterized extension の2つの機能が無いとダメそう
8:52 AM
そしてFrom <E> がそもそも書けない
8:53 AM
あ〜
8:54 AM
さっき話してた assoc typeじゃできないケースこれか?
Avatar
はい
Avatar
omochimetaru 6/14/2017 8:54 AM
あ、でも、Box<E>とFrom<E>のEは一致するのか。
8:55 AM
extension Box : From where Box.Element : Error , Box.Element == From.Element { }
8:55 AM
一致は書けるから、Conditional Conformanceだけでいける気がしてきた。
Avatar
いけるはず
8:56 AM
assoctypeとgenericsは、僕の理解が正しければ記法が違うだけで同じ機能のはず
Avatar
omochimetaru 6/14/2017 8:56 AM
いや、このBoxの場合はそうなんだけど (edited)
8:56 AM
もしかしてRust自体は
8:57 AM
impl From<String> for Cat と impl From<Int> for Cat を、別々にconformanceできるんじゃないか?
Avatar
分けて書けますね
Avatar
おお
Avatar
omochimetaru 6/14/2017 8:57 AM
Swiftのprotocolだと、CatがFromを満たす時、Fromのassociated type T は1つに固定される
8:57 AM
でもRustのTraitでそれがジェネリックな場合は
8:58 AM
From<T> の Tの具象型ごとに異なる トレイトとして、それぞれconformanceできる
8:58 AM
そう考えると、 Rustのtrait が associated typeとgeneric parameterの両方持ってるのはわかりやすくて
8:59 AM
generic parameterが埋まった時に、traitが一つ完成して、個別の型は完成したそれごとにconformanceをもつんじゃない?
9:03 AM
impl From<i8> for i16 impl From<i8> for i32 impl From<i8> for i64 impl From<i8> for isize impl From<i16> for i32 impl From<i16> for i64 impl From<i32> for i64 impl From<u8> for i16 impl From<u8> for i32 impl From<u8> for i64
9:03 AM
そうっぽい。i32っていう型に対して、From<i8>, From<i16>, From<u8>がそれぞれconformanceしてる
Avatar
これかなり大きな差だな
Avatar
omochimetaru 6/14/2017 9:04 AM
ですね 新しい視点に気づけた
Avatar
Swiftだとこれはスッと出来ないので
9:06 AM
Either型みたいなまどろっこしいものをassoctypeに入れるしかない、それも単純にならないから
9:06 AM
ユーザ定義のサブタイプ、ユニオン型みたいなものが欲しくなってしまう
9:06 AM
もしかしてこれが可能ならサブタイピング要らなくなるんじゃないか?
Avatar
tarunon - 2017/05/09 えっとですねー 原初の欲求としては、assoctypeに複数値を持たせたいんですよ omochimetaru - 2017/05/09 昨日話してた可変長ジェネリックか tarunon - 2017/05/09 複数種類の型を定義すると、複数種類の実装のオーバーロードで実現される。 これが出来るとですね、assoctypeで引数を束縛するような、2つの型の関係が 1:1,1:多しか今は出来ないが omochimetaru - 2017/05/09 Tuple2にある機能はTuple3にも全て欲しい、みたいな? tarunon - 2017/05/09 多:多が可能になる いや、タプルとは違うな Viewから実装を引っぺがして、それをGenericsに作ることで NibとGenerics型の共存が出来ないかなと考えてるところから派生してる これ自体は上手く行きそうなんだけど、Viewと実装の繋ぎ込みがfuncになっちゃって、型を書くのが怠いから、assoctypeで縛ろうとしたが… という感じ、Viewと実装をassoctypeに持つ第三の型を作ればいい気もするけど、登場人物はなるべく増やしたくない omochimetaru - 2017/05/09 よくわからないけど、型Aと型Xの組み合わせのときの処理を静的に定義したい、そのペア自体を型付けしたい? tarunon - 2017/05/09 extension View: HasImpl { typealias Impl=Int } ↑これだと、Intしか実装がない。なので、IntかStringを使おうとすると↓ extension View: HasImpl { typealias Impl=Int|String } ↑こういうのが欲しくなる そうそう omochimetaru - 2017/05/09 (A/B/C) x (X/Y/Z) のような合成がしたいと tarunon - 2017/05/09 そう! omochimetaru - 2017/05/09 で、(*) x (X) とか (A) x (X) とか (A/B) x (*) の場合における実装を定義したい?(編集済) tarunon - 2017/05/09 えーっと、そこの掛け算全部書くのは吝かではない(編集済) omochimetaru - 2017/05/09 なるほど あー、 A / B / C とかは個別の データモデル型とか 個別のViewだから enum にならんのか
9:26 AM
まさにこれの実現と言えそう
Avatar
omochimetaru 6/14/2017 9:26 AM
たしかに?
Avatar
From型、まさに僕の理想の型だ、これが欲しかったんだ
Avatar
面白いですね、これ。traitを実装する型自体とtraitのgeneric parameterとが一対一に紐付かないのか (edited)
😁 1
Avatar
これが出来る実装を持ってるなら高階型もあと一歩な気がするけど実際どうなんだろ
2:09 PM
そこは難しいのかな🤔
Avatar
高階型を組むためには、型変数の中に不完全な型を取って、それに対する制約を書かないといけない Rustの型変数は完成した型を受け取るからできないっぽいね
2:56 AM
Rustだと trait Hoge<A> { fn aaa(&self) -> A; fn bbb(&self) -> i32; } に対して、 Hoge<i32> と Hoge<String> で別々の aaa(), bbb() の実装を持てる例 (edited)
2:56 AM
特に、aaa() と違って、bbb() はHogeの型パラAにかかわらずシグネチャが全く同じなので、オーバーロードの範疇ではできない事ができている。 (edited)
Avatar
これめっちゃおもしろい
3:02 AM
型によって実装が挿入できるの型クラス感
Avatar
Genericsパラメータに与えない場合、bbbが曖昧なので呼び出せない気がする
3:07 AM
rustc 1.18.0 (03fc9d622 2017-06-06) error[E0282]: type annotations needed --> <anon>:45:5 | 45 | call_hoge_generic(&cat); | ^^^^^^^^^^^^^^^^^ cannot infer type for `T` error: aborting due to previous error
3:07 AM
そのとおりだね
3:08 AM
call_hoge_generic::<i32, Cat>(&cat); このようにすることで呼び出せた。
3:08 AM
call_hoge_genericの型パラメータ、TとXを明示的に指定した。
Avatar
norio_nomura 6/15/2017 3:13 AM
ジェネリックなメソッドに型特化実装を書ける、っていう理解で合ってる?
Avatar
omochimetaru 6/15/2017 3:14 AM
いや、それは違いますね。そういうこともできるかもしれないけどここでやってるのはそうではない。
3:14 AM
call_hoge_i32 call_hoge_stringは完全に別々の関数です
3:15 AM
型ごとに特化した実装を持っているのは、「ジェネリックなメソッド」に対してではなくて
3:15 AM
「ジェネリックなトレイトのconformanceごと」です。
3:15 AM
impl Hoge<i32> for Cat { などの行ですね
Avatar
これRustは三角継承可能ってことじゃん
3:16 AM
ジェネリックなtraitのconrormanceごとじゃなくて、別のtraitと被っててもそれぞれ実装もたせれる気がする
Avatar
omochimetaru 6/15/2017 3:16 AM
trait Fuga にも fn bbb() があったら、ってこと?
Avatar
omochimetaru 6/15/2017 3:16 AM
できそうだね。(やってみて
Avatar
norio_nomura 6/15/2017 3:17 AM
「ジェネリックなトレイトのconformanceごと」です。
なるほど、そういうことか。
Avatar
omochimetaru 6/15/2017 3:17 AM
あい。どうしても分けわからない文章になる・・・
Avatar
うーん、 Swift は↓もできないのか。 protocol Hoge { associatedtype A func aaa() -> A //func bbb() -> Int } protocol HogeInt: Hoge { typealias A = Int func aaa() -> Int } protocol HogeString: Hoge { typealias A = String func aaa() -> String } struct Cat {} extension Cat: HogeInt { func aaa() -> Int { return 11 } //func bbb() -> Int { // return 22 //} } extension Cat: HogeString { func aaa() -> String { return "sss" } //func bbb() -> Int { // return 33 //} }
3:22 AM
Hoge の中身をコメントアウトすればコンパイルできる。
Avatar
omochimetaru 6/15/2017 3:22 AM
あ、↑もっていうのは、コメントアウトされてるbbbのことじゃなくて、コレ自体ダメなのか
Avatar
Hogeの中身がなければただのoverloadになるから出来ますね (edited)
Avatar
@omochimetaru うん、これ自体ダメ。
3:24 AM
これがダメなのは意図的な仕様なんでしょうか?それとも現状の実装の問題?
Avatar
assoctypeを一通りにしか決定できないのは仕様っぽい
Avatar
norio_nomura 6/15/2017 3:25 AM
意図したものですよね。
Avatar
できちゃうと、これの返値のタイプが決定できなくなってしまうのでは? func retAAA<H : Hoge>(h: H) -> H.A { return h.aaa() }
Avatar
@rintaro それはそこで ambiguous でもいい気も。
3:28 AM
↓で解決できないですかね?戻り値型から A を推論して渡せる hoge の型チェックをする。 let aaa: Int = retAAA(hoge)
Avatar
func printAAA<H : Hoge>(h: H) { print(h.aaa()) } これが何をprintするかを考えたときに (edited)
3:31 AM
(protocol Hoge および func printAAA) とそれ以外が別モジュールだったら
3:32 AM
解決できないと思います。
Avatar
まだ考え中ですがこれは説得力がある気がします・・・。
Avatar
ユニオン型導入とかいう逃げ道考えたけど全体的にRustのアプローチの方が筋がいい
Avatar
(あとここは #other-lang ) 😬
Avatar
omochimetaru 6/15/2017 3:33 AM
まあこの流れは仕方ないような・・・
Avatar
あ、rust の話からつづきだったのですね。なるほど
Avatar
norio_nomura 6/15/2017 3:34 AM
これと同義ですよね。 protocol Hoge { associatedtype A func aaa() -> A } protocol HogeInt: Hoge where A == Int {} protocol HogeString: Hoge where A == String {} struct Cat {} extension Cat: HogeInt { typealias A = Int func aaa() -> Int { return 11 } } // error: 'HogeString' requires the types 'Cat.A' (aka 'Int') and 'String' be equivalent extension Cat: HogeString { func aaa() -> String { return "sss" } }
Avatar
ぱっと見同じに見えます。
3:37 AM
逆に Rust では printAAA みたいなのはどうなるの??
Avatar
traitがGenericsなので
Avatar
omochimetaru 6/15/2017 3:37 AM
↑これが答えになってない?
Avatar
Hoge<X>に対してHogeだけで指定することは出来ない
Avatar
あー、そうか。
Avatar
omochimetaru 6/15/2017 3:38 AM
ああ、端的にそういえばいいか
Avatar
他に多重継承できるジェネリックインタフェースがある言語ってないのかな。
3:39 AM
Java とかはそもそも型パラ違いが型として分かれてないから、できないのは別の問題な気も。
Avatar
omochimetaru 6/15/2017 3:40 AM
Javaの場合はジェネリックな型っていうより
3:40 AM
Object型になった実装1個だしなあ
Avatar
Scalaはどうでしょう、多分できそう
Avatar
associatedtype<H: Hoge> と書けることと、ジェネリクスだと多重型パラ継承できるけど型パラ埋めないといけないから <H: Hoge> 相当のことができないことが対応してるのか。
Avatar
omochimetaru 6/15/2017 3:41 AM
はい、その特性が全く違うから
3:41 AM
Rustには両方入ってるけどちゃんとまとまってるっぽい
Avatar
なんかインタフェースと型クラスの違いみたいだ・・・。
Avatar
できることを狭める代わりにより柔軟なことができるという意味で。 (edited)
Avatar
norio_nomura 6/15/2017 1:39 PM
そうか、昼間のRustの例はconditional conformanceなのか。
Avatar
Python 書いてると Swift のノリで↓ってやっちゃって辛い。 for key, value in dict: ... 正しくは for key, value in dict.items(): ...
Avatar
omochimetaru 6/16/2017 8:35 AM
あるあるw
Avatar
Python...lambdaとか使いたくなるけど内包表記が慣れないorz そしてあまりlambdaは一般的じゃないのも辛い...
Avatar
lambda は記法が辛いのと、 mapfilter の戻り値が List じゃなくて辛いので内包表記慣れるのオススメです。
👀 1
8:43 AM
mapfilter なら内包表記で代替できますし、その二つがあれば大体問題ないんで。
8:43 AM
あ、あと、 Python 3.6 にして typing 使ったら大分 Swift みたいになりますよ。
Avatar
<map object at 0x106ac1ef0>
ほんまや...罠だ
8:44 AM
Python 3.6 にして typing 使ったら大分 Swift
typingいいですよね、これ無かったら書きたいと思わなかったです
🙂 1
Avatar
from typing import List list: List[int] = [2, 3, 5] squared: List[int] = [x * x for x in list]
Avatar
型を厳格に書こうと思うとけっこう面倒くさいという
8:45 AM
特にtuple返すパターン
Avatar
Tuple[int, int] とか書くのめんどくさい・・・ (edited)
8:46 AM
Callabble[[int, str], float] とかもっとめんどくさい。 (edited)
😢 1
Avatar
で、長くなりすぎてpepに引っかかるという
Avatar
PEP8 ね。 PEP は Swift の SE-0110 の SE みたいなもの。
Avatar
そうでした。このへんの呼称慣れない
Avatar
PyCharm の型チェック微妙にうまく働かなかったり、逆に誤検出したりするのが微妙。
Avatar
mypyも併用するとどうですかね?
Avatar
numpy.ndarray に対して % 使ったりすると戻り値 ndarray と解釈してくれない・・・。
8:50 AM
mypy 使ってないんでわかんないです。
Avatar
mypy、namedtupleの中まで検査してくれてるみたいで強かったです
Avatar
おお
Avatar
そのへんはnumpy側に定義ファイルが要るのかな?
Avatar
PyCharmと併用できないのが辛いですが...
Avatar
そういえば、この前リストだけじゃなくて辞書やセットも内包表記使えるの知って感動しました。
8:53 AM
SE-0165 の DIctionary の新しいイニシャライザ相当のことができる。 (edited)
8:54 AM
// Swift let idToUser = [String: User](uniqueKeysWithValues: users.map { ($0.id, $0) }) (edited)
8:55 AM
# Python id_to_user = {user.id: user for user in users}
Avatar
Swiftに見えてきた(錯乱)
Avatar
Swift 長ったらしいな。例の => を使えば↓でいけるのかな? let idToUser = users.map { ($0.id, $0) } => Dictionary.init
Avatar
レキシカルスコープがある限り間違えない
Avatar
↓の Kotlin のロゴ、小鳥っぽい。 https://kotlinconf.com/
KotlinConf is a two-day conference taking place in San Francisco, providing deep-dive technical content on Kotlin.
✨ 2
Avatar
omochimetaru 11/7/2017 9:03 AM
↑のKotlin Conf で、 カンファレンスアプリのiOS版が kotlin で書かれてたらしいですね。
9:04 AM
共有部分は サーバーとウェブとAndroidとiOSの4つの環境で共有されていて ↑はiOS固有部分のコード (edited)
Avatar
kotlinconf-app - KotlinConf Schedule Application
Avatar
omochimetaru 11/7/2017 9:06 AM
本当だww
Avatar
ObjCとJavaはObjCとSwiftより近いと思うのでKotlinでもうまくいきそうな気がする。
Avatar
omochimetaru 11/7/2017 9:09 AM
てか、 Kotlin/Nativeは JVM からは独立した仕様ですよ
Avatar
はい、そうだけど、 Kotlin は Java の言語仕様を忖度しているので
Avatar
viewDidLoadもsuper無くないですかこれ
Avatar
@tarunon ないですね。なんでだろう。単純に忘れてるのか、なくてもいいように作られているのか?
Avatar
UIViewControllerクラスのそれらのメソッドって実際中で何かやってるんでしょうか
Avatar
omochimetaru 11/7/2017 9:12 AM
実際はやってないと思ってた。
9:12 AM
親クラスがユーザ定義の場合に
9:12 AM
やってることがあるから、呼ぶようにクセ付けたほうがいいというだけで?
Avatar
UIViewControllerには実装がなんもないから呼ばなくても結果オーライになってるだけかなと思っt。
Avatar
omochimetaru 11/7/2017 9:12 AM
呼ばないと壊れる UIKit 標準のやつもあるのかな
9:12 AM
そうそう、同じく。 > 結果オーライ
Avatar
↓ラッパー層があるわけじゃなくて機械的に読み替えられてる? https://github.com/JetBrains/kotlin-native/blob/master/klib/src/platform/ios/UIKit.def
kotlin-native - Kotlin/Native infrastructure
Avatar
将来壊れない保証もないし呼んどいたほうが無難でしょ派
Avatar
ですね。リファレンスにも書かれてるし。
If you override this method, you must call super at some point in your implementation.
https://developer.apple.com/documentation/uikit/uiviewcontroller/1621423-viewdidappear
Avatar
Android とか super 呼ばないと殺されるのに
Avatar
omochimetaru 11/7/2017 9:17 AM
お、 must だ
Avatar
これ見てると Kotlin で iOS アプリ、まったく問題なく作れそうな気がする。
Avatar
omochimetaru 11/7/2017 9:19 AM
ンゴ・・・
Avatar
RNより現実感高いすね
Avatar
まあ、エディタとかは辛いかな?そのあたりは JetBrains だからうまくやってくれるのかな?
Avatar
omochimetaru 11/7/2017 9:19 AM
たしかに >RN
9:20 AM
は、はやく Swift Managed を・・・
Avatar
Scala ちゃん....
Avatar
React Nativeとか、何が悲しくてわざわざ JS のコード書かないといけないだという気持ちに・・・。
Avatar
omochimetaru 11/7/2017 9:23 AM
JS はまあいろんな言語で書けますから。
Avatar
OptionalについてKotlinのuntaggedに対してSwiftの方が明確に優位だと思ってたけど最近崩壊してることに気がついてどっちもどっちやねってなってる
9:24 AM
値型はまぁ
Avatar
omochimetaru 11/7/2017 9:24 AM
あとJSが書ける人はウェッブ業界にめっちゃ多い・・・
9:24 AM
githubで一番盛り上がってる言語JSだった気がする
9:25 AM
@tarunon でもkotlinになったら検査例外も値型も無いで
Avatar
そこな
Avatar
Kotlin 検査例外ないのヤバイ。
Avatar
Result で…
Avatar
do 記法のない Result なんて使えたもんじゃないよ・・・。
Avatar
じゃあやっぱり Scala ですよ
Avatar
Scala Nativeいつなの
Avatar
まだまだそう
9:27 AM
夏ぐらい?に見たときは GC の実装が云々
Avatar
やっぱりバックに企業がついてるのはパワだなぁ
Avatar
同じこと書こうとしてた。
Avatar
Scala ちゃんは今は一応 lightbend (元 typesafe) がやってるけど
Avatar
これからは Go, Swift, Kotlin, Rust の時代?
Avatar
うーん (edited)
Avatar
omochimetaru 11/7/2017 9:28 AM
MS が忘れられてる・・・
Avatar
MS が C# に代わるモダン言語出したら盛り上がるかも
Avatar
F#
Avatar
omochimetaru 11/7/2017 9:29 AM
Cωだっけ
Avatar
T, TypeScript(震え声
Avatar
企業がバックと言えば Hack とかあったな。今名前も思い出せなかった・・・。
9:31 AM
なぜかいつも流行らない Facebook 製言語。 Flow も。
9:31 AM
React は流行ったのに。
9:32 AM
↑これみて、 React より VueJS がナウいらしいと知った
Avatar
KotlinはSwift式の検査例外導入して、 Nullable を Union にしてくれたら結構いいと思うんだけどなぁ。
9:36 AM
検査例外ないのが一番辛い。
9:37 AM
↓ Kotlin と Swift のコレクションの比較。この一面を見ただけでもやっぱり Swift がいいと思ってしまう。 https://qiita.com/koher/items/c2ad26a587682eaeaf74
これは Mobile Act OSAKA #1 での発表した内容をまとめたものです。 --- iOS / Android 双方に関係ある...
Avatar
omochimetaru 11/7/2017 9:39 AM
Java系は mutability をちゃんとやろうとすると、安全性かパフォーマンスのどっちかが犠牲になりますからねえ (edited)
Avatar
Arrayが値型になってるのいいですね
9:39 AM
まあKotlinはそこらへん多分Javaとの互換性もあるでしょうけど…
Avatar
omochimetaru 11/7/2017 9:41 AM
kotlinのつらみもう一個あった JavaのType Erasure を引きずってるから、 List<Int> と List<String> でオーバーロードできなかったような
Avatar
値型で言うと、↑と似たような話を、 Swift の struct と Kotlin の data class にも書ける。
Avatar
omochimetaru 11/7/2017 9:41 AM
あと protocol の static func , static var とかのおかげで、swiftは型クラスもどきができるけど
9:42 AM
kotlinはできない
Avatar
List<Int> と List<String> でオーバーロードできなかったような
これ、検査例外と並ぶ Kotlin の辛い点。
3:29 AM
RubyのNative ExtensionをRustで書くプロジェクトがあるらしいです
3:30 AM
これがちゃんと確立されたら、Railsのエコシステムに乗っかってアプリケーションコードはRustで書くみたいなことができるのかな
👀 2
Avatar
おおー。 少し前にNode.jsのネイティブエクステンションをSwiftで書くというPJを実験的にやっていて、(https://github.com/noppoMan/node-native-extension-in-swift) まさに今これの高レベルなインターフェースを考えているところだったので、参考になります! Python版バインディングも作ろうと思っていたところなので、この際RubyのネイティブエククステンションをSwiftで作れるやつも書いてみようかな...
👀 1
Avatar
さっき社内で Kotlin で Optional 実装する話をしてて、 Nothing が bottom type なことと、 out を使ってうまく実装できておもしろいです。 sealed class Optional<out T> { class Some<out T>(val value: T): Optional<T>() class None(): Optional<Nothing>() } fun main(args: Array<String>) { val a: Optional<Int> = Optional.None() // OK }
Avatar
scalaもまさにそんな感じで実装されてますね〜
👍 2
Avatar
This PR implements a new --strictPropertyInitialization compiler option to guard against uninitialized properties in class instances. Strict property initialization checking verifies that each inst...
10:07 PM
TypeScript の 初期化 null check が来た
10:08 PM
元issueで指摘されてた細かいケースがどう解決したのかまでは不明
10:08 PM
It is still possible to observe uninitialized properties in methods that are called from the constructor (or from a base constructor).
10:08 PM
あー、Swiftみたいなフィールド全初期化前の self 利用制限は 実装されてないな。
Avatar
We’re happy to announce the release of Kotlin/Native v0.4, KotlinConf 2017 edition! This release adds support for accessing Objective-C APIs on iOS and macOS, WebAssembly target platform, as well a…
1:23 AM
fun readResource(resourceName: String): ByteArray { val filePath = NSBundle.mainBundle.pathForResource(resourceName, ofType = null) val fileData = NSData.dataWithContentsOfFile(filePath!!) ?: throw Error("failed reading resource $resourceName") return fileData.bytes!!.readBytes(fileData.length.toInt()) } (edited)
1:24 AM
?:throw 書けるのいいなぁ。 Nothing が bottom type なのが利いてる。 (edited)
Avatar
Kotlin/Native 0.4 が Objective-C interop をサポートしたっぽい、 Swift の領域を食いにきたな https://t.co/EWJCEMyOO9
😨 1
Avatar
Kotlin 、最低限検査例外だけでもサポートしてほしい。
Avatar
今から入れるとなるとどうなるんだろう?
Avatar
入れられないから辛い。
Avatar
普通に考えたら Result でやれってことなんでしょうけど、標準で用意されてないですよね?
Avatar
普通に考えたら非検査例外でやれ、では?
Avatar
suspend 入れるけど throws は入れないという判断が理解しかねる。
Avatar
標準のAPIとかでResultで返すやつないし。
Avatar
標準 API が返さない、そうだよね…
Avatar
RubyもC#もみんな非検査例外でやってるよ
3:45 AM
あ、Result派としてScalaがあるのか。
Avatar
Scala は do 記法が使えるから Result でいいんです。
3:46 AM
for 式で。
Avatar
あーなるほど。KotlinだとScala未満のことしかできないのか。
Avatar
非検査例外よりはちゃんと型で明示されるので
Avatar
↑で挙がってるように標準ライブラリの問題もあるしね。
3:48 AM
結局 try/catchdo 記法ってほとんど同じで( do 記法がエラー以外にも使える汎用的なものであることは別として)、現代の大抵の言語はそういうエラー処理機構を持ってるから、それなしでエラーと戦おうとすると辛いと思う。 (edited)
3:51 AM
try/catch 系を採用してる言語では、 Java が検査例外を導入したけど後続言語がみんな非検査例外に逃げちゃったから、 Java と Swift しかコンパイル時にチェックできる言語がない・・・。
3:54 AM
Java の検査例外は、 Swift の try! 相当のものと、 null safety 、 NumberFormatException が非検査例外なこと、 Effective Java で推奨されてる例外の使い分けに従ってない API あたりが複合して使いづらくなってるけど、本質的には Java の検査例外でも Swift の throws/try と同じような使い勝手を実現できると思う。
Avatar
同じような使い勝手
3:58 AM
try ブロックはやっぱキツイですよ ブロック切れちゃうし
3:58 AM
Swiftは try オペレータにしたのがかなり賢いと思う
Avatar
んん?? do ブロックだからそこは Swift でも同じじゃない? (edited)
Avatar
throws関数で中からthrowする場面が多い
4:01 AM
UIViewControllerみたいな根っこはdoになるけど
4:01 AM
あ、それはJavaもそうか?
Avatar
うん
Avatar
あ〜ちがうちがうわかった
Avatar
ただ、 throws に型を書けるから
4:01 AM
包み直さないといけないケースが多いけど
Avatar
doブロックの中に複数の文があるときに、個別に try するのがSwiftで
4:02 AM
tryブロックの中の複数の文があるときに、全部暗黙に try 済みになっちゃうのがJavaで
Avatar
それは Swift でも本来はやるべき。
Avatar
SwiftとJavaの差だとそこがつらいんだ
Avatar
@omochimetaru これはめっちゃ思った
Avatar
それ以外は同じ?
Avatar
それよりも try! がないことが一番辛い。
Avatar
ふむ?
Avatar
## try! でエラーを握りつぶすことなくコンパイラを黙らせる この節で述べることは本投稿で **最も重要なこと** です。 (edited)
Avatar
僕は try! はあんまり使って無くて、代わりに自作関数の assertNoThrow(reason: String, f: () throws ->R) を作って
4:05 AM
!していい理由を明記するスタイルにしてるんですけど
4:05 AM
Javaでもこれを自作すれば、簡単に握れるようにならんかな。 (edited)
4:05 AM
今はクロージャ入ったし。
4:05 AM
Java8だとクロージャが絡むと非検査例外onlyの世界にダウングレードするんだっけ? (edited)
Avatar
Java の場合は N 個の例外を投げられるから gysb の出番では?
4:06 AM
いや、違うか
4:06 AM
中で投げるだけだから Exceptionthrow できるラムダ式に対応した interface を一つ書けば OK か。 (edited)
4:08 AM
ただ、 Java には null safety がない辛さもあるからキツイ。 Listmap ついてないのとかも。
4:08 AM
ListMap のリテラルがないのも。これは Kotlin もだけど。
4:11 AM
@NonNull とかを解釈して API 読み替えて、 List 等のリテラルサポートして、 Listmap したら Stream にして map して collect してくれるような Java のプリプロセッサ(?)があれば Java でいい気もしてる。
Avatar
Int a = 42; Int? b = a; if (b != null) { List<Int> list = [a, b]; List<Int> square = list.map(x -> x * x); var Int c = square[0]; c = square[1]; } が↓に変換されてくれるようなイメージ。 final int a = 42; @Nullable final Integer b = a; if (b != null) { @NotNull final Integer b_ = b; @NotNull final List<Integer> list = List<Integer>.of(a, b_); @NotNull final List<Integer> square = list.stream().map(x -> x * x).collect(Collectors.toList()); int c = square.get(0); c = square.get(1); }
Avatar
依存型 + リージョンによるメモリ管理な型システムのSwiftによる実装が進んでく様子リアルタイムで見られるの、鬼アツじゃないですか https://t.co/lUGyeO0RQJ
👀 5
3:28 AM
Swiftリポジトリでよくみる CodaFi さんが、Swiftを使ってなんか言語作ってるらしい。
Avatar
CodaFi と Harlan は仲いいやね。これも、 https://github.com/trill-lang/trill
trill - A type safe, compiled language inspired by (and written in) Swift
Avatar
本当だ。こっちは見た目がかなりSwiftっぽいですね、GCついてるって書いてあるけど
Avatar
とはいえTrillは最近あんまやる気無いみたいですけど https://twitter.com/harlanhaskins/status/929083619750109184
@jckarter @JohnRHeaton @UINT_MIN 👋 Trill's in an unfortunate state right now and I haven't really had the time or motivation to get it back into shape 😅 I'd love more eyes on things (https://t.co/bgtItWgeIi)! Also if you're interested, we'd love to have contributors to Silt: https://t.co/lv9eOAci9T
Avatar
なるほどなるほど
Avatar
omochimetaru 12/1/2017 3:13 AM
Egison は1つの定まった標準形を持たないデータに対しても柔軟なパターンマッチが表現可能なプログラミング言語です。リストや多重集合、集合、ツリー、グラフなどといった幅広いデータ型を扱うプログラムを非常にシンプルに記述できます。
3:19 AM
エギソンすごすぎ
Avatar
C# の拡張メソッド、↓みたいなことできるのか。これは Swift でもできるけど、 Swift の Generics Manifesto にある Generic Extension 相当のこともできそう。 static bool All(this IEnumerable<bool> thiz) { return thiz.Aggregate(true, (r, x) => r && x); }
Avatar
while (condition) { // ... } while (condition); みたいなコードを見つけてびっくりしたのだけど、C界隈ではあるあるネタなのかな?
7:02 AM
コンパイル通ることにびっくり。
Avatar
僕は初めて見ました それ文法上OKだったのか。
7:03 AM
do { } while の do が条件付きって形ですよね
Avatar
それって
7:03 AM
二つの statement になってるとか?
Avatar
while (condition) { // ... }; while (condition) {}; という扱いっぽい
Avatar
暗黒コードだ (edited)
Avatar
二つの statement になってるならインデント(フォーマット)がおかしいだけで変じゃない気が。
Avatar
え、ループは2個あるのかw
7:04 AM
そこセミコロン無くて許される理由がよくわからん。
Avatar
} で statement が完了してるのでは?
7:05 AM
; を含まないと statement じゃないんだったら
7:06 AM
if (<bool>) <statement> else <statement> に対して <statement> のところに { ... } を埋めれなくなる。
7:06 AM
似たような話で、ちょうど最近↓のコメントした。 // JavaScript let a = 10; if (a <= 0) { console.log(a); } else while (a >= 0) { console.log(a); a--; } https://qiita.com/ayies128/items/0e460b512d4698fc483d#comment-72ba84723db3df2ee909 (edited)
Avatar
else - if 接続はelseがそもそも後続の文を取るからわかるんですけど
7:07 AM
C言語はそうか、改行って意味ないのか。
Avatar
うん。そのために ; がある。
7:07 AM
Swift に染まり過ぎではw
Avatar
まあ、今回の場合完全にミスでやっちゃってるんですけどね。 condition 部分が両方同じなので、二つ目の while が意味なし。
Avatar
何かテクニック的に書いてるんじゃなくていろいろあってバグってたけど副作用が特に無かったみたいな感じですか
Avatar
あー、パーサーの読み捨てループとかこういう雰囲気
7:11 AM
元は do - while だったのでは・・・
Avatar
でしょうねぇ。。。
Avatar
二つ目の while が意味なし。
もしかしてこのスレッドは止めといて別スレッドと変数共有して解除とかあるのかと思っちゃいましたw
Avatar
こういうふうにgoto failバグが産まれたんだろうなあ
Avatar
いやでも一つ目抜けてるからほぼ無理か (edited)
7:14 AM
swiftコンパイラのコードなのか😱
😇 1
Avatar
アザーラングすれなんてあるのか。
Avatar
omochimetaru 1/30/2018 6:20 AM
あります
Avatar
他の言語とswiftの比較みたいな。
Avatar
omochimetaru 1/30/2018 6:22 AM
そうですね、iOS開発でC#とかJSとか普通に使う事もあるのでSwiftと関連のない話題もOKです
6:22 AM
objcは一応専用のチャンネルがあります。
Avatar
持病のrustのFrom<T>がほしくなる病の発作が起きてしまった
😞 1
Avatar
API documentation for the Rust From trait in crate std.
7:21 AM
あー、これめっちゃ便利だ…
Avatar
omochimetaru 8/3/2018 7:21 AM
ジェネリックトレイトといって
Avatar
欲しい。。。
Avatar
omochimetaru 8/3/2018 7:21 AM
Swiftのジェネリクスとプロトコルが合体してて
7:21 AM
Swiftを超えた型システムをもってる
7:22 AM
その一番わかりやすいのがFrom<T>
7:23 AM
ジェネリクスと、プロトコルのアソシエイトタイプって、どう違うんだ?ってことを考えるときに
7:23 AM
ラストのジェネリックトレイトを眺めると
7:23 AM
わかりやすいと思います
Avatar
これがあると、制約付けた型プログラミングでworkaround無しにいろいろできるようになる
Avatar
omochimetaru 8/3/2018 7:24 AM
そういう話が前にここのサーバーであって、それからタルノンはずっとラストの事指くわえて羨ましそうにしてる
Avatar
あー、でも多分それだけじゃないですよね。この用例だとエラーの暗黙的変換が入ってますが、それ込みで欲しいという、とか思ってたらそれだけだった
Avatar
今だとfromは1個しか作れないから、後のすべてはクロージャを引数にとって誤魔化すしかない
7:25 AM
これが厳しい
Avatar
あー、擬似コード書いてやっとわかりました
7:27 AM
1 つの From protocol に対して associatedtype が 1 つしかないから、1 つの from しか作れないということですね
Avatar
型推論でオートマチックに通るのが1個まで、ですね
7:28 AM
後は制約しないものをオーバーロードしてmap(Foo.from)みたいにすればまあいけるっちゃいけるだが… (edited)
Avatar
あれ、勘違いしてました、もう一回擬似コード中。。。
Avatar
omochimetaru 8/3/2018 7:30 AM
それだと手書きになるし、Fromそのものとして抽象化されないよね>オーバーロード
Avatar
そうなんだよー
7:31 AM
だからworkaround
Avatar
中身見てないけど名前からしてそう
Avatar
omochimetaru 8/3/2018 7:31 AM
ConstructibleFromValueだし、まさにそれ
Avatar
protocol ConstructibleFromValue<T> { init(_ value: T) }
Avatar
protocol From { associated Convertible static func from(_ x: Convertible) -> Self } protocol AConvertible {} struct A: From { typealias Convertible = AConvertible static func from(_ x: Convertible) -> A { // ... } }
7:32 AM
ここまで書きましたが、これは辛い
Avatar
これの話をしていて、型パラ違いで Conform する話をしている。
Avatar
そもそも typealias コンパイル通るのか…?
Avatar
分かりやすい話が
Avatar
型パラ違いで conform 欲しいですね
Avatar
StringはFrom<Int>とFrom<Float>として定義可能で、勿論From<String>でもある
Avatar
ですね
Avatar
そういう、Stringを生成できるもの、みたいなのを、ジェネリックに一気に定義できるっていうのがね
Avatar
omochimetaru 8/3/2018 7:33 AM
Conformanceを多相化できるんですね
Avatar
これあると CustomReflectable とか CustomStringConvertible とかいらなくなっていいですね (edited)
Avatar
omochimetaru 8/3/2018 7:33 AM
そうそう。
Avatar
まさにそこがすべて一本化される
Avatar
欲しい派の1人になりました ✋
Avatar
そしてそれらを統合した、上位のfuncを定義できるようになる、今は無理です
Avatar
いや、Rust さすが理想の言語。。。
Avatar
↑にはもし Sequence<Int>Sequence<Double> に conform したら、 for ループでどうなんの?みたいな話が書かれてる。
Avatar
forに入れたらambitiousコンパイルエラーでは
Avatar
for x: Int in xs { ... } で良さそうですけどね。
Avatar
明示すればok
Avatar
これできても一見そこまで問題発生しなさそうに思うけどそんなにまずいのかなぁ。 (edited)
Avatar
あ、HKT 入ってるのか… これ欲しいですね
Avatar
ジェネリックプロトコルというより、 associatedtype 違いの conform できたら他にどんな問題が起こるでしょうか?
Avatar
そっちは問題がありそう
7:38 AM
前の思考実験の時に、untagged unionとassoctype入れてどうなるか、で
7:39 AM
確か世界が崩壊した
Avatar
話の腰折って申し訳ないんですが、for の ambiguous の話ってどこらへんに書いてあります?
Avatar
何が起きたかはもう一回考え直すけど同じ問題がありそう
Avatar
More importantly, modeling Sequence with generic parameters rather than associated types is tantalizing but wrong: you don't want a type conforming to Sequence in multiple ways, or (among other things) your for..in loops stop working,
👀 1
7:39 AM
ですね。
Avatar
あー、理解しました。これは確かに問題になりますね
Avatar
でも Element の型指定すりゃいいだけな気もするんですよね。
7:42 AM
まあ、サブタイピング考えたらめちゃくちゃ複雑になるかな。
Avatar
omochimetaru 8/3/2018 7:42 AM
SequenceはGeneric protocolにしなくてよくないですか?
🦀 1
Avatar
いやー
Avatar
しかし、そうなると associatedtype と generic protocol の使い分けがむずくなってきますね
Avatar
StringでUTF8とUTF16とCharacteのSequenceでオーバーロード、欲しくないですか
7:43 AM
Viewごとの
Avatar
struct Cat: Animal<Foo>, Animal<Bar> だったとして、 FooBar が共通の親を持ってたりしたら複雑そう。
Avatar
現状Swiftはサブタイプ滅茶苦茶なので
Avatar
Optional とか絡むと大変
Avatar
assoctypeでオーバーロードはstrictな要求が必要 (edited)
Avatar
omochimetaru 8/3/2018 7:44 AM
使い分けが難しいのはそうですね
Avatar
StringでUTF8とUTF16とCharacteのSequenceでオーバーロード、欲しくないですか
これほしいですね。
Avatar
例によってSequence<Int??>, Sequence<Int?>でもう壊れそう
7:45 AM
崩壊が想像に難くない
Avatar
この Sequence 問題、Rust でも起こってそうですけどどうやって解決してるのでしょう
Avatar
rustはサブタイプが無い
7:47 AM
問題にならないと思う
Avatar
あー、subtype 問題ではなく Sequence<Int> と Sequence<Double> 問題の方でした
Avatar
そっちは明示すれば良いだけで、何も問題ないと思う
Avatar
omochimetaru 8/3/2018 7:48 AM
別に全てのassociated typeが多相化するわけじゃなくて
7:48 AM
そうしたいものだけがそうなるので
7:48 AM
パラメタライズされてないトレイトについては
7:49 AM
Swiftと同じですよ
Avatar
waiwai swiftc のために移動します。 (edited)
Avatar
omochimetaru 8/3/2018 7:51 AM
API documentation for the Rust IntoIterator trait in crate std.
7:51 AM
One benefit of implementing IntoIterator is that your type will work with Rust's for loop syntax.
7:52 AM
とあるので、これがSwiftのSequence相当かな
7:52 AM
pub trait IntoIterator where <Self::IntoIter as Iterator>::Item == Self::Item, { type Item; type IntoIter: Iterator; fn into_iter(self) -> Self::IntoIter; }
Avatar
associatedtype でも型パラでも書けるのか。
Avatar
なるほど、構文的には下のように別れてるんですね trait Example { type Associated; } trait Example<Generic> { }
Avatar
omochimetaru 8/3/2018 7:53 AM
From pub trait From<T> { fn from(T) -> Self; }
7:54 AM
型パラメータに置くのと、associatedtypeにするのと、意味が異なります
Avatar
ですね
7:54 AM
だとすると、下は結構興味深いですね: pub trait TryInto<T>: Sized { type Error; }
Avatar
omochimetaru 8/3/2018 7:55 AM
型パラとassocが一つずつあるのか、どういう意味だろ
Avatar
Errorは一種類しか定義できなくなる
Avatar
omochimetaru 8/3/2018 7:56 AM
pub trait TryInto<T> { type Error; fn try_into(self) -> Result<T, Self::Error>; }
Avatar
Tは多層化できる
7:56 AM
あー、Error はやはり 1 種類になりますか
7:57 AM
Generic<T> ごとに Error が 1:1 対応するのも考えられなくはないな、と思ったんですが、Generic と Error が 1:1 なんですね
Avatar
omochimetaru 8/3/2018 7:57 AM
ああ、これはInto<T>が失敗しうるからTryなのか
7:58 AM
たしかに変換先の型によらず、変換失敗エラーの型は一つっぽい
Avatar
これを見るとswiftのErrorはなるほど感が高くてすき
Avatar
omochimetaru 8/3/2018 7:59 AM
pub trait TryFrom<T>: Sized { /// The type returned in the event of a conversion error. type Error; /// Performs the conversion. fn try_from(value: T) -> Result<Self, Self::Error>; }
7:59 AM
こっちがFromとの対比でわかりやすいな
Avatar
ああ、そうですね。TryInto がたまたま近くにあったので例として出しました
8:00 AM
この From<T> の話もそうなんですが、さっきのエラーの暗黙変換も便利っちゃ便利そうですよね。闇の使い方も作ってしまうかもですが…
Avatar
エラーの暗黙変換に関しては最近はfailureを使うのがトレンドですね。本体に入れようとしてるみたいです。https://qiita.com/termoshtt/items/8c015d9289613ec640f1
合成したエラー型を使う --------------------- Rustには例外がない。 全ての失敗するかもしれない計算はOptionやResultを使って処理する。 ```rust use std::{fs, io}; fn...
🙏 1
Avatar
https://actix.rs タイムラインにこれ流れてきて気になってるけどrustガチ勢的にはどうなんでしょ
😃 2
Avatar
Rustやっていきたいと思っているのでガチ勢いたら助けてくださいって感じ
Avatar
omochimetaru 8/9/2018 1:44 AM
RustコミュニティのDiscordとかあるのかな?
Avatar
そもそも勢いあるコミュニティあるのかしら
1:46 AM
## ■イベント概要 Rust入門者のLT大会&懇親会です。 最近Rust始めた方、これからRustを深めていこうという方、ぜひ集まって「Rustのここがよかった」「ここが好きになった」「ここがひっかかりやすい」な...
1:46 AM
Slackコミュニティあります。 登録がまだの人は是非ご参加ください。 -> https://rust-jp.herokuapp.com/
1:47 AM
## 概要 Wantedlyが内部向けにやっている勉強会に5名様だけご招待。 Rustは「速度」「並行性」「安全性」の3本の矢を達成する新進気鋭のプログラミング言語です。 Rustの良さを語ろうとするとこの段落に収...
Avatar
omochimetaru 8/9/2018 1:47 AM
なんでslackなんだろ
😎 1
Avatar
discord移住してなければslackが良いというだけの話と
Avatar
まだディスコの心地よさに気づいてない人のほうがおおいでしょ
😔 1
Avatar
コミュニティ分断とかはまあありそう
Avatar
slackは課金するとなるとワークスペースの管理者が被るしか無い?んだよね?
1:50 AM
そこで初めてディスコ移住モチベーションになるきがする
Avatar
ここは過去ログ消滅しないから良いよね(パーマリンクはない)
Avatar
omochimetaru 8/9/2018 1:52 AM
https://feedback.discordapp.com/forums/326712-discord-dream-land/suggestions/17828437-msg-id-jump
Modelmat commented · June 11, 2018 15:35 · Flag as inappropriate
Hey technically this is possible: https://discordapp.com/channels/{guild_id}/{channel_id}?jump={message_id} but not through the client.
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.
Step up your game with a modern voice & text chat app. Crystal clear voice, multiple server and channel support, mobile apps, and more. Get your free server now!
1:53 AM
進展があった模様
Avatar
おや
1:54 AM
実は1発言へのリンクあるってことか
Avatar
内部的にあることは明確で、なぜならjump機能があるから
Avatar
omochimetaru 8/9/2018 1:54 AM
なるほど
Avatar
それを俺達に開示してくれ!というのが主だった要求
Avatar
容量の問題でSlackからZulipへ移行しようとしてます。discordのもあるんですがそちらはあまり活発ではないですね。
👀 1
3:16 AM
handle とスコープについて↓に書いてそう。 https://go.googlesource.com/proposal/+/master/design/go2draft-error-handling.md#handlers
Avatar
無名スコープもできるっぽい package main import ( "fmt" ) func main() { a := 2 { a := 3 fmt.Println(a) } fmt.Println(a) }
3:24 AM
3 2
3:24 AM
この handlecheck かなり良いのでは?
Avatar
omochimetaru 8/29/2018 3:25 AM
おお
Avatar
@omochimetaru
deferがあるなら、という理由で理に適ってるという理屈はよくわからないです 特に、catchスコープの後ろに文が書けるけど、handleだとそれができなそう。
catch スコープの後ろに文が書けるのを無名スコープで再現できるなら、 handledefer 同様にネストを防げるのが良いところになるかな? defer にできるけど finally にできないことって他にあるっけ?
(edited)
Avatar
Generics も読んでた。 contract で Swift のプロトコルみたいなことできそうでいい感じ。
Avatar
omochimetaru 8/29/2018 3:48 AM
contractは型パラメータ取れますか?
3:48 AM
一足とびにSwiftの機能を超える可能性・・・
Avatar
contract Equal(t T) { t == t }
3:49 AM
型パラメータは associatedtype じゃなくてジェネリクスの型パラメータ?
3:50 AM
まだよくわかってないけど contract を型として使うことはできないんじゃない?
Avatar
omochimetaru 8/29/2018 3:51 AM
contract convertible(_ To, f From) { To(f) } func FormatUnsigned(type T convertible(uint64, T))(v T) string { return strconv.FormatUint(uint64(v), 10) }
3:51 AM
これ、Generic Trait 相当じゃないですか?
3:52 AM
あ〜わかってきたかも
3:52 AM
Goのcontractは型パラメータに対する追加的な制約だけど
3:52 AM
あくまで型パラメータに対するものであって
3:52 AM
ある具象型がcontractを満たすかどうかを自身で宣言するわけではないのかも
Avatar
うん、それはそうだと思うよ。
3:53 AM
たしか Go は元々そういうスタイルだった気が。
Avatar
omochimetaru 8/29/2018 3:53 AM
そして、それが満たされるかどうかは、Go言語のダックタイピングっぽい型チェックで、そのメソッドがあるかどうかで判断される。
Avatar
Go の interface もそうじゃないっけ?
3:53 AM
なので、 Swift の protocol とダックタイピングのあいのこみたいなのになりそう。
Avatar
omochimetaru 8/29/2018 3:54 AM
Rustだとある(ジェネリックかもしれない)traitを満たすのは、impl文で明示的にコンフォーマンスを取るけど
3:54 AM
Goのやつはcontract文としてそれが通るか?みたいなチェックをするっぽい
3:55 AM
型クラス相当の事はできるのかなあ contractの引数に対して更にcontract制約をかけられないとダメな気がする?
3:56 AM
よくわからないけどこれまでの言語のどれとも違う仕様っぽくて興味深いですね (edited)
Avatar
おもしろそう
Avatar
omochimetaru 8/29/2018 3:57 AM
少なくともconvertible contractのサンプルとかはSwiftより表現力がありそう
3:59 AM
Go言語のこれまでの「簡単」志向とは
3:59 AM
真っ向から矛盾しそうだけどその辺どうなっていくんだ・・・
Avatar
convertible は多重に満たせるから Swift の protocol より強力なのか。
Avatar
omochimetaru 8/29/2018 4:03 AM
2つのジェネリックな値を持ってその関係を規定できるから generic protocol のように機能しますね
4:03 AM
構文のスタイルとしてはRustやSwiftより Haskell の type class に近い気がします
4:04 AM
SwiftのprotocolやRustのtraitは雰囲気をクラス指向に寄せてとっつきやすくしたと思うけど
4:04 AM
Goのcontractはそういう意味では難しいHaskellに戻ってる雰囲気がする。
Avatar
Functor 書けないかと思ったけどわからん・・・。
Avatar
omochimetaru 8/29/2018 4:11 AM
contractにわたすところがその式をまるまる渡すことしかできなくて、型パラメータを分離して受け取れないから、できない気がしてきた。
Avatar
higher kindedは無理そうに見える
Avatar
handle とスコープについては、 Go の defer はスコープ関係なく関数単位だったはずだから、 handle はどうなんだろう?とさっきから思ってる。
https://go.googlesource.com/proposal/+/master/design/go2draft-error-handling.mdEach check may have a different handler chain function depending on the scope in which it is defined. For example, consider this function: がまさにそこに言及していそう func process(user string, files chan string) (n int, err error) { handle err { return 0, fmt.Errorf("process: %v", err) } // handler A for i := 0; i < 3; i++ { handle err { err = fmt.Errorf("attempt %d: %v", i, err) } // handler B handle err { err = moreWrapping(err) } // handler C check do(something()) // check 1: handler chain C, B, A } check do(somethingElse()) // check 2: handler chain A }
(edited)
5:42 AM
Check 1, inside the loop, runs handlers C, B, and A, in that order. Note that because handle is lexically scoped, the handlers defined in the loop body do not accumulate on each new iteration, in contrast to defer.
Avatar
omochimetaru 8/29/2018 7:30 AM
the handlers defined in the loop body do not accumulate on each new iteration
7:30 AM
accumulate on each new iterationってどういういみでしょ?
7:31 AM
deferの場合はforの終わりに3回deferが実行されて、 handleの場合はループごとに1回?
Avatar
ループしてもスコープ抜けたら無効ってことじゃない?
7:32 AM
defer だとループした回数だけ実行?
7:34 AM
package main import ( "fmt" ) func main() { for i := 0; i < 3; i++ { defer fmt.Println(i) } fmt.Println("end") } end 2 1 0
7:34 AM
スコープを抜けても実行されなくて、関数を抜けるときにそれまでのループで accumulate された defer が実行される。
7:35 AM
でも、 handle ではエラーが発生したときに、スコープ抜けた分は実行されないということかと。
Avatar
omochimetaru 8/29/2018 7:35 AM
func main() { for i := 0; i < 3; i++ { fmt.Println("a") defer fmt.Println(i) fmt.Println("b") } fmt.Println("end") }
7:36 AM
a b a b a b end 2 1 0
7:36 AM
deferはfuncにどんどん貯め込むのか
7:36 AM
for i in 0..<3 { print("loop \(i) begin") defer { print("defer \(i)") } print("loop \(i) end") }
7:36 AM
loop 0 begin loop 0 end defer 0 loop 1 begin loop 1 end defer 1 loop 2 begin loop 2 end defer 2
7:36 AM
Swiftのdeferと全然違うんですね
Avatar
そこが Swift と Go の defer の違いで、 Swift の方がいいと思ってたけど、この前見た例で Go の defer じゃないとできないのがあったんだよなぁ。何だったかなぁ・・・。
Avatar
omochimetaru 8/29/2018 7:37 AM
ネストせずにオブジェクトをどんどん確保していく(ファイルを3つオープンするとか
7:37 AM
あ、でもそれもいけるか、swiftで
7:37 AM
まあなるほど、このdeferの挙動が、accumulate on each new iterationで、
7:38 AM
handleはそうじゃないよってことですね。
Avatar
↑の defer の挙動の違いは Error Handling Rationale and Proposal に書かれてる。 Swift は意図的にスコープ単位に改変して導入した。 Overall, I think it is better to use a Go-style defer than a Java-style try ... finally. ... Unlike Go, I think this should be tied to scope-exit, not to function-exit. https://github.com/apple/swift/blob/master/docs/ErrorHandlingRationale.rst#clean-up-actions-1
The Swift Programming Language. Contribute to apple/swift development by creating an account on GitHub.
Avatar
omochimetaru 8/29/2018 7:39 AM
お〜言及されていた
Avatar
↓これ辛くないのかな? In some languages this would trigger a null pointer exception, but in Go it is common to write methods that gracefully handle being called with a nil receiver https://tour.golang.org/methods/12
Avatar
ポインタに対するメソッドが Swift の mutating func に、引数をポインタで受けるのが inout 引数に対応していておもしろい。 https://tour.golang.org/methods/4
Avatar
omochimetaru 9/6/2018 2:11 AM
これだと
2:12 AM
構造体のサイズがでかい場合に、 nonmutatingなメソッドであっても、
2:12 AM
必ず値渡しになりそう
Avatar
なので、実際にはポインタ渡しを使うことが多いみたい
2:12 AM
↓おもしろい挙動だ。 package main import "fmt" type I interface { M() } type T struct { S string } func (t *T) M() { if t == nil { fmt.Println("<nil>") return } fmt.Println(t.S) } func main() { var i I var t *T = nil i = t i.M() // OK i = nil i.M() // panic }
Avatar
omochimetaru 9/6/2018 2:12 AM
値渡しの勝手な間接化は許されているのか。
Avatar
nil の挙動が *T 経由のときと直接 Inil を代入したときで異なってる。 (edited)
2:14 AM
他の言語の感覚だとハマりそう。
Avatar
omochimetaru 9/6/2018 2:17 AM
Interface自体がnilの場合と、その型のnil値をinterfaceに入れている場合が区別されている?
Avatar
うん
Avatar
omochimetaru 9/6/2018 2:18 AM
Optional<Optional<T>> みたいになっていて、 Optional<Optional<T>> も Opitonal<T> も T も全部 <receiver>.<method of T> の式が書けて
2:18 AM
3つのケースで挙動が全部違う?
2:18 AM
クソ難しいな。
2:18 AM
触りたくなくなった
Avatar
↓の話、最初気持ち悪いなぁと思ったけど、 Swift の mutating funcinout-> じゃなくて . だし、そういう風にとらえると納得できそうな気持ちになってきた。 package main import "fmt" type Foo struct{ a int } func main() { f := Foo{a: 42} p := &f pp := &p fmt.Println(f.a) fmt.Println(p.a) // OK fmt.Println(pp.a) // NG }
2:20 AM
Go のポインタはポインタ演算はできないから、実質的に取り回せる inout みたいなものかと。
2:20 AM
Swift はダブル inout はできないけど。
Avatar
omochimetaru 9/6/2018 2:21 AM
func (t *T) M() これが関数っぽく見えるけどメソッドだと思えばSwiftも似てるか。
Avatar
それは普通にメソッドなのでは? Go のメソッド宣言の方法。
2:23 AM
ポインタに対してメソッドを記述してるんじゃなくて、 T に対して mutating func を書いてるととらえたら . でコールできるのも自然に思える。
Avatar
omochimetaru 9/6/2018 2:23 AM
文法の見た目の問題で、関数っぽいものをメソッドとして扱ってる世界に見える。
2:23 AM
pythonみたいな。
2:23 AM
レシーバを陽に書かれると。
Avatar
まあそうだけど、 Swift の値型のメソッドも暗黙的に self 引数があるだけの関数だし。
2:25 AM
さっきの *Tnil を代入するかで挙動が変わる件、インタフェースは (value, type) のタプルのようなものと説明されていて、 *T を代入した場合は (nil, *T) になるけど、 inil を直接代入すると nil になるんだと思う。
2:28 AM
type はエイリアスではなくて別の型が作られるみたいなんだけど、 package main import "fmt" type Double float64 func main() { var a float64 = 42.0 var b Double = Double(a) // 明示的な変換が必要 fmt.Println(b) }
2:28 AM
↓ができるのがなんでかよくわかってない。 package main import "fmt" type Any interface{} func main() { var a interface{} = 42 var b Any = a // OK fmt.Println(b) } (edited)
Avatar
omochimetaru 9/6/2018 2:30 AM
interface型同士はそれができるんじゃないですか?
Avatar
そうかも
2:32 AM
そうか、インタフェースを満たすかは暗黙的に解決されるからか。
Avatar
omochimetaru 9/6/2018 2:32 AM
同じtype文で構築してても、それがコンクリートな型なのか、interface型なのかは、
2:32 AM
型システム上?おおきな違いがありそうですね (edited)
Avatar
できた。 package main import "fmt" type Foo interface{ A()int } type Bar Foo type ConcreteFoo struct{} func (t ConcreteFoo) A()int { return 42 } func main() { var a Foo = ConcreteFoo{} var b Bar = a fmt.Println(b.A()) }
2:36 AM
インタフェースを満たすかどうかはダックタイピング的に暗黙的に解決されるから、 interface 同士は互換性さえあれば OK なんだ。
2:36 AM
なので、 type InterfaceA InterfaceB はタイプエイリアスのように働く。
2:39 AM
--- メソッドが同一パッケージ内の型に対してしか生やせないので func (i int) Double()int { return i * 2 } みたいに標準ライブラリの型に extension 的にメソッド生やせないの辛そう。 (edited)
Avatar
omochimetaru 9/6/2018 2:40 AM
↑を書くとどうなるんですか?
Avatar
コンパイルエラー
Avatar
omochimetaru 9/6/2018 2:40 AM
え〜〜
Avatar
↓で遊べて楽しい。 Swift もこういうの公式でほしい。 https://play.golang.org/
Avatar
omochimetaru 9/6/2018 2:41 AM
prog.go:7:6: cannot define new methods on non-local type int
2:41 AM
へえ
Avatar
↓ならできる package main import "fmt" type Int int func (i Int) Double()Int { return i * 2 } func main() { var x Int = 42 fmt.Println(x.Double()) }
2:42 AM
自分で宣言した Int に対して * が使えたり 42 というリテラルが代入できたりする仕組みはまだわかってない。
Avatar
Kishikawa Katsumi 9/6/2018 2:51 AM
package main import "fmt" type path string func Save(p path) string { return "Saved" } func main() { var p path p = "/tmp/xxx" fmt.Println(Save(p)) // OK s := "/tmp/xxx" fmt.Println(Save(s)) // Compile Error fmt.Println(Save("/tmp/xxx")) // OK } GoのtypeはSwiftと若干違うなと思ったことがあって、Goは2つ目のコードをコンパイルエラーにしてくれて、「おっ」と思ったけどリテラルを渡すことは防止できなかった。
2:51 AM
@swiftbot import Foundation typealias Path = String func save(path: Path) -> String { return "Saved" } var p: Path = "/tmp/xxx" print(save(path: p)) var s: String = "/tmp/xxx" print(save(path: s)) print(save(path: "/tmp/xxx")) Swiftは全部通るはず。
🛠 1
Avatar
swiftbot BOT 9/6/2018 2:51 AM
Author icon
kishikawakatsumi
import Foundation typealias Path = String func save(path: Path) -> String { return "Saved" } var p: Path = "/tmp/xxx" print(save(path: p)) var s: String = "/tmp/xxx" print(save(path: s)) print(save(path: "/tmp/xxx"))
Version:
swift-4.1.1-RELEASE
Output:
Saved Saved Saved
Error:
Avatar
omochimetaru 9/6/2018 2:52 AM
リテラルから一気にPath型になるのか・・・
Avatar
Kishikawa Katsumi 9/6/2018 2:52 AM
3番目をエラーにできたら一気にtype便利ってなるんですけどね。
Avatar
omochimetaru 9/6/2018 2:53 AM
SwiftでいうとStringLiteralConvertibleが、type をStringから作ってる時点で自動実装されてしまうという感じですかね
Avatar
まあでもリテラルから作れるのは便利ですけどね。逆にそれがないと ExpressibleByStringLiteral 相当のことができなさそうですし。
Avatar
omochimetaru 9/6/2018 2:53 AM
そうですね、それが禁止されてたら、種類を分けるだけの型として楽で便利そう
Avatar
Kishikawa Katsumi 9/6/2018 2:54 AM
Swiftの挙動はまあこっちを選択したんだろうなということでわかる。 Goの挙動は現実的にちょっと中途半端かなって。
Avatar
確かによくわからない挙動ではありますね。ただ、まだ Go のことをよくわかってないからルールが見えてなくてよくわからないように感じている気もします。
Avatar
Kishikawa Katsumi 9/6/2018 2:56 AM
そうなんですよね。
Avatar
もしかしてと思って逆方向試してみたんですけど、こっちも明示的変換が必要でした。 package main import "fmt" type Int int func main() { var x Int = 42 var y int = int(x) fmt.Println(y) }
Avatar
リテラルについては、↓も可能なので、値とは別のより柔軟なルールがあるんだと推測してます。 package main import ( "fmt" ) func main() { var a int = 42 // var b float64 = a // NG var b float64 = float64(a) // 明示的変換が必要 var c float64 = 42 // OK fmt.Println(b) fmt.Println(c) }
3:08 AM
Swift の ExpressibleByXxx 相当のことが暗黙的に適用されるルールがありそう。
Avatar
↓で三つとも同じ値が出力されるんだけど、 Go ってどこでスタックからヒープに持っていって GC の管理対象にするんだろう? package main import ( "fmt" ) type Foo struct{ A *int } func foo(a int) Foo { p := &a fmt.Println(p) f := Foo{A: p} fmt.Println(f.A) return f } func main() { f := foo(42) fmt.Println(f.A) }
Avatar
omochimetaru 9/6/2018 3:22 AM
return f → Foo (p) → p := &a で、p のエスケープがわかるので
3:22 AM
p := &a のところで、ヒープ上にコピーを作ってるんじゃないですか?
Avatar
main 側からみてもアドレスが変わらないのはなぜ? (edited)
3:34 AM
ああ
3:35 AM
コンパイラが構文解析か意味解析かなんかで &a をヒープにコピーするように判断してるってことか。
Avatar
omochimetaru 9/6/2018 3:35 AM
うん。aのアドレスを取ってるんじゃなくて、aのコピーをヒープ上にまず作ってそう。
Avatar
ローカルでのみ使われることがわかっている場合は単にアドレスを取る?
Avatar
omochimetaru 9/6/2018 3:38 AM
はい
3:38 AM
そうだったらいいな
Avatar
package main import ( "fmt" ) type Foo struct{ A1 *int A2 *int A3 int A4 int } func foo(a int) Foo { p1 := &a p2 := &a p3 := &a p4 := &a fmt.Println(p1) fmt.Println(p2) fmt.Println(p3) fmt.Println(p4) f := Foo{ A1: p1, A2: p2, A3: *p3, A4: *p4, } fmt.Println(f.A1) fmt.Println(f.A2) return f } func main() { f := foo(42) fmt.Println(f.A1) fmt.Println(f.A2) }
3:39 AM
0x10414020 0x10414020 0x10414020 0x10414020 0x10414020 0x10414020 0x10414020 0x10414020
3:40 AM
一つでもヒープに作られたら、 & で同じところを見るようになるのかな。ってか当たり前か。
3:40 AM
そうしないと元の値変更したときに参照できないか。
Avatar
omochimetaru 9/6/2018 3:40 AM
fooの先頭でaをヒープ上のコピーでshadowする。
Avatar
とすると、 & の時点じゃなくて a が渡された時点でヒープに確保してる?
Avatar
omochimetaru 9/6/2018 3:41 AM
ああ、まあそうでしょうね
3:41 AM
&の時点というか、それはエスケープ解析で
3:41 AM
関数のコンパイル時にまずやりそう
Avatar
そうすると、この関数の中では単に a にアクセスしても全部デリファレンスが走ってたりするのかな? (edited)
Avatar
omochimetaru 9/6/2018 3:41 AM
それはまた微妙で
3:42 AM
aに対する書き込みがなければ
Avatar
それはそうだね。書き込みがある場合。
Avatar
omochimetaru 9/6/2018 3:42 AM
レジスタからメモリへの書き戻しを削除して
3:42 AM
レジスタ上での操作に最適化できると思います
3:42 AM
Goコンパイラのスタイルは知らないですけど、 Swiftコンパイラだったら、そういうのは、
3:42 AM
基本的にまず保守的なコードを生成してから
3:43 AM
最適化で良いコードに変換していく
3:43 AM
最初の保守的な版は、常にポインタデリファレンス+メモリアクセスでしょうね
Avatar
なるほどー
Avatar
omochimetaru 9/6/2018 3:45 AM
例えばさっきのaのヒープエスケープが仮にそう動いてるとして、
Avatar
Go はセルフホスティングらしいから、 Go が読めればコンパイラ読んでその辺りも読めるのかな。 https://qiita.com/sonatard/items/815ba89e472047e38ca5

はじめに

Goは、Go1.5以降C言語による実装がなくなり、ほぼ全てがGoによって書かれています。そのためGoエンジニアは最悪Goのソースコードを読んで問題を解決することができるため、とても生産的な状態...
💡 2
Avatar
omochimetaru 9/6/2018 3:45 AM
とりあえずヒープエスケープするようにしておいてから、 って作り方もあるかと。
3:46 AM
読めば書いてあると思います
Avatar
https://t.co/pOx5BSA0n9 Rustのasync/await構文に関する議論は主に、前置awaitのほうが標準的でわかりやすい一方後置awaitのほうが(おそらく)使いやすいというジレンマに悩まされてきたが、コアチームは後置awaitの...
Avatar
awaitの戻り値をさらにメソッドチェーンしてそれをawaitしたいときに、後置の方が便利だと思いますね。
Avatar
omochimetaru 5/8/2019 4:27 AM
そこはSwiftの場合はまとめて書けそう await downloadImage(url).convert
Avatar
あ、そうなんですね。それは便利。
Avatar
omochimetaru 5/8/2019 5:30 AM
throwsに対するtryが1つにまとめられるのと同じノリで。
Avatar
まとめられるはずですね。ただ、僕は tryawait もひとつずつ書くのも嫌いじゃありません。
5:58 AM
あ、チェーンは微妙ですね。↓みたいな場合の話でした。 let a = try foo(try bar()) (edited)
Avatar
Josue Hernandez 7/3/2019 5:36 AM
swift
Avatar
#swift-2 から。 参照した先にポインタのペアがある(実装もある)?
In some of Oracle’s implementations of the Java Virtual Machine, a reference to a class instance is a pointer to a handle that is itself a pair of pointers: one to a table containing the methods of the object and a pointer to the Class object that represents the type of the object, and the other to the memory allocated from the heap for the object data.
https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-2.html#jvms-2.7
(edited)
Avatar
C 製のライブラリをプロジェクトに入れて使うケースで、 int 型を Swift で Int32 型にキャストするのは面倒なので、コンパイル時に int を 64 ビット扱いできたらいいなと思うのですが、そういうことって可能なのでしょうか?
Avatar
omochimetaru 8/22/2019 1:35 AM
もしかしたら指定できるのかもしれませんが普通はできない/やらないはずです、int型のビット幅は、標準ライブラリ関数のmemcpyとかstrlenとかに依存するかつ、それらはすでにビルド済みなので (edited)
1:35 AM
手元のコードだけコンパイルするときにそれを変更してもいろいろぶっ壊れちゃいます
1:35 AM
intのサイズは基本的にはターゲットOSとCPUに対して決定します
1:36 AM
C言語でビット幅を制御したいときは、最初から int32_t型やint64_t型を使うほうがよろしいです
1:37 AM
ちなみにですが、C言語のint型はSwiftから見るとSwift.CInt型です、そして、CInt型がInt32型へのtypealiasになっています。 これはターゲット環境によってalias先が変化します。
1:37 AM
てかmac環境だとintは64bitだと思います。 (MacはLP64だからintは32か) (edited)
Avatar
うーむ、なるほど。既存のを丸っと持ってきた形なんですが、Swift 側で Int32 キャストするか C の方を int64_t に全部書き換えるかですかねぇ。
1:38 AM
てかmac環境だとintは64bitだと思います。
あれれ
(edited)
Avatar
omochimetaru 8/22/2019 1:39 AM
CブリッジのところならCIntにキャストするほうがコードの意図が表現できて良いと思います
Avatar
spasm_triplet *spasm_triplet_alloc(int n, int m, int nzmax, int prime, int with_values) { これを let (n, m): (Int, Int) = size let nnz: Int = components.count let Atrip = spasm_triplet_alloc(n, m, nnz, 2, 1) // Cannot convert value of type 'Int' to expected argument type 'Int32' とエラーが出ているので、 C の intInt32 になってるのかと思いました。 (edited)
Avatar
Kishikawa Katsumi 8/22/2019 1:40 AM
とりあえず面倒を回避して動けばいいのであれば #define int int64_t とか書いたのを足したらいいんじゃないですか。
😱 2
Avatar
さすがにそれだと色々壊れそうなのでビビりました😅
Avatar
omochimetaru 8/22/2019 1:42 AM
let (n, m): (Int, Int) = size let nnz: Int = components.count let Atrip = spasm_triplet_alloc(CInt(n), CInt(m), CInt(nnz), 2, 1) 僕ならこうしますね
1:42 AM
こう書いておくとintが64bitの環境でも動く。
Avatar
なるほどなるほど。
Avatar
omochimetaru 8/22/2019 1:47 AM
今ちょっと調べたけど Intが64bitになる ILP64アーキテクチャのOSはほぼ無いですねw
😬 1
Avatar
Taketo Sano 9/4/2019 1:51 PM
C と Swift の連携で、Ubuntu でのみ再現するかなり嫌な感じのバグに苦しんでいます…😖 func rank() -> Int { let cA: UnsafeMutablePointer<spasm> = spasm_init(A) defer { spasm_csr_free(cA) } let rank = spasm_rank_hybrid(cA) return Int(rank) } spasm_ とついてるのが C のライブラリです。これを Ubuntu で実行すると spasm_csr_free(cA) の中で Segmentation Fault が発生します。 spasm_csr_free の中でポインタのアドレスを出力してみると、spasm_init で返されるポインタのアドレスから微妙に変わっています。であれば spasm_rank_hybrid の中で何者かがアドレスを書き換えてるのだろうと思いきや、この関数の return の直前でアドレスを出力してみても init で返されるものと同じになっているのです… C と Swift の連携によってアドレスが書き換わってるとしか思えない感じです…😖 しかも不気味なことに func rank() -> Int { let cA: UnsafeMutablePointer<spasm> = spasm_init(A) print(cA) // ← これを入れるだけ defer { spasm_csr_free(cA) } let rank = spasm_rank_hybrid(cA) return Int(rank) } こうすると Seg-Fault が発生しなくなります…😖 (edited)
1:55 PM
defer が悪さをしてるのかと思って func rank() -> Int { let cA: UnsafeMutablePointer<spasm> = spasm_init(A) let rank = spasm_rank_hybrid(cA) spasm_csr_free(cA) return Int(rank) } としてみましたが同じでした😣
1:59 PM
spasm_init: 0x7f3051b1c8f0 start of spasm_rank_hybrid: 0x7f3051b1c8f0 end of spasm_rank_hybrid: 0x7f3051b1c8f0 spasm_csr_free: 0x7f3051b1c800 こういう感じで、アドレスが f0 分ズレるという…
2:01 PM
Optional の分ズレてるとかかなぁ🙄
2:04 PM
f0 ズレるんじゃなくて & 00 されるようです😣
Avatar
omochimetaru 9/4/2019 2:04 PM
アライメントが関係ありそう・・・
2:04 PM
そのC関数のシグネチャはどうなってますか
Avatar
Taketo Sano 9/4/2019 2:07 PM
private func spasm_init(_ A: DMatrix<LinearSolver.R>) -> UnsafeMutablePointer<spasm> // `spasm_init` は Swift 製のラッパー関数で、その中で ↓ `spasm_compress` を呼んで返しています func spasm_compress(_ T: UnsafePointer<spasm_triplet>!) -> UnsafeMutablePointer<spasm>! func spasm_rank_hybrid(_ A: UnsafeMutablePointer<spasm>!, _ sparsity_threshold: Double) -> Int32 func spasm_csr_free(_ A: UnsafeMutablePointer<spasm>!) (edited)
2:09 PM
呼び出し元で型を UnsafeMutablePointer<spasm>! にしてみましたが,やはりダメでした orz
Avatar
omochimetaru 9/4/2019 2:09 PM
spasmはSwiftからどう見えてますか?
Avatar
Taketo Sano 9/4/2019 2:10 PM
それはどうやったら確認できますか? alt+click しても struct spasm としか出てきません.C の実装は ↓ です typedef struct { /* matrix in compressed-sparse row format */ int nzmax; /* maximum number of entries */ int n; /* number of rows */ int m; /* number of columns */ int *p; /* row pointers (size n+1) */ int *j; /* column indices, size nzmax */ spasm_GFp *x; /* numerical values, size nzmax (optional) */ int prime; } spasm;
Avatar
omochimetaru 9/4/2019 2:11 PM
Cmd+Ctrl+Clickかな?
2:11 PM
うーん、コンパイラのバグっぽく見える 手元でコード生成してみないと断定できませんが
2:12 PM
macだと生じないんですよね?
Avatar
Taketo Sano 9/4/2019 2:12 PM
C の実装に飛んでしまいますね… 同じパッケージに入れてるので
2:12 PM
そうなんです…
Avatar
omochimetaru 9/4/2019 2:12 PM
とりあえず、いったん回避して作業を続けるなら
2:13 PM
ポインタの代わりにintptr_tで受け渡しすると動くと思います https://cpprefjp.github.io/reference/cstdint/intptr_t.html
ポインタサイズの符号付き整数型。
2:15 PM
それにしても不思議だなあ
Avatar
Taketo Sano 9/4/2019 2:15 PM
すみません,どういう風に書けばいいのか分かりません 🙇 (edited)
2:15 PM
Swift の方で intptr_t にする感じですか?
Avatar
omochimetaru 9/4/2019 2:15 PM
C言語側で
2:16 PM
intptr_t spasm_compress_workaround(...) { return spasm_compress(...); } void spasm_csr_free_workaround(intptr_t pointer) { spasm_csr_free((spasm *)pointer); }
2:17 PM
こんなかんじにして、Swiftからはそっちをつかう。
2:17 PM
spasm_initのSwiftコードが見たいです。 (edited)
Avatar
Taketo Sano 9/4/2019 2:20 PM
private func spasm_init(_ A: DMatrix<R>) -> UnsafeMutablePointer<spasm> { let nnz = A.components.count let Atrip = spasm_triplet_alloc(CInt(A.size.1), CInt(A.size.0), CInt(nnz), CInt(p.intValue), 1) // note: transposed for c in A.components { spasm_add_entry(Atrip, CInt(c.col), CInt(c.row), CInt(c.value.representative)) // note: transposed } let ptr = spasm_compress(Atrip)! spasm_triplet_free(Atrip) return ptr } こちらです。行列の要素をセットして CSR 形式に圧縮しています。 (edited)
Avatar
omochimetaru 9/4/2019 2:20 PM
spasm_compressの返り値のポインタを再returnしてるので問題ないですね
Avatar
Taketo Sano 9/4/2019 2:21 PM
DMatrix<R> が自作の行列型です。
Avatar
omochimetaru 9/4/2019 2:21 PM
コードは問題なさそう
Avatar
Taketo Sano 9/4/2019 2:21 PM
ひょぇ〜😱
2:21 PM
このレベルのバグがどこで起きるか分からないとなるともはや安心して使えないですね…
Avatar
omochimetaru 9/4/2019 2:22 PM
ちょっとやばいですね
2:22 PM
今まで見つかってないのも謎。
2:25 PM
Linux+Cブリッジはサーバサイドとかでも結構使われてるはずなので
Avatar
Taketo Sano 9/4/2019 2:26 PM
ぬぅ
Avatar
omochimetaru 9/4/2019 2:26 PM
この関数の return の直前でアドレスを出力してみても
アドレスを出力するコードをみたいです
2:26 PM
なんかヒープアドレスじゃなくてスタックアドレスに見える。。
Avatar
Taketo Sano 9/4/2019 2:26 PM
printf("%p", A); こういうやつです. (edited)
2:27 PM
spasm_rank_hybrid の始まりと return の直前にこれを入れてます。
Avatar
omochimetaru 9/4/2019 2:30 PM
なるほど。
2:32 PM
spasm_csr_freeをラップしたSwiftの関数を用意したら直ります?
Avatar
Taketo Sano 9/4/2019 2:32 PM
やってみましょう…
Avatar
omochimetaru 9/4/2019 2:32 PM
func spasm_csr_free_swift(ptr: UnsafePointer<spasm>) { spasm_csr_free(ptr) }
Avatar
Taketo Sano 9/4/2019 2:35 PM
おっ,ありがとうございます,ほぼ同じコードを書いてましたw
Avatar
omochimetaru 9/4/2019 2:36 PM
時間のあるときにLinuxで見てみようと思うので、最小再現セットがもらえると助かります
Avatar
Taketo Sano 9/4/2019 2:37 PM
直らないですねぇ…しかもそこに print(ptr) を入れると直りますw
2:37 PM
気持ち悪すぎる😱
2:38 PM
optimization が何か悪さしてるのかなぁ
Avatar
omochimetaru 9/4/2019 2:38 PM
他の関数呼び出しの影響を受けているのでその可能性が高いですね
2:40 PM
Cのヘッダーと少しのSwift側のコードがあれば再現できそうな気がする
2:40 PM
SwiftPMだと中間コードを吐いたりできないのでそこから一手間ですが
Avatar
Taketo Sano 9/4/2019 2:41 PM
Cの関数呼び出して戻ってくるだけだと起きないっぽくて、中で色々複雑なことしてるのが影響してるようです…
2:42 PM
それゆえに最小再現セットを作るのが難しい…
Avatar
omochimetaru 9/4/2019 2:42 PM
Cの関数の中身が影響するのが変なんですよねえ。
2:43 PM
あとはspasm型の定義ぐらいですね
2:43 PM
Swiftから見えてるはずなのは。
Avatar
Taketo Sano 9/4/2019 2:44 PM
参っちゃいますね
Avatar
omochimetaru 9/4/2019 2:45 PM
そうですねえ
Avatar
Taketo Sano 9/4/2019 2:52 PM
Swift 5.1 beta 使ってるんで,試しに 5.0 に戻してみます。
Avatar
Taketo Sano 9/4/2019 3:02 PM
(まず 9/2 に出たばかりの最新版でやってみましたがダメでした)
Avatar
omochimetaru 9/4/2019 3:09 PM
コードの共有に問題がなければ最小化もこちらでやってみますよ
Avatar
Taketo Sano 9/4/2019 3:10 PM
Swift 5.0 でもダメでした。設定なども細々とあるので DM でお送りします 📧 l (edited)
Avatar
fprintf 形式で FILE * を引数にとる C のライブラリに Swift から text input stream 的なものを渡して文字を読み取りたいんですが,よく知られたやり方とかってあったりしますか…?
8:31 AM
MIRROR: M4RI is a library for fast arithmetic with dense matrices over GF(2) - malb/m4ri
8:33 AM
NSFileHandleなら man 2 open 互換なFile Descriptorを触れますが・・・
Avatar
むむ
Avatar
FILE* の方は無いかも・・・?
8:36 AM
FILE* から fd は取れるんですけど (man 3 fileno )
8:36 AM
fdから FILE* は取れない (ライブラリとしての抽象度が高い)
Avatar
むぅ
Avatar
普通にSwiftから fopen 呼ぶのはどうですか?
Avatar
あ,なるほど
8:41 AM
この関数を使おうと思ったら,C でファイルに書き込んでから Swift でそれを読むって感じにするしかないですよね?
8:43 AM
fmemopen なんてものがあるのか
Avatar
ああ、そういう事がしたいんですか
9:15 AM
FILE* はファイルの抽象だけど、たしかにfmemopenでいけそう
Avatar
Kishikawa Katsumi 2/14/2020 4:23 PM
https://twitter.com/kotlin/status/1227993505332682753 これ意外だった。Swiftとは微妙に違うところだな。
Did you know? Properties declared as 'val' can be overridden as 'var', and property setters can be made less visible than their getters #KotlinTips https://t.co/Ba1LxBF4dI https://t.co/U4Dpqo1Mlz
Retweets
162
Likes
599
Avatar
omochimetaru 2/15/2020 6:01 AM
class Read { var value: String { get { _value } } var _value: String = "" } class WriteRead: Read { private(set) override var value: String { get { super._value } set { super._value = newValue } } }
6:02 AM
Swiftだとこうなりますね。 Kotlinにおけるval はSwiftでいうと let というより get only var に似てる。 親クラスの実フィールドがprivateなときは同じようにはできない。 (edited)
Avatar
TypeScript で async function の戻り値の型が Promise でないといけないのって冗長じゃない?見た目上は(普通は)非 Promise な値を return するわけだし、 async なら Promise 返すってわかってるんだから戻り値の型に Promise 要らない気がするんだけど・・・。 C# に引きづられてる?
Avatar
interfaceだとasyncつけれなくて、Promiseを返す関数として宣言するんですよね。 async自体は実態としてはただのアトリビュートでしかなさそうな気がしています
Avatar
そうですね。考え直してみたんですが、JavaScript/TypeScript的には async は内向けのものでしかないですよね。外に向けた型ではなく、単にその関数の中で await が使えるよと。 (edited)
2:24 AM
外向きには Promise を返すという型で表現する。 Swift の async/await とは根本的に思想が違いますね・・・。 (edited)
Avatar
今度は Promise<boolean> を返す API を呼んで await 付け忘れて if に突っ込んでバグっててハマった・・・。もう === true とかで検査した方が安全なんじゃないか。それなら Promise<boolean>boolean の比較なんで tsc が検出してくれる。
😢 1
Avatar
Kishikawa Katsumi 12/11/2023 8:22 AM
https://tarao.hatenablog.com/entry/scala3-multi-stage Scalaのマクロはかなり理想的っぽい。
この記事はScala Advent Calendar 2023の11日目です.最近, 趣味でScala 3のコードをだいぶ書いていて, マクロの使い心地のよさに感心しました. 理論的な背景も含めて, 産業界で多く使われているプログラミング言語の中では筆者の知る限りぶっちぎりに優れたマクロを備えています. 他の言語にも見習ってほしいですね. たぶん見習おうとすると処理系を作り直す羽目になりますが.この記事ではScala 3のマクロのすごいところを例を使って紹介します.
Avatar
マクロじゃない普通のコードにめっちゃきれいに融合してますね
8:39 AM
Swiftのマクロが得ている周辺コードに関するメタデータはリフレクションで手に入れてて、そこが真似しづらそうなところですね
Avatar
golangのio.Reader的なものがSwiftにもあれば良かったのに。 type Reader interface { Read(p []byte) (n int, err error) } (edited)
Avatar
golangは実装の有無だけでinterfaceの適用可否が判断されてるぽいから、要求最小限なinterfaceを沢山作ることが出来てるのかな。Swiftだとプロトコル準拠の宣言が必要だから、要求最小限なinterfaceを沢山作るのは無理がありそうか。 (edited)
Avatar
Kishikawa Katsumi 4/11/2024 6:08 PM
https://www.douggregor.net/posts/swift-for-cxx-practitioners-value-types/ Doug GregorさんがC++プログラマの人向けにSwift入門の連載を始めた。最初は値型についてけっこう長く書いてる。
Swift for C++ Practitioners, Part 1: Intro & Value Types
Avatar
逆が欲しいw
1:05 AM
C++ for Swift Practitioners
Avatar
omochimetaru 4/12/2024 1:24 AM
逆向きはマッチする読者の数が少なそ〜
Avatar
C++ Interopも追加されて興味ある人いそうだけど、そもそもC++ Interopを使う人が少ない…(&使う人はC++習熟してそう) (edited)
t_sorena 1
Avatar
でも僕は欲しい
t_wakaru 8
Exported 828 message(s)
Timezone: UTC+0