Modulo Operator %%

# Matthew Morgan (5 years ago)

JS needs a modulo operator. It currently has the remainder operator % which works in most cases except for negative values. I believe %% would work great and be easy to remember.

let x = (-13) %% 64;

is equivalent to

let x = ((-13 % 64) + 64) % 64;

# kdex (5 years ago)

I would welcome such an operator as well. I find myself implementing a mod function from time to time, expressing it in terms of the remainder operator.

As for syntax, I don't see %% posing any syntactical ambiguities, so I'll second it.

# Cyril Auburtin (5 years ago)

agreed, let's make a proposal

# Michael Haufe (5 years ago)

I would prefer the syntax be ‘a mod b’ consistent with my wishlist item:

esdiscuss.org/topic/new-operator, esdiscuss.org/topic/still-waiting-for-integer-division

In to semantics:

www.microsoft.com/en-us/research/wp-content/uploads/2016/02/divmodnote.pdf

From: es-discuss <es-discuss-bounces at mozilla.org> On Behalf Of Cyril Auburtin

Sent: Tuesday, August 13, 2019 5:07 AM Cc: es-discuss <es-discuss at mozilla.org>

Subject: Re: Modulo Operator %%

agreed, let's make a proposal

On Tue, Aug 13, 2019 at 12:06 AM kdex <kdex at kdex.de<mailto:kdex at kdex.de>> wrote:

I would welcome such an operator as well. I find myself implementing a mod function from time to time, expressing it in terms of the remainder operator.

As for syntax, I don't see %% posing any syntactical ambiguities, so I'll second it.

On Monday, August 12, 2019 10:00:09 PM CEST Matthew Morgan wrote:

JS needs a modulo operator. It currently has the remainder operator % which works in most cases except for negative values. I believe the the %% would work great and be easy to remember.

let x = (-13) %% 64; is equivalent to let x = ((-13 % 64) + 64) % 64;_______________________________________________

es-discuss mailing list es-discuss at mozilla.org<mailto:es-discuss at mozilla.org>

mail.mozilla.org/listinfo/es

# Michael Haufe (5 years ago)

Related:

esdiscuss.org/notes/2018-01-24#13vd-operator-overloading-for-stage-1

I don’t see anything newer than this

From: es-discuss <es-discuss-bounces at mozilla.org> On Behalf Of Cyril Auburtin

Sent: Tuesday, August 13, 2019 5:07 AM Cc: es-discuss <es-discuss at mozilla.org>

Subject: Re: Modulo Operator %%

agreed, let's make a proposal

On Tue, Aug 13, 2019 at 12:06 AM kdex <kdex at kdex.de<mailto:kdex at kdex.de>> wrote:

I would welcome such an operator as well. I find myself implementing a mod function from time to time, expressing it in terms of the remainder operator.

As for syntax, I don't see %% posing any syntactical ambiguities, so I'll second it.

On Monday, August 12, 2019 10:00:09 PM CEST Matthew Morgan wrote:

JS needs a modulo operator. It currently has the remainder operator % which works in most cases except for negative values. I believe the the %% would work great and be easy to remember.

let x = (-13) %% 64; is equivalent to let x = ((-13 % 64) + 64) % 64;_______________________________________________

es-discuss mailing list es-discuss at mozilla.org<mailto:es-discuss at mozilla.org>

mail.mozilla.org/listinfo/es

# Waldemar Horwat (5 years ago)

On 8/13/19 7:27 AM, Michael Haufe wrote:

I would prefer the syntax be ‘a mod b’ consistent with my wishlist item:

This can bring up various syntactic troubles. What does the following do?

let mod +3

Is it calling the mod operator on the variable named "let" and +3? Or is it defining a variable named "mod" with no initializer, followed by an expression?

 Waldemar
# Michael Haufe (5 years ago)

On 8/13/19 7:27 AM, Michael Haufe wrote:

I would prefer the syntax be ‘a mod b’ consistent with my wishlist item:

On 8/13/19 9:12 PM, Waldemar Horwat wrote:

This can bring up various syntactic troubles. What does the following do?

let mod +3

Is it calling the mod operator on the variable named "let" and +3? Or is it defining a variable named "mod" with no initializer, followed by an expression?

I can't declare 'let' or 'var' as variable names, but even if I could (Say non-strict mode or ES3) that form would be a VariableDeclaration followed by an ExpressionStatement.

The proposed grammar extension is:

MultiplicativeOperator: one of * / % div mod

Michael

# Isiah Meadows (5 years ago)

For syntactic precedent, CoffeeScript and R both have %% for a modulus returning the sign of the divisor, where a %% b is equivalent to (a % b + b) % b. So JS wouldn't be the first here.

