August 23, 2020
On 8/23/20 6:18 PM, Per Nordlöw wrote:
> On Sunday, 23 August 2020 at 22:11:41 UTC, Steven Schveighoffer wrote:
>> static if (is(int != T))
>> {
>>    // use T
>> }
> 
> Furthermore, what's wrong with allowing
> 
> static if (int is T)
> {
>     // use T
> }
> 
> static if (int !is T)
> {
>     // use T
> }
> 
> ?
> 
> Less syntax for developer to remember.

It becomes confusing when the symbols are not builtins, though it would look a lot nicer.

But this is definitely a much more drastic change than just allowing != in the existing is-expression. I imagine the changes to the compiler would not be simple for this.

-Steve
August 23, 2020
On Sunday, 23 August 2020 at 21:12:13 UTC, Stefan Koch wrote:
> Because you don't want to make them even more complicated than they are already.

Are you saying the developer experience or the dmd-implementation for handling them is already too complicated?
August 23, 2020
On Sunday, 23 August 2020 at 22:45:10 UTC, Steven Schveighoffer wrote:
> But this is definitely a much more drastic change than just allowing != in the existing is-expression. I imagine the changes to the compiler would not be simple for this.

I guess Walter wants a distinct syntax for compile-time expressions. `X is Y` is already used at run-time.

Is this related to context-independent grammars?
August 23, 2020
On Sunday, 23 August 2020 at 22:47:41 UTC, Per Nordlöw wrote:
> On Sunday, 23 August 2020 at 21:12:13 UTC, Stefan Koch wrote:
>> Because you don't want to make them even more complicated than they are already.
>
> Are you saying the developer experience or the dmd-implementation for handling them is already too complicated?

Both.

Right now is expressions can be seen as symbolic equations.
If you add inequality then you have to support constraint sets as well.
Or life with another wired special case.

August 23, 2020
On Sunday, 23 August 2020 at 22:40:23 UTC, Steven Schveighoffer wrote:
> Is there a reason you prefer writing !is(T == U) to is(T != U)? Or are you looking to define more things?

I don't prefer the former form, but it's not longer (you have to write parentheses either way), and 95% of my is-expressions are testing for a positive match (so no ! needed at all).
August 23, 2020
On Sunday, 23 August 2020 at 22:18:48 UTC, Per Nordlöw wrote:
> On Sunday, 23 August 2020 at 22:11:41 UTC, Steven Schveighoffer wrote:
>> static if (is(int != T))
>> {
>>    // use T
>> }
>
> Furthermore, what's wrong with allowing
>
> [...]

If I may interject, that's the wrong way to think about it. You should stop asking "Why not?" and ask "Why?" instead.
Why should we allow this syntax ? What's the benefit over the current syntax ?

Having two syntaxes for the same thing will lead to:
- Two sides arguing over which one should be preferred (e.g. when writing examples);
- Rules being implemented in linter(s), e.g. DScanner;
- A special mention in any style guide(s);
- Subtle differences between the two syntax creeping in;

We actually have a good example for this: alias declarations.
I'm actually a big fan of [this quote](https://www.goodreads.com/quotes/19905-perfection-is-achieved-not-when-there-is-nothing-more-to) when it comes to design.
August 24, 2020
On 23.08.20 23:08, Per Nordlöw wrote:
> Why aren't more operators allowed inside `is(...)`-expressions?
> 
> For instance
> 
>      if (!is(CommonType!(typeof(min), typeof(max)) == void))
> 
> could be written as
> 
>      if (is(CommonType!(typeof(min), typeof(max)) != void))
> 
> .

So is(undefined != void) would be `true`? (Where `undefined` does not exist.)
August 24, 2020
On 8/24/20 4:03 AM, Timon Gehr wrote:
> On 23.08.20 23:08, Per Nordlöw wrote:
>> Why aren't more operators allowed inside `is(...)`-expressions?
>>
>> For instance
>>
>>      if (!is(CommonType!(typeof(min), typeof(max)) == void))
>>
>> could be written as
>>
>>      if (is(CommonType!(typeof(min), typeof(max)) != void))
>>
>> .
> 
> So is(undefined != void) would be `true`? (Where `undefined` does not exist.)

Yes. If you write !is(T == void), then you are already not checking whether T is defined. This is no different.

This literally is just a nicer way to write it, where the operation is closer to the parameters, instead of partly outside the expression.

-Steve
August 24, 2020
On Monday, 24 August 2020 at 11:49:05 UTC, Steven Schveighoffer wrote:
> On 8/24/20 4:03 AM, Timon Gehr wrote:
>> On 23.08.20 23:08, Per Nordlöw wrote:
>>> Why aren't more operators allowed inside `is(...)`-expressions?
>>>
>>> For instance
>>>
>>>      if (!is(CommonType!(typeof(min), typeof(max)) == void))
>>>
>>> could be written as
>>>
>>>      if (is(CommonType!(typeof(min), typeof(max)) != void))
>>>
>>> .
>> 
>> So is(undefined != void) would be `true`? (Where `undefined` does not exist.)
>
> Yes. If you write !is(T == void), then you are already not checking whether T is defined. This is no different.
>
> This literally is just a nicer way to write it, where the operation is closer to the parameters, instead of partly outside the expression.
>
> -Steve

The problems I see here are:

1) Complicating the rules for is expressions further
2) Adding a special syntax for what I perceive to be an uncommon case

I.E. (T != void) does not narrow your result set significantly.
The only place where you could write that is if your T-set is already narrowed down.
Or rather if you have a (T == void) specialization which you want to rule out.

I might be wrong here but I do think that's uncommon.
August 24, 2020
On Monday, 24 August 2020 at 12:28:27 UTC, Stefan Koch wrote:
> 2) Adding a special syntax for what I perceive to be an uncommon case

This is a very common case because void is frequently special cased. You cannot have a local variable of type void meaning any time you want to work with a generic function return value, you can't just be like `T ret = call(); return ret;`, you must check if T != void before doing that.

What I usually do though is static if(is(T == void)) call(); else { ret = call(); /* process ret */ return ret; } but it is obnoxious to duplicate that call every time still.

Lots of Phobos things also return void as the special case of "not found".

What I'd love is if we didn't have to special case void all the time... but we do, making some variant of this specific check pretty common.