How IT Works

プログラマーやっています。技術よりも人間学的なところが好きです。

途中参加のプロジェクトに慣れるまで

近況

 最近、これまでとは違うプロジェクトに途中参加することになって、大きな環境の変化に対応する日々を過ごしていました。

 これまではフロントエンド・バックエンドの両方を触っていましたが、今はほぼフロントエンド専任です。

 技術的にはNuxt.jsが中心で、Angularに似ているとはいえ、その違いを吸収するのに時間を使っていました。

 事前にNuxtとVueの情報を拾っていたので「たぶん、行けるだろう」と思いきや、プロジェクトの理解に半日ぐらいかかって、自分の中で困惑することが多かったので、その知見を書いてみようと思います。

プロジェクトを理解するまで

実際の画面を触ってみる

 参加するころには大体の画面はできていたので、とりあえず何も考えずに触ってみました。ある意味、ユーザー目線に近かったので、この時の気持ちを書いておけばよかったのでは、と今更ながら思ったりします。

 何となく20分ぐらい触って大体の機能を拾っただろう、とこの時点では思っていたのですが、ここで開けなかったページがあったみたいです。

 手探りだと体系的にはいかないですね。ちなみに仕様書はあったそうですが、「最初は書いていたけど、更新されている自信はない」といわれたので、あまり確認していません。

フォルダ階層をざっとみる

 Nuxtは基本階層が決まっているので簡単かなと思ってみていました。

 2階層目以降は、スマートフォンとPCでコンポーネントを分けているという話を事前に聞いていたので、まだつかめました。

 3階層目はドメインごとに切られていましたが、ここがわからなかったです。実際の画面の言葉は日本語で、ファイル名は英語なのでそこが微妙にしっくりきませんでした。

 それでもなんとなくは理解して、これで仕事できるかなと思いました。

直近のIssueを直してみる

 Issueをつぶすのが当面の仕事だと言われていたので、直近3つぐらいのものを適当に取り出して、直せれば理解できたんじゃないかと勝手に考えて、やってみました。

 ですが、全然できませんでした。

 Issueは大体ドメインの言葉で書かれていて、それがどこに当たるのか全く分からないという感じです。Issueも砕けた表現が多く、暗黙的に大体知っているよねみたいなコンテキストで書かれている気がしました。

 なので、まずIssueの内容が理解できなかったので、その対策を考えました。

用語表を作る

 とりあえず、ドメインで使われている用語、変数名、意味の対応表をひたすら作っていきました。

 コンポーネント志向なので、その階層も意識しながらひたすら書き込んでいきます。

 そうすると明らかに同じ意味でありながら、違う変数名があったり、違う階層なのに名前が近いものなど不思議なものもいくつかありました。

 そういう絶妙なものが理解を難しくしていたところもあり、それをはっきりと定義づけできるとやっとIssueの意味が理解できるようになりました。

コンポーネントを図にする

 最後にIssueはデザインを修正するものだったのですが、意味が分かってもコンポーネントの配置関係がわからないと直せないなとなりました。

 最初は開発者ツールでやっていましたが、同時の視認性が弱いなぁと思って、スケッチブックにページごとにコンポーネントの配置を書きました。

 それで見ると、どこがデザインの要なのかがわかって、それでIssueの解法がわかりました。そこまでくると、他のIssueもやっつけられそうになったので、理解を終えました。

知見

Issue駆動でプロジェクトをとらえる

 最初は漠然とプロジェクトを見ていましたが、「何を知りたいのか」「何を直したいのか」をはっきりと定義することで理解が加速した気がします。

 それがIssueである必要はないと思うのですが、はっきりとした問いを立ててそこから理解するようにするとものの見方が定まるように思います。

用語を理解する

 用語の問題がここまで大きいとはあまり考えていなかったです。バックエンドのロジックであれば、DDD的なものの見方が大事だと思っていたのですが、フロントエンドの部品もドメイン的な性質が大きいんだなと感じました。

 名前と意味を正確に定義するということ、フォルダの切り方の大切さと、最初にそれを説明するのが結構大事なんだなと思いました。こういうのもREADMEにあってもいいのかもしれないですね。

手を動かす大事さ

 見るとか、理解するという感覚は漠然としやすいです。なので、書くことが大事な気がします。

 コンポーネント図を作っていると見やすいというのもありますし、能動的な頭の働きがあって、疑問とかも浮かびやすいです。なので、最近は複雑なことを始めるときは大抵紙から始めます。

 Scrapboxとかに表を書くこともありますが、どちらにせよ見るではなく新しく作るのがいい気がします。

