Twitterでふぁぼったものをひたすら試します

Swiftの小ネタ

qiita.com

普段Swiftを書いてる皆様用にいくつか振りたい小ネタっていうか話題があるので読んでいってください。
(本当はもっと規模のでっかい話をしたかったんですが間に合いませんでした…iOSDCとか来年のカレンダーには間に合わせます!)

その1:型理論カレンダー用に書いたやつ

s-shimotori.hatenablog.com

Swift書かない人も読むことを想定して書いたやつなので↑には結論を書いてないのですが、この記事の結論は
「Swiftで使われる 型消去 の意味は世間一般とは違うっぽいのであんまでかい声で連呼するとこっちが消されそう…」
です。

その2:tupleについて

  • tupleの添字は0始まり派と1始まり派がいる。1始まり派でいうとHaskell(1990年生・ fst, snd)やKotlin(2011年生・first〜)とか。0始まり派は我らがSwift(2014年生)の他にRust(2010年生)など。バージョン上がって0始まり派に寝返ったScalaとかいうのもいるので我々の時代が来ている……かは定かではない。
  • 配列と違いtupleは違う型のオブジェクトを持つことができるが、配列のように tuple[i] などと動的に要素を指定することはできない。そりゃまあ subscript の戻り値の型が定まりませんし。
    • どうにかして定まるような仕組みがあれば書けるとも言える。Scala 3にはパターンマッチにより最終的な型を決定する型が存在する("match type")。この仕組みがSwiftに欲しいかと言われると?うーん……いらないかな…

その3:[SE-0330] Conditionals in Collections

この機能地味に欲しいやつ。まあ本日時点でReturned for revisionなんですが…

github.com

私はこう書きたいって過去に3回くらい考えたことある。ありますよね?地味〜にめんどくさいじゃないですか、こう書けないせいで・・

let array = [
    "apple",
    "banana",
// ここで一旦配列の宣言を切り上げて `append("peach")` とかするのだるい
#if YOU_LIKE_PEACH
    "peach",
#endif
    "pear"
]

問題点はいくつかあるようで、

let ambiguous = [
#if HOGE
    "peach",
#else
    "peach": 100
#endif
]

というふうに違う型が来たらどうするのか?とか、これを実現するには実装が複雑になるんじゃという懸念があるらしい。

ちなみに現在、#if を扱っているのはlibSyntaxだそうです。導入前はAST側に #if を任せていたとか。

(Source) -> [Parser] -+-> (AST) -> [Sema] -> ...
                      | and
                      +-> (libSyntax) -> [SwiftSyntax, ...]

Integrating libSyntax into the compiler pipelineの解説 | by Yusuke Kita | Mediumから引用)

Syntax側が担うのだからなんとかなるんじゃ
とか、
#if 配列 #elseif 辞書 #endifの場合は両者をまとめて扱える専用のノードが必要になるぞ
とか、 そもそも #if はLexerで扱うべき
とか、
C#でこの手のことが書けるのは条件に合うほうだけを取り込んでいるから(しかし完全に切り捨てているわけでもない)
とか、

などなど。
SE-0330: Conditionals in Collections - #22 by tkremenek - Proposal Reviews - Swift Forums

ちなみにこの話は2018年ごろからあって最近復活したものっぽいです。議論の結果やいかに。

いろんな型消去

qiita.com

初心者です。初心者なので型システム入門を何周してもわかりません。無限に周回と挫折を繰り返しています。誰か型システム入門の攻略チャートを組んでください……

なんで型消去を選んだ

さて、型システム入門のなかで 型消去 という語が登場します。皆さんは型消去と聞いて何を思い浮かべるでしょうか。私は普段Swiftを書くのでSwiftの型消去テクニックを真っ先に思い出します。これは型システム入門で紹介される型消去とは異なります多分。どうやら「型消去」という3文字自体はあくまで型を消去するという意味しかなく、どんな形であれ型を消す作業をしていればそれは型消去となってしまうようです。さっぱりわからん。

Wikipediaの型消去のページにはC++の例とJavaの例が載っています。
型消去 - Wikipedia
Wikipediaで説明されているJavaの型消去は、恐らく型システム入門の言う 型消去意味論 の一環として行われていることだとは思うのですが、意味論として型消去について語っている資料が英語論文くらいしかないので読んでないよくわからん。

