北海道苫小牧市出身の初老PGが書くブログ

永遠のプログラマを夢見る、苫小牧市出身のおじさんのちらしの裏

rustでdiscordのbotを作ってみたくて下調べ(2)

discord の bot を作るのなら websocket が必須なので下調べ。

というか、調べなくても discord-rs が使っていた websocket がそのまま使えるはずと思っていたのだが、開発が sluggish なので tokio-tungstenite を勧めている。良い名前空間を使っているだけに悲しい。

tokio-tungstenite の方は、 async/await への対応がまだであり、 鋭意作業中 のようだ。近日中にリリースされそうな勢い。

一方で、 crates.io で改めて検索すると、 ws なんてやつがいる。利用数は多いようだが、こいつは async/await とは別のエコシステムで実装されているように見える。 async/await の issue では tungsteniteが勧められている

ということで、 tokio-tungstenite の async/await 対応が終わるのを待つのが、一番幸せになれる道のような気がしている。

rustでdiscordのbotを作ってみたくて下調べ

結論から書くとまだ何もしてない。

discord-rs というのがあるのだけど、だいぶ古い。特に嫌なのが issue にも上がっている通り openssl 1.0 系への依存。 昨年末にEOLを迎えている ので避けておきたい。

という事で手元でバージョンを上げようと試みたのだが、これがかなり厳しい。特に hyper 周りがバージョンが上がって大きくインタフェースが変わっており、変更量が多すぎて諦めた。ついでに edition も Rust 2018 にしようと試みたのだが、 try! の廃止があまりにもきつかったので断念。 cargo fix --edition を使えと書いてあったが、 try! は警告を出すだけで何も直してくれず、おい、その量は無理だろって量の warning が出ただけの結果となった。

という事で、手で bot を書いてみようかなと。 discord bot の基本は Haskell ではあるが fumivalさんのエントリ がとてもわかりやすかった。後は discord-rs を参考に手を動かすだけ。

Rust 1.39 より await / async syntax が入り、 runtime も tokio 以外も使えるのでやってみたかったのだが、 hyperはtokioに依存しているぽい ので、無理せず tokio を使うべきかなあという結論。あと、 discord-rs は hyper に依存しているが、当時の hyper が持っていた機能は reqwest に移っていそうだったので、こっちを使うほうが良さげ。

という事で、結局調べていただけでまだ何もしていない。

2019年のまとめ

今年を箇条書きでまとめておく。歳のせいか意識の高い話は何もなく、ああ、良くないなあとは思うのだが、まあそれとは別の話として、将来の自分用にメモを残して置くことはいいことだろう。

plain-old jarで JUnit5 を試す

https://junit.org/junit5/docs/current/user-guide/#running-tests-console-launcher に書いてあるんだけど、分かりにく過ぎたので。

$ curl -O https://repo1.maven.org/maven2/org/junit/platform/junit-platform-console-standalone/1.5.2/junit-platform-console-standalone-1.5.2.jar
$ cat SampleTest.java
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;

public class SampleTest {
    @Test
    public void testOneEqualsOne() {
        assertEquals(1, 1);
    }
}
$ javac -cp junit-platform-console-standalone-1.5.2.jar:. *.java
$ java -jar junit-platform-console-standalone-1.5.2.jar -cp . --scan-classpath

Thanks for using JUnit! Support its development at https://junit.org/sponsoring

╷
├─ JUnit Jupiter ✔
│  └─ SampleTest ✔
│     └─ testOneEqualsOne() ✔
└─ JUnit Vintage ✔

Test run finished after 169 ms
[         3 containers found      ]
[         0 containers skipped    ]
[         3 containers started    ]
[         0 containers aborted    ]
[         3 containers successful ]
[         0 containers failed     ]
[         1 tests found           ]
[         0 tests skipped         ]
[         1 tests started         ]
[         0 tests aborted         ]
[         1 tests successful      ]
[         0 tests failed          ]

今日は 吉祥寺.pm20 の日です

弊社での開催でしたので、自分用のメモを残しておきます。

本当は難しいPSL / hiratara

自分のセッションでした。

speakerdeck.com

Windowsデスクトップでweb開発 / setoazusaさん

  • Windowsで開発している人は少ない
  • TypeScriptやJavaScriptならなんとかなる?
  • ネイティブコード、symlink、permission、ビルドスクリプトでのUNIXコマンド
  • 大型アップデートの繰り返し。Win7とは違う
  • VSCode のリモート WSL のデモ
  • wsl.exe を起動
  • Dancer(Perl)でのデモ
  • サーバを起動
  • VSCode から編集して、反映
  • Live Reload が効かない。WSLの問題なのでWSL2に期待
  • Windows 開発で楽しく Perl 開発

EMはじめまして 10年努めたSIerから転職して3週間 / tenten0213さん

  • エンジニアリングマネージャー
  • 1on1やった
  • オープンなカルチャー
  • やることがない ... 20%ルールなどやる
  • タイトルと給料がオープン
  • 給料はみんなで決めている
  • リクルートに力を入れている

オープニング

  • 20回目です
  • 6周年です
  • 生まれ故郷: YAPC::Asia のリジェクトコンの与太話で生まれた

ソフトウェアラジオとC++ / jj1bdxさん

  • 昔のラジオ
  • FMエアチェック
    • ラジオをカセットに録音?
  • 現代のラジオ
    • USBデバイスで得た信号をソフトウェア処理
    • コードが書ければラジオをかけれる
  • 負の周波数とは?
  • std::atan2 はすごく時間がかかるので、 gnu の実装を使う
  • AM放送なら振幅が必要
  • FM放送なら位相を微分し、復調する
  • 位相が歪むとFM放送で不快な音がする
  • 時間だけを見ると、反射波の遅延の波が加算される
  • マルチパスフィルタ: 逆方向のフィルタをかける
  • FIRフィルタ 複素数でやったフィルタ
  • Vector Optimized Library of Kernels (volk ... x86 と ARM だけすごく早くなる)
  • 世界初のOSSで実装したマルチパスフィルタ
    • airspy-fmradion
  • Rasberry Pi でも動く
  • Windows 対応も予定している
  • 冬の夜に 雷を伝える 電離層

