Jump to page: 1 24  
Page
Thread overview
August 13
A bug that crops up now and then in D is that someone negates `a == b` by prepending a `!`. The result is `!a == b`. This parses as `(!a) == b` and will often silently do the wrong thing because negation implies cast to `bool`, and `bool` can be compared with integral types and `enum` members.

I think it would be better for this to give a diagnostic and require explicit parentheses, similar to bitwise operators (where the operator precedence is unintuitive in the other direction).
August 13
On Tuesday, 13 August 2024 at 10:14:29 UTC, Timon Gehr wrote:
> A bug that crops up now and then in D is that someone negates `a == b` by prepending a `!`. The result is `!a == b`. This parses as `(!a) == b` and will often silently do the wrong thing because negation implies cast to `bool`, and `bool` can be compared with integral types and `enum` members.

Yes please!
August 13

On Tuesday, 13 August 2024 at 10:14:29 UTC, Timon Gehr wrote:

>

A bug that crops up now and then in D is that someone negates a == b by prepending a !. The result is !a == b. This parses as (!a) == b and will often silently do the wrong thing because negation implies cast to bool, and bool can be compared with integral types and enum members.

I think it would be better for this to give a diagnostic and require explicit parentheses, similar to bitwise operators (where the operator precedence is unintuitive in the other direction).

I’m quite sure this requires no DIP. Yes, this is a breaking change. The fix is to write (!a) == b and it’s unlikely that anyone has boatloads of !a == b in their code.

August 13

On Tuesday, 13 August 2024 at 10:14:29 UTC, Timon Gehr wrote:

>

A bug that crops up now and then in D is that someone negates a == b by prepending a !. The result is !a == b. This parses as (!a) == b and will often silently do the wrong thing because negation implies cast to bool, and bool can be compared with integral types and enum members.

I think it would be better for this to give a diagnostic and require explicit parentheses, similar to bitwise operators (where the operator precedence is unintuitive in the other direction).

This should be done. The current behavior isn't likely something that's used very often (testing equality of two bools). Breaking code isn't a problem because !a == b would fail to compile, and it's trivial to fix. Other changes to the language have been more annoying while providing less benefit.

August 13

On Tuesday, 13 August 2024 at 10:14:29 UTC, Timon Gehr wrote:

>

A bug that crops up now and then in D is that someone negates a == b by prepending a !. The result is !a == b. This parses as (!a) == b and will often silently do the wrong thing because negation implies cast to bool, and bool can be compared with integral types and enum members.

I think it would be better for this to give a diagnostic and require explicit parentheses, similar to bitwise operators (where the operator precedence is unintuitive in the other direction).

Doesn’t require a DIP, but I’ve also never seen anyone think this would work? Do we really need to pander to people who don’t even understand that logical operators only return bool? Maybe that seems harsh, but I have never even thought of doing this because it’s just so obviously wrong—if I wrote it then I must have meant what I wrote, and I was probably happy with how it looked too. Having to wrap it in parenthesis would just negate that and add to my code’s parenthesis hell.

P.S. this isn’t a bug; and ! is ‘logical not’, not ‘negation’.

August 13

On Tuesday, 13 August 2024 at 20:30:10 UTC, IchorDev wrote:

>

Do we really need to pander to people who don’t even understand that logical operators only return bool?

To rephrase my point a little: this is emergent behaviour with an obvious cause—a logical not always comes before a comparison.
A problem I have actually had is not being able to parse the operation order for expressions like 1 + 2 * 3, but I don’t think we should require parenthesis there either.
Also, here’s a nice case where I’d actually want to write this: !myInt == myBool Again, here the parenthesis would just be visual noise.

August 13
On Tuesday, 13 August 2024 at 10:14:29 UTC, Timon Gehr wrote:
> A bug that crops up now and then in D is that someone negates `a == b` by prepending a `!`. The result is `!a == b`. This parses as `(!a) == b` and will often silently do the wrong thing because negation implies cast to `bool`, and `bool` can be compared with integral types and `enum` members.

I was a bit surprised that someone would write that (other than someone new to C-like syntax), but then I saw:
https://github.com/dlang/dmd/pull/16778#discussion_r1715017456

> I think it would be better for this to give a diagnostic and require explicit parentheses, similar to bitwise operators (where the operator precedence is unintuitive in the other direction).

Yes, it's consistent with other bug-prone patterns that dmd requires parentheses to disambiguate:
https://dlang.org/spec/expression.html#conditional_expressions
https://dlang.org/spec/expression.html#bitwise_expressions

Also braces for dangling `else`.

August 13

On Tuesday, 13 August 2024 at 20:40:32 UTC, IchorDev wrote:

>

On Tuesday, 13 August 2024 at 20:30:10 UTC, IchorDev wrote:

>

Do we really need to pander to people who don’t even understand that logical operators only return bool?

I think it's actually that they don't know the operator precedence, or they just made a mistake.

>

A problem I have actually had is not being able to parse the operation order for expressions like 1 + 2 * 3, but I don’t think we should require parenthesis there either.

Agreed, because that syntax comes from maths rather than a subset of programming languages.

>

Also, here’s a nice case where I’d actually want to write this: !myInt == myBool Again, here the parenthesis would just be visual noise.

The diagnostic doesn't need to fire when both sides are bool.

August 13

On Tuesday, 13 August 2024 at 20:30:10 UTC, IchorDev wrote:

>

But I’ve also never seen anyone think this would work?

It's easy to have a lapse of focus. Last hour, I accidentally used && for bit masking instead of &. I also sometimes write if (x = 3) by mistake, or forget a return statement like this:

bool f(int x)
{
    x == 3;
}

Luckily the D compiler catches these. It's not that I thought these things would work in D, but simple human error.

It's also worth noting that things are different in other programming languages. In some languages the last expression is automatically returned. And in Python, the order of operations makes !a == b actually work like most (new) programmers intend:

>

python

> >

not (3 == 4)
True
not 3 == 4
True
(not 3) == 4
False


August 13

On Tuesday, 13 August 2024 at 20:30:10 UTC, IchorDev wrote:

>

Doesn’t require a DIP, but I’ve also never seen anyone think this would work? Do we really need to pander to people who don’t even understand that logical operators only return bool? Maybe that seems harsh, but I have never even thought of doing this because it’s just so obviously wrong—if I wrote it then I must have meant what I wrote, and I was probably happy with how it looked too. Having to wrap it in parenthesis would just negate that and add to my code’s parenthesis hell.

P.S. this isn’t a bug; and ! is ‘logical not’, not ‘negation’.

It would make sense to allow it for only bools. However, we can write this code:

import std;

void main() {
    int z = 4;
    writeln(z == 2);
    writeln(!z == 2);
    writeln(!z == 0);
    writeln(z == 0);
}

The output is

false
false
true
false

It's hard to justify allowing something like that to slip through given that it's an easy mistake to make. A test might not even catch it.

« First   ‹ Prev
1 2 3 4