仿射宽松线性类型的想法能否在无类型设置中实现以实现安全突变?

问题描述

如果我可以不时在 ArrayMap 上使用安全的就地破坏性更新,那将会很有用。线性类型是一种通过将值的消耗限制为 exactly once 语义来允许安全突变的技术。虽然似乎不可能在 Javascript 中实现 exactly once,但这里有一个宽松的最多一次变体的实现,它对应于仿射类型:

class LinearProxy {
  constructor() {
    this.once = false;
  }

  get(o,k) {
    if (this.once)
      throw new TypeError("non-linear type usage");

    else this.once = true;

    if (k === "run")
      return once(f => {
        const r = f(o);

        if (r === o)
          throw new TypeError("non-linear type usage");

        else return r;
      });

    return o[k];
  }

  set(o,k,v) {
    if (this.once)
      throw new TypeError("non-linear type usage");

    o[k] = v;
    return true;
  }
}

const linear = o => new Proxy(o,new LinearProxy());

const once = f => {
  let called = false;

  return x => {
    if (called)
      throw new TypeError("non-linear type usage");

    else {
      called = true;
      return f(x);
    }
  };
};

const run = f => tx =>
  tx["run"] (f);
  
const id = x => x;
const last = xs => xs[xs.length - 1];
const dup = xs => [...xs,...xs];

const xs = linear([1,2,3]),ys = linear([1,zs = linear([1,3]);

xs[3] = 4;
xs[4] = 5;

console.log(
  "run(last) (xs):",run(last) (xs)); // 5

try {run(last) (xs)}
catch(e) {console.log("run(last) (xs):",e.message)} // type error (A)

try {const x = xs[4]}
catch(e) {console.log("x = xs[4]:",e.message)} // type error (A)

try {xs[0] = 11}
catch(e) {console.log("xs[0] = 11:",e.message)} // type error (B)

try {run(id) (ys)}
catch(e) {console.log("run(id) (ys):",e.message)} // type error (C)

console.log(run(dup) (zs)); // [1,3,1,3] (D)

曾经使用过的线性类型的后续读访问 (A) 和写访问 (B) 会引发类型错误。尝试立即访问线性类型的引用 (C) 也会引发类型错误。后者只是一个简单的检查,以防止意外返回引用。人们很容易绕过它,所以我们必须依靠这种情况的约定。

然而,D 不是仿射的,因为参数被消耗了两次。非线性使用发生在函数范围内这一事实是否意味着它仍然(相对)安全?有没有更聪明的方法在 Javascript 中实现线性类型?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...