Runner in the High

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

新しいフレームワークを学ぶならTodoMVCではなくRealWorldを参考にしよう

よく新しいフレームワークを学ぶにはTodoアプリを作ってみるのがよい、と言われる。実際、Todoアプリを様々なフレームワークで作ってみたサンプルをまとめたサイトもあったりする。

ところが、実際に業務で作るようなアプリケーションはTodoアプリの範疇を超えている。とくにSPAにもなると、画面遷移やWebAPI連携、大規模な状態管理などなどの条件が増えるので、Todoアプリを作っているときには考慮できていなかった大変さが出てくる。

そこで参考になるのが RealWorld example apps と呼ばれるプロジェクト

f:id:IzumiSy:20190609165127p:plain

端的に言うと、TodoMVCの大規模版

規定のスペックに沿って、様々なウェブフレームワークで作られたアプリケーションのリポジトリがリストアップされている。

f:id:IzumiSy:20190609165323p:plain

スペックについて

"Conduit" is a social blogging site (i.e. a Medium.com clone). It uses a custom API for all requests, including authentication.

要求されているスペックはConduitと呼ばれるMediumクローンを作る、というもので、具体的には以下のような機能を満たしているとのこと。

  • ホーム画面
  • JWTを使ったユーザー登録・ログイン画面
  • ユーザーの設定画面
  • 記事の投稿/編集画面
  • 他ユーザーをフォローする
  • お気に入り記事一覧

ここまでの機能を実装しているアプリケーションとなると、わりとかなり本格派なんじゃないだろうか。

ちなみに、フロントエンド以外にもサーバーサイド・フレームワークによる実装もあるので、サーバーメン的にも参考になると思われる。

Clean Architecture 達人に学ぶソフトウェアの構造と設計

Clean Architecture 達人に学ぶソフトウェアの構造と設計

"初夏のJavaScript祭り2019" にElmのはなしで登壇した

 6/1に開催されたJavaScript祭りというイベントに「jQueryからElmまで」というタイトルで15分枠の登壇をした

 内容はjQueryからJavaScriptを触り始めた自分が、Elmを書くまでにどういう困難を経験してどういう学びを得たのか、にフォーカスを当てたもの。

 フロントエンド界隈はトレンドの変化が早いと言われがちだが、闇雲に新しいフレームワークが乱立しているというわけではなく、どのフレームワークもアプリケーションを作る上での問題を解決するために生まれているのは間違いない。これはjQueryprototype.jsのころから変わっていないし、そもそもテクノロジー自体が問題解決をするためのものであることからも自明だと思う。そう考えると、いまElmを書いている自分は割と遠いところまで歩いてきたなぁ、と感じさえする。

Prop Drilling について

 懇親会の際に、スライドの中で触れていた Prop Drillingアンチパターンなのか? という話になったが、これは正直スライドの表現が悪かったと思っている。

 自分としては、Prop Drilling はその後に触れられるイベント・エミッタを乱用するパターンを説明するきっかけとして使いたいだけで、アンチパターンだとは思っていない。まずモジュール結合度の観点からみても、コンポーネントに渡されるパラメータが増えても結合度は低い状態であるし、コンポーネントに対する入力が増える以外の欠点がないからだ。