Most languages Wikipedia lists in their comparison (en.wikipedia.org/wiki/Modulo_operation) use a function for this kind of modulus operation, not an operator. That itself seems worth noting.


Isiah Meadows contact at isiahmeadows.com, www.isiahmeadows.com

# Waldemar Horwat (5 years ago)

On 8/13/19 8:32 PM, Michael Haufe wrote:

On 8/13/19 7:27 AM, Michael Haufe wrote:

I would prefer the syntax be ‘a mod b’ consistent with my wishlist item:

On 8/13/19 9:12 PM, Waldemar Horwat wrote:

This can bring up various syntactic troubles. What does the following do?

let mod +3

Is it calling the mod operator on the variable named "let" and +3? Or is it defining a variable named "mod" with no initializer, followed by an expression?

I can't declare 'let' or 'var' as variable names, but even if I could (Say non-strict mode or ES3) that form would be a VariableDeclaration followed by an ExpressionStatement.

The proposed grammar extension is:

MultiplicativeOperator: one of * / % div mod

And I'm saying that's potentially problematic because it changes the meaning of existing programs that happen to use "mod" as a variable name. The above is one example that would turn a let statement into a mod expression. Here's another example:

x = 4 mod(foo)

 Waldemar
# Claude Pache (5 years ago)

Le 12 août 2019 à 22:00, Matthew Morgan <mmm211 at zips.uakron.edu> a écrit :

JS needs a modulo operator. It currently has the remainder operator % which works in most cases except for negative values. I believe the the %% would work great and be easy to remember.

let x = (-13) %% 64; is equivalent to
let x = ((-13 % 64) + 64) % 64;

Is there a strong advantage of an %% operator over a Math.mod() function? There is the precedent of the ** operator implemented as alternative of Math.pow() few years ago. It would be interesting to hear the feedback of those that use regularly powers, whether the benefit was clear (personally, I almost never use either Math.pow() or **, so that I can’t say anything).

At least one disadvantage of an operator over a function, is that you have to think about precedence. The problem is exacerbated in JS, because (following some other languages) the unary minus has an uncanny high precedence level, confusingly very different than the one of the binary minus; so that, after having designed **, it was realised at the last minute that -a**b would be dumbly interpreted as (-a)**b instead of -(a**b) or 0-a**b, as anybody who would be likely to actually use the operator would expect. (That particular issue was resolved in a hurry by making the parenthesis-left form a syntax error.)

# Andrea Giammarchi (5 years ago)

FWIW another disadvantage is that operators cannot be polyfilled, so it'll take forever for those not using transpilers to adopt these, while having a Math,mod would work right away

# Michael Luder-Rosefield (5 years ago)

Is there any way we can add function/operator equivalence to the language? Perhaps some kind of 'operators' global object with symbol fields matching operator string to functions/constraints?

Dammit babies, you've got to be kind.

# kdex (5 years ago)

We could circumvent this by making %% analogous to **. That is, we could provide a function form Math.mod as well as an infix operator %%.

# Michael Haufe (5 years ago)

On 8/14/19 7:50 PM, Waldemar Horwat wrote:

And I'm saying that's potentially problematic because it changes the meaning of existing programs that happen to use "mod" as a variable name. The above is one example that would turn a let statement into a mod expression. Here's another example:

x = 4 mod(foo)

Potentially yes and surely there is a yacc definition where one could check to be certain? Regardless, let's assume there is or that workarounds to guarantee infixity are not worth the complication ([no LineTerminator here] usage).

We know that syntax is the last bastion of language luddites, so it's best not to linger on something which was not my main concern. I am more interested in maintaining the duality of the operators over how they are represented (within reason). Thus, if '%%' is what is preferable, then '\' would be the partner.

Michael

# Michael Haufe (5 years ago)

Thursday, August 15, 2019 2:47 AM, Andrea Giammarchi wrote:

FWIW another disadvantage is that operators cannot be polyfilled, so it'll take forever for those not using transpilers to adopt these, while having a Math,mod would work right away

With such an approach there is risk of another ‘smooshgate’ [1][2]. There is nothing stopping those developers from using a function anyway to bridge the gap if they can’t or won’t use a compiler. This is already the current state of affairs.

[1] developers.google.com/web/updates/2018/03/smooshgate [2] adamsilver.io/articles/the-disadvantages-of-javascript-polyfills

Michael

# Isiah Meadows (5 years ago)

An operator is far more concise than a function call, and is likely to see greater use. It also aligns better with peoples' intuition on what the "modulus" is, avoiding subtle bugs like in `isOdd = x => x % 2 ===

