java で digital circuit simulator 実装

びっくり。というか、scheme とか ruby の lambda に感動。
scheme 版とか ruby 版では fuction box (or-gate とか inverter とか) において add-action! される手続きは以下のようなカンジになっていた。

scheme 版 (and-gate での例)

  (define (and-action-procedure)
    (let ((new-value
           (logical-and (get-signal a1) (get-signal a2))))
      (after-delay and-gate-delay
                   (lambda ()
                      (set-signal! output new-value)))))
  (add-action! a1 and-action-procedure)

ruby 版 (一部のみ)

    p = Proc.new { newVal = logicalNot(@i.value);
      afterDelay(@d, lambda{@o.value = newVal}, @ag) }
    @i.addAction p


手続きを取り扱えない現行バージョンの java は interface でコールバックを作っておいて、一定の名前の手続きにおいて出力側の回線の値を設定する必要がある。しかも java では lambda の中に閉じ込められている newVal のような変数の使い方ができない。

最初は interface を実装した function box において agenda 登録時に this を渡しとけば良いだろうと思っていたら、agenda の中で同じオブジェクトが queue の中に入ってるからどこかの値が変化したら一斉にそれに追従しやがった (当たり前

仕方がないので、agenda にはその時の状態を持った function box なオブジェクトを無理矢理作って queue に登録、などとゆー事をしたんですが、これは作成者のスキルが駄目なのか、はたまた java はステとゆー事なのかどちらなのでしょうか。

しかし、scheme は置いとくとしても、ruby の lambda は強力だな。

追記

む。よく考えてみるに、半加算器の初期化の方法がマズイ (SICP で例示されている方法なんですが、マズイとゆー表現は微妙かも) のであって、半加算器の中の回線がきちんと初期化されている状態から input な wire の状態を変えるのであれば、マトモに動作するかも、という事に思い当たっています。

これはどうなんだろう。仕様という表現の範疇なソレなんだろうか。