インデントをするヤツが死んでしまった話

 この記事は、ゆる言語学ラジオサポーターコミュニティにおける非公式イベントである、アドベントカレンダー企画のために執筆されました。

 ゆる言語学ラジオって何? という方には向かないかもしれませんので、予めご了承ください。

 昨日は、しうさんの「天狗になったけど質問ある?」でした。 

 明日は、らこらこさんの「語言辞典を持ち歩き、言語学者を推す生活」です。



はじめに

 さて、ゆる言語学ラジオをご存知の方は既に記事タイトルでピンと来たものがあると思います。
 そう、この動画です。

https://youtu.be/qNHfKNjX8Us?t=15

 インデントが何かということは動画内でも触れられていますが、私なりにもここで説明してみようと思います。――とは言っても、実は大した話はありません。インデントは決してプログラマだけが意識するものではないからです。
 インデントという言葉は、和訳では「字下げ」という言葉がよく当てられます。この字下げやインデントと呼ばれる機能は「Word」や「Pages」、「Googleドキュメント」のような文書作成ソフトを使ったことのある人なら一度は見たことがあるのではないでしょうか。
 例えばこの記事の目次も、章立てに合わせてインデントがされています。
このようにすることで記事の構成が一目瞭然となり、自分の目的となる記述がどこにあるのかも推測できるようになります。このようにインデントというのは、物事の構造を整理するための手段としてプログラマに限らず用いられているものなのです。

なぜ人はインデントするのか

インデントは読む人の見通しをよくしてくれる

 インデントは物事の構造――その中でも包含関係を表すのに適しています。
 この記事を例に考えてみると、「なぜ人はインデントするのか」という大きな問いの中に、

①インデントは読む人の見通しをよくしてくれる
②インデントすることで思考を整理できる
③忘れるためにインデントする

 と、3つの目的がある(と執筆者は考えている)んだなということが分かるわけです。
 このようにインデントされた目次には、執筆者が何を考えてどんな論を展開しようとしているのかをあらかじめ知らしめる機能があります。
 詩や小説のような読者へ驚きを提供する文学作品ならば分かりません。
 しかしそうでない場合、何も分からない真っ暗な洞窟をわずかな明かりで進まされるよりは、結論に至る大まかな道のりを照らされているほうが、読者は理解が進むはずなのです。その一助として、インデントは重要な役割を持っているのです。
 文章でなくプログラムであってもこれは同じことで、プログラムにインデントを付けるということは、後にそのプログラムを読む人(場合によってメンテナンスする人)に、そのプログラムがいったい何をしようとしているのか、その論理構造をあらかじめ分かりやすくしてくれる機能があるのです。

インデントすることで思考を整理できる

 インデントするということは、プログラマにとって(そしておそらく文章を書く人にとって)思考を整理する手段でもあります。読む人にとって分かりやすい表現は、書いている本人にとっても分かりやすい表現になります。
 例えば以下のようなコードがあるとします。

// インデントできるプログラマだけを選別して返す。
IList<Human> filterProgrammers(IList<Human> people)
{
    // 人間のリストを作成する。
    IList<Human> list = new List<Human>();

    // すべての人間についてチェックを行う。
    foreach (var human in people)
    {
        if (human is Programmer programmer)
        {
            // プログラマだったらインデントできるかチェックする
            if (programmer.Indentable)
            {
                // インデントができるプログラマはリストに入れる。
                list.Add(programmer);
            }
            else
            {
                // インデントができないプログラマは死んだほうがいい。
                programmer = null;
            }
        }
    }

    // インデントができるプログラマのリストを返す。
    return list;
}

 コードの内容は4段に分かれています。
 全体ではコメントを含めて28行のコードですが、一番小さなブロック(中括弧で囲まれた領域)は、括弧を含めても4行です。この中括弧で囲まれている範囲のことをスコープなどと呼んだりします。
 このように小さなブロックにコードを分割しておくことで、プログラマはそのプログラムを記述するとき、もしくは修正を行うとき、必要なブロック内のことに集中することができます。
 たとえば「死んだほうがいい」はやりすぎなので、何もしないように変更するとします。インデントされているコードでは変更すべきブロックがどこにあるか一目で見つけられます。
 修正を行ったら、修正を行った箇所からひとつずつ外側のブロックに向かってスコープを広げながら、修正が他の処理に何か影響するかチェックしていきます。このプログラムの場合は直接的な影響はなさそうです。

