Thread overview
[proposal] version statements with multiple arguments.
Oct 23, 2012
1100110
Oct 23, 2012
Jesse Phillips
Oct 23, 2012
timotheecour
Oct 24, 2012
Walter Bright
Oct 23, 2012
1100110
Oct 24, 2012
Walter Bright
Oct 24, 2012
Don Clugston
Oct 24, 2012
Nick Treleaven
October 23, 2012
Looking at std.io (hopefully the right version maybe?) I see this:

version(OSX)
{ 	do something; }
version(Windows)
{ 	do the same thing as above; }
version(FreeBSD)
{ 	ditto; }
version(Linux)
{	finally do something different; }
and:
version(Windows) version(DigitalMars)
{ 	something; }


I was rather surprised that this wasn't accepted:
//Error: found '||' when expecting ')'

version(OSX || Windows || FreeBSD)
{ 	do something; }
version(Linux)
{ 	do something different; }


The last one could be intuitively described as:
version(Windows && DigitalMars)
{ 	blah; 	}


So I guess in the end I am proposing a change.
A change that I cannot see breaking backwards compatibility while also shortening code duplication.
It also seems much more 'intuitive' to me.

version(Windows) version(DigitalMars) {}
made me think twice to make sure I knew what it was doing.

What do you guys think?  If this was implemented, how could it break backwards compatibility?
Is something like this worth a change?
Are there any drawbacks to this idea?


-- 
Shut up, Opera.
October 23, 2012
On Tuesday, 23 October 2012 at 03:22:08 UTC, 1100110 wrote:
> So I guess in the end I am proposing a change.
> A change that I cannot see breaking backwards compatibility while also shortening code duplication.
> It also seems much more 'intuitive' to me.
>
> version(Windows) version(DigitalMars) {}
> made me think twice to make sure I knew what it was doing.
>
> What do you guys think?  If this was implemented, how could it break backwards compatibility?
> Is something like this worth a change?
> Are there any drawbacks to this idea?

This "issue" comes once in a while. The suggested solution:

version(OSX)
    version = Somethingable
version(Windows)
    version = Somethingable
version(FreeBSD)
    version = Somethingable

version(Somethingable)
    dosomething();

version(Linux)
   otherthing;

Not necessarily more concise but it can add description to what the actual version being created.
October 23, 2012
Indeed, having version logic has been requested many times before.
For example:
http://www.digitalmars.com/d/archives/digitalmars/D/learn/Can_I_do_an_or_in_a_version_block_33426.html
http://www.digitalmars.com/d/archives/digitalmars/D/11946.html

quote from those:
"Walter would reject it. He has stated clearly in the past that he intended version to be simple and minimal, and that adding anything onto it will only result in abuses."

I tend to think that not having version logic (&&,||,!) results in greater abuse, ie people WILL come up with their own incompatible, verbose solutions (string mixins and whatnot) to achieve the same results;

Another point is that we are sometimes too lazy to write statements as follows:
version (linux){  version = linuxOrBSD;}
version (BSD){  version = linuxOrBSD;}
version(linuxOrBSD){do_something;}
(that's ugly but it's the official recommended way; much more verbose than:
version(linux || BSD){do_something;}
)

and instead we lazily duplicate code, because "do_something" is small enough:
version (linux){  do_something;}
version (BSD){  do_something;}
Later on we (or the maintainer) update the first "do_something" and forget to update the second. Bug follows.

Seriously who hasn't encountered that?

Might as well provide a clean standard solution so everybody uses it. It should be easy to implement and wont' break any code.
October 23, 2012
On Mon, 22 Oct 2012 22:31:43 -0500, Jesse Phillips <jessekphillips+D@gmail.com> wrote:

> On Tuesday, 23 October 2012 at 03:22:08 UTC, 1100110 wrote:
>> So I guess in the end I am proposing a change.
>> A change that I cannot see breaking backwards compatibility while also shortening code duplication.
>> It also seems much more 'intuitive' to me.
>>
>> version(Windows) version(DigitalMars) {}
>> made me think twice to make sure I knew what it was doing.
>>
>> What do you guys think?  If this was implemented, how could it break backwards compatibility?
>> Is something like this worth a change?
>> Are there any drawbacks to this idea?
>
> This "issue" comes once in a while. The suggested solution:
> [snip]
>
> Not necessarily more concise but it can add description to what the actual version being created.

That is true, and I do recall that version = something; now that I think about it.

It just seems to me that version statements are essentially booleans, and could be easily rewritten as:
static if(true || false || false) { } by the compiler, similar to how (I *think*) certain binary operators are rewritten.
(I'm just going by what I hear, I'm not really a compiler kinda guy...)

It would make sense to me to be able to use boolean operators on what is essentially
a true/false statement.

I'd be willing to see if I can hack together support for it, as a proof of concept,
but I wanted to see if it would be blatantly shot down first.

