2012/11/25

ソフトウェアの3つのインターフェイス
The 3 Interfaces of Software

ソフトウェアは以下の3つの存在に対して境界面を持ちます。
  1. ユーザ
  2. コンピュータ
  3. 開発者
もちろん、
  1. ユーザにとっては使いやすく
  2. コンピュータにとっては計算しやすく
  3. 開発者にとっては、保守も含めて開発しやすい
ソフトウェアが理想です。
必ずしもこれらは互いに対立するものではありませんが、
  1. 全てを1つにまとめる必用があること
  2. 人とコンピュータとでは得意/苦手なデータ構造やアルゴリズムが異なること
  3. 人は立場によって欲する情報が異なること
等の理由よって、トレードオフの関係になることもあり、
なかなか理想通りにはいきません。

これだけでも大変なのですが、ソフトウェア開発においては、
ユーザと顧客とが異なる場合も少なくありません。
たとえ顧客とソフトウェアの間に直接の接点はなくても、
何分お金を出して頂くスポンサー様です。
開発者は顧客を満足させるために、
いろいろと考えなければなりません。


開発者は、(コンピュータも含む)4種類の異なる方々を
満足させるソフトウェアを設計/実装する必要があります。
大変なわけです。



2012/10/22

ファーシーアの一族と道化の使命

洋物のファンタジィでは久しぶりの当たりでした。

<ファーシーアの一族> 著:ロビン・ホブ、訳:鍛治靖子 
  ・騎士の息子(上・下)
  ・帝王の陰謀(上・下)
  ・真実の帰還(上・下)

全て文庫本(創元推理文庫※)です。
もともと小さな字がビッシリとある本なのに、巻を追うごとに分厚くなっていきます。
6分冊で 1.6cm  -> 1.4cm -> 2.6cm -> 2.4cm -> 2.8cm -> 2.8cm。
しかも、話がなかなか進みません。よくこんな本が売れるものだなと思います。
まぁ、読み始めれば、面白いのですがのですが。

    
        
            

翻訳者の鍛治靖子氏は、ファンタジーの翻訳時にはできるだけカタカナを使わないようにしているらしく、「火酒」など、普段は使うことのない古風(?)な日本語も楽しめます。
ただ、本作では、名前の意味が重視されていて、意味のある(英)単語が人(や馬などの動物)の名前として付けられる文化を持った世界となっています。読み出せばすぐに分かることですが、タイトル中の「騎士」「帝王」「真実」も、実は登場人物の名前です。
ちょっと意地の悪い楽しみ方になるかも知れませんが、このあたりの翻訳の苦労を想像するというのも、一つの楽しみ方でしょう。

なお、続編も刊行中です。

<道化の使命> 著:ロビン・ホブ、訳:鍛治靖子
  ・黄金の狩人(1・2・3)
  ・仮面の貴族(1・2・3)

続編の「道化の使命」では同じ3部作ですが、各部3分冊になっています。
1冊が普通の厚さ(1.6cm程度)で、行間の隙間も広くて読み易いです。
しかしこの続編、最後の第3部が未翻訳です。早期の翻訳を望みます。
    
       
こうして並べてみると、「道化の使命」の表紙は、3冊で1枚の絵になっていたのですね。
全く気がついていませんでした。

※創元推理文庫
 東京創元社の文庫には、「創元推理文庫」と「創元SF文庫」等があります。
 なぜか推理(ミステリィ)だけでなく、ホラーとファンタジィも「推理」に入っています。
 ホラーはともかく、「ファンタジィはどちらかというとSF」な気がする私でした。

2012/10/16

構造化/クラス指向/オブジェクト指向/サービス指向
Map Methods to the Abstraction Plane

先日のとある雑談のまとめ。その2。

前回の抽象化の基本2軸と照らし合わせながら
ソフトウェアの設計手法について、少し考えてみます。

  1. フローチャート
  2. 構造化設計/構造化プログラミング
  3. クラス指向
  4. オブジェクト指向
  5. サービス指向

