www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - More operators inside `is(...)` expressions

reply Per =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
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))

.
Aug 23 2020
next sibling parent reply Stefan Koch <uplink.coder googlemail.com> writes:
On Sunday, 23 August 2020 at 21:08:30 UTC, 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))

 .
Because you don't want to make them even more complicated than they are already.
Aug 23 2020
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 8/23/20 5:12 PM, Stefan Koch wrote:
 On Sunday, 23 August 2020 at 21:08:30 UTC, 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))
I agree. There's a reason we have != and don't require people to write !(x == y)
 
 Because you don't want to make them even more complicated than they are 
 already.
This one though is really annoying. I've bristled at that a few times when I had to write it. What is the cost here? Just use the same AST node for the is expression, and wrap it in a `not` AST node. -Steve
Aug 23 2020
next sibling parent Stefan Koch <uplink.coder googlemail.com> writes:
On Sunday, 23 August 2020 at 21:20:21 UTC, Steven Schveighoffer 
wrote:
 On 8/23/20 5:12 PM, Stefan Koch wrote:
 On Sunday, 23 August 2020 at 21:08:30 UTC, 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))
I agree. There's a reason we have != and don't require people to write !(x == y)
 
 Because you don't want to make them even more complicated than 
 they are already.
This one though is really annoying. I've bristled at that a few times when I had to write it. What is the cost here? Just use the same AST node for the is expression, and wrap it in a `not` AST node. -Steve
True, though how is pattern matching going to work if you allow != ?
Aug 23 2020
prev sibling parent reply Dennis <dkorpel gmail.com> writes:
On Sunday, 23 August 2020 at 21:20:21 UTC, Steven Schveighoffer 
wrote:
 What is the cost here? Just use the same AST node for the is 
 expression, and wrap it in a `not` AST node.
What would `is(int != T, T)` mean? To me it sounds like T should be bound to an arbitrary type that's not int, but when you lower it to `!is(int == T, T)` it returns false.
Aug 23 2020
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 8/23/20 5:52 PM, Dennis wrote:
 On Sunday, 23 August 2020 at 21:20:21 UTC, Steven Schveighoffer wrote:
 What is the cost here? Just use the same AST node for the is 
 expression, and wrap it in a `not` AST node.
What would `is(int != T, T)` mean? To me it sounds like T should be bound to an arbitrary type that's not int, but when you lower it to `!is(int == T, T)` it returns false.
I don't get this question at all. What does that mean anyway? According to the grammar, the `, T` part is supposed to be template parameters. And what is wrong with: static if (is(int != T)) { // use T } -Steve
Aug 23 2020
parent reply Per =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
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.
Aug 23 2020
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
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
Aug 23 2020
parent Per =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
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?
Aug 23 2020
prev sibling parent Mathias LANG <geod24 gmail.com> writes:
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.
Aug 23 2020
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 8/23/20 5:52 PM, Dennis wrote:
 On Sunday, 23 August 2020 at 21:20:21 UTC, Steven Schveighoffer wrote:
 What is the cost here? Just use the same AST node for the is 
 expression, and wrap it in a `not` AST node.
What would `is(int != T, T)` mean? To me it sounds like T should be bound to an arbitrary type that's not int, but when you lower it to `!is(int == T, T)` it returns false.
BTW, what I would propose is that the following case be added as an is Expression: is(Type != TypeSpecialization) As syntax sugar for: !is(Type == TypeSpecialization) And no other forms using != are valid. -Steve
Aug 23 2020
parent reply Dennis <dkorpel gmail.com> writes:
On Sunday, 23 August 2020 at 22:17:49 UTC, Steven Schveighoffer 
wrote:
 BTW, what I would propose is that the following case be added 
 as an is Expression:

 is(Type != TypeSpecialization)

 As syntax sugar for:

 !is(Type == TypeSpecialization)

 And no other forms using != are valid.
In that case the unclear `is(int != T, T)` case does not apply anymore. But that would only expand the (already confusing) list of is-expression forms with another special case.
Aug 23 2020
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 8/23/20 6:25 PM, Dennis wrote:
 On Sunday, 23 August 2020 at 22:17:49 UTC, Steven Schveighoffer wrote:
 BTW, what I would propose is that the following case be added as an is 
 Expression:

 is(Type != TypeSpecialization)

 As syntax sugar for:

 !is(Type == TypeSpecialization)

 And no other forms using != are valid.
