📝論文紹介: Software Development Waste(ソフトウェア開発におけるムダ)
ICSE 2017 勉強会のために論文を眺めてたら、リーンソフトウェア開発におけるムダについて調査した論文*1がおもしろそうだったので読んだ。
🐾背景: リーンソフトウェア開発
Womackはトヨタ生産方式を分析し、リーン思考を提案した*2。これは、「資源を消費し、価値を生まない活動」であるムダ(waste)の発見と除去を基本原則する。
リーンソフトウェア開発は、リーン思考とトヨタ生産方式をソフトウェア開発に適用した手法である。 リーンソフトウェア開発ではムダとして以下のものが挙げている。*3
トヨタ生産方式におけるムダ | リーンソフトウェア開発におけるムダ |
---|---|
在庫 | 未完成の作業 |
加工しすぎ | 再学習 |
作りすぎ | 使われないコードや余分な機能 |
物の運搬 | 作業の引き継ぎ |
手待ち | 開発の遅れ |
人の動作 | 作業の切り替え |
不良・手直し | 欠陥 |
価値 | なし |
活用されない才能 | なし |
しかし、ここでムダとされるものが妥当かを検証した研究はない。
🎯目的: ムダの発見
リーンソフトウェア開発には、どのような種類のムダが存在するかを調べる。
🔬調査方法: Pivotalにおける調査
Pivotalで行なわれたソフトウェア開発を対象とし、グラウンデッド・セオリーを構築した。
以下の3つの方法で、データを収集した。
- Pivotal Labのプロジェクトに参加し、観察した。 2年と5ヶ月間をかけて8個のプロジェクトに参加した。
- Pivotalの社員33人にインタビューを行なった。これにはソフトウェアエンジニア、インタラクションデザイナー、プロダクトマネージャが含まれる。
- レトロスペクティブ(ふりかえり)のトピックを分析した。 1年間の間に行なわれた91のミーティングを対象とした。
📊発見した9種類のムダ
調査の結果、9種類のムダを発見した。
誤った機能や製品の作成
誰も必要としない機能や製品を作ると、参加している全員の時間や労力が無駄になる。 これは、チームの士気やオーナーシップ、顧客満足度に影響する。
調査したプロジェクトにあった実例:
- ペルソナにもとづいて開発をしたが、その後の調査でペルソナがあやまっていることがわかった。
- マーケティングのために、ユーザの必要としない機能を追加した。
バックログ管理の失敗
プロダクトバックログの管理を失敗すると、プロジェクトの遅延や生産性の低下につながる。
調査したプロジェクトにあった実例:
- 一度に複数の作業を進めることを優先したため、最初のリリースでは一部の作業が未完了のままだった。その機能は無効化されてリリースされた。
- ビジネス側の要求に応じてユーザ登録プロセスを何度も変更したため遅延した。
- プロダクトマネージャーが変更をくり返したため遅延した。
作業のやり直し
作業の遣り直しがムダなのは自明である。 これは以下の原因で発生する。
- 技術負債。調査したプロジェクトの中には、リリース日を優先したため、リリース後に数週間にわたるやり直しが必要になったものがあった。
- 作業中における欠陥の発。 調査したプロジェクトの中には、いくつかの画面を作ったのちに、モバイル対応が必要であることが発覚したものがあった。
- ストーリーの拒否。実装が不十分のために、プロダクトマネージャーが受け入れを拒否することがある。
- 完了条件が不明瞭なストーリー。調査したプロジェクトの中には、開発者が実装を完了したのち、ストーリーとモックアップにインタラクションが不足していることが判明したものがあった。
不必要に複雑な解決策
機能が不必要に複雑だと、ユーザの時間を浪費する。
調査したプロジェクトにあった実例:
- 操作フローが、一部画面では左から右になっているのに、別の画面では上から下になっていた。
- 複数のインタラクションデザイナーがいるため、レイアウト、リスト、警告、ボタンなどが複数作られた。
- インタラクションデザイナーが2種類のフォームデザインを作ったために、複数のCSSが必要になった。
- 顧客側の開発者が「複雑であればあるほど、重要な仕事をしていると実感できるのでよい」という態度でいることに開発者が不満をもらした。
本質でない認知負荷
認知負荷理論(Cognitive Load Theory)は、人間の作業記憶には限りがあるため、負荷が多すぎると学習や問題解決が阻害されるとしている。本質的な認知負荷とは、タスクをこなす上で避けられないものを指す。 一方で本質的でない認知負荷とは周囲の環境などに追加されるものを指す。*4
ソフトウェア開発には認知負荷が高いもの多いため、開発者の思考力は貴重な資源である。そのため、本質でない認知負荷はムダであるとみなす。 これは以下の原因がある。
- 過度に複雑なストーリー。不必要に長く複雑で不明瞭なストーリーは開発者の作業記憶を消費してしまう。
- 非効率なツール。 機能不足だったり複雑なライブラリや貧弱な開発環境、貧弱な開発プロセスなども含む。
- 技術負債。 技術負債はコードの理解や変更を難しくする。 調査したプロジェクトの中には、テストスイートを実行すると大量の警告が出力され重要な情報が埋もれてしまうものがあった。
- マルチタスク。複数のタスクを同時にやろうとすると、作業記憶に多数の情報を保持する必要があるため、認知負荷が増加する。
精神的苦痛
精神的苦痛は貴重なリソースである開発者を消費してしまう。 精神的苦痛は生産性の低下や燃え尽き症候群や欠勤、健康問題などにつながる。
調査したプロジェクトの中には、機能とリリース日が変更不能なプロジェクトがあった。 このプロジェクトでは、チームの士気や一体感が低下したり、メンバー間の問題解決に時間がかかった。
待機/マルチタスク
優先度の高い機能に着手できない場合、開発者は待ったり、優先度の低い機能に着手してしまう。 これはプロジェクトの遅延につながる。
調査したプロジェクトにあった実例:
- 受け入れ環境が不安定だったため、プロダクトマネージャーが受け入れ作業を放置して別の作業を始めた。
- ビデオ会議設備が不足しており待ちが発生した。
- テストの実行に17分かかるため、開発者が別の作業をはじめてしまった。
知識の損失
知識の損失は、特定の知識をもったチーメメンバーがいなくなったときに発生する。 そして失なわれた知識を再獲得が必要になってしまう。
調査したプロジェクトの中には、全メンバーが入れ替わったプロジェクトがあった。 システムの理解に数ヶ月かかり、その間のベロシティはほぼ0になった。
非効率なコミュニケーション
非効率なコミュニケーションは不完全だったり誤解を産むコミュニケーションである。 チームの規模や非同期コミュニケーション、非対称なコミュニケーションが増えると、チームの生産性が低下する。
調査したプロジェクトにあった実例:
- 移動に一時間かかるオフィスにチームが分割された。 リモートコミュニケーションを活用したが、次第にレトロスペクティブで議題にのぼるようになっていった。
- ミーティングを特定の人が支配し、おとなしい人が意見を言えないようになった。
- iOSチームが自身のプロセスにチームの決定をうまく反映できなかった。レトロスペクティブを繰替えすことで改善した。
🔁既存のリーンソフトウェア開発におけるムダとの比較
リーンソフトウェア開発のムダとされているものとは、以下の違いがあった。
- 「引き継ぎのムダ」とされるものは観察できなかった。
- 新規で 「不必要に複雑な解決策」「本質でない認知負荷」「精神的苦痛」「非効率なコミュニケーション」の4つを観察した。
- それ以外は類似のものがあった。
まとめ
この論文ではソフトウェア開発におけるムダとその原因をエビデンスに基づいて示した。 そのために2年と5ヶ月をかけてデータを集め、グラウンデッド・セオリーを構築した。
その結果、既存のリーンソフトウェア開発におけるムダは支持されたが、いくつかの点で異なっていた。新規で4つ導入した一方、引き継ぎのムダは支持できなかった。
*1:Todd Sedano, Paul Ralph, and Cécile Péraire. 2017. Software development waste. In Proceedings of the 39th International Conference on Software Engineering (ICSE ‘17). IEEE Press, Piscataway, NJ, USA, 130-140. DOI: https://doi.org/10.1109/ICSE.2017.20
*2:J. P. Womack and D. T. Jones, Lean thinking: banish waste and create wealth in your corporation. Simon and Schuster, 1996.
*3:TABLE II: Comparison of Manufacturing Waste with Lean Software Development Wasteより引用
*4:http://miwalab.cog.human.nagoya-u.ac.jp/database/resume/2016-10-25.pdf を参考にした
🎤発表資料
勉強会の発表資料を作る際に気をつけていること。 最近だと📝The reason for using reason #ML_study - みずぴー日記を作った。
関係ない話は削る
発表で言いたいことがぼやけてしまうので、余分な話はしないようにしている。
自己紹介をいれると発表のテーマと違う話をすることになってしまうので、省略している。だいたいは「こんにちは、mzpです」くらいで済ませてる。
話の流れを整理するために事前に発表原稿を作っている。 何度か読み直して余分な話を削っている。 発表後は、このときの原稿をブログに貼り付けて、記事にしている。
導入は丁寧にする
「なぜこの技術が必要なのか」「なぜこの技術が登場したのか」といった動機の説明が不十分だと魅力がうまく伝わらないので、ここに時間を割く。
原稿や資料を作る際もここに時間をかけている。
「背景」→「困っていること/欠点」→「解決策」というストーリーにすることが多い。
後ろの席からも見やすいスライドにする
会場の形状によっては、前の席の人の頭でスライドの下のほうが隠れてしまうことがある。なので、文字を大きくしつつ、スライドの下のほうには空にするか補助情報だけを書くようにしている。
色を減らす
会場の明さやプロジェクターの性能によっては細かい色の区別がつけれないことがある。
なので、できるだけ使う色の種類は減らしている。地の文である黒と、強調したい部分を示す赤色系くらいにしている。
その他好み
凝ったテーマを使うことに気恥かしさを感じるので、KeynoteのWhiteテーマ(白い背景に黒い文字)を使っている。 タイトルの位置や文字のサイズなどは変更している。
明朝体が好きなのでスライドに使ってる。堅苦しい雰囲気がでてしまうが、みんなそこまで気にしないだろと思って、好みを優先させている。
📝The reason for using reason #ML_study
ML勉強会 #2で話した。
要約
近年のJavaScriptは進化が激しく、様々な拡張が提案されている。その中にはMLの機能を類似したものも多数ある。例えば、オブジェクトとレコード型のように使えるようにする拡張やパターンマッチを導入する拡張といったものが提案されている。
しかし既存の言語にMLを意識した機能を追加するのは簡単ではない。
そこでFacebookのReasonそこでOCamlをJavaScriptに近づける、というアプローチを採用してる。具体的には文法をJavaScriptに近づけたり、周辺ツールの整備を行なっている。
JavaScriptの必要性
Misoca
ボクはMisocaという請求書を管理するWebサービスを作る仕事をしている。今日の交通費も出してもらった。ありがとう!
React/Redux
Webサービスを作るには、JavaScriptを扱う必要がある。
JavaScirptフレームワークは数多く存在しているが、そのうち有力なものの一つにReactとReduxがある。 Misocaでも採用している。
React
Reactはview、要はHTMLを構築するライブラリである。 今回の話とはあまり関係がないので、詳細は省略する。
Redux
ReduxはJavaScriptプリケーションの状態を管理するためのライブラリである。 以下のような型を持つ関数によって状態を遷移を管理する。
state -> action -> state
state
はその名のとおりアプリケーションの状態であり、action
はなんらかの操作を表す。 そしてこの関数はreducerと呼ばれます。 名前が一般的すぎますね。
Reduxの話はちょっとしたいので、reducerの例をいくつか見ていきます。
例: counter reducer
数を数えるreducerは上記のように定義できる。 アクションの種類(type)が INCREMENTAL
なら1を足す、 DECREMENT
なら1を引く、そうでない場合はそのままの値を返すようになっている。
これでカウンターの値という状態を管理する。
例: todo reducer
もうちょっとアプリケーションっぽいreducerも紹介する。 TODOの完了状態を切り替えるreducerは上記のように定義できる。
各項目は、固有のIDと項目の名前、完了したかどうかなどと項目として持っている。 アクションは種類をあらわすtypeフィールドに加えて、どの項目の完了状態を切り替えるかどうかを示すidフィールドを持つ。
そしてこのreducerはアクションが TOGGLE
のときは、idを確認する。 そして、idが一致したら完了状態のだけを反転させた新しい状態を作って返す。
reducer idiom
このtodo reducerはreducerでよく使われるイディオムが2つ登場している。
1つ目は TOGGLE
で使った「typeがxのとき、yという項目を持つ」である。これは、OCamlのヴァリアント型と似ている。
次は完了状態の切り替えで使っていた「状態をコピーし、一部だけ更新する」である。これはOCamlのレコードの更新と似ている。
ML由来の機能
このように最近のJavaScriptにはML系から様々な機能が輸入されている/されようとしている。
他に導入されているもしくは導入が提案されている機能としては
などがある。
more ML features
これらの機能を実現するために各種ツールを利用する。 例えば拡張されたJavaScriptからブラウザで動くJavaScriptを生成するためのBabelだとか、JavaScriptに静的な型検査を導入するflowなどを使う。
OCaml
あーあ、こんなときにバリアント/レコード型があって、パターンマッチがあって、静的型検査があってJavaScriptが生成できる言語があればなー。あー。
あっOCamlでいいじゃん。あってよかった。じゃあ使いましょう。 便利。 めでたし、めでたし。
JavaScriptとOCamlのギャップ
これで終われる世界はだいぶ幸せだが、そうもいかない。
JavaScriptとOCamlの間には大きなギャップが存在している。 それは文法だったり、ツールの使い方だったりする。
これReasonの紹介スライドにあった画像だが、途方にくれてる感があって最高だと思う。
OCamlのJavaScript化
しかしJavaScriptにMLの機能を導入するよりも、文法やツールを追加してOCamlをJavaScriptに近づけるほうが楽そうである。 少なくともReasonの開発チームはそう考えている。
Reasonがやっていること
ではReasonがJavaScriptプログラマに使いやすくするためにやっていることについて話していく。
BuckleScriptとの連携
OCamlをJavaScriptを出力できるように、BuckleScriptというOCamlからJavaScriptを生成するコンパイラと連携している。
上記の通り、BuckleScriptは人間にもかなり読みやすいコードを生成する。
人間に読みやすいコード
「人間にもかなり読みやすいコード」というのをBuckleScriptはかなり重視している。 これはREADMEにのってる例ですが、自動生成したとは思えないコードになっている。
中間言語であるlambdaからJavaScriptを生成しているこれができる、バイトコードから変換しているjs_of_ocamlとの重要な違いだ、とマニュアルに書いてあった。
余談: OCamlの魅力
BuckleScriptの資料が「なぜJavaScriptを使うか」という疑問に対しては、ブラウザで動く言語で…とかいろんな場所で動いて…とかいろいろと説明している一方、「なぜOCamlなのか」という疑問に対しては「もうしってるでしょ」ですませていた。格好いいと思う。
文法: 変数束縛
次は文法についてです。 JavaScriptの雰囲気にあうように文法が変更されている。
例えば変数束縛はletのあとのinをつけなっているし、行末には ; をつけるようになっている。
文法: 条件分岐
条件分岐も中括弧で範囲を示すようになっている。
文法: パターンマッチ
パターンマッチはmatchからswitchにキーワードが変更になっている。中括弧を明示してるのでネストしてもややこしくならない!ってマニュアルに書いてあった。
パッケージマネージャ
パッケージマネージャーはJavaScriptのnpmをそのまま使っている。 Reason自体も各種ライブラリのバインディングもnpm経由でインストールできる。普段と同じパッケージマネージャが使えるので、JavaScript使いには親切になっている。
が、npm install bs-platformするとOCamlのダウンロードとビルドがはじまるのはアツいと思う。
コード補完: Merlin
いくつかの周辺ツールも用意されている。 OCamlの補完ツールであるmerlinはそのまま使える。
エディタ拡張
各種エディタの拡張も用意されている。 Reasonはコードフォーマッタもあるので、それもエディタから使えるようになっている。
BeterErrors
既存のOCaml toolchainのラッパーもある。
例えばBetterErrorsはコンパイラのエラーを整形し、 式のどの部分で型を間違えているかをわかりやすく表示する。 エラーメッセージの整形をしているだけなので、既存のコンパイラとパイプとつないで使うことができる。
RED
またocamldebugの使い勝手を改善するREDというツールもある。
余談: Reasonという名前
気付いてると思うが、Reasonという名前は検索しづらい。というかFacebookのだしてるライブラリはflowだとかinferだとか検索しにくい名前ばかりである。
Reasonという名前のせいで、exampleの名前がおもしろくなっている。 ライフゲームが実装されたイグザンプルのプロジェクト名がreason-of-lifeなのは最高だと思う。
Reasonの利用例
Reasonがどのあたりで使われているかの話をします。
Facebook Messanger
具体的にどの部分かは分かりませんがFacebookメッセンジャーの25%はReasonに書き換えられているらしい。このTweetには書いてないですが、ブラウザ版の話らしい。
React
Reactのプロトタイピングにも使われている。 JSXをサポートしてたりと、やたらReactのサポートが厚いのが気になっていたんですが、このためかもしれない。
Trello.md
ボクもReasonつかって、Chrome拡張を書いた。Chrome拡張のバンディングは存在してなかったので、必要な部分だけ自分で書いた。
Reasonのよい面
パターンマッチ最高
予想通りですがパターンマッチ+レコード更新の組み合わせは最高だった。 「各アクションのパラメータが型で保証される」「返り値の構造が変わっていないことが型で保証される」「すべての分岐を網羅していることをコンパイラが保証してくれる」というあたりがよい。
ビルド速度
BuckleScriptはOCamlのLambdaIRを変換した上で、末尾呼び出しの除去や定数畳み込み、インライン化などの最適化をなった上で、JavaScriptを生成する。 一見時間がかかりそうに見えるが、JavaScriptにしたあとの処理のほうが遅いので、あまり気にならなかった。
無
JavaScriptにはnullやundefinedみたいな「無」みたいな値がある。 これをfunctional扱えるようなモジュールが用意されている。
sがnullでない場合のみ内容を出力する関数、sがundefinedの場合のみ内容を出力する関数は上記のようになる。
callback hell
JavaScriptでは通信はコールバックで書く必要がある。それはいわゆるcallback hellを招く。このコードはPHPですが。
OCamlには非同期モナド(lwt)があるので、これを利用して >>=
によるチェーンで書ける。 これは DelayedInc
が発行されるのをまち、その後1000ms秒待ち、 Inc
を送信しています。
Reasonのつらい面
次はつらい側面について話す。
インストール時間の増加
ReasonはOCamlコンパイラをforkして作っている。 そのため、インストール時にOCamlのビルドが必要になる。
そのため別マシンに移ったときなどにOCamlのビルドが毎回走ってしまう。CI上でOCamlのビルドが毎回はしるのでつらい。
大量の型定義
JavaScriptライブラリを使う箇所では、大量の型定義が必要になる。こんな感じの定義が延々と続くことになる。つらい。
JSON
JSONから情報を取得するのも大変で、一段ネストをすすめるためにパターンマッチが必要になる。
バリアントのランタイム表現
先ほど話した通りパターンマッチとバリアントの組み合わせは便利。
しかし、ランタイムではバリアントの名前が失なわれるため、デバッグがつらい。多相バリアントにするともっと難しくなる。
よくわかってない部分
Reasonに関してよくわかってない箇所の話をしていく。
vimハイライト
vimのプラグインも準備されいるが、 キーワードのハイライトがおかしい。 たとえば when
はキーワードだがハイライトされない。一方で普通の識別子である box
はハイライトされる。
プラグインのソースコードを読むとforked from rustと書いてあり、ハイライトがおかしい原因は分かる。 が、なんでそのままになっているか分からない。
JSCaml
JSCamlはFacebookが出しているJavaScriptをOCamlに変換するコンパイラである。 念のためにもう一度いいますが、JavaScriptをOCamlに変換するコンパイラである。
READMEに「ReasonでJavaScriptライブラリを使いたいときに、いったんJavaScriptにすると便利」とか「貧弱なデバイスでJavaScriptを実行したいときに便利」と書いてある。なんなんだ。
esy
ReasonはJavaScriptのパッケージマネージャーnpmをそのまま利用している。 しかし、Reason/OCamlのようなビルドが必要な言語との相性はあまりよくない。
そこで、yarnをforkし、ソースコードの取得とビルドを明確に区別できるようにしたesyが開発されている。
opamブリッジ
またopamとのブリッジも用意されているので、npmのライブラリもopamのライブラリもインストールできる。そのため、npmのレポジトリに大量のopamのライブラリが登録されている。
迫力がある。
参考文献
この資料を作成するにあたって参考にしたものをあげておきます。
- awesome-reason。reasonの各種資料へのリンク集。ツールや発表資料へのリンクがある。
- Dawn of Reason。 途中で何度か図を引用してます。OCamlをJavaScriptに近づければいいんだ!!という話が書いてあった。
- Reason guide。reasonの文法などはここに書いてあったり書いてなかったりする。書いてないやつはOCamlからの連想でなんとかなる。
- Bucklescript manual。 BuckleScript部分、つまりJavaScriptとの連携部分のマニュアル。が、文法はOCamlなのでReasonで使えたり使えなかったりする。
まとめ
- JavaScriptにはMLの機能が必要で、どんどん導入されている。
- でも大変なので、OCamlを使ったほうがいい。
- そのままだと大変なので周辺環境を整備したのがReason
以上です。
✈️北海道ワーク
先週一週間は北海道の旭川で過した。 長期休暇を取ったわけではなく、昼間はリモートで勤務をした上で夕方から観光していた。
🏠宿
有給消化中の友人と一緒にAirbnbで部屋を借りた。 1週間でたいだい6万円くらい。
調理器具がついてたので、近所のスーパーで買ってきた魚やジンギスカンを焼いて食べていた。 焼くだけでだいたいうまい。
🏢リモートワーク
部屋についているWifiで仕事をしていた。通信速度などが不安だったが、問題なかった。念のため、市内のコワーキングスペースの場所を確認しておいたが、必要なかった。
普段通り仕事をしていたので、北海道にいることは気づかれなかった。 途中でTwitter経由でバレた。
普通にミーティング一緒にしてたけど北海道にいるって気がついてなかったです。好きそうな仕事があったのにオフィスに来ないから、なんかアップル製品の予約とかで忙しいのかなと思ってた。
— とよし / Misoca (@toyoshi) 2017年6月13日
👣市内観光
早めに仕事を開始して、17時くらいには仕事を終わらせ、その後、市内の観光をしていた。
「櫻子さんの足下には死体が埋まっている」は旭川が舞台なので、市内の登場した場所にいくつか行った。びーとるのたびにっき 『櫻子さんの足下には死体が埋まっている』(TVアニメ版その①)~北海道・旭川エリア(旭川市・当麻町・美瑛町)~【舞台探訪(聖地巡礼)】がバスでの行き方も記載してあり、便利だった。
手。
街中に急に手がでてくるので、びっくりする。🙌。
ロータリー
ティーハウス ライフ・ラプサン
サイトによって日本最北の紅茶専門店と書いてあったり書いてなかったりする。 よく分からない。
シフォンケーキが登場していたので食べた。
ダンデリオン
ケーキ屋。ちょっと離れた場所にあるので、バスでは行けなかった。 レンタカーを借りた日に行った。
かぼちゃのモンブランが登場していたが、時期が違うらしく売っていなかった。モンブランは売り切れていた。
🍽食事
何を食べてもおいしかった。
うに
駅前のイオンで塩水うにが1500円くらいで売っていたので買った。 めっちゃうまい。
寿司
寿司は文句なしにうまい。
旭川ラーメン
旭川ラーメンも何店舗か食べにいった。
ぞい。
みそバターラーメンには、バターが予想の倍くらい入ってる。
地ビール
地ビールが何種類があるらしいので、飲みにいった。翌日寝坊すると飛行機に乗れなくなるという状況で飲むビールは、スリリングだった。
4種飲み比べセットを頼んだら、なぜか5種類でてきた。
🚗観光
週末+有給で周囲を観光した。
旭山動物園
一度行ったことがあるので、そこまで感動しないかなーと思ってたけど、すごかった。迫力がすごい。
青い池
macOSの壁紙になっている青い池を見にいった。 時期と時間が違うので、壁紙とはだいぶ印象が違うけどキレいだった。 次は冬に行きたい。
向う道はひたすらまっすぐだった。
カーナビが「このまま道なりです」と言ったあと無言になった
— mzp (@mzp) 2017年6月17日
富良野
青い池のあとは富良野に行った。 広大な土地に花が整然と植えてあるのは独特の迫力がある。
✨感想
知らない街を散歩したり、地元の名物を食べるのが好きなので、働きながらしばらく滞在できるのはよかった。Airbnbブログで掲げられている「暮すように旅をしよう」はだいぶ好みにあっている。
ホテルに泊まるのに比べて自炊の割合が増えるのが心配だったか、スーパーで買ってきた何かを焼けばおいしくなるので問題はなかった。北海道だからな気はしている。
とはいえ、自宅に比べるとモニタの数が不足していたり、ネットワーク環境もそれほどよくなかったりと、めっちゃ作業が捗るという感じではなかった。
総合的によい体験だったのでまた行きたい。
📋Trello.md
TrelloボードをMarkdownに変換してクリップボードに書き込むChrome拡張を作った。
ボードの例
📦インストール
Trelloのボードを開いた上で画面右上のアイコンをクリックすると、Markdown化されたボードの内容がクリップボードに書き込まれる。
💞動機
ふりかえりのKPTを書くのにTrelloを使っていると、内容のスナップショットを保存したいことがある。 その際、ボードの内容をMarkdownに変換してesaなどに保存すると便利である。
この用途のためにYusukeKokubo/trello2md: Export Trello Cards to Markdown formatというのがあるが、CLIツールで若干起動が面倒だったのでChrome拡張にした。
✨Reason
ソースコードはhttps://github.com/mzp/trello.md/にある。
見ると分かるが、実装はReason + Bucklescriptで行なった。 ソースコードの割合をみても大半がOCamlになっている。
JavaScriptのような文法
Dawn of reasonにあるようにReasonはJavaScriptに文法を寄せようとしているらしい。
実際、いくつかの箇所でそのようになっていた。 例えば、OCaml(Bucklescript)ではレコードの構築、オブジェクトの構築、JSONの構築はすべて違う文法で行なうが、Reasonでは見た目を似せようとしていた。
// レコードの構築 let x = { x : 0, y : 1 }; // オブジェクト < x : int, y : int> の構築 let x = {. x: 0, y: 1 }; // JSON(Js.Json.t)の構築 let x = { "x": 0, "y":: 1 };
ただすべての行末に ;
をつける制約はなくてもよかったんじゃないかな、とは思う。
Chromeバインディング
ChromeのAPIに対するバインディングは必要な分だけ、自分で定義した。
わりと自然に書けた気がするがやはり大変。
module Tabs = { type tab = Js.t { . url : Js.Null.t string, id : int }; module OnUpdated = { external add_listener: (int => unit => tab => unit) => unit = "addListener" [@@bs.val] [@@bs.scope ("chrome", "tabs", "onUpdated")]; } };
vim-reason
https://github.com/reasonml/vim-reasonをいれたが、なぜか一部のキーワードがハイライトされなかった。
syntax fileを見てみたら “Forked from Rust” と書いてあり、 box
などがキーワード扱いされてておもしろかった。
その他所感
🔀bs-lwt
BuckleScriptで非同期処理を書きたかったので、Lwtのバインディングを作った。 たぶんReasonからも使えると思う。
🙅 制限
Lwtの一部はUnixモジュールなどに依存しているのでBuckleScriptからは使えない。 なのでコア部分(src/core
以下にあるモジュール)のみを使えるようにした。
利用できるモジュールの一覧はREADMEに書いてある。
🎯動機
BuckleScriptでredux-sagaみたいなのが作りたかった。 そこで、redux-sagaのソースコードを読んでみたところ、タスクスケジューラを実装していることが分かった。
タスクスケジューラを再実装するのは大変なので、軽量スレッドのライブラリであるLwtのバインディングを作った。
「redux-sagaみたいなの」は今のところ ripple_task.mli みたいになっている。 Lwt_list.map_s
のような関数で合成できるので、ジェネレータで実装したタスクより使いやすい気がしている。
😵大変だった箇所
submodule
最初、Lwtのソースコードはgit submoduleを使ってレポジトリに追加していた。 npmはsubmoduleに対応してるのでしばらくはうまくいっていたが、途中でyarnが対応していないことに気がついた。
これ踏んだ https://t.co/rOHWjNlOCQ
— mzp (@mzp) 2017年5月14日
しょうがないので、ソースコードをレポジトリに直接追加した。
バージョン番号
Lwtのバージョンとバンディングのバージョンの対応を考えるのが大変そうだったので、この2つを一致させるルールにした。
そしたら今度はバンディングのビルド方法を修正したときにバージョンをあげる方法がなくなってしまった。 試しに v3.0.0.1 みたいに4桁目を使ってみたが、semverではなくなりインストールできなくなってしまった。
postinstall
最初は、bucklescript-addons/bs-mochaを参考に、postinstall
ででライブラリをビルドするようにしていた。
が、ReasonのDiscordで聞いてみたら、
postinstall
でビルドするのは古いスタイルで、今はなにもする必要はない- ライブラリを利用するプロジェクトが
bsb -make-world
すれば、依存ライブラリもビルドされる - 出力するモジュールの種類を後で変更できるので、このほうが柔軟である
とのことだったので、消した。
BuckleScriptの依存関係解決がよくわかんなくてreasonmlのdiscordで聞いてた
— mzp (@mzp) 2017年5月28日
質問すると即レスくるんだけど、どうなってんの...
— mzp (@mzp) 2017年5月28日
💞所感
githubにpushだけしておいたら、Discordで晒されてて勢いを感じた。 typoを修正するプルリクエストも来た。
🌴沖縄
地域を変えれば花粉症が軽減するのがどうかに興味があったので沖縄にいってきた。 沖縄は梅雨の時期だということは出発前日まで気づいてなかった。
🌊座間見
とまりんに行ったら、ちょうど座間見行きのフェリーがでてたので乗った。1年前に来たときは海が荒れてて乗れなかったけど、今回は乗れた。
今日のる予定だった離島便の状況です。 pic.twitter.com/8J3B8ptpAJ
— mzp (@mzp) 2016年3月10日
何も計画せずに行ったら、レンタカー屋が閉まってた。 「もしかして事前に予約しないとオープンしないタイプの店では????」という話をしてたが、真偽は分からない。
しょうがないので、徒歩でいける砂浜に移動した。
港から砂浜の間は山道になっている。
海。
どうしようもないので寝転がって時間を潰す。
暇すぎて動画を作ってた。
🔦鍾乳洞
別の日は玉泉洞を見にいった。
鍾乳洞みたいなーという軽い気持ちではいったら、かなりの距離を歩いて大変だった。 今しらべたら890メートルあるらしい。わりとじめじめしてるし、圧迫感のある中を歩くのは大変だった。
キレいだけど、青いライトアップをして青い泉と名乗るのはどうかと思う。
あと終盤電波が届かないことにつらみを感じつづけていた。
☕️コーヒー
うわさの泡盛コーヒーは買った。 あとで飲もうと思ってホテルの冷蔵庫で冷してたら、そのまま忘れてきたので飲めていない。
ノンアルコールのコーヒーはスタバで飲んだ。
🌡気温
ちょうど名古屋に夏日が来てる時期だったので、沖縄のほうが涼しかった。
あと名古屋の気温が、沖縄より高いらしく帰りたくない
— mzp (@mzp) 2017年5月22日
🍴食事
写真を見たら肉ばっかりだった。
座間見で食べたたラフテー。これを食べてる間にレンタカー屋が閉まったという説もある。
ステーキ。
唯一あった肉じゃない写真。オジサン(魚の名前らしい)を塩で煮たやつ。
行きたかったけど満員で入れなかったところ。2000円で飲み放題、食べ放題はちょっとおかしいと思う。
✨まとめ
そういえば、現状報告ですが、沖縄来ましたが花粉症はそこまで改善してません。ボクはイネ花粉症です。
— mzp (@mzp) 2017年5月21日
これで劇的に改善したら来年からこの時期は沖縄にいるつもりだったんだけどな、、、
— mzp (@mzp) 2017年5月21日