// インデントできるプログラマだけを選別して返す。
IList<Human> filterProgrammers(IList<Human> people)
{
    // 人間のリストを作成する。
    IList<Human> list = new List<Human>();

    // すべての人間についてチェックを行う。
    foreach (var human in people)
    {
        if (human is Programmer programmer)
        {
            // プログラマだったらインデントできるかチェックする
            if (programmer.Indentable)
            {
                // インデントができるプログラマはリストに入れる。
                list.Add(programmer);
            }
            else
            {
                // インデントができないプログラマも生かしておく(何もしない)。
                // programmer = null;
            }
        }
    }

    // インデントができるプログラマのリストを返す。
    return list;
}

 これがもしインデントなしで全部一行で書かれていたら、このようにはいきません。自分が今どの部分のコードを書いていて、どこに影響するのかたちまち分からなくなるでしょう。

忘れるためにインデントする

 インデントすることで思考を整理でき、読む人の理解を助けるということをここまで述べてきました。そしてプログラムを後から読むのは決してほかの人とは限りません。自分の書いたプログラムを後から自分で見返すこともあるでしょう。
 プログラムというのは後から機能を追加したり、不具合の修正をしたりすることがあります。しかし自分の書いたプログラムのことを隅々まで覚えているという人はまずいないでしょう。むしろプログラマは一度出来上がったプログラムのコードについて積極的に忘れる傾向にあります。
 自分の書いたプログラムを修正したくなったとき、それがスムーズにできるように整えておくというのは重要なスキルです。インデントはそのために必要な一要素と言えます。
 プログラマというのはコンピュータに手順を示すことで様々な作業を自動的に行えるようにします。それによってプログラムの利用者は手順を意識せずにその恩恵を受けられるようになります。
 にもかかわらず、その処理手順のささいなことを覚えておかなければいけいないのは馬鹿馬鹿しいからです。プログラムを作ってコンピュータに処理が任せられるようになったら、中身のことは忘れてブラックボックスとして扱う。それがプログラマの習性です。

インデントしたらおかしくなった??

HTMLの画面レイアウト基本編

 さて、インデントの重要性が分かってきたところでそろそろ本題に入りたいところですが、この後の話を理解してもらうために、もう一つ前提知識を用意します。Webサイトを作るときに使用されるHTMLという言語に関する話です。
 特にWebにも限らないですが、コンピュータで画面ないしはウィンドウ上に物を配置していくときに、主に2つのことをコンピュータに指示してあげる必要があります。
 1) テキストや画像などのオブジェクトをどのようなルールで並べるか
 2) 並べたオブジェクトの余白や境界をどうするか

 この2つが画面のレイアウトを決めるもっとも基本的な要素になると思います。
 1) は、「座標で配置するのか、それとも上から順番に並べるのか」といったことや、「画面に入りきらないときに折り返すのか、スクロールさせるのか」といったことになります。
 2) は、配置したオブジェクトの「パディング」「マージン」「ボーダー」などと呼ばれるものを指定します(下図)。
 下図では、箱のようなものにテキストが入っていて上から順に並べられています。箱の境界(ボーダー)が黄色の部分、境界の外側のオレンジ色の余白がマージン、境界の内側のテキスト部分との間にある緑色の余白がパディングと呼ばれます。

 現代では様々なレイアウトのWebサイトが存在しますが、基本はこういう地道な設定を積み重ねて人間にとって見やすいページを作っていきます。

インデントを付けただけなのに

 さてようやく本題の「インデントをするヤツが死んでしまった話」である。
 Webアプリ制作では、デザイナとプログラマが分業して作業を行うことがある。デザイナさんがHTMLやCSSといったものを使って見栄えのいいページを作り、プログラマがそこに必要な処理を追加してページにデータを埋め込んでいく。
 あるプロジェクトで私はデザイナさんから、インデントの欠片もないHTMLを受け取った。ページは綺麗なのだが、HTMLはぱっと見で何が書いてあるのか分からない。
 デザイナさんはページ制作にある種のツールを使ってデザインしていることが多く、そういったツールの吐くソースというのは必ずしも人間にとって分かりやすいものでないことも多くある。
 例えば下のようなHTMLである。※1

 このままでは分かりにくすぎる。私はせっせと呼吸をするようにインデントを整え始めた。そうしてインデントの整えられたHTMLが以下である。

 おわかりいただけただろうか。
 結果が変わっているのだ。余白が増えて全体的に横に伸びているように見える。しかし当時の私はインデントしたことで結果が変わっているなどと夢にも思っていないのでよく確認していなかった。
 そんなわけで後日、私はデザイナさんに嫌味を言われることになる。

