Math.hypot(1)

# Jason Orendorff (7 years ago)

I think the spec says that

Math.hypot() ===> NaN
Math.hypot(1) ===> NaN
Math.hypot(1, 2, 2, 4) ===> 3
Math.hypot(3, 4, undefined) ===> NaN

Is that correct?

I'm basing this on paragraph 4 of clause 15, plus the first sentence of 15.8.2, plus the fact that Math.hypot() appears to "require" 2 arguments.

The last case illustrates that the default argument syntax used in the heading:

15.8.2.29 Math.hypot( value1 , value2, value3 = 0 )

is not quite how the function behaves.

How about we change this function to take any number of arguments (like Math.max), convert them all using ToNumber, and compute the norm?

Math.hypot() ===> 0
Math.hypot(1) ===> 1
Math.hypot(1, 2, 2, 4) ===> 5

Allowing 3 arguments but ignoring the 4th seems like a bit of a head fake, to me.

# Allen Wirfs-Brock (7 years ago)

On Jul 31, 2013, at 9:25 AM, Jason Orendorff wrote:

I think the spec says that

Math.hypot() ===> NaN
Math.hypot(1) ===> NaN
Math.hypot(1, 2, 2, 4) ===> 3
Math.hypot(3, 4, undefined) ===> NaN

No, default value assignment is trigger for arguments that have the actual value undefined. So the last one is the same as Math.hypot(3,4,0)

Is that correct?

I'm basing this on paragraph 4 of clause 15, plus the first sentence of 15.8.2, plus the fact that Math.hypot() appears to "require" 2 arguments.

The last case illustrates that the default argument syntax used in the heading:

15.8.2.29 Math.hypot( value1 , value2, value3 = 0 )

is not quite how the function behaves.

But it's supposed to behave that way.

How about we change this function to take any number of arguments (like Math.max), convert them all using ToNumber, and compute the norm?

Math.hypot() ===> 0
Math.hypot(1) ===> 1
Math.hypot(1, 2, 2, 4) ===> 5

Allowing 3 arguments but ignoring the 4th seems like a bit of a head fake, to me.

This was discussed at the March 2012 TC39 meetings and the consensus was what is currently in the spec. Here is what the minutes say:

Discussion of hypot, hypot2.
hypot is the square root of the sum of squares and takes either two or three arguments.
hypot2 is the sum of squares and takes either two or three arguments.
Waldemar: How is hypot2 better than just doing x*x + y*y?
Luke: It's just ergonomics.
General reluctance about the hypot2 name because it looks like the 2 means two arguments (as in atan2).  Some debate about other function names (hypotSq? sumOfSquares?).
MarkM: How is hypot better than sqrt(x*x + y*y)?
It's potentially more efficient and more accurate.  It is widespread in numeric libraries.
Consensus:  hypot will support just two or three arguments.  hypot2 dropped.   <<<<=====
Waldemar, MarkM:  Why not one or zero arguments?  It would be 0 for zero arguments and abs for one argument.
Allen, DaveH:  If you pass one argument to hypot, you'll get NaN.
Luke:  It's not variadic.
Waldemar:  Why isn't it variadic?
Luke:  2 or 3 is the 99% use case.
Waldemar:  2 or 3 arguments is the 99% use case for max.
Waldemar:  If it's not variadic and takes only 2 or 3 arguments, you'll get silent mistakes.  If you pass in four arguments, you'll get the hypot of the first three, and the last one will be silently ignored.  That's bad.
Luke:  Will go back to the experts to explore implementing variadic hypot.

I don't recall whether we ever heard back form Luke. But the spec. reflects the recorded concensus as of that meeting.

# Jason Orendorff (7 years ago)

On Thu, Aug 1, 2013 at 11:46 AM, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:

Waldemar:  Why isn't it variadic?
Luke:  2 or 3 is the 99% use case.
Waldemar:  2 or 3 arguments is the 99% use case for max.
Waldemar:  If it's not variadic and takes only 2 or 3 arguments, you'll get silent mistakes.  If you pass in four arguments, you'll get the hypot of the first three, and the last one will be silently ignored.  That's bad.

Heh! Thanks for the long quote.

It's striking how many good points Waldemar has in this exchange.

Luke:  Will go back to the experts to explore implementing variadic hypot.

I don't know if I qualify as an expert, but variadic hypot would be no harder to implement than what is currently specified (probably easier, honestly), and no harder to optimize.

To answer a question posed in that discussion, one way hypot(a, b) is better than sqrt(aa + bb) is that the latter underflows if the arguments are both small, and overflows if either argument is large.

# Luke Hoban (7 years ago)

More discussion on this here: ecmascript#309. CC Roger Andrews who had argued there that this should be 2- and 3- arguments only.

Personally, I don't see a strong case against allowing hypot to be variadic from re-reading that discussion, and do believe that would be a more expected behavior for ECMAScript, as for example Waldemar's last comment below points out.

# Brendan Eich (7 years ago)

Luke Hoban wrote:

More discussion on this here: ecmascript#309. CC Roger Andrews who had argued there that this should be 2- and 3- arguments only.

Good stuff there. But I would appreciate more detail from Roger on the "(Otherwise we get into over-complicated issues with vector 2-norms, etc.)"issues cited in ecmascript#309#c15 -- if it's not just about excessive rounding error mentioned earlier.

Personally, I don't see a strong case against allowing hypot to be variadic from re-reading that discussion, and do believe that would be a more expected behavior for ECMAScript, as for example Waldemar's last comment below points out.

Agree, unless there's a footgun Roger sees that we should avoid arming users with.

# Tab Atkins Jr. (7 years ago)

On Thu, Aug 1, 2013 at 10:24 AM, Luke Hoban <lukeh at microsoft.com> wrote:

More discussion on this here: ecmascript#309. CC Roger Andrews who had argued there that this should be 2- and 3- arguments only.

I can't follow the argument chain; it's clear there was more discussion going on privately. In ecmascript#309#c5 Roger argues that it would be fine to do variadic hypot. In ecmascript#309#c8 Jens lightly objects, but only because of the name. (He later agrees that it doesn't make sense to make a new 3-arg hypot function just because of naming unease.) Then in ecmascript#309#c15 Roger suddenly reverses, and documents the consensus as being just 2/3-arg hypot. Like Brendan, I'm confused about what the "over-complicated issues with vector 2-norms" he cites in that comment are supposed to be.