Clojure如何解析名称?

时间:2012-10-26 17:34:03

标签: clojure

当我在Clojure中编写这样的函数调用(my-function [a b c])时。 Clojure如何找到我的功能?它是否从全局/每个命名空间符号表执行查找?

我假设符号表是作为哈希表实现的,它为查找提供了O(1)时间复杂度。它还需要将函数名称作为字符串与表中的符号进行比较,该符号应该花费O(n)时间(n是符号的长度)。这意味着符号越长,名称解析就越慢。这是对的吗?

3 个答案:

答案 0 :(得分:3)

  

Clojure是一种编译语言 - 它直接编译为JVM字节码,   但仍然是完全动态的。

- 从http://clojure.org/

的首页开始

编译意味着符号已经预先存在,因此关于函数名长度的第二个语句仅在编译时才为真。此外,如果您担心每个CPU周期,JVM / CLR语言将因各种原因而不是您的朋友。

答案 1 :(得分:3)

符号使用固定字符串,因此它们与==进行比较,而不是与.equals进行比较。所以即使你说的部分是O(n)也是O(1)。然而,它几乎不重要,因为所有这些查找(a)无论如何都非常快,并且(b)在编译时发生,而不是运行时。一旦运行程序,所有函数调用都已解析为指针解引用或其类似物。

答案 2 :(得分:2)

命名空间确实表现为地图,您可以使用ns-map函数直接查看它们:

autotestbed.core> (pprint (take 5 (ns-map *ns*)))
nil
([sorted-map                                                                                               
  #<Var@6899a7ce:                                                                                          
    #<core$sorted_map clojure.core$sorted_map@5875c014>>]                                                  
 [read-line                                                                                                
  #<Var@1de9e86e: #<core$read_line clojure.core$read_line@57c00972>>]                                      
 [re-pattern                                                                                               
  #<Var@74064c7b:                                                                                          
    #<core$re_pattern clojure.core$re_pattern@37d02427>>]                                                  
 [keyword?                                                                                                 
  #<Var@4798088a:                                                                                          
    #<core$keyword_QMARK_ clojure.core$keyword_QMARK_@630b813f>>]                                          
 [hta-deploy-cmd                                                                                           
  #<Var@7a7bce95:                                                                                          
    #<core$hta_deploy_cmd autotestbed.core$hta_deploy_cmd@6a6a782d>>])

更具体地说,他们将变量映射到对象。

如果你确实想要在它的var中查找函数,那么更改会立即通过你的程序传播,你可以在编译时调用var而不是var中包含的函数,这会导致查找每个函数拨打:

(#'foo 4) looks the function up in the var every time
(foo 4) looks it up in the map once when it's compiled.