まとめ

 今までライブラリとかを覗くことが多かったので、「今回も大丈夫だろう」という謎の自信があったのですが、実際業務レベルで理解するとなると戸惑うところが大きかったです。

 これまではベストプラクティスの勉強が多かったのですが、そこにドメインが絡んできたり、デザイン回りの話が絡んだりで必要な見方が違ったんだろうなと思います。

 その中で問題を整理しながら、理解のための手順を踏めたのはいい経験になりました。

 あとから、Vue.jsのDevtoolsを使えば、もっと早かったのでは思いましたが、紙に書くのが少し楽になるぐらいの感じでしょうね。

 新しくライブラリを見るときあたりに、こういう視点で見れたらまた知見がありそうなので、それもやってみたいです。

ポートフォリオ作りました

成果物

公開ページ(GitHub Pages) dexia2.github.io

ソース github.com

製作期間

構想:1週間

基本的な実装:5日

動機

 エンジニアなのにも関わらずあまりOSS活動をしておらず、簡単な技術を証明する何かが必要だろうと思い立って作りました。

デザイン

 デザイナーではなくプログラマーなので、なんとなく機械的というか2次元的な感触のデザインのほうがイメージに合うかなと思って、そうしました。

 また、最初にレスポンシブ対応もすると決めました。ポートフォリオにたどり着く方の多くはPCでアクセスするような気もしましたが、技術力の一つとしてスマホ用のデザインが要求されることも多いので対応することにしました。

 内容は業務経歴書などを参考にしました。

使った技術

  • Angular6
    • TypeScript
    • Scss
  • Angular Material
  • Chart.js
  • reset.css

 大体、業務で使っている技術スタックそのままです。

デプロイ先

 凝ったものではないので、GitHub Pagesを使わせてもらいました。

感想

AngularとAngular Materialが便利

 静的Webサイトを作ったのは初めてなのですが、Angularから始めるととても楽でいいです。

 TypeScript、Sassあたりのビルド設定、自動更新のサーバーを勝手に用意してくれますし、CSSカプセル化されています。

 それを自前でやることで技術力を見せるべきでは?と言われるとその通りなのですが、主題に早く入れるのはありがたかったです。

 Angular Materialのパーツはレスポンシブデザインに対応していて、そのまま使えました。デザインは一部書き換えましたが、その方法もシンプルなのですごく楽させてもらいました。

技術的に遊べる

 CSSはFlexbox、CSS Grid Layout 、アニメーションあたりを使って、すごく楽しんでいました。業務ではライブラリに投げている部分も多く、自前で組む楽しさがありました。

 あとは色々な方のWebサイトを開発者ツールで覗きながら開発していたので、勉強になりました。

 最近は常時、開発者ツールを開いて文書構造とCSSを当てるゲームをしていますが、結構楽しいです。

プログラマーの技量はあまり示せなかった

 TypeScriptでガリガリ書く部分がそうそうなかったので、マークアップを頑張ったぐらいしか伝わらないなぁと感じました。

 最近はCSSでできることが多くて、スクリプトで頑張らなくても大体のことはできました。

 WebGLとかで表現を入れようかと思いましたが、自分のPCだとカクカクするので、あまり情報を見るためのサイトに使うのもどうかなという気持ちがあります。

今後

 コンポーネント化の構想だったり、アクセシビリティだとかを含めてもう何回か見直すだろうと思います。

 ただ、今回は無難に作りすぎたきらいがあるので、もっと遊んだものを作りたい気持ちがあります。最初は中国風のデザインを目指して、太極図や陰陽五行、八卦のアニメーションなどを作ったりしていましたが、レスポンシブ対応が辛くて諦めていました。

 今回とりあえずの成果物を作れたので、趣味のほうも試せる環境にあります。なので、今後はちょっと遊びモードに入れたらなぁと思います。

まとめ

 CSSやデザインの勉強がしたい人の題材として、ポートフォリオづくりはいいと思います。

 早急にポートフォリオを作る必要がある人はAngularとAngular Materialを使うと、サクッとできて楽です。

最近取り組んできたこと(2018年4月~8月)

Web周り

表現方法の工夫

 アニメーションへの興味がなぜか沸々とわいてきていたので、そこらへんを追求していました。

SVG

 仮想DOMとSVGを組み合わせれば、独創的なUIがサクサク作れるとどこかで聞いたので、Angularであみだくじを作ってみました。

github.com

 コンポーネント化したりとか、定数の外出しをしたほうがいいんでしょうけど、技術的な実験だったので1ファイル簡潔でさらさら書きました。

 最初はdivと罫線で頑張っていたのですが、線に触れた時のイベントまわりが複雑になりそうだったので、SVGに転換しました。

 line要素とか、直感的にマークアップを書けるのでよかったです。x軸、y軸の計算ロジックは増えたので、そこらへんは多少面倒でしたが。

