K Combinator in Tcl

比如,用list模拟 Stack 的 pop 操作。

# stack pop
set stack [list 1 2 3]
set stack [lreplace $stack 0 0]

根据Tcl的内部实现机制:

  1. Tcl内部通过引用计数进行内存管理
  2. 变量$stack作为参数传递给lreplace时,其引用计数会 +1
  3. 通常lreplace在修改$stack的值之前需要先复制一份其内容
  4. lreplace针对$stack引用计数为1的情况不进行内容复制
  5. 要是可以在$stack变量传递给lreplace之前减少它的引用计数就好了

于是人们想到下面这种操作:

# stack pop
set stack [list 1 2 3]
set stack [lreplace \
    [lindex 
       [list $stack [set stack ""]] \
    0] \
0 0]

关键的地方是set stack ""减少(抵消)了对变量$stack的引用。

proc K {x args} {
    return $x
}

# stack pop
set stack [list 1 2 3]
set stack [lreplace [K $stack [set stack ""]] 0 0]
# stack pop
set stack [list 1 2 3]
set stack [lreplace $stack[set stack ""] 0 0]

参考资料