目的
通过对fp的学习,发现改变了一些编程的思路,这里对于这方面的讨论比较少,所以抛砖引玉,学习下。
下面举个例子
(defn simpfy-piece
"throw away the unnessesaries"
[piece]
[(schema/piece-name-id
(b/get-state :piece-name-ids)
(:entity piece)
(:key piece))
(:val piece)])
下面是修改之后的代码。
(defn piece->simple-piece
"throw away the unnessesaries"
[piece-name->id]
(fn [piece]
[(piece-name->id (:entity piece) (:key piece))
(:val piece)] ))
其中的变化
- 大部分pure方法命名都是 a->b,比如
piece->simple-piece。 - 返回的方法的参数只有一个。
- 如果方法有依赖,则在参数中定义,但返回一个pure方法,例如将
schema/piece-name-id这个依赖的方法,通过参数传递进来。 - 副作用都是在最上层并单独处理。
问题:
- 没法做到composition,很多方法都是有多个参数,没法通过组合方法达到目的。
- 这种做法,下层的代码很容易理解,但是上层的代码就受罪了,大量的内嵌方法调用,层层方法有依赖。如下。
(defn query
[clause]
(query/query->entities
(query/vindex->entities
(query/entity-id->entity
(query/entity-id->pieces
(idx/entity-id->kindex ref-kindex)
(store/ids->pieces
(store/id->piece (fn [entity-name id]
(p/get! (b/get-state :pieces-db) id)))))
(query/pieces->entity (sc/piece-name->id
(b/get-state :piece-name-ids)))))
{:piece-name->id (sc/piece-name->id (b/get-state :piece-name-ids))
:piece-name->vindex ref-vindex}))
最后,有没有同学可以分享自己的心得,如何用好functional programming.
如果能分享代码更好。
我上面实现的功能比较简单,piece->simple-piece 是将一个map结构的数据,删除掉不需要的部分,同时将里面key为"name"的值转换成id,所以依赖piece-name->id,如果各位来实现,是怎么个思路。