March 08, 2012
I would like to do something like this:

version (linux || BSD) {
    // do something...
} else {
    version (Windows) {
        // do something else
    } else {
        // do something else
        assert(false, "Unsupported operating system");
    }
}

The only way I've been able to do this, is by splitting up the two versions and repeat code.

Is there a better way to do this? A static if can do this, so is there a way that I can use a static if somehow?
March 08, 2012
On 8 March 2012 18:38, Tyler Jameson Little <beatgammit@gmail.com> wrote:
> I would like to do something like this:
>
> version (linux || BSD) {
>    // do something...
> } else {
>    version (Windows) {
>        // do something else
>    } else {
>        // do something else
>        assert(false, "Unsupported operating system");
>    }
> }
>
> The only way I've been able to do this, is by splitting up the two versions and repeat code.
>
> Is there a better way to do this? A static if can do this, so is there a way that I can use a static if somehow?

I don't think there is an 'elseif' for versions, probably because you are normally checking mutually exclusive version descriptions. Otherwise, its probably a good idea to keep the syntax as is, since it stops people from abusing the mechanic.

--
James Miller
March 08, 2012
On 03/07/2012 10:07 PM, James Miller wrote:
> On 8 March 2012 18:38, Tyler Jameson Little<beatgammit@gmail.com>  wrote:
>> I would like to do something like this:
>>
>> version (linux || BSD) {
>>     // do something...
>> } else {
>>     version (Windows) {
>>         // do something else
>>     } else {
>>         // do something else
>>         assert(false, "Unsupported operating system");
>>     }
>> }
>>
>> The only way I've been able to do this, is by splitting up the two versions
>> and repeat code.
>>
>> Is there a better way to do this? A static if can do this, so is there a way
>> that I can use a static if somehow?
>
> I don't think there is an 'elseif' for versions, probably because you
> are normally checking mutually exclusive version descriptions.
> Otherwise, its probably a good idea to keep the syntax as is, since it
> stops people from abusing the mechanic.
>
> --
> James Miller

I had played with this in the past. The assignment to version has an interesting meaning of "collecting" everything assigned to it:

import std.stdio;

version (linux)
{
    version = linuxOrBSD;
    version = foo;
}

version (BSD)
{
    version = linuxOrBSD;
    version = foo;
}

void main()
{
    version (linuxOrBSD) {
        writeln("linux or BSD");
        // do something...
    } else {
        version (Windows) {
            // do something else
        } else {
            // do something else
            assert(false, "Unsupported operating system");
        }
    }

    // Later on even this works
    version (foo) {
        writeln("even foo!");
    }
}

Ali

March 08, 2012
On Thursday, March 08, 2012 06:38:48 Tyler Jameson Little wrote:
> I would like to do something like this:
> 
> version (linux || BSD) {
>      // do something...
> } else {
>      version (Windows) {
>          // do something else
>      } else {
>          // do something else
>          assert(false, "Unsupported operating system");
>      }
> }
> 
> The only way I've been able to do this, is by splitting up the two versions and repeat code.
> 
> Is there a better way to do this? A static if can do this, so is there a way that I can use a static if somehow?

You can do

version(x) {}
else version(y) {}
else {}

but there is no logical and or logical or with versions. It's _only_ checking whether a particular version exists or not. Walter Bright is completely against having anything more complicated with versioning, since he thinks that it just engenders bad code and bugs.

Now, you could do

version(x)
    version = xOrY
else version(y)
    version = xOrY

version(xOrY) {}

and then xOrY will exist for the rest of that module. But that's as close as you're going to ge to logical and or logical or for versions.

Of course, if the issue is linux || FreeBSD, you might want to just consider using Posix. Unless you're doing something that is specific to linux and FreeBSD but not Posix in general (which I would expect to be unlikely), Posix will do the trick just fine.

- Jonathan M Davis
March 08, 2012
> Now, you could do
>
> version(x)
>     version = xOrY
> else version(y)
>     version = xOrY
>
> version(xOrY) {}

Huh, clever! I like it!! I hope I don't have to do that very often, though...

> Of course, if the issue is linux || FreeBSD, you might want to just consider
> using Posix. Unless you're doing something that is specific to linux and
> FreeBSD but not Posix in general (which I would expect to be unlikely), Posix
> will do the trick just fine.

Yeah, that was just an example. Perhaps a better example would be comparing versions of something:

version (LIBV1 || LIBV2) {
    // include some dirty hacks for old versions
} else {
    // do some new fancy stuff for new features
}

I was mostly thinking that there are things that linux and BSD share that other BSDs may not. I know that Mac OS X has some subtle differences in a few things.

Anyway, I think this answers my question. I can get by with using your suggestion for those (hopefully) rare cases where I need something more specific.

Thanks!
March 08, 2012
> Now, you could do
>
> version(x)
>     version = xOrY
> else version(y)
>     version = xOrY
>
> version(xOrY) {}

