Even And Odd Integers
DISCLAIMER: This is not a proposal, just an idea
Several times recently I have been forced to identify even elements for the purposes of analyzing an array or other, similar groupings of data. After the second time I simply extended Int
and added an isEven
computed property, along with an isOdd
one to complement it (since they are inherently complimentary ideas).
After it came up several a few times I began to wonder if this is the sort of thing that should be included in the Standard Library (although I admittedly have no idea how much this problem affects other Swift users)
However, simply extending Int
wouldn't be appropriate for inclusion to the Standard Library; not just are there are a plethora of integer types, but it is also possible for users to define their own. Therefore, I recreated my extension for BinaryInteger
, a type inherited by all integers in the Standard Library (and presumably all custom integers as well).
Outline
The extension of BinaryInteger
(again, this protocol is inherited by all integers), would consist of two new computed variables, isOdd
and isEven
, both of which would be provided with a default implementation.
This default implementation is possible because BinaryInteger
already incorporates remainder operations, which are essential for determining whether a number is odd or even.
While only one property is technically needed, it is syntactically correct to provide both properties, as it makes more sense and feels more "swifty"
Implementation
implementation modified from feedback from @saagarjha
extension BinaryInteger {
///Returns true whenever the integer is even, otherwise it will return false
var isEven: Bool { return self % 2 == 0 }
///Returns true whenever the integer is odd, otherwise it will return false
var isOdd: Bool { return self % 2 != 0 }
}
Reasoning
While this solution is relatively simple and there are plenty of existing workarounds for this issue, this solution provides a syntactically nice way of querying an integer to see whether it is odd or even (eg. if 2.isOdd { /*Do Something */ }
) as well as one that is automatically implemented in all existing integer types as well as any custom ones a user implements.
Additionally, simplicity in Swift is important: the remainder (%
) operator, while one of the better known operators overall, is not one that will be immediately recognizable to those learning programming for their first time. Adding isOdd
and isEven
getters eliminates a common need for the operator, meaning that it could increase the amount of time before new developers would have to spend valuable time learning about it (in my own experience, which I realize will likely be different from others, the %
operator is of little importance most of the time).
This section was added based on feedback from @Letan
There are alternatives to this implementation that could have VERY bad performance, although these would almost certainly be implemented only by someone ignorant of the remainder operator. For example, it is feasible to attempt a switch to get the same sort of operation (using the description
property of an Int
and the final Character
of the resulting String
).
Other mistakes could be feasibly made by someone more experienced: for example creating an isEven
getter and having the isOdd
getter reference it (eg. var isOdd: Bool { return !isEven}
)
ABI Stability
This is a purely additive change, so it would have zero affect on ABI stability.
Because isOdd
and isEven
both receive default implementations, there would be no effort on the part of anyone to modify their custom integers (or for the Standard Library to change anything other than BinaryInteger
). Additionally, adopting BinaryInteger
would not increase in complexity.