'Double modulo' operator

Hello,

I think that Swift could use the 'double modulo' operator which is for
example in CoffeeScript (some discussion can be found here
Issues · jashkenas/coffeescript · GitHub).

This operator, unlike normal modulo, takes sign from the divisor, not the
dividend e.g. -10 % 3 == -1, but -10 %% 3 == 2.

In practice, this operator is useful for 'cyclical' indexing. For example,
it would be useful for calculating the real index into a collection when we
are using an index outside of the range of valid indices and could be used
to index into a collection using a negative index à la Python and Ruby
(where [1,2,3,4][-1] == 4).

The implementation would probably be something along these lines:

infix operator %% {
  associativity left
  precedence 150
}

func %%<T: IntegerArithmeticType>(lhs:T, rhs:T) -> T {
  return (lhs % rhs + rhs) % rhs
}

If accepted, this could be later incorporated into a method or operator
that works directly with collections using their count property.
Maybe the syntax could be something like [1,2,3,4] %% -1 == 4.

Ideas, suggestions?

Adam, I think this is a very particular case and not something that needs
to be added to the language. As you pointed out this already can be
implemented using resources already available in the language when needed.

···

On 21 May 2016 at 17:22, Adam Nemecek via swift-evolution < swift-evolution@swift.org> wrote:

Hello,

I think that Swift could use the 'double modulo' operator which is for
example in CoffeeScript (some discussion can be found here
Issues · jashkenas/coffeescript · GitHub).

This operator, unlike normal modulo, takes sign from the divisor, not the
dividend e.g. -10 % 3 == -1, but -10 %% 3 == 2.

In practice, this operator is useful for 'cyclical' indexing. For example,
it would be useful for calculating the real index into a collection when we
are using an index outside of the range of valid indices and could be used
to index into a collection using a negative index à la Python and Ruby
(where [1,2,3,4][-1] == 4).

The implementation would probably be something along these lines:

infix operator %% {
  associativity left
  precedence 150
}

func %%<T: IntegerArithmeticType>(lhs:T, rhs:T) -> T {
  return (lhs % rhs + rhs) % rhs
}

If accepted, this could be later incorporated into a method or operator
that works directly with collections using their count property.
Maybe the syntax could be something like [1,2,3,4] %% -1 == 4.

Ideas, suggestions?

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

This is one of those things that takes very little to add, I would use it if it existed (having written workarounds), but it isn't horrible not having it there.

The only place off the top of my head that I consistently use it for is wrapping, but that's a really nice use case.

-- E

···

On May 21, 2016, at 2:22 PM, Adam Nemecek via swift-evolution <swift-evolution@swift.org> wrote:

Hello,

I think that Swift could use the 'double modulo' operator which is for example in CoffeeScript (some discussion can be found here Issues · jashkenas/coffeescript · GitHub).

This operator, unlike normal modulo, takes sign from the divisor, not the dividend e.g. -10 % 3 == -1, but -10 %% 3 == 2.

In practice, this operator is useful for 'cyclical' indexing. For example, it would be useful for calculating the real index into a collection when we are using an index outside of the range of valid indices and could be used to index into a collection using a negative index à la Python and Ruby (where [1,2,3,4][-1] == 4).

The implementation would probably be something along these lines:

infix operator %% {
  associativity left
  precedence 150
}

func %%<T: IntegerArithmeticType>(lhs:T, rhs:T) -> T {
  return (lhs % rhs + rhs) % rhs
}

If accepted, this could be later incorporated into a method or operator that works directly with collections using their count property.
Maybe the syntax could be something like [1,2,3,4] %% -1 == 4.

Ideas, suggestions?
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

4 Likes

+1, I’ve never actually wanted a negative return value from %. Array subscripting and getting an enum case from a raw integer value both expect non-negative integers, so in these cases it only makes sense to deal with positive values.

···

Hello,