本記事では各言語における型消去の操作について整理します。そうすれば型消去意味論の意味を理解できるかもしれないから。

Swiftの型消去

Swiftにはprotocolというものがあり、何らかの機能に必要となるプロパティやメソッドを定義する。標準ライブラリでは同値比較用のprotocolやシーケンス用のprotocolなどを提供している。

protocolにはassociated typeという仕組みがあり、protocolの定義段階では仮の型名で保留にしておき、クラスがprotocolを準拠する時に具体的な型を指定できる。

protocol Container {
    // 具体的に何の型が取れるのかはここでは定めない
    associatedtype Element
    func take() -> Element
}

associated typeの問題点は、associated typeを含むprotocol型の変数を宣言できないことにある。

class MyBox<T> {
    private let item: T
    init(_ item: T) {
        self.item = item
    } 
}
extension MyBox: Container {
    typealias Element = T
    func take() -> T {
        return item
    }
}

// `MyBox` はただのクラスなのでOK
let a: MyBox<Int> = MyBox<Int>(0)
// protocol 'Container' can only be used as a generic constraint
// because it has Self or associated type requirements
// というエラーになる
let b: Container = MyBox<Int>(0)

どうしても宣言したい時は型消去をする。Any(protocol名) と名付けて使うのが慣例。標準ライブラリでも AnySequenceなどが提供されている。

 // Container型の変数を定義することはできないが、総称型に制約をつけることはできる。
struct AnyContainer<T> where T: Container {
    private let _container: T
    init(_ container: T) {
        _container = container
    }
}

let c: AnyContainer<MyBox<Int>> = AnyContainer(MyBox<Int>(0))

以上がSwiftの型消去テクニック。Swiftを書く人間がやるテクニックであって、コンパイラがどうとか実行時がどうとかという話ではない。

C++の型消去

上記のSwiftの型消去は多分C++の型消去技法に由来するのだと思う(C++を意識してないってこたぁないっしょ)。

Wikipediaでも説明があるが、C++ではテンプレートを駆使してAny型を作る。型安全を無視すればテンプレート以外の方法で型消去することも可能、らしい。
型の力を抜いて学ぶC++ - Google スライド

C++ 型消去」でGoogle検索をして出てくるのはこのテクニックの話。次に説明するJavaだと総称型関連の話がわんさか出てくるのだが、C++の総称型は型消去と異なる手法(こちらは全展開とか異種変換とか呼ばれるっぽい)を採用しているためかテクニックの話ばかり出てくる、ように見える。

Javaの型消去

本記事で取り上げる型消去の中では2番目に型消去意味論に近そう?に見えるやつ(個人の感想です)。

Javaに総称型が導入されたのは1.5のとき。Java仮想マシンの互換性を重視したので、プログラマが型変数を書いてもクラスファイルには型変数の情報を残さない、つまり型消去することにした。実際、コンパイル&デコンパイルをすると型変数が復元されない。

元のソースコードが以下のようだとすると、

class GenericClass<T>{
    private T value;

    public GenericClass(T value){
        this.value = value;
    }

    public T getValue(){
        return value;
    }
}

javap はこんな感じ。これは1.5で試した場合であって、今は型変数に関する情報をクラスファイルに書き残しており復元可能になっている。そうでないとデバッガが困るので。

class GenericClass extends java.lang.Object{
    public GenericClass(java.lang.Object);
    public java.lang.Object getValue();
}

Object 型に置き換えるこのやり方は同種変換と呼ばれる。どんなものが型変数に代入されようが、Object型なので何とかなる。ちなみにC++の異種変換は、ソースコード中で代入される型(intとかstringとか)へ置き換えたものを個別に用意するというもの。用意する分だけサイズが増えるが実行効率はこっちが有利らしい。

なので、Javaの場合は「同種変換という手法をとる過程で型消去して Object に置き換えた」となるのではなかろうか。

TypeScriptの型消去

  1. Javaと同様に、総称型は型消去によって実現しているらしい。
  2. コンパイルしてJavaScriptコードを生成するときに型アノテーションを消すことも型消去と呼ぶらしい。

