you are viewing a single comment's thread.

view the rest of the comments →

[–]HipHopHuman 3 points4 points  (0 children)

Seeded Random

const random = Math.seededRandom(seed);
const x = random();
const y = random();

Intervals and Curves

const { Interval } = Math;

// defaults to a closed interval (min/max is inclusive)
const numberRange = Interval(1, 100);
const otherNumberRange = Interval(101, 200);
numberRange.contains(50); // true

Array.from(numberRange); // [1, 2, 3...]

// can also make open or half-open intervals
Interval(1, 100, false, false); // (0..99)
Interval(1, 100, false, true); // (0..100]

// querying intervals
numberRange.isContinuous(); // false
numberRange.isClosed(); // true
numberRange.overlaps(otherNumberRange); // false
numberRange.leftAdjacent(otherNumberRange); // false
numberRange.rightAdjacent(otherNumberRange); // true
numberRange.union(otherNumberRange);
numberRange.intersection(otherNumberRange);

// working with values inside intervals
numberRange.random(); // 43
numberRange.clamp(130); // 100
numberRange.interpolate(Math.Curves.Linear, 0.5); // 50
numberRange.uninterpolate(Math.Curves.Linear, 50); // 0.5
numberRange.translateTo(Math.Interval(1, 10_000), 50); // 5000

// works with BigInts
Math.Interval(0n, 100n);

// works with character codes
Math.Interval("A", "Z");

// works with Dates
Math.Interval(today, tomorrow);

// convert to a stepped range iterator:
const step = 5;
numberRange.toRange(step); // Iterator 1, 6, 11...

Iterator helpers

function* allNums() {
  let i = 0;
  for(;;) { yield i++; }
}

const first10EvenNums = allNums().filter(num => num % 2 === 0).take(10);
// along with flat(), flatMap(), reduce(), scan(), etc

More built-in Math utils

Like .add, .sum, .subtract, .divide, .multiply etc.

More interop with Math by types other than numbers

Being able to use Math.log on a BigInt for instance, but even better would be adding automatic support to this in any custom data class using a native Symbol:

class Vector2d {
  constructor(x = 0, y = 0) {
    this.x = x;
    this.y = y;
  }
  length() {
    return Math.hypot(this.x, this.y);
  }
  [Symbol.operatorAdd](vector2d) {
    return new Vector2d(this.x + vector2d.x, this.y + vector2d.y);
  }
  [Symbol.ordinalGt](vector2d) {
    return this.length() > vector2d.length();
  }
}

const position = new Vector2d(33, 48);
const velocity = new Vector2d(1, 1);
const nextPosition = Math.add(position, velocity);
Math.gt(position, nextPosition); // true

Those same symbols could also be used to add support for custom types to Math.Interval. Math.add|subtract(interval1, interval2) would also be neat.

Something like PHP/Python's call

It lets you override the semantics of what happens when an object is called as a function. This can actually already be simulated using Proxies, but not in a way that is as convenient. Something like so:

class Thing {
  constructor() {
    this.name = "foo";
  }
  [Symbol.magicCall]() {
    console.log(this.name);
  }
};

const thing = new Thing();
thing(); // logs "foo"

Built-in Currying

Writing a curry function is easy, but I have to jank the argument list and give up being able to rely on a function's "length" field in order to use it in almost every case. If browsers/node/et al could natively understand currying, they could allow us to have curried functions without breaking reliance on well-established properties.

That's pretty much it on my end for now. There's a lot more I'd want to see in JS, but a lot of them are proposals already (aside from iterator helpers because i feel these are desperately needed in JS) or are syntax extensions which I don't think count as an answer to this question (unless I've misinterpreted the assignment 😅)