Hatena::ブログ(Diary)

偏見プログラマの語り!

2012-04-22

@PG_sister_bot の発言に想いを馳せる

| 13:11

 プログラミングクラスタの皆さんは漏れ無く@PG_sister_bot をフォローしていることと思います。

 このアカウントは、プログラムを勉強している人の毒舌な妹の発言をしまくるいわゆるネタ bot として有名です。僕もいつも楽しませてもらってるのですが、よくよく読むと彼女の発言はなかなか興味深く、マジレスしたい欲求に駆られてしまいました。

 というわけで本稿はネタ記事です!あくまでネタ記事です!*1

1.

GCの無い言語にこだわることと、メモリリーク起こすプログラムを書くことは別の問題ではないでしょうか。メモリリーク起こすプログラマGC のある言語を使って速度が得られるのであれば話は別ですが。彼女は、C++ 等の言語の進化の意義をどう肯定/否定するというのでしょうか。

2.

#include <stdio.h> の意味を理解しているプログラマがどれほどいるでしょうか。プリプロセッサという機能の理解、include 命令の仕様、そして stdio.h 及びその中で include されているすべてのヘッダに書かれているプログラムの意味を理解することがどれほど高度なことか...。これらを掌握しないと #include <stdio.h> を書くことが許されないのであれば、プログラムの勉強なんて誰も始められないと思います。

3.

確かに、ソースがやたら長いプログラムは良くないとされています。しかし、では何を以て「大規模なプログラム」と呼ぶのでしょうか。ソースの長さではないとしたら...ちょっと良い答えが思いつかないです。

4.

また「大規模なプログラム」ですね。「大規模なプログラム合理的に設計した」と言った以上、彼女の中で「大規模なプログラム非合理的に設計した」という表現は別の意味になるのでしょう。非合理的に設計された大規模なプログラムは、"ソースがやたら長いプログラム" とはまた別なのでしょうか。このへん、非常に興味深いですね。

5.

それはそうかもしれません。しかし... ではどうしたら良いのでしょうか。多くのプログラマは新しいパラダイムの環境を使ってみて、ようやくパラダイムシフトを得るのではないかと思います。パラダイムシフトを先に経験した後でコードを書くのであれば、昨今あちこちで賞賛されている「写経」という手法そのものが否定されてしまうのではないでしょうか。

6.

それはそうかも知れませんね。しかし、ではクラスとはいったい何でしょう?僕は、まだ答えが出せないでいます( 『クラスとは何か。』偏見プログラマの語り! )。誰か知ってたら教えてください。

7.

散らかっている(であろう)部屋を見たとして、いったい何が分かるというのでしょうか。使ったものを後始末しないと作業スペースは減るわけだから、そういう意味では一理あるように見えます。しかしそれは「後始末のための時間的コストがかからない」というメリットとトレードオフの関係にあることには留意すべきです。GC の実装だって、「あるメモリが不要になったとき、まずは何もしない」という戦略を採っています。それに、余っているスペースで十分に作業ができるのなら、メモリリーク自体は問題にならないでしょう。ゆえに、彼女の指摘は説教として不適切であるような気がします。

8.

何でもかんでも英語にするのは賛同できません。そもそもプログラムソースは、可読性が要求されるものです。もちろん多くのプログラムでは英語が使われているわけですから、全てを日本語で書くことが良いとは言いません。しかし、例えば日本の古楽器の管理をサポートするプログラムにおいて、太鼓を「Drum」琵琶を「Lute」、尺八を「Bamboo flute」に英訳して書くことにどういうメリットがあると言うのでしょう。「Taiko」「Biwa」「Shakuhati」と書くべきです。それと同様に、そのプログラムが書かれた文脈・背景を踏まえたうえでローマ字表記を使うことは、否定されるべきではないように思います。

9.

確かに「極端な解釈しかできない」のは、プログラマとして優秀とは言えないでしょう。しかし、問題を極端に解釈できるなら、妥当な対案を出せるプログラマになるまであと一歩でしょう。例えばプログラムのエラー対策において、極端で例外的なケースをイメージできないプログラマは目前の問題収束に走ってしまいがちです。そうやってプロジェクト終盤で設計のどんでん返しを誘発してしまうプログラマの方がよっぽど致命的です。下を見ればキリが無いとはいえ、極端ながらも問題を捉える能力を持つ人を "致命的" と罵る彼女に、プログラマの優劣を判断する能力はあるのでしょうか?