In that case the unclear `is(int != T, T)` case does not apply anymore. But that would only expand the (already confusing) list of is-expression forms with another special case.
I think the not-confusing not-special-case is expression boat didn't sail. It sank in the harbor. We have already sailed on the confusing is boat. At least it should be less annoying while we are on the journey. Is there a reason you prefer writing !is(T == U) to is(T != U)? Or are you looking to define more things? -Steve
Aug 23 2020
parent Dennis <dkorpel gmail.com> writes:
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).
Aug 23 2020
prev sibling parent reply Per =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
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?
Aug 23 2020
parent Stefan Koch <uplink.coder googlemail.com> writes:
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.
Aug 23 2020
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
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.)
Aug 24 2020
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
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
Aug 24 2020
next sibling parent reply Stefan Koch <uplink.coder googlemail.com> writes:
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.
Aug 24 2020
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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.
Aug 24 2020
parent Stefan Koch <uplink.coder googlemail.com> writes:
On Monday, 24 August 2020 at 12:34:13 UTC, Adam D. Ruppe wrote:
 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.
I see. So `T != void` is special because it doesn't really play well with the other types. That clarifies the motivation. Thanks for explaining Adam.
Aug 24 2020
prev sibling parent reply Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Monday, 24 August 2020 at 12:28:27 UTC, Stefan Koch wrote:
 1) Complicating the rules for is expressions further
It will complicate a lot more since, you can do type matching chains in is expression: ------ is(T : Z[], Z != X, X : SomeType) ------ - Alex
Aug 25 2020
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 8/25/20 3:12 AM, Alexandru Ermicioi wrote:
 On Monday, 24 August 2020 at 12:28:27 UTC, Stefan Koch wrote:
 1) Complicating the rules for is expressions further
It will complicate a lot more since, you can do type matching chains in is expression: ------ is(T : Z[], Z != X, X : SomeType) ------
That doesn't look valid according to the grammar. Or if it passes, it may not do what you think it does. You sure this works? -Steve
Aug 25 2020
parent reply Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Tuesday, 25 August 2020 at 12:55:34 UTC, Steven Schveighoffer 
wrote:
 On 8/25/20 3:12 AM, Alexandru Ermicioi wrote:
 On Monday, 24 August 2020 at 12:28:27 UTC, Stefan Koch wrote:
 1) Complicating the rules for is expressions further
It will complicate a lot more since, you can do type matching chains in is expression: ------ is(T : Z[], Z != X, X : SomeType) ------
That doesn't look valid according to the grammar. Or if it passes, it may not do what you think it does. You sure this works? -Steve
Ah, sorry for bad english. It should be "could do type matching" not "can". If support for negation is added inside is expression, then it should also be supported in such chains as above, not just the simplest case as suggested by other people in this discussion.
Aug 26 2020
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 8/26/20 3:52 AM, Alexandru Ermicioi wrote:
 On Tuesday, 25 August 2020 at 12:55:34 UTC, Steven Schveighoffer wrote:
 On 8/25/20 3:12 AM, Alexandru Ermicioi wrote:
 On Monday, 24 August 2020 at 12:28:27 UTC, Stefan Koch wrote:
 1) Complicating the rules for is expressions further
It will complicate a lot more since, you can do type matching chains in is expression: ------ is(T : Z[], Z != X, X : SomeType) ------
That doesn't look valid according to the grammar. Or if it passes, it may not do what you think it does. You sure this works?
Ah, sorry for bad english. It should be "could do type matching" not "can". If support for negation is added inside is expression, then it should also be supported in such chains as above, not just the simplest case as suggested by other people in this discussion.
No worries! My point actually was that I don't think such "chains" are valid, even without the !=. Do you have a valid case that works today (without !=)? -Steve
Aug 26 2020
parent Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Wednesday, 26 August 2020 at 11:44:22 UTC, Steven 
Schveighoffer wrote:
 No worries! My point actually was that I don't think such 
 "chains" are valid, even without the !=. Do you have a valid 
 case that works today (without !=)?

 -Steve
Well, you're right, it doesn't work even with ==, right now. I was pretty sure it should've worked. Seems that ==, is only allowed as first element in a 'is' chain, which is counter-intuitive. - Alex.
Aug 27 2020
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 24.08.20 13:49, Steven Schveighoffer wrote:

 
 Yes. If you write !is(T == void), then you are already not checking 
 whether T is defined. This is no different.
 
