オブジェクト指向と関数型

ちょっと前にTLで見かけたんですが、わたしのイメージはこんな感じ。

[ソース]

#include <cmath>
#include <iostream>

// オブジェクト指向的な書き方
namespace object{

struct vector{
    vector() : x(0.0f), y(0.0f), z(0.0f){}
    vector(float x, float y, float z) : x(x), y(y), z(z){}

    float length() const{
        return std::sqrt(x * x + y * y + z * z);
    }
    void normalize(){
        float len = length();
        if( len < (1e-6) ) return;
        x /= len;
        y /= len;
        z /= len;
    }
    void disp() const{
        std::cout << x << ", " << y << ", " << z << std::endl;
    }
private:
    float x, y, z;
};

}  // namespace object


// 関数型的な書き方
namespace functional{

struct vector{
    float x, y, z;
};

vector
make_vector(float x, float y, float z){
    return {x, y, z};
}

float
length(vector const& v){
    return std::sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
}

vector
normalize(vector const& v, float len){
    return len < (1e-6) ? v
         : vector{ v.x / len, v.y / len, v.z / len };
}

vector
normalize(vector const& v){
    return normalize(v, length(v));
}

void
disp(vector const& v){
    std::cout << v.x << ", " << v.y << ", " << v.z << std::endl;
}

}  // namespace functional


int
main(){
    // オブジェクト指向
    {
        using namespace object;
        vector v = vector(3.14f, 0.15f, -4.5f);
        std::cout << v.length() << std::endl;
        v.normalize();
        v.disp();
    }
    
    // 関数型
    {
        using namespace functional;
        vector v2 = make_vector(3.14f, 0.15f, -4.5f);
        std::cout << length(v2) << std::endl;
        disp(normalize(v2));
    }

    return 0;
}

[出力]

5.48927
0.572025, 0.027326, -0.819781
5.48927
0.572025, 0.027326, -0.819781

大雑把に書くと
オブジェクト指向 => オブジェクトと中心としたメソッドで処理
関数型 => 関数で処理
って感じですかね。
(もちろんこれが全てではありませんが。


わたしの場合は、元々オブジェクト指向的な考えでしたが、template を使い始めた辺りから関数を書くようになって来ましたね。


あくまでもわたしのイメージなので、『そんなの全然違うぜー』ってのがありましたら教えて下さい。
特に関数型は殆ど触ったことがないので…。