2017-03-03 24 views
1
  1. 我不禁注意到,笔者更喜欢叫(first options)多次超过缓存结果:关于defmulti的来源问题

    [docstring (if (string? (first options)) 
           (first options) 
           nil) 
    options  (if (string? (first options)) 
           (next options) 
           options) 
    m   (if (map? (first options)) 
           (first options) 
           {}) 
    options  (if (map? (first options)) 
           (next options) 
           options) 
    ...] 
    

我认为这是确定(以性能条款),因为它定义了一个将在编译期间执行的宏?

  1. 我还不确定是否理解调用宏的评估过程。以(defmulti ...)为例,纠正我,如果我错了:在编译过程中,宏是扩展,其中结果是调用特殊的let窗体,这反过来又翻译成字节码。那又怎么样?

  2. 假装我们定义一个FN,而不是一个宏观的,是值得引入一个额外的符号缓存(first options)结果:

    [f   (first options) 
    docstring (if (string? f) 
           f 
           nil) 
    options  (if (string? f) 
           (next options) 
           options) 
    f   (first options) 
    m   (if (map? f) 
           f 
           {}) 
    options  (if (map? f) 
           (next options) 
           options) 
    ...] 
    
  3. 究竟意味着什么,一个变种hasRoot?什么是Unbound

回答

1
  1. 是,呼吁first快。可变参数表示为一个序列,具体来说是一个clojure.lang.ArraySeq(至少要等到一定数量的参数)。

    user=> ((fn [& args] (type args)) 1 2 3) 
    clojure.lang.ArraySeq 
    

    first()ArraySeq的实施是一个阵列查找

    public Object first(){ 
        if(array != null) 
         return array[i]; 
        return null; 
    } 
    

    https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ArraySeq.java#L69

  2. 然后字节码然后被装载到JVM并执行。

  3. 我怀疑这会有所作为。

  4. var可以具有线程语言环境绑定,这意味着每个线程都可以看到不同的值。根绑定是var初始化的值。线程区域设置绑定不会压缩根绑定,它只是遮蔽它。 Unbound是针对没有根绑定创建的变量的实现优化。

    查看clojure.core/binding了解如何设置线程区域设置值。