您可以用哪种语言重新定义方法/功能?

时间:2014-04-26 14:09:47

标签: literate-programming

我对尝试识字编程很感兴趣。但是,我经常认为这些要求是在一般情况下说明的,但是后来会有例外情况。

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

但后来会有一段文字说教师可以给学生一个大厅通行证,当学生在课堂上时,学生可能会在大厅里。

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

因此,我能想象这种工作的唯一方法是:

  1. 您可以根据之前的定义重新定义方法/功能/子程序
  2. 即使调用者是在被调用者的最新重新定义之前定义的,也只调用了函数的最新版本(我相信这被称为" late binding")。
  3. 哪种语言符合这些标准?


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

1 个答案:

答案 0 :(得分:3)

很好地回答直接问题,

  

你可以根据它之前的定义重新定义方法/功能/子程序

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

  1. 可以保存函数值的可变变量
  2. 某种闭合形成算子,有效地构成了创建新函数值的能力
  3. 所以你不能在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);
    

    或Scheme:

    (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)
    

    ...或许多其他语言,因为这些是非常常见的功能。操作(我认为通常称为"建议")基本上类似于无处不在的x = x + 1,除了值是一个函数和"添加"围绕它进行额外操作以创建新的功能值。

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

    从技术上讲,你可以说这是后期绑定的一个表单 - 该函数是从变量中检索而不是直接链接 - 但通常该术语用于表示更加动态的行为,例如JS字段访问,其中字段甚至可能实际上不存在。在上面的例子中,编译器至少可以确定变量 f1将存在,即使结果是保持null或其他东西,所以查找速度很快。

    调用f1的其他函数将以您期望的方式工作,假设它们通过该名称引用它。如果您在var f3 = f1;调用之前around f3,则定义为调用f1的函数不会受到影响;类似的对象通过将其作为参数或其他内容传入而获得{{1}}。基本词法范围规则适用。如果你也希望这些功能受到影响,那么可以使用像PicoLisp这样的东西将它拉下来...但是你也做了一些你可能不应该做的事情(那&#39) ;不再是任何类型的约束:这是函数对象的直接变异。)


    除此之外,我不确定这完全符合文学编程的精神 - 或者就此而言,是一个描述规则的程序。规则应该更改取决于您通过书的距离或您阅读章节的顺序?识字程序不是 - 正如一段文字通常意味着一件事(你可能不理解它,但它的含义是固定的)无论你是先读还是最后,所以应该在一个真正的文化程序中声明, 对?人们通常不会像小说那样从封面到封面阅读参考书 - 例如规则书。

    虽然这样设计,程序的含义高度依赖于以一个特定顺序读取语句。它非常适用于机器友好的系列指令......而不是参考书。