余談

 もともと、この発表のインスピレーションは過去のこの記事にある izumisy-tech.hatenablog.com

 ReactのSFCやChoo.jsなどを知ってときに「ビューって関数やん!」と気付いたのを覚えている。

 その後、偶然にもElmを使っている会社へ新卒入社し、前提としてフロントエンド・アプリケーションは関数の組み合せで作れるということが自分の中での当たり前になっていった。一方で、その考えに至るまでに自分が書いていたフロントエンドは全く異なるものだったことを思い出した。一度なにかを知ってしまうと、それを知らなかった頃の自分には戻れない。それでも、どのように自分の考え方が変わっていったかはまだ思い出せる。こんなことを考えながら、今回はスライドを作った。

 登壇にあたっては、最終的にはJavaScriptにトランスパイルされるとはいえ、ElmはほとんどJavaScriptとは別の言語なので参加者層的に楽しんでもらえるかなという不安もあった。事前に主催の方から頂いたアンケートをみてもやはりVue.jsを書いている、という方が多かったし、発表内容にもVue.jsとVuexにフォーカスを当てたものが多かった。

 かくいう自分も、仮に開発対象のアプリケーションがのちのち自分の手を離れることになる場合、あるいは組織自体がElmをキャッチアップできる状態でない場合には、Elmを選択することはいまのところないだろうなと思っている。Vue.jsやVuexであれば、コミュニティの大きさから後任の開発者が確保できる可能性が充分にあるからだ。

 Elmの堅牢な型システムやある意味 "ズル" できないアーキテクチャは、必ず大規模なアプリケーションに必要なものであることには間違いないが、そもそも書ける人間がいない状態になってしまっては元も子もない。とはいえ、JavaScriptを触っている人間であれば、文法がパッと見で目新しいものあるだけで、Elmにはすぐに馴染めると信じている。そのような意味で、自分の発表を聞いてElmの存在だけでも知ってくれる人が増えてくれたとしたら非常にありがたい。

2019年現時点でのElmベストプラクティス6選

先日業務で1からElmアプリケーションを作りきったのでそのときの学びをメモっておく。

1. Model / Msg / View のような分割をしない

  • Rails などのフレームワークからきた人がやりがち。
  • Elm でファイル分割をするのはモジュール単位でのカプセル化をするときだけでよい。
  • なので基本的に1画面につき1モジュールとして、その中に Model / Msg / View / Update などを書いていく。
  • ここからさらにデータ構造として抽出できるものがあれば後述の Opaque Type として切り出す。

2. コンポーネント指向と混同しない

  • Elm は React や Vue.js のようなコンポーネント指向フレームワークではない。
  • 基本的に1画面につき1モジュールとして作る。
  • 再利用したい画面のパーツは関数として作ればよい。

3. Opaque Type の活用

  • Elmにはクラスはないが、モジュールシステムを使うことで公開する型、関数などを制限したカプセル化ができる。典型的なものは以下のふたつ。

3.1. 値オブジェクト

アプリケーションのドメインの固有な型を作ることで仕様をカプセル化する

module Bookmark.Title exposing (Title, new)

type Title =
    Title String

new : String -> Title
new value =
    Title value

ただ String をカプセル化しているだけにも見えるが、このように型を定義することで String をアプリケーション固有のドメインとして特化させることができる。

これには以下の利点がある

  • バリデーションなどのロジックをこのモジュールに実装することで責務分割がしやすくなる。
  • 関数のシグネチャから利用意図が分かりやすくなる
    • String -> String -> StringよりもTitle -> Description -> Bookmarkのほうが、コードに与えられた意味が理解しやすい。

3.2. コレクションオブジェクト

これが意外と使いドコロが多い。集合を型として表現したカプセル化

例えば以下のような Bookmark 型があるとする

-- Bookmark

module Bookmark exposing (Bookmark, isInvalid)

type Bookmark
    = Valid Title Description
    | Invalid
 
 
isValid : Bookmark -> Bool
isValid bookmark =
    case bookmark of
        Valid _ _ ->
            True
      
        Invalid ->
            False

その上で Bookmark のコレクションを扱う Bookmarks 型を定義する

-- Bookmarks
-- 上で定義したBookmarkの集合を表現した型

module Bookmarks exposing (Bookmarks, new, size)

import Bookmark exposing (Bookmark)


type Bookmarks =
    Bookmarks (List Bookmark)


new : List Bookmark -> Bookmarks
new bookmarks =
    Bookmarks bookmarks
  
  
size : Bookmarks -> Int
size bookmarks =
    bookmarks |> List.filter Bookmark.isValid |> List.length 

このコレクションオブジェクトのいいところは利用者側がコレクションの仕様を詳しく知らずに使えること

  • Bookmarks のコレクションが何で実装されているか (List, Set, etc...) は利用者側は意識しなくてよい
  • Bookmark のサイズがどのような基準で計算されるかは利用者側は意識しなくてよい