10.

アナタ、下の毛はスパゲッティなのですか!


以上、10 個チョイスしてみました。え、大人げない?あ、そうw

*1:一応、 bot 作者の @big_bros さんに公開の許可はいただきました。ありがとうございます!

2012-03-09

「デベロッパーが知るべき291のこと」のディスカッション

| 20:30

ニコニコ生放送で、こんな放送がありました。

デベロッパーが知るべき291のこと 〜開発者の明日を繋ぐディスカッション〜』

=開発者の明日を繋ぐディスカッションセッション生中継=

 

ソフトウェアアーキテクトが知るべき97のこと

プログラマが知るべき97のこと

プロジェクト・マネジャーが知るべき97のこと

そして、我々が知るべき292番目のこと。

 

【出演】

鈴木雄介氏 (ソフトウェアアーキテクトが知るべき97のこと)

和田卓人氏 (プログラマが知るべき97のこと)

神庭弘年氏 (プロジェクト・マネジャーが知るべき97のこと)

ニコニコ生放送(アーカイブ)

 2012/03/07(水)の放送ですので、まだ見ていない方は、2012/03/14(水)までは見れると思います*1Twitter ハッシュタグ#devlove

 この番組で語られていた内容が、かなり濃くて良かったです。開発に関するお話を時間いっぱい聞くことができますので現場の開発者は是非、見て欲しいです。

 さて、番組に出演している中に神庭さんという人がいます。僕は存じ上げなかったのですが、34 年間ずっと日本 IBM でプロジェクトマネジメントをメインにやってきた方だそうです。今年 65 歳でめでたく定年を迎えられたということで、プロジェクトマネジメントの一から十までを知っている人です。

 神庭さんの発言の一つ一つが個人的にどぉんと響いたので、いくつかピックアップして紹介します。まぁでも時間がとれるなら本稿よりも動画を見ましょう。

プログラマ、プロジェクトマネージャ、アーキテクトの役割分担について

神庭「最初はプログラマもプロジェクトマネージャもアーキテクトも無かった。全てがひとまとめになっていた。それが徐々に専門性が高まって分化してカタチ作られてきた。」

鈴木「今の若い世代は学ぶべきことが多すぎる。」

和田「合理性があったからそうなってきたのだろうけど、現代の開発者がセクト主義的になってはいけないと思う」

・今の開発者の行く末について

神庭「ゼロから全部作ってたのは良い時代。昔は内部設計、外部設計、テスト、リリースの全てを体験できた。しかしもう今はそういうのが無い。どこへ行っても既存システムがあるわけだし。例えばデータベース設計の経験が無いアーキテクトはアーキテクトと言って良いのか?と思うが、実際のところもうデータベースを一から設計することなんてほとんど無い。保守ばかり。こんな時代に次の時代の IT エンジニアをどう育てれば良いのか、ということを危機感として持っている。プロマネは比較的賞味期限が長いが、旬の技術に長けた人の賞味期限は長くない。」

和田「現役で居続けるということは、年下が増えるということ。年下から学べるようになることが価値。」

・チームについて

和田「神庭さんに聞きたい。これまで色んなチームを率いてこられたと思うが、チームを作る(チームビルディングする)際に心がけている事は?」

神庭「リーダーの立場に就いたときに注意がいる。役割としてリーダーというものはあるが、リーダーシップはリーダーとは関係がない。リーダーの言ったコトに従ってくれる人がいないとリーダーは機能しない。チームメンバーの成熟具合に合わせて、どういう風にしたら部下が動いてくれるかを考えないといけない。つまりリーダーが優秀かどうかはその人ひとりの努力・才能では決められない。例えば部下に "あれをやれ"、"これをやれ" と命令して動かそうとすると、チームはガラガラと崩れてゆく。チームの状態が悪くなったとき、メンバーは嫌いなリーダーのために働きたいとは思わないだろう。"何とかっていう優秀なリーダーが陣頭指揮を執って..." な〜んていう強い縦関係のチームは、現代において成功し得ない」

