八発白中

はてなブログに引越しました。

Emacsからlemに移行した

ずっとEmacsをメインエディタとしていましたが、先月lemに移行しました。

https://github.com/cxxxr/lem

lemはCommon Lispで書かれたエディタです。

そもそも自分はCommon Lisperだしlem使うほうが資産がCL界に降りてきて良いよな、という考えもあり使いたい気持ちはありました。

vi-modeさえまともに動けばまあ他の不便は我慢できるか、という状態だったので、vi-modeのバグを上げて修正と機能追加をしつつ使い始めてみました。

結果、なんとか使い続けられています。

この1ヶ月でEmacsを使ったのはSwift書くのに数日だけでした。さすがにシンタックスハイライトもないのはつらい。

活発な開発

lemには毎日コミットがあり「Common Lispプロジェクトでもっとも活発なのでは…?」と思うほど。

この1ヶ月でコミットは200を超えており、今日めでたくv1.4がリリースされました。

  • vi-modeの改善 by fukamachi & gos-k他
  • css-modeの追加 by myao
  • auto-save-modeに自動保存機能追加 by snmsts
  • ファイルエンコーディングエラーの対応 by snmsts
  • js-modeのオートインデント機能 by fukamachi
  • paredit-modeの部分実装 by gos-k & fukamachi

さらにリリース直後にrust-modeが追加されたりと勢いが衰えていない様子。

lemの良いところ

lemの良いところは起動が速いところです。

拡張も含めてダンプコアを吐くので起動が素のVim並に速いです。

起動が速いのでシェルと行ったり来たりできるため、必要ならシェルとの連携もできます。

たとえばQlotを使うには qlot exec lem とかやればlemのREPLがプロジェクトローカルなquicklispを参照します。

Common Lispで書かれているので拡張もContributeも楽です。

lemを使ってみませんか

特にCommon Lisperの方々、lemを使ってみませんか。

インストールはRoswellでできます。

ros install cxxxr/lem

インストールすると lem で起動できます。SLIMEは M-x slime で起動できます。

設定は ~/.lem/init.lisp に書きます。たとえばvi-modeを有効にするには、

(lem-vi-mode:vi-mode)

と書いておけば自動で有効になります。

僕の .lem はGitHubで公開しているので参考にどうぞ。

https://github.com/fukamachi/.lem

lemのバージョン更新もRoswellでできます。

ros update lem

普段使い以外にも、 git config —global core.editor lem とかしておくとコミットメッセージをlemで書けるのでおすすめです。

Mackerelで家族のヘルスチェックをする

5月に入院して1ヶ月くらい療養していました。

健康にも気をつけないとな、と今更ながら反省しつつ、どうすれば健康管理ってできるのかなと考えてみています。

Fitbitログから学ぶ

一年半前からFitbit Charge 2で心拍数と睡眠時間を記録しています。運動量ではなく、主に睡眠時間を計測するためにつけています。

普段は計測するだけして結果を見ることはほとんどないのですが、「今日は頭が働かないな」というときにふとFitbitのダッシュボードを見ると「なんだ睡眠不足か」とかわかるので便利です。

人によって必要な睡眠時間は異なります。僕は週の平均睡眠時間が7時間を切ると体調が悪くなるようです。

入院中に思い立って過去のFitbitのデータをさかのぼって見返してみると面白いことが見つかりました。安静時心拍数が見事に入院まで右肩上がりで推移しています。

単純な心拍数だけだと歩くだけでも上がりますが、これは安静時心拍数。なにもしていないときの平均値です。

もともと自分は安静時心拍数68〜74を推移していたのですが、入院前に88まで跳ね上がっていました。

安静時心拍数が高すぎる場合は頻脈と呼ばれるようです。

頻脈で疑う鑑別疾患は血液疾患(貧血)、精神疾患(緊張、ストレス、不隠、不安)、代謝疾患(甲状腺機能亢進症、脱水)、発熱、呼吸器疾患(低酸素状態)、心疾患(頻脈性不整脈群、心不全、心筋炎:徐脈もあり)等々様々な状態で見られうる。

心拍数 - Wikipedia

