April 12, 2019
On Friday, 12 April 2019 at 06:52:39 UTC, aliak wrote:
> On Friday, 12 April 2019 at 02:13:12 UTC, Walter Bright wrote:
>> On 4/11/2019 6:24 PM, Timon Gehr wrote:
>>>>    bool isOdd(int i) { return i & 1; }
>>>>
>>>> Filling the standard library with trivia is not a good idea.
>>> 
>>> Yes, if it is used often enough across many projects, adding functions with a simple implementation can be a very good idea. The main point is to standardize the function name and avoid duplicated equivalent code in everyone's personal util libraries.
>>
>> That would make sense if there was some application-specific higher level meaning to oddness, such as maybe the low bit being used as a flag. But there isn't when it is named "isOdd".
>>
>
> I've used n % 2 == 0 millions of times in GUI logic. Applying properties to things that are row'ed-out. Games is another one - very common. Fuzzy matching another one. isOdd would've made the call site a lot more clear.
>
>>
>>>> Not knowing about a common operator is not a reason to add library functions.
>>> No, but there can be other reasons.
>>
>> That was the reason given. I'm open to hearing a better one.
>
> Using n & 1 has always been a hack for oddness. It says nothing about what your code is doing. The average programmer would look at it and have to think about what's happening there.
>
> I do understand what you mean about being a bit suspicious about isOdd though when seeing it in code. But I think the same would apply to abs if we had not grown up with it being in math.h. We'd be doing "n>0?n:-n" or "(n+(n>>31))^(n>>31)" - or the more saner would write their own. And then when someone comes and tries to add abs to a standard library functions one could also say "not knowing about [a] common operator[s] is not a reason to add a library functions".

funny you mention abs(). My current job was enabled because the project leader was impressed with my optimisation skill. The first change I made in the code base (in the Levenshtein routine) was to replace the call to abs() by a macro doing nothing more fancy than "n>0?n:-n". The gain in performance was so massive, it completely floored me at that time. People underestimate the cost of a call, especially into a dynamic library (it is an indirect jump via the GOT), if it is in the hot loop it can be a massive cycle waster.


>
> But after all this time working on products as low level as drivers to as high level as web apps, the three things that have been the most important have been readability, maintainability, and correctness.


April 12, 2019
On Friday, 12 April 2019 at 10:45:15 UTC, Walter Bright wrote:
> On 4/11/2019 9:19 PM, Mike Franklin wrote:
>> And what do you have to say about this gem? https://github.com/dlang/dmd/blob/4c65b8726a66314e12ad1cad66b099d358e7165d/src/dmd/optimize.d#L62-L65
>
> Glad you asked. I added it so I could hook the return, which I often do when debugging.
>
>
>> Or this? https://github.com/dlang/dmd/blob/master/src/dmd/clone.d#L150-L154
>
> The commented out printf gives away the purpose.
>
>
>> It's the same thing.
>
> Nope.

Ok, you got me, Walter.  Touchez.
April 12, 2019
On 4/11/2019 11:14 PM, Nick Sabalausky (Abscissa) wrote:
> But here's the problem: That's your superpower. It's enviable, it's impressive, but it's absolutely NOT shared by the vast majority of GOOD programmers, let alone rank-and-file ones.

Knowing what (x & 1) is is a superpower? What about (x + x) ?

I'll cop to knowing half the x86 hex opcodes is a tad unusual, like knowing all the dialog to Star Trek TOS, but not (x & 1).

(Before you ask, the opcodes applies to me, the STTOS applies to at least 3 people I know.)

If you want isOdd() for your own personal library, feel free. Putting it into Phobos, however, is not happening.
April 12, 2019
On Friday, 12 April 2019 at 10:52:00 UTC, Patrick Schluter wrote:
> [snip]
>
> funny you mention abs(). My current job was enabled because the project leader was impressed with my optimisation skill. The first change I made in the code base (in the Levenshtein routine) was to replace the call to abs() by a macro doing nothing more fancy than "n>0?n:-n". The gain in performance was so massive, it completely floored me at that time. People underestimate the cost of a call, especially into a dynamic library (it is an indirect jump via the GOT), if it is in the hot loop it can be a massive cycle waster.
>

Was this C code (based on the reference to macros)? Could you get the same performance boost by pulling abs out into a static library?
April 12, 2019
On 4/11/2019 11:52 PM, aliak wrote:
> isOdd would've made the call site a lot more clear.

Feel free to add such a function to your code.


> Using n & 1 has always been a hack for oddness. It says nothing about what your code is doing.

isOdd() doesn't say what your code is doing, either.


> The average programmer would look at it and have to think about what's happening there.

I'm happy to elevate them to the next level with such thoughts :-)


> But after all this time working on products as low level as drivers to as high level as web apps, the three things that have been the most important have been readability, maintainability, and correctness.

(x & 1) isn't any harder to read than (x + 1).

