Runner in the High

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

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

千葉からの通勤

年明けに書いたこの記事で触れていたように、もともと住んでいた江東区から千葉県にある母親の実家へと引っ越した。

izumisy-tech.hatenablog.com

引っ越すにあたって、朝のラッシュがどんな感じなのかネットで調べてもいまいち要領を得ない感じなので、実際に自分が初日に職場のある六本木一丁目駅へ通勤してみてどんな感じだったかを、実録ドキュメントとして残すこととする。

ちなみに、住まいは新京成電鉄沿線である。

7:50~ 新京成電鉄津田沼

  • そんなに人は多くない。座れはしないが、車内が一杯というわけでもない。
  • 前原・薬園台からの乗り込みが意外と多い。
  • 新津田沼駅から降りた人たちはみんな脇目もふらずに津田沼駅へ向かっていく
  • 新津田沼駅に近づいてくるとホームの人の多さにギョッとする。とくに都心(新橋・錦糸町)へ向かう方向がすごい。
  • 津田沼駅の改札は、東京へ向かう電車がでているだけあって、さながらその光景は東京に勝るとも劣らない様相を呈している。学生の頃は井の頭線を使っていたが、ラッシュ終わり頃の井の頭線渋谷改札と同じくらいの混みよう。 ​

8:12~ 総武横須賀線で新橋へ

  • ホームで相当に混んでいたにも関わらず、実際にのりこんで見るとそんなに混んでない… が、行き先を見ると真逆に進んでいることに気づく。稲毛まで飛ばされてしまった。
  • この時間になると稲毛駅はガラガラ。もし稲毛駅に住むのであれば、この時間にもう余裕をもって座れるんではないかと思う。
  • 8:28ごろにようやく大船行きの総武横須賀線稲毛駅から乗り込む。この時間になるとラッシュを脱したらしく、普通に立てる程度の混雑。
  • 8:37の津田沼は乗り込んでくる人がそんなに多くない。逆に稲毛から乗ってみると降りる人が意外に多いのに驚く。
  • 8:53に新小岩到着。市川・新小岩あたりで乗車率がかなりキツくなってくる。
  • 錦糸町でドカッと降りていくも、そこそこ混雑している。が、そんなに乗り込みは多くない。 ​

その後

  • 新橋に着くと思ったら東京駅で止まってしまった。仕方ないので丸の内で四谷へ行き、そこから六本木一丁目へ向かった。
  • 9:37に乗り込む南北線がめちゃくちゃに混む。大勢が溜池山王で降りる。

後日談

  • この日の総武横須賀線はまだよかったほうで、また別日にはがっちりと車内でスクラムが組まれて、中に乗り込むのすら困難な日もあった。引っ越し初週ということもあり、会社には9:00~9:30のペースで出勤をしていたが、ラップトップなどの大事なモノ持って通勤する際にはもう少し遅めの時間に乗り込もうと思う。

  • 弊社にはあまり千葉方面在住の人間が多くなくナレッジ・シェアリングがしづらかったが、葛西に住んでいる先輩によると、9時台に乗る東西線は比較的余裕を持って立てる程度の混みようとのこと。

  • この引っ越しによって通勤時間は1時間半となったが、慣れとは恐ろしいもので、最初は「長すぎかもなぁ。耐えられるかな。」と心配していたものの、今となってはスマホをいじってポッドキャストを聴いたりしているといつの間にか着いている、というような感覚になってしまった。良くも悪くも現状に満足してしまうタイプの人間であることが功を奏したと言える。

  • せっかく遠くに済んだのだからリモートワークはどうなんだ、という話もあるが、おいおい余裕が出たらしてみたいと思っている

2019年の抱負、そして2018年を振り返る

今週のお題「2019年の抱負」

■ 2018年の出来事

 去年は各月の出来事を垂れ流して書いていたがめんどくさいのでやめた。今回は出来事を箇条書きスタイルで。

大学を卒業した

 大学を卒業した。ギリギリまで単位が足りているのかわからない状況で、教務課に問い合わせても「最終的な判断はご自分でしていただいて...」みたいな雑な回答しか得られず非常にフラストレーションが溜まった。

 こういう作業こそコンピューターで自動化して「あと〇〇の単位がいくつ足りません」みたいなのがリアルタイムで分かるようにすべきだろうが、と思った。とはいえ、練馬区の極小中堅大学にそんな文句を言っても仕方がない。もう卒業したしどうでもいいや、という感じではある。

 英文科的な所属であったのに、英語で本格的に教授とディスカッションしたのがこの大学4年生の頃だけだったのがなんとなく情けない。まあ、これも自分の大学選びが悪かったとしか言えない。