言い換えれば bookmark のコレクションにまつわるロジックの変更はすべてこのモジュールに閉じたものになる。

4. Record をインターフェースとして使う

Record はデータ構造に別名をつけただけのもの (type alias だし)

0.19からはタプルが2値しかとることができなくなったぶん Record が3つ以上の値をもつタブルの代替になった感がある。

Extensible Record を使った依存の切り離し

Record を部分的に満たすインターフェース (Extensible Record) を使うことによって特定のデータ構造への依存を分離できる

たとえば以下のコードは toSessionが Model に依存している

type alias Model = 
    { session : Session
    , currentUser : User
    , bookmarks : Bookmarks
    }
  
  
toSession : Model -> Session
toSession { session } =
    session

これはよくある例で、Model はデータが多くなればなるほど多くの関数が依存するようになりがちだ

実際には toSession 関数は session だけが存在するレコードが受け取れればいいので、以下のように Sessionable として定義した Extensible Record に依存させ Model の依存を取り除ける。

type alias Sessionable a =
    { a | session : Session }
  

toSession : Sessionable a -> Session
toSession { session } =
    session

この分離の利点は以下

  • テストする際に Model を丸ごとモックする必要がない
  • 依存の方向を統一できる (DIP)

特に Elm は循環参照をコンパイラが許さないので、アプリケーションが大規模になればなるほど Extensible Record の利用シーンは増える。

5. データ構造的な DRY よりも状態網羅性を大事にする

定義上の重複を減らそうとするのではなく、状態の網羅性の観点から適切かを考える

type Page
    = SignIn
    | Bookmarks
    | NewBookmark
    | Loading

type alias Model =
    { session : Session
    , currentUser : Maybe User
    , bookmarks : Maybe Bookmarks
    , currentPage : Page 
    }

上記の Model の欠点は以下の2点

  • Maybe の意図が不明確
    • bookmarkscurrentUser が Nothing なケースが定義から分からない
  • ありえない状態がとれる
    • currentPage が SignIn なのに Bookmarks が存在している、など

これを踏まえた上で、上記よりも以下のような Model がより望ましい

type Model
    = SignIn
    | Loading Session
    | Bookmarks User Session Bookmarks
    | NewBookmark User Session Bookmarks

この定義を見ると、SessionBookmarks を共通化したい気持ちがでてくるが、状態の網羅性が壊れるくらいであれば共通化はしないほうがいい。共通化するよりも堅牢さを大事にする。

6. Parcelを使うと最速で環境構築できる

いまのところこれが最速だと思う。

qiita.com

基礎からわかる Elm

基礎からわかる Elm

  • 作者:鳥居 陽介
  • 出版社/メーカー: シーアンドアール研究所
  • 発売日: 2019/02/27
  • メディア: 単行本(ソフトカバー)

Immutable.jsを使うメリット

 先日、新卒で入ったエンジニアが 「Immutable.jsの研修課題をやってるんですけど、正直なんで必要なのか分かんないっす」 と言っていた。

 たしかに React, Redux と Immutable.js をセットでつかおうみたいなノリの記事はネットでよく見るが、じゃあなんでそのセットなの?という点に関してはあまり詳しく書かれていないことのが多い気がしたので、個人的にその理由っぽいのを雑に書き残しておこうと思う。

イミュータビリティのいいとこ

  • コーディング・バグを減らす
    • 言語仕様上ミュータブルな JavaScript は、大勢で開発してるとこっそりどこかで参照を持ったオブジェクトを書き換えてた、なんてことになりやすい。なのでデータを更新する際にはイミュータブルであることが保証できるとバグが起こりにくいコードを書ける
  • メモリ効率がいい
    • イミュータブルなオブジェクトは中身が同じなのでコピーが参照のみになり、実行時のメモリ効率がよくなる
    • 参照がコピーされるだけなので、例えばコレクションの比較も実質 O(1) になるので速い
  • 地味にWikipediaイミュータブルのページが充実した内容で参考になる

