February 11, 2009
Walter Bright wrote:
> Denis Koroskin wrote:
>> Why did you catch that controversial !Linux example? Just imagine it is !HasFeatureX:
>>
>> version(!HasFeatureX) {
>>   ...
>> }
>>
>> is so much more intuitive than
>>
>> version (HasFeatureX) {
>> } else {
>>   ...
>> }
> 
> 
> This is to combat the pernicious problem of having features that subtract code <g>.

I've got two words for you, Walter.
Compiler bugs.
February 11, 2009
Don wrote:
> Walter Bright wrote:
>> This is to combat the pernicious problem of having features that subtract code <g>.
> 
> I've got two words for you, Walter.
> Compiler bugs.

I've never heard of those before. Are they like VW Bugs?
February 11, 2009
On Tue, 10 Feb 2009 19:28:46 -0800, Walter Bright wrote:

> Steven Schveighoffer wrote:
>> That example has nothing to do with || being allowed, and nothing to do with your exhibit B.  Your simple example makes sense to split into multiple files, but you simply waved your magic "split into multiple files" wand at Hans' code and because of the simplicity of D's versioning system, it's more maintainable?  I find it hard to believe without proof.
> 
> I cannot prove to you in any mathematical sort of way. All I can say is that I have a lot of experience doing things both ways, and what the results are. I can readily believe that it isn't obvious until one has done it both ways; programming is full of examples of such. Such as:
> 
> #define BEGIN {
> #define END }
> 
> I can't prove that's a bad idea, either. But experience shows it is <g>.

It's bad.  I agree with you.  I also have bad experiences with the preprocessor, one of the reasons I looked for something like D in the first place, and one of the reasons I'm leary of macros.  I'm not asking for the C preprocessor.  I'm asking for a bit of syntax sugar to avoid unmaintainable tables of expanded if statements.  What I mean by expanded if statements is that you are making me expand:

if(a || b)
  statement;

into

bool aorb = false;
if(a)
  aorb = true;
if(b)
  aorb = true;
if(c)
  statement;

Let's take a trip to analogy land.  It's like you are saying you have been bit by a tiger in the past.  Therefore, you dislike all animals, because they remind you of tigers, and who could blame you.  But because of your position of power, you have passed a law that *nobody* can like animals, for their own good.  Why not just avoid animals on your own, and let others have their tame animals?

> 
> 
>> Besides, your example exists *without* any new features to the versioning system.  That is, your example just shows how it's easier to maintain if you put the version identifier at the outermost layer, instead of in the innermost layer, and I agree with you there.  I just want to try and get rid of the cruft of:
>> 
>> version(A)
>>    version = AorB;
>> version(B)
>>    version = AorB;
> 
> I think I've been misunderstood here. I never intended one to actually use the "or" string in a version, my intent was that one determine just what the feature is that is AorB, and name the identifier that. For example:
> 
> version (linux)
> 	version = Pthreads;
> version (OSX)
> 	version = Pthreads;
> 
> version (Pthreads)
> 	...
> else version (Windows)
> 	...
> 
> I don't consider that cruft, but very reasonable self-documentation.

This is still cruft.  I'd consider this to be more succinct and just as self documenting (as well as more maintainable, I no longer have to change the string Pthreads in multiple locations in the declaration of it).

version(linux || OSX)
   version = Pthreads;

...

> 
> 
>> If you want to prove how much easier it is, actually split Hans' rat's nest into multiple files how you would do it, and I'll show you that it isn't any harder to maintain if you use ||.
> 
> I already did port it once, many years ago, it's why I know how hard it is. Take a look at D's gc which uses personality modules. I ported that to the mac pretty easily and never touched the main code. I can't even figure out where the mac osx code is in the hbgc or what would need to be changed for it. I couldn't even figure out if the hbgc supported OSX or not.
> 
> To sum up, I've done it both ways. The personality module method approach is head and shoulders the clear winner.

That's all fine, and I pretty much agree with you, but I think we are arguing apples and oranges.  In what way does using || in a version statement prevent or even discourage you from separating out your versions into modules based on platforms or personality?  It seems like a design preference that is orthogonal to this feature.