要因はおそらく「貧血」か「ストレス」か「発熱」でしょう。

安静時心拍数は異常がなくても上下するのですが、一日の中で出社している時間は高く、家に帰ってくると下がります。

仕事中でも特に上がっている時間帯は会議中だったりして、会議中にストレスかかってるのだな、とか分析できます。

けれど、入院してから頻脈だったことがわかったところで遅すぎます。悪くなる前にこれを知れたらいいのに。

Fitbitの機能として心拍数のアラート通知はありません。

アラートといえばMackerelさん

そこでアラートといえば、と考えに上ったのがMackerelでした。

サーバー監視サービスのMackerelはメトリクスのグラフ化だけでなく閾値での警告通知をしてくれるはずです。そこにデータ投げればいいんじゃない?と思ってやってみました。

Fitbit Web APIを叩いてMackerelに流すだけの簡単なスクリプトを書いて、さくらVPSに設置してcrontabで5分おきにFitbit→Mackerelに心拍数などのデータを流す。

やってみた

↓僕 (Eitaro) の心拍数(左)と睡眠時間(右)

f:id:nitro_idiot:20180531224913p:plain

これは薬の副作用であまり寝られていないときのグラフです。

睡眠時間の折れ線が複数あるのは睡眠レベル別の時間です。Fitbitでは浅い睡眠、レム睡眠、深い睡眠、睡眠中の覚醒時間を計測できます。

f:id:nitro_idiot:20180802105949p:plain:w360

↓これは実際に来ているアラート画面。

f:id:nitro_idiot:20180531224914p:plain

meymao(妻)の睡眠時間アラートも来ています。妻もFitbit Alta HRをつけているので睡眠時間と心拍数を計測しています。

夫婦で普段からSlackを使っているので、MackerelのSlack IntegrationをつけるとSlackにも流れます。

これは5時間程度しか寝られなかったときの通知。

f:id:nitro_idiot:20180802105219p:plain:w360

睡眠レベルを使って熟睡できていないときもアラートが来るようにしています。

さすがに心拍数をSlackに流すとうるさいのでそちらはメールでアラートを飛ばしています。

まとめ

Mackerelのアラートは単純なしきい値だけでなく、過去10個の計測値の平均でアラートできたりします。ので、心拍数のスパイクで無駄にアラートが飛ぶのも抑制できます。

未解決のアラートが続いているときに再アラートする機能も便利です。

たとえば睡眠時間アラートで12時間後に再通知に設定すると夜9時ごろに再度睡眠時間のアラートがSlackに飛ぶので、「今日は早く寝なきゃ」というリマインドとして使えます。

Mackerelの難点は、高いってことでしょうか。プランが「無料」か「月額1800円」しかないです。

無料プランだと24時間しかデータが記録できないので1日1回の睡眠計測では1個しかデータ登録できず、グラフ化ができません。

かといって1800円を個人ユースでは高いな、と思うので間のプランが欲しいところです。

プロジェクト全体でリーダーマクロを有効にする

先日、弊社の新サービス「ポケペイ (Pocket Change Pay)」のランディングページが公開されました。

pay.pocket-change.jp

ポケペイは独自電子マネーを作れるプラットフォームです。プラットフォーム内で換金 (Exchange) もできる仕組みはポケチェらしさがあります。

去年転職して からCommon Lispで仕事してるとは言うけれども、具体的に何をしてるのか聞かれると言えないもどかしさがありましたが、これで言えます。これを作ってます。

APIなどサーバーサイドと、チャージ用端末のクライアントアプリにCommon Lispが使われています。

ポケペイの話はまたいつかするとして、今日は小ネタです。

Common Lispのリーダーマクロ

Common Lispには「リーダーマクロ」という機能があります。

リーダーマクロとは、プログラムのリード時に特定の文字に応じてフックして好きな処理を入れることができる機能です。フックする処理はCommon Lisp自身で書くことができます。これにより好きなシンタックスを作ることができます。

具体例をあげるとCommon Lispアノテーションを導入する「cl-annot」とか。

@export
(defun foobar ()
   ...)

@ という文字をフックして後に続くフォームと組み合わせてS式に展開します。