CSSアニメーション

 ローカルで色々と試していました。あんまり実例は残っていないですが、キーフレームあたりもちゃんと理解したので、ローディングとかは自前で書けそうなレベルです。

 キーフレームとSVGを組み合わせてというのとか、あとはCSSの変数を使ってローディングの%表示をするというのが面白かった記憶があります。

3D

 本を読んで勉強したり、APIのリファレンス、リポジトリを延々と眺めていました。

 ただ、三角関数や頂点の計算などが合って、かなり数学的なにおいがして、手を出せていません。WebGLは直で触っても行けそうな感じはしましたが、three.jsとかのほうが情報量が多そうで悩み中です。

 CSSでも簡単なものならできるらしいですね。

Chrome 拡張

 Slackと連携したり、Amazonへのリンクを飛ばしたり簡単なものを実装しました。

 地味に便利なことができそうと思いつつ、それ以降は触っていません。でも、簡単な割には可能性を感じました。

言語の勉強

Clojure

 core系のAPIと実装を追うところまではやっていました。core.matchの実装が拡張ポイントを押さえていて気持ちいいなぁとか思っていました。

 core.async、core.logicは使い方だけ抑えたところで終了。

 APIとか実装を調査して記事を書こうと思ったのですが、思いのほか皆さん色々紹介してくれていたり、APIリファレンスが詳しかったりしたので、途中で挫折しました。

 とりあえずClojureで書ける大まかな手法は理解できたんじゃないかと思って、ちょっと最近は別居中というかそんな感じです。

いろいろな言語に手を出す

 なぜかいろいろな言語への興味がわいてきたので、手あたり次第に言語の勉強をしています。

 どの言語も一度は勉強していたのですが、疎遠になっていました。Clojureを理解したあたりで、もう一度勉強し直してみるとなぜかすいすい頭に入ってしまって、はまってしまいました。

 Pythonも以前見た時は普通じゃないか?と思っていたのですけど、今見ると色々そろっていてまぁ使いやすいよなぁと思ったり。

 とはいえClojureをまじめに触った時に本当に言語を学ぶときは集中して時間を書けるしかないと学んだので、どこかで絞るだろうと思います。

 最近の流れだとPythonとGoですかね。言語的にはRustとScalaが好きですが、いかんせんそういう用途で書かないので。

 ちなみに、自分は1冊の技術書を1日20ページ以上読めないので、分散しています。こういう読み方が単に好きなんですね。

 勉強方法としては

 あたりですかね。技術書を読んだ後、具体的なリポジトリを探してにらめっこが一番多いパターンな気がします。

今後

 諸事情で趣味よりは技術的にやっていないところを補うことになると思います。

  • GraphQL
  • React/Redux
  • WebSocket
  • WebWorker

 ここらへんと趣味のバランスが難しいですが、どこかでまとめてやらないとつらそうですね。

 言語の勉強が楽しすぎて実用性より構文を眺めてしまうので、ちょっとそっちは休憩しないとかもです。

Clojureを歩いている

前書き

 昨年9月ごろからLispを勉強しています。

 Lispを1か月勉強して - How IT Works

 最初はCommon Lisp、途中からEmacs Lispを経たりして、今はClojureを勉強している感じです。

 以前は「リーダマクロがない?、引数はベクターで受け取る? そんなの邪道だ」と思ってCommon Lispを中心に考えていましたが、今はClojureの設計はとてもきれいだと思って、その考えをとりあえずできる限り盗もうと思って頑張っています。

 Clojureのimmutabilityあたりにちょっと詰まりましたが、それさえ乗り越えれば、Clojureはとてもシンプルで使いやすい言語だと思います。

 逆に言うとClojureはなんとなく使いやすい言語で、なんとなく書けるのでその先に行くには意識的な努力がいるんじゃないかなというのが今の感想です。

 だから、最初はとりあえずなんとなく書きたいものを書いて、読みたいものを読むというスタンスでしたが、計画的に努力するように心がけているところです。

勉強のメディア

プログラミングClojure

 最初は本を読んで勉強していました。

 「プログラミングClojure」は日本語の中では一番まとまっていてよかったです。改めてみるとつまみ食い感がすごい気もしますが、大事な情報がきちんと入っていて3回くらい読み直しました。

 今ならちょっと古いのかもしれませんが、選択肢があまりないので導入なら問題ないかなと思います。

プログラミングClojure 第2版
Stuart Halloway and Aaron Bedra
オーム社
売り上げランキング: 346,168

Clojureによる、初めての関数型プログラミング

 基礎を固めた後としてはこれがよかったです。とてもシンプルな設計でどうやってアプリを作っていくかを学べてよかったです。

 全体としてみてどうかといわれると難しいですが、細かいテクニックとかはこれで覚えた気がします。