・経験談

和田「神庭さんは、プロマネとして長年やってきたわけだから、色んな曲者とも仕事してきたはず。」

神庭「毎回色んな人がいる。お客さんにもいろんな人がいる。もうこればっかりは諦めるしか無い。ただ一度、こちらの部下に手を出す客がいた。そのときはさすがにキレた。その客は強いこだわりと勤勉さを兼ね備えており、気に食わないところがあるとすぐ手を出す、非常に困った客だった。だから "俺の部下に手を出したらてめぇを会社に居れなくしてやるッ!" って凄んで黙らせた。しかし、注意深く聞いていると、その客の意見には正しいこともたくさんあった。そこで、みんなの前で、彼の正しさや勤勉さについて褒め称えてあげた。そしたらそのあとは徐々にうまく事が進むようになった。プロマネの仕事は、場合によってはケンカも辞さないというつもりで臨むことでようやく分かりあえる、というような事もあるってこと。たとえ相手が客であろうとも。」

・鈴木さんから話題のフリ

鈴木「アーキテクト・プログラママネージャのうちどれが大事かを敢えて上げるとするならば、どれだと思うか?これはその意見が良い悪いという議論をしたいのではなくて、なぜそう思うに至ったかという話を聞きたい。」

和田「優等生的な答えを出すなら、どれが大事とかは無い。」

神庭「メンバーそれぞれが "俺が一番大事だ" とギャーギャー言い合うチームが良いチーム。」

・世界における日本について

神庭「実際問題、インフラ投資しようと考える企業はもうほぼ無くなってきている。企業はインフラの差で勝負しようと思っていない。つまり今後は仕事が減るってこと。さらに少子高齢化で 2010 年からの 10 年間に 25% の PM が退職する。これは、既に海外に心配されているレベル。日本は外国人労働者の割合も低く、労働鎖国状態。英語の語学力でも、日本は中国台湾韓国に負けて 55 位という状態。国際競争力に乏しい。このままでは、明るい未来を描きにくい。プログラミングで生き残る領域はどこにあるだろうか。」

和田「客の要望を早く正確にカタチにする能力での差別化は推し進めることができるはず。何がしたいのか、何を提供するのか、そういう意識をしっかり持った上で、開発者ひとりがちゃんと個として立たないと、替えが効いてしまう。」

神庭「最初から自律する気が無い人は流されるしかない。なるようにしかなれない。」

・最後らへん

↓笑ったw

神庭「リーダーシップっていうのは言いだーしっぺ、っていうのが大切なんですね。(会場沈黙)」

*1:プレミア会員じゃない人は見れないかも

2011-12-03

C++11 とオブジェクト指向

| 17:53

 これは C++11 Advent Calendar 2011 の 3 日目の記事です。*1

 C++03 から C++11 になったことで大小さまざまな言語仕様拡張・変更がありましたが、それらが C++ におけるオブジェクト指向プログラミングをどう変えてゆくのか、現段階で思うところを書こうと思います。


・プロローグ 「C++11 と魔法少女まどか☆マギカ」

 f:id:kura-replace:20111125005201p:image:w360

 C++11 の 11 は 2011年 のことです。そして魔法少女まどか☆マギカは 2011年 の日本を舞台にした大ヒットアニメです。偶然でしょうか?いいえ、これらが無関係なわけがありません。

 さて、C++ に追加された機能で最も強力なのが右辺値参照だと思います。これについては gintenlabo(@SubaruG) さんや, alwei(@aizen76) さんが後日のアドベで詳細を書いてくれると思います。しかしそれら機能の多くはライブラリアンのために提供されており、末端のプログラマにはあまり関係がありません。僕のような下っ端のプログラマに最も強く影響するのは move() ではないでしょうか。

 move() というと何やら難しそうですが、

 move() は、簡単に言うと引数をマミる関数です。

 f:id:kura-replace:20111122201942p:image:w400

 そう、実は C++11 の言語仕様にはマミさんのソウルジェムが輝いているのです。(嘘です)

 move のサンプルはもう散々目にしたかもしれませんが、コードにするとこうなります。

