2

我有兴趣尝试文学编程。但是,我经常会在一般情况下说明要求,但稍后会给出例外情况。

例如,在一个部分中,它会说学生在上课期间不允许进入走廊。

但是稍后会有一个部分,上面写着老师可以给学生一张大厅通行证,此时学生可能在上课时在大厅里。

所以我希望能够allowedInTheHall在第一部分之后定义,这样它就不允许学生进入大厅,但是在第二部分之后重新定义allowedInTheHall,以便它首先检查是否存在大厅通行证,以及是否丢失然后委托回之前的定义。

所以我能想象这种工作的唯一方法是一种语言:

  1. 您可以根据之前的定义重新定义方法/函数/子例程
  2. 即使调用者是在被调用者的最新重新定义之前定义的,也只有最新版本的函数被调用(我相信这被称为“后期绑定”)。

那么哪些语言满足支持这些标准呢?


PS-我的动机是我正在处理现有的需求(在我的案例中是游戏规则),我想将我的代码嵌入到现有的规则中,以便代码遵循人们已经熟悉的规则结构。我认为这种情况也会在尝试执行法律合同时出现。

4

1 回答 1

3

好回答直接的问题,

您可以根据之前的定义重新定义方法/函数/子例程

...基本上任何语言,只要它支持两个功能:

  1. 可以保存函数值的可变变量
  2. 某种闭包形成运算符,它实际上相当于创建新函数值的能力

所以你不能在 C 中做到这一点,因为即使它允许变量存储函数指针,C 中也没有可以计算新函数值的操作;而且你不能在 Haskell 中这样做,因为 Haskell 不允许你在定义变量后对其进行变异。但是你可以在例如 JavaScript 中做到这一点:

var f1 = function(x) {
    console.log("first version got " + x);
};

function around(f, before, after) {
    return function() {
        before(); f.apply(null, arguments); after();
    };
}

f1 = around(f1,
            function(){console.log("added before");},
            function(){console.log("added after");});
f1(12);

或方案:

(define (f1 x) (display "first version got ") (display x) (newline))
(define (around f before after)
   (lambda x  
      (before) (apply f x) (after) ))
(set! f1 (around
  f1
  (lambda () (display "added before") (newline))
  (lambda () (display "added after") (newline))))
(f1 12)

...或一大堆其他语言,因为这些确实是相当常见的功能。操作(我认为通常称为“advice”)基本上类似于 ubiquitous x = x + 1,除了 value 是一个函数,而“addition”是围绕它的额外操作的包装,以创建一个新的函数值。

这样做的原因是,通过将旧函数作为参数(到around,或只是 alet或其他)传递,新函数正在关闭它,通过本地范围的名称引用它;如果新函数引用全局名称,则旧值将丢失,新函数将递归。

从技术上讲,您可以说这是后期绑定的一种形式- 函数是从变量中检索而不是直接链接 - 但通常该术语用于指代更多动态行为,例如 JS 字段访问甚至可能实际上并不存在。在上述情况下,编译器至少可以确定变量 f1将存在,即使它被证明是持有null或其他东西,所以查找速度很快。

假设调用该名称的其他函数f1将按照您期望的方式工作。如果您在调用var f3 = f1;之前这样做,则around定义为调用的函数f3不会受到影响;类似地,f1通过将​​其作为参数或其他东西传入而获得的对象。基本词汇范围规则适用。如果你希望这些功能也受到影响,你可以使用 PicoLisp 之类的东西来完成它......但你也在做一些你可能不应该做的事情(这不再是任何类型的绑定:这是 a 的直接突变函数对象)。


除此之外,我不确定这是否符合文学编程的精神——或者就此而言,是一个描述规则的程序。规则是否应该根据您阅读本书的程度或阅读章节的顺序而改变识字程序不是-就像一段文本通常意味着一件事(您可能不理解它,但它的含义是固定的),无论您是先阅读还是最后阅读它,真正的识字程序中的声明也应该如此,对? 一个人通常不会像小说一样从头到尾阅读参考资料——比如一本规则书。

尽管这样设计,但程序的含义高度依赖于以特定顺序阅读语句。这是一个非常机器友好的系列指令......与其说是参考书。

于 2014-04-27T22:55:47.430 回答