【问题标题】:How does Clojure resolve a name?Clojure 如何解析名称?
【发布时间】:2012-10-26 17:34:02
【问题描述】:

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

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

【问题讨论】:

    标签: clojure


    【解决方案1】:

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

    -来自http://clojure.org/的首页

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        命名空间确实像地图一样,您可以直接使用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.   
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-29
          • 2011-02-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多