struct A { int data_ };

int main() {
    A a1 { 42 };
    A a2 = move( a1 );  // ここでマミる。a1 はもう使えない。
}

 では本題に入ります。




・第一話 「派生」

 派生は、多くのオブジェクト指向プログラミング言語で取り入れられている概念です。

class Base {};
class Derived: public Base {};

f:id:kura-replace:20111123034348p:image

 Derived は Base を完全に含んでおり、コンストラクタが呼ばれると内部に Base オブジェクトを生成します。しかし思うに、Base 部分は外部から調達したって良いような気がします。コードを↓このように修正してみます。

class Base {};

class Derived: public Base {
public:
    Derived( Base const & b )
      : Base( b ) {} // コピー
};

int main() {
    Base b;
    Derived d( b );
}

 しかし、この方法を採りたく無い場合があります。

 

 もし Base が外部リソースのハンドルを(例えばファイルを開いたまま)握っていたりしたなら話がややこしくなってしまいます。なぜなら↓図のように Base のコピーが生成されているからです。*2

f:id:kura-replace:20111123035552p:image

 そこで C++11 の move() を使います。↓図のように Base をまるごと Derived の Base 部分に差し込んでやることができます。

f:id:kura-replace:20111123182418p:image

コードにすると↓こうですね。

class Base {};
class Derived : public Base {
public:
    Derived( Base && b )
      : Base( move( b ) ) {} // 差し込む。
};
int main() {
    Base b;
    Derived d( move( b ) ); // ここでマミる。b はもう使わない。
}

 素晴らしい。Java でこういうクラスは定義できないですよね。

 カプセル化を維持したまま、生成タイミングをユーザーの都合に合わせて段階的にずらせるようなクラスを表現できました。

 

 キモいですか? いえ、大丈夫です。「基本クラス部分を右辺値参照で受け取って差し込む」という手続きが Derived の責任のもとで執り行われます。この考え方はオブジェクト指向の基本的な考え方に合致します。

 *3


・第二話 「豆腐分割問題」

f:id:kura-replace:20111123183829j:image:w280

 アホみたいな話で恐縮なのですが、どうも僕には

「豆腐を切ったら豆腐 2 つになる」ということを、Java は表現できない

ように思うのです。ちょっと Java のコードを書いてみますね。

// 豆腐。
class Tofu {
    private int weight;
    
    public Tofu( int weight ) {
        setWeight( weight );
    }
    public int getWeight() {
        return this.weight;
    }
    public void setWeight( int weight ) {
        if( weight <= 0 ) {
            throw new IllegalArgumentException( "重さの無い豆腐は豆腐では無いぃぃぃぃッ!" );
        }
        this.weight = weight;
    }
}

class Main {
    public static void main( String[] args ) {
        Tofu t = new Tofu( 100 );           // 100g の豆腐がある。
        Tofu[] sliced = Slicer.slice( t, 2 ); // 2つに切る。
        
        System.out.println( sliced[ 0 ].getWeight() ); // 50g
        System.out.println( sliced[ 1 ].getWeight() ); // 50g
        
        System.out.println( t.getWeight() ); // いくつになるべき?
    }
}

 最後の文で、もし t が 100g なら「豆腐を切ったら豆腐の総量が増えた」ことになってしまいますし、t が 0g ならそれは既に豆腐ではありません。こんなの絶対おかしいよ!

 オブジェクト指向プログラミングを紹介する文脈では、よく「現実のモノに名前をつけてモデル化するのがクラスで...」といいますが*4、その典型である Java のモデル表現能力は、この例が示すようにさほど高くないように思うのです。

 しかし C++11 には move() があります。

int main() {
    Tofu t { 100 }; // 100g の豆腐がある。
    
    vector< Tofu > sliced = Slicer::slice( move( t ), 2 );  // ここでマミる。
    
    cout << sliced[ 0 ].getWeight() << endl; // 50g
    cout << sliced[ 1 ].getWeight() << endl; // 50g
    cout << t.getWeight() << endl; // そもそも t にはアクセスしてはならない。
}

 

 素晴らしい。main 関数を書いたプログラマが「豆腐 t は、Slicer::slice に渡したら消えて無くなる」という旨をコード上で正しく表現できるわけです。






 (当初、さやかの手足が切られる例を用意していたのですが、グロかったので豆腐にしました)


