Clojure 函数中的基元参数还是集合参数?
我对函数式编程相当陌生。我以前的编程经验主要是Java 在函数式语言中设计函数时,传递原语还是传递集合更好?由于我缺乏函数式语言方面的知识,我觉得我无法通过选择一种或另一种来看到影响 在我看来,传递集合会产生更清晰、更直观的代码(例如,传递名为person的地图,而不是名称、姓氏等)。另一方面,这会创建集合结构的依赖项。也许这仅仅取决于你从地图上使用的信息量。不确定 我意识到这是一个公开的讨论,但我最关心的是是否有一种实际的方法来设计功能 更新1 假设我们有我前面说过的人物地图,我们想要str它的内容。我想我们应该做一些类似的事情:Clojure 函数中的基元参数还是集合参数?,clojure,Clojure,我对函数式编程相当陌生。我以前的编程经验主要是Java 在函数式语言中设计函数时,传递原语还是传递集合更好?由于我缺乏函数式语言方面的知识,我觉得我无法通过选择一种或另一种来看到影响 在我看来,传递集合会产生更清晰、更直观的代码(例如,传递名为person的地图,而不是名称、姓氏等)。另一方面,这会创建集合结构的依赖项。也许这仅仅取决于你从地图上使用的信息量。不确定 我意识到这是一个公开的讨论,但我最关心的是是否有一种实际的方法来设计功能 更新1 假设我们有我前面说过的人物地图,我们想要str它
;
(def person {:name "John" :surname "Doe"})
(defn str-person
"Give the full name of a person"
[person]
(apply str (interpose ", " (map #(get-in person [%]) [:surname :name]))))
; => Doe, John
; primitive alt
(defn str-person
"Give the full name of a person"
[name surname]
(str surname ", " name))
; => Doe, John
现在,我相信第一个解决方案更接近于FP,并且可以扩展,等等,但另一方面,它似乎有点过头了。这取决于用例 我不认为FP“更喜欢”一个或另一个,只要你传递的是不可变的结构,
否则,你将面临失败的风险,而这正是FP的基础 仅从实用角度来看,我更喜欢传递集合和地图。您可以将一个相当复杂的数据结构放在一个映射中,并将其作为单个参数传递。这比将数据位作为单独的参数传递更容易。这不仅仅适用于函数式语言——同样的推理也可以应用于过程式或面向对象的语言。在Clojure中,由于您的域是在数据结构(如哈希映射)中建模的,因此您的工作主要是通过映射这些数据结构上的函数和转换来表达的 因此,我发现我的应用程序的高级域级表达式通常定义为:
(map process-thing things)
例如,以下是我们作为一项服务部署的令人敬畏的推特处理器应用程序的精髓:
;; Get tweets from twitter
(def tweets [{:username "max"
:text "I'm tweeting."}
{:username "kate"
:text "I ate breakfast."}])
(defn capitalize-tweet [{:keys [text] :as tweet}]
(let [processed-text (clojure.string/upper-case text)]
(assoc tweet :text processed-text)))
(map capitalize-tweet tweets)
;=> ({:text "I'M TWEETING.", :username "max"}
; {:text "I ATE BREAKFAST.", :username "kate"})
如果我需要进行更多的处理,或者如果我的tweet处理器的范围扩大,我发现对我的应用程序进行推理的最简单方法是引入更多的处理tweet
功能,并将它们链接到一个工作流中:
(map (comp do-something-else do-something capitalize-tweet) tweets)
我的三个处理函数接受一条tweet,并可能以不同的方式对其进行分解,它们可能与较小的函数协作,完成一件事,如clojure.string/upper case
,但这些是实现细节
更小的函数和库调用被缝合在一起,以服务于沿着管道发送tweet的更广泛目标,而这些小函数构成了我用来表示管道的更高级tweet处理函数
这通常是我喜欢用Clojure处理问题的方式,它使我的代码组织起来很容易。这些在原语上运行的小函数组成functionA,其他小函数组成functionB,functionA和B在我的程序的核心数据结构上运行
另一个例子是,检查环()。一个请求哈希映射出现,通过定义应用程序的处理程序(以及转换处理程序的中间件函数!)进行转换,然后出现一个响应哈希映射。这是一个相当普遍的问题。你能提供一些示例代码吗?你会考虑哪种方法?是的,伙计,我知道它是通用的。请参阅更新1。还有一种中间方法:解构-传递映射,但使用单个值,例如(defn str person[{:keys[name姓氏]}](str姓氏”,“name))嘿status,谢谢你的回答。这是否直接从传递的地图中选择关键点?是的,上面的地图表单查找与符号等效的关键字。您还可以使用:strs或:syms作为字符串或符号键。顺序集合还有一个位置等价物,例如(defn[[first u-third]]…)将集合中的第一项和第三项用作第一项和第二项,但忽略第二项。有点浓,但你看