Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting reference to the JavaScript Function object behind an operator

Here is a lisp procedure that simply adds 'a' to the absolute value of 'b':

(define (a-plus-abs-b a b)
  ((if (> b 0) + -) a b))

I think this is beautiful, and I am trying to find the best way of writing this in JavaScript. But my JavaScript code is not beautiful:

var plus = function(a,b) {
    return a + b;
};

var minus = function(a,b) {
    return a - b;
};

var aPlusAbsB = function(a,b) {
    return (b > 0 ? plus : minus)(a,b);
}

The main problem is that I cannot use the + and - symbols as references to the functions they really represent as I can with lisp. Can anyone come up with a more graceful way of doing something like this, or have I hit a language boundary?

Obviously, I can do this:

var aPlusAbsB = function(a,b) {
    return a + Math.abs(b);
}

, but this is more of a thought experiment than a pragmatic question.

Is there any way I can get reference to the core functions in the JavaScript language just as if they were user-defined?

like image 898
Matthew Taylor Avatar asked Mar 09 '10 23:03

Matthew Taylor


People also ask

How do you reference a function in JavaScript?

In Pass by Reference, a function is called by directly passing the reference/address of the variable as the argument. Changing the argument inside the function affects the variable passed from outside the function. In Javascript objects and arrays are passed by reference.

How will you pass object to the function by reference?

Then we call the modify() function using call by the reference method. Because of this, the modification also reflects in the actual parameter. In the main() function, the amount paid after calling modify() function is 2100. So, the value of the object is changed by the modify() function due to pass by reference.

Can you pass object to JavaScript function?

We can pass an object to a JavaScript function, but the arguments must have the same names as the Object property names.

Does JavaScript copy object by reference?

Passing variables to functions is working the same way like copying for the same data types in most of the languages. In JavaScript primitive types are copied and passed by value and objects are copied and passed by reference value.


4 Answers

It's a very cool idea - would be great for evaluating mathematical expressions but you simply can't set an operator (or the logic behind it) to a variable. Sorry :-)

like image 153
Andy E Avatar answered Nov 04 '22 00:11

Andy E


It depends on what aspects of the lisp implementation you find particularly beautiful. I'll propose another version of your suggestion that I think ends up a little closer to your lisp definition's syntax by doing some dirty things.

// Give ourselves + and - functions to level the playing field with lisp.
Number.prototype['+'] = function(x)this+x;
Number.prototype['-'] = function(x)this-x;

// Now we can have some fun.
var aPlusAbsB = function(a,b) a [b > 0 ? '+' : '-'] (b);

// Some other notable language barrier differences, but not too dissimilar?
// (define (a-plus-abs-b a b) ((if (> b 0) + -) a b))
like image 34
Kevin Vaughan Avatar answered Nov 04 '22 01:11

Kevin Vaughan


Though not as elegant as the LISP code, you could create a function dynamically that acts like an operator (on numbers), but it's not.

function op(o) {
    return new Function("a", "b", "return a " + o + " b");
}


function aPlusAbsB(a, b) {
    return (b > 0 ? op('+') : op('-'))(a, b);
}

Additionally, we can hide the complexity of generating these inside an if wrapper, but that's the closest I can get :)

function is(expr, op1, op2) {
    return expr ? op(op1) : op(op2);
}

function aPlusAbsB(a, b) {
    return (is(b > 0, '+', '-')(a, b));
}
like image 22
Anurag Avatar answered Nov 04 '22 00:11

Anurag


I think everyone else got here first, but JS is slightly less purely functional than lisp, operators are not functions or objects, but operators.

like image 43
ysaw Avatar answered Nov 04 '22 00:11

ysaw