Clojureによる、初めての関数型プログラミング
gpsoft (2013-09-28)
売り上げランキング: 64,595

Clojure Programming

 ちょっと学んだらあとは英語で頑張れというのがClojureですが、洋書のなかで1番好きなのはこの本でしょうか。

 一つ一つの概念について丁寧にページを割いて説明してくれていて、構文への愛があります。多少古いので最先端ではないのかもですが、Clojureを学ぶという意味ではとても好きです。

 洋書であればWeb、機械学習に絞ったものなど色々ありますが、自分はきちんと基礎から学びたいタイプなのでそういう系はあんまり肌に合っていない感じはします。

 関数型、リアクティブプログラミングの設計あたりは次あたりに読んでみようかなぁと思っています。

Clojure Programming
Clojure Programming
posted with amazlet at 18.04.21
Chas Emerick Brian Carper Christophe Grand
Oreilly & Associates Inc
売り上げランキング: 69,016

Web

Git Hub

 最初はClojureのTrendのリポジトリを眺めていました。

 Trending Clojure repositories on GitHub today · GitHub

 でも、ClojureのTrendは毎日ほぼ変わらないですし、上がってくるのはほぼデータ系でこれだけに頼るのは厳しいですね。感覚的にはRubyとかJavaScriptあたりだと変動が大きくて面白かったんですけどね。

 勉強が目的なら、Clojureの公式のリポジトリをめぐるほうが楽しいと思います。

 github.com

 その先の調べ方はあんまり考えていないので、今発掘中です。

Clojure Docs

 Clojure Docsを眺めるのも勉強になってよかったです。APIにどんなものがあるか眺めるのも楽しいですし、サンプルを自分なりに作り直してREPLで叩くのも楽しいです。

Community-Powered Clojure Documentation and Examples | ClojureDocs

 Clojureは細かい関数、マクロが多いので時々API一覧を見て不要な処理を本当に書いていないのかを確かめるのがいいと思っています。

その他

 Qiitaとか、ブログとかはちょいちょいありますが、あまり更新されていないので主要な情報源にはならないかなぁという印象はあります。

 Clojure界隈にはとても優しい方々がおられるので、そういう人たちと仲良くしながら情報がないかアンテナを張っておくほうが大事かなぁと思います。

おすすめされた情報源

 一応自分なりの勉強方法はあったものの百戦錬磨のClojurianたちはどうやって勉強されているのか聞いてみました。

 redditとMLは確かに毎日眺めるにはちょうどいい感じでした。

 Podcastなどはいくつか聞いてみて、意外に英語でもプログラミング系ならわかりました。ただ、通勤しないので、聞くタイミングがなかなか作れないのでもう少し考えたいです。

 transcriptsはかみ砕きながらみないと難しいですが、研究材料としてはこれ以上なく楽しそうでした。

勉強の方法

REPL it

 やはり書くことが一番の勉強だと思っていて、本でもWebでも面白いものを見つけたらREPLに打ち込んで改変してテストするのが一番よかったです。

 マクロあたりもずーっと読んでいるだけではわからなかったものの、色んなパターンをうちこんでもう最近は間違えないですね。

テーマをもってやる

 前にも書いたのですが、Clojureは自分の思うように書きやすすぎるので特定の構文を使わなくても意外に何とかなります。自分だと、

 とかは別に自分で書かなくても何とかなるというところがあって、やっぱり時間をとって研究しないといけないなという風に思っています。

 そのためには何かアウトプットを書くといいのかなと思って、Qiitaとかにあげたりしています。正直、Clojurianの方々から見るとミスリーディングなどが多くて恐れ多い部分もありますが、それを自分だけで認識できないので開き直ってアップするという感じです。

 今のところこんな感じです。

Clojureの長めのマクロを読む - Qiita

Clojureのクォート - Qiita

メタ・テスト - Qiita

 Clojure公式リポジトリの構文上の比較研究が多いですが、いずれはライブラリ、プロジェクトあたりの研究をして、それが終われば自分なりの形を作れればいいかなと考えています。

 Clojurianへの道は遠いですが、自分は少しずつ進むほうが性に合ってそうなので、地道にやっていきます。

まとめ

 ClojureC#とかJavaScriptに比べて日本語の情報量が少ないので、より情報を得る手段が洗練されてきている気がします。

 実務はLispではないので、きっちりこのやり方をそちらにもフィードバックしていけたらエンジニアとしてのランクがちょいと上がるかなぁとか考えます。

 最近は実用物はあんまり考えていませんが、Lispの長い歴史を追いながらエンジニアはどういう風にしてきてこれからどうなっていくのだろうかというところにも興味があり、どうしようかは迷っています。

 ただ、今とても楽しいのでもう少しだけ、研究という体で学んでいきたいです。やり方がガラッと変わったら、また何か書きます。

