Runner in the High

技術のことをかくこころみ

ソーラーパフミニが被災したときに便利だった

先日9/9に、千葉県広域で大規模な停電があり、自分の家も約一日にわたって電気が使えない状況になった。我が家は自分とおじいちゃん&おばあちゃんで生活しているが、真夏30度のなか暗闇とともに生活をするのはなかなかにしんどいものがある。

そのときにとても役に立ったのが、このソーラーパフミニという製品で、簡単に言うと折り紙のようにたたんで持ち運び可能&ソーラー発電式可能な発色の優しいウォームライト。

これのいいところは、まず光がすごく優しいので、電球やロウソクと比べて暗闇の中で目が痛くなるようなことがない。それに、停電の際にはあまり火を使いたくない(火災に繋がる危険があり、暗闇で燃え広がると大変な事故になる可能性もある)ので、このような蓄電で動くライトは非常に助かる。

今回、まったく蓄電などの準備していない状態でいきなり使ったのだが、まったく遜色なく動いてくれてすごく助かった。一度しっかりと光の下で充電しておけば、二晩くらいは余裕でもつんじゃないかと思う。

続・最近読んだ太平洋戦争に関する本4選

この記事の続編(?)

izumisy-tech.hatenablog.com

深海の使者

ノンフィクション・ドキュメンタリーの大御所、吉村昭によって描かれる遣独潜水艦作戦のドキュメンタリー。

映画「ダンケルク」を見てから、船乗りから見る潜水艦というのはめちゃくちゃ怖いものなんだというイメージを持っていたが、一方で潜水艦に乗る人間もまた異常な緊張感に晒されながら生きていたということがよく分かる。

読んでいて自分も思わず息を止めてしまうような描写が多い。特に敵の多い海域で数時間も酸素交換せずに連続潜行をしたり、海上駆逐艦をやり過ごすために海底で息を潜めながらもジワジワと艦内の酸素が失われていく描写には、逃げ場のない空間特有の恐ろしさがある。

日本軍兵士―アジア・太平洋戦争の現実

太平洋戦争の日本兵がいかに劣悪な環境および装備で戦っていたかをひたすら紹介する本。

意外な事実だが、当時の日本兵は実際に敵兵に銃で撃たれたりする「戦死」よりも、環境からくる病死のほうが多かった。もちろん、兵士が病気になるということは、太平洋戦線の極限的な環境からは容易に想像できるものだが、ほとんどの場合、兵士に対する処置は場当たり的なものに終止するだけで、何かしらの恒久的対策は取られることがなかった。

戦場での病死意外にも、戦場におけるいじめ、自殺、上層部の混乱、覚せい剤の乱用、などなど様々なテーマで戦争という状況が生み出す地獄が、当時を生き延びた人の証言とともに描かれている。中でも個人的に恐ろしかったのは、海没死の章で紹介されていた水中爆傷。軍医の証言を読むだけでも恐ろしい。

ドキュメント戦艦大和

戦艦大和が撃沈される菊水作戦を描いた、生存者による証言ベースのノンフィクション・ドキュメンタリー。

筆者による描写は連合軍と日本海軍それぞれの記録に基づくものに限られ、それ以外の大半は実際の乗艦者及びパイロットによる記録、証言になっている。この本を読むと、日本海軍のトレードマーク的存在であったはずの戦艦大和が、取り回しのしづらいお荷物的兵器になっていた事実が分かる。まさか大和の最期が片道燃料のみの玉砕戦闘になるとは、作った当時は誰もが想像していなかっただろう。

また、なにより連合軍による爆雷撃が始まったあたりからの描写の激しさがハンパではない。恐ろしいほど細かい戦闘の描写が描かれていて、ただ読んでいるだけでも実際に自分が大和の乗組員にでもなったかのような気持ちになる。しかし、海の上で四方八方から攻撃を受けるというのは、その場にいれば本当に気が気ではなくなるだろう。

ミッドウェー戦記