触ってみよう Micronaut Framework / shimamchanさん

  • コールドスタート時の性能が重要視
  • JVM は不利
  • Sprint boot からインスパイア
    • 依存はしていない
  • 昔のフレームワークはモノリシック前提だった
  • Netty ベース
  • @Singleton アノテーション。独自実装アノテーションもある
  • Kotlin、Groovy も対応
    • Groovy はイメージ化できない
    • ScalaClojureにも対応する予定らしい
  • DI対象がない場合は実行時エラー
  • コンパイルしたあとはデコンパイル(して、何をやっているか調べる)
    • リフレクションを使ってないことがわかる
  • フィールドインジェクションすると、リフレクションが使われる
    • むやみに使うとテストでもDIコンテナが必要にある
    • コンストラクタインジェクションのほうが、よい。 final にできる

PHP で AST 解析して Java の中間コードを生成する / memoryさん

  • PHP そのものを JVM 言語にする話
  • Abstract Syntax Tree 抽象構文木
    • 意味のある情報のみをツリーに
    • インデントなどを消す
  • 言語に合わせたシンタックスを理解してトークンに分解
  • AST解析の方法
    • PHPのライブラリを使うか
    • 自作するか
  • nikic/PHP-Parser を利用
  • Javaのオペコードとは
    • javap で吐き出せる
    • iconst_1, iconst_2, iadd, iconst_3 (1 + 2 + 3)
  • echo を System.out.println に直すのはすごく大変
  • PHPJava にするデモ
  • javap するとコンパイル元が HelloWorld.php になっている
  • php-java / コントリビュート募集中
    • 作っている理由: 刺激が欲しいから
    • 辛いところ: 型

詳解 Class::Accessor::Typed / papixさん

  • Kichijoji Poem Meeting : 句会
  • お前の型は間違っている、という話は勘弁
  • Go、Scalaとは違う
  • Perlの型: スカラ、配列、ハッシュ
  • 文字列を期待するところにリファレンスを渡すと
    • 期待する動作をしない
    • 死なない
  • モジュールで動的に型を定義する。実行時に検証
    • エラーにならないよりはマシ
  • Smart::Args 型チェック
    • 型の定義は Mouse::Util::TypeConstraints
    • Type::Tiny というのもある
  • bless 後付で作られたPMP
    • 祝福するとオブジェクトができる
    • クラスビルダーを使って、書きやすくする
  • フルスペック(バリデーションやMixin)なものとシンプルなもの
  • フルスペック
  • シンプル
    • Class::Accessor, Class::Accessor::Fast
    • Class::Accessor::Lite, Class::Accessor::Lite::Lazy
  • Class::Accessor::Lite::Lazy : ro_lazy など
  • フルスペックは重厚。複雑。型の恩恵がある
  • Class::Accessor::Typed
    • Class::Accessor::Lite::Lazy + SmartArgs
  • ベンチマーク
    • Moose, Moo(ISA) よりは速い
    • Mouse よりは遅い
  • 始めよう 型の力で 良いPerl

スポンサートーク / hirose30さん

  • FOについて
  • RTBを作った会社。マーケティングテクノロ
  • モバイル、WEBの広告。位置情報の広告。タクシー
  • TV ✕ AdTech
  • Give People Work That Requires A Person
  • Roppongi PRODUCT MANAGER Meetup やってます
    • 決意表明: 1年以内に開催したい

IR Reading 2019 秋に行ってきました / sakuraさん

  • モンハンとマリオメーカーとプログラミングから変更
  • IR(情報検索)の論文読み
  • 5時間で22人のスピーカー、26本
  • Health Cards for Consumer Health Search
    • ナレッジグラフ。健康のクエリにも有効?
    • 右側に出るやつ
  • Teach Machine How to Read: REading Behavior Inspired Relevance Estimation
    • 検索結果のユーザがどう目を動かすか
    • アルゴリズムを提案
    • 順次読み、垂直減衰、クエリ志向、文脈依存、選択読み、早期終了
    • クエリ志向を考慮したアルゴリズムが多い
    • これらすべてを考慮したアルゴリズムを考える論文
  • 決意表明: 検索を諦めない

自分の仕様の伝え方は間違っていた! / i47_rozaryさん

  • ストーリーテリングで仕様を伝える
  • よくある伝え方
    • 機能のリストが書いてある
    • なぜ必要なのか書いてない
  • ストーリーテリング
    • 物語を通じて、情報を印象づける
  • 病院に行かない理由にも色々ある
    • 定期検診がめんどい、忘れる
    • 急病だが病院が遠い、行けない
  • タスクに簡単に書くと、開発者は作り始めてしまう
    • 利用状況の説明が足りない
  • ユーザの環境情報を元に仕様を考える
    • チーム全員でプロダクトに向き合うことができる
  • 決意表明: 40歳になったら宇宙旅行

それでもスクラムマスターをやっていく / KamoShinichiroさん

  • 30分のスライドを5分で
  • スクラムマスターの価値
  • PはPoemのP
  • 人間は自分たちへの甘えがある
    • 現状の自分を肯定しがち。masterへpushしたときなど
    • そこで止まってしまう
    • 長期的に見ると問題が起きていることがある
  • 悪いからサボるのではなく弱いからサボる
  • チームのトレーナー : スクラムマスター
  • スクラムマスターは第三者なので、自分しか知らない自分がいる
    • 走りながら自分のフォームを見直すことができない
    • エンジニアにも同じことを言えるだろう
  • ボトルネックになったりしがち。だが、価値がある

