lambda?

D言語の無名関数って皆さんご存知ですか?
これって便利っちゃあ便利なんですけど、
1行程度の関数を書くときに一々関数の引数の型書いたり、
{return hoge;}()のreturnって書くの面倒だったり色々不便です。
そんなわけで関数リテラルを簡易に書けた気分になれるライブラリ書いて見ました。
というか、上の文は心底どうでもよくて、単にmixinで遊んでみたかっただけとか。


なお、現在はローカル変数に触れないという駄目駄目な状態です。

void main(){
	//引数を2倍して3を足す関数の定義
	alias lambda!(`a -> a*2+3`) fun;
	printf("%d\n",fun(100));
	printf("%d\n",fun(10));
	printf("%d\n",fun(1));
	//直接作った関数を呼び出すことも出来る
	printf("%.*s\n",lambda!(`a,b,c-> a~b~c`)("Hello",", ","world!"));
}
import std.typetuple;
import std.metastrings;
template split(char[]string,char[]sep , int i=0){
	static if(string[i..i+sep.length]==sep)alias TypeTuple!(string[0..i],string[i+sep.length..$]) split;
	else alias .split!(string,sep,i+1) split;
}
template find(char[]string,char[]srch){
	static if(string.length < srch.length)const find = string.length;
	else static if(string[0..srch.length] == srch) const find = 0;
	else const find = .find!(string[1..$],srch) + 1;
}
template splits(char[]string,char[]sep){
	static if(find!(string,sep) == string.length){
		static if(string.length  == 0)alias TypeTuple!() splits;
		else alias TypeTuple!(string) splits; 
	}else
		alias TypeTuple!(string[0..find!(string,sep)],.splits!(string[find!(string,sep)+sep.length..$],sep)) splits;
}
template strip(char[]string){
	static if(string.length == 0)alias string strip;
	else static if(string[0] == ' ')  alias .strip!(string[1..$])   strip;
	else static if(string[$-1] == ' ')alias .strip!(string[0..$-1]) strip;
	else alias string strip;
}
template join(char[]sep,T...){
	static if(T.length == 0)const char[] join = "";
	else static if(T.length == 1) const char[]join = T[0];
	else const char[]join = T[0] ~ sep ~ join!(sep,T[1..$]);
}
template map(alias F,T...){
	static if(T.length == 0) alias TypeTuple!() map;
	else alias TypeTuple!(F!(T[0]),.map!(F,T[1..$])) map;
}
template p(char[]msg){pragma(msg,msg);}
template TP(char[]F){const char[]TP = "___"~F~"___";}
template TP2(char[]F){const char[]TP2 = TP!(F) ~ " " ~ F;}
template lambda_(char[]msg){
	alias strip!(split!(msg,"->")[0]) arg;
	alias splits!(arg[0]=='('?arg[1..$-1]:arg,",") args;
	alias Format!("return %s;",split!(msg,"->")[1]) body_function;
	alias Format!("typeof((){%s;%s}())",join!(";",map!(TP2,args)),body_function) Result;
	alias Format!("%s f(%s)(%s){%s}",
		Result,
		join!(",",map!(TP,args)),
		join!(",",map!(TP2,args)),
		body_function
	)FunctionMsg;
	mixin(FunctionMsg);
}
template lambda(char[]msg){alias lambda_!(msg).f lambda;}