1. フローチャート
 「フロー」という名前の通り、
 動的な振る舞いを記述する手法です。
 条件分岐や繰り返し等もありますが、
 基本的に上から下に流れる1本道です。
 小さなバッチ処理であれば、これで十分ですが、
 構造の記述が容易ではないため (つまり設計者に構造について考えることを促さないため)

 ソフトウェアの規模が少し大きくなると、
 使い辛い手法になってしまいます。

2. 構造化設計/構造化プログラミング
 階層的に抽象化されたプログラムの組み合わせとして
 プログラミングを記述する手法です。
 簡単に言えば「本の目次」のように
 プログラムを設計/実装することです。
 鳥の目から虫の目に段階的に変化していくということです。
 但し、「本の目次」であるため、前から順に読んでいくという
 フロー(=振る舞い)の記述も含んでいますが、
 1本道であるという点ではフローチャートと変わりません。

3. クラス指向
 さしあったって、クラス指向では
  構造化プログラミングでの構造化を助けるために、
  クラスという枠組み(箱)を提供している
 と考えれば良いでしょう。
 オブジェクト指向言語を導入したバッチプログラムで、
 よく見かける形態です。

4. オブジェクト指向
 バッチ処理の場合、振る舞いはほとんど1本道のため
 設計上は余り問題にはなりませんが、
 ユーザー対話型のイベントドリブン処理の場合、そうはいきません。
 様々な状態での様々なイベントに対して、
 適切な振る舞いを提供するというのが、
 大きな設計課題となります。
 そこで、構造とともに振る舞いをモデル化する
 オブジェクト指向設計が、もてはやされているわけです。
 とはいえ、イベントドリブン処理といえども
 一度振る舞いが決定されれれば、
 そこから先は(比較的短い)1本道です。
 構造化が重要なことに変わりはありません。

5. サービス指向
 鳥の目で、静的な構造を決定するときの手法の一つです。
 業務全体を鳥の目で見て、業務上の一処理を基本粒度として
 ソフトウェア群を構造化するという手法です。
 ソフトウェアの大規模化とクラウドコンピューティングの台頭により
 全体の構造がどうあるべきかということが、
 昨今のホットな話題になっているのでしょう。


ということで、雑談のまとめはこれで終わりです。


2012/10/15

設計と抽象化
The 2 Axises for Abstraction


先日のとある雑談のまとめ。その1。

そもそも(ソフトウェアの)設計とは何でしょうか?
広辞苑によれば、設計とは
  …或る製作・工事などに当たり、その目的に則して、
  工費、敷地、材料および構造上の諸点などの計画を立て
  図面その他の方式で明示すること。…
とのことです。
「その目的」とは、何らかの問題解決でしょう。
「図面その他の方式」とは、実物を作るのではなく、
モデルを作るということでしょう。
「設計」のインスタンスが「実装」という考えです。
そこで、ここでは設計を
 「問題を解決する解(案)のモデルを作ること」
と定義して、
少し考えてみることにします。

  1. 解(案)
  2. 抽象化
  3. 解はどこから来るのか?

1. 解(案)
 「解」ではなく「解(案)」としたのは、
 実際に作ってみるまでは、それでうまくいくのか
 わからないことも多いからです。
 なお、問題にはいくつもの説明が可能であり、
 そのため、解もいくつでも存在しえます。
 もちろん、解の良し悪しはありますが、
 最終的にはそれも価値判断でしかありません。

