Skip to content

Instantly share code, notes, and snippets.

@ossbase
Created October 21, 2015 18:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ossbase/b593400fee121f57ea05 to your computer and use it in GitHub Desktop.
Save ossbase/b593400fee121f57ea05 to your computer and use it in GitHub Desktop.
(defmacro def-action
[name & {:keys [props]}]
(let [defaults {:disabled false}]
`(def ~(symbol name) ~(merge defaults props {:type (keyword name)}))))
(def-action call)
(def-action hangup)
(def-action mute)
(def-action unmute)
(def-action hold)
(def-action unhold)
(defn deactivate
"Action will be deactivation"
[action]
(merge action {:disabled true}))
(defn actions
"Select and execute flow for get action"
[member]
(cond
:else (-> []
(call-member-actions member)
(call-member-visual-state member))))
(defn call-member-actions
""
[actions {{:keys [type] :or {type :idle} :as status} :status}]
(cond
(= type :calling) (if (:mute status)
(conj actions hangup hold unmute)
(conj actions hangup hold mute))
(= type :holding) (conj actions hangup unhold)
(= type :idle) (conj actions call)
:else actions))
(defn call-member-visual-state
""
[actions {{:keys [type] :or {type :idle} :as status} :status}]
(cond
(= type :holding) (if (:mute status)
(conj actions (deactivate unmute))
(conj actions (deactivate mute)))
(= type :idle) (do (println (deactivate mute)) (conj actions
(deactivate hold)
(deactivate mute)))
:else actions))
;; test get actions
(flow-actions {:status {:type :calling}})
@akivascript
Copy link

Just after a quick glance, you have a function calling another function that’s defined ​_after_​ the calling function. They have to be defined in order (line 23). If you want to get around this, use declare although that's pretty rare.

Line 21: Not sure why you have a cond that’s just an :else. I’d ditch that. Also, you shouldn’t need a threading macro when you’re starting with an empty state. Let the first function call establish initial state. And then I’d use comp.

Also, there are a lot of conds in there. That’s usually a sign of imperative-style programming. It’d probably be more idiomatic to use defmulti.

@bensu
Copy link

bensu commented Oct 21, 2015

Hi!

I wouldn't start with macros. Some suggestions:

  1. docstrings are optional, there is no need for "".
  2. You can pack both (if (:mute status) ...) as (if (:mute status) unmute mute)
  3. Those conds can be written as case if you want fast and local dispatch or multi-methods if you want slower but extensible dispatch.
  4. The cond in actions makes no sense. It's like calling if false { ingnore } else { doStuff } in JavaScript.
  5. call-member-visual-state does both data transformations and side effects. Try to extract the do block and print statement into another function that you can mark as side-effecting and preserve the other pure functionality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment