わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

You must / You can

きれいなコードを書くための鉄則

きれいなコードを書くための鉄則

「aが10から20までの間」という条件を考えてみます。たとえばSQLにはBETWEENという便利な書き方があって、「a BETWEEN 10 AND 20」のように書くことができます。しかし、たいていのプログラミング言語では不等号と論理演算子を組み合わせることになります。このとき、不等号の向きによって、いくつかの書き方ができます。

a >= 10 && a <= 20  ―(a)
10 <= a && a <= 20  ―(b)

(p.39)

そのあと,「10 <= a <= 20」と書くわけにいかない話となります.この種の式は今期,小テスト*1で出題し,試験でも問いました.意図は2つあって,一つは,数式の「10≦a≦20」に対応するCのプログラムコードは「10 <= a <= 20」ではないんだよということ,もう一つは,「<=」は左結合の演算子なんだよなあということです*2
本はというと,そういった数式との対応づけで,たいてい(b)を推奨しているとした上で,“(b)の書き方はどうしても馴染めません”と言います.次のページに行くと,囲みの箇条書きで1項目,“不等号は < と <= のみを使用し、> と >= の使用は禁止する”とし,世の中にはこんなコーディングルールもあるようだ,としています.
そのルールだと書きにくいコードの例を示し,p.41へ.結論は,“比較対象となる変数、式は左側にあったほうが意味が理解しやすいと思います”.
主張はわかるものの,すっきりしません.読んでしばらくは,(a)すなわち「a >= 10 && a <= 20」だと都合の悪い例が書かれていない点に,引っかかりを覚えました.すなわち(a)と(b)を対等に取り上げておらず,(b)を悪者にして(a)のほうがいいと主張したいのかな,とも思ったのですが,そうでもなさそうです.
もう少し考えて,見当がつきました.これは,

  • 不等号のうち,> と >= の使用は禁止する

  • 不等号について,< も <= も,> も >= も使っていいじゃないか

との対立なのでした.こう設定すると,> と >= の禁止によって,不自然な書き方になる例も作りやすくなります.そして,言語仕様として提供されているものは,そりゃ,活用するほうがいいだろう,などと進められます.
著者の結論は“比較対象となる変数、式は左側にあったほうが意味が理解しやすいと思います”でした.これをあえて,悪意に解釈して,

  • 等式や不等式では,比較対象となる変数・式は左側に書く

というコーディングルールを設けたら,どうでしょうか.やはり,息苦しく見えます.その都度,比較対象となるのが何かを,チェックする必要があります*3.2種類,別々の過程で計算した値を,比べようとするとき,「比較対象となる変数」はどちらなのでしょうか.
これは,

  • 等式や不等式では,比較対象となる変数・式は左側に書かなければならない

  • 等式や不等式では,左右に何を書いてもよい

との対立と見ることができます.
さらに,次のようにも考えることができます.まず,「不等号について,< も <= も,> も >= も使っていいじゃないか」にせよ「等式や不等式では,左右に何を書いてもよい」にせよ,ルール(規制)を設けない状態から始まります.
その上で,実際にコードを書いたりレビューをしたり,修正したりしていきます.そうしながら,不等式の書き方について,慣習・慣例が形成されていきます.
ある状況においては,「> と >= は使用しない」や「比較対象となる変数・式は左側に書く」といった慣習・慣例が,確立することもあります.
そうしてできた慣例は,「不文律」「暗黙の了解」として,実質的なルールとなることもあるでしょう.
著者のいう“不等号は < と <= のみを使用し、> と >= の使用は禁止する”は,慣例がルール化されたものなのかもしれません.


ここまで示した2組の対立は,「You must」と「You can」との対立と言うことができます.
「かけ算の順序」論争にも適用できそうです.順序の有無というのは,

  • かけ算には順序がある

  • かけ算には順序がない

との対立というよりは,

  • かけ算の式では,順序を意識しなければならない

  • かけ算には,順序があるものと,順序がないものがある

との対立として,表すことができます.「You must」と「You can」が確認できるように,英訳しておきます:

  • You must pay attention to the order of the multiplication.
  • You can find ordered multiplications and unordered ones.

とはいえ,このような対立構造は恣意的なものです.小学校の授業例などから,うかがい知ることができるのは,「かけ算には,順序があるものと,順序がないものがある」を前提とし,2年の導入のほか,学年が上がっても「かけ算の式では,順序を意識」すべき状況が多いということです.順序を意識すべきでない事例としては,面積と,順列・組み合わせの計算*4が思い浮かびます.


「C」と「5×3」の両方に属する記事として,これまでcalloc射影多次元配列の要素数・再考を書いてきました.canとmustについては,英文から学ぶ *10でも取り上げています.

(リリース:2013-02-07 早朝)

*1:授業で参考書に指定している『Cプログラミング入門以前』では,pp.214-215で取り上げられています.「a == b == c」「30 <= a <= 60」は間違いであり,代わりのコードとして「a == b && b == c」「30 <= a && a <= 60」を挙げています.

*2:読解問題のプログラムコードには,「p = q = s;」が入っていました.代入演算子は右結合なので,動作としては「q = s; p = q;」,実質的には「pとqの値をsにする(ポインタp,qの指し示す先をsに合わせる)」となります.

*3:とはいえ無用なコストというわけでもなく,その手間が,各条件式を精査することにつながる,という主張も可能でしょう.

*4:「計算による出し方は,軽く触れる程度にします」「深入りする必要はありません」と書かれた本を,一昨年の6月に,取り上げています.なぜそうなっているかは,順列や組み合わせは,場合の数の積の法則,そして直積(順序のないかけ算の典型例!)によって説明できるからでしょう.