0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

同じ答えを返す2つのコード、どっちで書くべき?

0
Posted at

この記事は Zenn に投稿した記事 の転載です。

はじめに

初めての投稿です。
未経験からエンジニアを始めて1年が経ちました。

さて、
エンジニアになり、プログラミングを学び始めると、どこかで一度は耳にする言葉があります。

「コードは短い方(簡潔な方)が良い」

本当でしょうか。私はこの間、自分の書いたコードと模範解答っぽいコードを並べて、この言葉を疑うことになりました。

題材は、よくあるマッチ棒の問題です。

マッチ棒の正方形問題

マッチ棒で正方形を横に並べて作ります。
1個目の正方形には4本必要で、2個目からは辺を1つ共有できるので3本ずつ足せばいい。「正方形をn個作るのにマッチ棒は何本必要か?」という問題です。

 _ _ _
|_|_|_|   ← 正方形3個 = 4 + 3 + 3 = 10本

私の頭に浮かんだのは、式というより動作でした。4本で1つ目の正方形を作って、3本ずつ足していく——その手の動きがそのままコードになりました。

~①思考のコード化~

function countMatchsticks(squareCount) {
  const FIRST_SQUARE = 4;   // 最初の正方形は4本
  const STICKS_TO_ADD = 3;  // 2個目以降は3本ずつ足す

  let total = FIRST_SQUARE;
  for (let i = 0; i < squareCount - 1; i++) {
    total += STICKS_TO_ADD;
  }
  return total;
}

先述した「1個目の正方形には4本必要で、2個目からは辺を1つ共有できるので3本ずつ」を、まさに動作の単位でコードにしていますよね。

一方で、この問題にはもっと短い書き方があります。

~②短い書き方~

function countMatchsticks(squareCount) {
  return 3 * squareCount + 1;
}

どちらも同じ答えを返します。では、どっちで書くべきなのでしょうか。

2つのコードを読んだとき、頭の中で起きたこと

正直に白状します。

長い方のコードは、読んだ瞬間にマッチ棒が見えました。4本で正方形を作って、3本ずつ足していくあの動作が、コードの上にそのまま乗っている。だから読んだだけで正しさが分かった

短い方は違いました。3 * squareCount + 1 を見ても、マッチ棒は浮かばなかった。ではどうやって「これも正しい」と納得したかというと——同じ数字を入れて試したんです。n=1なら4、n=2なら7、n=3なら10……よし、合ってる。

ここに大事な非対称があります。

  • ①思考のコード化:読めば分かる
  • ②短い書き方:検算しないと信じられない

短いコードは、正しさの確認という労働を、読む側に外注しているのです。

変数名を付けてみると、残酷な差が出る

この差をもっとはっきり見る実験があります。
両方のコードに、意味のある名前を付けてみることです。

長い方は簡単でした。FIRST_SQUARE(最初の正方形は4本)、STICKS_TO_ADD(2個目以降は3本)。コメントを全部消しても、変数名だけでマッチ棒の世界が語れています。

では短い方は?

3 はまだ「1個あたり3本」と名付けられます。でも + 1 に付けられる名前がないんです。マッチ棒の正方形の世界に「1本」という実体は存在しません。「1本」は工程だからです。

あの +1 は、4本の正方形を「3本 + 1本」に分解した計算の残滓でしかない。

つまり短いコードは、変数名で意図を表現しようとした瞬間に破綻します。意図がもうコードの中に残っていない証拠です。

では「短いは正義」は完全に間違いなのか?

ここで面白いのは、数学の世界だと結論が逆転することです。
数学なら間違いなく、展開し切った 3n + 1 の方が良い。

なぜ正解が逆転するのか。

数学の 3n + 1 は、そもそも命題を立てて、論法を使って証明した結果として出てくるものです。「なぜこうなるか」という物語は、式の外側——証明の過程——に保管されている。だから式自体は限界まで削ぎ落として美しくしていい。物語は別の場所にちゃんとあるからです。

コーディングはそうじゃない。

たとえば、
半年後にこのコードを初めて開いた同僚(あるいは未来の自分)が読めるのは、コードとそれに付随するドキュメント、あとコメントくらいです。

証明ノートは添付されていない。だから物語(=設計者の意図)は、コードの中に残すしかない。

  • 4 + (n-1)*3 は、証明を式の中に畳み込んだ形
  • 3n + 1 は、証明を捨てた形

「短いコードが正義」という思い込みの正体は、物語を外部に持てる数学の美学を、物語を内部に持つしかないコードの世界に、そのまま輸入してしまったものだったのです。

結論:どっちで書くべきか

ここまで物語肯定主義のように話してきましたが、一度フラットに考え直します。
「短い=正義」でも「長い=丁寧」でもありません。問うべきはこれです。

「このコードを次に読む人に、何を伝えたいか」

動作の物語を伝えたい場面なら、手順が見える形で。答えだけで十分な場面(証明済みと共有されている、あるいはコメントやテストが物語を別途保管している)なら、短い形で。

初学者のうちは、自分の書いた「長いけど動作が見えるコード」を恥じる必要はまったくない、というのが今回の私の結論です。

おまけ:この話の続き

今回の話は、突き詰めると「意図をコードに残すか、消すか」という選択の話です。
では逆に、意図をわざと消したい場面があるとしたら・・?——実はあるんです。

難読化やセキュリティの世界。

その話はまた別の記事で。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?