MikeMcl / bignumber.js

A JavaScript library for arbitrary-precision decimal and non-decimal arithmetic
http://mikemcl.github.io/bignumber.js
MIT License
6.63k stars 743 forks source link

Question: Efficiency of creating a new constructor for every operation #323

Closed lars-jpeg closed 2 years ago

lars-jpeg commented 2 years ago

I'm a fan of a functional programming style and I was wondering would it be wasteful to create a new BigNumber constructor for every calculation with the provided config? Below is an example that tries to achieve a pure functional style. Is .clone() well suited for this purpose?

export const divide =
  (config) =>
  (dividend, divisor) => {
    const BigNumberWithConfig = BigNumber.clone(config)

    if (!isNumber(dividend) || !isNumber(divisor) || divisor === 0) {
      return 0
    }

    const result = new BigNumberWithConfig(dividend).dividedBy(divisor).toNumber()
    return result
  }
shuckster commented 2 years ago

Seems like your curried function isn't quite taking advantage of the closure.

I'd move clone to the outer function body:

export const divide =
  (config) => {
    const BigNumberWithConfig = BigNumber.clone(config)

    return (dividend, divisor) => {
      if (!isNumber(dividend) || !isNumber(divisor) || divisor === 0) {
        return 0
      }

      const result = new BigNumberWithConfig(dividend).dividedBy(divisor).toNumber()
      return result
    }
  }
lars-jpeg commented 2 years ago

Wow @shuckster . Gotta say I wasn't even aware of this pattern. Today I learned something new! That looks really handy.

shuckster commented 2 years ago

@lars-jpeg No worries! Closure is a powerful JS feature, and is what helps it stand alongside "full" FP languages without blushing too much.

A nice basic demonstration of it is memoizing, if you'll suffer me posting a self-authored explainer.