ひとり暮らしを始めた

 江東区に住み始めた。実家は世田谷区なので、なぜいまさら江東区なぞに...という感じではあるが、自分はミーハーなので清澄白河駅周辺に住みたいという欲求がとても強かった。

 また、実家は単なる集合住宅であり、成人4人が住むにはもはや狭すぎた。また、やはり人生経験としてひとり暮らしをしたいというのも個人的な願望としてはあったのだ。本当は高層階タワーマンションに住みたかったが、自分の収入と照らしあわせて最終的に見つけることのできた物件はあまり良いものではなかった(後述)

社会人になった

 Fringe81株式会社に入社した。 www.fringe81.com  10社くらいインターンに参加して、最終的に最高な会社だったなということでここに決めた。正直、なぜ自分がFringe81に決めたかという話は、軽く話してしまうともったいない気がしているので時間を取って書こうと思っている。が、あっという間に一年目が終わってしまいそうなので焦っている。

 入社してからは主にScala, Golang, Elmを書いている。もともとJavaScriptRubyばっかり使っていた身からすると、相当レベルの高い言語を書いているなという感じがする。決してプログラミング言語に優劣をつける気はないけれど、正直動的型付けよりも静的型付けの言語のほうが思想が深いと感じている。特にScalaなんか正にそうで、型システム自体がめちゃめちゃ深い。そして行き着く先はモナドだと思う。ここはまだまだ全然自分の中で咀嚼できていないことだらけなので、根気よくやっていきたい。

 Elmに関しては非常に自分の中で好き度が増している。とくにReactやVue界隈のどこまでいっても道具選びで消耗している感から解放されている感じがよい。Elmアーキテクチャというデ・ファクト・スタンダードが決まっているのもよい。社としてのプロダクトづくりの前提としてElmを選ぶという決定ができるというのはすごく喜ばしいことだと思うし、自分がElmを学ぶ必要に迫られるきっかけがあるというのはとてもありがたいと思っている。

海外出張に行った

 弊社がWebSummitへ参加するということで、人生で始めての海外出張へ行った。というかそもそも社会人が初めてなので、そりゃ初めてで当然という感じではある。 fringeneer.hatenablog.com  人生発ヨーロッパでもあったけど、現地のカンファレンスで話した言語は英語だったのでとくに問題はなかった。これまで英検準一級まで取った甲斐があったな、というくらいたくさん英語が話せたのでとても満足した。大学ではスペイン語を勉強していたものの、ポルトガル語は微妙に違うところがたくさんあり、そしてそもそも単位をほぼCで取得していたのでまったく役に立たなかった。単語は節々にそれっぽく分かるものがあった程度。

 帰りのトランジットで降りたパリが正直汚くて萎えた。リスボンは町並みやら気候やら、食事がとても自分にあっていた気がして、ちょっと暮らしてもいいかもなと思ったりした。

■ 学んだっぽいこと

2018年で学んだっぽいこと。こう書くといろいろある。

アプリケーション設計

 例えば大量のトラフィックを捌けるようなアプリケーションを設計する、という状況になるとして、アプリケーションの特性に応じてI/Oがボトルネックになるのか、CPUがボトルネックになるのかなどの勘所が学生の頃よりは持てているような気がする。弊社はGCPを使ってマイクロサービスっぽい構成でアプリケーション開発をしているが、Cloud Pub/SubやTaskQueueがどういった理由で必要になるのかというのは今思えば去年は全くもって想像できなかったんではないかと思う。

 また、適切なモジュールの責務分割と、それにまつわるユニットテストを書くことにすごく重要性を感じるようになった。これまでは、モジュール間の粗結合性をコードレベルでどう生み出せばいいのか、という知識が足りてなかったため、実質的にユニットテストをあまり意味のないものだと思っていた。だが、例えば「クリーン・アーキテクチャ」や「オブジェクト指向設計実践ガイド」などを読み込んでいくことで、複数モジュール間の依存関係をどのようにして粗結合な実装として表現すればいいのか、という概念的な知識がついてきた。特にこの2冊は「いかにして変化に強い設計にするか」という目的に向かってたくさんのヒントを提示してくれた。

 自分ひとりで作っているようなアプリケーションは結局作ったら作りっぱなし、という場合がほとんどであったけれども、業務でお金を生む機械として作るアプリケーションには、非常に多くの変更が加えられる。うれしいことに、ユーザーが比較的増えつつあるサービスを作っているだけあって、先輩たちから指導を受けながらアプリケーション設計を実践する機会がたくさんあったと言える。

新しい言語のパラダイム

 ScalaやElmは自分にとって本当にパラダイムシフトになった。

 自分が初めて使ったプログラミング言語はCだったが、そのときは「型付言語ってめんどくさいな」という気持ちが強かった。それもあってActiveBasicやらHSPに逃げたりしていたところもある。けれども、RubyJavaScriptを使ってある程度の規模のSPAやらサーバーサイド・アプリケーションを作ってきた過去を少しでももっていると、型があるということでどれだけの凡ミスやそれにまつわるランタイムエラーを防げるかがとてもよく分かった。

 が、逆に動的言語には動的言語なりのよさ(たとえばダック・タイピングとか)があり、自分の中でそういう考え方を失ってしまうのもそれはそれでもったいないと思うところがある。その点Golangはすごくちょうどよい。Interfaceでダックの実装をある程度約束できたり、動的/静的型付の良さをうまく折衷できている感がある。ポインタやリフレクションがでてくるとすぐランタイムエラーまみれのコードを書いてしまえるのが少し気になるが。