元海軍軍人の作家、豊田穣によるミッドウェー海戦の戦史物語。ここまでの本の殆どがノンフィクション・ドキュメンタリーであったが、コチラの本はもう少し登場人物のフィクショナリ―感がある。

ミッドウェー海戦といえば前回の記事で紹介した失敗の本質でも触れられる旧日本軍の失敗作戦のひとつとして有名だが、この本ではそのミッドウェー海戦の前後含めてどのように実際の戦いが行われたかが描かれている。日本海軍が空母の艦載機を爆装に切り替えている最中に連合軍機動部隊から急襲を受けるあの混乱具合は、こちらでもしっかり描かれており、読んでいてこの部分に差し掛かるだけでも肝が冷える感覚を味わえる。

しかしながら、若干気になるのはこの本で描かれているもののどこまでが事実で、どこまでがフィクションなのかがいまいちぼんやりしていること。本の中で出てくる登場人物はどれもめちゃくちゃ饒舌だが、よくもまあここまで当時のことを覚えていられるなと。しかし戦争ほど強烈な経験をしたら、そうそう記憶が薄れるということもないのかもしれないが...

"Elm Meetup in Summer" を開催して登壇した

elm-jp.connpass.com

前回Elmのミートアップが最後に行われたのは1年以上前で、運営や会場の関係で長らくこのようなElmを愛する者達の交流会は開かれていなかったが、急遽弊社オヒスの大広間(?)を貸してElmエンジニアたちを集めてワイワイしようという運びとなった。CTOが食事を出す件も快諾してくれ、とても豪華なイベントになったのではないかなと思う。

このイベントに自分は開催前から当日まで大きく関わらせてもらったものの、人がたくさんあつまるイベントをオーガナイズするというのは人生で初めてと言ってもいい経験だった。参加者の方や、登壇者、運営のお手伝いをしてくれた方々には本当に感謝しかない。次回もこのようなミートアップを開催する折には、Elmコミュニティを盛り上げるようなすばらしいイベントにしたいという意気込みがある。

また、当日の盛り上がりはABさんの作ってくれたこのTogetterで見れる togetter.com

コミュニティのメンバ(そもそもメンバという概念はないが)である@y047akaさんがミートアップのためのステッカーを作ってきてくれた。まさかステッカーが作られるとは思ってなかったが、やはりこのような物理のグッズがあるというのはテンションがアガるものだ。

トークについて

自分はElmを最大限学ぶための資料をたくさん紹介する、という体のトークをした。

ちょっとElm界隈に詳しい人なら「そんなの知ってるよ」となってしまうような内容だったかもしれないが、参加者の方からは、少なからず知らないものがあったのでよかったというフィードバックを頂けて、このテーマでよかったなという気持ちになった。

新しい言語を学ぶにあたっては、やはり最初期のオンボーディング体験がすごく重要であると思う。オンボーディングがどのようなものだったかで、主観的な言語へのイメージというのは大きく変わるといってもよい。今回の僕のトークで、Elmに興味のある人たちがより多くのElmリソースに触れるきっかけになれば嬉しい。

なお、登壇資料の中で言及したNoRedInkのリチャードフェルドマンによるカンファレンスでのトークまとめは以下の記事になる。正直、どれも50分程度のキーノートかつ全英語なのでハードルは高いが、電子辞書片手にしても充分に見る価値がある。

izumisy.work

余談

なお、弊社の会場からの眺めが非常に好評でよかった。

晴れた日は夕方とくにキレイで、状況によっては富士山も見える。最高のロケーションだ。

こうして個人的には楽しみな一方で心配も多かったElmミートアップの開催は幕を閉じた。

最初は30-40人程度集まれば充分だな〜と思っていたものが、フタを開けてみると応募の時点で100人超え、当日来場者でも70人ほどの比較的大きなイベントとなった。やはり、同じものが好きな人間同士であつまるイベントというのは楽しいし、イベントを通して様々な学びもあった。

