わさっきhb

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

優先順位

優先順位は,評価順序ではない

C言語で利用可能なさまざまな演算子,そして式の評価方法を決めるための,演算子の間の「優先順位」と「結合の向き」を学び終えたところで,日常生活にも活用してほしい,アドバイスを送りたいと思います.
それは,「優先順位は,評価順序ではない」ということです.
Cで例を挙げましょう.「α || β && γ」という式を考えます*1.α,β,γはそれぞれ変数というよりは,それぞれが複雑な式である*2と考えてください.ちなみにあるコンパイラでは,この式を書くと「まぎらわしいよ」と警告を発してくれますが,文法的には間違ってはいません.
さてこの式,どんな順番で評価するでしょうか?
優先順位としては,&&のほうが,||よりも高いです.あえてカッコをつけると「α || (β && γ)」となります.なので,&&を含む部分式の評価が先で,そのためには,&&の左側,すなわちβが真か偽かを見なければならない…
というのは,間違いです.この式は,まずαの真偽を見ます.αが真なら,βやγの式を評価することなく,この式全体は1すなわち真となります.
αが偽なら,そこで,β && γを評価することになります.つまり,βの真偽を見て,偽なら,γを見ることなく0.βが真だとしたら,γも見て,真なら1,偽なら0です.
優先順位だけを見れば,β,γ,αの順じゃないのと思いたいところ,実際にはα,β,γの順に評価するわけです.これは,&&や||という演算子の特殊な性質によるところが大きいのですが,ともあれ,「演算子の優先順位は,その式の評価の順序を決めるものではない」というのは,知っていて損はないでしょう.

評価しないのは,優先順位が低いからではなく,依存するものがあるから

とはいっても,「α || β && γ」は極端な例です.通常は,優先順位と結合の向きによって,評価の順序も自ずと決まります.また,「こんなの,書いたらどう評価されるのかな…」と思うような式は,たいてい規格において「未定義」となります.
「a[i++] = i;」という式を考えてみましょう.aは配列で,iがそうですね5のときに,この式を評価すると,「a[5] = 5; i = 6;」となるでしょうか? 「a[5] = (i++された後のi);」となってa[5]には6が代入されるでしょうか? これは未定義です*3.実用上,書いてはいけないのです.
さてでは,優先順位に絡めて,世の中の言説を一つ,挙げてみましょう.
「優先順位を付けるのは,害悪だ.低い優先順位をつけると,ずっとそこに,手をつけられることがない」というのがあります.
世の中の優先順位付けというのは,人手で行う主観的なものであり,そもそも優先順位をつける対象は,それぞれ一応別個で,作られた優先順位リストに基づいて,人間あるいは組織が行動するとか,問題解決するとかいったものです.プログラミングで,おっとここは万全を期して,プログラミング言語の仕様あるいは規格として出現する,優先順位というのは,コンパイラインタプリタなどが行い,常に一意に定めるものですし,式にせよプログラムコードにせよ,評価の前段階では,演算子オペランド,あるいは何らかの評価値を決める要素を切って捨てる,ということはできません.
そういう違いがありながらも,さきほどの言説に対して,Cの演算子を通じて優先順位の概念を学べば,一つの反論ができます.それは,「手を付けないのは,優先順位を低くしたからではなく,依存するものがあるからではないか?」です*4
Cの式の評価については,評価されないかもしれないものがあります.3つですね.論理ANDの&&演算子,論理ORの||演算子,そして?:による3項演算子です*5
さて解説…&&と||は先ほど取り上げましたので省略しまして,?:は,「α ? β : γ」という形で,3つのオペランドをとります.評価の順序は,最初にαを見ます.これが真なら,βのところを評価しまして,その結果が,この式全体の評価値となります.αのところが偽なら,γですね.それの評価結果が,その式の結果ということです.
逆に言うと,αが偽なら,βは評価されないし,αが真なら,γは評価されない,ということです.βやγの中に,代入演算子や増分,減分演算子があっても,代入によって変数の値が変わることはない,そこは必ずしも評価されない,というのはきちんと理解してから使いましょう.
Cの式で,評価されない箇所があるのは,優先順位ではなく,その演算子をどう解釈するかのルールが決められているからです.
では世の中の,「低い優先順位をつけたために,ずっとそこに,手を付けられることがない」ケースは,どう理解すればいいのでしょうか?

優先順位は,いずれも無視できないものの間で付ける

