Question

I wrote the following function as a part of a jQuery plugin I am developing:

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

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

    return this;
};

After testing a highly recursive function that heavily depended on .append2, I optimized .append2 to:

$.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;
};

While this code is more efficient in terms of speed, it still left me unsatisfied. I have, essentially, defined the same function twice:

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

And I wondered if there is any language that lets me defined the function only once as:

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

And then operate on it by replacing the argument to $this.append from value to callback(key, value). (And, no, not by manipulating strings. By manipulating the function itself.)

Is there any such programming language?

Was it helpful?

Solution

Any homoiconic language lets you do this do some degree or another. All of the Lisp languages let you build functions procedurally out of bits and pieces and then invoke them as normally. The Io language is rare in that I believe it will let you go the other way: given a function, you can pull apart its source code and manipulate it.

OTHER TIPS

Hm... the answer is kind of yes and kind of no. If you want to modify the function itself, then I don't believe that's possible, because the function is just binary data. But you might want to look into Scheme: everything in Scheme is a "list" (including the body of a function), and as long as you haven't evaluated the body, you can change it as will. Take a look at eval for more info.

Many languages have reflection to the level that they allow replacement of arguments and such (including Java, C#, Smalltalk, and Ruby, I believe). However, there are separation of concerns issues when you have one part of the program mutating another. You could put a default value for callback that just returns value; that would be a more elegant solution that would remove the conditional expression.

The crux of the matter is this expression:

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

In Mathematica, you could (roughly) re-express this as follows:

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

... bearing in mind that this and undefined have no special meaning in Mathematica. Without getting into details, this expression first defines a function that unconditionally calls callback. It then transforms the body of that function to simply use value if an only if callback has the value undefined. In idiomatic Mathematica there are easier ways to handle such a simple case, but it illustrates the requested capability and is a useful tool in more complex situations.

As for your desire to "plug in a function between the caller and callee":

have a look at advice in, say, (Emacs) Lisp, and at the concept of aspect-oriented programming.

If I'm understanding what you're looking for, possibly functors provide a solution. By manipulating the functor state/parameters, you can achieve the behaviour you describe, by changing the object/information the function operates on.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top