So... What I'd really like to know is: Would *you* welcome such a change?
-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
October 23, 2012
On Tuesday, 23 October 2012 at 04:32:02 UTC, 1100110 wrote:
> On Mon, 22 Oct 2012 22:31:43 -0500, Jesse Phillips <jessekphillips+D@gmail.com> wrote:
>
> That is true, and I do recall that version = something; now that I think about it.
>
> It just seems to me that version statements are essentially booleans, and could be easily rewritten as:
> static if(true || false || false) { } by the compiler, similar to how (I *think*) certain binary operators are rewritten.
> (I'm just going by what I hear, I'm not really a compiler kinda guy...)
>
> It would make sense to me to be able to use boolean operators on what is essentially
> a true/false statement.
>
> I'd be willing to see if I can hack together support for it, as a proof of concept,
> but I wanted to see if it would be blatantly shot down first.
>
> So... What I'd really like to know is: Would *you* welcome such a change?


This proposal has made a quarterly appearance since the earliest days of D1... and heavens yes, would I welcome it.  While the standard (version = Somethingable) approach is actually fine in many cases (self documenting, puts all the logic in one place, etc etc) it is also quite overkill in many cases (the logic matters exactly once, the logic branches differently in different places, etc etc).  It's the same as every toolbox having different types of screwdrivers.  Yes they do the same thing, but in different circumstances one will be clearly preferable over another.

-- Chris Nicholson-Sauls

October 24, 2012
On 10/22/2012 8:17 PM, 1100110 wrote:
> The last one could be intuitively described as:
> version(Windows && DigitalMars)
> {     blah;     }

It was a very deliberate design choice to not allow !, || or && in version statements. Such tend to devolve over time into unmaintainable chaos.
October 24, 2012
On 10/22/2012 9:26 PM, timotheecour wrote:
> Another point is that we are sometimes too lazy to write statements as follows:
> version (linux){  version = linuxOrBSD;}
> version (BSD){  version = linuxOrBSD;}
> version(linuxOrBSD){do_something;}
> (that's ugly but it's the official recommended way; much more verbose than:
> version(linux || BSD){do_something;}
> )

1. Verbosity is not the enemy. Clarity is the goal.

2. The example would be better as:

  version (linux){  version = Something;}
  version (BSD){  version = Something;}
  version(Something){do_Something;}

where Something is the name of the feature being enabled. With careful selection of Something, the code can be quite readable.
October 24, 2012
On 23/10/12 05:17, 1100110 wrote:
> Looking at std.io (hopefully the right version maybe?) I see this:
>
> version(OSX)
> {     do something; }
> version(Windows)
> {     do the same thing as above; }
> version(FreeBSD)
> {     ditto; }
> version(Linux)
> {    finally do something different; }
> and:
> version(Windows) version(DigitalMars)
> {     something; }
>
>
> I was rather surprised that this wasn't accepted:
> //Error: found '||' when expecting ')'
>
> version(OSX || Windows || FreeBSD)
> {     do something; }
> version(Linux)
> {     do something different; }
>
>
> The last one could be intuitively described as:
> version(Windows && DigitalMars)
> {     blah;     }

That allows you to create the same bird's nest that you can get with #ifdef in C.

See bug 7417 for a different solution that fixes other problems as well.
Just make version declarations behave like bool variable declarations:

version useTheOrdinaryWay = OSX || Windows || FreeBSD;

version dmdWindows = Windows && DigitalMars;
version (dmdWindows) { blah; }




October 24, 2012
On 24/10/2012 10:40, Don Clugston wrote:
> On 23/10/12 05:17, 1100110 wrote:
>> Looking at std.io (hopefully the right version maybe?) I see this:
>>
>> version(OSX)
>> {     do something; }
>> version(Windows)
>> {     do the same thing as above; }
>> version(FreeBSD)
>> {     ditto; }
>> version(Linux)
>> {    finally do something different; }
>> and:
>> version(Windows) version(DigitalMars)
>> {     something; }
>>
>>
>> I was rather surprised that this wasn't accepted:
>> //Error: found '||' when expecting ')'
>>
>> version(OSX || Windows || FreeBSD)
>> {     do something; }
>> version(Linux)
>> {     do something different; }
>>
>>
>> The last one could be intuitively described as:
>> version(Windows && DigitalMars)
>> {     blah;     }
>
> That allows you to create the same bird's nest that you can get with
> #ifdef in C.
>
> See bug 7417 for a different solution that fixes other problems as well.
> Just make version declarations behave like bool variable declarations:
>
> version useTheOrdinaryWay = OSX || Windows || FreeBSD;
>
> version dmdWindows = Windows && DigitalMars;
> version (dmdWindows) { blah; }

Vote up!
http://d.puremagic.com/issues/show_bug.cgi?id=7417