So far the pattern is `is(S op T)`. It checks whether S is a valid type and then checks `S op T`.
 This literally is just a nicer way to write it, where the operation is 
 closer to the parameters, instead of partly outside the expression.
(I think the implications any of this has for the compiler implementation or the user experience has been greatly exaggerated.)
Aug 24 2020
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 8/24/20 1:17 PM, Timon Gehr wrote:
 On 24.08.20 13:49, Steven Schveighoffer wrote:

 Yes. If you write !is(T == void), then you are already not checking 
 whether T is defined. This is no different.
So far the pattern is `is(S op T)`. It checks whether S is a valid type and then checks `S op T`.
But op is only '==' or ':', which are in sync with the requirements without needing the first part (if S is invalid, then obviously it can't equal T, or be convertible to T). We have room to add other ops that might have a slightly different behavior. That being said, if it could be added so is(S != T) is false if S is invalid I wouldn't object.
 
 This literally is just a nicer way to write it, where the operation is 
 closer to the parameters, instead of partly outside the expression.
(I think the implications any of this has for the compiler implementation or the user experience has been greatly exaggerated.)
The problem is usually something like: static if (!is(Some!(Long!(Chain, Of, Template, Parameter, Data) == int)); At a glance, seeing that initial '!' among the various instantiation '!', and associating it with the check at the very end '==', is difficult for code review. It's ok, it's just not ideal in terms of focusing the reader on the operation at hand. This isn't a must-have, it's just something that has annoyed me multiple times (where I am reading code, trying to figure out why it's doing what it's doing, and then realize I missed the '!' at the front). Really, all the arguments for having '!=' for binary operations vs doing !(someExpr == otherExp) apply here. I also really don't find the "it will complicate the compiler" arguments convincing. -Steve
Aug 24 2020
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 24.08.20 19:36, Steven Schveighoffer wrote:
 
 Really, all the arguments for having '!=' for binary operations vs doing 
 !(someExpr == otherExp) apply here.
Some, not all (you are not getting rid of parentheses).
 I also really don't find the "it will complicate the compiler" arguments
convincing. 
If it does so meaningfully, it's probably an issue with the chosen implementation strategy.
Aug 24 2020
prev sibling parent reply Ogi <ogion.art gmail.com> writes:
On Sunday, 23 August 2020 at 21:08:30 UTC, 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))

 .
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.
Aug 28 2020
parent reply Jacob Carlborg <doob me.com> writes:
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
Aug 28 2020
next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
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
Aug 28 2020
prev sibling parent reply Ogi <ogion.art gmail.com> writes:
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?
Sep 01 2020
next sibling parent reply Jacob Carlborg <doob me.com> writes:
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
Sep 01 2020
next sibling parent Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
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
Sep 01 2020
prev sibling parent reply Ogi <ogion.art gmail.com> writes:
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.
Sep 01 2020
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
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
Sep 01 2020
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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.
Sep 01 2020
next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
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
Sep 01 2020
prev sibling parent Ogi <ogion.art gmail.com> writes:
On Tuesday, 1 September 2020 at 16:29:57 UTC, 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.
Why stop on `a` and `b` though? https://run.dlang.io/is/u1GuZs
Sep 01 2020
prev sibling parent reply Ogi <ogion.art gmail.com> writes:
On Tuesday, 1 September 2020 at 14:00:19 UTC, Steven 
Schveighoffer wrote:
 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.
Whoever would do horrible deeds with `version` is still able to do all of them with `static if`, meanwhile the good guys are stuck with this wooden syntax. Seems a bit irrational to me. I feel like beating a dead horse. Surely it has been discussed ad infinitum. And after all, it’s not such a big deal, it’s not like you have to juggle versions in your code all the time. But things like that are no good for D’s public image.
Sep 01 2020
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.com> writes:
On 9/1/20 2:36 PM, Ogi wrote:
 On Tuesday, 1 September 2020 at 14:00:19 UTC, Steven Schveighoffer wrote:
 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.