令和なのでメールを読む話 / tennashiさん

  • 人間は増えますね
  • PM = "P"OP I"M"AP
  • neomutt でメールを読む
    • mutt から派生。 CLI 。 hjkl で移動ができる
  • HTMLメールをちゃんと読める?
    • w3m
    • テキストベース。 hjkl で移動ができる。 mutt が勝手に開く
    • 普通、 text/plain と text/html が両方送信されている
  • IMAP 接続が遅い問題
    • mbsync (isync)
    • IMAPサーバからメールを取って Maildir 形式で保存
  • Maildir 形式
    • メールの形式: RFC5322/RFC2822/RFC822
    • ローカルの形式はない。 mbox か Maildir(++)
    • mbox は1ファイルだから怖い
  • mbsyncの定期実行は systemd やら cron
  • imapnotify : IMAPのNOTIFY 拡張をトリガに

いまさらMySQL::Dump::Parser::XSの話 / karupaneruraz さん

  • ダンプすると数十GB
  • mysqld 通して importすると時間がかかって大変
  • MySQL::Dump::Parser::XS
    • 5 年前に作った
  • 金でいいインスタンスを立てるといい
  • 突然のPR
  • 5年越しのCPANリリースした
    • メタ文字のサポート
    • charset indicator ( __latin1'abc' ) など

昔作っていたソシャゲーの裏側 / わいとんさん

  • 大井町.pm 6人くらい
  • 2007 年 facebook platform
  • 2008年 月mixiアプリ
  • 2009年 怪盗ロワイヤル
  • モバゲーAPI, GREEアプリ
  • 2011 探検ドリランド
  • 2007年12月
    • 「猿渡学園」
    • 2013年 クソアプリオブ・ザ・イヤーに選ばれる
    • すでに存在しない会社
  • 猿渡学園の裏側
  • 猿渡学園DX (iアプリスマホアプリ)
  • ヤンキー、学力は控えめ
  • モヒカン版きれいなジャイアン
  • 検索機能でタイマン (PvP)
    • 戦術は3つ
    • メールで果たし状
  • tableタグを利用した体力ゲージ
  • 10,000 回自動対戦で、差があるとエラーとなる(パワーバランス)
  • Scientific Linux 4.x
  • Perl 5.8 (よくわからない言語)
  • Catalyst (Catamoose ではない)
  • Apache2.0 + mod_perl
  • Tritonn (MySQL 5.0 + Senna)
  • memcached
  • gearman から TheSchwartz に
    • タイマン、抗争が発生しない現象が解決
  • Ultra Monkey L7, Heartbeat
  • iptables + Heartbeat

事業を横から見たエンジニアの悩み / kfly8さん

  • 組織の生産性を上げることが仕事のミッション
  • 総合格闘技。人に聞いて現状把握。仮説を立てる。PDCAを回す
  • 毎日デプロイではなく、ゆっくり、継続がキモ
  • 1on1、勉強会、カンファレンス参加支援、評価制度 うまく機能しているか
  • マネージメントが機能しているか
    • 目標設定、成果、進捗、雑談
  • フルスクラッチで頑張りすぎ

エンジニアが(きっと)知らないエンジニア採用の話 / chan_centerさん

  • 採用って恋愛に似ている?
    • 似てない。採用はできるけど彼氏はできない
  • 相手の気持ちに従う、相手のペース、何もしなかったり、3時間の面談
    • うまくいくこともうまくいかないこともある
    • 万能薬はない
    • 相手に有効な切れるカードを増やしていく
  • Facebook 送りまくり、マックでエンジニアぽい人をナンパ
    • これは引かれるので、絶対にやめたほうがいい
  • 相手のことを考えていっぱいやる
    • 活動時間が半分入って、同じ人数入る
  • 決意表明: 恋愛にノウハウを活かしたい

今日は安全なシステムプログラミング言語Rustへの招待の日です

IIJさんでのセミナー を聴講に来ましたので、自分用のメモを残しておきます。

