我应该如何建立一个列表并将其返回到clojure中?

use*_*512 5 porting functional-programming clojure

我还在学习这种外星人的功能范式......

我将如何在Clojure中以函数方式编写以下代码?假设这个缺失的部分在别处定义,并且在评论中描述.这是我熟悉的Python.

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()
Run Code Online (Sandbox Code Playgroud)

所有我真正需要知道的是如何构建一个新的回调函数,就像在reopenAll函数中一样,但是我在这里包含了一些更多的上下文,因为我有可能犯下某种功能范式的暴行,你最有可能可能想要修复整个程序.:)

Jus*_*mer 6

在Clojure中构建数据结构通常涉及reduce将一系列输入提供给累积最终返回值的函数.以下是编写函数的两种方法,该函数将用户名的映射(即字典)构造为返回值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)])))
Run Code Online (Sandbox Code Playgroud)

请注意,这两个函数返回一个值,并且不会像Python代码那样改变全局状态.全球状态本身并不坏,但将价值生成与国家操纵分开是件好事.对于州,你可能想要一个atom:

(def usernames [...])
(def cancel-fns (atom nil))

(defn init []
  (reset! cancel-fns (reopen-all usernames)))
Run Code Online (Sandbox Code Playgroud)

这是cancel-all为了完整性:

(defn cancel-all []
  (doseq [cancel-fn (vals @canel-fns)]
    (cancel-fn)))
Run Code Online (Sandbox Code Playgroud)