August 28, 2020
On Friday, 28 August 2020 at 07:22:51 UTC, Ogi wrote:

> There is one expression where allowing “!” would be much more beneficial — version condition. Currently we are forced to write something like:
>     version (OSX) {} else {
>         /* ... */
>     }
> when it could be just:
>     version (!OSX) {
>         /* ... */
>     }
> I am aware that it was Walter’s intention to make the version syntax simplistic, but I don’t think that allowing “!” would do any harm.

There's a workaround: define bool enums for all version identifiers and use `static if` instead:

version (OSX)
    enum OSX = true;
else
    enum OSX = false;

static if (!OSX) {}

--
/Jacob Carlborg
August 28, 2020
On 8/28/20 8:45 AM, Jacob Carlborg wrote:
> On Friday, 28 August 2020 at 07:22:51 UTC, Ogi wrote:
> 
>> There is one expression where allowing “!” would be much more beneficial — version condition. Currently we are forced to write something like:
>>     version (OSX) {} else {
>>         /* ... */
>>     }
>> when it could be just:
>>     version (!OSX) {
>>         /* ... */
>>     }
>> I am aware that it was Walter’s intention to make the version syntax simplistic, but I don’t think that allowing “!” would do any harm.
> 
> There's a workaround: define bool enums for all version identifiers and use `static if` instead:
> 
> version (OSX)
>      enum OSX = true;
> else
>      enum OSX = false;
> 
> static if (!OSX) {}

I think someone posted this a while ago:

template staticVersion(string s)
{
  mixin("version(" ~ s ~ ") enum staticVersion = true; else enum staticVersion = false;");
}

-Steve
September 01, 2020
On Friday, 28 August 2020 at 12:45:24 UTC, Jacob Carlborg wrote:
>
> There's a workaround: define bool enums for all version identifiers and use `static if` instead:
>
> version (OSX)
>     enum OSX = true;
> else
>     enum OSX = false;
>
> static if (!OSX) {}
>
> --
> /Jacob Carlborg

Why use `version` then?

September 01, 2020
On Tuesday, 1 September 2020 at 07:11:45 UTC, Ogi wrote:

> Why use `version` then?

Because that's set automatically by the compiler. Here's a list of the predefined version identifiers set by the compiler [1].

[1] https://dlang.org/spec/version.html#predefined-versions

--
/Jacob Carlborg

September 01, 2020
On Tuesday, 1 September 2020 at 09:05:27 UTC, Jacob Carlborg wrote:
> On Tuesday, 1 September 2020 at 07:11:45 UTC, Ogi wrote:
>
>> Why use `version` then?
>
> Because that's set automatically by the compiler. Here's a list of the predefined version identifiers set by the compiler [1].
>
> [1] https://dlang.org/spec/version.html#predefined-versions


Also, more versions can be set via the -version compiler flag:

https://dlang.org/dmd-windows.html#switch--version

Perhaps an even more useful version of the above trick:

struct Version {
    template opDispatch(string name) {
        mixin("version ("~name~") enum opDispatch = true; else enum opDispatch = false;");
    }
}

static if (Version.Windows) pragma(msg, "Windows machine");
static if (Version.linux) pragma(msg, "Linux machine");

--
  Simen
September 01, 2020
On Tuesday, 1 September 2020 at 09:05:27 UTC, Jacob Carlborg wrote:
> On Tuesday, 1 September 2020 at 07:11:45 UTC, Ogi wrote:
>
>> Why use `version` then?
>
> Because that's set automatically by the compiler. Here's a list of the predefined version identifiers set by the compiler [1].
>
> [1] https://dlang.org/spec/version.html#predefined-versions
>
> --
> /Jacob Carlborg

I am aware of that. I mean that the enum workaround for version condition is the indication of its poor design.