Huh, clever! I like it!! I hope I don't have to do that very often, though...

> Of course, if the issue is linux || FreeBSD, you might want to just consider
> using Posix. Unless you're doing something that is specific to linux and
> FreeBSD but not Posix in general (which I would expect to be unlikely), Posix
> will do the trick just fine.

Yeah, that was just an example. Perhaps a better example would be comparing versions of something:

version (LIBV1 || LIBV2) {
    // include some dirty hacks for old versions
} else {
    // do some new fancy stuff for new features
}

I was mostly thinking that there are things that linux and BSD share that other BSDs may not. I know that Mac OS X has some subtle differences in a few things.

Anyway, I think this answers my question. I can get by with using your suggestion for those (hopefully) rare cases where I need something more specific.

Thanks!
March 08, 2012
On 2012-03-08 06:38, Tyler Jameson Little wrote:
> I would like to do something like this:
>
> version (linux || BSD) {
> // do something...
> } else {
> version (Windows) {
> // do something else
> } else {
> // do something else
> assert(false, "Unsupported operating system");
> }
> }
>
> The only way I've been able to do this, is by splitting up the two
> versions and repeat code.
>
> Is there a better way to do this? A static if can do this, so is there a
> way that I can use a static if somehow?

A workaround is to use static if constants, here's a start:

https://github.com/jacob-carlborg/mambo/blob/master/util/Version.d

-- 
/Jacob Carlborg
March 08, 2012
On Thu, 08 Mar 2012 06:12:44 -0000, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> On Thursday, March 08, 2012 06:38:48 Tyler Jameson Little wrote:
>> I would like to do something like this:
>>
>> version (linux || BSD) {
>>      // do something...
>> } else {
>>      version (Windows) {
>>          // do something else
>>      } else {
>>          // do something else
>>          assert(false, "Unsupported operating system");
>>      }
>> }
>>
>> The only way I've been able to do this, is by splitting up the
>> two versions and repeat code.
>>
>> Is there a better way to do this? A static if can do this, so is
>> there a way that I can use a static if somehow?

> <snip>... Walter Bright is completely
> against having anything more complicated with versioning, since he thinks that
> it just engenders bad code and bugs.

IIRC the argument was that we should define version identifiers for 'features' or 'behaviours' not for platforms, etc.

So, given the 2nd example, instead of:

version (LIBV1 || LIBV2) {
    // include some dirty hacks for old versions
} else {
    // do some new fancy stuff for new features
}

do:

version (LIBV1) version = LIB_OLD
version (LIBV2) version = LIB_OLD

version (LIB_OLD) {
  // dirty hacks
} else {
  // new fancy stuff
}

Regan

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
March 08, 2012
On Thu, 08 Mar 2012 01:07:08 -0500, James Miller <james@aatch.net> wrote:

> On 8 March 2012 18:38, Tyler Jameson Little <beatgammit@gmail.com> wrote:
>> I would like to do something like this:
>>
>> version (linux || BSD) {
>>    // do something...
>> } else {
>>    version (Windows) {
>>        // do something else
>>    } else {
>>        // do something else
>>        assert(false, "Unsupported operating system");
>>    }
>> }
>>
>> The only way I've been able to do this, is by splitting up the two versions
>> and repeat code.
>>
>> Is there a better way to do this? A static if can do this, so is there a way
>> that I can use a static if somehow?
>
> I don't think there is an 'elseif' for versions, probably because you
> are normally checking mutually exclusive version descriptions.
> Otherwise, its probably a good idea to keep the syntax as is, since it
> stops people from abusing the mechanic.

Noting that there actually isn't an elseif keyword for if either, of course there is the same construct for version:

// if
if(cond1)
{}
else if(cond2)
{}

// version
version(version1)
{}
else version(version2)
{}

-Steve
March 08, 2012
I find it interesting that having this feature would somehow "enable" abuse, yet we can do so much abuse already with CTFE, templates, and string mixins. One large pain in the ass is to pass an integral at compile time. I sometimes wish to use a syntax such as "version(foo == 5) {}". The only alternative that I know of is to use string imports via -J switch to initialize an enum. Compare that with the simple -Dfoo=5 in DMC/GCC/etc. We might not have globals or macros in D, but at least 'version(foo) = 5' or something similar should work. It's also strange that version uses its own meaning of the equals operator, I really dislike that.

Generally it seems version is the poorest-developed feature of D. And the counterargument for new features is always a Go-like stance ("you just won't need it"/"people will abuse the feature").

Of course all I can do now is whine and not propose something better. :) But there have been a few threads about version and its issues. I think it's only a matter of time before D gets popular enough that we get these kinds of threads every other day. Maybe then something will change.
« First   ‹ Prev
1 2 3
Top | Discussion index | About this forum | D home