# Math.max() without Arguments

I posted the following poll on Twitter asking what would be returned if you called JavaScript's `Math.max()`

function *without* any arguments.

🏆 #JavaScript Quiz time! (no cheating) 🏆

— west, donavon west™️ (@donavon) March 20, 2020

We all know that `Math.max(1, 2, 3)` will return 3.

But what is the result if you call `Math.max()` without any arguments. Bonus points if you can explain why in the replies.

I gave 4 possible answers: `undefined`

, `-1`

, `0`

, and `-Infinity`

.

I'm just going to go ahead and spoil it for you. The answer is `-Infinity`

(about half of you got it right, yay! 👏). But why?

Let's dive into the possible JavaScript-based implementations of `Math.max`

.

### Using reduce to return -Infinity

JavaScript already has one, but if I were to write a `max`

function from scratch, this is how I would do it.

```
const max = (...values) =>
values.reduce((max, value) => (value > max ? value : max), -Infinity);
```

The function accept a single rest parameter called `values`

, which will be an array. `reduce`

is aptly named as it works to translate an array into a single value. We seed the initial `maxValue`

value with `-Infinity`

.

With each iteration through the array, we return `value`

(if it is greater than `maxValue`

) or `maxValue`

. When all values have been compared, we return `maxValue`

to the caller.

So because we seeded `maxValue`

with `-Infinity`

if there are zero items in the array, we return the initial value of `maxValue`

(i.e. `-Infinity`

).

Let's test our code by calling it with some sample data.

```
assert(max() === -Infinity, 'Should be -Infinity');
assert(max(-1000) === -1000, 'Should be -1000');
assert(max(1, 2, 3) === 3, 'Should be 3');
```

Yep. They all pass!

This is a short and sweet implementation.

### Using reduce to return 0 (or -1)

If we took our code above and replaced the initial value of `-Infinity`

with `0`

, the code would still work. Or would it?

Let's see this by running our tests again – changing the first one to check for zero instead.

```
assert(max() === 0, 'Should be 0');
assert(max(-1000) === -1000, 'Should be -1000');
assert(max(1, 2, 3) === 3, 'Should be 3');
```

As you see, calling `max()`

without any arguments did correctly return `0`

, but we get an error with the test for `-1000`

.

```
AssertionError: Should be -1000
```

Why is `max(-1000)`

failing? What do you think this is returning? It is errantly returning `0`

instead of `-1000`

. This is because a `value`

of `-1000`

is not greater than a `maxValue`

of `0`

.

People tend to think in terms of positive numbers. Returning `0`

would break some valid conditions as we've shown.

### Using reduce to return undefined

What if we wanted to return `undefined`

? This isn't a bad idea (my 8-year-old guessed this when I "quizzed" my family) but would add complexity to our solution above.

Let's take a look.

```
const max = (...values) =>
values.reduce((max, value) => {
if (max === undefined) {
return value;
}
return value > max ? value : max;
}, undefined);
```

You see, we would explicitly need to check if `maxValue`

was `undefined`

inside of our loop. It works, but conditions add time and code complexity.

### In conclusion

We've learned that returning `-Infinity`

or `undefined`

are the only possible valid conditions of the four I presented in my Twitter poll.

However, `-Infinity`

greatly reduces code complexity and IMO, is the best solution.

#### Follow up from Brendan Eich

It turns out that my guess was right! This is exactly how `Math.max`

is implemented. I received the following tweet from the father of JavaScript, Brendan Eich.

That's right. Math.max in ur-JS and ES1&2 took only two parameters, but ES3 generalized to compute maximum of a variable number of arguments. This motivates -∞ as the max of the empty set (0 args) basis case, as you showed.

— BrendanEich (@BrendanEich) March 21, 2020