0

我正在寻找具有以下功能的数据结构或在 Clojure 中模拟它的方法(通过http://www.erlang.org/course/advanced.html#refs):

引用是具有两个属性的 erlang 对象:

它们可以由程序创建(使用 make_ref/0),并且可以比较它们是否相等。

Erlang 引用是唯一的,系统保证通过对 make_ref 的不同调用创建的两个引用永远不会匹配。保证不是 100% - 但与 >100% 相差很小:-)。

尤其是来自 Oz 语言的 Name 数据类型 (http://www.mozart-oz.org/documentation/tutorial/node3.html):

创建名称的唯一方法是调用过程 {NewName X},其中 X 被分配 >一个保证在全球范围内唯一的新名称。姓名不能伪造或印刷。

虽然“不可伪造”的值听起来很可疑,尤其是在像 Clojure 这样的动态语言中,这正是我要寻找的。Van Roy 在 CTM 中使用此功能来创建所谓的“安全数据结构”,然后在代码中用于在受信任实体之间共享的安全令牌:

declare NewWrapper in
proc {NewWrapper ?Wrap ?Unwrap} 
    Key={NewName} 
in 
    fun {Wrap X} 
            fun {$ K} if K==Key then X end end
    end 
    fun {Unwrap C} 
            {C Key}
    end 
end

% A secure declarative unbundled Stack
declare NewStack Push Pop IsEmpty in
local Wrap Unwrap in
    {NewWrapper Wrap Unwrap}
    fun {NewStack} {Wrap nil} end
    fun {Push S E} {Wrap E|{Unwrap S}} end
    fun {Pop S E}
        case {Unwrap S} of X|S1 then E=X  {Wrap S1} end
    end
    fun {IsEmpty S} {Unwrap S}==nil end
end

可以在 Clojure 中模拟这种行为吗?这样我可以保证,例如,当且仅当我授予他令牌时,程序员才能解开数据结构。我知道它可能是不安全的,但我想找到在功能上与 Van Roy 相同的解决方案,并且至少很难被程序员规避。

下一个要求是基于纯 Clojure 而不是 JVM 魔术 - 所以没有“token = new Object()”等。例如,函数值看起来像一个很好的候选者,因为 AFAIK after (defn f [] nil) then (identical ? fx) 仅在 x=f 时计算为真,并且 f 不像函数式语言中的其他构造那样受到内存优化的影响(或者是吗?)。但是,这种方法可能会产生我不知道的进一步后果。上面示例中的 {NewName} 是否可以只替换为新的匿名函数(提供非分布式环境)?

4

1 回答 1

6

gensym保证产生可用于命名事物的唯一符号。

user> (gensym 'token)
token3783
user> (gensym 'token)
token3788
user> (gensym 'token)
token3793
user> (gensym 'token)
user> (def mine (gensym 'token))
#'user/mine
user> (def yours (gensym 'token))
#'user/yours
user> (= mine yours)
false
user> (= mine mine)
true
于 2012-04-26T00:19:51.390 回答