I think that Swift could use the 'double modulo' operator which is for example in CoffeeScript (some discussion can be found herehttps://github.com/jashkenas/coffeescript/issues/1971).

This operator, unlike normal modulo, takes sign from the divisor, not the dividend e.g. -10 % 3 == -1, but -10 %% 3 == 2.

In practice, this operator is useful for 'cyclical' indexing. For example, it would be useful for calculating the real index into a collection when we are using an index outside of the range of valid indices and could be used to index into a collection using a negative index à la Python and Ruby (where [1,2,3,4][-1] == 4).

The implementation would probably be something along these lines:

infix operator %% {
associativity left
precedence 150
}

func %%<T: IntegerArithmeticType>(lhs:T, rhs:T) ->T {
return (lhs % rhs + rhs) % rhs
}

If accepted, this could be later incorporated into a method or operator that works directly with collections using their count property.
Maybe the syntax could be something like [1,2,3,4] %% -1 == 4.

Ideas, suggestions?_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

1 Like

I’m not really sold on the `%%` spelling, but I think the operation itself is worth exposing. This is the remainder of a “flooring” division (as opposed to the C-family “truncating” division[1]). If we do provide it, we should also provide the accompanying divide operation.

– Steve

[1] there are several other ways to define division beyond these two: remainder is always positive, remainder is closest to zero, etc. Truncating and flooring division are the most common by a wide margin, however.

···

On May 21, 2016, at 4:22 PM, Adam Nemecek via swift-evolution <swift-evolution@swift.org> wrote:

Hello,

I think that Swift could use the 'double modulo' operator which is for example in CoffeeScript (some discussion can be found here Issues · jashkenas/coffeescript · GitHub).

This operator, unlike normal modulo, takes sign from the divisor, not the dividend e.g. -10 % 3 == -1, but -10 %% 3 == 2.

In practice, this operator is useful for 'cyclical' indexing. For example, it would be useful for calculating the real index into a collection when we are using an index outside of the range of valid indices and could be used to index into a collection using a negative index à la Python and Ruby (where [1,2,3,4][-1] == 4).

The implementation would probably be something along these lines:

infix operator %% {
  associativity left
  precedence 150
}

func %%<T: IntegerArithmeticType>(lhs:T, rhs:T) -> T {
  return (lhs % rhs + rhs) % rhs
}

If accepted, this could be later incorporated into a method or operator that works directly with collections using their count property.
Maybe the syntax could be something like [1,2,3,4] %% -1 == 4.

Ideas, suggestions?
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

3 Likes

I think this is a very particular case

I disagree. Swift has the concept of a range all over the place and this is
a fundamental range operation.

As you pointed out this already can be implemented using resources

already available in the language when needed.

Right. A lot of things in the standard library can be implemented using
resources already available, it's about the ergonomics.

···

On Sat, May 21, 2016 at 1:44 PM, Leonardo Pessoa <me@lmpessoa.com> wrote:

Adam, I think this is a very particular case and not something that needs
to be added to the language. As you pointed out this already can be
implemented using resources already available in the language when needed.

On 21 May 2016 at 17:22, Adam Nemecek via swift-evolution < > swift-evolution@swift.org> wrote:

Hello,

I think that Swift could use the 'double modulo' operator which is for
example in CoffeeScript (some discussion can be found here
Issues · jashkenas/coffeescript · GitHub).

This operator, unlike normal modulo, takes sign from the divisor, not the
dividend e.g. -10 % 3 == -1, but -10 %% 3 == 2.

In practice, this operator is useful for 'cyclical' indexing. For
example, it would be useful for calculating the real index into a
collection when we are using an index outside of the range of valid indices
and could be used to index into a collection using a negative index à la
Python and Ruby (where [1,2,3,4][-1] == 4).

The implementation would probably be something along these lines:

infix operator %% {
  associativity left
  precedence 150
}

func %%<T: IntegerArithmeticType>(lhs:T, rhs:T) -> T {
  return (lhs % rhs + rhs) % rhs
}

If accepted, this could be later incorporated into a method or operator
that works directly with collections using their count property.
Maybe the syntax could be something like [1,2,3,4] %% -1 == 4.

Ideas, suggestions?

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Adam, there is no need for an operator to compute the real index using
a negative index. You can simply use arr.endIndex.advancedBy(-1) for
that or, in this particular case, arr.endIndex.predecessor(). Right
now this is the standard, although I''d rather use int indices
directly.

···

On 21 May 2016 at 17:56, Adam Nemecek <adamnemecek@gmail.com> wrote:

I think this is a very particular case

I disagree. Swift has the concept of a range all over the place and this is
a fundamental range operation.

As you pointed out this already can be implemented using resources
already available in the language when needed.

Right. A lot of things in the standard library can be implemented using
resources already available, it's about the ergonomics.

On Sat, May 21, 2016 at 1:44 PM, Leonardo Pessoa <me@lmpessoa.com> wrote:

Adam, I think this is a very particular case and not something that needs
to be added to the language. As you pointed out this already can be
implemented using resources already available in the language when needed.

On 21 May 2016 at 17:22, Adam Nemecek via swift-evolution >> <swift-evolution@swift.org> wrote:

Hello,

I think that Swift could use the 'double modulo' operator which is for
example in CoffeeScript (some discussion can be found here
Issues · jashkenas/coffeescript · GitHub).

This operator, unlike normal modulo, takes sign from the divisor, not the
dividend e.g. -10 % 3 == -1, but -10 %% 3 == 2.

In practice, this operator is useful for 'cyclical' indexing. For
example, it would be useful for calculating the real index into a collection
when we are using an index outside of the range of valid indices and could
be used to index into a collection using a negative index à la Python and
Ruby (where [1,2,3,4][-1] == 4).

The implementation would probably be something along these lines:

infix operator %% {
  associativity left
  precedence 150
}

func %%<T: IntegerArithmeticType>(lhs:T, rhs:T) -> T {
  return (lhs % rhs + rhs) % rhs
}

If accepted, this could be later incorporated into a method or operator
that works directly with collections using their count property.
Maybe the syntax could be something like [1,2,3,4] %% -1 == 4.

Ideas, suggestions?

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Would you want to make this a function? Or an operator but a different one?

···

On Mon, May 23, 2016 at 7:30 AM, Stephen Canon <scanon@apple.com> wrote:

I’m not really sold on the `%%` spelling, but I think the operation itself
is worth exposing. This is the remainder of a “flooring” division (as
opposed to the C-family “truncating” division[1]). If we do provide it, we
should also provide the accompanying divide operation.

– Steve

[1] there are several other ways to define division beyond these two:
remainder is always positive, remainder is closest to zero, etc.
Truncating and flooring division are the most common by a wide margin,
however.

On May 21, 2016, at 4:22 PM, Adam Nemecek via swift-evolution < > swift-evolution@swift.org> wrote:

Hello,

I think that Swift could use the 'double modulo' operator which is for
example in CoffeeScript (some discussion can be found here
Issues · jashkenas/coffeescript · GitHub).

This operator, unlike normal modulo, takes sign from the divisor, not the
dividend e.g. -10 % 3 == -1, but -10 %% 3 == 2.

In practice, this operator is useful for 'cyclical' indexing. For example,
it would be useful for calculating the real index into a collection when we
are using an index outside of the range of valid indices and could be used
to index into a collection using a negative index à la Python and Ruby
(where [1,2,3,4][-1] == 4).

The implementation would probably be something along these lines:

infix operator %% {
  associativity left
  precedence 150
}

func %%<T: IntegerArithmeticType>(lhs:T, rhs:T) -> T {
  return (lhs % rhs + rhs) % rhs
}

If accepted, this could be later incorporated into a method or operator
that works directly with collections using their count property.
Maybe the syntax could be something like [1,2,3,4] %% -1 == 4.

Ideas, suggestions?
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

It's a fundamental mathematical operator (it's actually the 'true modulo'
operation), the % operator is the remainder operation. This distinction is
not a made up distinction (e.g.

)