今回のElmミートアップで感じたのは、やはりコミュニティの存在感というのはすごく重要なものであるなということ。Elmのコミュニティには、JavaScriptにはない独特の良さがある。これは自分がelm Europeで感じたのと同じものだし、それを日本でも感じられるというのはすごく幸せなことだ。これからも、少なからずElmという言語、そしてコミュニティに貢献していきたい。そう思えるようなミートアップであった。

労役をする側には前提として作業効率を改善するメリットがない

いくら効率を上げて作業量を減らしたとしても、労働者からすれば、減った分を補う余剰の仕事が増えていくだけ。うれしくなるのは経営者、マネージャ層だけであって、労役側は効率が上がることによるメリットをなにも享受しない。

できるだけ働きたくない

労働をする側が望むのは、ラクな仕事をダラダラやってできるだけ多く遊びの時間を作り、できるだけ早く帰ること。突き詰めれば、どれだけ仕事をせずにお金をもらうか。この点から見ると、効率をあげることで自分の仕事が増えるほうがリスクであり、積極的に効率が低い方式を採用するほうがメリットになる。効率化は労働をする側にとってはデメリットだ。

開発者で言えば、デプロイが遅ければそれを言い訳にコーヒーを飲みに行ったりネットサーフィンをしたりできる(この場合、並列で仕事をするなどの積極的労働はしない)が、これが早くなってしまうと、この「遊び」の時間が少なくなってしまう。デプロイが遅い、という事実が普通*1になれば「今日はデプロイだけの日にしましょう! 時間がかかるので^^;」と説得できる。その日はデプロイだけやって、一日おわり。あとは飲みにでも行って、さっさと帰って家で寝るとしよう。

最も大きな敵は、見返りもなにも求めずに積極的に改善活動を行う人間だ。このような「やる気のある人間」がいることで、相対的に怠けている人間が炙りだされることになる。組織全体がサボタージュに向かっている集団では、このような人間は積極的に排除されていく。

労働者と経営者的観点

このような見えないサボタージュを続けられてしまうと会社は非常に困る。会社からすれば、できるだけ人件費あたりの生産効率を良くしたい。そのためには、誰かが効率改善をする必要がある。だが、現実的な改善活動を経営者やマネージャだけが行うのは難しい。改善というのは前線で手を動かして働く人間だからこそ分かる不満から生まれうるものであるし、労働者以外の人間から思いつく改善というのは微妙なものも多い。

結局、一般的に労働者がよく言われる「経営者的観点を持て」というのはこれを指すことが多い。ただ言われたことをするだけではなく、労働者が自ら全体効率を改善することで企業の利益アップにつながっていくことを経営者は望んでいる。だが、多くの場合一ミリも理解されずに終わる。

できるだけ働かずにお金をもらいたい労働者と、できるだけ人件費をゼロに近づけたい経営者。このパレート効率的関係を改善することで会社は成長する。

労働者は効率を改善するのか

はなから仕事をする気がない人間というのはここでは論外とする。しかし、会社の成長が自分の利益に直結するということが学習されると「自らが会社を成長させるんだ」と意気込む労働者は少なくない。彼らは会社や経営者を信じているし、自分たちの労働で会社が大きくなることを喜ぶ。会社を経営する側からすれば、こうした人間を積極的に採用したいし、それ以外の人間はできるだけ重要なポジションから排除したい。

つまり、経営者には労働者の自己効力感を養うことが求められる。自分たちの手で会社が成長している、そして自分の利益にもなっているんだ、という実感を労働者に与えること。

こうして初めて、労働者が経営の目を持ち始める。

*1:CDフローの改善なんて、世の中にある数パーセントのイケイケスタートアップだけがやっていることで、我々はそんなことをする必要がないんだぞ、と。

Elmを書くなら見ておきたいRichard Feldmanのトーク4選

弊社では「筋肉の人」*1として知られるRichard FeldmanはElmの創造神ことEvan擁するNoRedInkに所属するエンジニア。