ReactとRedux

  • 仕様的に React+Redux 自体がイミュータビリティを期待したものになっている
  • React が Unidirectional なデータの流れ方をする
    • コンポーネントの中で明示的に setState が呼ばれて初めてビューの更新が予約される。
    • この更新はミュータブルなステートの部分更新などではなく、新しいステートを丸ごと与える。
  • Redux が関数型アプローチ
    • React 界のFlux実装のデファクトスタンダードこと Redux はステートの変更を純粋関数で行う
    • 変更を行う Reducer が React のステート更新と同様に既存のステートから新しいステートを返す(イミュータブル)
  • この辺の前提に加えて、ES6だけで更新処理周りのコードを書いていると、スプレッド演算子Object.assign まみれになるところが、Immutable.jsでスマートに書けたりする。
    • 最近のバージョンでは TypeScript と組み合わせたトランスパイル時のチェックもそこそこいい感じになってきている

他の一部フレームワークとの相性

  • Vue.js で Vuex に載せるデータを Immutable.js のコレクションにしたら微妙だった
    • そもそも Vuex 自体がステートをミュータブルで持つので、どこがミュータブルでどこがイミュータブルなのかを気をつけないと意図しない挙動が起きることがあった
    • そもそも Vue.js では Object.defineProperty と呼ばれる更新検知の機構を使って効率的にオブジェクトの更新を検知しているので、逆に Immutable.js を使わないほうがパフォーマンス的にもよくなる気がするし、むしろ使うべきじゃなかったと思っている。
  • Boost the Performance of an AngularJS Application Using Immutable Data · Minko Gechev's blog
    • ちょっと古いが Immutable.js を AngularJS と使った人の記事
    • AngularJS は Digest Loop の中で scope オブジェクト間の差分チェックをして、もし差分があればそれをビューに適用していく仕組みになっている。これがコレクションになると O(n) になるが、 Immutable.js を使うとコレクション比較が実質 O(1) なのでパフォーマンスが向上する。
    • この作者は immutable というディレクティブを自作したらしいが、 AngularJS 組み込みの filter ディレクティブなどとの相性が悪いらしく率直に言って使いづらそうだ。
  • Immutable.js は JS のプレーン・オブジェクトへ変換する処理のオーバーヘッドがそこそこデカいので、ユースケース上ここがボトルネックになってくるとどのフレームワークと組み合わせていてもイミュータビリティが破綻し始める感がある。
    • Wantedly People のフロントエンドを作ってる人がこのつらみをどこかで書いていた気がする
  • JavaScriptにおけるコレクション(というか配列)操作についての計算量はここに書いた izumisy.work

まとめ

  • React と Redux 自体がそもそもイミュータビリティとの相性がいいフレームワークになっているという印象。他のフレームワークだと場合によっては微妙。 React+Redux でやるなら Immutable.js は入れておいて損がないよ、と言われる理由はだいたいこんなもんかな。
  • 余談だが Redux に影響を与えたと言われる Elm は全ての関数が最初からイミュータブル。もはや言語レベルでこうなっているのは結構嬉しかったりする(チームでコンセンサスを得る必要がなかったりするから)
  • 最近では Immer という Immutable.js オルタナティブが出たらしい。パット見ではコレクション系のクラスっぽいものがなくAPIが非常にシンプルという印象。こっちも要チェックっぽい。
  • おそらくイミュータブルの概念を理解するにあたってはガベージコレクションなどのメモリに関する知識と、データに対する計算量などのアルゴリズム的な知識のふたつが必要になるのではないかと思う。アルゴリズムについて学ぶにあたっては、やはり「アルゴリズムとデータ構造」が一番おすすめであると言える。

「完璧につくらない」という能力

 自分の欠点として、まず「完璧につくろうとしてしまう」というものがあることが分かってきた。

www.wantedly.com

