函数中的原始或集合参数?

时间:2013-06-25 15:34:43

标签: clojure

我对函数式编程很新。我以前的编程经验主要是Java。

在用函数式语言设计函数时,传递原语或集合是否更好?由于我对函数式语言缺乏了解,我觉得通过选择其中一种来看,我看不到影响。

在我看来,传递一个集合会产生更清晰,更直观的代码(例如,传递一个名为person的地图而不是名字,姓氏等)。另一方面,这会创建集合结构的依赖关系。也许它只取决于您必须从该地图中使用的信息量。不确定...

我意识到这是一个公开的讨论,但我主要担心的是,如果有一种事实上的方法来设计功能。

UPDATE1

假设我们有像之前所说的人物地图,我们想要改进其内容。我想我们会做类似的事情:

; 
(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,它可以扩展等等,但另一方面,它似乎有点过分。

3 个答案:

答案 0 :(得分:2)

从实用性的角度来看,我更喜欢传递集合和地图。您可以在地图中组合一个非常复杂的数据结构,并将其作为单个参数传递。它比作为单个参数传递数据位更容易。这不仅适用于函数式语言 - 同样的推理也可以应用于过程语言或面向对象语言。

答案 1 :(得分:2)

在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"})

如果我需要更多处理或者我的推文处理器范围扩大,我发现推理我的应用程序的最简单方法是引入更多process-tweet函数并将它们链接到一个工作流程中:< / p>

(map (comp do-something-else do-something capitalize-tweet) tweets)

我的三个处理函数接受一条推文并可能以不同的方式对其进行解构,并且它们可以与像clojure.string/upper-case这样的小功能协作,但这些是实现细节。

将较小的函数和库调用拼接在一起,以实现向管道发送推文的更广泛目标,而这些小函数构成了我用于表达该管道的更高级别的推文处理函数。

这通常是我喜欢用Clojure处理问题的方式,它使我可以轻松地组织代码。这些基本操作的小函数组成了functionA,而这些其他小函数组成了functionB,其中functionA和B在我程序的核心数据结构上运行。

再举一个例子,看看Ring(https://github.com/ring-clojure/ring/wiki/Concepts)。请求哈希映射进入,通过定义您的应用程序的处理程序(以及转换处理程序的中间件函数)进行转换,并显示响应哈希映射。

答案 2 :(得分:0)

这取决于用例。

我不认为FP“更喜欢”其中一个,只要你传递不可变结构, 否则你冒着失去referential-transparency的风险,而FP几乎就是建立起来的。