Evanが比較的キーノート的なElmの未来やらビジョンを語るトークをする一方で、RichardはどちらかといえばElmをプロダクションで使うにあたって、どのように書くことでスケーラブルにできるか、のようなはなしをメインに据えている感じがある。

彼はアメリカで開催されているelm-confや、ヨーロッパのelm Europeなどで割と長尺のトークを務めることが多く、その内容もElm中上級者になるにはうってつけの内容ばかり。どのトークもElmの基礎的な文法や紹介は完全に端折られていて、Elmを使うこと前提でどのようにうまく使うかにフォーカスしている。

彼の動画は会社のElmメンの会(?)の中で一気に集中して見たことがあり、僕含めみんなにとって非常に学びが多かった。ということで、中でもこれだけは!というものをこの記事では紹介したい。

twitter.com

"Making Impossible States Impossible"

2016年のelm-confでのトーク。Elmではカスタムタイプを使って排他的な状態をモデリングすることで、ビジネスルール上起き得ない状態を作り出すことを不可能にすることができる。たとえば、絶対に空にならないリスト、というモジュールを作りたければ、型をしっかりとモデリングすることで空状態のリストを作れないようにすることができるし、それをコンパイル時に検出することができる。

また、カスタムタイプに対する操作を制限して内部の情報をカプセル化するためのテクニックとして、Elmのモジュールシステムを用いたOpaque Typeが紹介されている。

www.youtube.com

"Immutable Relational Data"

データソースがアプリケーションの中に分散すると、どうしても同期をとらないといけなくなってしまう。そして、同期をとる部分というのはerror-prone(エラーが起こりやすい)部分でもある。なので、できるだけデータというのは重複しないようにして、パフォーマンス改善のキャッシュ戦略などを除いては可能な限りSingle Source of Truthを守ろう、というはなし。

Elmで配列の値を扱う際、なにも考えないとすぐに「これはListでいいかな」みたいな発想をしてしまいがちだが、ListよりもSetやDictなどのコレクションを適切に使うほうが、そのデータの集まりはどういう集まりなのか(たとえば、ユニークなデータのあつまりなのか、それとも重複を許すのか等)が意図が明確になるのでよい。これはElmに限らずJavaScalaなど、コレクションの種類が豊富な言語でも同じかなと思う。

www.youtube.com

"Scaling Elm App"

題名の通りで、デカいElmアプリケーションに起こりがちなあれこれに関するTipsのトーク

上のふたつのトークと比べて、実際のアプリケーションに起こりがちなことにフォーカスしている。たとえば、Modelが大きくなってきたときにはどうするのがいいか。再利用可能なパーツをTEAモジュールにするにはどうすればいいか、などなど。

www.youtube.com

"Make Data Structures"

2018年のelm Europeでの彼のトーク。個人的には一番推し。

プロダクションで作るようなアプリケーションでどのようにカスタムタイプを使ったデータ構造のモデリングをするのが望ましいかについて話している。

このトークではDreamwriterと呼ばれるサンプルのElmアプリがお題となっていて、アプリケーションの仕様としてデータをWeb APIとIndexedDBへ同時に取得しに行き、どちらにもデータがなければ空の状態とする、というものがある。単純に考えると、すぐに個別のデータの有無をMaybeで表現しようとしてしまいがちだが、カスタム型でデータの取得状態をLoading/LoadingProblem/LoadedOne/Loaded などのように表現をすることで、仕様上ありえない競合状態を作り出せなくできる。

加えて今回もまたOpaque Typeに言及しており、今回はモジュールのAPIとしてどのような関数を公開すべきか(セッター/ゲッターではなくマッパーを公開しよう、など)という内容も含まれる。非常に充実した内容だ。

www.youtube.com

余談

この記事を書いたとき、4番目の動画がYoutubeで見つからなかったので本人にメンションしていた。実際には自分の見落としだったけれどリプがもらえて、Elm界隈の距離の近さいいナ〜と思った瞬間でもあった。

基礎からわかる Elm

基礎からわかる Elm

  • 作者:鳥居 陽介
  • 発売日: 2019/02/27
  • メディア: 単行本(ソフトカバー)