安全なシステムプログラミング言語Rustへの招待 / keenさん

  • 2015 年に 1.0.0 がリリース
    • ここからは安定している
  • 6週間ごとのリリース
  • 言語仕様は2つ
    • Rust2015 と Rust2018
    • 移行ツールはある。両方をコンパイルしてリンクすることも可能
  • 実例
    • firecracker AWS Lambda の内側
    • Magick Pocket: DropBoxのストレージマネージャ
    • Servo: レンダリングエンジン
    • Redox : OS。 大学のプロジェクト
    • TiKV: KVS
  • システムプログラミングは?
    • ランタイムがない (GCがない)
    • メモリは自動管理
    • Cと相互連携
    • 生パケット、組み込み系など
  • メモリ配置
    • Cと違い、詰めようとする
    • #[repr(C)] をつけると、 12 となる
  • イテレータ
    • (2..).filter(...).take(...).for_each(...)
    • 最適化により、速いコードになる
  • トレイト
    • Haskellでいう型クラス
    • C++ の concept らしい
    • 静的ディスパッチ、動的ディスパッチ
    • derive : DebugShow 相当
    • 自分を self で受け取る Python 的なスタイル
    • {:?} で Debug プリントができる
  • 型検査
    • 制約を書いてなければ、メソッドを呼べない
    • C++のテンプレートと違ってコンパイル時に落ちる
  • enum
    • generics, 構造体のように引数も取れる
    • 代数的データ型。木構造をきれいに書ける
  • Ordering
    • 値として定義
    • reverse やメソッドチェーンで簡単に定義できたり
  • 例外はない
    • Result 型を利用する
    • ? で早期 return が可能
    • ? がググりようがないのが初心者には辛い
  • fork
    • nix::unistd::fork の戻り値が、型を見るとわかりやすい
  • forkのデモ
    • alacritty : rust 製のターミナルエミュレータ
    • Cargo.toml に依存を書く
    • cargo run で実行まで一度にやってくれる
  • 安全
    • セキュリティ面。余計なデバグが減る
    • gdbを使わなくてもいい
  • 生産性が高い
    • Cは低級言語。便利な機能があり、低レイヤが扱える、両立
    • async / await は OS がなくても動く
      • システムコールが要らない、という意味。ユーザスレッド。
      • アロケートがなくても動く
      • ステートマシンのコードに変更してくれる
      • 言語仕様としては依存しない
  • 活発なコミュニティ
  • ネットワークドライバを書く実験。Rustが若干遅い
    • 5~6%遅い
    • IPC は Rust の方が断然良い → CPUを使い切れているとも言える
    • 低級な言語でCPUを使い切れないより、高級な言語で使い切りたい
  • 安全
    • NULL Pointer, use after free, 範囲外アクセス, data race は起きない
    • race condition は防げない(デッドロック
      • プログラムのロジックのバグなので
  • 範囲外アクセス
    • vec![1, 2, 3] コンパイル時にチェックしない
    • 実行時例外
    • 固定長配列 [1, 2, 3] に定数でアクセスする場合はコンパイルエラー
  • 所有権
    • 値のライフタイムがある
    • 所有権は移動する。移動後にアクセスするとコンパイルエラー ( move セマンティクス)
    • 関数呼び出しによる所有権の移動
    • 2回データが使えないのは不便
  • 借用
    • &data でデータを貸す。
    • & にはポインタを取るという意味もある
    • 所有するポインタ Box もある
  • 借用は元のデータより長生きできない
  • Rustのデータはイミュータブル
  • C言語では *a = 0; *b = 1; return *a をしても 0 が返るとは限らない
    • a == b のとき
    • Rustでは可変参照は複数作れないので、大丈夫
  • Rust では Pointer Alias の制約が強い
    • 挙動がわかりやすく、コンパイラが最適しやすいというメリット
  • コンパイル時に Read-Write lock がかかっている
  • Nullがほしいときもある
    • find の結果がないとき、など
    • Option
      • i32 など、ポインタじゃない値も nullable にできる
      • 値なのでメソッドが生やせる
    • Option<Pointer> は最適化でポインタになる
  • Copy トレイトでマークすると、 move されない
    • i32 など
  • データには所有者がいる、ポインタは実体がある、nullポインタなどはない
  • アプリケーションの設計に関わる
    • C++のお手本のような設計をするとコンパイラは通りやすい
    • 所有者を意識する。長寿のデータ型を所有者とする
    • データ構造 HashMap などは所有者となる
    • 処理のフローを考えて無駄なコピーを廃する
      • HTTP Request 関連のものは Request に全て持たせるなど
  • get get_mut では所有権が奪えない
    • 所有権を奪うには remove
  • リソースを開放する API がない
    • open はあるが close がない
    • lock はあるが free はない
  • close のエラーは握りつぶされるので注意
    • ファイルディスクリプタに対して close がエラーを吐くと何もできないが (ディスクリプタの再利用があるかも)
    • バッファ付きで読み込み専用ファイルディスクリプタを包むと、書き込めるが、close時に落ちる、などはありうる
      • flush を先にしておくことで回避可能
  • Rustの進歩
    • 参照のライフタイムのチェックを緩めたり
  • 所有権があると書けないデータ構造
    • グラフ
    • opt out する : Rc 複数共有、 RefCell 実行時借用チェックなど
  • RcRefCell はマルチスレッドで使うと落ちてくれる
    • Arc Mutex などを使うと O.K.
    • Rust の Mutex は守る値を明示する
    • Send トレイトが実装されていると、 spawn に渡せる
    • ドキュメントを読まなくてもスレッドセーフか分かる
  • 安全性を捨てる
    • Cの関数を呼ぶ
    • 未初期化のメモリ(ハッシュテーブルなど)
    • unsafe ブロックで囲むとなんでもできる (コンパイルが通るが、セグフォ)
  • unsafe
    • nullポインタを作るのは良い。書き込みはNG
    • 基本は使わない
    • 同頑張っても無理な時 ( Vec など)
    • 高速化(境界外アクセスの無視 get_unchecked
    • C の FFI : safe な API でラップするのが普通
  • コミュニティが活発なものは成長する
    • stack overflowの人気一
    • MicroSoft
    • crates.io 30,000+ クレート ( Ruby は 15 万 )
    • コミュニティ中心でオープン / Mozillaがサポートしているだけ。AWSもサポート
  • Linuxユーザが多い(シェアは 1% のはずだが)
    • rust2020 タグを付けると、希望を吸い上げてくれる

  • UB(Undefined Behavior) が起きない
  • 日本語コミュニティもある (rust-jp slack)
    • beginer チャネルもある

  • Q). Sparkでも使える?
    • A). jarからJNIを使って呼び出さないと。厳しい。Sparkを使ったほうがいい(rustで書き直した人も。CPUバウンドを解決できるらしい)

今日は Haskell Day 2019 の日です

咳が止まらない状態で非常に厳しいですが、来ていますので、自分用のメモを残しておきます。