私から言うと,これは,「優先順位というのを,何に対して付けるのか」の考え方の違いです*6
優先順位付けは,いずれも無視することができないものを対象とします.そして,そのすべてにまんべんなく対応するのは,時間や金銭,ヒューマンパワーなどのリソース不足が理由で,できないというのが前提です.そんな状況で,メリハリをつけ能率良く問題解決をしていくために,優先順位を付けるという作業を行うのです.
この考え方だと,「手を付けられることがない」ような課題は残りません.優先順位付けをする前に,それは優先順位を付けるに値する対象であるかを,しっかりとチェックするからです.取るに足りないものは,その段階で取り除かれます.他の項目に吸収されることだって,あるでしょう.
そして一人でえいやっと決めるか,何人かで合議するかして,優先順位を付けたあと,行動するときは,優先順位リストの内容を全て見てから,見ながらとなります.当然ですが,優先順位の見直しは,必要に応じて行います.すっかり解決したものは,取り除きますし,順位を上げないといけないものや,新しい項目を設けることも,あるでしょう.

優先順位は前後関係ではなく上下関係

そして,優先順位はその項目の間の上下関係であり,必ずしも前後関係ではありません.
限られた予算を割り振るというシチュエーションで,例えば7項目あって優先順位を付けたとして,順位の高いものから満額を配分して,途中で足りなくなったらそこまで,そして下位の項目には1円も配分されない…というのが,前後関係の一例です.
もちろん,そんなことをしてはいけません.先ほど言ったことの繰り返しですが,「いずれも無視することができない」のです.
で,どうするかというと,優先順位1位には,満額を配分することにしましょう.2位以下には,100%は無理ですが,高い順位ほど高い充足率になるよう,減額配分しましょう.というのが,上下関係に基づく優先順位の活用です.
そうそう,予算配分に優先順位を付けるのは,絶対必ず100%誰がやっても今言ったやり方,というわけではありませんので,組織の中で,優先順位付けという作業をするとなったら,取りまとめの人が,その優先順位をどのように利用するのかを説明し,決定に関わる人の間で同意を得ておく必要があるでしょうね.
予算は数量であり,100%にも0%にもできます.では必ずしもそうはいかないタスク(問題解決)に対して,上下関係の優先順位はどういうことかというと,そうですね,項目ごとに,達成目標と,その達成に必要な,リソースの推定値を書いてみましょう.リソースは,一人でするなら作業時間でいいでしょう.1か月単位で組織でとなると,「人月」ならぬ「人日」が,いいかもしれません*7
そうすればあとは分かりますよね.決めた期間内に活動し,期間経過後に検証するのです.そして次の期間の,優先順位の決定に使用します.
優先順位を付けて行動するのはビジネスマンなら当たり前,かもしれませんが,プログラミングと同様で,ルールが与えられたら誰でもすぐに正解が作れる,というものではありません.慣れです.大学生活の中で「優先順位を付けること」を心がけ,ときには痛いミスもしながら,日常生活のツールとして自分のものにしたら,試験前や就職活動のとき,そして社会人になってからも,きっと役立つでしょう*8
そうそう,検証は,必ずしも期間経過後でなくてもかまいません.
自動集計できる機構を用意して,期間の途中に,眺めるのです.「あれ,これ,優先順位を高くしてたのに,下位のものより,リソース(の割合)が低いぞ,どうなってるんだ?」と分かれば,課題や優先順位を見直したり,関係者の間でコミュニケーションをとったりするのもいいでしょう.

*1:http://d.hatena.ne.jp/takehikom/20070127/1169846276

*2:必要ならα,β,γそれぞれは,一番外側で「(」と「)」で挟まれていて,それらの式に含まれている演算子が,|| や && に影響しないようになるものとします.

*3:JIS X 3010 : 2003 p.48 脚注(70).

*4:あとの展開に出せなかったので,脚注として書いておきますが,日常生活において手を付けない理由は,漫然としたやる気のなさではないでしょうか.「それが重要」「解決しないと」など,ふとしたきっかけで気づけば,それを最優先にしてきびきび行動できるというのも,よくあることです.なので,優先順位リストに入れるべきかはともかく,頭の片隅に引っかけておくだとか,メモやどこかのファイルに書き残しておくといったひと手間は,かけて損にはならないでしょう.

*5:「Cの式で,必ず評価されないもの」となると,可能性が一つ増えます.「sizeof(x++)」のような,sizeofのオペランドの中の副作用です.

*6:「『優先順位というのを,何に対して付けるのか』が間違っている」と切って捨て,その後に自分の考え方・やり方を提案するという書き方のほうが,ブログでアクセスを呼ぶための調味料のように思うのですが,どうもそういう表現は好きになれません.アクセス数やブクマ数,被引用に左右されず,今の自分が読んで最善だと思う表現を,選び続けていくことにします.

*7:wikipedia:人月

*8:http://d.hatena.ne.jp/takehikom/20080221/1203541549,自己管理