Out of Memory

本ブログは更新を停止しました。Aerieをよろしくお願いいたします。

目次

Blog 利用状況

ニュース

2009年3月31日
更新を停止しました。引き続きAerieを御愛顧くださいませ。
2009年2月3日
原則としてコメント受付を停止しました。コメントはAerieまでお願いいたします。
詳細は2月3日のエントリをご覧ください。
2008年7月1日
Microsoft MVP for Developer Tools - Visual C++ を再受賞しました。
2008年2月某日
MVPアワードがVisual C++に変更になりました。
2007年10月23日
blogタイトルを変更しました。
2007年7月1日
Microsoft MVP for Windows - SDKを受賞しました!
2007年6月20日
スキル「ニュース欄ハック」を覚えた!
2006年12月14日
記念すべき初エントリ
2006年12月3日
わんくま同盟に加盟しました。

カレンダー

中の人

αετο? / aetos / あえとす

シャノン? 誰それ。

顔写真

埼玉を馬鹿にする奴は俺が許さん。

基本的に知ったかぶり。興味を持った技術に手を出して、ちょっと齧りはするものの、それを応用して何か形にするまでは及ばずに飽きて放り出す人。

書庫

日記カテゴリ

動的言語のなんとやら 2

昨日のネタの続き。

「動的言語はちょこちょこ書いてサクッと実行できるから便利」ってのは、開発環境が軽快だからというところに起因する結果であり、動的言語自体に起因することではないということがわかった。
「大規模な開発には向かないけど、小規模な開発には便利」ってのも疑問があるところ。
静的型チェックがないから大規模な開発には向かないのはそうだとしても、じゃあ静的言語は小規模な開発に向かないのかと言うと、そういうことはないような気がする。
小規模開発なら静的言語でも動的言語でも大差はなく、大規模開発では静的言語に軍配が上がるということだと思う。
「型宣言が要らない」ことをメリットとして聞く場合もあるけれど、それもねぇ…。
単純な型ならともかくとして、ユーザ定義型とか関数型みたいな複雑な型の場合、コンパイラが行う型推論と並行して、同じ推論を脳内でもしなきゃいけない。これを大きな負担と感じるのは、俺が静的言語脳だからか?

さて、何だか動的言語にはいい所がないような論調になってしまったので、ちょっと挽回しておこう。

動的言語の特徴とは何かと言えば、ずばり「動的であること」に尽きる。つまり、ダックタイピングができること。それだけと言ってしまってもいい。
ダックタイピングができると何が嬉しいかというと、抽象化の、ひいてはモデリングの新しい次元が開けるというのがあるだろう。

「サブクラス」と「サブタイプ」を区別するという考え方がある。
唐突ではあるが、C++ の template と C# の Generic を対比してみよう。
それぞれで、「コレクションの要素をすべて足し合わせる」というコードを書いてみる。

C++ではこうだろう。たぶん。

template< typename T, typename Iterator >
T accumlate( Iterator begin, Iterator end )
{
    T temp = T();

    for( ; begin != end; ++begin )
    {
        temp += *begin;
    }

    return temp;
}

#include <iostream>
#include <vector>
#include <string>

int main()
{
    int ints[] = { 2, 5, 8 };
    int iret = accumlate< int >( ints, ints + 3 );
    std::cout << iret << std::endl;

    std::vector< std::string > strings;
    strings.push_back( "ABC" );
    strings.push_back( "DEF" );
    strings.push_back( "GHI" );

    std::string sret = accumlate< std::string >( strings.begin(), strings.end() );
    std::cout << sret << std::endl;

    return 0;
}

対して、C# では、もちろんこうだ。

using System;
using System.Collections.Generic;

namespace Hoge
{
    class Program
    {
        static T accumlate< T >( IEnumerable< T > iter )
        {
            T t = default( T );

            foreach( T temp in iter )
            {
                t += temp;
            }

            return t;
        }

        static void Main( string[] args )
        {
            int[] ints = new int[] { 2, 5, 8 };
            int iret = accumlate( ints );
            Console.WriteLine( iret );

            List< string > strings = new List< string >();
            strings.Add( "ABC" );
            strings.Add( "DEF" );
            strings.Add( "GHI" );

            string sret = accumlate( strings );
            Console.WriteLine( sret );
        }
    }
}

…違うね。C# の方はコンパイルエラーだ。
accumlate の型引数 T について何の制約も課していないので、T 型のオブジェクト同士を足すことができるということがコンパイラにはわからない。
何か制約を課そうと思っても、C# では演算子は継承できないから不可能だ。
仮に IAccumlatable などというインターフェイスを定義したところで、int も string もそんなものを実装していないから、やはり使えない。

C# ではサブクラスとサブタイプは同一だ。継承しなければサブタイプが定義できない。
C++ では違う場合がある。上記の例で言えば、int と std::string には何ら継承関係が無いにもかかわらず、同じ += 演算子を持っているから同じように扱える。
この場合、テンプレート引数 T が += を持っていることを要請するが、int と std::string はともに T のサブタイプであると考えることができる。だから統一した方法で扱える。Iterator も同様だ。

