30歳からのプログラミング

30歳無職から独学でプログラミングを開始した人間の記録。

ツリー図を簡単に作れるウェブアプリを作った話と、抽象的思考力の話

他の図形も作れるようにしたい気持ちはあるが、今はツリー図だけ。

shape-painter.numb86.net

ソースも公開している。

github.com

作った動機

単純に、自分が欲しかった。
図形を作成するツールは、もっと高機能で高品質なものが、他にたくさん存在する。だがそういったツールは、機能が多すぎて初見では分かりづらかったり、自分が欲しい図を作るためには細かい調整が必要だったりする。

このアプリでは、カスタマイズ性を犠牲にして、とにかくシンプルで直感的に操作できるようにすることを、基本的な方針とした。
そして、ユーザが細かい調整を出来ない代わりに、頻出の図形に対してテンプレートを用意しておけば、簡単な操作で「それっぽい」画像を作成できるのではないかと考えた。
現時点ではツリー図しか用意していないので、その目的はあまり達成できていないのだが。

最初の図形としてツリー図を選んだのは、思い付いた図形のなかで一番難しそうだったから。後述するが、実際、難しかった。

自分にとって需要がありそうだったから、というのも理由のひとつ。
プログラミングの世界では「木」という概念は頻繁に出てくる。

先日公開した以下の記事のグラフもこのアプリを使って描いたが、npm パッケージの依存構造は、まさに木である。

numb86-tech.hatenablog.com

DOM や仮想 DOM もそうだし、抽象構文木もその名の通り木である。木構造を簡単に描画できるツールがあれば、何かと便利なのではないかと考えた。

このアプリそのものを作った理由に戻ると、フロントエンドの腕試しという意味合いもある。
「何かを作ることが一番勉強になる」とはよく言われるし、私もそう思うが、フロントエンドに専念してアプリを作るのは意外と難しい。
インタラクティブ性のない完全にスタティックなサイトなら、わざわざ React や TypeScript を使う必要性がない。
かといってバックエンドも用意するとなると、「フロントエンドの腕試し」という趣旨から大きく逸脱してしまう。何より、公開後のメンテナンスや運用が大変になってしまう。
フロントエンドだけで完結するこのアプリは、題材としてちょうどよかったのだ。

振り返り

React などのフロントエンドの腕試しとして始めたのだが、そこではそれほど苦労しなかった。
それよりも、とにかくロジックを考えるのが大変だった。

ここでいうロジックとは、ツリーの各ノードをどこに配置するかを計算することなのだが、ここに一番時間が掛かった気がする。
ノードとノードが重なってはいけないし、全体として見た時に不自然な形になってはいけない。
試行錯誤の結果、複雑な形状でも、なんとかそれっぽく表示できるようになった。

f:id:numb_86:20200530140912p:plain

修正に修正を加えているので、全体の処理の流れはとても綺麗とは言い難いし、恐らく無駄も多いとは思うが。

ロジックやアルゴリズムを考えるのが本当に苦手なんだということを痛感した。
その原因のひとつが、抽象的に思考する能力の低さ。
抽象的なものを、抽象的なまま扱えない。具体的なものに落とし込まないと、思考することができない。
極端な例を挙げると、x + 1という処理がどんな結果をもたらすのか、イメージできない。x12を当てはめて考えることでようやく、処理の流れや規則性を掴むことができる。
もちろんこれくらい単純な例なら具体化しなくても済むのだが、もう少し複雑な処理になると、途端に厳しくなる。

抽象的思考力が低いせいで、ロジックを考えるのに時間がかかる。そして何とか考えついても、それをコードで表現するのにまた時間がかかる。
x12のときだけ処理できればいいのではなく、xにどんな数値が入っても処理できなければならない。そういうプログラムを書くためにはやっぱり、抽象的に物事を考える能力が必要になる。

抽象的思考力の低さは、プログラマとして致命的な欠陥だと思う。

ポインタを使うプログラミングは今日書かれるコードの90%には必要とならず、製品コードにおいてははなはだ危険なものであるということは素直に認める。その通りだ。そして関数プログラミングは実務ではほとんど使われていない。それも認める。
しかしそれでも、最もエキサイティングなプログラミング仕事ではこれらは重要なものなのだ。
(中略)
しかしポインタと再帰の明らかな重要性以上に重要なのは、これらの学習から得られる精神的な柔軟さと、これらを教えている授業からふるい落とされないために必要な精神的態度が、大きなシステムを構築する上で欠かせないということだ。ポインタと再帰には、ある種の推論力、抽象的思考力、そして何よりも問題を同時に複数の抽象レベルで見るという能力が要求される。そしてポインタと再帰を理解できる能力は、優れたプログラマになるための能力と直接的に相関している。

Javaスクールの危険 - The Joel on Software Translation Project

私は「優れたプログラマ」になりたいし、「エキサイティングなプログラミング仕事」をしたい。
この記事の趣旨としては Scheme や C を使って再帰やポインタを学べということだと思うが、それらの言語を使っていけば抽象的思考力が上がるのだろうか?

もうひとつ「プログラマとして致命的では?」と感じたのは、英語力の低さ。
プログラミングにおいて命名は非常に重要だが、英語が苦手すぎて、適切な名前が思い付かない。単語レベルなら自動翻訳でどうにかなるが、一定以上複雑なことを表現しようとすると、かなり厳しい。コメントを書くのにも時間がかかる。
保守性を考えればコミットメッセージも重要だと思うが、これもやっぱり時間がかかる。というか、「そんなことに頭を悩ませていないでさっさとコーディングを進めたい」という気持ちになり、ついいい加減なメッセージになってしまう。

いろいろと書いたが、曲がりなりにも公開まで持っていったことは褒めたい。

今後の運用について

フロントエンド技術の「砂場」として使っていきたい。
TypeScript の型付けはまだまだ改善の余地がある。anyで逃げたところも多々あるし、実践のいい機会になると思う。
パフォーマンスもほとんど考慮していない状態なので、いろいろと試せると思う。

もちろんツリー図以外の図形も作りたいのだが、他に学びたいものや作りたいものがあるので、それらとの兼ね合いが難しい。