最近取り組んできたことの振り返り(2017年末~2018年3月)

動機

 思い返すと、2017年末くらいから色々とコードを書くようになって、それなりに形にできたのでその振り返りをしたいなと思います

やってきたこと

配球ゲーム

github.com

 バドミントンの配球を2次元に落とし込んで読み込んでみようという試みで書いたシミュレーションです。製作期間は2か月足らずくらいでしょうか。

 細かいところは大体Qiitaに最近は書いているので、技術的なところはそこを見てもらえれば。

ClojureScriptで配球予測ゲームを書いてます - Qiita

 感覚的なところで言うと、これが一番収穫だったかなぁという印象です。

 Lisp系の言語を使ってそれなりに知見を貯められたとかそういうところもありますが、自分の思考とプログラムを近づけるということが一番自信を持ってできたというところで価値があります。

 表現が伝わるか難しいですが、ライフハックそのものではなく思考を拡張することこそがシステムの価値じゃないかという思いがあって、 そこに踏み込めた第一作としてはとてもよかったです。

統計ごっこ

github.com

 バドミントンのいいデータセットが見つからなかったので、とりあえず人力でJSONを書いてそれで分析していました。

 1試合どころか1ゲームで6時間かかったので、途中でまじめにやるのは無理だとわかりました。

 分析結果は一応他のブログに書きました。

バドミントン・メモ:女子シングルスを数値で見る

バドミントン・メモ:女子シングルスを数値で見る2

 簡単な分析であってもそれなりの知見が得られることはわかって、その点では満足でした。

 ただ、複雑な分析をする手段をもっていないので、そこが足りないのかなと思いました。ストローク同士の関連を見たり、複雑な相関を見る道具がそろっていないのは実感しました。

 Rとかを触ればいいのかなぁとか色々模索はしていますが、結論は出ていないです。

 また、データセットをとるためには、たぶんYoutubeAPIとOpenCVを組み合わせたりして自分でやるしかない気がしていますが、そこまでの価値があるのかちょっとわからないので、保留中です。

指示出し器

github.com

 何も考えずに買ったAmazon Echoを買いました。

 練習の指示を出したら楽しいんじゃないかと思って、指示を出してくれるスキルを作りました。

 でも、Alexaは対話型なので、一方的に話しかけてほしい自分の願いはかなわなさそうだったり、そもそも音声に反応する練習を積んでも意味がないのではと思い作って終わりです。

 ついでに作ったメモ用のスキルのほうが役になっています。

GitHub - dexia2/MemoSkill: Slackにメモを保存するスキル

Alexaを使ってSlackにメモを保存する - Qiita

 練習メニュー管理、量の記録あたりなら役に立つかもですが、ちょっと考え中です。練習テーマあたりを言ってくれたらうれしいかなぁ。

 可能性は感じましたが、まだ積極的には生かせていないです。

書籍管理

Google Apps Scriptで書籍を管理する - Qiita

 珍しく実用品を作りました。

 とはいえ、似たようなサービスはもうあるらしいので、技術の実験的なところですね。Google App Scriptは便利で自分のような個人用作品を使うにはまぁそれなりに使えそうでした。

 やる気がないところをやる気がないなりに成果を出すというところでは最高です。

振り返ってみて

 やはり一番よかったのはProcessingで遊んだ配球ゲームですね。

 機械学習や統計、画像処理をやることで他の人に貢献できるんじゃないかという気持ちはあるのですが、自分の感覚とどれくらい一致するか?というところを考えるとビジュアライゼーションの優先度が高いかなぁという気がしています。

 あるいは練習管理が結構大事で、練習のテーマ管理、テスト管理、あとはモチベーション管理あたりが課題になっていて、そこらへんの心理的側面をどれだけシステムで行けるかなぁというのが今の気持ちです。

 いろんな技術をまたげるようになってきた感じはしますが、まだ本質に近いものを量産できていないので、そこにまた近づけたらいいなと思います。

 それはさておき、Git HubとQiitaはエンジニアのInstagramとは言いえて妙ですね。本当にそんな感じです。

Emacsを使い始めての感想

前書き

 1か月ほど前から本格的にEmacsを使い始めました。

 何か1つくらいエディターを極めたいなぁという願望はずっと持っていて、ちょいちょいVimを触ったりはしていました。

 しかし、Pythonを入れないと解決しない問題に遭遇した際に、もともとVim scriptを好きになれなかったのもあって、手放してしまいました。特にバージョン絡みの問題だったので、さすがにそこまで環境を汚すのはあんまり。。という気持ちでした。

 加えて、Lisp系の言語で遊びたいという従来の目的をするにしてもVImはあんまり有効でないこともあったので、それならEmacsのほうがいいだろうと考えて乗り換えました。

 いざとなれば、Spacemacsに乗り換えればいいという保険もあったので、気軽な気持ちで使い始めました。

