`
yangdong
  • 浏览: 65025 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Named arguments in Clojure

阅读更多
Clojure doesn't provide direct support for named arguments, which are supported under some popular dynamic languages like Ruby, Python. The following Python code was exerpted from `The Joy of Clojure':
def slope(p1=(0,0), p2=(1,1)):
return (float(p2[1] - p1[1])) / (p2[0] - p1[0])
slope((4,15), (3,21))
#=> -6.0
slope(p2=(2,1))
#=> 0.5
slope()
#=> 1.0

It calculates the slope of a line, which can be determined by two given points. The following Clojure code mimics the named arguments:
(defn slope
([] (slope [0 0] [1 1]))
([{:keys [p1 p2] :or {p1 [0 0] p2 [1 1]}}] (slope p1 p2))
([p1 p2]
(/ (- (float (p2 1)) (p1 1)) (- (p2 0) (p1 0)))))
(slope [4 15] [3 21])
;=> -6.0
(slope {:p2 [2 1]})
;=> 0.5
(slope)
;=> 1.0

I think it's sufficient for most of the cases. However, if you want to go deeper, let's use the defnk from clojure.contrib.def.
-------------------------
clojure.contrib.def/defnk
([fn-name & fn-tail])
Macro
  Define a function accepting keyword arguments. Symbols up to the first
 keyword in the parameter list are taken as positional arguments.  Then
 an alternating sequence of keywords and defaults values is expected. The
 values of the keyword arguments are available in the function body by
 virtue of the symbol corresponding to the keyword (cf. :keys destructuring).
 defnk accepts an optional docstring as well as an optional metadata map.

Unfornately, no examples were given in the doc string. Here's a simple example:
(require '[clojure.contrib.def :as def])
(def/defnk t [a :b 1] [a b])
(t 3)
;=> [3 1]
(t 3 :b 4)
;=> [3 4]


It should be noted that, the optional/named arguments must be put at the tail of the argument list. i.e. You can't write this: (def/defnk t [a :b 1 c] [a b c]) If you do, weird thing would happen. Or, your function may not even compile.
(def/defnk t [a :b 1 c] [a b c])
(t 1 2 3)
;=> [1 1 nil]
(def/defnk t [a :b 1 c d] [a b c d])
;=> java.lang.Exception: Unable to resolve symbol: d in this context
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics