标签: defn

帮我写一个Clojure宏,它自动将元数据添加到函数定义中

我意识到宏俱乐部的第一条规则是不要使用宏,所以下面的问题更多的是作为学习Clojure的练习而不是其他任何东西(我意识到这不一定是宏的最佳用法).

我想编写一个简单的宏,它充当常规(defn)宏的包装器,并最终向定义的函数添加一些元数据.所以我想要这样的东西:

(defn-plus f [x] (inc x))
Run Code Online (Sandbox Code Playgroud)

......扩展到这样的东西:

(defn #^{:special-metadata :fixed-value} f [x] (inc x))
Run Code Online (Sandbox Code Playgroud)

原则上这对我来说似乎并不难,但是我无法[args]确定正确解析定义函数中的其他形式的具体细节.

作为奖励,如果可能的话,我希望宏能够处理所有不同形式的defn(即,有或没有docstrings,多个arity定义等).我在clojure-contrib/def包中看到了一些看起来可能有用的东西,但是很难找到使用它们的示例代码.

lisp macros clojure defn

19
推荐指数
1
解决办法
3205
查看次数

如何在Clojure中从字符串中定义函数?

我想这样做(在REPL或任何地方)

(defn (symbol "print-string") [k] (println k))
Run Code Online (Sandbox Code Playgroud)

然后能够做到

(print-string "lol")
Run Code Online (Sandbox Code Playgroud)

或者,如果还有其他方法可以从宏中的自定义字符串创建defn,那么你可以把我推向正确的方向吗?

eval metaprogramming function clojure defn

15
推荐指数
4
解决办法
2701
查看次数

动态检索Clojure函数元数据

环境:Clojure 1.4

我试图从函数向量中动态提取函数元数据.

(defn #^{:tau-or-pi: :pi} funca "doc for func a" {:ans 42} [x] (* x x))
(defn #^{:tau-or-pi: :tau} funcb "doc for func b" {:ans 43} [x] (* x x x))

(def funcs [funca funcb])
Run Code Online (Sandbox Code Playgroud)

现在,检索REPL中的元数据(有点)是直截了当的:

user=>(:tau-or-pi (meta #'funca))
:pi

user=>(:ans (meta #'funca))
42

user=>(:tau-or-pi (meta #'funcb))
:tau

user=>(:ans (meta #'funcb))
43
Run Code Online (Sandbox Code Playgroud)

然而,当我尝试做一个地图,让:ans,:tau-or-pi或基本:name从元数据,我得到异常:

user=>(map #(meta #'%) funcs)
CompilerException java.lang.RuntimeException: Unable to resolve var: p1__1637# in this context, compiling:(NO_SOURCE_PATH:1) 
Run Code Online (Sandbox Code Playgroud)

在做了一些搜索后,我从2009年的帖子中得到了以下想法(https://groups.google.com/forum/?fromgroups=#!topic/clojure/VyDM0YAzF4o):

user=>(map #(meta …
Run Code Online (Sandbox Code Playgroud)

metadata function clojure defn

8
推荐指数
1
解决办法
794
查看次数

如何将:arglists修改为Clojure fn或宏?

如何修改Clojure FN或宏的:arglist属性?

(defn tripler ^{:arglists ([b])} [a] (* 3 a))

(defn ^{:arglists ([b])} quadrupler [a] (* 4 a))

% (meta #'tripler) => 
  {:arglists ([a]), :ns #<Namespace silly.testing>, :name tripler, :line 1, :file "NO_SOURCE_PATH"}

% (meta #'quadrupler) => 
  {:arglists ([a]), :ns #<Namespace silly.testing>, :name quadrupler, :line 1, :file "NO_SOURCE_PATH"}
Run Code Online (Sandbox Code Playgroud)

好的,那里没有运气,所以我尝试执行以下操作。

(def tripler
  (with-meta trippler
    (assoc (meta #'tripler) :arglists '([c]))))

% (with-meta #'tripler) => 
  {:ns #<Namespace silly.testing>, :name tripler, :line 1, :file "NO_SOURCE_PATH"}
Run Code Online (Sandbox Code Playgroud)

嗯,现在:arglists键不见了?好吧,我放弃了,我该怎么做?我只想修改:arglists的值。上面的示例使用defn,但我也想知道如何使用宏(defmacro)设置:arglists。

macros arguments clojure defn

4
推荐指数
2
解决办法
1120
查看次数

Clojure中的多方防守 - 第一场比赛是先发球吗?

具体而言,在以下情况下会发生什么:

(defn avg
  ([] 0)
  ([& args] (/ (reduce + args) (count args))))

(avg)
Run Code Online (Sandbox Code Playgroud)

也就是说,我可以依靠clojure总是返回0而不是归零吗?

overloading clojure defn arity

2
推荐指数
1
解决办法
192
查看次数

Clojure 中的 defn- 和 defn ^:private 有什么区别?

两者似乎都表示私有函数,类似于大多数 OOP 语言中的私有函数。是否存在功能差异或者只是语法糖?

我见过 defn ^:private 在环应用程序的处理程序上下文中使用。

clojure defn ring

2
推荐指数
1
解决办法
72
查看次数

Clojure将名称定义为乘数

任何人都可以解释为什么在下面的代码中,函数的名称在第一部分作为*(乘数)?

(defn bar
     ([a b]   (bar a b 100))
     ([a b c] (* a b c)))
Run Code Online (Sandbox Code Playgroud)

bar两个args (bar 2 3)产量(* 2 3 100)

clojure defn

0
推荐指数
1
解决办法
61
查看次数

0
推荐指数
1
解决办法
76
查看次数