2. 抽象化
 実物を作るのではなくモデルを作るということは、
 抽象化するということです。
 抽象化とは、思考方法の一種で、
  対象から注目すべき要素を重点的に抽出し、他は捨て去る方法
 です。
 そこで、何に着目し、何を捨てるかが問題になります。
 決まった答えはありませんが、ソフトウェア設計に限らず、
 抽象化に以下の2つの軸が広く使用されています。

 (1)鳥の目 <-> 虫の目
 (2)静的 <-> 動的

 (1)鳥の目 <-> 虫の目
  鳥の目は、全体像に着目し、細部を捨て去ります。
  虫の目は、細部に着目し、全体像を捨て去ります。
  巨視的/微視的、マクロ/ミクロ、等呼び方は色々です。

 (2)静的 <-> 動的
  静的な視点は、構造に着目し、振る舞いを捨て去ります。
  動的な視点は、振る舞いに着目し、構造を捨て去ります。
  データ構造とアルゴリズム、と言った方が判りが良いかもしれません。
  会計でのストック/フロー分析も同じ手法です。

3. 解はどこから来るのか?
 これが一番問題なのですが、
 設計解を得るプロセスは明確ではなく、
 設計者の思いつきや閃きといっても過言ではありません。
 とはいえ、ゼロからでは思いつきや閃きは生まれません。

 設計中は、虫の目 <-> 鳥の目  静的<->動的 を
 行ったり来たりしならが、
 知識と経験を基にしたパターンマッチングや
 演繹/帰納/アブダクションを行っているのだと思います。


ということで、続きはまた明日。

2012/10/14

堂島ロールと山田池公園

久方ぶり、かつ100エントリー目の節目に当たる投稿です。
が、特に内容はありません。m(_ _)m

昨日の朝ごはんは、パティシエリー モンシュシュの堂島ロール。


こういうのは、切らずにそのままフォークを突っ込んで食べるのが、美味しいのです。
ごちそうさまでした♪

-----------------------------------------------------------------

さすがに食べた分は、ちょっと運動しないといけない。
ということで、こちらも久方ぶりに山田池公園をお散歩。

池の水は一応戻ってますね。前回(2012/01)の写真とは大違いです。


ピラカンサでしょうか?赤い実がたくさんなっていました。

山田池大橋のあたりは、綺麗というか汚いというか、
緑色の縞模様ができていました。藻でしょうかね。

ところで、池干し調査についてちょっとWeb調べてみると
大阪府のWebサイトに報告書がアップされていました。
「なぜExcelなのか?」というツッコミは置いておいて
(と言いつつツッコんでますが)
全部で4ページで、一般向け広報としては
それなりに良くまとまっているのではないかと思います。

しかし、前回気にしていた生態系への配慮についても、よくわかりませんでした。
魚については、捕獲して養魚池で保管されたようですが、
水生植物/昆虫/鳥などへの影響がどうであったのかも、知りたいところです。

報告書にある通り「前例の少ない事業」ですので、
元データや写真など、更に詳しい情報も公開してもらえると
各所で有効活用されるのではないでしょうか。


2012/02/17

「Beautiful Code」を読む(下)

「Beautiful Code」をついに最後まで読了。3回目、最後のふりかえりです(1回目の中間ふりかえり、2回目の中間ふりかえり)。こんな企画(?)、始めるんじゃなかったと、何度後悔したことか... まあ、それでも最後まで辿り着けた要因の1つに、つぶやかないといけないという緩い義務感があったのも確かです。

第23章 MapReduceでの分散プログラミング
解決したい問題を解くコードの詳細と並列化のための詳細を分離して、並列化処理をフレームワーク化。並列/分散プログラミングの経験がなくとも並列/分散が容易に可能。
MapReduceは「Googleを支える技術」西田圭介(技術評論社 WEB+DB PRESSプラスシリーズ)で読んでいた内容で、復習になりました。

第24章 美しきかな、並列
昨日に引き続き、並列処理が問題。並列処理間で動作を協調させる手法としてのロックにはデッドロックやロック漏れ等色々と問題があるが、もっとも基本的な弱点はモジューラプログラミングをサポートしていないこと。
ロックに替えてHaskellにあるソフトウェア・トランザクショナル・メモリ(STM)を使用することで、うまく解決できる。が、詳細はちょっと消化不良です。
前章のMapReduceはデータをうまく分割して並列処理間でのロックによる動作協調を不要にしている。但し複数種類のトランザクションが同一データに対して実行が必要なときには、何らかの排他処理が必要で、それを解決するのがSTM。

