暇つぶし

遅延評価のカスタマイズって
言語がサポートすれば簡単にサポートできるはずなのに
なんでそれやってる言語ってみかけないのかね、
なんて思ってたが
最近は私ごときでは
言語オタクとはとても名乗れない状況なので
誰か教えてくれないかななんておもいつつ
C++で実装してみることにした。
(それ自体すでに存在しそうな気もする)


テンプレートパラ−メータへのキャストあたりを
使うと、字面上で普通の変数と区別できなくなってしまうが、
とりあえずそれをやってみる。
クラス名はschemeに習ってpromise。
あとせっかくなので遅延評価じゃなくてスレッドにしてみた。

  #include <boost/thread.hpp>
  #include <iostream>

  template < class T >
  class promise {
   public:
    template < class F >  // T ()
    promise(F f)
        : thread_(boost::bind(
            &stub<F>, boost::ref(value_), f )) {
    }
    ~promise() { thread_.join(); }

    operator T () {
      thread_.join();
      return value_;
    }

   private:
    template < class F >
    static void stub(T& value, F f) {
      value = f();
    }

   private:
    T             value_;
    boost::thread thread_;

  };

int main() {
  promise<int> p([]()->int{ return std::cin.get(); });

  std::cout << (int)p << std::endl;
  
  return 0;
}

まあなんかそれなりに使えそうな気がしないでもない。


キャストだと字面でわからなくて危険なので、forceとかしてみようか。

T force() {
  thread_.join();
  return value_;
}

でも字面が面倒だとlambdaをautoで持つのとどう違うのか、という
疑問が生ずるな。


ならいっそのこともっと手を抜いて

template < class R >
operator R () {
  thread_.join();
  return static_cast<R>(static_cast<T>(value_));
}

とするか。


気が向いたらcopyableにしとくかな。
内部でthread_pool使うようにしたら
TopCoderでmemoization代わりに使ったりできないかな。