2度現地で参加したリモートハッカソンでは、SAPに勤める若いエンジニア、バークレーで勉強をしている学生とそれぞれペアを組んで開発をしたが、彼らのコードはさほど自分が期待していたような洗練されたものでなかったように思えた。

 自分は、アメリカでハッカソンに参加したときに現地のエンジニアとコードを一緒に書く機会があった。

 そのときの自分は、彼らのコードを見て「ふーん、こんなもんか」と思っていのたが、今思い返してみると、それ自体が彼らの強みだったのではないかと思う。美しい設計や、実装の抽象化を突き詰める前に、まず動くものをつくる。コードはあとからリファクタリングすればよい。そのときの自分は、コードを書くという行為の目的を履き違えていた。

 つまり、コーディングには2種類の能力がある。まずは、品質に敢えて目を向けずに動くものを最速で作る能力。次に、いくら品質が悪いものでも、リファクタリングできる能力。スタートアップやベンチャーでコードを書くには、このふたつが求められるのでないかと思い始めた。

社会人エンジニアに求められたもの

 去年の4月から社会人としてエンジニアをやっている。

 いつのまにやらもう1年が経とうとしているが、自分が仕事としてコードを書くエンジニアになって、これまでにどんなことを学んできたのか? ということを文章として書き残していなかった。タイミング的に「新卒」というラベルが剥がれそうな時期であるので、ここに書き残してくこととする。

 が、なかなか自分自身の成長を文章で書くのはなんとももどかしいものがある。自分は人を褒めることを躊躇したくないし、自分自身を「謙遜」*1と称して蔑みたくないという気持ちがあるが、それでも実際はなんとも言えない感情との板挟みになる。ということで、折衷して自分自身を客観的に「社会人エンジニア」のひとりとして捉えて、彼に何が求められてきたのか、というのを文章にしてみることとした。

言語やフレームワークにこだわらずプロダクト開発ができる

 例えば、新しく会社でプロダクトを作る、となった際に、技術要件として自分がこれまで触ったことのない言語やフレームワークが非常に有用であるということが分かるのであれば、その時点で自分がその言語/フレームワークを触ったことがなかったり、得意ではなかったとしても、そのタイミングで即座に業務で使える程度の技術をすぐに身に付ける柔軟性が期待される。

 もちろん、人には向き不向きがあり、それを個人差として捉えることもできる。けれども、業務でコードを書くというのは最終的にはビジネスを実現するための手段としての位置づけであるということは間違いない。ビジネスというのは、大抵の場合市場競争に巻き込まれるものであるし、そこへ個人差が常に加味されるかと言われると、難しいものがある。

 とは言うものの、ある程度コードを書いた経験があれば、少しづつ横展開できる基礎知識はついてくるものなのではないかと思う。自分は社会人になって初めてScalaとElmを業務で書き始めたが、全く持って手も足もでないということはなかった。なんでもかんでも「まずやってみる」というのが大事だ。

チーム開発を想定できる

 弊社が非常に設計を大事にする社風である、ということはいつぞやの記事でも書いた。設計を大事にする、という点が意味するのは、開発におけるスケーラビリティを大事にしているということだ。この「開発がスケーラブルである」という言葉が表現したいものは、チームがいくら大きくなっても、全体のアーキテクチャが破綻することのないようルールづくりができているということ。

 学生の頃はチームで開発をするなどということは一ミリも考えたことがなかった。それは、10社以上のインターンを経ても変わらなかった。どの会社に行っても、せいぜいインターンでやるのはハッカソン的な開発か、中/長期でもちょっとしたバグフィクス程度のものだった。結局、そのようなタスクをするだけに終始しているようでは、チームで効率よく開発をしていける仕組みづくりや、運用に乗せる際にどういうことを考慮するべきか、のような「業務」としてのものづくりを体験することはできないし、ちょっとコードを書くだけのアルバイトでしかない。

 一方で(ここからはポジショントークになるが)弊社のインターンは学生にもチームの存在前提で設計をさせる。これは夏季の短期インターンでもそうだ。もちろん時間は全く持って足りていないし、思考の負荷も高い。けれども、チームで大きなアプリケーションを作るともなれば、予め負荷の前借りを設計の段階でしておかなければ、あっという間に雪だるま式に負債が溜まり込んでしまう。負債をゼロにし続けることは無理だが、それでも設計指針をきっちりと練っていくことで、負債が溜まるスピードを遅くすることはできる。