Google検索でざっと眺めたところでは、普通は1の用法で、稀に2の用法で使っていることがあるように見える。まあわざわざ2の話をすることはないでしょうね。だが高級言語→低級言語へコンパイルする過程で型をひたすら消去した、と見立てれば型消去意味論に最も近い気がする(個人の感想です)。
FAQ · microsoft/TypeScript Wiki · GitHub

まとめ

  • 型消去は手段である。コンパイルの過程で行うものが多いが、プログラマがせっせと型を消す話のこともある。
  • 型消去意味論はよくわからない。論文を読まないといけないようだ。

この辺読むと楽しいよ

理解の足りてない本記事よりこれらを当たるべき

来月の技術書典にはもうちょっとしっかりまとめるつもり、論文も1本くらいは読むつもり

#iOSDC Japan 2021に参加しました

ちょっと立て込んでいて細かく書く時間がなくて申し訳ないです。取り急ぎ。

全体通して

  • プロの声優さんにタイトルと名前を読み上げてくれるなんて聞いてないんですけど!どうして今年落選しちゃったの私!来年は見てろよ!
  • 思わずパソコンの前で拍手してた(ニコ生コメントに88888と入力するのではなく)。臨場感がありすぎたのかもしれない。そしてそろそろ会場参加したいと思い始めているのかもしれない。
  • 最近ずっと勉強会に参加していなかったので、発表意欲が湧いた。一応少しずつ勉強はしているんだけど纏まったものがない(落選最大の理由)。
  • ここ最近はずっと型システム入門の本を読んでいる。個人的な興味があるからという理由以外に、稲見さんの発表で毎年†完全理解†してしまうのを食い止めたいという理由があった。正直言ってしまうと今年も†完全理解†したが最後まで集中力を保つことはできたし、私にとって初見の分野だったばんじゅんさんの発表を楽しめたのは成果と言えると思う。
  • 来年は運営のお手伝いに復帰したいっス・・

個々の感想とか

わかる〜って言いながら見たやつ

わかる〜。

自社のプロジェクトで導入していないtipsには勉強になった。みんな便利ツールの作り込みすごいなあ。。

導入済みのtipsも面白かった。「やっぱあれ効果あるんだな」とか「導入した人ありがとう」とか思ってた。

デザイン系の話

デザインシステムの知見は色々聞きたかったので色々聞いてみた。どうしたもんかなあ。悩みますね。でも絶対やるべきことだと思ってるのでこうして各社取り組みが行われているのには嬉しさというか時代が来たなって思います

自分と縁遠い分野なのであえて聞いたやつ

むしろこういうやつの方が醍醐味だよね どうせ自分が普段やってる分野の話は後で見返すし。。

むずかしーって言いながら聞いたやつ

問題の稲見さんの発表。ほとんどわからんかったけど「そこは後でググればわかるだろうな」みたいな余裕を持って聞くことができたので、ここ最近の勉強は無駄ではなかったと思う。引き続き頑張っていきたい。

問題のばんじゅんさんの発表はこっち。こういうのもちゃんと理論があるんだなあ。

にゃーん

にゃーん

2020年もiOSDC Japanで色の発表をしました(「大解剖!UIColorファミリー」) #iosdc

これまでに発表した色のあれこれ

流石にDark Modeで得たネタで終わりかと思ったのだが、
???「UIColorのサブクラス作れたりしないかなー」
の一言からUIColorのサブクラス発表が生まれた。

世の中的には「UIColorのサブクラス作成はほぼ不可能」は既知の情報だった。なぜサブクラスの作成が不可能なのかは誰も説明していなかったのでとても画期的な発表だった(役には立たない)。

今年はスタッフをしたのか

してない(ネットワークの仕事がなかったので)(当日の都合がつかなかったので)
体力的には非常に楽だったが物足りない気持ちもあり。

「大解剖!UIColorファミリー」

UIColor自体は有用でも内部実装の情報は何も役に立たないので「『役立つ情報を話します』な優良誤認をしていないか」がすごく不安だった。

SwiftUI.Color 情報がないのでこの分のネタをどうしようか微妙なところ。

今のところ不明な点:

  • sRGBな SwiftUI.ColorCGColor に変えるとなぜか数値がちょっとずれる
    • display P3はズレない。
  • Asset Catalogの色をStoryboard上で使うとなぜか数値がちょっとずれる(らしい)

総合的に

