April 13, 2019
On 4/13/19 3:04 AM, Julian wrote:
> On Saturday, 13 April 2019 at 04:40:08 UTC, Walter Bright wrote:
>> On 4/12/2019 9:15 PM, Nick Sabalausky (Abscissa) wrote:
>>> If for you, they're the same level of abstraction, that's great. For most, it isn't.
>>
>> If you want to write a library of such, and contribute it to Dub, feel free. If you find an audience for it, great.
> 
> Done: https://code.dlang.org/packages/isodd

That we got to this kind of time investment is worrisome. There's so many places where work needs to go, and this is at the very best of negligible impact.

Ironically isOdd and isEven were not approved for Swift - see Implementation Notes. Instead, the only nontrivial function isMultiple was approved:

bool isMultiple(T)(T isThisMultiple, T of)
if (isIntegral!T)
{
    if (isThisMultiple == 0) return true;
    if (of == 0) return false;
    static if (T.min < 0)
        if (isThisMultiple == T.min && of == -1) return true;
    return isThisMultiple % of == 0;
}

Such a function has some subtleties and corner cases that even seasoned programmers can get wrong. It can't be reasonably written as inlined code. I find its presence in a language's standard library reasonable.

If isMultiple were proposed for Phobos, the argument should be centered on frequency of use. It does happen that such queries appear with a constant on the right (e.g. a power of two) but general queries for arbitrary integers are rare.
April 13, 2019
On Saturday, 13 April 2019 at 07:49:13 UTC, Nick Sabalausky (Abscissa) wrote:
> On 4/13/19 1:37 AM, Walter Bright wrote:
>> On 4/12/2019 10:18 PM, H. S. Teoh wrote:
>>> writing (x % 2) conveys intent much better
>>> than (x & 1).
>> 
>> They produced different code. Try this with your favorite C compiler:
>> 
>> int foo(int x)
>> {
>>      return x % 2;
>> }
>> 
>> int bar(int x)
>> {
>>      return x & 1;
>> }
>
> Sounds like compiler room-for-improvement.

No. The code is different since C99 requires that modulo of negative dividends return a negative result.
   foo(-1) = -1
   bar(-1) = 1
April 13, 2019
On Saturday, 13 April 2019 at 07:04:23 UTC, Julian wrote:
> On Saturday, 13 April 2019 at 04:40:08 UTC, Walter Bright wrote:
>> On 4/12/2019 9:15 PM, Nick Sabalausky (Abscissa) wrote:
>>> If for you, they're the same level of abstraction, that's great. For most, it isn't.
>>
>> If you want to write a library of such, and contribute it to Dub, feel free. If you find an audience for it, great.
>
> Done: https://code.dlang.org/packages/isodd
>
> It doesn't seem like there's a way to run library unit tests
> with dub?
>
> I'll add non-manpage documentation later.
>
> And a logo, of course.

;-)
I'm stuck trying to think of a good logo....
April 13, 2019
On Saturday, 13 April 2019 at 07:04:23 UTC, Julian wrote:
> On Saturday, 13 April 2019 at 04:40:08 UTC, Walter Bright wrote:
>> On 4/12/2019 9:15 PM, Nick Sabalausky (Abscissa) wrote:
>>> If for you, they're the same level of abstraction, that's great. For most, it isn't.
>>
>> If you want to write a library of such, and contribute it to Dub, feel free. If you find an audience for it, great.
>
> Done: https://code.dlang.org/packages/isodd
>
> It doesn't seem like there's a way to run library unit tests
> with dub?
>
> I'll add non-manpage documentation later.
>
> And a logo, of course.

Hi posted a review on IRC:

[13:10] <B4S1L3> It's a joke but I already see several bad things
[13:11] <B4S1L3> 1. parameter should be const to prevent superfluous template instantiation
[13:11] <B4S1L3> 2. no module name
[13:11] <B4S1L3> 3. pragma(inline, true) not there
[13:12] <B4S1L3> 4. no test for BigInt
[13:12] <B4S1L3> "X" needs works, see review comments ;)
[13:13] <alphaglosined> expression isOdd(T:ulong)(T value) => value & 1;
[13:13] <B4S1L3> 5. floating point is accepted
...
[13:15] <B4S1L3> so you see, this isOdd function we joke about. The package is not good. It's not phobos-grade at least
April 13, 2019
On Saturday, 13 April 2019 at 12:13:36 UTC, Basile B. wrote:
> Hi posted a review on IRC:
>
> [13:10] <B4S1L3> It's a joke but I already see several bad things
> [13:11] <B4S1L3> 1. parameter should be const to prevent superfluous template instantiation

To be clear, the actual problem with that is that error messages
aren't as clear, in some misuse like isOdd("not even a number") ?

And that a misuse will *accidentally* work, if & is overloaded.

> [13:11] <B4S1L3> 2. no module name

It has one though: isodd, the name of the file. Making that
explicit might make it more like phobos modules but it probably
also needs different style braces, javadoc-style comments, etc.

> [13:11] <B4S1L3> 3. pragma(inline, true) not there

I hadn't heard about that.

@nogc @safe and such should also be there I suppose.

> [13:12] <B4S1L3> 4. no test for BigInt
> [13:12] <B4S1L3> "X" needs works, see review comments ;)
> [13:13] <alphaglosined> expression isOdd(T:ulong)(T value) => value & 1;
> [13:13] <B4S1L3> 5. floating point is accepted
> ...
> [13:15] <B4S1L3> so you see, this isOdd function we joke about. The package is not good. It's not phobos-grade at least

Thanks.