C++ は動的言語ではないが、ダックタイピングができるという点で、動的言語と同じ利点を持つと言っていい。
その利点とは、このように、クラスの継承関係にかかわらず、サブタイプの関係に基づいて抽象化したコードを書くことができる、というものだ。

オブジェクト指向の三本柱の一つにポリモーフィズムというのがあるが、クラスの継承関係に基づいたものは特に「アドホックポリモーフィズム」と呼び、対して、サブタイプ関係に基づくものを「パラメトリックポリモーフィズム」と呼んで区別することがある。
動的言語や C++ ではどちらも可能だが、C# ではアドホックポリモーフィズムしか使えない。

とは言うものの、だ。
上記の例で言えば、コレクションの要素が何であるかによって、「足し合わせる」という行為の意味も、足し合わせた結果の意味も変わるわけで、accumlate のようなのは「過ぎた抽象化」であるような気もする。
この印象は、Scheme のコードを読んだりするとより顕著に感じる。
こういったことが可能なのは、ビジネスロジックから切り離された、ユーティリティー関数のような場合だけなのではないだろうか。
C++ の std::for_each のように、標準ライブラリに入っていればいいが、そうでない場合、サブクラス関係にないもの同士を統一的に扱う関数を自分で定義するほどのものではないと思うのだが、どうなのだろうか。

…む? なんだか「C++サイキョー!」という結論に落ち着いてしまった気もするが…まぁいいか。

投稿日時 : 2007年9月6日 1:43

Feedback

# re: 動的言語のなんとやら 2 2007/09/06 1:55 中博俊

>これを大きな負担と感じるのは、俺が静的言語脳だからか?

そうそう(^m^)

# re: 動的言語のなんとやら 2 2007/09/06 2:02 シャノン

とは言え、C# 3.0 ならまだ可愛いもので、カリー化なんか使われた日にゃとても読めませんて。

# re: 動的言語のなんとやら 2 2007/09/06 2:55 NyaRuRu

んー,C++ の機能ってほとんどがコンパイル時になので,プロジェクトがでかくなればなるほどコンパイルが鬱陶しくなる気がします.
バイナリモジュールを分けようとすると,こんどは DLL 境界で鬱陶しいことになるとか,ヘッダファイルの管理がややこしくなるとか.

C++で書いていて一番楽しいのはむしろ小規模の段階で,中規模,大規模になるに従ってコンパイルとかビルトとか生々しい部分がどんどん重荷になってくるという印象があるんですがどうですかね?

# re: 動的言語のなんとやら 2 2007/09/06 7:00 ひろえむ

んー。 私もシャノンさんと同意見だなぁ。

どう考えてもテキストエディタが楽だと言うふうにしか聞こえないんですよねー<動的言語。

積極的に採用すべき理由が見あたらないんですよねー。

今まで不便とされてきたことが改良されてIDEが拡張されて補助機能が増えてきたのに、なんであえて先祖返りなんだろうか・・と(^^;

もちろん、使わないという意味ではないんですが、なぜそちらにトレンドが・・・というのは少々不思議に思ったりして。

# 動的言語のなんというか 2007/09/06 7:47 拝啓、さかもとと申します

シャノンさんのブログのエントリ 「動的言語の強みっつーかなんつーか」 「動的言語のなんとやら 2」 を拝読。 2についてはコメントを含め、私の知能にはオーバースペックなので分かったフリをすることに決定。

# 動的言語のなんというか 2007/09/06 7:47 拝啓、さかもとと申します。

動的言語のなんというか

# re: 動的言語のなんとやら 2 2007/09/06 8:52 アキラ

C++最強!w

# re: 動的言語のなんとやら 2 2007/09/06 9:36 シャノン

> C++で書いていて一番楽しいのはむしろ小規模の段階で,中規模,大規模になるに従ってコンパイルとかビルトとか生々しい部分がどんどん重荷になってくるという印象があるんですがどうですかね?

あー、確かにね。それはありますね。

# re: 動的言語のなんとやら 2 2007/09/06 12:29 凪瀬

「型推論は脳内コンパイラへの負担が大きい説」が広まっていますなw

いまどきは静的言語でもステップ実行できますから、いきなり静的言語で学習しても大丈夫に思うし。

# re: 動的言語のなんとやら 2 2008/03/12 19:02 NyaRuRu

>動的言語や C++ ではどちらも可能だが、C# ではアドホックポリモーフィズムしか使えない。

こういうの書いてみたですよ.
http://d.hatena.ne.jp/NyaRuRu/20080313/p1

# re: 動的言語のなんとやら 2 2008/09/15 20:07 Akira

将来的にRubyに以降する為にJavaで修行しています。静的言語の問題とかがしっかり分からないと動的言語は使ってはいけない気がします。

タイトル
名前
Url
コメント