Boost.Lambdaでletとかwhereを書かせろ

#define LET(var) [&] { var IN
#define IN(body) return body; }()

#define LAMBDA(def) [&] { LAMBDA_WHERE(LAMBDA_WHERE_I def) return LAMBDA_BODY def )); }()
#define LAMBDA_WHERE_I(body) LAMBDA_WHERE_II
#define LAMBDA_WHERE_II(where) NIL where
#define LAMBDA_WHERE(where) LAMBDA_WHERE_III(where)
#define LAMBDA_WHERE_III(where) LAMBDA_WHERE_IV_ ## where
#define LAMBDA_WHERE_IV_LAMBDA_WHERE_II
#define LAMBDA_WHERE_IV_NIL

#define LAMBDA_BODY(body) body LAMBDA_BODY_I((
#define LAMBDA_BODY_I(par)

// let風
LET (int x = f(1, 2, 3);) (_1 + x)

// where風
LAMBDA((_1 + x)(int x = f(1, 2, 3);))
LAMBDA((_1 + 1))

展開結果:http://codepad.org/C3kVMzVi
C++0xラムダ式を多相型にしようとしても無理だったので、Boost.Lambdaでletとか使えればいいんじゃないかと思った。試すのは面倒なのでやってない。BOOST_PP_SEQ使えば楽ちんだけど修行した。名前を宣言するためだけにラムダ式で覆う。letとかwhereにあたる節をベタな式じゃなくて、名前、値、型(省略可)の何らかのデータ構造取るようにするとかもまたよいのではないかと。

追記:where風の実装がどうも気に入らないのでBoost.PPで書いてみた。しかしまだ気にいらない。

#include <boost/preprocessor/seq/elem.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/arithmetic/dec.hpp>
#include <boost/preprocessor/control/expr_iif.hpp>

#define LAMBDA(seq) [&] { BOOST_PP_EXPR_IIF(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(seq)), BOOST_PP_SEQ_ELEM(1, seq)) return BOOST_PP_SEQ_ELEM(0, seq); }()

// where風
LAMBDA((_1 + x)(int x = f(1, 2, 3);))
LAMBDA((_1 + 1))