You can simply use arr.endIndex.advancedBy(-1) for

You are not taking into account when a function is passed an argument and
needs it to be in some range. It's not that it's impossible to implement,
it's just that this is more ergonomic.

···

On Sat, May 21, 2016 at 2:09 PM, Leonardo Pessoa <me@lmpessoa.com> wrote:

Adam, there is no need for an operator to compute the real index using
a negative index. You can simply use arr.endIndex.advancedBy(-1) for
that or, in this particular case, arr.endIndex.predecessor(). Right
now this is the standard, although I''d rather use int indices
directly.

On 21 May 2016 at 17:56, Adam Nemecek <adamnemecek@gmail.com> wrote:
>> I think this is a very particular case
>
> I disagree. Swift has the concept of a range all over the place and this
is
> a fundamental range operation.
>
>> As you pointed out this already can be implemented using resources
>> already available in the language when needed.
>
> Right. A lot of things in the standard library can be implemented using
> resources already available, it's about the ergonomics.
>
>
>
> On Sat, May 21, 2016 at 1:44 PM, Leonardo Pessoa <me@lmpessoa.com> > wrote:
>>
>> Adam, I think this is a very particular case and not something that
needs
>> to be added to the language. As you pointed out this already can be
>> implemented using resources already available in the language when
needed.
>>
>>
>>
>> On 21 May 2016 at 17:22, Adam Nemecek via swift-evolution > >> <swift-evolution@swift.org> wrote:
>>>
>>> Hello,
>>>
>>> I think that Swift could use the 'double modulo' operator which is for
>>> example in CoffeeScript (some discussion can be found here
>>> Issues · jashkenas/coffeescript · GitHub).
>>>
>>> This operator, unlike normal modulo, takes sign from the divisor, not
the
>>> dividend e.g. -10 % 3 == -1, but -10 %% 3 == 2.
>>>
>>> In practice, this operator is useful for 'cyclical' indexing. For
>>> example, it would be useful for calculating the real index into a
collection
>>> when we are using an index outside of the range of valid indices and
could
>>> be used to index into a collection using a negative index à la Python
and
>>> Ruby (where [1,2,3,4][-1] == 4).
>>>
>>>
>>> The implementation would probably be something along these lines:
>>>
>>> infix operator %% {
>>> associativity left
>>> precedence 150
>>> }
>>>
>>> func %%<T: IntegerArithmeticType>(lhs:T, rhs:T) -> T {
>>> return (lhs % rhs + rhs) % rhs
>>> }
>>>
>>> If accepted, this could be later incorporated into a method or operator
>>> that works directly with collections using their count property.
>>> Maybe the syntax could be something like [1,2,3,4] %% -1 == 4.
>>>
>>> Ideas, suggestions?
>>>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>
>