*1:昔の動画はそうでもないが、年々筋骨隆々になってきている。実際に結構トレーニングはしているようだ。

GolangでUnmarshallerインターフェースを実装した構造体をフィールドの型として使うと便利

例えばこんな構造体が定義されているとして

type User struct {
    Name   string `json:"name"`
    Status int    `json:"status"`
}

この構造体をJSONからUnmarshalしてマッピングする際に、以下のような要件があるとする

  • statusの取りうる範囲は1,2だけ、かつそれぞれACTIVE, INACTIVEという定数にマッピングしたい。
    • 1,2以外の数値が来たらエラーにしたい。
  • statusフィールドがないときもエラーにしたい。

User構造体を受け取ってバリデーションをする関数を作ってもよいが、以下のようにStatus型を新しく作り、それにUnmarshallerインターフェースを実装させるとグッとスマートにできる。

type User struct {
    Name   string `json:"name"`
    Status Status `json:"status"` // int型からStatus型に変更
}

Unmarshallerインターフェースを実装したStatus型

Unmarshallerインターフェースは以下のような定義になっている

type Unmarshaler interface {
    UnmarshalJSON([]byte) error
}

JSONのUnmarshalをする際、マッピング対象のフィールドにUnmarshallerインターフェースを実装したものがあると、そのフィールドへのマッピングの際に自動的に実装されたUnmarshalJSONメソッドが呼ばれるようになる。

つまり、Status型にこのUnmarshallerインターフェースを実装することで、User型がUnmarshalされる際に自動でStatus型に実装された任意のマッピング処理およびバリデーション(!)行えるようになるというわけだ。

Unmarshallerインターフェースを用いて要件を実装したStatus型は以下になる。

type Status int

const (
    ACTIVE Status = iota + 1
    INACTIVE
)

// Unmashaller
func (status *Status) UnmarshalJSON(data []byte) error {
    var value int

    if err := json.Unmarshal(data, &value); err != nil {
        return fmt.Errorf("Failed decoding status: %s", err.Error())
    }

    switch value {
    case 1:
        *status = ACTIVE
    case 2:
        *status = INACTIVE
    default:
        return fmt.Errorf("Invalid status: %d", value)
    }

    return nil
}

statusの取りうる範囲をバリデーションできているか見てみる

上の実装を終えた上で、Status型をフィールドに持つUser型をJSONからマッピングしてみるとこうなる

func main() {
    src := `{ "name": "Jonathan", "status": 3 }`

    var user User
 
    if err := json.Unmarshal([]byte(src), &user); err != nil {
        panic(err) // panic: Invalid status: 3
    }

    // ...
}

statusに3が与えられているのはUnmarshal時にマッピングエラーになる! すばらしい

statusフィールドが存在しない場合にどうするか

実はこれだけではまだ、以下のようにstatus型が抜け落ちているJSONマッピングに対するエラー検知ができていない

{ "name": "Jonathan" }

上のJSONマッピングするとどういう挙動になるかというと以下のようになる。

func main() {
    src := `{ "name": "Jonathan" }`

    var user User
 
    if err := json.Unmarshal([]byte(src), &user); err != nil {
        panic(err)
    }

    fmt.Printf("%#v\n", user) // main.User{Name:"Jonathan", Status:0}
}

つまりint型の初期値である0が代入される。

自分の場合は以下の IsEmpty のようなレシーバメソッドを生やして、仮にUnmarshalが成功したとしても、必ず直後にIsEmptyを事前条件チェックとして呼ぶようにしているが、若干微妙ではある。

type Status int
 

const (
    ACTIVE Status = iota + 1
    INACTIVE
)

func (status Status) IsEmpty() bool {
    return status == 0
}

// ...

func main() {
    src := `{ "name": "Jonathan" }`

    var user User
 
    if err := json.Unmarshal([]byte(src), &user); err != nil {
        panic(err)
    }
 
    if user.Status.IsEmpty() {
        panic("status is empty")
    }

    fmt.Printf("%#v\n", user)
}

