All Projects → rbuckton → Proposal Functional Operators

rbuckton / Proposal Functional Operators

Licence: bsd-3-clause
Proposal for the additon of functional operators to ECMAScript

Labels

Proposal to add functional operators to ECMAScript

This strawman seeks to define the possible syntax and semantics for functional operators for ECMAScript.

Status

Stage: 0
Champion: None identified

For more information see the TC39 proposal process.

Proposal

A "functional operator" is an operator-like sigil that acts like a function at runtime. In addition, a "binary functional operator" allows either the first or second operand to be fixed.

Most functional operators are written as {<<op>>} where <<op>> is one of the binary or unary operator punctuators, or one of the instanceof, in, or typeof keywords. In cases where an operator has an overloaded definition between both binary and unary forms, the unary versions of the operator have the form {~<<op>>}.

Each functional operator can be expressed as existing JavaScript given the following syntactic conversions:

// exponentiation operator function
{**}                // (a, b) => a ** b

// multiplicative operator function
{*}                 // (a, b) => a * b
{/}                 // (a, b) => a / b
{%}                 // (a, b) => a % b

// additive operator function
{+}                 // (a, b) => a + b
{-}                 // (a, b) => a - b

// shift operator function
{<<}                // (a, b) => a << b
{>>}                // (a, b) => a >> b
{>>>}               // (a, b) => a >>> b

// relational operator function
{<}                 // (a, b) => a < b
{<=}                // (a, b) => a <= b
{>}                 // (a, b) => a > b
{>=}                // (a, b) => a >= b
{instanceof}        // (a, b) => a instanceof b
{in}                // (a, b) => a in b

// equality operator function
{==}                // (a, b) => a == b
{===}               // (a, b) => a === b
{!=}                // (a, b) => a != b
{!==}               // (a, b) => a !== b

// bitwise operator function
{&}                 // (a, b) => a & b
{|}                 // (a, b) => a | b
{^}                 // (a, b) => a ^ b

// logical operator function
{&&}                // (a, b) => a && b
{||}                // (a, b) => a || b

// unary additive operator function
{~+}                // (a) => +a
{~-}                // (a) => -a

// unary bitwise operator function
{~}                 // (a) => ~a

// unary logical operator function
{!}                 // (a) => !a

// other unary operator function
{typeof}            // (a) => typeof a

Each functional operator is a frozen function that exists at most once per realm. This can help to cut down on the number of function objects allocated within a given program.

Fixed arguments

In addition, binary functional operators may fix either the first or second operand:

// fixed arguments
{+} 1               // (a) => a + 1

2 {*}               // (a) => 2 * a

In these cases, the function returned is a unique frozen function object.

Examples

const sum = ar.reduce({+});

const result = numbers 
  .map({*} 2)  // scale
  .map({+} 5)  // offset

const strings = numbers
  .map({+} "");

const numbers = strings
  .map({~+});

const positive = numbers
  .filter({>} 0);

const halves = numbers
  .map({/} 2); // no need for regexp lookahead/cover grammar

Prior Art

  • F# symbolic operators.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].