どうしてこうなった?HTMLの分かりにくい仕様

 実はHTMLは、空白文字(半角スペースやタブ、改行)がソース中で意味を持つことがある。だから安易に空白を入れて見やすくなったと喜んでいるとこういう事故に遭遇することがあるのだ。
 というのは、HTMLというのはドキュメントの構造を記述するものだからである。
 さてここからHTMLの空白文字の扱いや回避方法について記述するつもりだったのだが、既に遅刻していることもあるので、ざくっと割愛させてもらって最後にリンクだけ置いておくことにする(後で追記するかも)。※2
 しかしこの話から得ておくべき教訓がある。
 プログラマは必ずしもその扱う言語(プログラミング言語に限らず)の仕様を隅々まで理解して運用していないことも多い。どんなときでも何かが見落とされている可能性を忘れてはいけない。テストという工程はそのためにある。

落とし穴はいつもブラックボックスの中に掘られている

コンパイラが生んだ不具合

 コンパイラというのは、人間の書いたプログラムをコンピュータが理解できる機械語に翻訳するソフトのことである。
 当然このコンパイラに不具合があればコンピュータは正しく命令を解釈できなくなるので大問題となる。だからプログラマはコンパイラに不具合があるかもしれないなんてことを通常では考えない。そんなことを考え出したら、その言語で書かれたプログラムが軒並み正しく動く保証を無くしてしまうからだ。だから、プログラム言語というものを設計・開発している人たちはきっと完璧な仕事をしてくれているに違いない。

 ――そんな風に思っていた時期が私にもありました。

 結論として、コンパイラに不具合があることもある。
 あなたが完璧なヒューマンで、完璧なプログラマであって、完璧なコードを書いたとしても、完璧なシステムは作られない。
 なぜなら言語仕様通りにコンピュータが動いていないかもしれないからだ。

エラーのないシステムは妄想の中にしか存在しない

 完璧なシステムなどといったものは存在しない。完璧な障害が存在しないようにね。※3

 どんなに一生懸命考えて設計したシステムにも見落としは存在する。
 どんなに一生懸命テストしても、ユーザや攻撃者は予想外のことをする。
 そしてあなたには何の責任もないのだが、どんなに一生懸命に構築したって、その土台となるはずの、プログラム言語やフレームワークや製品/サービスに不備があることもあるのだ。

 人間は、当たり前のようにやっていることを、一番見落としてしまう。
 言語仕様に考慮漏れがあるとか、コンパイラに不具合があるとか、高いお金を出して買った製品にセキュリティホールがあるとか、おそらく多くの人は考え(たく)ない。しかしどんなシステムも人間が組み立てたものである以上完ぺきではない。
 あなたの書いたコードは本当にあなたの思った通りに動いているのか。あなたの書いた文章は本当にあなたの意図した通りに相手に伝わっているのか。
 ここまで読んでいただけた人には伝わっていると信じたいのだけれども、私は決してインデントを付けない方がいいという主張はしていない。しかし当たり前のようにやっていることを疑ってみることも大切なのではないだろうか。
 あまりいいオチが用意できませんでしたが、遅刻もしているのでこの辺で終わりにします。以上、インデントしたら死んでしまった話でした。
2023/12/10 深夜37時

注釈

※1このHTMLはフィクションです。執筆者の実際の仕事とは一切関係ありません。

※2HTML の white-space の仕様について参考になりそうなもの
 ・HTMLにおける「空白文字」
 https://reference.hyper-text.org/html5/basicknowledge/whitespace.shtml
 ・空白文字とラッピング:white-space プロパティ
 https://www.w3.org/TR/css-text-3/#white-space-property


※3村上春樹(1979)「風の歌を聴け」より
「完璧な文章などといったものは存在しない、完璧な絶望が存在しないようにね。」

この記事が気に入ったらサポートをしてみませんか?