1(example from https://en.wikipedia.org/wiki/Modulo_operation#Common_pitfalls - try passing a negative to it). And given this one is high value (see above) and *very* low cost (it can literally desugar to(x % y + y) % y`), I feel it does meet that bar.

It would be interesting to hear the feedback of those that use regularly powers, whether the benefit was clear (personally, I almost never use either Math.pow() or **, so that I can’t say anything).

It has enough benefit I've seen CoffeeScript users default to %% and only using % when they explicitly want the dividend-dependent semantics. And engines with a native %%, if they can detect the operands are always non-negative, can optimize it to % pretty easily. It's better enough that you'd likely start seeing some partially legitimate FUD spread about the standard %.

One other added benefit of using divisor-dependent modulo is that x %% (2**n), where x and n are integers and n >= 0, could always

be safely rewritten to x & (2**n - 1) while still preserving semantics, but x % (2**n) does not have this property. For example:

  • -1 %% (2**1)-1 %% 11
  • -1 & (2**1 - 1)-1 & 11
  • -1 % (2**1)-1 % 2-1

BTW, I literally tested all three of these in Chrome's devtools console, using my x %% y(x % y + y) % y desugaring.

As for a native implementation and the spec, I'd recommend just doing copysign(fmod(x, y), y) instead to retain precision.

At least one disadvantage of an operator over a function, is that you have to think about precedence. The problem is exacerbated in JS, because (following some other languages) the unary minus has an uncanny high precedence level, confusingly very different than the one of the binary minus; so that, after having designed **, it was realised at the last minute that -a**b would be dumbly interpreted as (-a)**b instead of -(a**b) or 0-a**b, as anybody who would be likely to actually use the operator would expect. (That particular issue was resolved in a hurry by making the parenthesis-left form a syntax error.)

I doubt this would happen with %%. It's similar enough to the existing % in concept that most would expect it to have the same precedence. With **, there was a very unique issue with it: there were people actually reading it both ways, and even a language (Python) that interprets -a ** b and -a**b differently in light of that (as (-a) ** b and -(a ** b) respectively). That's not a concern at all with most operators, so it doesn't apply to most new operator proposals.


Isiah Meadows contact at isiahmeadows.com, www.isiahmeadows.com

# Andrea Giammarchi (5 years ago)

To me there's no risk, as MooTools, Prototype, and Scriptacolous are both things of the past, and never implemented Math.mod ... so, with that approach, custom transpiling functions are more dangerous, as somebody might have implemented %% already for other purposes, and we break Babel outcome adding new syntax anyway ... the smoosh accident, is the equivalent of custom Babel utilities these days.

Look at TypeScript and the private class fields, if you want to compare new syntax instead

# Andrea Giammarchi (5 years ago)

Fair points, but since ** has its Math.pow counter part, why wouldn't %% have Math.mod as counterpart too? At least it looks like there's room for both, if standardized, as the behavior and description would likely be mostly the same (precedence a part)

# Jordan Harband (5 years ago)

Static functions don't have the same risk as prototype functions; Math.mod would make sense to add.

One suggestion, though, would be to try to add the API method first, and look at usage for awhile before trying to add the syntax.

# Isiah Meadows (5 years ago)

BTW, I just wrote up a more precise, formalized proposal over here: isiahmeadows/proposal-divisor-dependent-modulo, and I'd be more than willing to work with a TC39 champion on it. I personally prefer syntax (pretty strongly), but I'm not beholden to it.

I do feel the semantics are simple enough it'd be okay to lower it to syntax, and it naturally just glides right in. I find it very odd that some languages use a simple operator % or relatively short function for remainder keeping the sign of the dividend but relegate the version keeping the sign of the divisor (the more useful and intuitive of them) to a much more verbose function call. Of all Wikipedia lists in en.wikipedia.org/wiki/Modulo_operation, here's the four that do this currently - all but one expose an operator for the first:

  • Fortran: mod for dividend-dependent, modulo for divisor-dependent
  • Julia: %/rem for dividend-dependent, mod for divisor-dependent
  • Java: % for dividend-dependent, Math.floorMod for divisor-dependent
  • XBase++: % for dividend-dependent, Mod for divisor-dependent

And it's worth noting most other languages (including some end user-oriented ones) that show a syntactic preference to one or the other expose a simpler one where the sign matches the divisor, a more complicated one where the sign matches the dividend. For a variety of examples:

  • Ruby: %/modulo for divisor-dependent, remainder for dividend-dependent
  • SML: mod for divisor-dependent, Int.rem for dividend-dependent
  • Elm: modBy for divisor-dependent, remainderBy for dividend-dependent
  • Euphoria: mod for divisor-dependent, remainder for dividend-dependent
  • Python: % for divisor-dependent, math.fmod for dividend-dependent
  • Smalltalk: \\ for divisor-dependent, rem: for dividend-dependent

And of course, many don't even expose a type of modulo where the sign matches the divisor. For some examples:

  • APL
  • LibreOffice/Excel
  • Lua
  • Perl
  • Mathematica
  • PL/I
  • TCL

There's also Dart, a relatively new language which defaults to non-negative always.

This relatively long list of languages, despite C's heritage and semantics being inherited in much of them, makes me question using a function for this, and there would need to be a lot of FUD to get people to use the function more than the operator.

So this is why I would prefer an operator as opposed to syntax for this.


Isiah Meadows contact at isiahmeadows.com, www.isiahmeadows.com

# Matthew Morgan (5 years ago)

Isiah, thank you for composing this proposal.

# peter miller (5 years ago)

+1 for at_least having Math.mod()

And here's a reason why:

The code mod = (x,y) => ( ( x % y ) + y ) % y is not only slow but

inaccurate. For example, for mod( -249825144445569.97, -2022673516699079.8) gives -249825144445569.75 (Chrome Version
77.0.3865.35) instead of -249825144445569.97

I then switched to mod = (x,y) => x - Math.floor( x / y ) * y which

gives an accurate answer, and is faster.

But, on a hunch that flow control would be faster than arithmetic, I
devised this:

mod = (x,y) => {
   const z = x % y;
   return  (y >= 0 && z >= 0 ) || ( y < 0 && z <= 0 ) ? z : y + z;
}

And that is sometimes the fastest approach -- assuming I haven't screwed
up the maths; cf jsbench.me/lrjze7oqv9/2 Although it does seem to
depend on the numbers - with the Math.floor() approach sometimes coming
out faster.

And this all neglects BigInts, Infinites, NaNs, and signed zeroes.

So this isn't a trivial function to polyfill. And, for that reason alone,
it should be in the standard. (And if we get it in Math, and convince
people to use it, then the pressure for a more ergonomic solution will
increase.)

Peter

# kdex (5 years ago)

Reply inline.

On Friday, August 16, 2019 5:50:40 PM CEST peter miller wrote:

Hi,

+1 for at_least having Math.mod()

And here's a reason why:

The code mod = (x,y) => ( ( x % y ) + y ) % y is not only slow but inaccurate. For example, for mod( -249825144445569.97, -2022673516699079.8) gives -249825144445569.75 (Chrome Version 77.0.3865.35) instead of -249825144445569.97

I then switched to mod = (x,y) => x - Math.floor( x / y ) * y which gives an accurate answer, and is faster.

But, on a hunch that flow control would be faster than arithmetic, I devised this:

mod = (x,y) => {
   const z = x % y;
   return  (y >= 0 && z >= 0 ) || ( y < 0 && z <= 0 ) ? z : y + z;
}

And that is sometimes the fastest approach -- assuming I haven't screwed up the maths; cf jsbench.me/lrjze7oqv9/2 Although it does seem to depend on the numbers - with the Math.floor() approach sometimes coming out faster.

And this all neglects BigInts, Infinites, NaNs, and signed zeroes.

Most, if not all, functions on the Math prototype can't handle BigInt, but that's a separate issue.

While it would be nice if Math.mod supported that, another Math proposal could spec that along with fixes for all the other methods.

For now, it should be good enough if we had a modulo operation at all.

# Alex Gordon (5 years ago)

Code that uses % is often surprisingly buggy. For example even a simple function such as this is broken if n is negative:

function isOdd(n) { return n % 2 === 1; }

isOdd(-3) // false

The same is not true in other programming languages. The same in Python works just fine:

def isOdd(n): return n % 2 == 1

isOdd(-3) // true

The advantage of an operator over a function is that it allows us to say to people who are new to JS: "Always use %% instead of % unless you have a good reason". Just the same as we say "Always use === instead of == unless you have a good reason".

# Isiah Meadows (5 years ago)

BTW, that very example is something I cover in my proposal's introduction. It's also part of why I want an operator - this is one of the few times where spreading FUD is a good idea IMHO. isiahmeadows/proposal-divisor-dependent-modulo


Isiah Meadows contact at isiahmeadows.com, www.isiahmeadows.com

# Cyril Auburtin (5 years ago)

Another typical example:

const normalizeHue = hue => (((hue % 360) + 360) % 360) / 360; // phew..

// would become:
const normalizeHue = hue => (hue %% 360) / 360;
# Matthew Morgan (5 years ago)

Now how does this get to becoming a proposal? Is there a TC39 member that has seen this and will introduce it to the committee?