オンラインなのにいつもの企業さんがスポンサーしてくださってるし、豪華ノベルティも届いたし、収録から当日まで初年度と思えないオペレーションでとてもビビった。いつも通り楽しいiOSDCだった!
(懇親会とかでご挨拶や思いがけない出会いができなかったのはざんねんだけど・・しょうがないね)

Swift evolution proposals No.268 - No.273を読んだだけ

qiita.com

2019年の感想:
上半期は UICollectionView を軽くやって下半期はDark ModeをやってたのでSwiftのことはすっかり忘れました。マジで何もわからん。Swift5さえ怪しい気がする。

なのでここ1ヶ月のproposalを軽く読んでアドベントカレンダーをごまかす。
No.268〜No.273です

Refine didSet Semantics

swift-evolution/0268-didset-semantics.md at master · apple/swift-evolution · GitHub
今のステータス:Active Review (5-9 December 2019)

今のSwiftは、 didSet が動くと oldValue の取得をするために毎回getしちゃうらしい。たとえ oldValue を使わなくてもallocateしたりしちゃうらしい。
このproposalは 「oldValue を使わない時はその辺の処理をスキップしたい!」というもの。

Increase availability of implicit self in @escaping closures when reference cycles are unlikely to occur

swift-evolution/0269-implicit-self-explicit-capture.md at master · apple/swift-evolution · GitHub
今のステータス:Accepted

self の書き方が変わるっぽい。

class Test {
    var x = 0
    func execute(_ work: @escaping () -> Void) {
        work()
    }
    func method() {
        execute { [self] in
            x += 1  // ← [self]って明示したからself.xって書かなくていいことにする
        }
    }
}
struct Test {
    var x = 0
    func execute(_ work: @escaping () -> Void) {
        work()
    }
    func method() {
        execute { 
            x += 1  // ←この場合、selfはstruct(値型)なんだから[self]って明示する必要もないでしょ
        }
    }
}

今は不要なところでも self.x って書いてるし、Appleは不要なselfは書かない方針のようなので必要なところだけ明示するようにする。

Add Collection Operations on Noncontiguous Elements

swift-evolution/0270-rangeset-and-collection-operations.md at master · apple/swift-evolution · GitHub
今のステータス:Active review (December 13th...19th, 2019)

IndexSet 以外に RangeSet を増やしたいというproposal。

numbers = Array(1...15)
let notTheMiddle = RangeSet([0..<5, 10..<15])

print(Array(numbers[notTheMiddle]))
// Prints [1, 2, 3, 4, 5, 11, 12, 13, 14, 15]

Package Manager Resources

swift-evolution/0271-package-manager-resources.md at master · apple/swift-evolution · GitHub
今のステータス:Accepted with revisions

一言でいえばタイトル通り。SPMなので、もちろんプラットフォームに依存しない形で。

目標をざっくり訳すと

  • 簡単にリソースファイルを追加できるようにする
  • リソースではないファイル(ドキュメントなど)を間違えて混入しないようにする
  • プラットフォーム依存のもの(xibとか)も対応する
  • ローカライゼーションも。
  • package authorが好きなところにリソースファイルをおけるようにする

とのこと。

Package Manager Binary Dependencies

swift-evolution/0272-swiftpm-binary-dependencies.md at master · apple/swift-evolution · GitHub
今のステータス:Accepted with revisions

これも一言でいえばタイトル通り。

CocoaPodsみたいにクローズドソース(Firebaseとかそういうの)に対応できるようにしたいというのがモチベ。

ただ、以下のことをやるつもりはないらしい(バイナリでできたものについて詳しくないからよくわかんない。。)

  • Ease of production of binary packages
  • Simplicity of binary artifact distribution mechanism
  • Widespread use of binary packages

あと、proposalには「最初はAppleのプラットフォーム対応だけ」と書いてあるので今後に期待する要素がそれなりにありそう。

Package Manager Conditional Target Dependencies

swift-evolution/0273-swiftpm-conditional-target-dependencies.md at master · apple/swift-evolution · GitHub
今のステータス:Accepted

targetのdependencycondition: が増えるらしい。

            dependencies: [
                .product(name: "Bluetooth", condition: .when(platforms: [.macOS])),
                .product(name: "BluetoothLinux", condition: .when(platforms: [.linux])),
                .target(name: "DebugHelpers", condition: .when(configuration: .debug)),
            ]

