2018-11-28

情報系の論文投稿はもううんざり

ソフトウェアテストシンポジウム2019東京(JaSST'19 Tokyo)に共同執筆者として経験論文を投稿し採用された。

採用されたのは大変ありがたいことだ。素直に感謝したい。

シンポジウムは2019年3月27日(水)~28日(木)に開催予定なので,論文はリアルタイムOSのテストの関することで,論文の詳しい内容については触れられないが,毎度のことながら査読コメントにはげっそりさせられる。

誤字や内容についての指摘はありがたく指摘を受け入れたいのだが,論文の査読コメントはなぜ,匿名なのだろうか。それってなんで隠すのだろうっていつも思う。投稿者は名乗るのに, ※1 査読者は匿名なのはなぜなのか。

※1 JaSST では査読時は投稿者が誰か知らされていないという指摘があったため訂正。

査読者がもしも知り合いだったら失礼になるので変なこともかけないのだが,査読者が誰だか分からないから遠慮すべきかどうかもまったくわからない。だから,失礼かもしれないが,言いたいことを言ってしまおうと思う。

査読者が匿名なのは,おそらく投稿者である下々の者が,偉い先生方に対してコメントに反論するなど,あり得ない。受け付けないというということなのだろう。※2 でも,論文査読時のその上から目線が大っ嫌いだ。査読者がそういうつもりでなくても,査読のシステムがそうなっている。査読者は名乗らない,査読に対する意見は受け付けないというシステムなのだ。

※2 投稿者/査読者 ともに匿名にすることで公平性を担保する意図があるそうです。

そして,いつも「フン」と思うのは,論文の作法に則っていないという指摘だ。「最初に他の研究の問題点や違いが述べられていない」とか「考察が先,結論が後」とか,「参照する他の論文をもっと掲載せよ」といったコメントは,ごもっともなのだろうが,本質的な話じゃないなと思う。

例えば,論文の投稿者はその学会やシンポジウムに観客を呼び込むための大切なネタ元であると考える。そうすると,学会やシンポジウムの主催者や査読者は次もその次も気持ち良く論文を投稿してもらう必要がある。ならば,論文査読コメントは次のような書きぶりにしたらどうだろうか。

【論文査読結果のお知らせ】

 この度は,○○学会に論文をご投稿いただき,まことにありがとうございます。投稿いただいた論文を拝読だせていただきました。
 △△に関する研究は貴重であり,たいへん興味深い内容です。□□の結果はソフトウェアのーーを向上させることのつながると思います。
 なお,ーーの部分については,さらにーーのような掘り下げを行えば,さらなる展開が見られるのではないかと思います。
 :
 非常に形式的な指摘で恐縮ですが,ーーの部分は,ーーのようにした方がより論文として説得力が高まると思われます。また,本論文と同じような研究があれば,読者の参考となるため,ーーのデータベースで関連する論文を検索して,参照論文として掲載してはいかがでしょうか。
 :

 ○○学会にて,本研究のご発表をお待ちしております。また,ーー様の更なる研究と投稿をお待ちしております。

【例示終わり】※査読がコメントがこんな感じになることはあり得ないけど。

ソフトウェアのレビューにレビューワとして参加するときは,できるだけ本質的なことを重点的にディスカッションし,形式的な問題はレビューが終わったあとにこっそり指摘したり,メールでお知らせしたりして,プロジェクトメンバのモチベーションが下がらないように気を遣ったりしている。

それは,レビューではエンドユーザーに対する価値向上につなげるために指摘をするのあって,ルールやシステムへの逸脱を是正することが最終目的ではないからだ。ルールやシステムに従うことはあくまでも間接的にエンドユーザーに対する価値向上につながっているのだということをすっかり忘れるソフトウェアの品質保証担当もいる。ルールを守ることが目的になっているケースだ。そういう組織では現場のエンジニアはゲンナリしていたり,QAとは建て前で接して本音を言うのはやめようと諦めてしまったりしている。

だから,問題を解決したい,改善したい,世の中のためになりたいと思って論文という書き物をしているのに,形式的な指摘はイラッとすることがある。

だから,自分は論文書いて査読コメントを受ける度に,論文ではなく本で勝負したいと思う。自分はアカデミアにはなれない,ならない思う。論文で偉い先生方に評価されるより,本で「役に立った」という評価を受ける方が100倍うれしい。
アカデミアが学生を育てて教え子が社会に貢献するようになるのは,すごくやり甲斐があると思う・・・
ちなみに,アカデミアが論文に関して新規性や作法に関する指摘をする理由を知っている。学位を取るためには,学会で論文を採用されることが必要であり,論文採用の条件として過去の論文との違いや新規性が求められるからだ。

でも,ソフトウェアの品質向上に関する分野で,役に立つか立たないかをさておき,新規性を最重要と見るのには,強い違和感を感じる。仮に,同じような研究や実証があったとしたって,それが現場の役に立つならいいじゃないかと思う。

また,情報系のアカデミアが数学的に検証可能な論理が大好きなのも知っている。例えばフォーマルメソッドなどがその例だ。数式を使って論理の正しさを証明できると,いかにももっともらしい論文になるから,みんな好きなんだろう。

でも,まってくれよと言いたい。ソフトウェアを作っているのはロボットじゃない人間だろって思う。人間の思考や振る舞いは数式で表すことができない。最近流行のAIだって,人間の脳神経系のしくみをシミュレートしているのだ。

だから,情報系の論文はもっと心理学とか人間の行動学を取り入れていいはずだ。ソフトウェアのメトリックスで語りきれない部分に解決策があることも多い。

GD3 コンサルティング代表/JMAC GD3 センター長 の吉村達彦はトヨタとGMはすでにどちらも90%以上の品質を実現できているが,GMがトヨタに数%勝てないのは「品質を心配する意識:Awareness : Worrying about Quality」の違いだと言った。詳しくはこちら

「品質を心配する意識:Awareness : Worrying about Quality」はおそらく数値では表せない。でも,数値では表せないところを解明していかないと,最後の数%の品質は上がらないのではないか。そこをもっと研究しろよとアカデミアに言いたい。

みなさんは「ソフトウェアエンジニアリング論文集 80's」という本を読んだことがあるだどうか。

これが,論文の形式に則った論文か?といったものばかりだ。超有名どころの論文だから許されるのか? いや,論文が主張するべきところが共感できるから,受け入れられているのではないか。

最初に載っている論文はワインバーグの論文で,冒頭で宮本武蔵の五輪の書を紹介している。

論文の書き出しはこうだ

宮本武蔵は,五輪の書の中で次のように書いている。
大きな所は見えやすし,ちいさき所は見えがたし,其子細大人数のことは即座にもとをりがたし,一人の事は心一つにてかわることはやきによつて,ちいさき所しる事得がたし。
「大きなところは見えやすく,小さいところは見えにくい。というのは,大人数でやることは急速に転換できないから容易に捕捉できるのに対し,個人のことはその人の心一つですぐ変化するから分かりにくい。」
ソフトウェア研究者の Barry Boehmは "Software Engineering Economics" の中で次のように書いている。
へたくそな管理は,他のいかなる要因よりもソフトウェアのコストを急速に増大させる。
 :
ワインバーグだから許されるのかもしれないが,論文の作法はまったく無視している。この本に掲載されている論文はどれも「中身で勝負」という内容であるように思える。

ソフトウェアの品質を向上させるためにメトリクスを取るというのもよくあるし,メトリクスに関する論文はよく見る。でも,ソフトウェアのメトリクスを取るにしても,それはプロジェクトメンバーがソフトウェアの品質を改善するためにメトリクスを取ろう!となれば,有効なデータとなるだろうが,いやいややらされている状態で有効なデータが取れないのではないか。

それは,結局,ソフトウェアの品質問題はエンジニアという人の問題に帰着するからではないか。だから,数字だけを追っかけても改善するわけもなく,人の問題も同時に改善する気持ちがないと効果が上がらないのではないか。

人の問題は数字にしにくいし,数学的論文にはならないから,人をテーマにした情報系の論文はほとんど見ない?が,それでは結局のところ,現場の改善にはつながらないのではと思う。

P.S.
人材の育成や現場の改善に尽力をつくしているアカデミアの方々には敬意を表します。
アカデミアの友人もたくさんいるのでこの手の記事書くときには気を遣うなあ・・・

2018-11-01

Raspberry Pi3を使ったリアル波形描画(4) オブジェクト指向設計の必要性について考える

組込みソフトウェアの開発で使う言語はいまだにC言語が多いと聞く。

下記の図は,独立行政法人 情報処理推進機構 社会基盤センターが調査した「ソフトウェア開発データ白書 2018-2019」のデータである。

これによると,開発言語がC言語であると解答した組織が108で,C++と解答した組織81をまだ上回っている。ちなみに,一位はJavaの629である。

今どき gcc ですら,c++ は対応済みなので,C言語を使っているのはコンパイラがC++に対応していないという理由ではないと思う。それは「C言語でできるのに,わざわざC++で作り直す,C++を学習し直す必要あるのか?」という単純な問いに答えられないからではないだろうか。

日本人が英語を学習するのと同じで,言語の習得というのはハードルが高く見えるものだ。実際使いこなせるようになるには,それなりに時間もかかる。

だから,「C言語でできるのに,わざわざC++で作り直す,C++を学習し直す必要あるのか?」という問いに対する答えはちゃんと用意しておいた方がよい。

自分なら「ソフトウェアの再利用率を高め,開発効率と品質向上のために必要で,10万行を超える規模のソフトウェアアプリケーションではオブジェクト指向言語を使わないと自転車操業から抜けきれない。」と答える。

実際,同じ機能のアプリケーションソフトウェアをCPUやOSが変わる度に作り直して問題を作り込んでしまっている例を少なからず見るが,作り直す工数も馬鹿にならない上に,リリースしたあとに見つかった不具合の対応がこれまた大変だ。

ソフトウェアは見えにくいから,ソフトウェアアイテム(モジュール)の再利用率も見えにくい。ハードウェアならば,共通部品を使ってコストダウンを図る取り組みが外から見えるのに,ソフトウェアでは過去に作ったことのある機能のソフトウェアモジュールを新たに作り直しても誰も文句を言わない。

そうなってしまう理由はいろいろある。例えばこんな理由だ。
  • その機能のソフトウェアモジュールがすでにあることを知らなかった。
  • ソースコードはあったが,使い方が分からないので新規に作ったほうがいい。
  • 他人の作ったソフトウェアは使いたくない。
  • 新規に作った方が売り上げが上がる。(派遣や請負のソフトウェア開発)
  • 再利用せよという指示がなかった。
  • OSやCPUに依存している箇所があるので使えない。
そもそも,再利用できるようなソフトウェアとして作っていない場合,確かに再利用は難しい。そういう組織は「再利用」という言葉は使わず「流用」という。再利用することを意図して作ったソフトウェアではなく,たまたまそこにあったものを使い回すのが「流用」で,流用レベルでしか使ったことがないのだ。

そういう組織,プロジェクトではコードクローン(同じようなコードがシステムのあちこちに散らばっている状態)が多い。

数千行のソフトウェアで製品が動いていたころ,青春時代を過ごし管理職になった技術者は「ソフトウェアを再利用しなければもう無理」という感覚にならないかもしれない。数十万行,数百万行まで増大してししまったソフトウェアを前に「なぜ,不具合がなくらなないのか」「どうしてソフトウェアエンジニアはミスを繰り返すのか」と自問し続けて負のスパイラルから抜け出せなくなっているのではないだろうか。

その状態を脱却するには,再利用率の高いソフトウェアを作るしかない。資産価値の高いソフトウェアモジュールを再利用できれば,その組織のコアコンピタンスになるし,信頼性の高いソフトウェアモジュールを何回も再利用できれば,開発効率と品質を同時に上げることができる。

C++を体験してみる。Turtle クラスを作成し,オブジェクトを作る

この事例は絶版になってしまった「C++プログラミングスタイル」,1992/8, 山下 浩 (著), 黒羽 裕章 (著), 黒岩 健太郎 (著) を参考にしている。

C++言語を学習するには「基礎からしっかり学ぶC++の教科書」を読むことをお勧めする。これから先は C++言語の概要は知っているという前提で進める。

オブジェクト指向設計でソフトウェアを作成すると,再利用がやりやすいことを 亀のひな形を例にして説明する。

亀の実態がシステムの中で一つしか使われないならば,亀のひな形であるTurtleクラスを作るメリットはあまりないが,システムの中で亀1,亀2 のように複数使用する際には Turtleクラス を作るメリットがある。

また,オブジェクトを使う側の者は,オブジェクトに対して必要な命令を与えて,レスポンスを受けるだけの方が使い勝手が良い。オブジェクトの中身の複雑なアルゴリズムなどは知らない方が,責務を分担できる。責務を分担して,オブジェクトの責任と権限を移譲するという考え方は,大規模・複雑化したシステムでは有効だし,そうしていかないと数十万行以上のソフトウェアシステムではやってられない。

100万行を超えるようなソフトウェアシステムでは「隅々まで把握している技術者がプロジェクトに一人以上いる」という状態を維持できない。

ということで,Turtle クラスを設計してみる。

1.1 Turtle クラスとは
  • X座標,Y座標,向きをクラスの内部(private メンバ)に持つ
  • 外部からは,左を向く,右を向く,指定距離だけ前進することを指示できる。
  • 外部から,現在のX座標,Y座標,向きを尋ねることができる。

Turtle オブジェクトの利用者は,Turtle が内部でどのような動き(処理)をしているのか知らない方が,Turtle を利用しやすい。右を向けとか,左を向けとか,nだけ前進しろとか,今の向きやX,Y座標を聞いたら答えてくれるだけの方が使い勝手がいい。

よしんば,Turtle の中身を知っていると中身をいじりたくなってしまう。これがC言語開発の良くない点だ。

そもそも再利用することを前提に作っていないので,ベターッとソースコードをいじってしまう。さわらなくていいところを隠蔽して,インタフェースだけをアクセスできるようにしようという意図がない。

もちろんC言語でそういった変数や関数の隠蔽は可能だが,そういう意識を持った人だからできることであり,C++を使えば言語上の縛りがあるから,自然とそういった設計になる。

Turtle クラスは ひな形(クラスが持つメンバ変数,メンバ関数が定義されている。このひな形を元にして,オブジェクトを生成(ひな形で定義した変数,関数の領域を確保して,初期化して使えるようにする)する。

同じ性質を持つオブジェクトを複数生成し,それぞれを独自に動かすことができる。
下記の例では, TurtleオブジェクトA と B は別々のタートルとして,動かすことができる。

これは構造体を使って実態を2つ作るのと同じだ。組込みではクラスとオブジェクトは一体一のことが圧倒的に多いからもしれないが,このしくみを使うと意外と簡単におもしろいことができるようになる。

1.2 方向

  0~360° で方向を指定する。






            0°
           ↑
     270° ←  亀   →  90°
                   ↓
           180°

Turtle クラスのソースコード(ヘッダー)ap_turtle.h

#ifndef AP_TURTLE_H
#define AP_TURTLE_H

class Turtle
{
public:
    Turtle();
    void turnleft();                // 左を向く
    void turnright();               // 右を向く
    void forward(int distanse);     // 前進する
    int getXPosition(void);        // 現在のX軸の位置を得る
    int getYPosition(void);        // 現在のY軸の位置を得る
    int getDeraction(void);        // 現在の向きを得る

private:
    int mX;          // X座標
    int mY;          // y座標
    int mD;          // 亀の向き
};

#endif // AP_TURTLE_H

Turtle クラスのソースコード ap_turtle.cpp

#include "ap_turtle.h"

Turtle::Turtle()
{
    mX=0;
    mY=0;
    mD=0;
}

void Turtle::turnleft()
{
    mD=mD-90;
    if (mD < 0) mD = mD+360;
}

void Turtle::turnright()
{
    mD=mD+90;
    if (mD>360) mD=mD-360;
}

void Turtle::forward(int distanse)
{
    if ((mD==0)||(mD==180)) mY=mY+distanse;
    if ((mD==90)||(mD==270)) mX=mX+distanse;
}

int Turtle::getXPosition()
{
    return mX;
}

int Turtle::getYPosition()
{
    return mY;
}

int Turtle::getDeraction()
{
    return mD;
}

Turtle クラスのソースコード main.cpp

#include
#include "ap_turtle.h"
#include
 using namespace std;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Turtle turtleA;
    Turtle turtleB;

    printf (" Tuttle A Position (X , Y) = ( %3d , %3d ) \n", turtleA.getXPosition(), turtleA.getYPosition());
    printf (" Tuttle B Position (X , Y) = ( %3d , %3d ) \n", turtleB.getXPosition(), turtleB.getYPosition());

    turtleA.forward(10.0);
    turtleB.turnright();
    turtleB.forward(20.0);

    printf (" Tuttle A Position (X , Y) = ( %3d , %3d ) \n", turtleA.getXPosition(), turtleA.getYPosition());
    printf (" Tuttle B Position (X , Y) = ( %3d , %3d ) \n", turtleB.getXPosition(), turtleB.getYPosition());

    return a.exec();
}

サンプルプログラムの解説

  • Turtle クラスのオブジェクト turtleA と turtleB を生成し,現在の位置を表示。
  • turtleA を 10前進させる。
  • turtleB を左に向かせる。(左に90度)
  • turtleB を 20前進させる。
  • turtleA と turtleB の現在の位置を表示。
Turtle クラスの向きの変え方や前進,後退の仕方は Turtle クラス の内部に隠蔽させているので,turtleA や turtleB を動かす側のユーザーは,現在の位置確認と右向け,左向けといくつ前進させるのかだけを指示すればよい。

こうしておけば,そのソフトウェアアイテム(オブジェクト)を使う側の視点と,内部のしくみの視点を分離することができる。

内部のしくみの信頼性が高く,ソフトウェアアイテム(オブジェクト)の使い勝手がよければ,このソフトウェアアイテムは再利用資産となる。

ソフトウェアアイテム(オブジェクト)が複数の製品群に渡って再利用可能な資産となれば,新に作らなければいけないソフトウェアが減り,開発効率が上がる。

だだし,再利用可能な資産となるかどうかは,そのソフトウェアアイテム(オブジェクト)に何をさせるのか,どんな責務を持たせるのか,今後のソフトウェア修正の要求に耐えうるのかといった要件を満足させるくらいの出来でないとダメだ。やみくもに作ったのでは再利用資産にはならない。

そういう意味で Turtle クラス はちょっと工夫すれば,有名なテキストベースのゲームスタートレックゲームに応用できる。

次回は,Turtle クラス を修正して,スタートレックゲームの簡易版を作ってみる。


スタートレックシミュレーションゲーム(Wikipedia)

<スタートレックゲームのオリジナルの動画>
  1. スタートレックゲームのソースコードと解説
  2. MZ-80 でスタートレックゲームを遊んでいる動画
  3. Apple II でスタートレックゲームを遊んでいる動画