本当はUnmarshalJSONメソッドの中でどうにかしたいが、Unmarshal対象のフィールドがない場合には当たり前だが呼ばれない。ここはちょっと苦しい。

Opinionatedなライブラリとチーム開発

 GitHubなどで作者がライブラリ(やフレームワーク)をopinionatedであると形容しているのを見ることがある。Opinionatedというのは直訳すると「意固地な」「意志のかたい」のような雰囲気になるが、意固地なライブラリというのは正直意味が通らない。ではどういう意味なのかというと、そのライブラリが、作者によって強く方向付けられていることを意味する。言い換えれば、利用者がある種のルールを強制されるものだ。

 フロントエンドのはなしをするが、たとえばElmはとてもopinionatedな言語(このケースはライブラリではないが)であると言える。創造神エヴァンによって、言語自体にSPA開発用のフレームワークが内蔵されているし、JSによくあるような裏技やハックを使うことが言語仕様上できなくなっている。TEAというアーキテクチャによって、アプリケーションの構造やデータの流れが統一されている。これはまさに彼自身の思想そのものだ。

 他のものでいうと、Vue.jsも比較的フレームワークという観点では微妙にopinionatedだと言えるが、細かい部分ではそうではない。一方、Reactはビューのみに責務を絞っているという点でless opinionatedに見える。ReduxはJavaScriptなライブラリの中では最もopinionatedだろう。

ライブラリと思想

 ちゃんとした意図や背景があって作られたものには、公式のページかどこかに丹精込めて作者が思想を説明しているページがあるケースが多い。たとえばReduxのMotivationROM.rbのCore Conceptsはすごくいい例で、既存の解決策やアプリケーション・アーキテクチャのどこがイケてないのかを説明した上で、自分たちの思想を実装したライブラリがどう優れているのかを説明している。

 思想が弱いライブラリというのは、使っているうちに思わぬところで綻びが出るものが多い。とくに誰彼構わずいい顔しようとするタイプのものに顕著な印象がある。オールインワンだとか、初心者に優しいと謳うもの、easyやsimpleなどのフレーズを使うものが怪しい。パフォーマンスが優れていることをアピールして、肝心な思想を煙に巻くケースも多い(もちろん、パフォーマンスに優れていることがそのライブラリ自体の思想ならおかしくはないが)

 Less opinionatedなライブラリは利用者にルールを強いない代わりに、ルールを作りを委ねてくる。小規模な開発では問題にならないが、チームが大きくなる頃には必ずコンセンサスゲームをすることになる。ライブラリを使う我々側に、それなりの思想を持つことが期待される。しかもチーム開発ともなれば、チーム全体で思想が共有されている必要がある。運用に乗せるのも頑張らねばならない。これがまた、人が増えたときに骨が折れるのだが...

ElmのSlackチャンネルが情報収集をするのに便利

世界中のElmエンジニアが集まるSlackワークスペースがあり、情報収集をするには非常によい。

あまり日本のElm界隈では知られてないのかな? と思ったのでメモ程度に周知しておく。以下のページからSlackのワークスペースに入れる。基本的に全部の会話が英語なので、英語が読み書きできるとなおよい。

elmlang.herokuapp.com

様々なチャンネルがあるが、基本的には #general#begineers に入っておけば良いと思う。質問に対する回答は、参加者人数が多いだけあってめっちゃはやいし、とくにディスカッションが活発でおもしろい。 Elmのカンファレンス情報は #conferences にまとまっているし、作ってみた系の告知やニュースは #news-and-links にどんどん流れてくる。

その他にもローカルなミートアップに関するチャンネルなど腐るほどチャンネルがあるので好きなのに入ればよいと思う。たいてい、あまりメジャーじゃない言語やフレームワークに関しては、日本語情報に触れているうちは最新の情報や尖ったコンテンツにはアクセスできない。なので、こういうグローバルなSlackワークスペースにいるほうが学びが多い。