 
 (def messages (chan))
 
+(def effects (chan))
+
+(defprotocol Effect
+  (run-effect [this]))
+
+(defrecord Random [callback]
+  Effect
+  (run-effect [this]
+    ((:callback this) (rand-int 100))))
+
+(defrecord Print []
+  Effect
+  (run-effect [this]
+    (println "Printed!")))
+
+(defn printaction [action old-model new-model effect]
+  (js/console.groupCollapsed action)
+  (js/console.info old-model)
+  (js/console.info new-model)
+  (js/console.info effect)
+  (js/console.groupEnd))
+
+(go
+  (while true
+    (let [effect (<! effects)
+          message (run-effect effect)]
+      (if-not (nil? message) (>! messages message)))))
+
 (def root (.getElementById js/document "app"))
 
 (defn submit [message]


(defn main [initial-model view update]
  (go-loop [model initial-model]
           (println model)
           (q/render (view model) root)
           (recur (update model (<! messages)))))

;; ******************************************************************


              (:counter model)
              (d/button {:onClick (fn [e] (submit (->Increment)))} "+"))
         (d/p {} (d/button {:onClick (fn [e] (submit (->GenerateRandom)))} "Random"))
         (d/p {} (d/button {:onClick (fn [e] (submit (->PrintSomething)))} "Print something"))
         (d/p {}
              (d/input {:onChange (fn [e] (let [value (-> e (.-target) (.-value))]
                                            (submit (->Type value))))