You are not taking into account when a function is passed an argument and needs it to be in some range.

If you pass an out-of-range argument, you should reject it using a precondition, thrown error, or nil return value. And if for some reason you really *do* want to force the value into the range, clamping it to the bounds of the range seems like a more sensible solution than modulo. I'm sure there are cases where you *would* want to do this, but they seem like they'd be few and far between.

···

--
Brent Royal-Gordon
Architechies

If you pass an out-of-range argument, you should reject it using a

precondition

Different use case. I have a circular buffer.

. And if for some reason you really *do* want to force the value into the

range, clamping it to the bounds of the range seems like a more sensible
solution than modulo

I have a circular buffer, I don't want to be clamping it to the bounds of
the range.

I'm sure there are cases where you *would* want to do this, but they seem

like they'd be few and far between.

It's the 'correct' implementation of modulo.

···

On Sat, May 21, 2016 at 4:40 PM, Brent Royal-Gordon <brent@architechies.com> wrote:

> You are not taking into account when a function is passed an argument
and needs it to be in some range.

If you pass an out-of-range argument, you should reject it using a
precondition, thrown error, or nil return value. And if for some reason you
really *do* want to force the value into the range, clamping it to the
bounds of the range seems like a more sensible solution than modulo. I'm
sure there are cases where you *would* want to do this, but they seem like
they'd be few and far between.

--
Brent Royal-Gordon
Architechies

I wouldn't mind if the standard `%` operator worked like this and there would be another top-level function `mod(p, q)` that worked like `%` in C. The only times that I've ever needed the modulo operation (https://en.wikipedia.org/wiki/Modulo_operation\) to behave some way on negative values it's always been the suggested remainder-of-flooring-division way.

On the other hand, there's a performance penalty (avoidable by using the other mod operation), so I can understand if not everyone agrees.

And like Steve said below, then we'll need a flooring division function (or operator) as well. And a flooring `(f, r) = divmod(p, q)` too, I suppose.

In any case, I'm probably +1 if a well-thought proposal is brought to the table.

— Pyry

···

Adam Nemecek wrote:

Would you want to make this a function? Or an operator but a different one?

On Mon, May 23, 2016 at 7:30 AM, Stephen Canon <scanon@apple.com> wrote:
I’m not really sold on the `%%` spelling, but I think the operation itself is worth exposing. This is the remainder of a “flooring” division (as opposed to the C-family “truncating” division[1]). If we do provide it, we should also provide the accompanying divide operation.

– Steve

[1] there are several other ways to define division beyond these two: remainder is always positive, remainder is closest to zero, etc. Truncating and flooring division are the most common by a wide margin, however.

1 Like

That kind of breaks backwards compatibility.

Also currently in swift, the % operator is called the remainder operator,
not the modulo operator, so technically the current implementation is
correct. In Haskell for example, there are two functions, rem (as in
remainder) and mod (as in modulo). I guess we could leave % to mean
remainder and introduce a mod function?

···

On Mon, May 23, 2016 at 11:59 AM, Pyry Jahkola <pyry.jahkola@iki.fi> wrote:

I wouldn't mind if the standard `%` operator worked like this and there
would be another top-level function `mod(p, q)` that worked like `%` in C.
The only times that I've ever needed the modulo operation (
https://en.wikipedia.org/wiki/Modulo_operation\) to behave *some way* on
negative values it's always been the suggested
remainder-of-flooring-division way.

On the other hand, there's a performance penalty (avoidable by using the
other mod operation), so I can understand if not everyone agrees.