大規模トラフィックを想定できる

 これは非常に抽象的な話であるが、例えば自分は社会人になって初めてPub/Subやタスクキューの使い所を学んだ。

 CSVファイルをアップロードして一万人のユーザーを管理画面から登録させる、といった要件があるとしたら、学生のころの自分は全てリクエスト・ハンドラの中でまるごと処理しようとしていたのではないかなと思う。このようなことをしてしまうのは「もしこの機能が〇〇万人に使われるようになったら、どこがボトルネックになるのかな?」というような思考が働いていないからだ。

 このタイプの思考を巡らせるためには、スケールするもの/しないものの知識がまず前提にあり(たとえばCPUバウンドな処理はスケールさせることができるが、IOは一貫性とのバランスをとる必要がある、など)その上で、RDBMSやNoSQLのような道具に関する知識との掛け算が必要になる。もちろん、学生でもGCPAWSなどのツールを大規模のデータと共に運用していれば、勘所は抑えられるのではないかと思う。けれども、自分は全くと言っていいほど経験も、知識もなかった。

特定の言語・フレームワークにロックインされない設計の思想と知識がある

 コードを書くということは、インターネットに転がっているQiitaの記事を読んだり、リファレンスを読んだりすれば、すぐにできることであるが「どのようなコードを書くか」という方向性がなければ、いきあたりばったりで意図の読めないコードを量産するだけになってしまう。

 大事なことは、大局的な方向性として「変化に強いアプリケーションを作る」*2のを前提にすることだ。まさにこれは言語・フレームワークがなんであろうと関係がない。この前提を踏まえた上で初めて「じゃあ今回はクリーン・アーキテクチャでいきましょう」というような決定を下すことができる。逆に言えば、いくら流行っているからと言ってクリーン・アーキテクチャを採用しても、それが方向性にそぐわなければ、単に編集するファイル数が多くて面倒くさいアーキテクチャを採用しただけじゃないですか、という判断になりかねない。

 実際には設計のみならず、実装にも同様のことが言える。たとえば、Scalaのコンパニオン・オブジェクトを使ったコンストラクタ隠蔽やElmのOpaque Type、Golangのパッケージシステムを使ったプライベート化などは、どれも責務分離を表現するカプセル化の実装知識だが、逆に言うとカプセル化がどのようなケースで重要なのか、ということを理解するためには大局的な設計の思想が必要になる。

 言語やフレームワークが変わっても、我々が「変化に強いアプリケーション」を作る必要がある、という前提はこれから変わっていく可能性があるとは言いづらい。その前提を実現するために、様々な「設計」の思想を理解し、知識として持っておくことは言語・フレームワークに落とし込んだ個々の実装表現とは切り離されているという点で独立して重要だと言える。

izumisy-tech.hatenablog.com

*1:謙遜されないと不愉快になる、という人がいるが、このような謙遜を強いる人間というのは相手に自分自身の自己肯定感の低さを押し付けているだけだ。自信を持って悪いことなど何もない。

*2:ビジネスというのは常に同じ形であり続けない。市場が変わればアプリケーションの仕様も変わるし、仮に仕様が変わらなかったとしても、そのアプリケーションを支えるツールが変わる可能性は大いにある。変化に耐えられない組織が市場を制することができないという事実は、多くの有名な日系企業のこれまでの歴史が証明している。

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

戦争、とくに太平洋戦争に関する本を読んでいる。

大学生のとき語学留学でフィリピンに行ったり、卒業旅行でグアムに行ったりしたが、やはり東南アジアの島国をめぐると様々な形で戦争の形跡を目にする。戦争を経験していない世代として、戦争とはどんなものであったか、というものに興味が湧く。

