我有兴趣尝试文学编程。然而,我经常会笼统地陈述要求,但后来才给出异常(exception)情况。
例如,在一个部分中,它会说类似“上课期间学生不得进入走廊”之类的内容。
但是稍后会有这样的部分,其中会提到“教师可以给学生一张大厅通行证,此时学生可以在上课时在大厅里。
”所以我希望能够在第一部分之后定义 allowedInTheHall
,以便不允许学生进入大厅,但在第二部分之后重新定义 allowedInTheHall
code> 以便它首先检查大厅通行证是否存在,如果缺少,则委托(delegate)回之前的定义。
所以我能想象这种工作的唯一方法是一种语言:
- 您可以根据以前的定义重新定义方法/函数/子例程
- 即使调用者是在被调用者的最新重新定义之前定义的,也只会调用最新版本的函数(我相信这称为“late binding ”)。
那么哪些语言满足支持这些标准?
PS-我的动机是我正在处理现有的需求(在我的例子中是游戏规则),并且我想将我的代码嵌入到现有的规则中,以便代码遵循人们已经熟悉的规则的结构。我认为在执行合法契约(Contract)时也会出现这种情况。
最佳答案
好吧,回答直接问题,
you can redefine a method/function/subroutine in terms of it's previous definition
...基本上任何语言,只要它支持两个功能:
- 可以保存函数值的可变变量
- 某种闭包形成运算符,实际上相当于创建新函数值的能力
所以你不能在 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/