Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Clojure中获取参数名称?_Clojure_Macros_Var - Fatal编程技术网

如何在Clojure中获取参数名称?

如何在Clojure中获取参数名称?,clojure,macros,var,Clojure,Macros,Var,我想从函数内部获取在函数外部定义的var的名称。该名称应该是我在原始定义范围内使用的名称,而不是我实际尝试使用该名称的任何嵌套绑定 因此,我想做一些类似(学术示例): 当从REPL调用eg时,这是有效的,但当从“内部”作用域eg调用时,编译器会阻塞 编译器说“无法解析变量y”(macroexpand…显示它试图在当前名称空间中查找局部变量y,而不是当前名称空间中的原始变量。我认为(var…)只查找名称空间变量,因此这会阻止宏在函数或其他绑定(如let)中工作 我想我不得不从定义变量的同一范围手动

我想从函数内部获取在函数外部定义的var的名称。该名称应该是我在原始定义范围内使用的名称,而不是我实际尝试使用该名称的任何嵌套绑定

因此,我想做一些类似(学术示例):

当从REPL调用eg时,这是有效的,但当从“内部”作用域eg调用时,编译器会阻塞

编译器说“无法解析变量y”<代码>(macroexpand…显示它试图在当前名称空间中查找局部变量y,而不是当前名称空间中的原始变量。我认为
(var…
)只查找名称空间变量,因此这会阻止宏在函数或其他绑定(如
let
)中工作

我想我不得不从定义变量的同一范围手动获取变量名,并将其作为额外参数传递。有没有一种更优雅的方法通过绑定链将var名称信息传递到使用它的位置?那太糟糕了

谢谢

为什么不将
(获取变量名称\u symbol-here)
传递给希望在主体内使用变量名称的函数?例如,使用与上面给出的
get var name
f2
f3
my var
完全相同的定义(但稍微更改
f1
):

注意
@(解析x1)
——这是返回
my var
引用的值的东西(反过来
my var
x1
引用的值)

另外,我想指出的是,当前的
get var name
实现将在传递给它的参数不是符号或是符号但当前未绑定到值时引发异常。这是你想要的行为吗


如果我的建议没有回答您的问题,那么您似乎不想将
(get-var-name(get-var-symbol-here)
传递给可能最终使用var名称的函数,而是出于某种原因,您确实希望能够从函数体内部执行
(get-var-name…
。如果是这样的话,为什么你想这样做呢?或者,如果您觉得我因为其他原因没有回答您的问题,那是什么原因?

无法获取函数中外部作用域中使用的变量的名称-函数只接收在运行时作为参数传递的值,而不是变量本身

您唯一可能做的就是在每个级别使用宏而不是函数。这允许您在编译时通过不同的宏传递变量本身:

(defmacro f1 [x1] `(println "hello, you passed var name >>" ~(str x1) "<<"))
(defmacro f2 [x2] `(f1 ~x2))
(defmacro f3 [x3] (let [zzz x3] `(f2 ~zzz)))

(f3 my-var)
=> hello, you passed var name >> my-var <<

(defmacro f1[x1]`(println“您好,您传递了变量名>>”~(str-x1)”您可以使用
#”读取器宏将实际变量传递给函数,而不是变量解析值,如下所示:

user=> (defn f1 [x1] (println "hello, you passed var name >>" (:name (meta x1)) "<<"))
#'user/f1
user=> (defn f2 [x2] (f1 x2))
#'user/f2
user=> (defn f3 [x3] (let [zzz x3] (f2 zzz)))  
#'user/f3
user=> (def my-var 3.1414926)
#'user/my-var
user=> (f3 #'my-var)
hello, you passed var name >> my-var <<

user=>(defn f1[x1](println“您好,您传递了变量名>>”(:name(meta-x1)))这个,是这个的一百倍。其他答案(到目前为止)与提问者的假设一致,即变量参与并实际起作用,但事实并非如此(如问题中的最后一个示例所示)。谢谢,但我需要从函数体中获取var名称。基本上,我正在尝试将作用域更高的变量的名称附加到函数调用下面几层的其他文本中。我想我可以在启动调用链之前使用
(binding…
)来尝试这一点。@Sonicsmooth我想我明白了。我很想看看真正的(即非学术性示例)您正在做/试图做的事情的版本…好吧,我也放弃了
(binding…
)。它需要在我的命名空间中添加一个虚拟变量,使其变得丑陋。我正在尝试编写自己的数据库内部联接,其中每个表都是一组clojure映射;在一组映射中,映射共享键。(我知道'clojure.set'中已经有一个连接)。但是如果这两个表有一个公共键,那么在计算笛卡尔积的(天真的)第一步中,其中一个值会被删除,所以我试图保持键的名称不同。目前我只在“left.”和“right”前面加上前缀到共享键名,但我想改用var名称。我可以像在另一个响应中一样从REPL传递使用的var,但我也希望传递一个let绑定符号。@Sonicsmooth我现在了解更多,但老实说,我不熟悉数据库操作,所以我觉得我有点不懂。不过,如果你提出一个新问题,我想,描述了“在不丢失共享密钥的情况下进行数据库内部联接”的问题(或者您将如何命名它),您可能会得到一个最终问题的解决方案,该解决方案可能涉及也可能不涉及从嵌套作用域中获取变量名称。谢谢,这个响应实际上触发了我对符号->变量->值在clojure中如何工作的多小时调查。它从repl与变量一起工作,但仍然不适用于let有界符号。
(defn another-func [y]
  (get-var-name y))
(defmacro get-var-name [x]
  `(:name (meta (var ~x))))
(defn f1 [x1] (println "hello, you passed var name >>" x1 "<<"))
(defn f2 [x2] (f1 x2))
(defn f3 [x3] (let [zzz x3] (f2 zzz)))
(def my-var 3.1414926)
=> (f3 (get-var-name my-var))
hello, you passed var name >> my-var <<
=> nil
(defn f1 [x1] (println "hello, you passed var name >>" x1 "<<"
                       "\nwhich refers to value >>" @(resolve x1) "<<"))
=> (f3 (get-var-name my-var))
hello, you passed var name >> my-var << 
which refers to value >> 3.1414926 <<
=> nil
(defmacro f1 [x1] `(println "hello, you passed var name >>" ~(str x1) "<<"))
(defmacro f2 [x2] `(f1 ~x2))
(defmacro f3 [x3] (let [zzz x3] `(f2 ~zzz)))

(f3 my-var)
=> hello, you passed var name >> my-var <<
user=> (defn f1 [x1] (println "hello, you passed var name >>" (:name (meta x1)) "<<"))
#'user/f1
user=> (defn f2 [x2] (f1 x2))
#'user/f2
user=> (defn f3 [x3] (let [zzz x3] (f2 zzz)))  
#'user/f3
user=> (def my-var 3.1414926)
#'user/my-var
user=> (f3 #'my-var)
hello, you passed var name >> my-var <<