まとめ

SPMが集中してた

TaPLの2章と3章に出てくる単語を調べた(だけ)

qiita.com

Q なんでこんなまとめブログみたいなことしてるの
A すうがくむずかしすぎて2章と3章を読んだことがなかったから

2章

2.1

  • "加算"

http://www.math.is.tohoku.ac.jp/~obata/student/subject/file/2018-7_kasan.pdf

集合Aから集合Bへの全単射が存在するとき, AとBは濃度が等しいといい
(略)
自然数の集合\mathbb{N} = \{1, 2, 3, \ldots \}と濃度が等しい集合A可算集合という. 言い換えれば, 全単射f: \mathbb{N} \rightarrow Aが存在するような集合A可算集合である.

https://www.hongo.wide.ad.jp/~jo2lxq/dm/lecture/02.pdf

  • Aを整数の集合とする
  • x \in Aから、x + 1というAの要素への関係をRとする
  • この場合 R = \{(x, x+1) | x \in A\} \subset A \times Aであり、RA上の関係である、という。
  • "保存される"

これよくわかんなかったんだけど。。

2.2

用語

日本語 英語
 対称的 symmetric sRtならばtRs
反対称的 antisymmetric sRtかつtRsならばs=t
 反射的 reflexive sRs
 推移的 transitive sRtかつtRuならばsRu

↑を組み合わせたやつ

前順序 半順序
 対称的    
反対称的  
 反射的
 推移的

3章

3.4

  • 操作的意味論

http://www.kurims.kyoto-u.ac.jp/~kenkyubu/kokai-koza/H28-hasegawa.pdf

実際にプログラミング言語の処理系が行っているような具体的な計算の規則によってプログラムの意味を与える流儀は、操作的意味論(operational semantics)と呼ばれます。操作的意味論が与えられると、コンピュータ上で動作するプログラミング言語の処理系を与えることが(少なくとも原理的には)できるので、現在では、操作的意味論は、プログラミング言語の定義を与える有力な手法とみなされています。

http://research.nii.ac.jp/~ichiro/lecture/model2003/operational%20semantics.pdf

抽象機械の例

  • 表示的意味論

https://ipsj.ixsq.nii.ac.jp/ej/index.php?action=pages_view_main&active_action=repository_action_common_download&item_id=65197&item_no=1&attribute_id=1&file_no=1&page_id=13&block_id=8

意味領域は,「定義されていること(definedness)」の度合いを表す順序\sqsubseteqが与えられた集合である.

  • 公理的意味論

https://www.fos.kuis.kyoto-u.ac.jp/~igarashi/class/sf03w/resume5.pdf

操作的/表示的意味論を使ってプログラムの性質の議論をするためには,数学的に定義された実行関係・意味関数などを対象として,メタ言語 (日本語+集合の基礎知識) によって非形式的に議論を行なわなければならなかった.ここでは,プログラムの性質を直接の対象として扱う形式的体系 (規則による導出体系) を考える.そして,形式的体系により証明できる性質を以て,プログラムの意味を定義した,と考える,このようなプログラムへの意味付けの方法を公理的意味論と呼ぶ.

感想

4章から先の単語はプログラミング言語の話題で出てくるから初見感はない(正直まだよくわかってない)

技術書典7で当日の手伝いをして戦利品いっぱい買った

techbookfest.org

当日スタッフ

多分6回目とかもうその辺になりそうな気がする。技術書典2とか3とかから手伝ってるので。
今回はイベントスペースの面積が2倍になったが別に体力が2倍になることはないので結構疲れた。DroidKaigiやiOSDCより疲れ、工大祭よりはマシだった。

『綿を育てて布を作る。【栽培編】』『【紡糸編】』

教養をつけるために購入。綿には(当然だが)品種違いがあるとか、本来なら多年草だとかいうのを初めて知った。

『みんなの測量塾』『地学の散歩路』

早稲田大学地学愛好会というところの同人誌。早稲田はいろんなサークルがあるらしくて羨ましい。母校は火山やってる先生はいてもサークルはない。

『みんなの測量塾』は歴史やら何やらの知識も含んで比較的簡単に読めて面白かった。『地学の散歩路』もモノ自体は興味深くはあったけど知識がなくて難しくてスムーズに読み進まない……

