Emacsを使い始めての感想
前書き
1か月ほど前から本格的にEmacsを使い始めました。
何か1つくらいエディターを極めたいなぁという願望はずっと持っていて、ちょいちょいVimを触ったりはしていました。
しかし、Pythonを入れないと解決しない問題に遭遇した際に、もともとVim scriptを好きになれなかったのもあって、手放してしまいました。特にバージョン絡みの問題だったので、さすがにそこまで環境を汚すのはあんまり。。という気持ちでした。
加えて、Lisp系の言語で遊びたいという従来の目的をするにしてもVImはあんまり有効でないこともあったので、それならEmacsのほうがいいだろうと考えて乗り換えました。
いざとなれば、Spacemacsに乗り換えればいいという保険もあったので、気軽な気持ちで使い始めました。
やったこと
VsCodeにEmacsのキーマップを入れる
業務では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冊でしょうか。
ただ、どちらも悪くはないにせよ、Vimで言うところの「実践Vim」みたいな「これさえ読んでおけば大丈夫!」というものはない印象ですね。
結局、Webの断片の情報をかき集めながら進んでいくというスタイルをとらざるを得ず、入り口があるようでない感じがしました。
入門者にとってはあんまり優しい環境とは言えないかもしれないですね。
カスタマイズを始めた
いろいろやったので、あんまりまとめて書くのは難しいですが、
- デフォルトの変数をいじくった
- 行数表示とかハイライトとかテーマとか
- キーバインドの変更
- 特に削除系のキーバインドとバッファー操作系を変えました
- あとは C-c k とC-c C-kとかを間違えやすいやつを書き替えました
- プラグイン導入
- 大体el-getで入れました
- これはたいそう便利でした
- 大体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で遊んでから試してみるかもしれないです。
「30 seconds of code」個人的10選/30秒で楽しめるES2015パターン集
前書き
ES2015はJavaScriptにとって大きな変革で、開発者にとっては大きな困惑を生んでいるようです。
いろんなAPIが増えたり、新しい構文が出たりでなかなか使いこなすのは確かに大変だと思います。
そこでES2015を効率よく習得できるパターン集が出されています。1問30秒で解けるくらいの問題が、大量に並んでいて非常に勉強になります。
それだけでは寂しいので、その中から個人的に気に入っている問題をとりあげて簡単に解説します。
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の神髄を味わってみてはどうでしょうか。
2018年やりたいこと100
動機
下記のブログを見て、面白そうだなぁ、自分もそれだけ挙げられるかしらという単純な動機です。
それにこうやってわくわく未来を想像する時間が一番創造的な気がするので、気が変わらないうちに書ききります。
やりたいこと100
- Common Lispの発展的な機能(CLOS、リーダマクロなど)を学ぶ
- Clojure+ClojureScriptでWe
- Common Lispで好きな言語をエミュレートする
- Emacsのメジャーモードを何個か書きたい
- ClojureとかをEmacs環境で書けるようにしたい
- Smalltalkの基礎を押さえる
- Prolog勉強
- Perlの勉強を始めたい
- Rubyもなんとなく癖とか覚えたい
- C++はやってみたいが、余裕があれば
- 低レイヤーにも首は突っ込んでみたい
- JavaScriptを書く時にも関数型プログラミングのスタイルを混ぜたい
- CSSの新しいAPIとか発想についていきたい
- 定期的にVimとEmacsのキーバインドを覚える
- SpaceEmacs触ってみたい
- AWSに触れてみる
- Dockerに触れてみる
- Linuxを触る時間は増やしたい
- GraphQLやってみる
- スポーツとITについて考える
- 関数型プログラミングのスタイルをもう少し深く学びたい
- ゲームプログラミング周辺に触れてみる
- Ruby Kaigiに行く
- Lispの勉強会に顔を出してみたい
- できれば、Perlの勉強会ものぞいてみたい
- 毎日Git Hubのトレンドとソースコードを眺める
- 毎日趣味のソースコードを書く(草を生やす?)
- 毎日新しいニュースを眺める
- 他の人のサービスに積極的にアンテナを張る
- On Lisp写経
- Let Over Lambda写経
- スマートスピーカーのアプリを書く(やる気があればClojureScriptで)
- クローラーを使って何か作りたい
- ブラウザ操作で買い物をしたい
- もしくはAmazonAPIで便利な生活が送れないか考える
- ラズパイを気持ち触ってみたい
- なにかのパーサーとかを書いてみたい
- なにかOSSにプルリクするチャンスをうかがう
- ブログ記事もできれば、書きたい
- 技術記事をまじめに書く練習をしたい
- いろんなタイプの記事に挑戦
- 技術同人誌みたいなものの世界にも首をちょっとつっこめたらいいな
- 技術書展も行ってみたい気持ちはある
- 高専系のイベントも見てみたいところはある
- 毎日本を読む
- レビューはたまに書けたらいいな
- 英語のブログとかでの情報収集を進める
- 毎日反省日記を書く
- 後輩ともくもく会をやる
- 打ち込みとはどんなものなのか見てみる
- 同級生ともくもく会をやる
- バドミントンの配球予測ゲームを完成させる
- バドミントンの上達に直接かかわる何かを作りたい
- Processingの基本を学んで、バドミントンのなにかをエミュレートしたい
- 練習量は増やす
- 練習方針を固めたい
- スポーツの本も1か月に1冊は読みたい
- バドミントンのブログも2週間に1回くらいは書きたい
- 後輩には負けない
- 親孝行する
- Twitter中毒にならない
- 昼寝を減らす
- 間食を減らす
- 転職条件を考える
- 4か月に1回歯医者に通う
- 定期診断に引っかからない
- エナジードリンクは週に2回ぐらいまでに留める
- 信濃の後輩のところに遊びに行く
- 面白い会話ができるように心がける
- 面白い会話を分析するアプリでも作ればいいんだろうか
- 朝食とかの購入をシステム化したい
- システム思考に向いたツールを探す
- 定期的に買っている本をアプリで管理する
- できるかぎり本は電子書籍で買う
- 技術書以外も読む時間をどこかで作る
- ゲーデル、エッシャー、バッハを読む
- 本に散財しない
- 同級会が開かれることを祈る
- 友達に昔の話を伝えたい
- ついでに転職の話を聞く
- 友達の結婚式に呼ばれたい
- 友達にやさしくする。技術の話は控える
- ドキドキしないことは極力やらない
- コードレビューはやさしくする
- 新入社員と仲良くなる
- 新入社員が伸びる条件と教育方法を見極める
- バレーかサッカーのプロの試合を観戦したい
- 映画見たい
- 工数管理の考え方とか上司から盗みたい
- モーニングペーパーもできれば書き続けたい
- 部屋をきれいに保つ
- 業務で迷ったことを力づくで解決しない
- 人に聞く前に考える
- 普段聞いている音楽リストを更新する
- 姪っ子の心を理解する
- 見たいことのないクラフトに出会いたい
- 芸術系のなにかに手を付けてみてもいいのかも
- 週に1度は掃除する
- おいしいたこ焼きとから揚げ屋さんを見つける
- 海外に行けたら行く
所感
60個くらいでスタックがなくなって深堀りでしのいでいましたが、80くらいから時間をかけないと全く出てこなかったです。真剣に考えたので、人間性がだいぶ出てしまった感じもあります。
やりたいなぁと思いながら、言語化できていなかったところが出てきたのはよかったかなと思います。基本的に作ろうと思ったことも大体忘れてしまうので、備忘としてもいいですね。
言語8個習得はどう考えても無謀だったり、いろいろと願望込みなのでこれに優先順位をつけて、アイデアを肉付けすればそこそこ有用だという感じはしました。
ただ、プログラム系だと技術でだいぶん稼げるのでもう少しルールを限定したほうが、面白かったかもしれないですね。
今年は、とにかくいろんな言語とかツールに深く入り込めたらいいなと考えているので、深さ優先でいろいろやりたいです。とりあえず、上に書いたことを今日から実践するように頑張ります。
2017年振り返り
仕事
基本的にはAngularを使って、古いシステムを入れ替えるという計画があり、その設計・技術検証あたりをずっとやっていました。
今まではPGとしての活動のみでしたが、要件定義やDB設計、画面設計の一部も任せてもらいました。チームの人数は4人で、そのうち2人は初めてWebシステムを作るというので、大体のことは自分ともう1人のリーダーでやりました。
あとは4か月間新入社員の教育を担当し、業務をやりながら教えていました。
仕事で印象に残ったところ
新入社員の教育
大体のところは記事に書いた通りです。
新入社員の研修を担当して感じたこと - How IT Works
新しい技術を導入して会社の技術レベルを引き上げたいというところと、自分で考えられる人材を育てたいという2つの試みを目的で設計しました。
前者は達成できましたが、後者はどうにもできませんでした。図解の方法を教えたり、極力ヒントを教えて答えを教えないようにしましたが、効果があったようには思えません。
技術を覚える勉強的なアプローチがダメだったのかなという気はしています。毎日新しい技術が出てくるので、効率よく作業を展開するというエンジニアリングは難しかったと思います。
実務は繰り返しのパターンが多いので、ある程度冗長にカリキュラムを組んで工夫させるのがよかったのかもしれません。
また、負荷をかけすぎて、余裕というものがなく、技術的な工夫より納期に追われていたのかなという考えもあります。
どちらにせよ、新しい技術を覚えることは簡単だとわかったので、もっと考える力を軽視せず、そこらへんをきちんと設計すべきだったと反省しています。
いいエンジニアは育つものなのか、育てるものなのかそういうところはいまだに自分の中で分かっていませんが。。
最近のWeb技術について
AngularでSPAでシステムを組みましたが、個人的には業務システムでは過剰だなという感想を持ちました。
UIにもよりますが、単純なCRUD系のシステムであれば、APIを挟むことによるセキュリティ維持にかかるコスト、レイヤーをまたぐことによる二重メンテナンスによるコストを払いきれない感じがしました。
これを世間一般のスタンダートとすることが正しいのか、という気持ちはいまだに捨てきれていません。
思想的に言うと、コンポーネントを関数的に表現するという考え方は気に入りました。扱いやすいです。Fluxは入れてませんが、それに近いことができるのは気持ちいいです。
CSSModule的なものも素敵で、あぁこれが欲しいものだったという感じがでていてよかったです。
ただ、CSSに関しては何というか、コンポーネント間での相互作用みたいものがまだ残っていて、入力に対する出力という純粋さがないので、少々気持ち悪さがありますが。。
Windows Formsとか、Swingくらいの適当さでデザインが組める何かがほしいです。
RxJSは最初はsubscribeするだけでしたが、途中からいろいろ組み合わせてすっきりと書けるようになりました。連続したイベントを表現する分には楽でよいです。
ただ、途中から分岐が増えるとパズルみたいになって、可読性が低くなるきらいがありました。ルール作りなしに自由に使っていい代物ではない感じがしますね。
趣味
前半はLinuxとVimを触っていました。後半はLispを触っていました。
Vim
Linuxを1か月勉強してみた - How IT Works
Linuxは勉強したのはいいのですが、メインマシンではないので、そこまで恩恵はなかったです。コマンドラインに慣れたというところくらいですね。
Vimの恩恵は言葉で書けないくらいで、劇的な変化でした。
パターンが多い業務システム開発では、コピーと改変でものを作るので、コーディングの効率が大きく変わりました。
困るのはペアプログラミングに近いことをやるときぐらいです。
Vimは一度覚えて終わりというよりは、何度もやらないと覚えきれないです。最近、また「実践Vim入門」を読み始めました。4週目くらいですが、いつ読んでも気づきがあるいい本です。
Lisp
自分はプログラミング言語の構文を眺めるのが趣味みたいなところがあるのですが、Lispは特別でした。
特に印象に残ったのは「Let Over Lambda」です。
Lispが遅いならマクロで早くすればいいだけとか、マクロを作るマクロを定義するとか、想像をどんどん超えたマクロを出してくるのが衝撃でした。
これをみてLispを生涯のパートナーにしたいと思って、惚れこんでしまいました。
といいながら、途中Clojureに浮気していました。
こちらはモダンなLispという感じで、Lispの過激な機能を削って安定版にしたような印象です。また関数型に傾倒していて、状態にかなり厳しい感じです。
環境周りがかなり整備されているうえに、欲しいライブラリやAPIは大体あるので単にLispで遊ぶならこちらはだいぶんいいなぁと思えました。
実用的な何かを作るとしたら、第一の選択肢はこっちを選ぶでしょうね。
あとは、情熱的なPGの方が多く、刺激を受けました。どこにでも顔を出されるので、少々怖いなと思うところもありましたけど。。
そういうところでClojureも気に入りましたが、自由こそプログラマに与えられた最良の道具だと思うので、Common Lispでもう少し頑張ろうとは思っています。
来年やりたいこと
Emacs
CとMの使い分けが面倒で、途中で挫折していましたが、Emacs Lispが魅力的なので来年はEmacsに傾倒したいです。
どうにもSpace Emacsというそこらへんの解決策を含んだものもあるらしいので、それも含めてEmacsに深く入り込みたいと思っています。
エディタがカスタマイズできれば、自分用の作業のほとんどが効率化できるだろうというところで夢があります。
Common Lisp
CLOSとか、リーダーマクロをいじくったりというところはできていないので、そこらへんを掘り下げたいなと思っています。
最終的にはDSLみたいなものを作るところがゴールのような気がしています。
思いついたこと
基本的に自分の興味は適当です。今は3D表現、Processingあたりが面白そうと感じていますが、やるかどうかはわからないです。
とりあえず、面白そうと思えば飛びつけばいいと思っているので、LispとEmacsをベースに好きなことに浸っている一年になるように願っています。
Lispを1か月勉強して
動機
巷ではLispは「神の言語」と呼ばれていると聞いて、興味を持ったのが始まりです。
具体的に調べてみると、マクロと呼ばれる「コードを生成するコード」をかけるという話でした。
業務ではC#やTypeScriptといった静的な言語を扱うことが多いのですが、個人的にはJavaScriptのダイナミックな動きが好きだったので、Lispはその延長線上にあるような予感がしました。
あとは今はやりの関数型言語に分類されることが多いので、そこらへんの思考を盗めるとよいコードを書くことにつながるのではないかともくろみました。
そういうわけで、死ぬ前に一度は触ってみようと思い、勉強を始めました。
勉強方法
Lispを書くにはEmacsがいいということだったのですが、今のところ自宅のPCはWindowsなので手軽にできるxyzzyでやることにしました。
xyzzy - カスタマイズ可能で軽快な Windows 用テキストエディタ
まずは、下のページを写経することから始めました。基本的にscratchで書いて、C-jでコンパイルして、評価するだけです。
慣れてきたら、くじ引きとかボウリングとか適当な課題を作って遊んだり、Git Hubの適当な問題を解いて遊んでいました。
書籍は色々買いましたが、以下の4冊がなかなかいいなと思います。
上2つはLispの概要で、下2つはマクロの使い方です。特にマクロについては使い方が難しいので、書籍があることが大きな助けになっています。
感想
Lispは関数型ではない
勉強し始めてから学んだのですが、Lispは関数が中心の言語ではありますが、必ずしも関数で書かなくてもいい言語でした。
なんならオブジェクト指向っぽくも書けますし、手続型でも書けます。
こうした自由度の高さはJavaScriptに近い感じがしました。
REPL楽しい
今までコンパイル言語ばかり触ってきたので、すぐに評価してテストできるのはとても楽しい体験でした。
コンパイル言語や静的型付けが悪いとは思えませんし、いい面も多いのですが、試しながら書く趣味のプログラミングならこちらのほうが好きですね。
現代言語に劣らない
正直かなり前に開発されたはずの言語にかかわらず、高度なストリームや高階関数を使ったコレクション、オプショナルな引数など新しい機能が含まれています。
だから、Lispが最近の言語に比べて面倒だと思うことは少なかったです。今でもこれなら、昔はもっと突出した言語だったんだろうなと感じます。
逆にいうとLispのエッセンスはかなり最近の言語に取り入れられていて、Lispでなくてはいけないという部分は大分減っている気もします。
マクロ難しい
単なるテンプレートかと思っていましたが、難しいです。
何が難しいかといえば、こうすれば楽になるというパターンを導きだすのが難しいです。普段の癖で、何でも関数で抽象化してしまったり、楽にできる場面を見逃すことが多いです。
書籍を読みながら幅は広げていますが、いまだにマクロを自在に使うという段階まで来ていないです。
自由と代償
Lispの良さも悪さも自由から来ていると思います。
構文までいじくれる言語なので、どんな書き方、どんなデータ構造でも自在に作れるのですが、それゆえにプログラマの技量・思想にすべてがゆだねられている言語という印象です。
正直、今の自分であれば、やり方のパターンがある程度固まっているJavaScriptのほうが間違いなく早く書けます。
そういう意味でLispが神の言語というよりは、Lispを自由に扱えるようになったプログラマが神の域に近づくというのが正解のような気がします。
だから、自分は1か月勉強しましたが、スタートラインに立っただけで、Lispの本質に近づけていないような気がします。
まとめ
Lispには深さがあると思います。特にマクロを作るマクロだとか、マクロでクロージャを操作するという発想を見たときに、考え方の深さに驚きました。
オブジェクト指向や関数型も勉強して楽しかったのですが、これにマクロが組み合わさるとどこまで表現が深くなるんだろうかとドキドキします。
正直にいうと、Lispは万人が勉強すべきという感じはしません。関数型をやりたいならJavaScriptやHaskell、Scalaあたりでいいのかなと思います。
でも、プログラミングの魅力をもっと味わいたいならこの言語はベストに近いと思いました。
新入社員の研修を担当して感じたこと
研修の概要
今年の新入社員研修を担当して、一からカリキュラムを組み立ててやり通しました。
条件は下のような感じです。
- 5カ月間毎日行う
- 配属される部署は不明
- さらに配属されるチームによって必要とされる技術セットは大きく違う
- 古い技術の保守チームもある
- ただ、Windows FormsとWeb系の技術の基本は少なくとも身につけてほしい
- 新入社員は2人、自分は業務と平行して教育する
研修設計で当初考えたこと
教えない
最低限のルールはあるものの、ほとんど自由に近い条件なので、最初のカリキュラムの設計が大事かなと思いました。
とりあえず最低限考えたことは以下の2つです。
- 技術要素をできる限り広くする
- 教えない教育を中心にする
うちの会社では配属後に丁寧な教育をしないチームもあります。だとすれば、この会社で生き残っていくためには、自分で学び自分で考えるサバイバル能力がいるのではないかという考えがありました。
それに加えて、自分で自ら学ぶことができるのであれば、どんな部署に行っても大丈夫だろうということです。
具体的には仕様と使用する技術は指定しましたが、文法やライブラリの使い方を一から教えたことはないです。
参考書等は必要と言われた段階で用意しました。
レベル設定
また、レベル設定は想定される一番レベルの高いチームに合わせました。とはいえ、世間でいえば普通くらいでしょうが。
社内の最高レベルに5か月で行けるか、行けないかという実験的な部分もありましたが、まぁ低いレベルに合わせるのもどうかなという感じです。
具体的には以下のような感じです。
- 極力新しい技術を使う
- コードレビューを厳しくする
- デザインもできる限り業務に近づける
- 仕様変更を辞さない
カリキュラム
- C#
- Web
- その他
- JavaScript課題
- PowerShell
- Markdown
- Git
- 座学
- プログラミングパラダイム
結果
技術的には問題なし
新しい技術を覚えることについては全く問題なかったです。実際丁寧に教えたことはないですが、GitやAngular4、Expressの使い方などは比較的ちゃんと理解していたと思います。
個人的な感覚から言えば、それなりの頭があれば技術を覚えるという点は問題ないという印象を受けました。
抽象概念で躓く
やや問題になったのは、Anuglarのコンポーネントの設計やオブジェクト指向設計、もしくは関数型に近いロジックの書き方というところでしょうか。
あるいは具体的には再帰の使い方や高階関数の使い方は理解してもらうのが大変でした。
スピードが上がらない
時間切れでボウリングの課題も終わりませんでしたし、スピードに関しては最後まで向上が見られませんでした。
コードを書くというところは確実にできるようになっていましたが、管理画面に3か月かかるなど速度面は十分でないという傾向がありました。
反省
特に学んでよかったこと
PowerShell
うちの会社は基本的にVisual Studioで作業していて、あんまりシェルは触らないのですが、あえて研修はVSCodeでひたすらシェルで作業させました。
一度基本的なコマンドを理解すると応用がかなり効くので、なかなか便利でした。
Git
Gitはとても便利なうえに使えるとデグレ時などにとても役に立ちます。比較的すぐに扱えるようになりましたし、コミュニケーションにもよかったので早く導入すればよかったです。
Express
比較的自分で設定しないと動かないという特性を考えると教育には良かったと思います。 Webの仕組みを知らなくても動かせるフレームワークもありますが、あえて薄いものを選びました。
いらなかったこと
Angular4
重すぎます。情報源も少ないですし、何をするにしても流儀が多くそれが教育に関してはノイズになっていました。
Reactがいいかと言われるとあれも何だかんだ付随品が多いので、個人的にはjQueryを推します。
やるとすれば、jQueryで小さい課題を多めに扱って、そのうち一つをReactで書き換えるぐらいがいいかと。
レスポンシブデザイン
デザイン面で完全に足を引っ張っていました。一度崩れると修正が難しい割りに、CSSについて学べることが多くないのが残念。
新入社員がやってみたいと自発的に言いだしたので任せてみましたが、一部分が可変くらいでよかったんじゃないかという印象です。
座学
座学でオブジェクト指向設計、関数型のパラダイムを時間をかけて勉強してもらいましたが、定着率が思うほどあがらなかったです。
これは課題をそれらのパラダイムを使わないときれいに解けない課題を作って解かせたほうがよかったですね。
教える最善の方法は座学よりも課題ということに最後のほうで気づきました。
だめだったところ
結果的に一人は一番レベルの高いチームに行って上手くやっているようですし、もう一人も開発が関係ない部署に行ってなんとかやっているとのことらしいです。
自分で設定した目標からするとちゃんと果たせたと評価はしていいでしょう。
ただ個人的な感覚から言うと、満点ではない感じがします。
プロジェクトに入る分には問題ないのですが、優秀なプログラマに迫れたかというと近づけていない感じがします。
うちの会社の優秀なプログラマの方はこのカリキュラムにあることを優に1か月もあれば十分吸収したそうですし、自分も当初計画では3か月で今回の内容が終わると読んでいました。
そう考えると、技術だけ繕って本質を教えきれなかったのではないか?という気持ちがぬぐいきれません。身についたのは答えを調べる能力だけなのではないか?
なので技術セットを多少甘くしてでも、思考の仕方、抽象度の高い考え方を教えればよかったなぁというのが反省になります。
具体的には小さな課題をたくさん用意するとか、あとはスライドを作成したLTなどが意外にいいのかなという感じがしています。
感想
研修を通してずっと優秀なプログラマとはなんだろうということを考えていました。
途中で感じたのはこだわりの強さがその1つの条件なのかなという風に思いました。
コメントの入れ方、ロジックの切り方、デザインの見せ方、パフォーマンスとかそういうところに脅迫的なこだわりを持っている人が優秀な人には多いとか。
そういうところが最後まで研修とつながらなかったのが、すごく残念でした。
来年は多分担当ではないと思いますが、それが資質なのか、環境なのか、教育の賜物なのかとかそういうことをもう少し注視して経過を見てみたいです。
言い訳
研修の期間だけが決まっていて目的があいまいなこと、そもそも開発に行くとは限らないのにカリキュラムが 開発限定なのはどうかという議論は置いておいといてください。
まぁ、基本的にプログラミング未経験者しか入社してくれず、有名大学の人が来ることもなく、家にPCがないというプログラマーがそこそこいるという環境では何かしらの仕組みがいるのは確かですが。。
よく考えたらインターンシップみたいですよね。これ。
最近始めた習慣とかについて
前書き
最近は生活をちゃんと管理しようという気持ちが強いので、色んなことを習慣にしてみています。
徐々に仕事や生活の仕事の質が改善できつつあるような気がするので、簡単に書きます。
タスク管理
一日の最初に計画を立てる
あたりまえのような気がしますが、今までは一日分のTodoリストを書いて終わりでした。
今はちゃんとこの時間にこのTodoを終わらせるというような時間まで指定して計画を立てます。
一日にやる作業は色々なものがあって、書類を作成したり、コードを書いたり、メールを返信したりと色々なものがあります。
作業にはそれぞれ向いている時間帯がありますし、あるいはずーっと同じことをしていると疲れるときもあるので、それらをもろもろ考慮して計画を立てます。
常に計画があっているわけではありませんが、それを含めてPDCAを回していけると時間をよりよく使える気がします。
ちなみに、Todo管理には「Jooto」、毎日やるべき作業や習慣には「Habitica」を使って管理するのが好きです。
ポモドーロテクニックを使う
計画に関係する話なのですが、最近はポモドーロテクニックという考え方を使って仕事しています。
簡単にいうと、仕事は25分間とにかく集中して5分間休むのがいいという方法です。このサイクルを1ポモドーロのカウントします。
このテクニックのメリットは集中力を継続できることと、1ポモドーロが30分になるので自分の作業量をカウントしやすいことです。
ちなみに、一日10ポモドーロできれば、いいほうだと聞いています。
ポモドーロテクニックと計画を組み合わせることで、集中力は大分維持できるようになった感じがあります。それに定時を意識するより、短い時間を意識したほうがモチベーションが切れにくいですね。
ちなみに、プログラミングだけは50分集中して10分休憩というサイクルのほうが好きです。
PDCAを回す
最近はPDCAの本を読んでいて、PDCAを回すように意識するようになりました。
下記の本は両方面白いのでお勧めです。
大事なことはまず思いついたアイデアを全部書きだして、見直せるようにすることです。
ここが改善できるんじゃないかと思ったら、とりあえず書きだしておいて時間のある時に振り返ります。
また、改善案は必ずアクションまで落とし込んで、Todoリストにどんどん入れていきます。これを仕事に組み込めると少しずつ質が良くなります。
まとめ
こうやって見返してみると、自分でも大したことをしていないなという感じがします。
しかし実感としては集中力を高く保ちつつ、仕事の質を改善できているのであえて記事にしてみました。
なんでも見えるようにして、改善を続けていくというのはやはり大事ですね。
このまま改善を続けていって、もう少しいい習慣ができたらまた書きます。