第25章 構文の抽象化:syntax-caseマクロ
読み飛ばし。LISPもSchemeも知らないし「The Scheme Programming Language」も読んでられませんので。

第26章 労力節約のアーキテクチャ:ネットワークソフトウェアのためのオブジェクト指向フレームワーク
ネットワークプログラミングの非本質的な複雑さの多くは、CレベルのOS APIを使うことに起因する。
ソケット通信やマルチプロセス/スレッド用のAPIは、OS間の互換性がないだけなく、同じOSのバージョン間でも互換性がない場合がある。包囲ファサードパターンを用いてAPIとそのデータとを安全なオブジェクト指向クラスの内部にカプセル化する。

第27章 ビジネスパートナーをRESTfulにまとめ上げる
URLとリクエスト文字列でコマンドディスパッチを行い、データを取得/更新し、レスポンス文字列を生成して返す、というのがWebサービスの基本構造。
ディスパッチされたコマンドに対応する処理をファクトリパターンで行うなど、基本を確認するのに良い内容です。文中の例でデータ取得にPOSTを使用しているは、リクエストXMLが長くなってGETで処理しきれないからでしょう。

第28章 美しいデバッグ
プログラマにとっては、機能に富んだデバッグツールの使用方法を習うよりも、系統立ったデバッグ手法の訓練をする方が重要。仮説検証サイクルを回しながら欠陥のある場所の範囲を狭めていきます。
欠陥混入前のコードと混入後のコードのテストコードを用いて自動的に差分デバッグすることで、完全自動デバッグが可能となる。つまり人間による対話的なデバッグが全く必要なくなります。

第29章 エッセイのごときプログラム
プログラムの美しさは、効率良くプログラムを書き、効率良くプログラムを読解し、効率良くプログラムを修正できるところにある。簡潔さ、保守的、シンプルさ、柔軟性のバランスが大切。
抽象化とは、いくつかの概念の塊をまとめてより高次の概念を作り出すこと。一度に扱わなければならない概念の数が減るので理解を助け、再利用や保守も容易になる。言語が積極的に抽象化を行うことで、プログラムをより簡潔にすることを支援できる。
軽量言語の仕様、文法、ライブラリ量は少しも軽量ではない。目標はプログラマの労力の軽量化であって言語自身の軽量化ではない。本質的に複雑な問題を解決するための言語のシンプルさを追求すると、プログラマに複雑さを押し付けることもあり得る。

第30章 世界につながる手段がボタンだけだったら
理論物理学者のホーキング教授は、たったボタン1つで操作するソフトを使って書いたり話したりする。ボタン1つで手際よく使えるエディタを考案するのは、非常に興味深い技術的挑戦。
実はボタンは、ただ押した/押さないの2値の入力装置ではなく、押す時間の長さを変えて信号を出すことも出来るアナログ装置である。「長押し」の発想ですね。

第31章 Emacspeak:完全に音声のみのデスクトップ環境
GUIと同様の効率の良さを目を使わない環境でも達成することが音声デスクトップの目標。言葉だけでなく、言葉以外のオーディオ出力の表現力を活用する。
ACSS(音声スタイルシート)で発話のスタイルを指定する。CSSなのでカスケードが可能。コメント用の音声と太字用の音声を合成することで、コメント中の太字の音声を表現出来る。 また頻繁に発生する事象は音声アイコンで通知する。

第32章 働くコード
本のようであること、似たものは似て見えるようにすることについては全く同感。1画面で2バージョンのコードを並べて表示するdiffツールでも、行全体を見るために横スクロールが不要な程度に1行が短いのはすごい。
プログラマはコードを構文に応じて色づけしてくれるテキストエディタだけを通して読むわけではなく、diff、merge、パッチ、コンパイラのエラーメッセージ、デバッガ等を通じても読むので、コードの見た目は、結構重要。