■第三話 「定数オブジェクト」

 例えば double const や enum など、定数を定義することはよくありますが、組み込み型だけが定数ではありません。ユーザー定義型のオブジェクトを定数とみなすこともあるかと思います。

 例えば↓こんなやつ。

// 色。
class color {
public:
  int r_value, g_value, b_value;
};

int main() {
  color const yellow { 255, 200, 30 };
  
  // yellow.r_value は 255 である。
  assert( yellow.r_value == 255 );
}

 さて、本当に定数なら↓これが動いてナンボでしょう。

int main() {
  color const yellow { 255, 200, 30 };
  
  int n = input();
  switch( n ) {
  case yellow.r_value: cout << "r と同じ"; break;
  case yellow.g_value: cout << "g と同じ"; break; 
  case yellow.b_value: cout << "b と同じ"; break;
  }
}

 残念ながらコンパイルエラーです。いくら定数といえど、構文上は const 修飾された変数と全く同じなので case 値にすることはできないんですね。C++03 まではこうした「定数のようなオブジェクト」をどう頑張っても本当の定数にすることはできませんでした。

 

 そこで C++11 からは、新しく constexpr というキーワードが利用できるようになりました。constexpr の詳細は boleros(@bolero_MURAKAMI)さんや iorate(@iorate)さんが関連記事を書いてくれる予定ですが、

 簡単に言うと constexpr は「これは定数だ」とコンパイラとの間で契約を結ぶものです。

 そう、契約....

 

 

 

 

 「僕と契約して、<censored>!」*5

 f:id:kura-replace:20111125003410p:image

 そう、C++11 プログラマは皆、魔法少女なのです。(嘘です)

 

 

 constexpr は、関数や変数に適用してコンパイル時に定数値を決定づけます。↓こんな感じ。

int main() {
  constexpr color const yellow { 255, 200, 30 };
  
  int n = input();
  switch( n ) {
  case yellow.r_value: cout << "r と同じ"; break;
  case yellow.g_value: cout << "g と同じ"; break; 
  case yellow.b_value: cout << "b と同じ"; break;
  }
}

 素晴らしい。コンパイルが通りました。

 また契約といえば assert ですが、C++11 では static_assert という静的な assert も使えるようになりました。

 こうしてコンパイル時定数の表現能力が上がるということは、C++ の強力なテンプレートメタプログラミングの威力が増すということであり、最適化が増強されるということでもあります。これらを組み合わせることで定数オブジェクトの利用シーンは確実に増えるはずです。どんどん使っていきましょう。



■いじょ。

 C++11 らしいところ、ということで 3 つほど出しましたけど、探せば何かもっと面白いネタは有りそうな気がします。(ところどころ Java を反面教師として出してますが、僕は Java は嫌いじゃないですよ。)

 それでは、次のDigitalGhost(@decimalbloat)さんの記事を楽しみに待ちましょ。

*1:「オブジェクト指向」をタイトルに入れるのって妙に勇気が要るんですけど何故でしょうね。

*2:そもそも大事なリソース握ってるようなものはコピー不可クラスにするのがベターですけども。

*3:もちろん、C++03 であっても、所有権込みでオブジェクトを移動するという話だけならばスマポに包めば実現できていました。しかし C++ は値の言語です。NULL 値の可能性をコンパイラに潰してもらえるぶん、move() の方が優れているように思います。

*4:そういう説明自体が適切ではないというのは今や周知の事ですので、そこを突っつくような dis はやめてね☆

*5:面白くない

青字青字 2011/12/06 11:33 第一話 「派生」で、Baseクラスのデストラクタが仮想になってないことに意味ってあるのでしょうか?

kura-replacekura-replace 2011/12/06 14:42 特に意味はないですね。しかしこれが不自然ということでもないです。以前書いたこの記事でそのへんについて書いてありますので参考までに。
http://d.hatena.ne.jp/kura-replace/20110220/1298223352

