如何获取参数的名称在Clojure? [英] How to get name of argument in Clojure?

查看:114
本文介绍了如何获取参数的名称在Clojure?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like to get the name of a var defined outside a function, from within a function. The name should be the name that I used at the scope of the original definition, not any nested bindings where I'm actually trying to use the name.

喜欢做类似的事情(学术示例):

So I would like to do something like (academic example):

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

我可以根据我发现的一些东西做这个宏:

I'm able to do this macro based on some stuff i found:

(defmacro get-var-name [x]
  `(:name (meta (var ~x))))

这在例如从REPL调用时起作用,但是当从内部范围调用时编译器阻塞,例如

This works when called eg from the REPL, but compiler chokes when called from an "inside" scope eg

(defn another-func [y]
  (get-var-name y))

编译器说无法解析var y。(macroexpand ...)尝试在当前命名空间中查找局部变量y,而不是在当前命名空间中的原始变量。我认为(var ... )仅查找namespace vars,因此这将阻止宏在函数或其他绑定(例如 let

Compiler says "saying Unable to resolve var y". (macroexpand...) shows it's trying to find local variable y in the current namespace, rather than the original variable in the current namespace. I think (var...) looks for namespace vars only, so this prevents the macro from working either within a function or another binding such as let.

我认为我不得不手动从同一范围手动获取变量名称该变量并将其作为一个额外的参数传递。有没有更优雅的方式来传递var名称信息通过一系列的绑定到它的使用点?

I think I'm stuck having to manually get the variable name from the same scope where I define the variable and pass it along as an extra parameter. Is there a more elegant way to pass var name information through a chain of bindings to the point where it's used? That would be bad-ass.

感谢

推荐答案

可能在函数内部获得在外部作用域中使用的var的名称 - 函数仅接收在运行时作为参数传递的,而不是var本身。

It's not possible to get the name of the var used in an outside scope within a function - the function only receives a the value passed as a parameter at runtime, not the var itself.

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

The only thing you could potentially do is use macros instead of functions at each level. This allows you to pass the var itself through the different macros at compile time:

(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 <<

这是非常丑陋的 - 你肯定不想用宏编写所有的代码获得此功能!它可能有意义,虽然在一些特殊的情况下,例如。如果您正在创建某种基于宏的DSL。

This is pretty ugly - you certainly don't want to be writing all of your code with macros just to get this feature! It might make sense though in some specialised circumstances, e.g. if you are creating some kind of macro-based DSL.

这篇关于如何获取参数的名称在Clojure?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