And like Steve said below, then we'll need a flooring division function
(or operator) as well. And a flooring `(f, r) = divmod(p, q)` too, I
suppose.

In any case, I'm probably +1 if a well-thought proposal is brought to the
table.

— Pyry

Adam Nemecek wrote:

Would you want to make this a function? Or an operator but a different one?

On Mon, May 23, 2016 at 7:30 AM, Stephen Canon <scanon@apple.com> wrote:

I’m not really sold on the `%%` spelling, but I think the operation
itself is worth exposing. This is the remainder of a “flooring” division
(as opposed to the C-family “truncating” division[1]). If we do provide
it, we should also provide the accompanying divide operation.

– Steve

[1] there are several other ways to define division beyond these two:
remainder is always positive, remainder is closest to zero, etc.
Truncating and flooring division are the most common by a wide margin,
however.

I've had to write a "true mod" function enough times across different
projects (usually for circular buffer indexing or angular arithmetic) that
it would absolutely support its inclusion in stdlib (for both integer and
floating point types).

The `%` operator historically has been implemented as "remainder" though
(even when called "modulus"), so while it would be nice to be "pure" and
have `%` do the right thing, I think it would be too confusing for users to
have the operator have a subtly different meaning compared to every other
programming language that looks like it.

I'm not crazy about the `%%` spelling, but I can't think of anything better
either at the moment.

···

On Mon, May 23, 2016 at 12:24 PM Adam Nemecek via swift-evolution < swift-evolution@swift.org> wrote:

That kind of breaks backwards compatibility.

Also currently in swift, the % operator is called the remainder operator,
not the modulo operator, so technically the current implementation is
correct. In Haskell for example, there are two functions, rem (as in
remainder) and mod (as in modulo). I guess we could leave % to mean
remainder and introduce a mod function?

On Mon, May 23, 2016 at 11:59 AM, Pyry Jahkola <pyry.jahkola@iki.fi> > wrote:

I wouldn't mind if the standard `%` operator worked like this and there
would be another top-level function `mod(p, q)` that worked like `%` in C.
The only times that I've ever needed the modulo operation (
https://en.wikipedia.org/wiki/Modulo_operation\) to behave *some way* on
negative values it's always been the suggested
remainder-of-flooring-division way.

On the other hand, there's a performance penalty (avoidable by using the
other mod operation), so I can understand if not everyone agrees.

And like Steve said below, then we'll need a flooring division function
(or operator) as well. And a flooring `(f, r) = divmod(p, q)` too, I
suppose.

In any case, I'm probably +1 if a well-thought proposal is brought to the
table.

— Pyry

Adam Nemecek wrote:

Would you want to make this a function? Or an operator but a different
one?

On Mon, May 23, 2016 at 7:30 AM, Stephen Canon <scanon@apple.com> wrote:

I’m not really sold on the `%%` spelling, but I think the operation
itself is worth exposing. This is the remainder of a “flooring” division
(as opposed to the C-family “truncating” division[1]). If we do provide
it, we should also provide the accompanying divide operation.

– Steve

[1] there are several other ways to define division beyond these two:
remainder is always positive, remainder is closest to zero, etc.
Truncating and flooring division are the most common by a wide margin,
however.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

1 Like

You have both good points.

In that case, if we still want to define new operators here (which might not please everybody), then I'd suggest finding a common prefix or suffix character (e.g. `^/` and `^%`) for both the floored division and floored modulo (for one, because we can't define `//` as an operator).

But I think it'd be clearest to just make them both top-level functions, e.g. `floordiv(p, q)` and `floormod(p, q)`. If anyone uses either a lot, and likes to make it terse, it's easy to define a private operator wrapper for it.

