Interesting; I had started playing with the core.async approach, and it's good to see that Pedestal's on that same path.

Brian, I like that too. It looks like you're providing the state when you do the def-action? Is the "self" variable "state", captured through the closure?

Walter van der Laan wrote:
An alternative that I'm looking at is pedestal 0.3.0. It sort of works like this...

;; Create a transform-channel and transform-function to handle all changes to 'state'
(defn init []
  (let [c (chan)]
    (go (while true
          (when-let [[path v] (<! c)]
            (swap! state assoc-in path v))))
    c))
(def transform-chan (init))
(defn transform [path v]
  (>! transform-chan [path v]))

;; Change the state by calling transform
(transform [athlete-number :active?] true)
(transform [athlete-number :timestamp] ms)

;; Create an inform-channel where functions can subscribe to changes in 'state'
(def inform-channel-subscriptions
  [[update-timestamp [:* :timestamp]]
   [update-active [:* :active?]]])

This approach is described in:
https://github.com/pedestal/pedestal/blob/master/app/examples/walkthrough.clj

On Friday, November 29, 2013 6:58:32 PM UTC+1, Sam Ritchie wrote:

    Hey guys,

    As I start to work on more Clojurescript UI code, I've been
    running into a pattern with atoms and watches that I THINK I can
    abstract away... but the solution feels wrong, and I'd love to
    hear a better way.

    Say I'm building a stopwatch for timing runners in a race. I've
    got a clojure record like this:

    (defrecord StopwatchState [
      active? ;; timer running?
      timestamp ;; UTC time of this particular state
      stopwatch-time ;; the time on the stopwatch as of "timestamp"
      results ;; pairs of [athlete number, time]])

    and a bunch of functions that toggle the timer, mark an athlete
    crossing the line, update the timer, etc.

    My view holds the current state in an atom:

    (def state (atom ,,some-stopwatch-state))

    and I update my views by adding watches to the atom and refreshing
    the various UI components to match the new state.

    Now! Here's the annoying pattern. In the cljs UI world, to poke
    these atoms, I end up wrapping all of my model functions like this:

    (defn toggle! []
      (swap! state toggle))
    (defn mark! [athlete-number]
      (swap! state mark athlete-number))

    I can think of two ways to break the pattern.

    1) A deep-code-walking macro that transforms code like (mark state
    athlete-number) into (swap! state mark athlete-number) if the
    first argument is an atom;
    2) a defstatefn macro that defines the "mark" and "mark!" versions
    at the same time.

    Both feel wrong. My goal is to program in a more declarative way.
    Is there a better way to structure UI code?

-- Sam Ritchie (@sritchie)
    Paddleguru Co-Founder
    703.863.8561
    www.paddleguru.com <http://www.paddleguru.com/>
    Twitter <http://twitter.com/paddleguru>// Facebook
    <http://facebook.com/paddleguru>

--
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

--
Sam Ritchie (@sritchie)
Paddleguru Co-Founder
703.863.8561
www.paddleguru.com <http://www.paddleguru.com/>
Twitter <http://twitter.com/paddleguru>// Facebook <http://facebook.com/paddleguru>

--
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to