More bluntly, it'll be hard for someone to succeed with D if they have only a vague understanding of what 2's complement arithmetic is, and a conceptual problem with the & operator. isOdd() isn't going to fix that for them.

April 12, 2019
On 4/11/2019 11:52 PM, aliak wrote:
> But I think the same would apply to abs if we had not grown up with it being in math.h. We'd be doing "n>0?n:-n" or "(n+(n>>31))^(n>>31)" - or the more saner would write their own. And then when someone comes and tries to add abs to a standard library functions one could also say "not knowing about [a] common operator[s] is not a reason to add a library functions".

abs() is different. Note that `n` appears multiple times in your examples, which matters if the expression `n` contains side effects. This side effect problem is a common one C programmers encounter when they use an abs() macro.

Avoiding the side effect without using the function can be awkward, thus justifying the function.
April 12, 2019
On 4/11/2019 11:20 PM, aliak wrote:
>  From Chris Lattner (swift/llvm creator): "I think that first class support for Windows is a critical thing, and I doubt anyone in the Swift community would object to it. The problem is that we need to find someone who wants it badly enough and has the resources/know-how to make it happen."

They haven't sent me an offer so they can't want it that bad :-)

But I'm too old to be a "cultural fit", so you guys are stuck with me.
April 12, 2019
On Friday, 12 April 2019 at 11:03:21 UTC, Walter Bright wrote:
> Knowing what (x & 1) is is a superpower? What about (x + x) ?

Most new programmers have a math background and (x + x) is taught in middle school. CPU math can be very unintuitive however. You might not raise an eyebrow when I state `1/2 == 0` or `1.0 - 0.9 - 0.1 != 0`, but it surprises newcomers.
(x & 1) assumes knowledge of bitwise operators and integer representations (it wouldn't work on negative integers in 1's complement).

This is part of a student's implementation of a hash function in Java, taken from an algorithms course I was teaching assistant for:
```
String bstring = Integer.toBinaryString(b);
if(bstring.length() > 31) {
  bstring = bstring.substring(bstring.length() - 31, bstring.length());
}
b = Integer.parseInt(bstring, 2);
```
The description of the last step was "H = (the last 31 bits of of b) mod s".
Many students did it like this. It's tempting to think they are just ignorant, but is it really reasonable to expect ANY programmer to be comfortable with bit-math?

> If you want isOdd() for your own personal library, feel free. Putting it into Phobos, however, is not happening.

I can't speak for everyone, but I'm not vowing for anything like this in D. D is a system's programming language, and it can expect a certain of level of proficiency of its adopters.
I just feel like some responses here express the sentiment 'look what a dumb decision Swift developers just made', while I think that it can be very reasonable given the userbase of Swift.
April 12, 2019
On 4/12/19 7:03 AM, Walter Bright wrote:
> On 4/11/2019 11:14 PM, Nick Sabalausky (Abscissa) wrote:
>> But here's the problem: That's your superpower. It's enviable, it's impressive, but it's absolutely NOT shared by the vast majority of GOOD programmers, let alone rank-and-file ones.
> 
> Knowing what (x & 1) is is a superpower? What about (x + x) ?
> 
> I'll cop to knowing half the x86 hex opcodes is a tad unusual, like knowing all the dialog to Star Trek TOS, but not (x & 1).
> 
> (Before you ask, the opcodes applies to me, the STTOS applies to at least 3 people I know.)
> 
> If you want isOdd() for your own personal library, feel free. Putting it into Phobos, however, is not happening.

Here's the deal:

1. You don't include it in the standard library.
2. People who don't know the best way look it up on stackoverflow, and learn that they can do x & 1.
3. Now they have a superpower too. Win-win.

-Steve
April 12, 2019
On 12.04.19 04:13, Walter Bright wrote:
> On 4/11/2019 6:24 PM, Timon Gehr wrote:
>>>    bool isOdd(int i) { return i & 1; }
>>>
>>> Filling the standard library with trivia is not a good idea.
>>
>> Yes, if it is used often enough across many projects, adding functions with a simple implementation can be a very good idea. The main point is to standardize the function name and avoid duplicated equivalent code in everyone's personal util libraries.
> 
> That would make sense if there was some application-specific higher level meaning to oddness, such as maybe the low bit being used as a flag. But there isn't when it is named "isOdd".
> ...

Parity is an important property of integers. Not all integer data types support efficient bitwise arithmetic.

> 
>>> Not knowing about a common operator is not a reason to add library functions.
>> No, but there can be other reasons.
> 
> That was the reason given. I'm open to hearing a better one.

std/range/primitives.d
---
@property ref T front(T)(T[] a) @safe pure nothrow @nogc
if (!isNarrowString!(T[]) && !is(T[] == void[]))
{
    assert(a.length, "Attempting to fetch the front of an empty array of " ~ T.stringof);
    return a[0];
}
--

"Who's the clown who's put that there? Don't D programmers know about the array index operator?!"