Fork me on GitHub
#code-reviews
<
2015-07-01
>
meow14:07:47

so I'm working on some helper functions for event handling in cljs and have the following:

(defn listen!
  ([channel func]
   (go-loop []
     (func (<! channel))
     (recur)))
  ([src event-type func]
   (events/listen src event-type func)))
I like that on the consuming side of this function I can setup my event listeners like this:
(defonce listen-for-dom-viewport-resize!
  (poly/listen! @rc-cha-dom-viewport-resize on-dom-viewport-resize))

(defonce listen-for-dom-window-load!
  (poly/listen! js/window "load" on-dom-window-load))

(defonce listen-for-env-mouse-move!
  (poly/listen! @rc-cha-env-mouse-move on-env-mouse-move))
So I can easily mix between traditional callbacks handling the events or async.core style handlers that take from a channel.

meow14:07:26

What I'm not sure about is whether it's a bad design choice to define listen! the way I did since I'm taking advantage of the fact that I have a different arity, but the parameters are unrelated. So I could split the function into something like:

(defn listen-take!
  [channel func]
  (go-loop []
    (func (<! channel))
    (recur)))

(defn listen!
  [src event-type func]
   (events/listen src event-type func))
But with that I lose the simplicity (or is it just easiness?) on the consuming side. Any thoughts?

meow15:07:45

Anyone? Anyone? Bueller?

meow15:07:18

Where is Ferris?

alejandro15:07:15

@meow: In my opinion, you’re actually adding complexity by having such different behavior based purely on arity. You’re saving yourself a bit of typing, but I think you’re still burdened as the caller to understand that the two different signatures are quite different.

meow15:07:08

@alejandro: Right, that's one of my concerns.

meow15:07:06

At the same time the similarity is in the intent on the consuming side: I've got a func that I want to get called whenever an event happens - whether the event is coming from the js environment or from an async channel.

meow15:07:01

Makes me wonder if I can create some concept for the source of the event.

meow15:07:02

I also have a listen-put so if I separate all concerns I end up with the following:

(defn listen!
  [src event-type func]
  (events/listen src event-type func))

(defn listen-take!
  [channel func]
  (go-loop []
    (func (<! channel))
    (recur)))

(defn listen-put!
  ([src event-type channel]
   (events/listen src event-type #(put! channel %))
   channel)
  ([src event-type channel subject]
   (events/listen src event-type #(put! channel subject))
   channel))

meow15:07:44

I guess that's the most straightforward approach. Perhaps someone else can think of a clever way to combine them. But it would have to be done without losing clarity.