— Pyry

···

Tony Allevato wrote:

I've had to write a "true mod" function enough times across different projects (usually for circular buffer indexing or angular arithmetic) that it would absolutely support its inclusion in stdlib (for both integer and floating point types).

The `%` operator historically has been implemented as "remainder" though (even when called "modulus"), so while it would be nice to be "pure" and have `%` do the right thing, I think it would be too confusing for users to have the operator have a subtly different meaning compared to every other programming language that looks like it.

I'm not crazy about the `%%` spelling, but I can't think of anything better either at the moment.

On Mon, May 23, 2016 at 12:24 PM Adam Nemecek via swift-evolution <swift-evolution@swift.org> wrote:
That kind of breaks backwards compatibility.

Also currently in swift, the % operator is called the remainder operator, not the modulo operator, so technically the current implementation is correct. In Haskell for example, there are two functions, rem (as in remainder) and mod (as in modulo). I guess we could leave % to mean remainder and introduce a mod function?

On Mon, May 23, 2016 at 11:59 AM, Pyry Jahkola <pyry.jahkola@iki.fi> wrote:
I wouldn't mind if the standard `%` operator worked like this and there would be another top-level function `mod(p, q)` that worked like `%` in C. The only times that I've ever needed the modulo operation (https://en.wikipedia.org/wiki/Modulo_operation\) to behave some way on negative values it's always been the suggested remainder-of-flooring-division way.

On the other hand, there's a performance penalty (avoidable by using the other mod operation), so I can understand if not everyone agrees.

And like Steve said below, then we'll need a flooring division function (or operator) as well. And a flooring `(f, r) = divmod(p, q)` too, I suppose.

In any case, I'm probably +1 if a well-thought proposal is brought to the table.

— Pyry

Adam Nemecek wrote:

Would you want to make this a function? Or an operator but a different one?

On Mon, May 23, 2016 at 7:30 AM, Stephen Canon <scanon@apple.com> wrote:
I’m not really sold on the `%%` spelling, but I think the operation itself is worth exposing. This is the remainder of a “flooring” division (as opposed to the C-family “truncating” division[1]). If we do provide it, we should also provide the accompanying divide operation.

– Steve

[1] there are several other ways to define division beyond these two: remainder is always positive, remainder is closest to zero, etc. Truncating and flooring division are the most common by a wide margin, however.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Seems like making it an operator will cause more issues than it solves. I think that floordiv and mod functions are probably the way to go. I'm going to wait a little longer for more feedback and write up a proposal at some point.

···

On Mon, May 23, 2016 at 1:20 PM -0700, "Pyry Jahkola" <pyry.jahkola@iki.fi> wrote:

You have both good points.
In that case, if we still want to define new operators here (which might not please everybody), then I'd suggest finding a common prefix or suffix character (e.g. `^/` and `^%`) for both the floored division and floored modulo (for one, because we can't define `//` as an operator).
But I think it'd be clearest to just make them both top-level functions, e.g. `floordiv(p, q)` and `floormod(p, q)`. If anyone uses either a lot, and likes to make it terse, it's easy to define a private operator wrapper for it.
— Pyry

Tony Allevato wrote:

I've had to write a "true mod" function enough times across different projects (usually for circular buffer indexing or angular arithmetic) that it would absolutely support its inclusion in stdlib (for both integer and floating point types).
The `%` operator historically has been implemented as "remainder" though (even when called "modulus"), so while it would be nice to be "pure" and have `%` do the right thing, I think it would be too confusing for users to have the operator have a subtly different meaning compared to every other programming language that looks like it.
I'm not crazy about the `%%` spelling, but I can't think of anything better either at the moment.
On Mon, May 23, 2016 at 12:24 PM Adam Nemecek via swift-evolution <swift-evolution@swift.org> wrote:
That kind of breaks backwards compatibility.
Also currently in swift, the % operator is called the remainder operator, not the modulo operator, so technically the current implementation is correct. In Haskell for example, there are two functions, rem (as in remainder) and mod (as in modulo). I guess we could leave % to mean remainder and introduce a mod function?