(青字ってもしや...!)

2011-09-19

「函数プログラミングの集い 2011 in Tokyo」を速読みしたい人へ。#fpm2011

| 07:45

 先日「函数プログラミングの集い 2011 in Tokyo」というイベントがあったようです。

 僕は行ってないし Ust 録画も見ていないのですが、TL の流れを見るにかなり面白い内容だったみたい。しかしこれ追いかけるにはややボリュームがありすぎるので、 Togetter(全 2,378 post!) *1から名言を pick up*2。ざっくり雰囲気掴みたい人はどうぞ。

*1@primnum さんまとめ乙!

*2:2011/09/19 7:00 AM 時点で favs + RTs ≧ 3 の post

2011-05-14

Boost. 勉強会 #5 に参加してきた。

| 23:58

 まず最初に謝らねばなりません。

 以前書いた Boost.勉強会 #3 の記事 ですが、

 タイトルが「Boost 勉強会 #3 に参加してきた。」

になっていました。

 正しくは「Boost. 勉強会 #3 に参加してきた。」

となっているべきであり、「.」の存在を軽視しておりました。大変失礼いたしました。

 えぇさて今回は Boost. 勉強会 #5 に参加してきました。今回は初めての名古屋開催ということで関東より近いということもあり、足を伸ばしてきました。近いから現場で聞こうと思った、というレベルを超えて、今回は登壇してきました。「Boost.statechart / Boost.MSM」というタイトルで 20 分と短いスライドでしたが、外部でのセッションが初体験ということもあり楽しんで喋らせていただきました。

 そもそも何で僕が喋る事になったかというとこれまた以前参加させていただいた NGK(名古屋合同懇親会) で @bleis センセに声をかけていただいたからです。あれに行ってなかったら喋ってなかったと思います*1

 全ての元凶は某ぐるぐるであり、ぐるぐるを育てた名古屋であり、従って名古屋まじ怖いです。

 セッションの資料はここにアップしました。

 Keynote 版 『boost_statechart_msm.key

 PDF 版*2boost_statechart_msm.pdf

 あと、セッションでデモした「bleis 削除ゲーム」のソースはここにアップしてあります。(ビルドには Qt が必要です)

 『boost_statechart_msm.zip

 

 僕以外のセッションですが、一番印象的だったのはやはり @kumagi センセの『春のlock free祭り』でした。

 そもそも、僕が lock free という言葉を聞いたは数ヶ月前でした。しかしそれがどういうものかを知った最初の感想は(えっ... 本気でそんなこと考えてる人がいるの...!?)だったのを覚えています。

 今回のセッションでは lock free の実現のためのアルゴリズムについて丁寧に噛み砕いて解説されており、一般のプログラマにとっても価値あるセッションだったのではないかと思います。また、発表順も一番バッターでしたし 40 分という長時間の設定だったのでかなりハードルが高かったと思うのですが、 3 分に 1 回ぐらいは冗談を交えたりして聴衆を飽きさせない喋りをしてたんですげーなぁと思って見ていました。セッションの進め方という面でも僕にとって良い刺激になりました。

 他の方のセッションも面白かったのですが、いかんせん自分の発表もあったので緊張で心臓がメルトダウンしそうな状態が続いており、集中して聞けなかった部分もあったのは反省点。後でスライドを確認させていただきます。


 懇親会。

 @cpp_akira センセからは魔導書第二弾について話を聞かせてもらいました*3。主に @otf センセとだべってました*4。@decimalbloat センセは相変わらず食欲旺盛そうでした。@Cryolite センセの野良セッション「非同期呼び出しにおける所有権の移動」が凄く興味深かったです。あと、会場の隅に居たとはいえ、あの空間で喫煙してサーセンしたっ!

 以上、今回も楽しませていただきました。関係者の方々及び参加された方々、ありがとうございました。

*1:@fatus_hina センセあたりが喋ってたんじゃないかなぁと思う

*2:変換が完全じゃないようなので図とかがおかしくなってますので留意のこと

*3:以前会ったときよりやや痩せたような

*4:以前会ったときよりずいぶん太ったような