Even and Odd Integers

My point was that testing for oddness by writing x % 2 == 1 rather than x % 2 != 0 makes it look like the author has an incomplete understanding of the semantics of %, and should be considered bad practice (even in cases where x would only ever be positive).

If this bad practice is common enough, it's an indication that % is not a "very fairly basic feature" and isOdd is not "trivially composable".

4 Likes

x % 2 == 1 tests that x is both positive and odd all in one go, which is entirely legitimate when the only expected inputs are positive. In no way is such testing of one's assumptions (for free, performance-wise!) bad practice.

I don't agree with this specific statement. I am only speaking in defense of isDivisible(by:) but divisibility is a component of the clearly-not-quite-so-clear semantics of % isDivisible(by:) would be a great addition.

Another one: It's pretty common to do odd/even striping of tables. In fact, it's so common that CSS has three syntaxes for its :nth-child selector: :nth-child(odd), :nth-child(even), and :nth-child(2n+1).

7 Likes

I am very strongly in favor of adding isDivisible(by:). I am on the fence about isOdd or isEven, but I figure they would get enough use in UI code that they are probably worth being there for beginners/convenience.

1 Like

<bikeshed>
It should be isEvenlyDivisible(by:), because 10 is divisible by 3. Just not evenly divisible.
</bikeshed>

Edited to add:

I'd be in favor of adding isOdd and isEven because:

:one: they increase readability and therefore expressivity

:two: It makes mapping or ternary logic simpler which increases readability and therefore expressivity

view.backgroundColor = row.isEven ? .white : .lightGray

vs

view.backgroundColor = (row % 2 == 0) ? .white : .lightGray // extra parentheses yuck
2 Likes

That's not standard usage, at least not in Number Theory (see e.g. here).

2 Likes

And are we seriously expecting that users of Swift will be well-versed in number theory in order to understand this distinction? Or could we help them understand what the method is actually doing by giving it a nice, descriptive name?

4 Likes

I think "is divisible" is descriptive enough. I've never heard anyone say that 10 is divisible by 3 (in the context of integers). Your comment seemed to imply that "10 is not divisible by 3" was technically wrong somehow, which is not true.

11 Likes

If I came across a method on an integer that was isDivisible(by:), I would assume it would return true for everything except zero, because nothing is divisible by zero, because division by zero is undefined.

100 is divisible by 42. 1 is divisible by 2. π is divisible by e. etc. I learned this all the way back when I was six or seven years old.

Then along comes Swift and tells me that what I've known for decades is wrong?

I get that there's this motivation to be as pedantically correct as possible. But we also need to account for general human understanding, and the intricacies of number theory and "what division actually means" is not general knowledge. Let's make this language forgiving and name things in such a way that we are teaching people what goes on, instead of making them wonder "wtf why doesn't this work like I expect it to"

ETA: 10 is absolutely divisible by 3, in the context of integers. I get back 3.

1 Like

The problem with that is that you first have to figure out who that "general human" is and what they actually understand. It might not be what either one of us two understand.

That said, I don't think it's too much to ask of people that they should learn what a method they want to use does. It's not like we rename "map" because people might think it has something to do with Apple Maps.

(Also "the intricacies of number theory" != "literally the first thing about Number Theory". Should we replace the type "Int" with "WholeNumberWithLimitedRange", too?)

5 Likes

I understand where you're coming from but I think "divisible" is generally considered to mean "able to be divided without a remainder".

Oxford definition for divisible (mathematics): (of a number) containing another number a number of times without a remainder. ‘24 is divisible by 4’

Wolfram also has a divisible function. "Divisible[n,m] is effectively equivalent to Mod[n,m]==0."

16 Likes

Type “is divisible by” (with quotes) into your favorite search engine. When I did, I found many high-ranked hits on pages clearly intended for a general audience, even a grade-school audience, not mathematicians. All the pages I checked clearly define “is divisible by” as equivalent to “leaves zero remainder when divided by”. It is unfair to say that definition demands the reader be “well-versed in number theory in order to understand”.

I'm not saying “is evenly divisible by” isn't also common usage. It is. But I personally don't like that phrasing, because it's got “even” embedded in it, which also means “divisible by two”, so why muddy the waters? If you want to be pedantic, “is exactly divisible by” avoids overloaded terms.

But I think “is divisible by” is generally understood to mean “leaves zero remainder when divided by”, and will be understood that way by most Swift users, regardless of mathematical background.

15 Likes

Iff we really wanted a different name to avoid possible ambiguity that I don't completely agree is there then I would suggest hasFactor(_:) (we shouldn't have to pronounce Integer, at least, because types)

At some point this reduction reaches absurdity. We have to assume some mathematical preliminaries. Can we assume users know what "+" means, or do we need to spell that out too? Swift integers don't add like normal integers; should it be x.addingOrPossiblyTrapping(y) instead? "is divisible by" is a totally standard phrase in semi-technical English, and easily searched for if anyone is confused.

4 Likes

As a non-native English speaker I immediately understand isDivisible(by:), but when I would come across isEvenlyDivisible(by:), I'd probably google for 'evenly divisible' to find out what that means.

2 Likes

I've never heard anyone use "is divisible" that way. Every time I've ever heard anyone say that x "is divisible by" y, they meant that the remainder of dividing x by y is zero. Your definition of the phrase is so trivial as to be completely useless. The only thing that your definition of "is divisible" can distinguish between is zero and not zero, which we already have a simpler and more idiomatic category for: non-zero.

3 Likes

i got more confused by isEvenlyDivisible(by:) bc it sounds like it has to do with the number being even

2 Likes

While I understand what you are trying to say, I think that for the vast majority of Swift users, isDivisible(by:) has the exact same connotation as isEvenlyDivisible(by:).

If an Int value can be divided in a way that my high school math teachers would consider mathematically correct (eg. 3/3 = 1 or 10/2 = 5) than I think that nearly all Swift programmers would intrinsically understand that isDivisible(by:) would return true while it would otherwise return false, if only because it wouldn't make sense to have something that returns true in all circumstances except when the parameter is zero.

Yes, you can divide 10 by 3, but that question isn't the question most people care about or mean. The english language (and presumably many others) are filled with questions and statements that technically have one meaning, but are interpreted another way.

The meaningful question is whether or not it divides without a remainder, which is the implied meaning of the question among everyone I've interacted with on the topic.

2 Likes