完全に自分用のメモです。
前日のTrainingDayよりさらに付いて行くのにやっとの状態だったのでだいぶ雑なメモになってますがご容赦ください。
量子コンピュータをScalaでかわいくシミュレーションしてみよう
- 量子計算は複素行列が肝
- まずはcase classを使って複素数型を実装
- 量子ゲートの複素行列計算をしようとすると簡単にOutOfMemoryになってしまう。。。
- Mapを使ってメモリを節約できる!
- 型レベル自然数。0から再起的に構築する。
- クロネッカー積はサイズが決まってないといけない。
- Pipeline演算子を使って計算順序を逆転させる
関数型プログラミングによるパフォーマンス
-
メモリアクセスパターンによって処理速度は異なる
-
Access Pattern Benchmark
- sequential > randomPage > dependentRandomPage > randomHeap > dependentRandomHeap
- 〜90ns/op
-
r = s(2 -p) / 2(1 - p)
- 待ち行列理論の式
-
system engeneering
- messaging
- concurrent distributed network & protocol
- Skiplists, Trees, Scoreboards -> pointer chasing hell
- ポインタを追いかけるのはうんざり
-
ソーセージの中身の肉の質はピンキリ。
-
関数型のデータ構造もソーセージのようなもの
- CRDTs
- Commutative Replicated Data Types
- Operations are replicated
- e.g. Add 10 to value, or -10
- Convergent Replicated Data Types
-
Log Buffer
- CRDTの構造が得られるようなデータが欲しい
- メモリにファイル酵素像を取り、操作のたびにTailを動かす
- Concurrent Publication?
- Log Buffer (ファイル) は適当に切り替えることでページがいっぱいになってもブロックしないようにしましょうという話。
-
状態をどう把握するか?
- Publishers, Senders, Receivers, and Subscribers
-
Shared Mutable State is Evil?
* https://github.com/real-logic/aeron
仕事で役立つモナド変換子
- WHAT & WHY
-
Functor(関手)
-
Futureのlistにどうmapするか
-
flatten * map = flatMap
-
Future[List] に対して1回のmapで済ますためにFunctorを定義する話と、map後にネストしたリストをflattenするためにflatMapが出てくる話
-
モナドは逐次実行を可能とする
-
モナドは
F[F[A]]
をF[A]
につぶすことができる -
Functorは合成できるけど、モナドは一般的に合成できない。モナドを合成してモナドを作ることはできない
-
FutureとOptionをいかにして合成するか -> FutOpt
-
合成したいモナドの型が具体的にわかっていれば個別に実装することで合成可能になる
-
その「特定のモナド」のための型を作る必要が有る。case classでFutOpt[X]を定義して implicit valでFutOptのpure, map, flatMapなどを定義する。同じようにlistOptのようなものを考えると、パターンが見えてくる。
-
OptionTはscala.Option のモナドトランスフォーマー。
-
OptionTはモナドトランスフォーマ。OptionT[Future, String] とすればFuture[Option[String]]のflatMapを手に入れる事ができる。
-
より一般化すると、Foo[Bar[X]]はBarT[Foo, X]となる。
-
MonadTransformerは特定のことには長けているが、苦手もある
-
EitherT[F[_], A, B]
-
Tips
- 2つ以上のモナドを積み上げると辛くなる。
- モナド変換しはAPIに出さないようにする。ラッピングして共有しないようにする。
- 重いコードなので性能を機にするならベンチマークを取る
- 局所的な最適化に用いる
-
EFF (extensible effects)
-
もしScala初心者がMonoidを投げ込まれたら
-
Scala歴6ヶ月。去年の10月よりf-codeにジョイン。
-
OSS cafebabepy (python implementation on jvm)
-
まず初見で困惑。新しい概念と出会った時どう戦っていくか。
-
目的は新しい概念を取り入れ適切に使うこと
-
そのために定期的な勉強会による地道なスキルアップや、チームメンバのスキルレベルのすり合わせを行った。
Scalaでの部分的な関数型プログラミング
-
純粋関数(副作用のない関数)だけでプログラムを組み立てることで、テストしやすいなどの恩恵を得られる
-
非純粋ライブラリに依存しているなど、現実的には全てを純粋関数でやることは難しい
-
Easy
- val, immutable
-
Hard...
- IO, FREE
-
Basic Strategy
- printlnなどの副作用を見つける
- 2 layers appeared
- 副作用のない部分を関数として切り出す(PurelyLayer) # M3ではパッケージを部活して運用している
- Effectful layer
- DB Access
- IO
- 切り出したpure layerは、核となるビジネスルール(ロジック)とみなせる
- Effectful layer -> pure layerと依存性を一方向に保つ
Recursive Schemeを用いた量子アニーリングマシン専用言語(DSL)の開発
- 量子アニーリングベースの量子コンピュータ(D-Wave)向けのScalaによるDSL実装
- 量子アニーリングとは組み合わせ最適化問題を解く確率的アルゴリズムの一種
- ほとんどの離散最適化問題はQUBOで表現できる
- 量子コンピューターを使うには二段階で問題をAQCのハードウェアへ埋め込む
- QUBOを手で作るのはめんどくさく、コードは直感的に理解しにくい
- そのために、最適化問題からQUBOを構築するためのDSLを作成した
- 再帰関数の処理は1)子構造の値の評価、2)親構造がどのように値を束ねるか、の2つに分けられる
- 数式表現をファンクターにすることで、親構造を保ったまま子構造だけ潰していきたい
- Fixによって数式を構築し、catamorphismを最適。
- これで、すべての重要な処理はAlgebraに集約できる。
Haskell VS Scala
-
Scala
- SCAlable LAngage -> Scala
- 基本的にはオブジェクト指向言語
- Javaとの互換性を重視
- Module System
- ML/OOスタイルのモジュールのどちらも使える
- Type Inference
- Haskellに比べるとかなり制限されている
- ローカルな型推論のみをサポートしている
- Monadic Notation
- メソッドチェインのシンタックスシュガー
- Evaluation Strategy
- 正格がデフォルトです
- 注釈がついている引数の評価は遅延される(=> がついた引数)
- Purity
- どのような項も副作用を持つ
- 不必要な副作用は推奨されません
- Type Class
- 型クラスのインスタンスが複数存在できる
-
Haskell
- 非正格関数型プログラミング言語の標準
- 実装はほとんどGHC一択
- 純粋関数型言語。ほぼ副作用を持たない
- Module System
- namespace, import, export
- weaker than modern programing language.
- Type Inference
- Hindley-Milnerを拡張した強力な型推論
- 型推論の完全性はない
- Monadic Notation
- do構文
- Evaluation Strategy
- 非正格がデフォルト
- 実行時に評価
- |-# LANGUAGE Strict #-|を入れると切り替えることができる
- Purity
- どのような項も副作用を持たない
- Type Class
- 型クラスのインスタンスは一つだけ
Haskell + Scala ハイブリッド開発大作戦
-
Etaという言語
- Haskell on JVM(JVM上で動くHaskell)
- Typelead Inc. in indisa
-
Purity in Haskell
- Haskellは難しい?
- スタンダードIO、if-else、forなど全然使えます
- 手続きっぽく書くこともできなくないです
- ScalaではPure/Inpureが型のシグネチャから区別できない
- HaskellはIO型を明示する必要がある(純粋関数型言語)
- IOが型に現れるため、コンパイラがチェック可能
- 副作用が型として見える点で一線を画す
-
Java/Scala interoperation
- Java -> Eta
- Eta -> Java
- 問題になるのは状態の扱いと継承
- 状態への対応方法
- flatMap!
- The Model of States
- Stack[String]
- pop
- push
- を純粋関数で表現
- JavaモナドはJava呼び出しのためのDSL
- レシーバと戻り値の組で型が決まる
- 継承への対応
- GHC Extensions
- GHC specialities.Enabled by special comments.Unavoidable for modern Haskell
- DataKinds
- TypeFamilies(型レベルの関数を定義できるようにする)
- TypeOperators
- GHC specialities.Enabled by special comments.Unavoidable for modern Haskell
- 継承関係を表現するための三つの拡張
- 型レベルプログラミング。。。いい響き。
- カインドは「型の型」
- DataKinds拡張でデータ型を昇格できる
- TypeFamilies拡張を用いた型レベル計算。Extendsの推移性について定義。
- TypeOperators拡張による型演算子の定義
- GHC Extensions
-
Example of hybrid project building
- Eta -> Scala
- デフォルト引数やimplicitなパラメータ・・・
- Annoying!!!(めんどい。。。)
- EtaからScalaのライブリラリを呼ぼうとするとボイラプレートが増えすぎる
- デフォルト引数やimplicitなパラメータ・・・
- ベストプラクティス
- 第一段階:Scala内にEtaを埋め込む
- 第二段階:EtaからJavaを呼ぶ
- Etlas
- ビルドツール
- Eta -> Scala
-
今日から始めるEta
- tour of Eta(すごいHaskellよりやや実践より)
- Japan Haskell User Group
- Slack / Raddit / @Haskell-jp
Scala製システムを3年間運用することで起きた様々なことへの対処
-
はてなのシステム
- perlがいっぱいまだある
-
Mackerelはサーバ監視プラットフォーむ
-
2013/11 に最初のコミット
-
3つ目のコミットで
play new
-
マイクロサービス構成
- API
- Website
- External URL Monitoring
- TSDB
- AWS Crawler
- Azure Crawler
- CloudProvider Integration
- Documents
-
language
- Server(micro service): Scala, Go, Python
- Client(mackerel-agent, plugins): Go
-
PlayFW
- 2.2.1 -> 2.3.1(launched!) -> 2.5.12 -> 2.6(maybe during this year...)
-
3年間の運用で起きたこと
- Play version up
- BoneCP -> HikariCP
- Slick2 -> Slick3(DBIO!)
- blocking-slick!
- Playでカナリアリリースするとバージョン不一致で不思議なエラーが起きた
- バージョン違いでデータの複合化できない問題
- sbt version up
- build.scala -> build.sbt
- over 560 lines
- SBT相談会
- build.scala -> build.sbt
- removed some functions
- rotation of eployees
- 教科書で学び、ペアプロやレビューで慣れてもらう
- これまで10人以上入れ替わっている
- moved the platform Data center to AWS
- Play version up
-
History
- May 8th, 2014 beta release
- May 16th, 2014: mackerel-agent became the open source
- Sep 17th, 2014: upgrading to production releases
- February 2017: Play2.3 -> Play2.4
- August 2017: Infra platform has become AWS
- 2017年10月 ioドメインの不調が起こった。名前解決できない問題が起きた。
- February 2018: Database server has become RDS
リアクティブDDD実践入門
ex) https://github.com/j5ik2o/akka-ddd-cqrs-es-example
-
ChatworkでAkkaを使ったメッセージングシステムを構築
-
Reactive DDD
- Resilient, Responsive, Elastic.
- Akkaを使ってCQRSとイベントソーシングの例を説明します
-
銀行口座をCQRS + Event Soucing
- Domain Modeling
- Customer, BankAccount, Deposit etc...
- RMU => Read Model Updater
- Usecase Analytics
- A customer deposits to his own bank account
- Anotations
- A = Actor
- B = Boundary, 画面
- C Control
- E = Entity, domain model
- A customer refers to transaction histories in his own bank account
- Boundary of Aggregate definition(集約境界の定義)
- BankAccount(Command Side) -> WriteDB -> RMU -> ReadDB -> Dao, Record(Query Side)
- Layered Architecture
* 依存は単方向になるように設計。チャットワークではプロジェクトを分けて循環依存にならないようにしている - Domain object and Aggregate
- Domain Modeling