吉村昭戦艦武蔵

戦史ドキュメンタリーの大御所、吉村昭の綴る定番中の定番。 太平洋戦争を知っている人であれば戦艦大和は誰しも知っているが、その兄弟艦である戦艦武蔵知名度はさほど高いとは言えない。自分も武蔵は名前しか知らなかった。

武蔵の建造までの長い歴史と、いかにしてあの巨艦の進水を成功させたのか、そしてどのようにして最期を迎えたのかが丁寧に描かれている。

日本海軍による最後の実戦投入で、連合軍戦闘機から猛烈な攻撃を受けて撃沈される様は冗談抜きで手に汗握る描写だった。

吉村昭 「零式戦闘機」

最強の戦闘機と呼ばれたゼロ戦の、開発と活躍からその凋落までを描いたドキュメント。

自動空戦フラップや沈頭鋲、アクタン・ゼロの存在をこの本で初めて知った。

戦争はテクノロジーの進歩を促す大きな要因である、というのは例えばインターネットを見ても本当に実感するところではあるけれど、本書の中でも日本海軍がいかに戦闘機開発に心血を注いでいたかがよく分かる。もちろん毎度毎度、新しい戦闘機に求める要求は厳しくなるが、それに応えていた技術者もすごい。

初期のゼロ戦の無双具合を知った上で、後半の連合軍戦闘機によるサッチウィーブ考案以降のゼロ戦のエピソードを見るのは、なかなか心にくるものがある。

源田実 「海軍航空隊始末記」

吉村昭のドキュメンタリはどちらかといえば現場の話がメインになっているが、この本は太平洋戦争中に航空参謀を務めた源田実の目線で描かれた真珠湾攻撃から終戦までのドキュメンタリになっている。後から知ったのだが、この人がブルーインパルスを創設したらしい。

航空参謀だけあって、太平洋戦争に活躍した日本の戦闘機パイロットとのエピソードがたくさん出てくる。

中盤のミッドウェー海戦を超えたあたりから一方的な負け戦が延々と描かれはじめ、しんどい読み物になってくる。特に空母を一気に失ったあたりのやっちまった感は、読者として読んでいるだけでも痛いくらい伝わってくる。

日本人のことを「勝ち戦には人一倍強く、負け戦には案外脆い所がある」と表現しているのが、なぜか心に残っている。

戸部良一、その他 「失敗の本質」

ちょっと前に話題になった本。上の三冊とは若干毛色が違う。ドキュメンタリとは異なる客観的なアプローチで、太平洋戦争における日本軍の組織的特性から「なぜ負けたのか」を考察している。

この本で取り上げられているのは「ミッドウェー海戦」「ガダルカナル作戦」「インパール作戦」など、いわゆる太平洋戦争において激戦とされた戦いの数々で、これを読むだけで太平洋戦争の雰囲気が分かる。

まえがきで「できるだけ多くの人々に読んでもらうために読みやすさ、平易さをも心がけた」と書いているが、正直な所、そこそこ難しいところがある。何が難しいかというと、やはり地名に馴染みがないものが多かったり、そもそも日本軍の組織構造が分かっていないと難しかったりする。それでも、各章にアナリシスとして、その戦いで何が日本軍の敗けへと繋がったのかを要約するものがあるので、それを読むだけでも学びがある。

この本を読んでいると、逆に日本軍と対峙したアメリ海兵隊がいかに戦いの度に組織改善に取り組んでいたかが分かる。著者のひとりである野中郁次郎アメリ海兵隊に関する本を書いており、組織としてどのような点で勝っていたのかを研究している。

プログラミング・インポテンツ

紛れもない事実として、学生の頃よりも明らかにプライベートの時間でプログラミングをするのが億劫になった。 後輩にこのことを話すと「それってインポみたいですよね」と言われたので、これをプログラミング・インポテンツと名づける。

いまの生活に関して

朝9~11時くらいに出社して、働いて夜8~10時くらいに帰ってくる。
先週千葉に引っ越したので、より朝の時間が早くなり夜も遅くなった。

