literate-programming - 您可以用哪些语言重新定义方法/函数本身?

标签 literate-programming

我有兴趣尝试文学编程。然而,我经常会笼统地陈述要求,但后来才给出异常(exception)情况。

例如,在一个部分中,它会说类似“上课期间学生不得进入走廊”之类的内容。

但是稍后会有这样的部分,其中会提到“教师可以给学生一张大厅通行证,此时学生可以在上课时在大厅里。

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

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

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

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


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

最佳答案

好吧,回答直接问题,

you can redefine a method/function/subroutine in terms of it's previous definition

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

  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)

...或一大堆其他语言,因为这些确实是相当常见的功能。该操作(我认为通常称为“建议”)基本上类似于无处不在的 x = x + 1,只不过该值是一个函数,而“加法”是额外操作的包装它创造了新的功能值(value)。

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

从技术上讲,您可以说这是后期绑定(bind)的一种形式 - 该函数是从变量中检索而不是直接链接 - 但通常该术语用于指代更加动态的行为,例如 JS 字段访问,该字段甚至可能不存在。在上述情况下,编译器至少可以确保变量 f1 存在,即使结果是保存 null 或其他内容,因此查找速度很快。

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


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

虽然这样设计,但程序的含义高度依赖于以特定顺序读取语句。这是一本非常适合机器操作的系列说明...与其说是一本引用书,不如说是一本引用书。

关于literate-programming - 您可以用哪些语言重新定义方法/函数本身?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23312055/

相关文章:

scheme - 文学编程的直觉动机?

java - 帮助更好地解析 Java 中字符串中的数字

node.js - 如何从 Express 路由映射中自动生成 API 文档?

html - 使用 knitr 设置 HTML 元元素

java - Java Maven 项目的 Marginalia/Docco/etc?

python - 使用 Org–Babel 控制缩进

python - 为 python 编织

language-agnostic - 垂直空白的使用

python - 在 Windows 上用 Python 进行文学编程的最佳方法是什么?

literate-programming - 自然语言编程与文学编程