再帰ラムダ

某所で挙がっていたことが気になった.ので,適当にググって発見したhttp://pc.2ch.net/tech/kako/996/996131288.htmlの169に書いてあったことを,おおよそそのまんまC++とBLLの形に翻訳してみた結果(と普通の再帰での書き方)が以下.

#include <iostream>
#include <boost/function.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/if.hpp>

template<class F>
struct fixer;

template<class F>
fixer<F> fix(F f)
{
  return fixer<F>(f);
}

template<class F>
struct fixer
{
  fixer(F f)
    : f_(f)
  { }

  template<class T>
  T operator()(T n)
  {
    return f_(fix(f_), n);
  }

  F f_;
};

int main()
{
  using namespace std;
  using namespace boost;
  using namespace boost::lambda;

  // 上の記事に従うと以下
  function<int (function<int (int)>, int)> f
    = ret<int>(if_then_else_return(_2 == 1, cref(1), bind(_1, _2 - 1) * _2));
  cout << fix(f)(1) << '\n';
  cout << fix(f)(2) << '\n';
  cout << fix(f)(3) << '\n';
  cout << fix(f)(4) << '\n';
  cout << fix(f)(5) << '\n';
  cout << fix(f)(6) << '\n';


  // 普通の再帰で書くと以下
  function<int (int)> g;
  g = ret<int>(if_then_else_return(_1 == 1, cref(1), bind(var(g), _1 - 1) * _1));
  cout << g(1) << '\n';
  cout << g(2) << '\n';
  cout << g(3) << '\n';
  cout << g(4) << '\n';
  cout << g(5) << '\n';
  cout << g(6) << '\n';
}

うむ.要するに黙っておとなしく関数にしときなさいってことですな.頑張れば汎用かつ分かりやすいものが作れるような気もするけど,そんなの考えてる/作ってるヒマがにゃい・・・.

今日のBoost

引数(argument)とパラメータ(parameter)の違い

http://lists.boost.org/MailArchives/boost/msg75419.php
自分も最近になってこれら2つの言葉が違うものを指しているのに気が付いたばかり.

int f(int a, int b); // a, bは「パラメータ」

int i, j;
f(i, j); // i, jは「引数(argument)」

template<class T> // Tは「パラメータ」
struct X;

X<int> x; // intは「引数(argument)」

filesystem::equivalentにバグ(・∀・)ハケーン

http://lists.boost.org/MailArchives/boost/msg75164.php
まれにBoostのライブラリ内部のバグに出くわすけれど,最初に自分のコードから疑ってかかるから発見が遅れるんだよにゃ〜.1.31.0ではBoost.Spiritにあるsymbolsのadd関数のバグにハマった経験あり.
http://article.gmane.org/gmane.comp.parsers.spirit.devel/2117
http://article.gmane.org/gmane.comp.parsers.spirit.devel/2118
1.32.0ではfixされてるけれど.

result_of

http://lists.boost.org/MailArchives/boost/msg75300.php
おぉ.
http://www.boost.org/libs/utility/utility.htm#result_of
ほんまや.っていうかLibrary TR Draftにも記述があるじゃん.ということは次期標準はこれでほぼ確定?今後polymorphicなファンクタ書きたいときはresultメタ関数を内部につけておけば次期標準ライブラリにスムーズにマッチして(゜д゜)ウマーなわけだ.ところで,BLLのsigはこっちに乗り換えてくれるのかな?

C++/Tcl

http://lists.boost.org/MailArchives/boost/msg75338.php
Let's Boostで紹介されていたの見たときにはそんなに気にとめていなかったけれど,よくよく考えてみたらC++から呼びたい/C++を呼びたいコードがいっぱいあることに気が付いた.後で見てみようっと.