人間の死臭

 隣人が孤独死したので、その死臭を嗅いだ。なかなか人間の死臭を嗅ぐ機会もないだろうということで、これもある意味学びなんではないかと思う。

 死んでいるのがみつかったのも真夏の結構暑い時期で、どうやら1ヶ月程度は放置されていたらしい。古い物件だということもあり、隣の部屋にインターホンがなかったため面倒くさがって自分は入居の挨拶をしなかった。が、どうやら何らかの病気を患った人だったらしい。弊部屋の壁は本当にペラペラなので、隣の部屋からゴホゴホと咳をしている音が頻繁に聞こえてきた。さすがにちょっと心配になっていたが、今思えばもうちょっとお節介だったら助かっていたのかもしれないなと思うことはある。

金が金を生むということ

 株やクラウドレンディングに手をいくつか手を出した。

izumisy-tech.hatenablog.com

 現時点で、少額だが100万を超える金をクラウドバンクで運用している。見方によっては、どちらかといえば新興の金融商品であるクラウドレンディングだけれども、個人的にはわりとおもしろい資産運用だと思っている。毎月5000円程度の不労所得でポケットに入ってくるのも嬉しい。とりわけクラウドレンディングでお金を運用してみて良かったなと思うのは、よく言われる「金が金を生む」とはどういうことかが分かってきたところにある。

 ロバート・キヨサキの「貧乏父さん金持ち父さん」の最初の章に頻繁に出てくるフレーズとして「金持ちは負債ではなく資産を買う」というものがあるが、結局そのとおりなんだろうなと思っている。自分の収入の大半で資産を買い、残ったお金で慎ましく生活するというのが、4月から社会人になった自分の生活だった。ともすれば、ゲームやら服やらをたくさん買ったり、毎月旅行に行ったりしてお金をいくらでも散財できるが、そういうものにあまり興味が湧かないというのは、わりかし自分でも得な性格だなと思うところがある。せいぜい買ってもプロテインか本くらいなもので、それ以外は散歩でもしてれば大体満足する。

■ その他

基本情報技術者試験に合格した

f:id:IzumiSy:20190104202041p:plain

 自分は文系のバックグラウンドであるため、ある程度情報工学の素養をつけるために受けてみた。毎日チビチビ勉強をするのは、なんとも懐かしい気持ちになった。

そこそこQiitaの記事を書いた

 27記事書いていたらしい。 qiita.com  「今年は100記事書きたい」みたいなことを言っていた記憶があるものの、それには遠く及ばなかった。一部のエンジニア界隈ではQiitaはオワコン、みたいな風潮が散見されるが、いまだに日本語のプログラミングに関する情報についてはQiitaが量的には一番ではないかと思う。自分の場合には毎回英語を使って調べることが多いので、あまり検索結果上でQiitaに遭遇することはないが。

■ 2019年の抱負

目下次の2点かなという感じ

もっと徹底的に節約する

 まずひとり暮らしをして思ったのは、やはり「ひとり暮らしというのはコスパが悪い」ということ。

 どこで聞いたのかは忘れたが「都内のひとり暮らしは最高の贅沢である」という言葉はあながち間違いじゃないなと思わされた。今住んでいる物件の家賃は8万であるが、もはやこの8万を払っていることすらもったいない。ということで今年は早々に物件を引き払い、千葉にある母親の実家に居候をする形にしようと考えている。通勤時間が伸びたところで、その分自由になるお金が増えるのであれば大した話ではない。単純計算で毎月8万の家賃を12ヶ月支払っているということを計算すれば、毎年約100万円をドブに捨てているということが分かる。ケツを拭く紙にすらなっていない。これは確かに最高の贅沢だ。

本をもっと読む

 2019年にはビジネスモデルや不動産、税に関する知識をもっと深めたいと思っている。

 不動産投資関連の本を読んでいて思ったのは、不動産にまつわる節税スキームは日本の税制の歪みを利用しているものが多いということ。結局それらをうまく利用できるかできないかは、自分自身がどれだけ知識をもっているかにかかっている。不動産に限らず、社会人として生きていく上で比較的重要とされる世の中の仕組みは、そのほとんどが学校で学べるものではないし、知っているかどうかで大きく生き方に差がでるのではないかと思うことが多くなった。ビジネスモデルもまた、社会の仕組みの隙間の落穂を拾うような形で生まれているものがあったりと、相互関係にあると思っている。