関数型(function type)を見つめるプログラミング / 山下さん

  • 関数の型、 Haskell では第一級
  • リスト型 a が型なら [a] も型
  • タプル a b が型なら (a, b) も型
  • タプル a b が型なら a -> b も型
    • a が domain 、 b が codomain
  • 高階関数
    • domain が関数 (a -> b) -> c
    • codomain が関数 a -> (b -> c) こちらは意識されにくい
  • 2変数関数 (a, b) -> c
  • セクション (+)高階関数
    • a が domain、 b が codomain
  • 逆に、 codomain が関数の高階関数は 2 項演算子
    • f: a -> a -> a `f`
  • curry :: ((a, b) -> c) -> a -> b -> c は高階化関数
    • 部分適用演算子、でもある f `curry` x
  • map :: (a -> b) -> [a] -> [b] は関数拡張関数
    • map は拡張適用演算子とも読める f `map` xs
    • fmapmap の一般化
  • ap :: [b -> c] -> ([b] -> [c]) も欲しい
    • 非関数を引数に適用する、拡張適用演算子
    • <*>ap の一般化
  • ($) は関数適用演算子
    • 何もしないから id と一致
    • 演算子の結合順位は重要
  • 二項演算子は拡張適用演算子
    • ◎ :: a -> b -> c について (◎) = ($) . (◎) = (◎) . ($)

Higher Kinded Datatypes / @fumieval さん

  • レコード
    • 複数の値に名前をかけ、一つの値にまとめることができる
    • 問題はあるが
  • フィールドを Maybe
    • 新しいフィールドを追加したときに過去のデータとの整合性など
  • データ型の宣言、コードが冗長
  • 多相型を使って解決する
    • data Item (h :: Type -> Type) = Item { item = h Text}
    • Item Identity, Item Maybe : Maybe の有無を共通化
    • Item (Const Text) : すべて文字列。CSVから読んだときなど
    • Item ((-> Value) : Value型からの関数をまとめる
    • カスタマイズ性が高まる
  • 構造を共通化すると、共通の操作が定義できる
  • babies パッケージ
    • instance FunctorB Item などが定義されており、 Generics で自動導出
    • bmap buniq bzipWith btraverse
  • fill :: ProductB t => t Identity -> t Maybe -> t Identity
    • Nothing 以外のフィールドを埋める関数
  • display 表示用の関数
  • HKD によるジェネリックプログラミングであれば、目的にあった型に変換できる
    • 爆アド : 爆発的なアドバンテージ
  • extensible
    • より短く書ける
    • APIがたくさん定義されている (末永くメンテしてきたので)
    • JSON のデシリアライズもできる (aeson より短く実現できる)
  • extensiblebabies の違い
    • extensible は標準の仕組みではないので自由度が高い
    • babies は標準仕様なので、言語のエコシステムから様々なサポートが得られる
    • extensibleインスタンスが予め用意されているもの
    • babies は標準なのでどんな型でも良い
    • extensible はレコードの追加削除が容易、重複も可能
  • TangleT の例
    • 体重と身長から BMI を出す例
    • 標準入力から体重、身長のフィールドの値を得て、BMIフィールドに hitch 関数で参照する例
    • 依存関係は自動で解決され、必要なフィールドだけユーザに聞かれる
  • 問題点
    • HKD は Generic1 のインスタンスにできるが、 GHC8.8 ではまだ自動導出無理
    • babies はコンパイル時間がやたら増大しがち ( extensible も )
  • これはもはやただの関数型プログラミングではない : Beyond Functional Programing
  • Q). レコードに HKD のパラメータを入れたが、なぜ Identity が必要? Functor とは関係ある? type エリアスではだめ?
    • A). Functor ではない。 type エリアスでは引数をすべて指定しなければならないので NG
  • Q). このスライドの h のカインドが Type -> Type 。複数の Type パラメータを受けるようにできる
    • A). できる。 Arrow を受けて name :: h String Int みたいな
  • Q). プロダクションで使っている?
    • A). 最近使い始めている。 Tangle はかなり前から
  • Q). GHC の Trees that Grow との違いは?
    • A). 独立した概念。両方を組み合わせることも
  • Q). HKD を使うと制約を使って fold する場合に constraint を必要なときに型ハックが必要で辛い
    • A). type application @Show など必要。面倒になるのは否めない。 extensible では成約と成約の組み合わせを扱うために And class などを用意して回避しようとしている
  • Q). And は何でも使える?
    • A). はい
  • おまけ: OpenGL のライブラリでも HKD を使っている
    • シェーダーに渡す型を、自動導出してコードを省略できる

「しんさんきぼう」GHCのderivingテクノロジー

  • 神算鬼謀 : GHC の deriving 機能がすごくなっている
  • deriving に三種類ある
  • Haskellの標準では、特定の型クラスについて、自動で関数適語を生やしてくれる
    • 特定の型クラスのみ
  • GHC拡張の deriving は3つ
    • GeneralizedNewtypeDeriving
    • DeriveAnyClass
    • DeriveVia
  • GeneralizedNewtypeDeriving (GND)
    • newtype 元の型クラスを newtype 先でも使う
    • newtype の元のインスタンスと同じ挙動をする
    • 自作モナドを作るときに便利
  • DeriveAnyClass
    • minimal implementation が空集合であるクラスを deriving 指定できるように
    • デフォルト実装があれば、 deriving 可能になる ( instance Xxx 宣言の代わり)
  • DerivingVia
    • GNDをもっと一般化したもの
    • deriving (Numeric) via Nat
    • via は、 newtype を複数経由している場合に、どの実装を使うか選べる
    • 経由していなくても representation が同じであれば via で指定できる
    • newtype だけでなく data でも使える
  • DeriveAnyClass GeneralizedNewtypedDeriving がかぶると、警告が出て DeriveAnyClass が使われてしまう
    • DerivingStrategies : deriving stock deriving anyclass deriving newtype が選べる
    • デフォルト実装を使うなら anyclass 、オーバーライドなら newtypevia
  • 「これが newtype の力だ、見たか!」
  • Q). どういう型を使うときに使える?
    • A). 使ったことはないです!
    • A). 「DerivingVia をお使いの方は?」「JSONインスタンスを作るときに、プレフィクスを消せる」