The syntax is unreasonably restrictive. I can see the point of prohibiting complex expressions (like `version (Windows || (POSIX && !LDC))`), but something as simple as version(!Windows) would be harmless.
September 01, 2020
On 9/1/20 9:32 AM, Ogi wrote:
> On Tuesday, 1 September 2020 at 09:05:27 UTC, Jacob Carlborg wrote:
>> On Tuesday, 1 September 2020 at 07:11:45 UTC, Ogi wrote:
>>
>>> Why use `version` then?
>>
>> Because that's set automatically by the compiler. Here's a list of the predefined version identifiers set by the compiler [1].
>>
>> [1] https://dlang.org/spec/version.html#predefined-versions
>>
>> -- 
>> /Jacob Carlborg
> 
> I am aware of that. I mean that the enum workaround for version condition is the indication of its poor design.
> 
> The syntax is unreasonably restrictive. I can see the point of prohibiting complex expressions (like `version (Windows || (POSIX && !LDC))`), but something as simple as version(!Windows) would be harmless.

In fact, I think version(a || b) would be the only thing we need to add, as the code you need to write to reproduce such a thing is horrendous, and the alternative is duplicating code.

You can already do version(a) version(b) to get the effect of &&.

`Not` is problematic, because you should really write code based on what the version is, not for everything else (for the most part), and the "not" can also be done via the slightly ugly but still reasonable version(x) {} else ...

But Walter is never going to approve any changes here, as this is one area where he will not budge, due to past experience with the C Preprocessor abuse. So this discussion is only academic. Just use the workarounds and move on.

-Steve
September 01, 2020
On 9/1/20 10:00 AM, Steven Schveighoffer wrote:
> On 9/1/20 9:32 AM, Ogi wrote:
>> On Tuesday, 1 September 2020 at 09:05:27 UTC, Jacob Carlborg wrote:
>>> On Tuesday, 1 September 2020 at 07:11:45 UTC, Ogi wrote:
>>>
>>>> Why use `version` then?
>>>
>>> Because that's set automatically by the compiler. Here's a list of the predefined version identifiers set by the compiler [1].
>>>
>>> [1] https://dlang.org/spec/version.html#predefined-versions
>>>
>>> -- 
>>> /Jacob Carlborg
>>
>> I am aware of that. I mean that the enum workaround for version condition is the indication of its poor design.
>>
>> The syntax is unreasonably restrictive. I can see the point of prohibiting complex expressions (like `version (Windows || (POSIX && !LDC))`), but something as simple as version(!Windows) would be harmless.
> 
> In fact, I think version(a || b) would be the only thing we need to add, as the code you need to write to reproduce such a thing is horrendous, and the alternative is duplicating code.
> 
> You can already do version(a) version(b) to get the effect of &&.
> 
> `Not` is problematic, because you should really write code based on what the version is, not for everything else (for the most part), and the "not" can also be done via the slightly ugly but still reasonable version(x) {} else ...
> 
> But Walter is never going to approve any changes here, as this is one area where he will not budge, due to past experience with the C Preprocessor abuse. So this discussion is only academic. Just use the workarounds and move on.

So for the or we have something like:

version(a) version = a_or_b;
else version(b) version = a_or_b;

Not too bad if you don't have many. And if you do:

https://run.dlang.io/is/CZ5B6z

I'll see myself out.
September 01, 2020
On 9/1/20 12:29 PM, Andrei Alexandrescu wrote:
> 
> So for the or we have something like:
> 
> version(a) version = a_or_b;
> else version(b) version = a_or_b;
> 
> Not too bad if you don't have many. And if you do:
> 
> https://run.dlang.io/is/CZ5B6z
> 
> I'll see myself out.

I couldn't have made my point better ;)

Defense rests.

-Steve
September 01, 2020
On Tuesday, 1 September 2020 at 07:11:45 UTC, Ogi wrote:
>
> Why use `version` then?

static if has problems with forward references:
https://issues.dlang.org/show_bug.cgi?id=3743
https://issues.dlang.org/show_bug.cgi?id=17883

Using version works better in cases like those.