github.com

やったこと

VsCodeEmacsのキーマップを入れる

 業務ではTypeScript+Angularを使っていたので、エディターは相性のいいVSCodeを使っていました。

 いきなりEmacsに移るのは難しかったので、キーマップをEmacsにしてキーバインドを覚える練習をしました。

Emacs Friendly Keymap - Visual Studio Marketplace

 最初はMキーとCキーの使い分けがまったくできず、移動にC-fとか二つのキーを使うのは逆に面倒じゃないかと思いながら、ひたすら耐えていました。

 1週間くらいで基本操作ができるようになり、2、3週間でC-a、C-k、C-yという連続技が使えるようになり、やっと楽しいと思える瞬間がたまに来ました。

 そのころにはEmacsの環境が大体できたので、Emacsに乗り換えました。

本を買って勉強

 いろいろEmacsの本を買いあさって、どんな風にするのがよいのかという情報を集めていました。

 特によかったものを選べといわれると、普通ではありますが、下の2冊でしょうか。

入門 GNU Emacs 第3版
入門 GNU Emacs 第3版
posted with amazlet at 18.02.10
Debra Cameron James Elliott Marc Loy Eric Raymond Bill Rosenblatt
オライリー・ジャパン
売り上げランキング: 326,673

 ただ、どちらも悪くはないにせよ、Vimで言うところの「実践Vim」みたいな「これさえ読んでおけば大丈夫!」というものはない印象ですね。

 結局、Webの断片の情報をかき集めながら進んでいくというスタイルをとらざるを得ず、入り口があるようでない感じがしました。

 入門者にとってはあんまり優しい環境とは言えないかもしれないですね。

カスタマイズを始めた

 いろいろやったので、あんまりまとめて書くのは難しいですが、

  • デフォルトの変数をいじくった
    • 行数表示とかハイライトとかテーマとか
  • キーバインドの変更
    • 特に削除系のキーバインドとバッファー操作系を変えました
    • あとは C-c k とC-c C-kとかを間違えやすいやつを書き替えました
  • プラグイン導入
    • 大体el-getで入れました
      • これはたいそう便利でした
  • diredとかorg-modeとか既存機能で遊ぶ

 カスタマイズの楽さにはびっくりしました。新しいコマンドの定義とか、キーバインドの変更、プライグイン導入どれもパパっとできたので、思いついたらいじくれるのは最高です。

評価

欠点

キーバインドが使いにくい

 前にも書きましたが、キーバインドになれるのはなかなかつらいものがあります。

 そういうものだと割り切ればいいのですが、Vimに慣れているとちょっと不合理じゃないかというキーバインドがデフォルトで多すぎます。

 割り当てられている関数も微妙に使いづらいものが多い(特にカット関係)印象がありました。

Emacs Lispが絶妙に使いづらい

 正規表現エスケープとか、ダイナミックスコープがデフォルトであることとか、基本のAPIが地味に貧弱であるとか書いていて、時たまいらいらすることがありました。

 Common LispとかClojureとかに慣れていると、感覚がずれてしまうこともあり、結構はまりやすいですね。Lisp一族といえど違いはそれなりに感じました。

静的言語だとIDEにできて、Emacsにできないことが多い

 そんなに静的言語を触ったわけではないのですが、C#とTypeScriptに関していうとリファクタリング、ビルド、あるいは補完という面で他のエディタと同等に持っていくのはつらいかなという感じがしました。

 それにここらへんはIDEを使う人が多いため、情報もそんなにないという点で苦労しています。

 Clojureとかの動的な言語で書いているとそこまで気になるレベルではないですかね。

長所

カスタマイズが容易

 気に入らなければ変えてしまえばいいという思想なので、短所で書いたキーバインドEmacs Lispの問題は自力で解決できます。

 それがいいか悪いかという話はありますが、気になった瞬間手を動かして試せるのは個人的には面白いと感じます。

情報量が多い

 他のエディタよりも歴史があるので、自分が苦痛に感じることは大抵解決済みです。そういう意味、いろんな知識を使いやすく、やはりハックする余地がとても広いような印象を受けました。

総評

 正直に言うとハックが好きな人でなければ、そこまでメリットは大きくないという印象を受けました。

 ロードマップがあるわけでもないですし、最近のIntelliJ IDEAを超える機能性を提供できるかというと、かなり頑張らないと厳しいでしょう。

 ただ、プログラム言語が好きな人やエディタ自体を愛する人にとっては遊び道具としてはとても優れていると思います。

 気が向いたらscratchを開いてアイデアを試したり、他の人のEmacs Lispを読んで遊んだりできます。何より、気になれば直せばいい自由は何よりもありがたいと思います。

 自分はもっと深く、深くエディタ自体に没入して遊びたいので、しばらくはEmacsで行こうかなと考えています。Spacemacsはもう少し素のEmacsで遊んでから試してみるかもしれないです。

