是否有任何编程语言将功能视为可以操作的数据结构?

时间:2011-02-27 06:10:32

标签: functional-programming programming-languages language-features code-injection homoiconicity

我将以下函数编写为我正在开发的jQuery插件的一部分:

$.fn.append2 = function(collection, callback) {
    var $this = this;

    $.each(collection, function(key, value) {
        $this.append(callback ? callback(key, value) : value);
    });

    return this;
};

在测试了一个高度依赖.append2的高度递归函数后,我将.append2优化为:

$.fn.append2 = function(collection, callback) {
    var $this = this;

    $.each(collection, callback
        ? function(key, value) { $this.append(callback(key,value)); }
        : function(key, value) { $this.append(value); }
    );

    return this;
};

虽然这段代码在速度方面更有效,但仍然让我不满意。基本上,我已经两次定义了相同的函数:

function(key, value) { $this.append(callback(key,value)); }
function(key, value) { $this.append(value); }

我想知道是否有任何语言可以让我只将该功能定义为:

function(key, value) { $this.append(value); }

然后通过将$this.append的参数从value替换为callback(key, value)来对其进行操作。 (并且,不,不是通过操纵字符串。通过操纵函数本身。)

有没有这样的编程语言?

6 个答案:

答案 0 :(得分:5)

任何homoiconic语言都可以让您在某种程度上做到这一点。所有的Lisp语言都允许您从程序上逐个地构建函数,然后像往常一样调用它们。 Io语言是罕见的,我相信它会让你走另一条路:给定一个函数you can pull apart its source code and manipulate it

答案 1 :(得分:4)

嗯......答案是肯定的,有点不。如果你想修改函数本身,那么我不相信这是可能的,因为函数只是二进制数据。但你可能想看一下Scheme: Scheme中的所有是一个“列表”(包括一个函数的主体),只要你没有评估正文,你就可以把它改成将。请查看eval以获取更多信息。

答案 2 :(得分:2)

许多语言都反映了它们允许替换参数等级(包括Java,C#,Smalltalk和Ruby,我相信)。但是,当程序的一部分变异时,问题就会分开。您可以为callback设置一个只返回value的默认值;这将是一个更优雅的解决方案,将删除条件表达式。

答案 3 :(得分:1)

问题的症结在于:

callback
    ? function(key, value) { $this.append(callback(key,value)); }
    : function(key, value) { $this.append(value); }

在Mathematica中,你可以(大致)重新表达如下:

Function[{key, value}, Append[this, callback[key, value]]] /.
  HoldPattern[callback[_, v_]] /; callback === undefined :> v

...请记住,thisundefined在Mathematica中没有特殊含义。在没有详细介绍的情况下,该表达式首先定义了一个无条件调用callback的函数。然后,只有当value具有值callback时,它才会将该函数的主体转换为仅使用undefined。在惯用的Mathematica中,有更简单的方法来处理这样一个简单的案例,但它说明了所要求的能力,并且在更复杂的情况下是一个有用的工具。

答案 4 :(得分:1)

至于你对"plug in a function between the caller and callee"的渴望:

看看({Emacs)Lisp中的advice,以及面向方面编程的概念。

答案 5 :(得分:0)

如果我理解你在寻找什么,可能会functors提供解决方案。通过操纵仿函数状态/参数,您可以通过更改函数操作的对象/信息来实现您描述的行为。

相关问题