Haskell メタプログラミングによるEgisonのパターンマッチの実装

  • MiniEgison : 2010 年から使っている Egison の機能を GHC へ移植
    • いくつかのGHC拡張を使っている
  • MiniEgisonとは
    • matchAll すべてのパターンマッチの結果を返す
    • matcher パターンの解釈の方法を定義
      • List リストとしてマッチ 、 Multiset 順不同としてマッチ
  • non-linear pattern matching : $x で束縛した値を #(x + 1) で利用
    • バックトラックで効率良く動く
  • infinitely many pattern-matching
  • matchmatchAllhead
  • Egisonのパターンマッチを利用して map concat uniq を実装できる
    • intersect difference も実装できる
    • Davis-Putnam Algorithm を実装する例
    • 数学的なアルゴリズムを簡単に記述できる表現力がある
  • ループは二種類ある
    • 探索範囲を狭めるループと、バックトラックを含む再帰
    • 後者をEgison pattern matchingへ隠せる
    • パターンマッチ指向プログラミング
  • 実装のため型システムを考える必要がある
    • この型システムをGHCに落とし込む
  • class Matcher m a ma のマッチャーという関係
  • MatchClause : マッチ式の表現
    • マッチする関数と、マッチする変数の組
  • マッチ式と対象をスタックに積んで評価しながらマッチする
  • 色々うまく使ってやっている
  • nil cons は多層化されているので複数の挙動で使える
  • 実行時間は2~4倍程度。頑張っている
  • 「パターンマッチでこんなに色々できてすごい」
  • Q). Lean に Egison を入れると網羅性は?
    • A). 研究課題。かなり考える必要がある
  • Q). ViewPattern 拡張とできることの違いは?
    • A). Non-Linear パターンがサポートできない
  • Q). 出力順は?
    • A). 幅選択なので、固定。探索木が変われば変わる

関数と型で理解する自動微分 / lotz さん

  • 導関数が欲しいときありますよね?
  • 微分計算はやりたくない → 自動微分
  • \x -> x^2 + sin x から \x -> 2 * x + cos x
    • ad パッケージを利用
    • var "x" を関数に渡すと、式を表示できる x + x + cos x
  • 合成関数の微分
    • 入力関数から計算 forward mode
    • 反対から計算 reverse mode
  • 他入力、他出力だと効率が変わる
    • n < m フォワードモードの効率が良い
    • n > m リバースモードの効率が良い
    • 機械次元では n > m が多い(特徴量が圧倒的に多い)。 reverse mode が重宝される
  • 実装方法
  • 二重数 : 二乗すると 0 になる数 ε
  • data D a = D a a 実部を撮る real 、虚部をとる tangent
    • (a + bε)(c + dε) = ac + (ad + bc)ε ライプニッツルールに対応しているのがミソ。
  • lift 1 実数, infinitesimal ε
  • diffD f x = tangent $ f (x + infinitesimal) これだけで O.K.
    • ad パッケージの Forward は二重数のこと
  • xy偏微分していくときに diffD は問題がある
    • dx と dy の区別のために適切に lift をする必要がある
  • newtype AD s a = AD {unAD :: a} s は幽霊型
  • diffAD forall s. AD s (D a) -> AD s (D a) を引数にとる
    • lift する箇所が違うと s が固定されず、型エラーとなる
    • forall s. AD s (..) はこのために必要な型
  • reverse mode
    • 誤差逆伝搬法はこれに該当する
    • Reverse s aAD s a みたいなもの
    • Tape Wengert List。式の組み立てを記録する
    • reverse mode は stateful となるため、 unsafePerformIO を使うことになる
  • Reverse mode を圏論から考える論文もある。まだ研究中の分野
  • Q). forward のほうが効率がいい問題は?
    • A). ぱっと思いつかない。 forward mode はきれいなので説明に使われる
  • Q). State モナドじゃなくて unsafe なのは?
    • A). 演算子のオーバロードで実際したいので。複雑な式は使いまわしたいが、 List で作ると表現しにくい
  • Q). ST モナドと同じ使い方なのに、なぜ unsafeIO
    • A). 外側に ST が出てきてしまう。内部では ST で評価している
  • Q). 二重数のうんちくは?
    • A). なぜ微分と対応するのか。テイラー展開の2乗以降を無視するということに対応している
  • Q). 整数 1 を渡せるのは Num Float 型クラスを受け取れるから?
    • A). はい

GHCJS + Miso で作る Web フロントエンド / チェシャ猫さん

  • フロントエンド書いている人 → 多い → Haskell に比べるとメジャーですから
  • サンプル htps://hakelda219.wb.a*p (公開禁止)
  • Miso はサーバサイドレンダリングができるが、その話はしない
  • GHCJS
    • GHC のフォーク
    • Haskellのライブラリが(ほぼ)そのまま使える
  • Miso (ロゴは味噌ラーメン)
    • GHCJS で Elm Architecture を実装したもの
    • 類似品は Reflex など
  • putStrLenconsole.log に出る
  • Elm アーキテクチャとは (TEA: The Elm Architecture)
    • Action - updateModel -> Model - (viewModel) -> View -> HTML -> Action -> ...
    • Actionを規定にして一方向にしか回らない
    • update view は純粋な関数 (状態がない)
    • 再現性がある。管理しやすい
    • View から値を取るわけではなく、 Model があるのが重要
  • 他の仕組み
    • Effect : IO 相当の副作用
    • Subscription : 外部から発生したアクションを Model へ反映
      • 例) マウスが動いたイベントを拾うなど
  • チャットのサンプルプログラムを消して、再実装するデモ
    • カッコの対応が合わなくてビルドが通らない
    • 成功
  • Q). nixosを使うのにメンバーがwindowsの場合は?
    • A). 知らないOSですね。VM使いましょう
  • Q). GHCJS テンプレートハスケルが使えなかった
    • A). 使えると称している。「ほぼすべて」というのは依存によっては動かない。 Lens は使える
  • Q). 実行時のパフォーマンスは?
    • A). Miso のサイトに張ってある。JSがElmと比較して大きい。
  • Q). lazy load する仕組みを考えているという噂を聞いた
    • A). わかりません
  • Q). JSとのつなぎ込みは?
    • A). ライブラリを使っている。 lenz っぽい記法でアクセサにアクセスする
  • Q). EffectとSubscriptionについて Extensible Efect と関係は?
    • A). 特にない

