Is it possible to define an infix function?

Is it possible to define my own infix function / operator in CoffeeScript (or in pure JavaScript)? For example, I want to call

a foo b 

or

 a `foo` b 

instead

 a.foo b 

or, when foo is a global function,

 foo a, b 

Is there any way to do this?

+7
source share
5 answers

ES6 allows very efficient use of the Haskell / Lambda calculus method.

Given the multiplication function:

 const multiply = a => b => (a * b) 

You can define the doubling function using a partial application (you do not take into account one parameter):

 const double = multiply (2) 

And you can compose a dual function by creating a quad function:

 const compose = (f, g) => x => f(g(x)) const quadruple = compose (double, double) 

But really, what if you prefer infix notation? As Steve Ladavich noted, you need to expand the prototype.

But I think this can be done more elegantly using array notation instead of dot notation.

The official symbol is used to compose the "" functions:

 Function.prototype['∘'] = function(f){ return x => this(f(x)) } const multiply = a => b => (a * b) const double = multiply (2) const doublethreetimes = (double) ['∘'] (double) ['∘'] (double) console.log(doublethreetimes(3)); 
+8
source

Actually, adding this as an answer: no , this is impossible.

This is not possible in vanilla JS .

This is not possible in CoffeeScript .

+3
source

You can with sweet.js. Cm:

Sweet.js extends Javascript with macros.

It acts as a preprocessor.

+3
source

This is definitely not infix notation, but it is close to : /

 let plus = function(a,b){return a+b}; let a = 3; let b = 5; let c = a._(plus).b // 8 

I don’t think that anyone really would like to use this “notation”, as it’s pretty ugly, but I think that maybe there are some settings that can be made to make them look different or better (maybe using this answer here to “call the function” without parentheses).

Infix function

 // Add to prototype so that it always there for you Object.prototype._ = function(binaryOperator){ // The first operand is captured in the this keyword let operand1 = this; // Use a proxy to capture the second operand with "get" // Note that the first operand and the applied function // are stored in the get function closure, since operand2 // is just a string, for eval(operand2) to be in scope, // the value for operand2 must be defined globally return new Proxy({},{ get: function(obj, operand2){ return binaryOperator(operand1, eval(operand2)) } }) } 

Also note that the second operand is passed as a string and evaluated using eval to get its value. Because of this, I think that the code will burst at any time when the value of the operand (aka “b”) is not defined globally.

+2
source

Javascript does not include infix notation for functions or sections for a partial application. But it comes with higher order functions that allow us to do almost everything:

 // applicator for infix notation const $ = (x, f, y) => f(x) (y); // for left section const $_ = (x, f) => f(x); // for right section const _$ = (f, y) => x => f(x) (y); // non-commutative operator function const sub = x => y => x - y; // application console.log( $(2, sub, 3), // -1 $_(2, sub) (3), // -1 _$(sub, 3) (2) // -1 ); 

As you can see, I prefer the visual names $ , $_ and _$ for text in this case. This is the best you can get - at least with pure Javascript / ES2015.

+1
source

All Articles