第33章 「本」のためにプログラムを書く
この「本」は数学家ポール・エルデシュのいうところの「本」。「平面上に任意の3点が与えられたときに、その3点が同一直線上にあるか?」を判定するプログラムを考える。数学的には中学生でも解けるが、美しいプログラムにするには色々と問題がある。
素朴な第1案は、2点を通る直線の方程式を求めて3点目がそれを満たすかを判定。直線がy軸に平行な場合は傾きがゼロとなり、ゼロ除算回避の特別扱いが必要。
第2案としては、3点のうち2点を通る2組の直線が平行(傾きが同じ)であれば、同一直線上にある。直線の方程式中のy切片を考えずに、傾きだけに着目すれば良くなる。それでも傾きゼロの特例扱いは残る。
傾きゼロ特例をなくす第3案。3点を頂点とする三角形の長辺が、2短辺の和と同じであれば同一直線上にある。辺の長さの計算には平方根を使用し無理数が発生し、計算精度が落ちる。また、極度に平たい三角形は計算誤差のため直線と区別できない。
第4案。3点を頂点とする三角形の面積をベクトルの外積で求め、それがゼロであれば同一直線上にある。平方根は出てこず、極度に平たい三角形でも平たくするために長辺を延ばせば延ばすほど面積が大きくなるので、計算誤差にだまされない。
コンピュータが正確かつ美しく計算出し易いように、問題を幾何的に変形していくところが面白いですね。なお訳注では、第2案を代数的に処理して、第4案と同じ結論に辿り着く方法が示されています。

2012/02/09

ソースコード静的解析の数理

「日経サイエンス」2012年03月号「NEWS SCAN 海外ウォッチ」の「がん検診の数理」に触発されて、というか殆どパクリですが、ソースコードの静的解析の数理について考えてみました。

条件
・全ステップの 0.4% (250ステップに1件) の割合で欠陥が存在する
・静的解析ツールで欠陥のあるステップを欠陥として検出する(陽性)確率を、99.5% とする
・静的解析ツールで欠陥のないステップを欠陥として検出する(偽陽性)確率を、1.0% とする

この静的解析ツールを10万ステップのコードがあるソフトウェアに適用するとすると
・欠陥ステップ数  = 100000 / 250             = 400 ステップ
・陽性ステップ数  = 400 * 0.995                = 398 ステップ
・偽陽性ステップ数 = (100000 - 400) * 0.01 = 996 ステップ
従って、
・ツール指摘欠陥ステップ数 = 398 + 996   = 1394 ステップ
・本当の欠陥ステップの割合 = 398 / 1394 = 28.6 %
となります。残念ながら、かなり少ない割合ですね。

この問題は数学者にはよく知られているようで、比較的まれなものを検出しようとしているときは、結果が陽性と出ても誤りのある可能性が高くなります。ここでは、欠陥が全ステップの 0.4% というのがミソです。これが全ステップの1.0%なら約50%程度まで、2.0%なら約75%程度まで、本当の欠陥ステップの割合は跳ね上がります。

なお本当に問題があるかどうかの精密検査として、人の目でチェックするのにはコストがかかります。それだけでなく、静的解析ツールを通すための修正やコメント追加を行って可読性を低下させたり、最悪、別の欠陥を埋め込むことになれば、この静的解析はマイナスとなりかねない面もあります。
実際の数値は静的解析ツールや欠陥の種類によって異なりますが、静的解析ツールを導入するときは、検出できる欠陥だけでなく、偽陽性の扱いにも考慮が必要です。

この点、C++の静的解析ツールの1つである cppcheck は偽陽性0%「The goal is 0% false positives.」と掲げており、卓見だと思います。

参考
 ベイズの定理、及び、ベイズ推定