スポンサーサイト

--年--月--日 --:--

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

C++言語で関数型プログラミング 第1章

2006年08月25日 18:07

前回、どこまで書いたっけかなw

・・・・・前回の解説じゃちょっと飛んでるところも多いね、こりゃ。

まず、用語説明から。
 ・TCClosure  クロージャー(Closure)を実現するために あるけ が作ったテンプレートクラス
 ・Lambda   無名関数を扱えるようにした BOOST に入ってるトリッキーなテンプレートクラス
こんなもんかな。

他にはカリー化とかも知っておいた方がいいんだろうけど、あるけ 自体実は良くわかってないので省きますw



さて、前回は式のオブジェクト化を行えば Closure が出来そうなこととか、Lambda がどうやって動いてるのか?を簡単に説明しました。

Lambda 自体はすごく綺麗に動的に関数の生成を行えるように作られています。
しかし、実際問題として、Lambda を有機的に使うことはすごく難しいです。
なぜなら、この前の説明で作った ((_1 * 100 + _2 + 10)(1,2)) の左辺値を変数に格納しようとしたら、

boost::lambda::lambda_functor_base::sig::type boost::lambda::lambda_functor::operator ()(A &,B &) const'
 with
  Act=boost::lambda::arithmetic_action,
  Args=boost::tuples::tuple    arithmetic_action,boost::tuples::tuple    lambda_functor,
    boost::tuples::tuple>,
    const boost::lambda::detail::parameter_traits_    IF::RET>::type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::
    null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,
    boost::tuples::null_type>>>,boost::lambda::lambda_functor>,boost::tuples::null_type,
    boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,
    boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type>>>,const boost::lambda::detail::
    parameter_traits_::RET>::type,boost::
    tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::
    null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type>,
  SigArgs=boost::tuples::tuple    null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,
    boost::tuples::null_type>,
  T=boost::lambda::lambda_functor_base,boost::
    tuples::tuple    lambda_functor,
    boost::tuples::tuple    arithmetic_action,boost::tuples::tuple    lambda::placeholder<1>>,const boost::lambda::detail::parameter_traits_    IF::RET>::type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::
    null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,
    boost::tuples::null_type>>>,boost::lambda::lambda_functor>,boost::tuples::null_type,
    boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::
    tuples::null_type,boost::tuples::null_type,boost::tuples::null_type>>>,const boost::lambda::detail::
    parameter_traits_::RET>::type,boost::
    tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::
    null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type>>,
  A=int,
  B=int

