オブジェクト指向
「我々は、思考の次元が低すぎる。もっと瞳が必要なのだ」 -- Bloodborne (FROM Software)
ぼくにとっては"オブジェクト指向"で、何を得られるかって言ったら、視点、「瞳」じゃないだろうか、と思う。 頭の中のシミュレーションのレイヤーが増える、みたいな話だ。
古典的には、というか、プリミティブには、設計ではデータと関数が主役だ。 データ指向の設計手法を用いて、ER図とかCRUDマトリックスによって、「レコードの生成」や「変更を受けるか否か」「mutableかどうか」は分かる。 同時に、機能(= function = 関数)を細分化していって、WBSを毛細血管のように張り巡らせ、それぞれのCRUDの事象と接続して、生きたシステムにすることもできるだろう。
こういう細分化は、システムの置かれた環境が静的であれば、たとえそれが非常に大規模でもうまくいくと思う。 しかしながら、現代においては、静的である、という前提はあまり良くないものと見なされている。 実際、人は変わり要求は変わる、ムーアの法則でインフラも変わる。"最新の"アルゴリズムは陳腐化する。予算も大きくなったり小さくなったりする。
そういった世界においては、上流の変更と、下流の変更の相互の波及を、意識して扱う手段が必要だ。 差分を認識するためには、それがidを持たねばならない。名前を持たねば認識できないのだ。 自分にとっての、いわゆる、オブジェクトがそれだ。 システム設計の中間構造を構成するノード、毛細血管の例に則れば、臓器のようなものだ。
そういうものが存在する、としたら。その仮定を、一旦公理として受け入れて、その上にできる構造を想像してみると、非常に豊かな表現が得られる。 別にそんなものが存在する必然性は無いんだけど、そういう観点でシステムを見る、そういう視点をくれる。
注意したいのは、別にオブジェクト自体に上流下流、隣接の変化をもって「波及を防ぐ」効果なんてないということだ。 意識できれば、考えられるし、制御できるし、文書化できるし、議論できるし、記録に残せる。
見えなければ、そもそも意識できない。 ぼくにとってはオブジェクト指向のオブジェクトというのはそういう存在だ。
生産性について
余談
10年半ぶりの記事らしい。笑う。 見返してみても、中身のない記事ばかりだな。 眠い頭で久々に文章を書く。
生産性について
動機
へーしゃでは、生産性の向上!っていうのが社是になっているんだけど、 こんなのがTLに流れてきて…
「ピカソがもっと短時間で絵を描けば金も儲かるし経済にもっと貢献できたのに、と考える人はいない」
— Yusuke Nozoe (@yusuke_nozoe) August 11, 2019
「生産性という基準で測れる仕事はたいてい、自動化したほうがいい仕事である」
「人間が得意なのは、時間を無駄にすること」
考えさせられる pic.twitter.com/KGsXu7yCW6
ちょっと考えを改めるきっかけになりそうなので、しっかり考えてみる。
創造と生産
何かを作り出す…っていうときは、創造と生産の両方があると思うんだけど、全く違う概念だよね。 たとえば、しごと文脈だと、「生産管理」はしても「創造管理」はしないよね。と思う。
ツイートの本でも言及されてるけど、たしかに、生産性っていうと時間単価で測れるものだよね。 逆説的に、創造は管理できないものだって思う。
もっと掘り下げてみると…
生産っていうのは、生産の前後で、単に「1個生産物が増える」「そのための材料が1単位減る」だけだと思う。つまり、単位生産あたりでの、質的変化はない。 創造っていうのは、前後で、「何か質的変化を伴う」。ただ、当然、「そのために費やされるリソース」は存在する。が、一般的観念からは生産物のほうが重視される。
のかな。 質的変化を伴う。とか書いたけど、ではそれはどういうことだろうか。ツイートの本だと、芸術分野を特に例に挙げているけれど。 疑問なのは「何が違うのか」「本当に管理できないのか?」だな。
生産の管理
まず生産がどう管理されるかを考えてみよう。
「生産量」をKPIにしようとすると、うーん。こういう概念はありそうだけど。
- 単位材料あたりの生産量
- 単位時間あたりの生産量
- 単位生産あたりの必要設備費
おっと。設備ってなんだろう。生産に使う道具、ってあらゆる生産に必要な気がしたけど、どうだろうか。 設備も、結局は外部から調達するか、自前でつくるかするし、材料と時間がかかるものだし、使えば消耗(消費)するよな、という感じ。 とすると、ものすごく長く時間を取ると、結局は「材料」ではあるのか。でも、時間を短く取ってゆくと、瞬間での生産量には関係がなくなってゆくとか。 (このへんは「プロセス設計」の話になるんだろうけど、ちょっと「質」の匂いがしてくる。)
つまり、結局は、上二つで定義できる気がする。生産量の、時間と材料量に関する偏微分だ。
そして、生産量を極大化するために「ボトルネックを見つける」「そこを改善して生産性アップ!」みたいなのが当然の原理だと思われてる気がする。 大雑把に言えば、「系に対する投入量を増やせばリターンが増える」という原則があるってことだよね。
少なくとも、全く同じ形のプロセスを増やせば、2倍の生産量が見込める。これはただちに「生産性」を向上しないけど、 「ボトルネックを見つける」「ボトルネックの部分を複製すれば、ボトルネックの生産量が2倍になる」「全体の生産量が上がる」「他の部分がボトルネックになる」 だから、全体の組み合わせとしての「生産性」は向上することになる。
生産プロセスには加法性がある。
創造の管理
当たり前だけど「創造」の成果、生成物は、同じものが2つ存在しても意味がない。量に対して特異的な存在だ。 芸術、発明、発見、あたりはこの性質を満たしていると思う。 (これが、大局的に満たされているかは微妙だが、個々の活動として管理するならば、局所的にこの性質が成り立つことが言えればいい)
同じものが2つ存在しても意味がないから、ちょうど1単位生成できたタイミングで、生産を止めなければならない。 さもなければ、生産量はそれ以上増えないのだから、必然、そこからの生産性はゼロだし、投入リソースが増える分、マイナスになってゆく。
また、これも「量に対して特異的」の範疇だと思うが、内部状態の観測ができない、という性質もあると思う。 "昨日30%ぐらいで、今日は70%だから、明日には完成しているだろう"みたいなことが言えない。 しかし「完成した」状態は存在する。というと…まるでNPみたいだ。
NPであるという類推から考えれば、創造に当たる人間が無制限に確保できれば、時間は制御可能になるかもしれないが、そんなことは実際問題不可能だ。 「同じポジションの人間を二人以上充てる」と、リードタイムは下がるかもしれない。XPやモブプログラミングのアプローチはこちらかも。
こういったアプローチが、実際に時間短縮に貢献したかを考えるためには、同じ入力に対して、同様のアウトプットをする実験をいくつか行う必要がある。 人間を3人確保しておいて、1人と2人に分けて、それぞれクリーンルームで作業に当たらせる、といったようなことを何度もやらなければならない。 その際、人間としては同じような性質の人間を用意しなければならない。 と考えると、非常に高コストだし、生産管理では可能な「生産しながら計測」ができない。
そうすると、
- 同じ出力を繰り返すことを回避するために、過去の成果を貯めておき、すぐに参照できるようにすること
- できるだけ早く完成を察知できるようにすること
- そのうえで創造のための時間をひたすら長くとること
というのが「創造性の管理」じゃないかと思う。
Fedora Core 6でjsarticle
めんどくさいから未だにバージョン6なFedoraで
jsarticleを使うためのメモ。
http://voyager.ce.fit.ac.jp/modules/smartsection/item.php?itemid=52
アルファベット頻度カウント
id:mzp:20081126:word
たぶん予想はしてると思うけど、早速7行化してみた。
#include <ctype.h> #include <stdio.h> char a[26]={0},*b; main(i,c)char**c;{ while(--i){b=c[i];while(*b)isalpha(*b)?++a[toupper(*b)-'A']:0,b++;} for(i=0;i<26;++i)printf("%c ... %d\n",i+'A',a[i]); }
ctype.hのisXXXX()とtoupper()、 tolower()は存在を忘れがち。
折角あるから使ってあげよう。
ピタゴラス数生成
直角三角形とピタゴラスの定理
を参考に、ピタゴラス数を小さい順*1に生成してみた。
Project Eulerぐらいにしか使い道がなさそうだけど。
#include <iostream> #include <queue> #include <boost/numeric/ublas/matrix.hpp> #include <boost/numeric/ublas/io.hpp> #include <boost/numeric/ublas/vector.hpp> using namespace boost::numeric::ublas; void output_pythagoras_numbers(int count){ struct f : std::binary_function<vector<int>,vector<int>,bool> { bool operator()(const vector<int>& lhs, const vector<int>& rhs) const{ return std::min(lhs(0),std::min(lhs(1),lhs(2))) > std::min(rhs(0),std::min(rhs(1),rhs(2))); } }; matrix<int> magic(3,3); magic(0,0) = magic(1,1) = -1; magic(0,1) = magic(1,0) = magic(2,0) = magic(2,1) = -2; magic(0,2) = magic(1,2) = 2; magic(2,2) = 3; std::priority_queue<vector<int>, std::vector<vector<int> > , f > q; vector<int> v(3); v(0) = 3, v(1) = 4, v(2) = 5; q.push(v); for(int i=1;i<=count;++i){ vector<int> v = q.top(); q.pop(); std::cout << i << " : " << v << std::endl; v(0) = -v(0); q.push(prod(magic,v)); v(1) = -v(1); q.push(prod(magic,v)); v(0) = -v(0); q.push(prod(magic,v)); } } int main(int,char**) { output_pythagoras_numbers(1000); }
*1:三つの数字のうち一番小さい数字が基準