(export
  (defun foobar ()
    ...))

いわゆる「マクロ」というのはコンパイル時ですが、これはそれよりも早いパース時に実行される点が違います。

この cl-annot は、アノテーションの定義もすることができるので、軽量Webフレームワークの「Caveman2」にはルーティング用のアノテーションがあったりします。

@route GET "/"
(defun index ()
  (render #P"index.tmpl"))

@route GET "/hello"
(defun say-hello (&key (|name| "Guest"))
  (format nil "Hello, ~A" |name|))

マクロでも同様の「機能」はできますが、「修飾」という意図を明確にするという意味で気に入って使っています。理由の詳細は昔書いた記事をご覧ください。

blog.8arrow.org

ASDFシステム全体で共通のreadtableを使う

このリーダーマクロは使いようによって便利ではあるのですが、いちいちファイルの先頭で (syntax:use-syntax :annot) とか書かないといけないのが面倒です。使うときにも、「このファイルでannot有効になってたっけ…」と確認しないと使えません。

これは特にパッケージごとにファイルを分割する package-inferred-system と相性が悪いです。

そもそもreadtableのようなシンタックスに関わるようなものは、プロジェクトメンバーの全員の合意が必要なものですし、ファイルごとにシンタックスを変えたいという需要も少ないように思います。

そこで、ASDFシステム全体でcl-annotが有効になった共通のreadtable使うようにすればいいんじゃね?と思ってやってみました。

ASDF :around-compile

 (defsystem "pokepay-server"
   :class :package-inferred-system
   :version "0.1"
   :author "Pocket Change, Inc."
   :description "Pokepay Project API & Admin site."
   :depends-on ("pokepay-server/boot"
                "cl-syntax")
+  :around-compile (lambda (thunk)
+                    (uiop:symbol-call :cl-syntax :%use-syntax :annot)
+                    (uiop:symbol-call :cl-syntax :%use-syntax :interpol)
+                    (funcall thunk))
   :in-order-to ((test-op (test-op pokepay-server/tests))))

:around-compile 内で cl-syntax:use-syntax しているだけです。上記の例ではついでにinterpolも有効にしています。

こうしておけばASDFのシステム内のファイル全部で自動的にアノテーションと文字列インターポレーションが有効になります。

まとめ

リーダーマクロをASDFシステム全体で有効にする方法を紹介しました。実際に弊社のアプリケーションで使っています。

ゆくゆくはCL21みたいにハッシュリテラルとか正規表現リテラルとかも有効にしていったら面白いかもしれません。

戦略家としてのリードエンジニア

先日THE PREDATORSのライブのためにZepp DiverCityに行った。

軽い気持ちで来たのだがチケットは完売。来場者は想像以上に多く3500人くらいはいたのではないかというほどの盛況だった。

入場してからまだ始まらないステージを眺めている間にも一同、テンションはやや高め。ガヤガヤとした空間で、後ろから一緒にきた仲間と楽しげに話す女性たちの声が聞こえてくる。

彼らは近隣の県から来たのか、昼に巡ったのであろう東京の名所について話をしていた。

「初めてちゃんと東京を観光したー」
靖国神社とか近くまで行くことはあっても入ることなんてなかったもんねー」
「なんか銅像あった!」
「うん、なんか銅像あった。誰の像だっけ?」
銅像あったしその像の名前も見たけど、なんて名前だったか思い出せない(笑)」

それを聞きながら僕は、それは幕末の長州の兵学者の大村益次郎ですね、と声をかけたい衝動に駆られたが、その日の僕の目的はライブであって、歴史に疎い女性陣に大村益次郎の人となりを語り伝えることではなかった。益次郎さんごめん。

大村益次郎。旧名は村田蔵六

蔵六は幕末の兵学者として、「戦術」と「戦略」を明確に分類して考えることができた異質の人間だった。

「戦術」と「戦略」

 蔵六の最終講義は、
「タクチーキのみを知ってストラトギーを知らざる者は、ついに国家をあやまつ」
 という主題のもとにおこなわれた。タクチーキと蔵六が発音しているのは戦術のことであり、蔵六はこれを戦闘術と訳している。ストラトギーは戦略――蔵六は将帥術と訳していた。

「戦術」と「戦略」はどう違うのだろう。

戦術は敵と相対したときに敵を倒すための技術である。剣術や砲術は当然そうだし、軍をいかに動かすかもこれに含まれるだろう。

一方、戦略はもう少し大きい視座で戦いを図る術だ。自軍の周りの地理を知り、時勢を見て、政治を行って、戦いを有利に導く。

最初に聞いたときはぼんやりと、そういう区分もあるか?とわかったような顔で読み流していた。具体的にどのような例があるかは、幕府が品川台場に築いた砲台についてのエピソードがわかりやすい。

「江川先生の品川台場は、戦術的なものにすぎない」
 と蔵六がいうのは、そこである。敵艦が台場すれすれに近づいてきてくれてはじめて砲が発射できるわけで、そういう間ぬけな軍艦はおるまい。それに艦砲の射程がどんどんのびているということを考えていない証拠に、砲台の砲がいかにも小さい。砲というものがいっさい発達しないという前提のもとに江川先生が設計したとしかおもえない、と蔵六はいうのである。

戦略的な視座に基づいたものでなければこういった間ぬけな策を打ってしまうことになる。

自分は戦略をわかっているか?

ふむふむ、と村田蔵六の話に関心しつつ本を閉じて、ふっと自分のことを振り返ってみた。

自分は戦略をわかっているだろうか?

僕はプログラマとして様々な会社に所属してきた。そこではできる限り良いプログラムを書くことでプロジェクトに貢献してきた。Common Lispのライブラリを多く作ってオープンソースで公開してきた。

これらの今までの活動はそれなりに評価されているとは思う。けれども、これらのどれを取っても「戦術」でしかない。

プログラムを書く、ということがそもそも戦術である。良いプログラムを書くのはプログラマにとって期待されていることではあるだろう。しかしそれとプロジェクトが成功するかどうかは別だ。

自分はプロジェクトの成功のために具体的な「戦略」を立てたことがあるだろうか?

いやいやそれは一介のプログラマの仕事ではなく上層のマネージャーの責務だ、という意見もあるかもしれない。けれど、組織にとってそんな無責任な戦術家にどれほどの価値があるだろう。

優秀なプログラマは凡人の10倍も20倍もの生産性があると言われる。それは確かに価値があることだ。しかし、戦場で100人や200人の敵兵を破ったからと言って自軍が戦に敗れては意味がない。

戦略家として生きる

ポケットチェンジに入社して1年が経った。

雇われた僕の役職はリードエンジニアである。ただのエンジニアではない。プロジェクトをリードし、成功に導くことを期待されている。

僕はCommon Lispの技術力を買われて雇用されたのは間違いないだろうが、雇われたのがLisp書きという戦術家ではないというのはなかなか期待が重たい。まあ勝手な責任感かもしれないけれども。

去年は30歳の誕生日を迎える節目の年だった。僕もプログラマとして次のステージに上がるべきときなのかもしれない。

そんなことを考え、今はポケットチェンジで新サービスの成功のために戦略家としてフルコミットを続けている。

僕には目標がある。

日本中で使われるサービスを作ること。そしてそのサービスがCommon Lispで動いていること。

求人

いつか僕が関わったプロダクトを紹介する機会もあるでしょう。

もし一緒にポケットチェンジで働くことに興味がある方はご連絡ください。

E-mail: eitaro.fukamachi@pocket-change.jp

なぜShibuya.lispは成功し続けているのか

この10月の3連休を利用して、大阪で開催された関西Lispユーザ会にお邪魔しました。

kansai-lisp-useres.connpass.com

一枠空きがあったので20分程度の発表もさせていただきました。いまいち余計だったかもしれません。

すべての発表が終わったあとにイベント終了まで少し空き時間がありました。その時間を利用して運営の一人の油谷さんから関西Lispについての運営指針の話がありました。内容は「Shibuya.lispは作ったプロダクトの発表の場になっていて発表のハードルが高い。関西Lispは気軽に発表してもらい、アットホームなコミュニティにしたい」というものでした。

僕は東京に住んでいることもあり普段はShibuya.lispコミュニティに参加しています。運営者とも話す機会が多いので運営指針もそれなりに聞いています。そういう立場で話を聞いていると「ほう、外からはそのように見えるのか」と非常に興味深く思いました。

Shibuya.lispの運営指針

実際のところShibuya.lispのイベントでの発表に具体的な制約はありません *1。発表したいと思った人が好きなテーマで好きな時間を使って発表できます。

「ライブラリを作りました」とか「ISLisp処理系を作りました」というような技術的に高度なものが目立つし事実かなり多い、というのは言われてみるとそうだな、という程度であまり意識したことはありませんでした。結果的にハードルが高くなって発表しづらくなっている、といえばそうなのかもしれませんが、かと言って逆に高度な発表を禁止するというのも違うでしょう。

そんな高度な発表も多くありながら毎月のイベント開催を5年弱もの期間継続しており、毎回20人前後の参加者を集めているというのがShibuya.lispの歴史とコミュニティの成熟による成果なのだとすると素晴らしいことだと僕は思います。

なぜShibuya.lispは成功しているのか

このようなShibuya.lispの成功は、東京という地の利はあったにせよ、運営陣の努力なく達成されているものではありません。

この辺りのポイントはκeenさんの以下のエントリーにまとめられています。

4年間続いたShibuya.lispのLispMeetUp | κeenのHappy Hacκing Blog

特に僕が重要だと思う点は「運営の負荷を減らした」ということです。

安定的に毎月のLisp Meetupの行うにはどうすればいいか。属人的な努力には依存しないことです。誰かの大きな努力に依存すればその人が忙しくなったタイミングで開催が途絶えます。

たとえば毎月安定して使える会場を用意することで、会場を手配するコストを減らしたり、毎月の開催テーマをローテーションすることで、何をやるかという運営の決断コストをなくすなどの工夫がなされています。

「発表者が集まらない問題」の解決策

加えて、関西Lisp油谷さんが問題としていた点は「だんだん発表者が集まらなくなっている」ことでした。

発表者を、関東陣の僕を除いて、4人も集められているのだから全く問題に感じる必要ないのでは、と思いはするのですが、イベント運営者としてはありがちな不安なので理解はできます。

Shibuya.lispの初期の運営のTech Talkも同じ問題を抱えていました。Tech Talkを定期開催しようとしても発表者が集まらず、運営が伝手で発表してもらえそうな方にお願いしており、それが運営陣の負担となっていました。そしてそれが「どうせ開催しても発表者集まらないしな」というネガティブな空気にも繋がり、運営が途絶える要因となります。

Shibuya.lispの運営が第2期メンバーに引き継がれたときに上記の問題に対する重要な決断は「発表者がいようがいまいが開催する」ということでした。

「そもそもShibuya.lispが何を目的として存在するのかを考えなくちゃいけないんじゃないですか」

単にイベントを開催するにしても、なぜ、というのが明確でなければいずれまた目的を見失う。Shibuya.lispは何かの手段であって、目的ではないんじゃないか、と。

僕のその言葉に一同黙り込んだ。さあ、Shibuya.lispをやる目的とは何だろうか──。

そのとき前運営の立場として参加していた佐野さんが言ったことは、図らずも新しい運営方針を決定付けたものかもしれない。

──「理由はそのコミュニティに集まった人々で作ればいいことで、我々はただその箱を用意すればいいんじゃないかな。だとすれば、『続ける』ということも十分目的になるよ」

Common Lispのコミュニティ事情 - 八発白中

発表者がいなければいないでいいのです。集まったメンバーで自己紹介をしてだらだら話をするでもよし、その場でライブコーディングを始めるもよし、早めに切り上げて飲みに行くでもよし。何にせよ場を作り続ける、ということを目的としたことは振り返っても成功の要因だった気がします。少なくとも「発表者が集まらない…」と運営陣が嘆くような心理的コストも減り、イベントの安定開催に一役買っています。

そういったShibuya.lispでの経験から言えば、油谷さんの不安は理解はできるけれども、あんまり心配しても仕方ないのでは、と思うわけです。

*1:Lispに関係すること、というのが唯一の条件だったと記憶。