『入門起床』

私は朝起きられる方なので寝坊をした記憶さえパッと出てこないが、"ステークホルダー"との待ち合わせに遅れたことはある。DroidKaigi運営のため西新宿駅に行こうとしたら丸ノ内線が通勤ラッシュで遅延してた。つらい。

『"距離"のノート』

噂の暗黒通信団の本。円周率の本はその辺で売ってるし、他の本は難しそうなので、これなら簡単かもしれないと思って買ってみた。実際、2点間の距離の話とかならわからないこともなかった。ノルムは習ったことは覚えてるけど何に使われてるのかは覚えてない。

iOSDCでの色の話のための下調べ中に「xy色度図状の2点(2色)間の距離の長さが実際の色の相違度と一致しているかいないか」という話題を見つけたけど、結局どういう結論なのかまではあまりよく覚えてない……

『いつもオプションとフィルタの使い方をググっている人が最初に調べるFFmpegの本』

動画編集が趣味ではないが、たまにffmpegを使うので買ってみた。わたし、タイトルに該当する人です。

いつ使うかって言ったら、 iOS Color Invert使用中のアプリをスクショしたいが通常スクショでは色反転が取れないので仕方なくQuickTimeで録画したのを静止画にしたいとき

楔形文字ユニコードの出会いにまつわるエトセトラ』

ユニコードの知識をつけてみたかったので購入。ユニコードにどういった種の文字があるかはなんとなく知っているつもりだったけど、古代文明や文字登録に至るまでの議論の方はさっぱりわからないのでなかなか難しかった。

クラウドエンジニアのための中国語入門(1)』

クラウドエンジニアでないし中国語は大学の第二外国語でやったきりだけど勘で読むのをやってみたくて購入。わかるようでわからないようでわかるようでわからない。

韓国(ハングル)の空港やドキュメントはマジでなんもわからないので、中国語圏(繁体字簡体字)の空港やドキュメントを見るとそれだけで泣いちゃう。

『空に飛ばす 9日間で軌道を描く』

サークルリストを眺めていて「この人たちどう考えても激レアさんに出てた人たちじゃん」ってなった。聞いてみたら実際そうだった。ので簡単そうなのを買ってみた。

衛星軌道のパラメータっていうのの存在を初めて知った。

『Nikkei Development Book』

知人の近況を知るために購入。VTuberやってるらしい。また新聞屋さんが新しいこと始めてる……

『XcodeGen導入ガイド』

UIばかりいじっていてプロジェクトの設定やビルドの話から日々おいていかれているので購入した。なんか気づいたらXcodeGenになってたりする。

これ読んで完全理解した気になった。

『Datarace Detection Algorithm and Implementation』

知ってる人がいたので買ってみた。まるちすれっどのことはわかんないなあ。

表紙に夕立がいる……

『数理論理学とラムダ計算の世界』

論理学、自分がどこまで理解しててどこからがわからないのかがわからなくなってきたので購入。このくらいなら覚えがあるらしい。復習用。

『技術季報』

次回はサークルに応募しようかなあ、こういうのって悩むより出せってやつですよね

『Money Forward Tech Book #1』

知人の近況を〜。意外と知ってる人いる。元号対応大変そうだなあ。私はのんびりしてるタイプだから間に合わせられないだろうなあ。

『量子ガール』

知人の〜〜。何もわからんかった!私はもうだめだ。

『新世紀日本古式泳法マニュアル』

古式泳法という名前は聞いたことあるけど内容を知らなかったので。習得方法や溺れた人の救助方法も書いてあった。
ちなみに私は最初から水辺に近づかないという選択肢をとる人生してる。

『OS Girls 02』

知人〜。OSとかハードウェアは規格読みこまなくちゃ行けなくて大変そうだな〜で私の知識が止まってる。

『TALKING NEKOISM』

製版機の実物ってよくわかってないので購入。プリンター欲しい界隈が欲しいのはこういうのなんだろうなあ。やっぱ個人が持つにはでかい。

『もしも明日盲目になっても絶望しないために知っておきたい32の支援技術』

我々はアクセシビリティ機能を実装しなきゃいけないから購入。あー明日からも頑張って実装しよー。終わんねー。しかしユーザが待っている。

まとめ

今回も雑多にたくさん買いすぎた(いい意味で)