On Mon, May 23, 2016 at 11:59 AM, Pyry Jahkola <pyry.jahkola@iki.fi> wrote:
I wouldn't mind if the standard `%` operator worked like this and there would be another top-level function `mod(p, q)` that worked like `%` in C. The only times that I've ever needed the modulo operation (https://en.wikipedia.org/wiki/Modulo_operation\) to behave some way on negative values it's always been the suggested remainder-of-flooring-division way.
On the other hand, there's a performance penalty (avoidable by using the other mod operation), so I can understand if not everyone agrees.
And like Steve said below, then we'll need a flooring division function (or operator) as well. And a flooring `(f, r) = divmod(p, q)` too, I suppose.
In any case, I'm probably +1 if a well-thought proposal is brought to the table.
— Pyry
Adam Nemecek wrote:

Would you want to make this a function? Or an operator but a different one?
On Mon, May 23, 2016 at 7:30 AM, Stephen Canon <scanon@apple.com> wrote:
I’m not really sold on the `%%` spelling, but I think the operation itself is worth exposing. This is the remainder of a “flooring” division (as opposed to the C-family “truncating” division[1]). If we do provide it, we should also provide the accompanying divide operation.
– Steve
[1] there are several other ways to define division beyond these two: remainder is always positive, remainder is closest to zero, etc. Truncating and flooring division are the most common by a wide margin, however.

_______________________________________________

swift-evolution mailing list

swift-evolution@swift.org

https://lists.swift.org/mailman/listinfo/swift-evolution

Sorry for bumping this thread after more than two years, but it's because of a recent related post and my concurrence with the people upthread who says essentially:

  • I’ve never actually wanted a negative return value from %. It does what I need only as long as the lhs is positive, but not when it's negative. In fact, I wouldn't be surprised if many uses of % are in situations where only a positive lhs has been considered, and if the use case was generalized to work also for a negative lhs, the code wouldn't work as intended unless % is replaced with a "true modulo" operation.

  • I've had to write a true mod function enough times across different projects (circular buffer indexing, angular arithmetic, periodic boundary conditions, subdivision of coordinate grids in games or graphics apps, etc.) that I would absolutely support its inclusion in the Standard Library.

I also think that this thread has arrived at some important conclusions (especially the ones quoted above), so it seems better to continue this discussion here rather than in a new thread. And there might be one more thing that needs to be sorted out before a proposal:

@scanon: According to this Wikipedia article, especially the top right diagram, the requested remainder seems to be the one of a euclidean rather than floored division.

Also, from the related recent post I mentioned above:

Could you please clarify, to make sure we have the correct background for a potential proposal, is it floored or euclidean?

3 Likes

You've requested a different operation than @Adam_Nemecek. He described a floored division ("This operator, unlike normal modulo, takes sign from the divisor") and you've described a Euclidean division ("I'e never actually wanted a negative return value").The former is more common among languages.

1 Like

Sorry for the confusion and thanks for making me realize it was there.

To be clear, I did mean to describe the same operator that @Adam_Nemecek describes:

Which is the % operator of eg Python:

 7 %  3 ==  1
-7 %  3 ==  2
 7 % -3 == -2
-7 % -3 == -2

Here's the % operator of Swift (and eg C) for reference:

 7 %  3 ==  1
-7 %  3 == -1
 7 % -3 ==  1
-7 % -3 == -1

I frequently find myself needing it (ie Python's % operator) in use cases where the dividend (lhs) can be negative, but I've never had a use case where the divisor (rhs) can be negative, meaning I don't care much about negative divisors (rhs), and thus negative remainders (results). That's why I wrote "I’ve never actually wanted a negative return value from %", which I now realize is confusing.

Now, it might be that @Nevin describes a different operator, I'm not sure but he might have just made the same accidentally confusing statement as I did, and if so, he might also be describing Pythons %.

However, I am sure that both @Adam_Nemecek and I mean the operator that is Python's %, ie the one where the sign of the remainder (result) is always the same as the sign of the divisor (rhs).

So I guess my question can be simplified to:
What kind of division and remainder are implied by Python's % operator?

EDIT: I now realized that I misinterpreted the diagram of the Wikipedia article. I now see that the requested operation is the remainder of a floored division, just like @scanon said ... Again, sorry for the confusion. It would still be interesting to know if @Nevin also meant to describe this operation.

It is the floor division, as documented:

The floor division and modulo operators are connected by the following identity: x == (x//y)*y + (x%y)

Btw, this thread is titled “Double modulo operator” but we probably want a version for integers as well. All the above given use cases (such as cyclic indices) are about integers, not about floating point numbers.

1 Like