Whoever would do horrible deeds with `version` is still able to do all of them with `static if`, meanwhile the good guys are stuck with this wooden syntax. Seems a bit irrational to me. I feel like beating a dead horse. Surely it has been discussed ad infinitum. And after all, it’s not such a big deal, it’s not like you have to juggle versions in your code all the time. But things like that are no good for D’s public image.
Well I can tell that I don't mind the limitations of version at all, and I enjoy the distinction. There are many features in a programming language that are more powerful than others and could supplant them (foreach/for/while/goto, overloading/templates, switch/if etc). Economy of means is an underrated principle of writing code (and in general). So if I'm in a place where version would fit, version it is. Otherwise I decide, for a reason, that static if is to be reached for. All of that would be hardly irrational.
Sep 03 2020
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Sep 03, 2020 at 12:21:35PM -0400, Andrei Alexandrescu via Digitalmars-d
wrote:
[...]
 Economy of means is an underrated principle of writing code (and in
 general). So if I'm in a place where version would fit, version it is.
 Otherwise I decide, for a reason, that static if is to be reached for.
 All of that would be hardly irrational.
+1. Economy of means is highly underrated these days, but it is a powerful principle that helps you write better code. T -- Amateurs built the Ark; professionals built the Titanic.
Sep 03 2020
parent reply Dominikus Dittes Scherkl <dominikus scherkl.de> writes:
On Thursday, 3 September 2020 at 16:49:24 UTC, H. S. Teoh wrote:
 --
 Amateurs built the Arc, Professionals built the Titanic
Do you choose your signature or are they random? (I doubt it, because they're so often so fitting)
Sep 03 2020
parent reply Nick Treleaven <nick geany.org> writes:
On Friday, 4 September 2020 at 05:58:31 UTC, Dominikus Dittes 
Scherkl wrote:
 On Thursday, 3 September 2020 at 16:49:24 UTC, H. S. Teoh wrote:
 --
 Amateurs built the Arc, Professionals built the Titanic
Do you choose your signature or are they random? (I doubt it, because they're so often so fitting)
The quote implies that the Ark was a better boat than the Titanic. This is obviously incorrect in terms of capacity, facilities and lifetime. It was Marketing that ruined the Titanic, not the engineers. (Plus the Ark is fictional and impractical).
Sep 05 2020
parent reply dweldon <danny.weldon gmail.com> writes:
On Saturday, 5 September 2020 at 12:27:19 UTC, Nick Treleaven 
wrote:

 Titanic, not the engineers. (Plus the Ark is fictional and
That depends on who is telling the narrative. While secularism captured mainstream science long ago, aided initially by since-proven fraudulent fossil finds, creation science has now advanced to a level that proves evolution false in many, many ways. You just won't get that information in the mainstream.
 impractical).
The ark design has been investigated by engineers and found to be incredibly seaworthy for what it was designed for. Not every species that we see today was present on the ark, only a few from each kind was needed. Rapid speciation occurred after they spread out over the earth, but all still remained within their initial kind. Eg. we can trace all dogs today back to wolves, so all that was needed were two wolves on the ark. Similarly for other animals.
Sep 09 2020
parent reply Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On Thursday, 10 September 2020 at 03:30:17 UTC, dweldon wrote:
 On Saturday, 5 September 2020 at 12:27:19 UTC, Nick Treleaven 
 wrote:

 Titanic, not the engineers. (Plus the Ark is fictional and
That depends on who is telling the narrative. While secularism captured mainstream science long ago, aided initially by since-proven fraudulent fossil finds, creation science has now advanced to a level that proves evolution false in many, many ways. You just won't get that information in the mainstream.
 impractical).
The ark design has been investigated by engineers and found to be incredibly seaworthy for what it was designed for. Not every species that we see today was present on the ark, only a few from each kind was needed. Rapid speciation occurred after they spread out over the earth, but all still remained within their initial kind. Eg. we can trace all dogs today back to wolves, so all that was needed were two wolves on the ark. Similarly for other animals.
Just... no. This is not the place for a debate over pseudoscience. -- Simen
Sep 10 2020
parent Stefan Koch <uplink.coder googlemail.com> writes:
On Thursday, 10 September 2020 at 08:00:23 UTC, Simen Kjærås 
wrote:
 Just... no. This is not the place for a debate over 
 pseudoscience.
Well have got a good laugh out of it. I don't think a debate would possibly start here. He didn't mention emacs vs. vim after all.
Sep 10 2020
prev sibling parent Tim <tim.dlang t-online.de> writes:
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.
Sep 01 2020