まぁ、こんな冗談みたいな長さのテンプレートを宣言しないと格納できないわけです(;´Д`)'`ァ'`ァ

これが Lambda を使用する場合のもっともとっつきにくい部分でしょう。
使える場面が少ないのと、使う場合は必ずテンプレート関数にしないといけないからです。
暗黙のテンプレート引数として使えば、別にどんな型だろうが使う側は知らなくてもOKですからね。


次は、Lambda がどうやって動いてるのかを説明しようと思います。
今日は忙しいのでさわりの部分だけw


blog_rank

スポンサーサイト

C++言語で関数型プログラミング 序章

2006年08月07日 17:33

以前書いたブログに Closure のこと書いてて、その記事の技術、全然公開してなかったから説明しながら公開していこうかと思います。


っていっても、Boost の Lambda みたいに綺麗になってないんだけどね。
けど機能はこっちの方が上だ!って自負がありますよこれ( ・`ω・´)

無名関数だって使えるし、遅延評価だってできます。
Haskell みたいに完全遅延評価(グラフリダクションっていうらしい。並列で遅延評価するって意味なのかな?)は出来ないけどね。
(出来たら恐ろしいけどw)



んで、本題。

やりたかったことはっていうと、

 1:動的に関数を生成する
 2:1で生成された関数も同じように動的に生成する関数の部品として再利用できちゃう
 3:無名関数みたいに、値が決まって無くてもあとで値を入れれば動いちゃう。
 
っていうことですね。
まぁ、要するに「式」をオブジェクト化したかったワケです。
「式」同士を演算子で結合できたりね。


Lambda の実装に触発されて出来たわけですけど機能は大分違いますね。

また、冒頭で Lambda みたいに綺麗になってないといいましたが、全て Template が生成する「実態」だけで済ませている Lambda と違い、このクラス(TCClosure と呼んでます)は new や malloc などで動的に確保したメモリを使用することでC言語特有の「汚い」実装になってるからです。
その代わり汎用的に出来るわけです。

実際、Lambda を有機的に使う場合、必ず Template 関数なりにしなければいけなかったところ、
Lambda の場合、型が自動的に作られるのと生成される型が複雑なので、
 とてもじゃないが指定して使うなんてことができない)
TCClosuer は戻り値だけ特定すれば、どんな関数やクラスでも利用可能です。
要するに、テンプレートの引数として必要なのは戻り値の型だけなんですね。


また、違う戻り値の TCClosure も型キャストさえ出来れば組み合わせて使う(組み合わせることで新しい TCClosure を生成する)ことが出来ます。



んで、どうやって実装しているか?
いきなり核心の部分を説明してもかなりわかりにくいです。


なんで、まずは簡単なことを考えましょう。

どうやって式をオブジェクト化するか?

これだけでもかなり抽象的ですねw

まず単純に考えて、
 a + b = f
において、
 「f の値を動的(必要な時)に求める」
が出来ればよさそうな気がします。

それじゃこれをクラス化してみましょう。


a を項クラス term とします。
そうすると、b は term クラスの保持する値が違うだけなので、同じ term クラスとして扱えます。
また、f は結果なので result クラスとします。

そうすると、a + b = f の式は
 term + term = result
と書けますね。


さて、ここで式の再利用を考えると result クラスの部分を term と置き換えれば上手く行きそうな気がします。
result = term とすれば term と term を演算子でつなぐと term を返す
これなら出来上がった term を使ってまた新しい「式」を定義できそうです。

そうです、これが Lambda で使ってる技術なんです。
Lambda の場合、全て「一つの部分」でやっちゃう
(たとえば
  ((_1 * 100 + _2 + 10)(1,2))
 など、式を変数として保存するのではなく、関数の引数として書いたり一箇所にまとめて書く)
ので、ワザワザ「式」を保存するオブジェクトを定義する必要がありません。
ですから、(Lambda の場合は)戻り値を再帰的に使って実現してるわけです。

(上の例では
 _1 * 100 で一つ戻り値が出来て(これを term1 とする)
 term1 + _2 でもう一つ戻り値が出来る(これを term2 とする)
 さらに term2 + 10 でもう一つ戻り値が出来る(これを term3 とする)
 よって、結局 term3(1,2) が呼ばれるわけです)



とりあえず今日はここまで。

次回は(いつになるかわからんけど)これの実装方法とか必要になるクラスのこととか書きます。




blog_rank

シェーダー開発ツール 3

2006年08月04日 01:01

だーー!!また時間が( ;Д⊂ヽ
しかもまだ夕飯食ってないよこれ。どうですかw

ってことで、今日も今日とて とりあえず最新スクリーンショットだけアップ。
帰ってから時間あれば記事書きます('A`)

今日は入れてなかったシェイプ処理を入れちゃいました。
あと検索機能とか置換機能は大分前に入ってたんだけど、スクリーンショットとか取ってなかったのでついでに入れてみました。

ShaderEditor060803_1.jpg

ShaderEditor060803_2.jpg



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

ってことで今帰宅(;´Д`)ハァハァ
毎度毎度の事ながら、帰る間際は忙しいです。。


今はパスタを茹でながら書いてますよこれ(・∀・)
書き終わる頃にはパスタが出来てるかな~。

パスタソースは前作っておいたガーリックとトマトと鳥肉のスープパスタっぽいやつ。当然冷蔵庫で保管。
んでもって、暑いから冷たいパスタになります。
茹であがったパスタを冷水で切ってからオリーブオイルとトマトのソースかけてから食すと最高です♪


こっちの写真も後でアップしようかなw



さて、いよいよシェーダー開発ツール、完成に近づいてきました
(あくまでファーストリリース版ね)

今日急いで入れたのがシェイプアニメーション。

あるけ が日ごろからメンテナンスしているグラフィックライブラリがあるんだけど、それにはシェイプ処理が入ってなかったんだよね。

んで、見栄えがいいから今日急いで入れました。
データはとっくの前にシェイプに対応してたから入れないと損なワケなんです。

これでアニメーション関連は
 ・スキンアニメ
 ・階層アニメ
 ・マテリアルアニメ
 ・テクスチャアニメ
 ・シェイプアニメ
が出来た~。

実は、アニメーションを処理する機構は全部一緒なんだよね。
だからちょこっと追加したらシェイプのアニメーション関連は直ぐ終わりました。


んが!問題は頂点のシェイプ処理。

頂点データが単純な4バイトの浮動小数点を使ってる分には物凄い簡単です。
オリジナルとシェイプモデルとで差分を取ったデータにレートかけるだけでいいから。

しかし、シェイプモデルやオリジナルのモデルの頂点データが2バイトの浮動小数点になってたり、整数型に圧縮されてたりすると展開するのも再圧縮するのも動的に行わないといけないわけです。

んで、全ての頂点圧縮フォーマットに対応しないといけないのが面倒なんですね('A`)
あるけ はテンプレート使ってやってるのでそこまでコード量は多くないですけど、その代わりきちんと動かすために複雑な動作を考えないといけないわけです・・・。

一度設計は終わってたのでそんなに行数も時間もかからなかったのが幸いでした。
・・・けど、かなり面倒だった~( ´Д⊂ヽ


ってことで、シェイプも出来たし、検索処理や置換処理のUIも出来たし。
とりあえずファーストリリースできそうな感じになりました。


もう公開できる段階なんですけども、諸種の事情でこのサイトで公開するのはもうちょっと先になりそうです(・∀・;)

、、、気がついたら締め切りまで後2日・・・ヤバスw



さて、パスタも出来たので夕飯~♪♪

DSCF0407.jpg


こんなのが出来ましたw
仕上げにバジルをまぶしたんですよ~(´▽` )


blog_rank


最近の記事


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。