■
D言語の遅延評価は複数回評価すると副作用も複数回生じます。
そういう評価方法もありとは思いますがあまり好きじゃないです。
そういうわけで値をキャッシュしてみた。
T delegate()lazy(T)(T delegate() dg){ struct lazy_t{ union{T delegate()dg;Object obj;T val;} byte state=1; T get(){ if(state == 0)return val; if(state < 0)throw obj; try return val = dg(),state = 0 ,val; catch(Object o)throw state=-1,obj = o; } } auto p = new lazy_t;p.dg = dg; return &p.get; } void main(){ int i; auto o = lazy(printf("Hello World")); printf(" %d\n",o()); printf(" %d\n",o()); o = lazy({throw new Object;return 0;}); try o();catch(Object o)printf("%p\n",o); try o();catch(Object o)printf("%p\n",o); }
うーん、delegateが関数外に出たら無効になるという制限は本当に厳しいなぁ。
構造体に引数を逃がすというマヌケなコードをしょっちゅう書いているような気がして悲しい。