github.com

「30 seconds of code」個人的10選/30秒で楽しめるES2015パターン集

前書き

 ES2015はJavaScriptにとって大きな変革で、開発者にとっては大きな困惑を生んでいるようです。

 いろんなAPIが増えたり、新しい構文が出たりでなかなか使いこなすのは確かに大変だと思います。

 そこでES2015を効率よく習得できるパターン集が出されています。1問30秒で解けるくらいの問題が、大量に並んでいて非常に勉強になります。

30secondsofcode.org

 それだけでは寂しいので、その中から個人的に気に入っている問題をとりあげて簡単に解説します。

 30秒考えて、何をやっているのかわからなかった人はぜひ上のサイトに挑戦してみましょう。

問題10選

pipeFunctions

const pipeFunctions = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args)));

// example
const add5 = x => x + 5;
const multiply = (x, y) => x * y;
const multiplyAndAdd5 = pipeFunctions(multiply, add5);
multiplyAndAdd5(5, 2); // 15

 これはいわゆる関数合成のための関数ですね。関数を順番に適用していって、最終結果を出力しています。

 Arrayのreduceメソッドは配列の要素一つずつに順に関数を適用していくという処理なので、関数の配列を作って回すとこういうことができるという好例です。

 また、...(ピリオド3つ)という記号はスプレッド演算子といって、配列を動的に展開するものです。

 これを使うことで引数を可変長で受け取れたり、新しい配列を簡単に作れたら非常に便利なことができます。ここでは、配列を引数に受け取らない関数で使えるように、使っています。

deepFlatten

const deepFlatten = arr => [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v)));

// examples
deepFlatten([1, [2], [[3], 4], 5]); // [1,2,3,4,5]

 多次元の配列を全部つぶして、1次元の配列に戻している関数です。

 一番に目につくのはmapの中で再帰処理が書かれていることですね。何階層あるかわからないので、再帰で書くしかないわけですが停止条件をきちんとかければ、1行の再帰でこういった表現ができるのは注目すべき点です。

 再帰自体表現力が高いですが、ES2015のAPIを使えばさらに鋭い書き方ができるわけですね。

 また、配列の結合をconcatでやっているところも注目です。concatはpushと違い元の配列を壊さないのでこういった関数的な処理ではよく使います。

groupBy

const groupBy = (arr, func) =>
  arr.map(typeof func === 'function' ? func : val => val[func]).reduce((acc, val, i) => {
    acc[val] = (acc[val] || []).concat(arr[i]);
    return acc;
  }, {});

// examples
groupBy([6.1, 4.2, 6.3], Math.floor); // {4: [4.2], 6: [6.1, 6.3]}
groupBy(['one', 'two', 'three'], 'length'); // {3: ['one', 'two'], 5: ['three']}

 そろそろ見慣れた構文ばかりで、すらすら読めるようになってきたのではないでしょうか。

 今回はreduceで条件に従ってグループ化したオブジェクトを作っています。reduceは最大値や平均、合計を出すために使われることが多いですが、リストからオブジェクトへの集約もよくあるパターンです。

 あとは3項演算子が出てきていますが、ES2015からはラムダ式で一文で書ききりたいことが多いので、よく使います。{}(ブレース)はできるかぎり、使わないほうがきれいに書けることが多いですね。

mapObject

const mapObject = (arr, fn) =>
  (a => (
    (a = [arr, arr.map(fn)]), a[0].reduce((acc, val, ind) => ((acc[val] = a[1][ind]), acc), {})
  ))();

// examples
const squareIt = arr => mapObject(arr, a => a * a);
squareIt([1, 2, 3]); // { 1: 1, 2: 4, 3: 9 }

 本質的にはgroupByに近いことをしています。そろそろreduceの力に気づいてきたのではないでしょうか。

 reduceは引数としてindexを受け取れます。それを使って、オブジェクトのキーを設定しているところとかがすごく工夫を凝らしてあって面白いですね。

 あとは、代入文のあとに,(カンマ)を使って、返り値をaccに戻しているところとかの技巧を感じとれたらなかなかES2015が身についていると思います。

sampleSize

const sampleSize = ([...arr], n = 1) => {
  let m = arr.length;
  while (m) {
    const i = Math.floor(Math.random() * m--);
    [arr[m], arr[i]] = [arr[i], arr[m]];
  }
  return arr.slice(0, n);
};