つまり、平日は仕事をして返ってきて寝るだけ。

プログラミングが嫌いになったのか?

いや、そんなことはない。

いまでも業務でコードを書いている時間というのは幸せだし、コードを書けるという能力によって組織に貢献できていると自分でも思っている。もちろん、それ以外にもちょっと英語ができるなどのはなしもあるが、それでもコードを書くというスキルが自分のアイデンティティの一部であることは間違いない。

じゃあなぜか?

おそらく、理由は以下の2つ

  • 会社で充分プログラミングしているのでもうお腹いっぱい
  • 設計が気になってサクサクとコードをかけない

会社でプログラミングをしているのでお腹いっぱい

会社では主にGolang, Scala, Elmのコードを書いているが、バグフィックスや新規機能開発である程度毎日コードを書いているので、そこそこ自分の中でのプログラミング欲のようなものは満たされている。僕は自分の中のプログラミング欲というものの上限値みたいなものを信じているので、それが満たされるとそれ以上プログラミングがしたいという気持ちが湧かなくなってくると思っている。これは食欲と同じで、一旦食事をしてお腹いっぱいになれば、それ以上何かを食べたいという気持ちにはならない、というやつだと思っている。

ところが、学生時代にプログラミングをしていたときは、朝10時に出社して夜返ってきてもまだプログラミングをしてやろうという気持ちがあった。いま思うと本当にプログラミングが好きだったんだろうなと思う反面、じゃあいまはなぜ...と思うことさえある。これが老いというものなのか。

設計が気になってサクサクとコードをかけない

自分の中ではこれが本当の理由なのではないかと思っている。弊社は非常にアプリケーションの設計/アーキテクチャを大事にする風土だ。サマー・インターンのときから徹底して柔軟なアプリケーションを生み出すための設計をやっていこうという気概に満ちていた。もちろん、自分はそんな風土に対する憧れにも似た感情を持って新卒入社をしたわけだ。ところが、設計というのは事実泥臭い作業で、コードを書く云々以前のはなしになる。よく言われるのが、開発業務は設計とコーディングで8:2くらいが丁度いい、というやつだが、これはあながち間違っていないと思う。

自分はまだ設計に関してはペーペーで、まだまだ大局的なアーキテクチャ設計から、実際のコード表現としてのデザインパターンまで満足のいく知識・経験があるとは言い難い。それだけに、きっちり設計に関して頭を使って考えていく必要がある。もちろん、これには非常に頭を使う。

一方、プライベートで書くコードなどというものは適当に流してコードを書くタイプのものであるはずだが、少しコードを書いているとすぐに「ここ、あとで拡張するときにちょっと不便そうだな...」とか「IOレイヤの責務がドメインに漏れ出してるな...どうしようかな」とか考えてはじめてしまうのだ。もちろん、設計に関して頭を使うことは悪いことではないし、そういうトレーニングをするのは間違いなく素晴らしいことだと自分でも思っている。が、プライベートでもまた頭を使うようなことをしたいかと言われると、正直微妙である。

逆に言えば、学生の頃は設計などというものを一ミリも考えていなかった。とりあえず動いて見た目がいい感じになるものが完成すれば満足だったし、レイヤの責務だとかオープン・クローズドが守られているかは全く持ってどうでもよかった。それはそれで、知らなかったという幸せだったのかもしれない。

これからに関して

そもそも、プライベートでプログラミングをする気が起きないのだからどうしようもないと思う。

世の中的には、仕事だけでプログラミングをしているやつはモグリだ、みたいな風潮がTwitterの観測上では強いようだが、実際仕事を始めてみるとそこそこ腹一杯になってくる。

秋ごろには自分でElmアプリを作ったり、Railsをちょこちょこ書いたりしていたが、ぶっちゃけなんか疲れてきてしまった。とりあえずここしばらくは不動産投資の本でも読んだり、英語のリスニングの勉強でもしてゆっくり過ごそうと思う。深刻に考えすぎるほうが良くないからね。