The real challenge will be to find a justification to bump
the major version number :-)
April 13, 2019
On Saturday, 13 April 2019 at 12:38:03 UTC, Julian wrote:
> On Saturday, 13 April 2019 at 12:13:36 UTC, Basile B. wrote:
>> Hi posted a review on IRC:
>>
>> [13:10] <B4S1L3> It's a joke but I already see several bad things
>> [13:11] <B4S1L3> 1. parameter should be const to prevent superfluous template instantiation
>
> To be clear, the actual problem with that is that error messages
> aren't as clear, in some misuse like isOdd("not even a number") ?
>
> And that a misuse will *accidentally* work, if & is overloaded.
>
>> [13:11] <B4S1L3> 2. no module name
>
> It has one though: isodd, the name of the file. Making that
> explicit might make it more like phobos modules but it probably
> also needs different style braces, javadoc-style comments, etc.
>
>> [13:11] <B4S1L3> 3. pragma(inline, true) not there
>
> I hadn't heard about that.
>
> @nogc @safe and such should also be there I suppose.
>
>> [13:12] <B4S1L3> 4. no test for BigInt
>> [13:12] <B4S1L3> "X" needs works, see review comments ;)
>> [13:13] <alphaglosined> expression isOdd(T:ulong)(T value) => value & 1;
>> [13:13] <B4S1L3> 5. floating point is accepted
>> ...
>> [13:15] <B4S1L3> so you see, this isOdd function we joke about. The package is not good. It's not phobos-grade at least
>
> Thanks.
>
> The real challenge will be to find a justification to bump
> the major version number :-)

`pragma(inline, true)` is not infered but the function attributes are. So... you should anotate your unittests with @safe pure nothrow @nogc and put the pragma for the tempalted funcs.

Anyway, I understand the joke, it's just like I think that the joke is not well executed ;)
April 13, 2019
On Friday, 12 April 2019 at 11:12:55 UTC, Walter Bright wrote:
> 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).

Maybe, dunno. I can see that x + 1 means "i add one to x", and that x & 1 means "I'm masking out the bit pattern of 1 from x". For the former, you can derive that "oh, that means the next index" (i.e. if(x.nextIndex) and for the latter, you can derive that "oh only odd numbers will have a value of one" (i.e. x.isodd). But the derivations are more secondary thoughts implied by the initial operation. So I can see the difference as well. Granted they're certainly not harder to read, but I do think they are not exactly the same.

>
> 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.

Can't argue with that :)


April 13, 2019
On Saturday, 13 April 2019 at 07:58:27 UTC, Andre Pany wrote:
> On Saturday, 13 April 2019 at 07:04:23 UTC, Julian wrote:
>> On Saturday, 13 April 2019 at 04:40:08 UTC, Walter Bright wrote:
>>> On 4/12/2019 9:15 PM, Nick Sabalausky (Abscissa) wrote:
>>>> If for you, they're the same level of abstraction, that's great. For most, it isn't.
>>>
>>> If you want to write a library of such, and contribute it to Dub, feel free. If you find an audience for it, great.
>>
>> Done: https://code.dlang.org/packages/isodd
>>
>> It doesn't seem like there's a way to run library unit tests
>> with dub?
>>
>> I'll add non-manpage documentation later.
>>
>> And a logo, of course.
>
> You can have different dub configurations, 1 of type library and 1 of type executable for the unit tests. The first configuration in the array list is the default configuration.
>
> I have a very bad feeling about such small dub packages, because we are now on the same quality level like NodeJS ):
>
> Kind regards
> Andre

Amen.

I guess most people have seen this but: https://www.theregister.co.uk/2016/03/23/npm_left_pad_chaos/

TL;DR - library with 11 lines of js code, pulled from npm, broke thousands of projects.
April 14, 2019
On Saturday, 13 April 2019 at 07:47:03 UTC, Nick Sabalausky (Abscissa) wrote:
> On 4/13/19 1:44 AM, Walter Bright wrote:
>> On 4/12/2019 9:38 PM, Nick Sabalausky (Abscissa) wrote:
>>> It's about the cognitive load.
>> 
>> As I pointed out upthread, isOdd() has a higher cognitive load.
>
> Not for normal programmers.

If you don’t know the modulo operator you should probably not be programming, and should spend some time in learning the basics of the language first. You don’t drive a car before knowing where the blinkers are.

I think it would be right to have functions such as `bool goLeft(int n) { return n % 2 == 0; }` or `bool isTail(int n) { return n % 2 == 0; }` since they abstract some decision logic in the application code. Whether or not you implement them with bitwise operators is not relevant.

But `isOdd()` is just another way of expressing code that should be written directly with the language operators because it is trivial, short, and meaningless on its own.
April 14, 2019
On 12.04.19 21:41, Walter Bright wrote:
> On 4/12/2019 6:31 AM, Timon Gehr wrote:
>> "Who's the clown who's put that there? Don't D programmers know about the array index operator?!"
> 
> front() is there for arrays as an adapter so one can use range operations on it.

My point exactly. x & 1 is not the best implementation of isOdd for all integer-representing types of x, and you may want to determine if an integer is odd in generic code. The reason why isOdd is not in Phobos is that Phobos has poor support for discrete mathematics in general, not necessarily that isOdd is too easy to implement for built-in integral types, and I hope my example demonstrates that.

There are of course other reasons why you would want to add functions with a simple implementations, I already mentioned standardization of function names, also, e.g. filter!isOdd is both faster to read and easier to type than filter!(x=>x&1).

Furthermore, it's just not nice when you are solving a problem and notice that a lot of functions you need to naturally express it are missing from the standard library and you need to add them to your own utility library first, presumably being too lazy to add the correct template constraints.