// examples
sampleSize([1, 2, 3], 2); // [3,1]
sampleSize([1, 2, 3], 4); // [2,3,1]

 リストの中から、重複していない要素を指定された数だけ取り出す関数です。ゲームとかではよく使いますね。ビンゴゲームに近いものなら、これだけでだいぶ組めそうです。

 手続き型に近く、あんまりES2015さを感じない例ではありますが、よく見ると [arr[m], arr[i]] = [arr[i], arr[m]];という見慣れない文があります。

 これは分配束縛(destructing)と呼ばれるもので、ここでは要素の入れ替えを行っています。

 関数型言語では有名な機能で、リストから最初の要素や残りの要素を取り出したり、必要な数だけ配列の要素を変数に取り出したり出来ます。ES2015の中でも、かなり大きな変更の一つといえるでしょう。

 ぜひ使いこなしましょう。

chainAsync

const chainAsync = fns => {
  let curr = 0;
  const next = () => fns[curr++](next);
  next();
};

// examples
chainAsync([
  next => {
    console.log('0 seconds');
    setTimeout(next, 1000);
  },
  next => {
    console.log('1 second');
  }
]);

 非同期で処理をつなげていく関数です。

 PromiseやらRxJSやらがある時代で別に必要ではないのですが、それらの仕組みをわかりやすくエミュレートしているので個人的には好みです。

 next関数が自分自身を再帰的に渡しているのがとても格好いいですね。クロージャーを使って、indexと関数の配列をつかんでいて、それを停止条件にしている感じですかね。それによって、短いながらも多くのことをしています。

curry

const curry = (fn, arity = fn.length, ...args) =>
  arity <= args.length ? fn(...args) : curry.bind(null, fn, arity, ...args);

// examples
curry(Math.pow)(2)(10); // 1024
curry(Math.min, 3)(10)(50)(2); // 2

 関数の引数を減らして、残りの引数を受け取る関数を返す関数です。開発者であれば、カリー化という言葉を聞いたことがあるでしょう。

 やっていることはクロージャを設定して、引数を1つ消費しているだけです。こうした処理は昔から書くことができましたが、スプレッド演算子とアロー演算子のおかげでだいぶ短く書くことができるようになりましたね。

digitize

const digitize = n => [...`${n}`].map(i => parseInt(i));

// examples
digitize(123); // [1, 2, 3]

 10進数の数値をばらして配列にしているだけなので、シンプルな関数です。

 ``(テンプレートリテラル)を使って、数値を文字にしています。そして、それをスプレッド演算子で展開したうえで、新しい配列を作っています。

 なんでこんな無駄なことをしているのかといえば、文字列はそのままだとES2015のArrayのメソッドを使えないからです。なので、一度ばらしてから、配列に展開しているわけです。

 短いコードのなかによくこんなに詰め込めたなと感心します。

sumPower

const sumPower = (end, power = 2, start = 1) =>
  Array(end + 1 - start)
    .fill(0)
    .map((x, i) => (i + start) ** power)
    .reduce((a, b) => a + b, 0);

// examples
sumPower(10); // 385
sumPower(10, 3); //3025
sumPower(10, 3, 5); //2925

 ここまで読んでもらえた方には特に新しいことはないです。Arrayを使うことでうまく、APIを使えるようにしているところとか、mapのindexをうまく使っているところあたりくらいでしょうか。

 しかし、短い密度でいろんなことをしているので、情報量が多く、まとめにはいいかなぁと思い選びました。

capitalize

const capitalize = ([first, ...rest], lowerRest = false) =>
  first.toUpperCase() + (lowerRest ? rest.join('').toLowerCase() : rest.join(''));

// examples
capitalize('fooBar'); // 'FooBar'
capitalize('fooBar', true); // 'Foobar'

 先頭を大文字にする関数です。よくあるパターンですね。

 ここではfirstという変数を分配束縛で取り出しています。そして、残りをrestという変数に入れています。こういう先頭とそれ以外という処理は関数型では頻出です。

 こういう分配束縛ができると、スマートに書けることを頭に入れておくと役に立ちます。

まとめ

 皆さんどうでしたか。ES2015というと、クラス構文とラムダ式、あとはmap、filterあたりにしか注目してこなかったのではないでしょうか。

 でも、見てきたようにスプレッド演算子分配束縛、reduceも同じように高い表現力があるんだよということをぜひ伝えたいと思います。

 JavaScriptはもはや表現力の高い言語で、短いコードに高度な情報を詰め込めます。変化が多くてつらいとか、文法が難しいとよく聞きますが、個人的にはこんなに書きやすい言語はそうないと思っています。

 ぜひ、「30 seconds of code」で遊んでみて、JavaScriptの神髄を味わってみてはどうでしょうか。