Clojure 如何从闭包定义函数

Clojure 如何从闭包定义函数,clojure,Clojure,这个问题涉及到 如果我重写(fn[n](fn[x](应用*(重复nx))as (defn power [n] (fn [x] (apply * (repeat n x))))` 像这样使用的话,效果很好 ((power 2) 16) 我可以用另一个幂来代替2,但我想用一个函数来表示平方,立方,等等。最好的方法是什么?我一直在REPL中摆弄它,但到目前为止运气不好。不太确定这是否是您要搜索的内容,但宏模板可能就是它。下面是我将如何编写您的代码: (use 'clojure.template)

这个问题涉及到

如果我重写
(fn[n](fn[x](应用*(重复nx))
as

(defn power [n] (fn [x] (apply * (repeat n x))))`
像这样使用的话,效果很好

((power 2) 16)

我可以用另一个幂来代替2,但我想用一个函数来表示平方,立方,等等。最好的方法是什么?我一直在REPL中摆弄它,但到目前为止运气不好。

不太确定这是否是您要搜索的内容,但宏模板可能就是它。下面是我将如何编写您的代码:

(use 'clojure.template)

(do-template [name n]
  (defn name [x] (apply * (repeat n x)))
  square 2
  cube   3)

user> (cube 3)
;=> 27
对于更复杂类型的类似任务,您可以编写一个宏来包装
do template
,对其参数执行一些转换,例如:

(defmacro def-powers-of [& ns]
  (let [->name #(->> % (str "power") symbol)]
    `(do-template [~'name ~'n]
       (defn ~'name [~'x] (apply * (repeat ~'n ~'x)))
       ~@(->> ns
              (map #(vector (->name %) %))
              flatten))))

(def-powers-of 2 3 4 5)

user> (power3 3)
;=> 27

user> (power5 3)
;=> 243

附言:如果你刚开始使用Clojure,这个宏可能看起来很尴尬,但不要因此而放弃!;-)

不太确定这是否是您要搜索的内容,但宏模板可能就是它。下面是我将如何编写您的代码:

(use 'clojure.template)

(do-template [name n]
  (defn name [x] (apply * (repeat n x)))
  square 2
  cube   3)

user> (cube 3)
;=> 27
对于更复杂类型的类似任务,您可以编写一个宏来包装
do template
,对其参数执行一些转换,例如:

(defmacro def-powers-of [& ns]
  (let [->name #(->> % (str "power") symbol)]
    `(do-template [~'name ~'n]
       (defn ~'name [~'x] (apply * (repeat ~'n ~'x)))
       ~@(->> ns
              (map #(vector (->name %) %))
              flatten))))

(def-powers-of 2 3 4 5)

user> (power3 3)
;=> 27

user> (power5 3)
;=> 243

附言:如果你刚开始使用Clojure,这个宏可能看起来很尴尬,但不要因此而放弃!;-)

使用宏完全围绕他的问题,即“我有一个生成闭包的函数,如何给这些闭包命名?”简单的解决方案是:

(letfn [(power [n]
          (fn [x]
            (apply * (repeat n x))))]
  (def square (power 2))
  (def cube (power 3)))

如果你真的不喜欢重复几次
def
power
,那么也只有到了那时,才是时候让宏参与进来了。但是,与使用函数进行定义的简单性相比,即使是最简单的宏所花费的精力也将被浪费,除非您定义的函数至少达到十次方。

使用宏来实现这一点完全是围绕他的问题进行的,这个问题是“我有一个生成闭包的函数,如何给这些闭包命名?”简单的解决方案是:

(letfn [(power [n]
          (fn [x]
            (apply * (repeat n x))))]
  (def square (power 2))
  (def cube (power 3)))

如果你真的不喜欢重复几次
def
power
,那么,也只有到那时,才是时候让宏参与进来了。但是,与使用函数的简单性相比,如果你不定义至少十次方的函数,那么即使是最简单的宏所花费的精力也会白费。

I没有回答您的问题。是否要创建函数集合:square、cube等?是的。我宁愿采用(幂2)语法,并将其替换为幂2、幂3(cubed),等等。当然有一个数学库,在生产代码中,我不会这样做,但我正在尝试将原始函数映射到它将如何接收其参数,并在REPL中尝试这一点非常有帮助。我没有理解你的问题。你想创建函数集合:正方形、立方体等吗?是的。我宁愿选择(power 2)语法,并将其替换为power 2、power 3(立方),等等。当然有一个数学库,在生产代码中,我不会这样做,但我正在尝试将原始函数映射到它将如何接收其参数,并在REPL中尝试这一点非常有帮助。谢谢。这是一个很好的答案。我在学习Clojure时遇到的很多问题都是让我的注意力集中在语法上。我越是对不一定在生产中使用的小数据进行处理,我就越能理解事情。谢谢。这是一个很好的答案。我在学习Clojure时遇到的很多问题是我的眼睛都被语法所困扰。对不一定在生产中使用的小数据进行处理越多,我就越能理解事情。是的,但是他的问题是stion的表达似乎有误,我不确定它是否那么简单。“等等”部分告诉我,他在寻找比他实际要求的更多的东西?我在精确性方面比你投了更高的票。我想要的是(def square(power 2)),但有一个宏观答案也很有帮助。就我个人而言,我会使用(power 2)是的,但是我想知道如何缩短它。是的,但是他的问题似乎表达错误,我不确定它是否那么简单。“等等”部分告诉我他在寻找比他实际要求的更多的东西?我在精确性方面比你投了更高的票。(def square(power 2))这是我想要的,但是有一个宏观的答案也很有帮助。就我个人而言,我会按原样使用(power 2),但不知道如何缩短它。