Haskell で作る競技型イベントの裏側 / matsubara0507 さん

  • mixi git challenge
  • 問題例「 users4.csv が push できない。 push せよ」
  • 旧構成
    • webhook -> Ruby/Sinatra -> Jenkins -> TypeScript (on Heroku) -> Slackにメッセージ
  • なぜ書き換えたか
    • メンテナンスがきつくなってきた
    • Jenkins plugin が古すぎ
    • スコアボードを作った人は退職
    • 8割が趣味
  • 作り直すならHaskell
  • Jenkins が嫌だった。 DroneCIに (go製)
  • GitHub Webhook -> Haskell / Servant -> DroneCI -> Haskell + Elm
    • DroneCIはリポジトリにテストファイルを置くが、参加者に見せたくないのでリポジトリを2つ用意
    • git-plantation
      • OSS にした(OSSにすれば、俺がやめても俺がやる)
  • アプリ
    • app, store, tool, slack の 4 アプリ
  • 依存パッケージ
    • rio, extensible, mix.hs, shelly(スレッドセーフ。 servantのため), servant, elmap.hs, github, drone, req, wreq, lenz
  • Drone の API クライアントがなかった → 作った
    • Go 製クライアントを移植
  • Servant の定義を Elm の API クライアントを定義
    • servant-elm 。elm-bridge (自動生成)
    • extensible 対応したのが elmap.hs
  • Elm のコードが吐き出される ( : が一つしかない)
    • elm-bridge が Elm の JSON 定義も吐き出してくれる
  • スコアボードを見る機能が重すぎた → cache を実装
    • Servant と STM
  • Docker
    • Stack v1 は Docker 対応していたが、 v2 は stack image がなくなった
    • マルチステージビルドを使えばいいやん、らしい
    • docker インテグレーションは残っている
  • Docker 化するときは .stack-work を無視する
  • rio : でボイラーテンプレートを書くのめんどい → mix.hs を作った
  • 設定をすべて Dhall にした
  • DrivingVia は type エリアスと宣言が悪い
  • mixi git challenge は Haskell
  • Q). 保守はどうするの?
    • A). 社内に書ける人はいた。きっと大丈夫でしょう
  • Q). Elmの型の自動生成はJSONのprefixと相性が悪い。取り除く際の苦労は?
    • A). Extensible は prefix は要らないので困らない。 Extensible を使うのは
  • Q). 予約語とぶつからない?
    • A). ぶつかりません

大規模数値計算を支える Haskell ── Pragmatic Haskell in Large-Scale Numerical Computation / 石井大海さん

  • 写真は一枚目だけ
  • Ekemmet さんにメンテーをしてもらって博士号を取った
  • 汎用ソルバを書く仕事。微分方程式さえ書けば
    • 4000億自由度
  • 使っている拡張: TypeApplications, FlexibleContexts, MPTC, DataKinds, TypeFamilies などなど
  • Dependent Haskell (依存型)
    • 物理量 : 速度、温度、電化
    • 表現は同じだが意味が違う
    • 境界の計算が大事。同じ量でも種類によって違う
    • 人間は不変条件を忘れるので、型に覚えてもらう
  • K-form
    • Sanity: 境界条件の処理がまだなら Yet 、済んでいれば Done
    • 処理済ではないもの Yet だけ Num インスンタンスに
    • 幽霊型で共通化することで、一回の実装で済む
  • GHC(k + 1) - 1 = k であることがわからない
    • ghc-typelits-natnormalise 型チェッカーの差替
    • 人にとって自明な制約をGHCがわからないので型検査機のプラグインで使う
    • シングルトンパッケージは使わないように頑張っている
  • モナドで仕事を分けている」というツイートがあったが、本当か
  • Tagless-Final Style
    • 細かい情報はモナド m にすべて押し付ける
    • 興味のあるオペレーションを取り出して結果をモナディックにしたもの
  • Reader, ReaderT env IO
    • RIO pattern は有用である
    • DerivingVia で実装の詳細を共有する
  • =<< などは Lisper のかっこと同じだが、普通の人には難しい
    • GADT でスマートコンストラクタを実装
    • freeモナドで書いたもの
  • 部屋の温度を扱う場合に Sequence として何を使うか
    • List わかりやすいが、ランダムアクセス不可
    • Vector を使う。 O(1) で検索可能
  • Stream Fusion で効率化できる
    • foldr f z . map g == foldr (f . g) z 変形すれば一回なめるだけで良い
    • loop を one-pass にする
  • Vector の種類
    • Boxed, Unboxed, Storable
    • 統一的に扱いたい。効率性は損ないたくない
  • Stream/Bundle はモナディックな値を想定している
    • unfoldrM indexM' stream' unstream' の 4 つのプリミティブを借りる
  • 破壊的な実行で高速に
    • PrimMonad : IO ST の抽象化
    • rio でも安価な破壊的変更
  • Stream/Bundle を積極的に使い、 PrimMonad の演算を使うと良い
    • 2 ~ 3 倍速くなった
    • 破壊的変更は友達、宣言的なコンビネータに包めば怖くない
  • ソルバが4種類あるときに、新しい機能を追加すると組合せ爆発
    • Plugin で追加できるといい
    • class Plugin p で定義しておく
  • Solver '[A, B] : A, B が入ったソルバ
    • A, B の状態を保持するのに、 extensible record を使うのがいい
    • カスタムライブラリを使いたい
  • カスタムライブラリを作った理由
    • 高速アクセス、依存性が少ない、ラベルが多態(ラベルを型にしたい)、 HKD 的なオペレーション
    • GHC プラグインを作った。型レベルプラグインの簡素化や記法の単純化
  • 「人間は忘れるので型に覚えてもらって下さい」
    • ゆくゆくはリリースしたい

Cadenza: Building fast functional languages (on the JVM) / Edward Kmett さん

  • 速い関数型言語が欲しい
  • いろんな言語が GraalVM で動かせる
  • ライブコーディング
    • ラムダ計算の実装
    • ValueClosuure のみ
    • 完成版があった
    • uneval の実装
    • 完成版その2
    • uneval . eval で正規化
    • Bool Nat の追加
  • 今後の展望
    • Dependent Types にするか、 GHC Core にするか
    • 後者は GHC のコードを多く再利用できる
  • Q). なぜ eval するか
    • A). eval は速いから。特に依存型について
  • Q). Kotlin は?

LT

Haskell で 3D モデルに触れる / as_capabl さん

  • 3D のファイルフォーマット
  • glTF
    • JSONとbinary / JSON が読めれば良い
    • aeson は便利だが、型が30、メンバーが200。手では多すぎる。
    • JSON Schema から自動生成すればいい
      • aeson-schema hjsonschema
      • どっちもだめ
  • CONJCT
    • CONfigurable Json sChema Translator
    • type generation に注力
  • holzgl の両方を併用
    • Haskellは手続き敵言語なのでただ書くだけ
  • 回転するデモ
  • ライブラリにしたい
    • holz-gltf

HaskellでIoTやってます / CycloneT さん

  • B2C開発でPHPで痛い目にあった
  • B2B開発の技術選定で Haskell を知った
  • Haskell + Elm が多い
  • WebAPI : Servant, Persistent/Esqueleto, Elm-export, Xlsx
  • IoT は Webアプリとあまり違わない
  • ユーザは何が欲しいかわからないので掘り出す
    • 定常的に開発するしかない
  • メリット
    • 開発速度と品質が両立、規模が大きくてもしんどくない、楽しい

QuoraでHaskellへの愛を語る / かわのさん

  • Quora は Yahoo 知恵袋のようなもの
  • 若気の至りといっても 44 歳
  • どのプログラミングに Haskell と回答を書いた
    • 高評価。愛は伝わる
  • SIer では C#, Cobol もあるような現場
  • 値が変更不可である
  • グローバル変数がない
  • 変更不可 (Java では final ばかりつける)
  • ループがない
  • 書いた順に動かない
  • 順次処理、分岐、繰り返し・・・のどれもない!
  • 学術的なライブラリが多く、プログラミングの世界が深遠だと知れる
  • Yasod
    • 一晩かけてビルド通らない
  • Stackのお陰で一発でビルドできるようになった
    • 他の人にHaskellを進められるようになった
    • 管理されてる人に足を向けて寝れない : 東京には向けて寝れるな
  • 今日東京に来て刺激的だった

Haskellで作ってわかる型クラス / coord_e さん

  • Nummul を考える
  • mulInt mulFloat をまとめられる機能
  • 同じ名前に別の実装を与える。片付けによってDispatch
    • adhoc polymorphism
  • Num :: * -> Constraint
  • mul@Int をアプリケーションすると制約が消える
    • instance がなければ消えずにエラーとなる
  • 型がついたときにどうやって適切な実装にするのか?
    • Dictionary-passing
    • 実際の実装を渡している -> 型検査時に決まる
  • 「一番話したいところに行く前に終わっちゃうな」
  • 「30秒じゃ話せない」
  • 終了

ABSTRACT TYPE CLASSES - HOW TO DESGIN A FUTURE PROOF TYPECLAS / mod_poppo さん

  • Haskellの型クラスには破壊的な変更が加わる
    • Monad, Applicative, Functor, MonadFail, Semigroup Monad
  • 破壊的変更はきつい
  • 抽象型クラス : メソッドが公開されていない
    • KnownNat : natSing は見えない
  • 抽象型クラスだと、実装を変えても何も起きない
    • 実際 KnownNat は Integer から Natural に変わっている
  • 例えば Monad を抽象にするには、 return などを普通の関数にする
  • 三者インスタンスを作れなくなる
    • DrivingVia などを使う必要がある
  • クラス階層を変えても、破壊的変更を避けられる
  • (そのうちブログに書くのでお楽しみに)

GHCGC / kazu_yamamotoさん

  • Servant でも Warp などは使っているので、熊本の方は東京に足を向けて寝ないで!
  • 「世代別並列コピーGC」 から 「並列コピーGC と 並行マーク&スイープGC 」に変わる
  • コピーGC は生きているオブジェクトを他方へコピーする方式
  • マーク&スイープ方式
    • オブジェクトをすべて見て、要らないものを捨てる
    • GCが遅く領域が断片化。領域を探すのが遅い
  • 並列の実現
    • サイズごとに領域がたくさんある
  • 新世代と旧世代に分類
    • 3回生き残ると旧世代に移す
    • 世代別仮説 : 旧世代のGCは少なくていい
  • 旧世代のGCは領域が無限に大きくなる。遅い
  • GC をするときに GHC はプログラムを止める
  • (時間切れ)椅子をGCしましょう