まえおき
そんな大したものではないけど、自分なりの設計のやり方みたいなのを整理して文書化したいなみたいな気持ちがある
— やんく✌('ω')✌ (@yy_yank) March 23, 2024
無意識で良しとしてやってることが多すぎるので
というわけで「俺のプログラミング」シリーズです。 自分が何を大事にしてプログラミングをしているか、自分でもよく分かってないので思いついたものを書いていく予定です。 今回はエラー、失敗について。
早く気づきたい
自分のことはあまり信用していない
なので、基本的に早い段階で失敗するような設計に仕向ける。
気づくタイミングはいくつかある
- コンパイル時
- lintなどのチェック時
- テスト実行時
- アプリ起動時
- プログラム実行時
アプリ起動時、プログラム実行時
基本的に、アプリ起動時やプログラム実行時に気づくのではかなり遅めで、最後の手段と思っている。 アプリ起動時に防御的にエラーにすると、コードや設定を変えては起動を繰り返して動作確認するみたいなことになり、かなり効率が悪い。
若者には信じがたいかもしれないが 過去にxmlをアプリ起動時に読み込み、不備があったらエラーになるような設計に触れたことがあるが、 アプリがなかなか起動せず半日とか1日終わるみたいな人が結構いた(という夢をみた)。
プログラム実行時にエラーにするのもリリースの最終確認中や実際のリリース後に気づくことにもなりえるので、あまり良くない。 システム利用中に想定されるケースでの失敗など、 このタイミングでユーザーや開発者に伝えざるを得ないもの以外は避けたほうが良さそう。
テスト実行時
テスト実行時に気づくのは、開発中に気づけるという点は良い。 しかし、開発中の対象のテストは頻繁に流したとしても その他の周囲のテストを頻繁に流すかというと個人差がある。 最悪、CIなどが落ちるタイミングで気づくか、「なんかテスト落ちてるよ」と同僚に言われて気づくこともありえる。
またテストスイートが太ってくると気づきづらくなったりテスト全体が遅くなったりしてくる。 なのでテストは最小限にしたいと思っている。
しかしリファクタリングや新規機能開発などした時も、既存コードが壊れていないことを保証するために必要十分は欲しい。
結論、テストはありがたい存在だが、しがらみでもある。
lintなどのチェック時
linterなどはルールチェックなど含めて様々なものがある。 従っておくと自然とコードは見た目上整ってくる。 これはビルド時に組み込むことも出来るし、CIなどに含めることも出来る。 IDEやエディタの設定によってはコンパイルエラーと同様に表示することも出来る。
静的チェックと実行時チェックの狭間に居るような存在に思える。良い付き合いをしていきたい存在。
コンパイル時
色々書いてきたけど、自分としてはコンパイル時に不具合や問題に気づけるのが一番良いと思っている。 これには結構使用するプログラミング言語によって差が出てくるところだし、そのプログラミング言語を書くプログラマの熟達度も影響する。
プログラミング言語ごとの強み弱み、トレードオフを設計に落とし込む
つまり、全てをコンパイル時に表現しようとすればするほど取っつきにくい言語になるのではないかと思う。そのあたりはトレードオフがあるかもしれない。
例えばRustは常にメモリのことを意識した実装をしなければいけないし Haskellは正直詳しくないので知った風に書くと、様々なモナドを意識する必要があるかなと思うし、関数とかなんやかんやしないといけない。 RubyとかPythonとかもよくは知らないんだけど、静的型付けではないので後づけの型を付けたり、テストを充実させたり、フレームワークに乗っかったりするのではないだろうか。 JavaとかもフレームワークとIDEに乗っかることで、言語の弱みを賄ってるところがあるのではないかと思う。
それぞれの言語をdisりたいわけでもなくて、立ち位置、実行速度、ビルドの速度、エコシステムなどで特徴が出ているということが何か言いたい。
まとめ
僕個人としては、全てをコンパイル時に気づくければめちゃ便利!って思いはありつつ コンパイル時に全てを表現しようとすると、プログラミングの難易度が上がり、コンパイル速度は遅くなる傾向にあるのではないかと思う。
書くのが難しい、コンパイルが遅い、となると早かったはずのコンパイル時のフィードバックは遅くなってくるというジレンマがある。
なので、言語によってどこで失敗するかの濃淡、コントラストがあるし
それをそれぞれ使いこなし、適材適所で設計ができるのが良いプログラミングかなと思う。
0 件のコメント:
コメントを投稿