Last active
May 30, 2018 12:40
-
-
Save janherich/c0d7347a29d868e295d04c8dcc86b5dd to your computer and use it in GitHub Desktop.
Purely functional proposal
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Rather then relying on macros, I propose to have `merge-fx` helper exposed as function | |
;; taking variable number of arguments (where the first one is always cofx, second one could | |
;; be initial effects map and then variable number of effects producing functions, with the | |
;; all of them with the same form as now: | |
(defn effects-fn [arg1 arg2 {:keys [db] :as cofx}] | |
{:db (update db :some-key arg1) | |
:http-call ...}) | |
(defn final-effects-fn [cofx] | |
(merge-fx cofx | |
(partial effects-fn "a" "b") | |
effects-fn1)) | |
;; Advantage is that composing dynamic effects is trivial and we don't need any other helpers: | |
(defn final-effects-fn [cofx] | |
(apply merge-fx cofx | |
(map #(partial effects-fn "a" %) some-dynamic-sequence-of-values))) | |
;; Another advantage is that conditionaly ommiting steps during effects composition is trivial | |
;; without need for any extra special constructs (provided we just filter out `nil` values in | |
;; the `merge-fx` helper) | |
(defn final-effects-fn [cofx] | |
(merge-fx cofx | |
(when some-condition | |
(effects-fn "a" ""b)) | |
(effects-fn1))) | |
;; Disadvantage is that you have to either take care of the curring (partial) during composition, | |
;; or write the helper functions as higher-order-functions anytime arguments other then just `:cofx` | |
;; map are required (effectively pushing responsibility for currying down): | |
(defn effects-fn [arg1 arg2] | |
(fn [{:keys [db] :as cofx}] | |
{:db (update db :some-key arg1) | |
:http-call ...})) | |
(defn final-effects-fn [cofx] | |
(merge-fx cofx | |
(effects-fn arg1 arg2) | |
effects-fn1)) | |
;; Optionally, we can introduce `defnfx` macro, which will make curried functions more pleasant | |
(defnfx effects-fn [arg1 arg2] | |
{:db (update db :some-key arg1) | |
:http-call ...}) | |
;; The above will generate the the function creator automatically |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment