digitalmars.D - version()
- Manu (23/23) Jan 15 2012 Why can't I do this:
- Mike Parker (26/49) Jan 15 2012 This is something I've wanted ever since I first started using D. Really...
- Jacob Carlborg (5/28) Jan 15 2012 A workaround is to declare variables and use static ifs:
- Manu (6/42) Jan 15 2012 ... these aren't acceptable work arounds, in this case, you're written a
- Jacob Carlborg (5/41) Jan 15 2012 It is a workaround that works, regardless if you think it's acceptable
- Adam D. Ruppe (39/39) Jan 16 2012 I somewhat rarely use version anymore. I used
- Manu (29/68) Jan 16 2012 The fact that everyone has their own work-around, and everyone has a
- Era Scarecrow (7/12) Jan 16 2012 Seems I'm joining in the middle of a debate, sorry if I say anything al...
Why can't I do this:
version( linux || OSX )
{
  something common to each
}
???
This is not acceptable:
version( MinGW )
{
version = linuxOrMinGW;
}
else version( linux )
{
version = linuxOrMinGW;
}
version( linuxOrMinGW )
{
  seriously...?
}
Surely basic logical expressions within a version seem not only logical,
but also very necessary?
There must be a reason this is impossible, or else I can't believe it's not
already like that...
 Jan 15 2012
On 1/16/2012 8:44 AM, Manu wrote:
 Why can't I do this:
 version( linux || OSX )
 {
    something common to each
 }
 ???
 This is not acceptable:
 version( MinGW )
 {
 version = linuxOrMinGW;
 }
 else version( linux )
 {
 version = linuxOrMinGW;
 }
 version( linuxOrMinGW )
 {
    seriously...?
 }
 Surely basic logical expressions within a version seem not only logical,
 but also very necessary?
 There must be a reason this is impossible, or else I can't believe it's
 not already like that...
This is something I've wanted ever since I first started using D. Really 
annoying when you need to do the same sort of version checks across 
multiple modules. One workaround:
----------------
module myconfig;
version(MingW)
{
     enum bool linuxOrMingW = true;
}
else version(linux)
{
     enum bool linuxOrMingW = true;
}
else
{
     enum bool linuxOrMingW = false;
}
-----------------
module foo;
import myconfig;
static if(linuxOrMingW)
{
     ...
}
-----------------
 Jan 15 2012
On 2012-01-16 00:44, Manu wrote:
 Why can't I do this:
 version( linux || OSX )
 {
    something common to each
 }
 ???
 This is not acceptable:
 version( MinGW )
 {
 version = linuxOrMinGW;
 }
 else version( linux )
 {
 version = linuxOrMinGW;
 }
 version( linuxOrMinGW )
 {
    seriously...?
 }
 Surely basic logical expressions within a version seem not only logical,
 but also very necessary?
 There must be a reason this is impossible, or else I can't believe it's
 not already like that...
A workaround is to declare variables and use static ifs:
https://github.com/jacob-carlborg/orbit/blob/master/orbit/util/Version.d
-- 
/Jacob Carlborg
 Jan 15 2012
On 16 January 2012 09:28, Jacob Carlborg <doob me.com> wrote:On 2012-01-16 00:44, Manu wrote:... these aren't acceptable work arounds, in this case, you're written a whole module to subvert the insanity! :) At bare minimum, the version list/map/table/whatever it is should be exposed to static-if, without having to create a module like the one you just described.Why can't I do this: version( linux || OSX ) { something common to each } ??? This is not acceptable: version( MinGW ) { version = linuxOrMinGW; } else version( linux ) { version = linuxOrMinGW; } version( linuxOrMinGW ) { seriously...? } Surely basic logical expressions within a version seem not only logical, but also very necessary? There must be a reason this is impossible, or else I can't believe it's not already like that...A workaround is to declare variables and use static ifs: https://github.com/jacob-**carlborg/orbit/blob/master/** orbit/util/Version.d<https://github.com/jacob-carlborg/orbit/blob/master/orbit/util/Version.d>
 Jan 15 2012
On 2012-01-16 08:33, Manu wrote:
 On 16 January 2012 09:28, Jacob Carlborg <doob me.com
 <mailto:doob me.com>> wrote:
     On 2012-01-16 00:44, Manu wrote:
         Why can't I do this:
         version( linux || OSX )
         {
            something common to each
         }
         ???
         This is not acceptable:
         version( MinGW )
         {
         version = linuxOrMinGW;
         }
         else version( linux )
         {
         version = linuxOrMinGW;
         }
         version( linuxOrMinGW )
         {
            seriously...?
         }
         Surely basic logical expressions within a version seem not only
         logical,
         but also very necessary?
         There must be a reason this is impossible, or else I can't
         believe it's
         not already like that...
     A workaround is to declare variables and use static ifs:
     https://github.com/jacob-__carlborg/orbit/blob/master/__orbit/util/Version.d
     <https://github.com/jacob-carlborg/orbit/blob/master/orbit/util/Version.d>
 ... these aren't acceptable work arounds, in this case, you're written a
 whole module to subvert the insanity! :)
 At bare minimum, the version list/map/table/whatever it is should be
 exposed to static-if, without having to create a module like the one you
 just described.
It is a workaround that works, regardless if you think it's acceptable 
or not, and I've already done most of the work so you don't have to.
-- 
/Jacob Carlborg
 Jan 15 2012
I somewhat rarely use version anymore. I used
to use it for different client customizations
to my app, but you can't turn features on and
off in a a central file like that, since the
version= doesn't affect other modules.
I switched for a while to static if like this:
version(client_a)
  enum feature_x = true;
version(client_b)
  enum feature_x = false;
== other file ==
static if(feature_x)
   void feature_x_impl() {}
But, now, I have a way of doing it without
version, and it's even better.
client_a_config.d:
===
module app.config;
enum feature_x = true;
===
client_b_config.d:
===
module app.config;
enum feature_x = false;
===
Real file:
===
import app.config;
static if(feature_x)
  // implement
===
Then, I pick the desired version just by picking
the file on the command line.
So, there's no version stuff in there at all... I now
think version is *almost* useless. Could probably use
this for operating system versions too, putting the
common components in a shared file.
 Jan 16 2012
On 16 January 2012 23:19, Adam D. Ruppe <destructionator gmail.com> wrote:
 I somewhat rarely use version anymore. I used
 to use it for different client customizations
 to my app, but you can't turn features on and
 off in a a central file like that, since the
 version= doesn't affect other modules.
 I switched for a while to static if like this:
 version(client_a)
  enum feature_x = true;
 version(client_b)
  enum feature_x = false;
 == other file ==
 static if(feature_x)
  void feature_x_impl() {}
 But, now, I have a way of doing it without
 version, and it's even better.
 client_a_config.d:
 ===
 module app.config;
 enum feature_x = true;
 ===
 client_b_config.d:
 ===
 module app.config;
 enum feature_x = false;
 ===
 Real file:
 ===
 import app.config;
 static if(feature_x)
  // implement
 ===
 Then, I pick the desired version just by picking
 the file on the command line.
 So, there's no version stuff in there at all... I now
 think version is *almost* useless. Could probably use
 this for operating system versions too, putting the
 common components in a shared file.
The fact that everyone has their own work-around, and everyone has a
DIFFERENT work around is hard evidence that version() is insufficient, and
the current design is making D code WORSE.
Even Walter describes and supports the work-arounds to use in his poses
from years ago.
I can see absolutely no evidence that performing logical expressions on
versions is not required by any cross platform applications, including
phobos! However now, instead of expressing the logic in a concise and
familiar fashion, you have to try and decode each individuals own personal
work-around scheme, at the expense of 10s of lines of really ugly
spaghetti, and for absolutely no benefit.
There is hard evidence people can't work without version logic, so why
continue to deny it?
Using '} else {' as a substitute for ! for example, you're STILL typing
'!', you're just writing it in the ugliest and least intuitive way
possible. Are people REALLY more likely to mis-read/misunderstand the '!'
in the expression than miss the obscure 'else' statement to fake the same
effect?
Using 'version(A) version(B)' as a substitute for &&... it's still &&,
except it's way longer, and it's certainly not as clear that you're really
performing a boolean &&. Why not just write what it is?
And ||, the MOST common operation to want to perform... let's not mention
the work around, it's clearly the worst. Suffice to say, you're still
producing OR logic, but again, writing it in a really archaic fashion.
People ARE writing these logical constructs whether they use a clear
logical expressions or not... why not just let them write it between the
parentheses in a clear and concise manner, than scatter and obscure the
logic across 10 lines?
 Jan 16 2012
The fact that everyone has their own work-around, and everyone has a DIFFERENT work around is hard evidence that version() is insufficient, and the current design is making D code WORSE. Even Walter describes and supports the work-arounds to use in his poses from years ago.Seems I'm joining in the middle of a debate, sorry if I say anything already answered in a previous post. I may be in error, if so likely ignore this. This seems to be more a talk about inconsistent use of version (and redundancies). I'll add my two cents. It seems to me that OS and architecture specific modifications (that would make use of version()) should be in it's own file, perhaps something like 'arch_specific.d' and 'os_specific.d'. That way any unique and domain/system specific inconsistencies/issues can be handled in one place. Like Windows, Posix, x86_64 code, etc. Making multiple source files to deal with specific OS's or other related issues seems like the whole issue with code duplication (Change one, gotta change it everywhere else too). So having a 'os_windows.d' and 'os_posix.d' and a 'os_freebsd.d' and whatever other possible combinations just seems to in the long run breed problems rather than solving them, especially if they are minor differences between them. The only time you should include version specific in your sources, is when the differences are only in one spot (anywhere in the code), only one source file, or compile time sources and pre-compiled modules cannot work together. That goes down to compiler implementation. Likely you'll be compiling from sources so that ceases to be the issue. Version, mixins, static if's and aliases effectively remove the need for a preprocessor, doing the same job in a more controlled way that wasn't ugly and doesn't require extra passes through the source. But excessively using any and all of these (or misusing) can make code appear as bad as anything in a C's .h file. D is not a religion; But everyone (well almost) understands the need for consistency, code cleanliness and separation of Architecture & OS specific code. So barring the most trivial uses of version (or only found in one spot ever) guidelines and recommendations should be put down. 'The D Programming Language' book Andrei published has maybe a whole Page on version() total. The exact guidelines to follow may not matter so much, so long as it's clean, simple to follow and remember, and makes enough sense that everyone tries to adopt it. I'm sure if Walter or Andrei put an article, coding standards, or said 'Just do it this way', everyone would likely follow suit; Mostly since it gives you a direction and not leaving you to make up something on your own or worse follow previous conventions that used a pre-processor in C or C++. Hope I haven't rambled too much.
 Jan 16 2012








 
  
  
 
 Mike Parker <aldacron gmail.com>
 Mike Parker <aldacron gmail.com> 