Giter Club home page Giter Club logo

proposal-math-extensions's Introduction

Math Extensions Proposal

Champion

Rick Waldron

Status

This proposal is currently stage 1 of the TC39 process.

Motivation

These functions exist in many, many JS libraries either hand rolled or via many modules on npm. Providing them as built-ins serves to pave cow path. Implementations and naming is inconsistent. Several other languages offer these as built-ins.

Java

Python

Racket

Rust

Questions

  • Math.map
    • Is it...
      • Math.scale <-- this
      • Math.map
      • Math.remap
    • Should there be a corresponding Math.fmap? (ie. https://tc39.github.io/ecma262/#sec-math.fround, Step 3 & 4 convert result to IEEE 754-2008 binary32 (using roundTiesToEven), then to IEEE 754-2008 binary64).
  • Math.constrain
    • Is it...
      • Math.constrain
      • Math.clamp

Polyfills

proposal-math-extensions's People

Contributors

rwaldron avatar zloirock avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

proposal-math-extensions's Issues

Math.exp2

JS Math can probably use a few more functions from native C code, such as Math.exp2.

JS would also be better for scientific types of calculations with some more functions useful to that domain.
I don't have anything particular in mind for these two categories, but maybe I'll come by and drop by a few that might be helpful.

Math.scale should work for "negative" output scales too

The current (as of 2016-09-29) implementation of Math.scale does not work if the output scale is "negative"

Math.scale(0.6, 0,1, 0,10);  // <= should return  6 [0...1] => [0...10]
Math.scale(0.6, 0,1, 10,0);  // <= should return  4 [0...1] => [10...0]
Math.scale(0.6, 0,1, 0,-10); // <= should return -6 [0...1] => [0...-10]

I also think this "flipping of scales" should maybe mentioned specifically in the reference / manual

A working polyfill seems to be this:

defineMath("scale", function scale(value, inMin, inMax, outMin, outMax)
{
  if ( arguments.length === 0 || Number.isNaN(value) ||
       Number.isNaN(inMin) || Number.isNaN(inMax) ||
       Number.isNaN(outMin) || Number.isNaN(outMax) )
  {
    return NaN;
  }

  if ( value === Infinity || value === -Infinity || (inMin == outMin && inMax == outMax) )
  {
    return value;
  }

  return outMin + ((value - inMin) / (inMax - inMin)) * (outMax - outMin);
});

Add Math.randomInteger

Generating random integers is a rather common procedure so it would be nice to have given that most people have probably used the suggested function from MDN.

Obviously this wouldn't be suitable for generating cryptographic-ally secure random integers as its limited by Math.random but it would be useful for non-secure use cases.

The proposed procedure would be as follows (based of the MDN code):

Math.randomInteger(max)

  1. Return `Math.randomInteger(0, max)

Math.randomInteger(min, max)

  1. If either argument is not an integer in the range Math.MIN_SAFE_INTEGER to Math.MAX_SAFE_INTEGER throw a RangeError
  2. If max <= min then throw a RangeError
  3. Let randomInteger be Math.floor(Math.random() * (max - min)) + min
  4. Return randomInteger

Questions:

  • Should values outside of the range Math.MIN_SAFE_INTEGER to Math.MAX_SAFE_INTEGER be allowed?
  • Should it be allowed to be called with floats within the range and turn them to ints like in the MDN function?
  • Should max be inclusive or exclusive?

[Suggestion] Methods to be added

Aside from the randomInteger from #8 and the Math.sum from #4, I think that including the methods below would help, especially when languages like Python, Matlab and Processing have them:

  • Math.clamp
Math.clamp = (low, x, high) => (x < low) ? low : ((x > high) ? high: x);
//Or using other methods
Math.clamp = (low, x, high) => Math.max(low, Math.min(x, high))
//Examples
Math.clamp(0, 5, 10); //5
Math.clamp(0, -1, 10); //0
Math.clamp(0, 42, 10); //10
  • Math.log which would allow the current Math.log to be more flexible without breaking it.
Math.log = (a, b = Math.E) => Math.log(a) / Math.log(b)
  • Math.range
Math.range = range = (...args) => {
 if (args.length === 1) { //Math.range(max)
   return range(0, 1, args[0])
 } else if (args.length === 2) { //Math.range(max, inc)
   return range(0, args[1], args[0])
 }
 
 let val = [],
   n = 0,
   [min, inc, max] = args;

 if (inc > 0) {
   for (let i = min; i <= max; i += inc) val[n++] = i
 } else {
   for (let i = min; i >= max; i -= inc) val[n++] = i
 }
 return val
};

// Examples
Math.range(5); // [0, 1, 2, 3, 4, 5]
Math.range(10, 2); // [0, 2, 4, 6, 8, 10]
Math.range(-1, .5, 1); // [-1, -0.5, 0, 0.5, 1]
  • Math.gcd
Math.gcd = (a, b) => b ? Math.gcd(b, a % b): Math.abs(a)
  • Math.lcm
Math.lcm = (a, b) => {
  let multiple = a;
  Math.range(a, 1, b).forEach((n) => multiple = (multiple * n) / gcd(multiple, n));
  return multiple;
}
  • Math.factorial or perhaps a syntactic sugar (like 5! or something not ambiguous)
Math.factorial = (a) => (a <= 1) ? a : a * Math.factorial(a - 1)
  • Math.combination/Math.choose
Math.combination = (a, b) => Math.factorial(a) / (Math.factorial(b) * Math.factorial(a - b))
  • Math.equivalent/Math.equiv/Math.approx
Math.equivalent = (a, b) => Math.round(a) === Math.round(b) || Math.floor(a) === Math.floor(b) || Math.ceil(a) === Math.floor(b) || Math.floor(a) === Math.ceil(b);

// Or
Math.equivalent = (a, b) => {
  let flatA = a | 0,
    flatB = b | 0,
    ceilA = a | 1,
    ceilB = b | 1;
  return Math.round(a) === Math.round(b) || flatA === flatB || ceilA === flatB || flatA === ceilB;
}

There are other methods I have in mind but the above would be a good start (e.g. Math.mean, Math.trimmedAverage).

Tuple methods

There are cases when devs need to "split" a scalar value into a vector (usually a 2-tuple). The most common are sgn_abs and div_rem, defined like so:

Math.divRem = (n, d) => [Math.trunc(n / d), n % d];

Math.signAbs = x => [Math.sign(x), Math.abs(x)];

(There may be more that I'm not aware of)

These are very useful when the calculations need to be reversible. sgn_abs is useful when implementing an nth-root finding algorithm. div_rem is useful when implementing other kinds of integer division (see #21).

The only problem I see with these, is that they don't return Numbers, so they break consistency with other methods. To solve this, they could be implemented as prototype methods instead:

Number.prototype.divRem = function(d) {return [Math.trunc(this / d), this % d]}

Number.prototype.sgnAbs = function() {return [Math.sign(this), Math.abs(this)]}

When the BigInt Math proposal gets to Stage 4, we can extend it like this:

BigInt.prototype.divRem = function(d) {return [this / d, this % d]}

BigInt.prototype.sgnAbs = function() {return [Math.sign(this), Math.abs(this)]}

Wrong names of RAD_PER_DEG and DEG_PER_RAD constants

Math.RAD_PER_DEG and Math.DEG_PER_RAD constants have invalid names in the current spec:

  • Math.RAD_PER_DEG is equal to 180 / PI, but must be equal PI / 180, because this constant means radians in one degree. Also Math.radians(degrees) must be computed as

    - 2. Let radians be (degrees × Math.DEG_PER_RAD).
    + 2. Let radians be (degrees × Math.RAD_PER_DEG).
  • Accordingly Math.DEG_PER_RAD must be equal 180 / PI, because it means number of degrees in one radian, and Math.degrees(radians) must be computed as:

    - 2. Let degrees be (radians × Math.RAD_PER_DEG).
    + 2. Let degrees be (radians × Math.DEG_PER_RAD).

Looks like this issue was introduced in the following commit b31aee6

alternatives to Math.radians and Math.degrees

I have found the following two functions to be applicable in more use cases (#5 (comment)) than the two proposed functions, Math.radians and Math.degrees

  • Math.toRadians( angle, perigon = 360 )
// `displacement` & `amplitude` may be in units of pixel for use with requestAnimationFrame
var displacement = amplitude * Math.cos( Math.toRadians( deltaTime, period ) );

// `displacement` & `amplitude` and/or `distance` & `wavelength` may be in units of pixel
var displacement = amplitude * Math.sin( Math.toRadians( distance, wavelength ) );

var radians = Math.toRadians( turns, 1 );
var radians = Math.toRadians( decimalDegrees ); // default perigon is 360
var radians = Math.toRadians( arcminutes + 60 * degrees, 60 * 360 );
var radians = Math.toRadians( arcseconds + 60 * ( arcminutes + 60 * degrees ), 60 * 60 * 360 );
var radians = Math.toRadians( gradians, 400 );
var radians = Math.toRadians( milliturns, 1000 );
var radians = Math.toRadians( binaryAngle, 256 );
  • Math.fromRadians( radians, perigon = 360 )
// e.g. CSS, electromagnetic coils and rotating objects
var turns = Math.fromRadians( radians, 1 );

// e.g. CSS, astronomical and geographic coordinates (latitude and longitude)
var decimalDegrees = Math.fromRadians( radians ); // default perigon is 360

// e.g. CSS, triangulation, surveying, mining, and geology
var gradians = Math.fromRadians( radians, 400 );

// e.g. measurement devices for artillery and satellite watching
var milliturns = Math.fromRadians( radians, 1000 );

// e.g. robotics, navigation, computer games, and digital sensors
var binaryAngle = Math.fromRadians( radians, 256 );

As latitude and longitude are often expressed as decimal degrees in the intervals [−90°, +90°] and [−180°, +180°] respectively, in my implementation I choose to ensure all return values are in an interval [-perigon/2, +perigon/2] (similar to Math.asin and Math.atan). This reduces surprises and may help maintain precision across multiple floating-point operations. This convention equates an angle in radians with the directed minor arc from one point to another on the unit circle, which is useful in some distance calculations.

With a suitable modulo operation (#21), it is simple for calling code to convert from [-perigon/2, +perigon/2] to [0, perigon] if needed

var radians        = Math.mod( Math.toRadians( angle, perigon ), 2 * Math.PI );
var angle          = Math.mod( Math.fromRadians( radians, perigon ), perigon );
var decimalDegrees = Math.mod( Math.fromRadians( radians ), 360 );

I have found that some JavaScript developers do not know the built-in trigonometry functions operate on angles expressed in radians. They assume, perhaps due to previous experience with calculators defaulting to DEG mode, that the following are valid

var opposite = hypotenuse * Math.sin( 45 /* degrees */ );
var degrees = Math.asin( opposite / hypotenuse );

Perhaps the presence of Math.toRadians & Math.fromRadians, and the absence of any function (in the Math namespace) with "degrees" in its name would help them to realise the built-in trigonometry functions expect angles to be expressed in radians.

[Suggestion] Constants to be added

Radical Constants 👍

In addition to Math.TAU = 2·π = τ #5, at least some of these would make sense to have as well

  • (Number.EPSILON = ε already exists)
Constant Calculation Definition Symbol Approximate value Name
👍 Math.PHI (Math.SQRT5 + 1) / 2 ½+√1¼ φ 1.6180339887498948 Golden Number or Golden Ratio
👎 Math.PHIM1 1/Math.PHI = Math.PHI-1 Φ 0.6180339887498948
👍 Math.SQRT2P1 Math.SQRT2 + 1 δs 2.4142135623730950 Silver Ratio
👎 Math.THETA Math.sqrt(Math.PI) * Math.PHI φ·√π θ 2.8678905742557635
👎 Math.RHO (Math.cbrt(0.5+Math.sqrt(69)) + Math.cbrt(0.5-Math.sqrt(69)))/18 ³√(½ + √69)/18 + ³√(½ − √69)/18 ρ 1.324717… Plastic Ratio or Platin Number
👍 Math.SQRT3 Math.sqrt(3) √3 1.732050807568877 Theodorus constant
👍 Math.SQRT5 Math.sqrt(5) √5 2.2360679774997897
👍 Math.SQRT3_2 Math.sqrt(1.5) √1½ 1.2247448713915890
👍 Math.SQRT2_3 Math.sqrt(2/3) √⅔ 0.8164965809277260

Standard angles in radians 👎

Twelfths 👎

Constant Calculation Degrees Approximate radians
Math.CLOCK1 = Math.DEG30 Math.PI / 6 30° 0.524
Math.CLOCK2 = Math.DEG60 Math.PI / 3 60° 1.047
Math.CLOCK3 = Math.DEG90 Math.PI / 2 90° 1.571
Math.CLOCK4 = Math.DEG120 Math.PI * 2/3 120° 2.094
Math.CLOCK5 = Math.DEG150 Math.PI * 5/6 150° 2.618
Math.CLOCK6 = Math.DEG180 Math.PI 180° 3.142
Math.CLOCK7 = Math.DEG210 Math.PI * 7/6 210° 3.665
Math.CLOCK8 = Math.DEG240 Math.PI * 4/3 240° 4.189
Math.CLOCK9 = Math.DEG270 Math.PI * 3/2 270° 4.712
Math.CLOCK10 = Math.DEG300 Math.PI * 5/3 300° 5.236
Math.CLOCK11 = Math.DEG360 Math.PI * 11/6 330° 5.760
Math.CLOCK12 = Math.DEG360 Math.PI * 2 = Math.TAU 360° 6.283

Fourths, Eighths or Sixteenths 👎

Constant Calculation Degrees Approximate radians Compass
Math.NORTH = Math.DEG360 0 0 North
Math.NNE Math.PI / 8 22½° 0.393 North-Northeast
Math.NE = Math.DEG45 Math.PI / 4 45° 0.785 Northeast
Math.ENE Math.PI * 3/8 67½° 1.178 East-Northeast
Math.EAST = Math.DEG90 Math.PI / 2 90° 1.571 East
Math.ESE Math.PI * 5/8 112½° 1.963 East-Southeast
Math.SE = Math.DEG135 Math.PI * 3/4 135° 2.356 Southeast
Math.SSE Math.PI * 7/8 157½° 2.749 South-Southeast
Math.SOUTH = Math.DEG180 Math.PI 180° 3.142 South
Math.SSW Math.PI * 9/8 202½° 3.534 South-Southwest
Math.SW = Math.DEG225 Math.PI * 5/4 225° 3.927 Southwest
Math.WSW Math.PI * 11/8 247½° 4.320 West-Southwest
Math.WEST = Math.DEG270 Math.PI * 3/2 270° 4.712 West
Math.WNW Math.PI * 13/8 292½° 5.105 West-Northwest
Math.NW = Math.DEG315 Math.PI * 7/4 315° 5.498 Northwest
Math.NNW Math.PI * 15/8 337½° 5.890 North-Northwest

Replace (or augment) Math.scale with Math.lerp/unlerp (possibly with better names)

Names obviously can be bikeshedded over to infinity, I'll admit that lerp/unlerp are bad ones. (GLSL goes with mix, HLSL goes with lerp, i've seen packages do linearInterpolate or interpolate and inverseLinearInterpolate, etc -- although those seem much too verbose to me).

Anyway, it seems extremely likely to me that linear interpolation is more common than linear remapping, and so a lerp/unlerp pair would get more use than Math.scale (even if they can be implemented by passing 0 and 1 as lo/hi values for Math.scale).

Including all 3 would be fine by me as well.

(P.S. other than that I'd like to thank you for including RAD_PER_DEG/DEG_PER_RAD as a constant in addition to a function!)

`Math.sum`?

Simplifying things like Math.sum(...Object.values(x)) or Math.sum(...numbers) where previously we'd need .reduce((a, b) => a+ b)?

Bitwise methods

JS already has Math.clz32 but counting trailing zeros is usually more helpful than the leading zeros, I'm speaking from personal experience.

As seen in the official MDN article about clz32, the polyfill can be implemented using CLZ as base:

//based on https://en.wikipedia.org/wiki/Find_first_set#CTZ
{
	const clz = Math.clz32;
	Math.ctz32 = function(x) {
		x = +x;
		return x | 0 ? 31 - clz(x & -x) : 32
	};
}

[Suggestion] Math.lerp and Math.normalize

Linear extrapolation and normalization are very common operations, particularly for graphics programming. I think they would make good candidates for inclusion in the standard.

For context, both of these are essentially specialisations of the proposed Math.scale, where:

  • normalize is equivalent to Math.scale(value, min, max, 0, 1)
  • lerp is equivalent to Math.scale(value, 0, 1, min, max)

But they are such common operations, and have their own mathematical names, I think they warrant inclusion.

Math.normalize = function normalize(value, min, max) {
  return (value - min) / (max - min);
};
Math.lerp = function lerp(norm, min, max) {
  return (max - min) * norm + min;
};

console.assert(Math.normalize(15, 10, 20), 0.5)
console.assert(Math.lerp(0.5, 10, 20), 15)

New rounding modes

I've read about this method and I found a roundingMode option, so I thought it may be a good idea to add at least 1 of these.

I personally would add expand, but tie-breaking modes seem more useful

[Suggestion] Math.mean and Math.roundBy

Hello, I really like this proposal, and I'd like two suggestions

Math.mean([1,2,3]) // 2

Math.roundBy(100.1234, 2) // 100.12

I'm proposing a separated method for round, since I think that Math.round could lead to breaking changes

modulo function

I'd like to add a modulo function, different from standard %.
Let's call it Math.mod (x, d).

  • if either x or d is not a number, return NaN.;
  • if (d= 0) return NaN;
  • if (x = 0) return 0;
  • if (d > 0) then
    • if (x > 0) {return x % d }
    • else /* that is, if (x < 0) */ return (x % d) + d;
  • else /* that is, if d < 0 */ return Math.mod (- x, -d);

Motivation: operator % produces the remainder of x diveded by Math.abs(d). There is no function that yields the algebraic modulo of x by d, which is of the same sign as d.
Not having this function handy causes frequent bugs in calendrical computations, including ICUs.

Math.{minIndex, maxIndex}

Something I often need is to get the index of a minimum in an array, not especially its value

Math.inf([6,4,5]) // 1
Math.sup([6,4,5]) // 0
// or this naming:
Math.minIndex([6,4,5]) // 1 
Math.maxIndex([6,4,5]) // 0
// or 
Math.argMin([6, 4, 5]) // 1
Math.argMax([6,4,5]) // 0
Math.argMin(6, 4, 5) // possibly as a variadic function?

Dot product?

I don't see any reason to add this because:

  • Math methods don't expect arrays, the only thing similar to that is making use of rest params or the local arguments object.
  • It's not a commonly used operation, although more frequently used than matrix multiplication.
  • It's easy to implement in userland (see polyfill at the footer).

However some reasons to add it may be:

  • Users/devs don't need to think about how to handle arrays with different lengths, because it would be standardized.
  • Less rounding errors, because implementations could use Kahan Summation or Pairwise Sum internally (related: Issue #4 ).

I think this shouldn't be added because, as said before, it would break the consistency of Math.*. This is better suited for the Array namespace or a new namespace, which are both out of scope of this proposal. I opened this Issue just in case someone has valid (and solid) arguments for adding it.

Polyfill:

Math.dotProd = function(arr0, arr1) {
  return arr0.map((_, i) => arr0[i] * arr1[i]).reduce((x, y) => x + y);
}

Wikipedia article

Should `factorial` be defined in all or some domains?

What I mean by "domain" is actually a math function domain. Should it return NaN for positive non-integer inputs? Or should it be defined in terms of the Gamma function (plus one)? If so, should it return NaN for negative args? or should it use the "raw" Gamma function definition where it returns "weird" values?

There are many conflicting definitions for negative inputs, so I guess the best choice is to return NaN.

About positive non-ints, I think it should definitely use Gamma. This is because interpolating the factorial function accurately and efficiently is very hard for most devs (including me). I know 1 person isn't enough evidence to assume most people have problems doing the same thing, but I'm sure if we do a survey we would get similar results.

MS calculator, Desmos, and WolframAlpha, all use an interpolated factorial, and (AFAIK) they all use Gamma internally. Again, these 3 pieces of software aren't enough justification to extend the domain of the factorial. Extending the factorial "just because some people do it" is an ad-populum fallacy. But we should be aware that the extended definition exists and try to reach a consensus if the factorial is actually added

Math.floor() should take a second param to specify decimal place like _.floor

I was completely floored when I found out that the current implementation of Math.floor() doesn't allow for specifying decimal place like _.floor() in lodash does. It would be nice to be able to pass in a second param to Math.floor() to specify decimal place for a little more precision.

Example

Math.floor(.046);
// => 0

vs.

_.floor(0.046, 2);
// => 0.04

Add TAU constant

With a TAU constant, defined as 2 * PI, a lot of the PI-related math becomes simpler. Furthermore, existing APIs, which use radians, such as CanvasRenderingContext2D.arc(), become easier to use because you can now express things in terms of turns. E.g. half a turn (TAU * 0.5) is half a circle.

Canvas example (JSFiddle):

const TAU = Math.PI * 2;
let canvas = document.querySelector('canvas');
let ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(
  50, // x
  50, // y
  40, // radius
  // startAngle
  // from 3 o'clock, 1/4 counter-clockwise turn
  TAU * -0.25,
  // endAngle
  // from 3 o'clock, 1/4 clockwise turn
  TAU * 0.25
);
ctx.stroke();

As one would expect, the result is half a circle going from 12 o'clock to 6 o'clock.

http://tauday.com/tau-manifesto
https://en.wikipedia.org/wiki/Turn_(geometry)#Tau_proposal

Processing: https://processing.org/reference/TAU.html
Python recently added TAU: https://docs.python.org/3.6/library/math.html#math.tau

tl;dr: Vi Hart - Pi Is (still) Wrong.
https://www.youtube.com/watch?v=jG7vhMMXagQ

`Number.prototype.toByteSize` / `Intl.SizeFormat`

This is not a mathematical fn. Its purpose is number formatting, more specifically, formatting a numeric value as SI/IEC byte/bit units.

Examples:

//"B" stands for "Byte" or "Octet"
//this is the default config, so the options-bag can be omitted
sizeFormat(1000, {sys: "SI", inUnit: "B", outUnit: "B"})
//"1 KB"

//"b" stands for "bit"
sizeFormat(1000, {sys: "SI", inUnit: "B", outUnit: "b"})
//"8 Kb"

sizeFormat(1000, {sys: "SI", inUnit: "b", outUnit: "b"})
//"1 Kb"

sizeFormat(2**32, {sys: "IEC", inUnit: "B", outUnit: "B"})
//"4 GiB"

//"W" is "Word" (16b)
sizeFormat(2**32, {sys: "IEC", inUnit: "W", outUnit: "B"})
//"8 GiB"

The rationale for the option-bag or "kwargs" (as in Python) is for readability and explicitness. The rationale behind allowing bits, Bytes, and Words, is for future-proofing.

I know this is out-of-scope for this proposal, so I suggest this to be placed in a separate proposal similar to Number.fromString (because it's related to parsing and formatting).

I posted this here because I couldn't find a better place. Sorry for any inconvenience

Math.constrain: wrong result for ±∞

Current step 2 of Math.constrain:

  1. If x is one of +∞, -∞, return x.

As a result, Math.constrain(Infinity, 2, 3) will be Infinity. I expect 3.

Solution: delete Step 2.

Elaboration on motivation?

I took a look at this specification, and it's hard for me to see why these are needed in JS itself as opposed to user-level libraries. Are any of them more efficient to implement on real hardware? Which ones? What makes user-level libraries inadequate for things like converting between degrees and radians?

`Math.copysign`?

The equivalent of copysign(a, b) amounts to most of my use of Math.sign in practice. This also can be done very cheaply on many platforms (including x86-64 and ARM) using bitwise instructions - it's just copying the high bit of the second argument to the first.

Doing this in userland is very inefficient, though:

function copysign(a, b) {
    return Object.is(Math.sign(a), Math.sign(b)) ? a : -a
}

This is very common in games (you can do copysign(baseSpeedX, player.x - enemy.x) instead of player.x < enemy.x ? -baseSpeedX : baseSpeedX) and in number-heavy code for various reasons. Helps avoid a lot of branches and a bunch of otherwise necessary boilerplate.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.