For instance, two developers quite easily translated the complicated C preprocessor example you gave into version statements for the *current* version system.  So it's still possible to have unmaintainable, unreadable code without || as a feature.

All I'm asking is to make this:

version(x || y)

turn into this:

version(x)
   version = xory;
version(y)
   version = xory;
version(xory)

automatically by the compiler.  I shouldn't have to do that bit of manual compilation.

-Steve
February 11, 2009
On Wed, 11 Feb 2009 05:43:48 +0000, Steve Schveighoffer wrote:

> What I mean by
> expanded if statements is that you are making me expand:
> 
> if(a || b)
>   statement;
> 
> into
> 
> bool aorb = false;
> if(a)
>   aorb = true;
> if(b)
>   aorb = true;
> if(c)
>   statement;

This should have been
if(aorb)
  statement;

-Steve
February 11, 2009
On Wed, 11 Feb 2009 14:07:29 +1100, Daniel Keep wrote:
> What about this?
> 
> /+{{VersionIdentifier}} ... +/


is that just a neater way to do this?
version(Identifier) { mixin(`
//code!
`)}
February 11, 2009
On Wed, 11 Feb 2009 08:51:10 +0000, Brian wrote:

> On Wed, 11 Feb 2009 14:07:29 +1100, Daniel Keep wrote:
>> What about this?
>> 
>> /+{{VersionIdentifier}} ... +/
> 
> 
> is that just a neater way to do this? version(Identifier) { mixin(`
> //code!
> `)}

after writing that i realized the mixin is probably evaluated even if the version is false, that kind of destroys that idea.
February 11, 2009
Brian wrote:
> On Wed, 11 Feb 2009 08:51:10 +0000, Brian wrote:
> 
>> On Wed, 11 Feb 2009 14:07:29 +1100, Daniel Keep wrote:
>>> What about this?
>>>
>>> /+{{VersionIdentifier}} ... +/
>>
>> is that just a neater way to do this? version(Identifier) { mixin(`
>> //code!
>> `)}
> 
> after writing that i realized the mixin is probably evaluated even if the version is false, that kind of destroys that idea.

mixin( version(Identifier) { `//code!` } else { ``});
February 11, 2009
Walter Bright wrote:

> 1. Why not version(!feature) ?
> 
> Because cognitive studies show that people just don't see the negation. Secondly, when you see things like:
> 
>     version (!linux) { ... }
> 
> they're almost always wrong. Versions should be positive things, because a version is something that is being build - one doesn't craft a makefile to build a notLinux.

And for code that can't/won't be rewritten, there's the workaround:

version (linux) {} else { ... }

But yeah, using Unix or Posix would be better than using !Windows.
(only problem there being that both those versions are in use now)

--anders
February 11, 2009
"Daniel Keep" <daniel.keep.lists@gmail.com> wrote in message news:gmtfd9$1bjk$1@digitalmars.com...
>
> What about this?
>
> /+{{VersionIdentifier}} ... +/
>

One thing that's nice about that in a really bizarre sort of way is that none of the code editors I've tried support syntax highlighting of nested comments, so all the code inside there would automatically be properly highlighted ;-)


February 11, 2009
Walter Bright wrote:

> Now let's try the other way. I add O_APPEND to the linux branch, and linux works great. Now I port to OSX, and the compiler dies with "O_APPEND is undefined". I know immediately exactly what is wrong, look up the .h file, and insert the right O_APPEND into the OSX version of the declaration.

Maybe I'm missing something here, but why is Mac OS X including
std.c.linux.linux ? Shouldn't it use std.c.darwin.darwin instead ?

> Furthermore, when I build a FreeBSD version, the compiler bings at me for every declaration that needs some porting attention, instead of silently using the wrong values.

GDC got tired of porting std.c.linux.linux over, so it generates a
std.c.unix.unix module from the C headers at configure time instead.

Also helps with the constants that have different values for different
architectures, in addition to having different values for different OS.

> This would be even better if the OSX and linux declarations were split into separate "personality" modules. That way you can develop happily on OSX without fear of accidentally breaking linux support. You can defer dealing with the linux version until you actually on the linux machine and are in an efficient position to take care of it.

The version(linux) and version(darwin) should keep those separated,
right ? And save you when you include the wrong std.c module, too...

--anders