I'm still learning this alien functional paradigm...
How would I write the following code in Clojure, and in a functional way? assume this missing parts are defined elsewhere and behave as described in the comments. Here it is in Python, which I am familiar with.
usernames = []
# just the usernames of all the connections I want to open.
cancelfunctions = {}
# this global contains anonymous functions to cancel connections, keyed by username
def cancelAll():
for cancel in cancelfunctions.values():
cancel()
def reopenAll():
cancelfunctions = {}
for name in usernames:
# should return a function to close the connection and put it in the dict.
cancelfunctions[name] = openConnection()
All I really need to know is how to build up a new dict of callbacks, like in the reopenAll function, but I'm including some more context here because chances are I'm committing some kind of functional paradigm atrocity, and you will most likely want to fix the whole program. :)
Building data structures in Clojure often involves reduce
, which feeds a sequence of inputs to a function which accumulates a final return value. Here are two ways to write a function which constructs a map (i.e. dictionary) of username to the return value of open-connection
.
;; Using reduce directly
(defn reopen-all [usernames]
(reduce
(fn [m name] (assoc m name (open-connection)))
{} usernames))
;; Using into, which uses reduce under the hood
(defn reopen-all [usernames]
(into {} (for [name usernames]
[name (open-connection)])))
Note that these two functions return a value and do not mutate global state, as your Python code does. Global state isn't inherently bad, but it's good to separate value-generation from state manipulation. For state, you'll probably want an atom
:
(def usernames [...])
(def cancel-fns (atom nil))
(defn init []
(reset! cancel-fns (reopen-all usernames)))
And here's cancel-all
for completeness' sake:
(defn cancel-all []
(doseq [cancel-fn (vals @canel-fns)]
(cancel-fn)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With