散文駆動プログラミング
現在、elm books――全くの初心者でも、テトリスを作ってみないか――(仮)という同人誌を、少しずつ執筆している。執筆中に、いかにとりあえず手をつけるかという実践としてとにかくなんでも良いから書くということをやっていた。その流れで実装のやり方についても考え直した。散文を書くことから実装としてしまって良い。
これを、散文駆動プログラミングと呼びたい。
普段、私達はまとまりで機能Aを実装しなきゃいけないとか、大体頭で整理できているように思っている。だけど、調子が悪いときはなかなか手がつけづらいことがあるだろう。それは、頭の中で「手をつけなければいけないちょっと重い何か」が占拠しているから。何か考えておかないといけないんだよな。というブロックがある。
私はワーキングメモリーが足りないと感じている。覚えようとするのが結構苦手。普段、実装のフローではなんとなくtodo管理ツールで機能をボンと置いたりしているのだが、なかなかそこにたどり着くまで時間というか精神的労力がかかる。
とりあえず実装を初めてみる?もしくは、タスクを分解してissueに入れる?そういうことをまずやる。実装する対象のファイルはあまり汚さずに、考えた実装・ロジックをまとまりでとりあえず書き込んでいく。そういう風に仕事をしているのだが、なかなか気分が乗るまでの時間がかかる。
なるべくなら、仕事の始まりはなめらかに、柔らかく離陸してしまったほうが良い。自分の脳が気づかないほど小さく、知らないうちに「はっ……やってしまっていた!!」そんな感じに。そういう風に始めてしまえば、いつの間にか目の前に「なんとなく仕事っぽいことをしている結果」が出てくる。
そうなると現金なもので、結構簡単に仕事モードに入れてしまう。こういう、ぬめっと始められるフローを作るのが大切だな、と執筆をしていて気づいた。
執筆は、別にいつまでやらなくてもいいし、やっても特に何の成果も無いように感じられるのだ。だから、いかに執筆の壁をなくすかというのが大切だった。脳が負担を感じる好きもないような、些細なことなのに、終わってみたら達成感がある、そういうものだったら喜んでやり始めてしまうというわけだ。最初のスタートは実になんでもよくするというのが、こつ。
どうして良いのか
小さな進捗は、大きなモチベーションを生む。テレサ・アマビール氏が検証したように。
そして、離陸するために使った文章は、色々なところに使える。たとえばADRのような設計判断に。たとえば関数のコメントに。たとえば、バグを防ぐスッキリした命名に。
ADRに
離陸するための文章には、
- 設計で悩んだ理由
- 設計の選択肢
- 選択するコンテキストや、考えておくべきステークホルダーのことなど
などがなんとなく書かれはじめ、そして徐々にはっきりと書かれることになる。なんとなく引っかかっているものが可視化されるからだ。ちょっとずつ考えられることが増えていく。書いているから忘れる心配もないし、書いていることを見ながら考えるので、メタ認知も活性化される。
書くことで考える。
こういう、些細だが重要な情報が詰まった文章は、たとえばChatGPTなどに要約させてしまえば良い。要約された文章は完璧ではないかもしれない。だけど、仕事の離陸のために使った使い捨てに近い文章が、後々参照して便利な形態に変化できるとあれば、これほど便利なことはないだろう。
関数のコメントに・スッキリした命名に
他にも、離陸するための文章には、
- これから実装する関数の機能に関して整理
- 実装の命名のために、この値がどう使われるかを整理
- なんとなくリファクタリングしておきたい場所
みたいな、ミクロな視点の考えも書いてあることが多い。こういう文章も、ちょっとしたコメントなどに整形してあげるだけで、後々の人の役に立つはず。
どこに書こうか
どこに書くか悩む。私は、私は実装するファイルにそのまま書いてみて良いんじゃないかと思う。その思考の過程自体も、コミットしてしまって良いのではないか。こういう、生の考えみたいなものは、後で新人を教育する時にも役に立つと思う。だって、先輩がどのように考えを進めているのか、直に見ることができるわけだからな。
まあ、もちろん恥ずかしい考えとかは消してしまったほうが、精神衛生上良いだろうけど。こういうあけひろげの思考をみんなで共有できる文化があったら、きっと失敗に対する恐怖とか薄れるんじゃないか?だって、みんな最初から良い実装にたどり着いているわけじゃないということが分かるから。
実際に、ファイルの中にコードが沢山増えてくると、コードを書かなければいけない、という磁場というか、潔癖症が発動してしまう気がしている。そういう潔癖症が、一番最初の完璧に実装しなきゃ、の方向に向かわせると思っている。
だから、コミットの一番最初はこれからやることを考えた文章、みたいに汚すことを確定していれば、安心して思考できるんじゃないのか、と思うのです。
最初は小さく。勢いはあとからついてくるという話。
きれいなコードで一杯のファイルに、とりあえず思考の痕跡を残してみる。そして、実装し、考えの足場、離陸するための文章は消してしまう。思考の最初の足場として、話すような適当な文章は、きっと最適なんじゃないかな。ラバーダックデバッグと一緒。
想像してやってみる
あ〜何をするんだっけな。あ、そうだ。まず、実装をしなきゃいけないんだった。何か、締切があるものがあった気がする……何だったっけ。
そうだそうだ、ユーザー登録画面についてを実装すれば良いんだった。
で、今は何をすれば良いんだっけ?うんと、何だっけ。うーん。
あ、そうだ、ユーザー登録画面のUIに関しては昨日やったんだった。昨日、ユーザー登録画面のUI、つまりモックまでは完成したんだった、うーんと。それで?何だったっけ。あ、モックというより、単純にコンポーネントね。それで、起動してコンポーネントが動くことは確認できたんだった。
うんと、とりあえずやらなきゃいけないことは、テストだよな。コンポーネントのstorybook書かないといけない。そんでもって、あとは、ユーザー登録画面でどうやってユーザー登録のapiを叩くかとか調べないといけないな。うーんと、結構私知らないところだったんだよな。何だっけ?tanstack Query?だったっけな。それについて勉強しなきゃだ。
えっと、何がわからないんだろう。えっとな〜何だっけ。わからないのは、useQueryじゃなくて、一回だけ使うやつの方だ、何だったっけ?useMutationとかいう名前だったような気が。
まあいいや、それについても調べるとして、UIのstate部分テストできないかなあ。今はとりあえずuseStateで全部ベタ書きしちゃってるけど、もしかしたらカスタムフックにしたほうが良いかも!
でも、カスタムフックにするほど散らばってもないしな。どうしようか。ただ、フックとしてテストできるとありがたかったりするんだよな〜〜〜
...
こんな感じで、思考を書き出していく。こうすると、考えておくべき、実装するべき、そして考えたことが書かれていくんだ。書く度に考えることが減って、明晰に思考できるように感じる。
ChatGPTで整形してみる
ChatGPTにお願いして、この文章から
- これからやるべきこと
- これから考えるべきこと
- 考えたこと、悩んだ理由、決定事項
などを、試しに箇条書きで抜き出してもらいましょう。
Based on the input <Sentence>, extract and organize the following pieces of information in a bullet-point format in Japanese:
- Actions or tasks that need to be taken next.
- Points or topics that need to be considered or thought about next.
- What has been thought about, the reasons for concerns or doubts, and decisions made.
Please ensure all details from <Sentence> are comprehensively and accurately covered.
---
<Sentence>
以下に、与えられた文から抽出・整理した情報を記載します:
**次に取らなければならないアクションやタスク**:
- 実装をすること。
- ユーザー登録画面についての実装。
- コンポーネントのstorybookを書くこと。
- ユーザー登録のapiの実装方法について調査すること。
- tanstack Queryについて勉強すること。
- useMutationという名前の機能について調べること。
- UIのstate部分のテストの可否を検討すること。
- useStateの部分をカスタムフックにするかどうかを検討すること。
**次に考慮または思考するべきポイントやトピック**:
- ユーザー登録画面のUIに関しては昨日やったこと。
- 今何をすべきか。
- ユーザー登録画面でのapiの叩き方。
- UIのstate部分のテストの可能性。
- useStateを使用した部分をカスタムフックにするかどうか。
- フックとしてのテストの有用性。
**考えられたこと、懸念や疑問の理由、決定事項**:
- ユーザー登録画面のUI、つまりモックが完成していること。
- コンポーネントが起動して動作することを確認したこと。
- tanstack Queryの名前が不明確なこと。
- useQueryではなく、一回だけ使うものの名前がuseMutationかどうかの不確実性。
- useStateでの実装がベタ書きであること。
- カスタムフックにする必要があるかどうかの不確実性。
- フックとしてテストする利点があること。
こんな感じで、ところどころいらない情報はあるけれども、結構簡単に使える形になっていると思います。
みんなバカにしてやらなかったりするけれど、日本語で関数の補助線を引くのと似ています。。それの、更に適当で良い、モチベーションいらずのスターター。面倒だと思ってやらないことが、実は一番楽に進める鍵になったりするんじゃないか。そういう話でした。
Discussion