www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - version and debug statements

reply maxter i.com.ua writes:
i've noticed code like this:

version (foo)
{}
else
{
	do something...
}

would it be more natural to be able to write:

version (!foo)
{
	do something...				
} 

the same applies to the debug statement. thanks
May 09 2006
parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
maxter wrote:

 i've noticed code like this:
 
 version (foo)
 {}
 else
 {
 	do something...
 }

Usually written as: version (foo) {} else { .... }
 would it be more natural to be able to write:
 
 version (!foo)
 {
 	do something...				
 } 
 
 the same applies to the debug statement. thanks

Yes it would, and Thomas patched this in bug #2522 digitalmars.D.bugs/2522 But I don't think that they ever caught on with W. digitalmars.D/11946 digitalmars.D/11995 --anders
May 09 2006
next sibling parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Anders F Björklund wrote:
 maxter wrote:
 
 i've noticed code like this:

 version (foo)
 {}
 else
 {
     do something...
 }

Usually written as: version (foo) {} else { .... }

Yeah, I've had to do that a few times myself; very annoying.
 would it be more natural to be able to write:

 version (!foo)
 {
     do something...               
 }
 the same applies to the debug statement. thanks

Yes it would, and Thomas patched this in bug #2522 digitalmars.D.bugs/2522 But I don't think that they ever caught on with W. digitalmars.D/11946 digitalmars.D/11995 --anders

That's odd, given that D is more or less designed to avoid silly hacks like this... -- Daniel -- v1sw5+8Yhw5ln4+5pr6OFma8u6+7Lw4Tm6+7l6+7D a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
May 10 2006
next sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Daniel Keep wrote:

 version (foo) {} else
 {
      ....
 }


 That's odd, given that D is more or less designed to avoid silly hacks
 like this...

Both D and W seem to be more open to suggestions now, so maybe it will be added in a future DMD version yet ? I'm still naively hoping for both of "version (Unix)" and "version (!Windows)" to be defined and legal in D. --anders
May 11 2006
next sibling parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Anders F Björklund wrote:
 Daniel Keep wrote:
 
 version (foo) {} else
 {
      ....
 }


 That's odd, given that D is more or less designed to avoid silly hacks
 like this...

Both D and W seem to be more open to suggestions now, so maybe it will be added in a future DMD version yet ? I'm still naively hoping for both of "version (Unix)" and "version (!Windows)" to be defined and legal in D. --anders

Well, I'll continue to hope that at some point it grows boolean expressions in version statements like "version(BSD | Linux)", but I can live without those :) -- Daniel -- v1sw5+8Yhw5ln4+5pr6OFma8u6+7Lw4Tm6+7l6+7D a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
May 11 2006
next sibling parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Daniel Keep wrote:

 Well, I'll continue to hope that at some point it grows boolean
 expressions in version statements like "version(BSD | Linux)", but I can
 live without those :)

Yeah, those can be hacked too. version (freebsd) version = freebsd_or_linux; version (linux) version = freebsd_or_linux; version (freebsd_or_linux) { ... } --anders PS. All platforms except Windows (and "Unix") use lowercase... http://www.prowiki.org/wiki4d/wiki.cgi?DocComments/Version
May 11 2006
prev sibling next sibling parent reply Don Clugston <dac nospam.com.au> writes:
Daniel Keep wrote:
 
 Anders F Björklund wrote:
 Daniel Keep wrote:

 version (foo) {} else
 {
      ....
 }

like this...

so maybe it will be added in a future DMD version yet ? I'm still naively hoping for both of "version (Unix)" and "version (!Windows)" to be defined and legal in D. --anders

Well, I'll continue to hope that at some point it grows boolean expressions in version statements like "version(BSD | Linux)", but I can live without those :) -- Daniel

Since "static if" is now legal at module scope, it's now practically a superset of "version". So it shouldn't be very complicated to move some of the functionality across. (There's a problem with using 'static if' instead of 'version' : if there's an 'import' statement bracketed by a static if, potentially you have to compile the program to find out which files are included. Obviously 'build' can't cope with that).
May 11 2006
parent reply "Derek Parnell" <derek psych.ward> writes:
On Thu, 11 May 2006 19:32:07 +1000, Don Clugston <dac nospam.com.au> wrote:


 Since "static if" is now legal at module scope, it's now practically a  
 superset of "version". So it shouldn't be very complicated to move some  
 of the functionality across. (There's a problem with using 'static if'  
 instead of 'version' : if there's an 'import' statement bracketed by a  
 static if, potentially you have to compile the program to find out which  
 files are included. Obviously 'build' can't cope with that).

And I don't want to make Build be a compiler too ;-) So I don't think it will ever try to execute static if statements. -- Derek Parnell Melbourne, Australia
May 11 2006
next sibling parent pragma <pragma_member pathlink.com> writes:
In article <op.s9d3gilp6b8z09 ginger>, Derek Parnell says...
On Thu, 11 May 2006 19:32:07 +1000, Don Clugston <dac nospam.com.au> wrote:


 Since "static if" is now legal at module scope, it's now practically a  
 superset of "version". So it shouldn't be very complicated to move some  
 of the functionality across. (There's a problem with using 'static if'  
 instead of 'version' : if there's an 'import' statement bracketed by a  
 static if, potentially you have to compile the program to find out which  
 files are included. Obviously 'build' can't cope with that).

And I don't want to make Build be a compiler too ;-) So I don't think it will ever try to execute static if statements.

I'll second that. Its also bad enough that any ddoc processing tool has to navigate version statement on top of comments and declarations. Adding the complexity of static if() would *really* overcomplicate things. - EricAnderton at yahoo
May 11 2006
prev sibling parent reply "Ameer Armaly" <ameer_armaly hotmail.com> writes:
"Derek Parnell" <derek psych.ward> wrote in message 
news:op.s9d3gilp6b8z09 ginger...
 On Thu, 11 May 2006 19:32:07 +1000, Don Clugston <dac nospam.com.au> 
 wrote:


 Since "static if" is now legal at module scope, it's now practically a 
 superset of "version". So it shouldn't be very complicated to move some 
 of the functionality across. (There's a problem with using 'static if' 
 instead of 'version' : if there's an 'import' statement bracketed by a 
 static if, potentially you have to compile the program to find out which 
 files are included. Obviously 'build' can't cope with that).

And I don't want to make Build be a compiler too ;-) So I don't think it will ever try to execute static if statements.

functionality of build directly in to the compiler; have it compile all current directory imports and link them together. If -c is supplied, then the compiler would compile them only as opposed to linking, facilitating flexible build processes. An advantage of this sort of approach is that the compiler already needs to know all about imports and locations, so the logical extension of that idea would be to have the compiler act on them. This is just something I came up with randomly while reading this thread; I don't know whether or not it's been proposed before.
 -- 
 Derek Parnell
 Melbourne, Australia 

May 11 2006
parent reply pagma <pagma_member pathlink.com> writes:
In article <e4069c$2da5$1 digitaldaemon.com>, Ameer Armaly says...
"Derek Parnell" <derek psych.ward> wrote in message 
news:op.s9d3gilp6b8z09 ginger...
 On Thu, 11 May 2006 19:32:07 +1000, Don Clugston <dac nospam.com.au> 
 wrote:


 Since "static if" is now legal at module scope, it's now practically a 
 superset of "version". So it shouldn't be very complicated to move some 
 of the functionality across. (There's a problem with using 'static if' 
 instead of 'version' : if there's an 'import' statement bracketed by a 
 static if, potentially you have to compile the program to find out which 
 files are included. Obviously 'build' can't cope with that).

And I don't want to make Build be a compiler too ;-) So I don't think it will ever try to execute static if statements.

functionality of build directly in to the compiler; have it compile all current directory imports and link them together. If -c is supplied, then the compiler would compile them only as opposed to linking, facilitating flexible build processes. An advantage of this sort of approach is that the compiler already needs to know all about imports and locations, so the logical extension of that idea would be to have the compiler act on them. This is just something I came up with randomly while reading this thread; I don't know whether or not it's been proposed before.

AFAIK its been proposed before. I think the opinion of many was that the benefit of having many utils that each do a particular job well, outweighs the strengths of a single swiss-army-style application; hence the term "toolchain". This also happens to be the main philosophy behind Unix in general, and (IMO) is one of the main reasons why the parts that have always worked well continue to do so. :) Also, In the case of DMD and Build, each is maintained by a separate person - we get far better man/hr per LOC coverage this way than if Walter has to manage both feature sets. ;) - EricAnderton at yahoo
May 11 2006
parent reply Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
pagma wrote:
 In article <e4069c$2da5$1 digitaldaemon.com>, Ameer Armaly says...
 "Derek Parnell" <derek psych.ward> wrote in message 
 news:op.s9d3gilp6b8z09 ginger...
 On Thu, 11 May 2006 19:32:07 +1000, Don Clugston <dac nospam.com.au> 
 wrote:


 Since "static if" is now legal at module scope, it's now practically a 
 superset of "version". So it shouldn't be very complicated to move some 
 of the functionality across. (There's a problem with using 'static if' 
 instead of 'version' : if there's an 'import' statement bracketed by a 
 static if, potentially you have to compile the program to find out which 
 files are included. Obviously 'build' can't cope with that).

will ever try to execute static if statements.

functionality of build directly in to the compiler; have it compile all current directory imports and link them together. If -c is supplied, then the compiler would compile them only as opposed to linking, facilitating flexible build processes. An advantage of this sort of approach is that the compiler already needs to know all about imports and locations, so the logical extension of that idea would be to have the compiler act on them. This is just something I came up with randomly while reading this thread; I don't know whether or not it's been proposed before.

AFAIK its been proposed before. I think the opinion of many was that the benefit of having many utils that each do a particular job well, outweighs the strengths of a single swiss-army-style application; hence the term "toolchain". This also happens to be the main philosophy behind Unix in general, and (IMO) is one of the main reasons why the parts that have always worked well continue to do so. :) Also, In the case of DMD and Build, each is maintained by a separate person - we get far better man/hr per LOC coverage this way than if Walter has to manage both feature sets. ;) - EricAnderton at yahoo

On the other hand, it happens that here that the "each do a particular job well" has something to be said: there is much overlap in the jobs of both utils (the compiler and build), such in fact that I think their jobs are not that different. And as an example, the java compiler (javac) does this. -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
May 12 2006
next sibling parent reply "Derek Parnell" <derek psych.ward> writes:
On Fri, 12 May 2006 23:41:09 +1000, Bruno Medeiros  
<brunodomedeirosATgmail SPAM.com> wrote:


 On the other hand, it happens that here that the "each do a particular  
 job well" has something to be said: there is much overlap in the jobs of  
 both utils (the compiler and build), such in fact that I think their  
 jobs are not that different.

However, with the next release of Build the differences will be much more pronounced. I've completed the coding for v3.0 of Build and I'm just tidying up the docs this weekend. The main new feature, which btw makes it diverge from DMD, is a macro processor. At this stage its only a text replacement feature but in subsequent releases it will have a fully functional macro processor included (which is already designed and prototyped). Just as an example, it can now transform things such as "for i = 1 to 100 do" to "for(int i = 1; i <= 100; i++){" -- Derek Parnell Melbourne, Australia
May 10 2006
next sibling parent reply Kyle Furlong <kylefurlong gmail.com> writes:
Derek Parnell wrote:
 On Fri, 12 May 2006 23:41:09 +1000, Bruno Medeiros 
 <brunodomedeirosATgmail SPAM.com> wrote:
 
 
 On the other hand, it happens that here that the "each do a particular 
 job well" has something to be said: there is much overlap in the jobs 
 of both utils (the compiler and build), such in fact that I think 
 their jobs are not that different.

However, with the next release of Build the differences will be much more pronounced. I've completed the coding for v3.0 of Build and I'm just tidying up the docs this weekend. The main new feature, which btw makes it diverge from DMD, is a macro processor. At this stage its only a text replacement feature but in subsequent releases it will have a fully functional macro processor included (which is already designed and prototyped). Just as an example, it can now transform things such as "for i = 1 to 100 do" to "for(int i = 1; i <= 100; i++){" --Derek Parnell Melbourne, Australia

I thought this sort of thing was generally decided to be A Bad Thingâ„¢ -- Kyle Furlong // Physics Undergrad, UCSB "D is going wherever the D community wants it to go." - Walter Bright
May 12 2006
parent reply "Derek Parnell" <derek psych.ward> writes:
On Sat, 13 May 2006 05:44:27 +1000, Kyle Furlong <kylefurlong gmail.com>  
wrote:

 Derek Parnell wrote:

 The main new feature, which btw makes it diverge from DMD, is a macro  
 processor.


 I thought this sort of thing was generally decided to be A Bad Thingâ„¢

So don't use it. Like 'goto'. -- Derek Parnell Melbourne, Australia
May 10 2006
parent Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Derek Parnell wrote:
 On Sat, 13 May 2006 05:44:27 +1000, Kyle Furlong <kylefurlong gmail.com> 
 wrote:
 
 Derek Parnell wrote:

 The main new feature, which btw makes it diverge from DMD, is a macro 
 processor.


 I thought this sort of thing was generally decided to be A Bad Thingâ„¢

So don't use it. Like 'goto'. --Derek Parnell Melbourne, Australia

Yet this kinda of thing seems worse than 'goto' and worse so that just not personally using it isn't enough. It begs for non-use advocacy to other people :/ You are, of course, free to do as you wish, but still.. -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
May 13 2006
prev sibling parent reply "Ameer Armaly" <ameer_armaly hotmail.com> writes:
"Derek Parnell" <derek psych.ward> wrote in message 
news:op.s9cnlnwc6b8z09 ginger...
 On Fri, 12 May 2006 23:41:09 +1000, Bruno Medeiros 
 <brunodomedeirosATgmail SPAM.com> wrote:


 On the other hand, it happens that here that the "each do a particular 
 job well" has something to be said: there is much overlap in the jobs of 
 both utils (the compiler and build), such in fact that I think their 
 jobs are not that different.

However, with the next release of Build the differences will be much more pronounced. I've completed the coding for v3.0 of Build and I'm just tidying up the docs this weekend. The main new feature, which btw makes it diverge from DMD, is a macro processor. At this stage its only a text replacement feature but in subsequent releases it will have a fully functional macro processor included (which is already designed and prototyped). Just as an example, it can now transform things such as "for i = 1 to 100 do" to "for(int i = 1; i <= 100; i++){"

project management and automation program?
 -- 
 Derek Parnell
 Melbourne, Australia 

May 12 2006
parent reply "Derek Parnell" <derek psych.ward> writes:
On Sat, 13 May 2006 06:25:13 +1000, Ameer Armaly  
<ameer_armaly hotmail.com> wrote:



 Just as an example, it can now transform things such as
   "for i = 1 to 100 do"
 to
   "for(int i = 1; i <= 100; i++){"

project management and automation program?

I neither know nor care. ;-) -- Derek Parnell Melbourne, Australia
May 10 2006
parent reply "Ameer Armaly" <ameer_armaly hotmail.com> writes:
"Derek Parnell" <derek psych.ward> wrote in message 
news:op.s9c0g6vc6b8z09 ginger...
 On Sat, 13 May 2006 06:25:13 +1000, Ameer Armaly 
 <ameer_armaly hotmail.com> wrote:



 Just as an example, it can now transform things such as
   "for i = 1 to 100 do"
 to
   "for(int i = 1; i <= 100; i++){"

project management and automation program?

I neither know nor care. ;-)

building, so why stuff them together in the same package, especially since it almost invents a new layered language? Furthermore, since building is really nothing mroe than taking advantage of already present information in the compilation phase, it would be redundant not to at least consider the idea of combining the two. By not knowing and caring, you're essentially putting together a secondary layered compiler with various features but without any consideration as to whether or not they actually belong there.
 -- 
 Derek Parnell
 Melbourne, Australia 

May 12 2006
next sibling parent reply Mike Parker <aldacron71 yahoo.com> writes:
Ameer Armaly wrote:

 But that's exactly my point- a macro processor is independent of automatic 
 building, so why stuff them together in the same package, especially since 
 it almost invents a new layered language?  Furthermore, since building is 
 really nothing mroe than taking advantage of already present information in 
 the compilation phase, it would be redundant not to at least consider the 
 idea of combining the two.  By not knowing and caring, you're essentially 
 putting together a secondary layered compiler with various features but 
 without any consideration as to whether or not they actually belong there.

Does it really matter? Having extra functionality in one tool is a convenience I find attractive. I hate having multiple tools in a tool chain. The more functionality Build gives me in one package, the better.
May 12 2006
parent reply "Ameer Armaly" <ameer_armaly hotmail.com> writes:
"Mike Parker" <aldacron71 yahoo.com> wrote in message 
news:e43e2l$svk$1 digitaldaemon.com...
 Ameer Armaly wrote:

 But that's exactly my point- a macro processor is independent of 
 automatic building, so why stuff them together in the same package, 
 especially since it almost invents a new layered language?  Furthermore, 
 since building is really nothing mroe than taking advantage of already 
 present information in the compilation phase, it would be redundant not 
 to at least consider the idea of combining the two.  By not knowing and 
 caring, you're essentially putting together a secondary layered compiler 
 with various features but without any consideration as to whether or not 
 they actually belong there.

Does it really matter? Having extra functionality in one tool is a convenience I find attractive. I hate having multiple tools in a tool chain. The more functionality Build gives me in one package, the better.

the full-build functionality being in the compiler proper. As to the macro processor and related components, I just don't see any logical grouping for them along with project building, thus they should be in their own plugin.
May 12 2006
parent Chad J <gamerChad _spamIsBad_gmail.com> writes:
Ameer Armaly wrote:
 "Mike Parker" <aldacron71 yahoo.com> wrote in message 
 news:e43e2l$svk$1 digitaldaemon.com...
 
Does it really matter? Having extra functionality in one tool is a 
convenience I find attractive. I hate having multiple tools in a tool 
chain. The more functionality Build gives me in one package, the better.

I agree with your philosophy on tool chains, which is exactly why I advocate the full-build functionality being in the compiler proper. As to the macro processor and related components, I just don't see any logical grouping for them along with project building, thus they should be in their own plugin.

I also agree with that all-in-one package ideal. Simple experience has shown me that I do NOT enjoy hunting down multiple downloads, learning multiple interfaces, and dealing with a number of things that are totally unnecessary in about 99% of cases. That said, I feel the argument against merging build and dmd is a good one. Let Derek and Walter work in their most efficient ways. My suggestion would be to bundle executables, not source. Just stick a sufficiently recent version of build in with every release of dmd. Document its functionality along side dmd's, at least in a basic "heads up" sorta way. This would save a very unnecessary step for every new D user on the path to having an intuitive setup for coding in D. My typical routine for setting up D on a new computer looks like this: Download/install dm linker Download/install dmd compiler Download build, toss build.exe into /dmd/bin Set up environment paths as needed (move onto other more specialized stuff here, like multimedia) We could at least get rid of one step there.
May 12 2006
prev sibling parent "Derek Parnell" <derek psych.ward> writes:
On Sat, 13 May 2006 10:57:33 +1000, Ameer Armaly  
<ameer_armaly hotmail.com> wrote:

 "Derek Parnell" <derek psych.ward> wrote in message
 news:op.s9c0g6vc6b8z09 ginger...
 On Sat, 13 May 2006 06:25:13 +1000, Ameer Armaly
 <ameer_armaly hotmail.com> wrote:



 Just as an example, it can now transform things such as
   "for i = 1 to 100 do"
 to
   "for(int i = 1; i <= 100; i++){"

project management and automation program?

I neither know nor care. ;-)

automatic building, so why stuff them together in the same package, especially since it almost invents a new layered language? Furthermore, since building is really nothing mroe than taking advantage of already present information in the compilation phase, it would be redundant not to at least consider the idea of combining the two. By not knowing and caring, you're essentially putting together a secondary layered compiler with various features but without any consideration as to whether or not they actually belong there.

So? If the tool is not worth using then don't use it. I'm not going to lose any sleep over it. The purpose of Build is to automate the 'building' process and if text processing can help somebody with that, it offers it. I could have made a separate Text Processing Utility (which I might just do anyhow), but for now, my 'macro' library is being used by Build rather than having a separate process. So such an attitude might not sit well with tool chain purists but I simply don't care for now. The source is freely available for anyone to fork the tool. -- Derek Parnell Melbourne, Australia
May 10 2006
prev sibling parent "Ameer Armaly" <ameer_armaly hotmail.com> writes:
"Bruno Medeiros" <brunodomedeirosATgmail SPAM.com> wrote in message 
news:e4238i$20ln$1 digitaldaemon.com...
 pagma wrote:
 In article <e4069c$2da5$1 digitaldaemon.com>, Ameer Armaly says...
 "Derek Parnell" <derek psych.ward> wrote in message 
 news:op.s9d3gilp6b8z09 ginger...
 On Thu, 11 May 2006 19:32:07 +1000, Don Clugston <dac nospam.com.au> 
 wrote:


 Since "static if" is now legal at module scope, it's now practically a 
 superset of "version". So it shouldn't be very complicated to move 
 some of the functionality across. (There's a problem with using 
 'static if' instead of 'version' : if there's an 'import' statement 
 bracketed by a static if, potentially you have to compile the program 
 to find out which files are included. Obviously 'build' can't cope 
 with that).

it will ever try to execute static if statements.

project functionality of build directly in to the compiler; have it compile all current directory imports and link them together. If -c is supplied, then the compiler would compile them only as opposed to linking, facilitating flexible build processes. An advantage of this sort of approach is that the compiler already needs to know all about imports and locations, so the logical extension of that idea would be to have the compiler act on them. This is just something I came up with randomly while reading this thread; I don't know whether or not it's been proposed before.

AFAIK its been proposed before. I think the opinion of many was that the benefit of having many utils that each do a particular job well, outweighs the strengths of a single swiss-army-style application; hence the term "toolchain". This also happens to be the main philosophy behind Unix in general, and (IMO) is one of the main reasons why the parts that have always worked well continue to do so. :) Also, In the case of DMD and Build, each is maintained by a separate person - we get far better man/hr per LOC coverage this way than if Walter has to manage both feature sets. ;) - EricAnderton at yahoo

On the other hand, it happens that here that the "each do a particular job well" has something to be said: there is much overlap in the jobs of both utils (the compiler and build), such in fact that I think their jobs are not that different. And as an example, the java compiler (javac) does this.

applied here: it requires an understanding of the language in order to process imports, something that the compiler already has. Thus, if the compiler were to take that information and use it to build whole projects, IMO it would be a bit more efficient.
 -- 
 Bruno Medeiros - CS/E student
 http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D 

May 12 2006
prev sibling parent Walter Bright <newshound digitalmars.com> writes:
Daniel Keep wrote:
 Well, I'll continue to hope that at some point it grows boolean
 expressions in version statements like "version(BSD | Linux)", but I can
 live without those :)

version (BSD) { version = FEATURE1; version = FEATURE2; } version (linux) { version = FEATURE1; } ... version (FEATURE1) ...
May 11 2006
prev sibling parent reply Walter Bright <newshound digitalmars.com> writes:
Anders F Björklund wrote:
 I'm still naively hoping for both of "version (Unix)"

DMD supports Windows and Linux; Unix is neither. For a compiler which targets the Unix operating system, it should set the Unix version.
 and "version (!Windows)" to be defined and legal in D.

In C and C++, I often see: #if !WIN32 when what is really meant is: #if linux i.e. the former is almost always a bug waiting to happen (when someone tries to compile for a third operating system). Versions should be "this build is for this configuration" rather than "this build is not for that configuration." One can also write: version (ThisFeature) { } else { version = ThatFeature; } ... version (ThatFeature) ... For an example of why D is this way, see the sources to the Hans Boehm garbage collector, where the complex thicket of #if's makes it extremely difficult to see exactly what is being compiled.
May 11 2006
next sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Walter Bright wrote:

 I'm still naively hoping for both of "version (Unix)"

DMD supports Windows and Linux; Unix is neither. For a compiler which targets the Unix operating system, it should set the Unix version.

It does... I was just hoping to be able to use the same code for both ? GDC has chosen "Unix" as the name for all of them, while Ares uses "Posix". The naming doesn't matter as much, as long as it is defined. Which one is better is just splitting hairs, and not so important to me. For instance, Linux is a kernel - more than it is an operating system ? But I take it that we need to continue to have at least three codepaths.
 i.e. the former is almost always a bug waiting to happen (when someone 
 tries to compile for a third operating system). Versions should be "this 
 build is for this configuration" rather than "this build is not for that 
 configuration."

Thanks for the clarification on the official position on the matter. I think it is unfortunate, but there are ways to use what we have... --anders
May 11 2006
next sibling parent reply Sean Kelly <sean f4.ca> writes:
Anders F Björklund wrote:
 Walter Bright wrote:
 
 I'm still naively hoping for both of "version (Unix)"

DMD supports Windows and Linux; Unix is neither. For a compiler which targets the Unix operating system, it should set the Unix version.

It does... I was just hoping to be able to use the same code for both ? GDC has chosen "Unix" as the name for all of them, while Ares uses "Posix". The naming doesn't matter as much, as long as it is defined.

For what it's worth, I chose "Posix" because it refers to the API rather than to a subset of systems that support that API. But I agree that both are sufficiently general that they could be considered equivalent.
 Which one is better is just splitting hairs, and not so important to me.
 For instance, Linux is a kernel - more than it is an operating system ?

I think technically, the "Unix" moniker refers to the two derivatives of the code originally developed at Bell Labs: BSD Unix, and AT&T Unix. The other versions are Posix compliant, but not actually "Unix." Sean
May 11 2006
next sibling parent Walter Bright <newshound digitalmars.com> writes:
Sean Kelly wrote:
 I think technically, the "Unix" moniker refers to the two derivatives of 
 the code originally developed at Bell Labs: BSD Unix, and AT&T Unix. The 
 other versions are Posix compliant, but not actually "Unix."

That is one of my problems with "Unix" - nobody knows what it means. Such confusion will inevitably creep into code which multiple people will be maintaining. Posix makes more sense, because it is a defined standard.
May 11 2006
prev sibling parent reply Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Sean Kelly wrote:
 Anders F Björklund wrote:
 Walter Bright wrote:

 I'm still naively hoping for both of "version (Unix)"

DMD supports Windows and Linux; Unix is neither. For a compiler which targets the Unix operating system, it should set the Unix version.

It does... I was just hoping to be able to use the same code for both ? GDC has chosen "Unix" as the name for all of them, while Ares uses "Posix". The naming doesn't matter as much, as long as it is defined.

For what it's worth, I chose "Posix" because it refers to the API rather than to a subset of systems that support that API. But I agree that both are sufficiently general that they could be considered equivalent.

Are they (equivalent)? How about Cygwin which "is a DLL implementing most of the POSIX API on top of Windows". Does it count as Unix? How can this fit into D's (current or alternative) versioning scheme of things? -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
May 12 2006
next sibling parent reply Sean Kelly <sean f4.ca> writes:
Bruno Medeiros wrote:
 Sean Kelly wrote:
 Anders F Björklund wrote:
 Walter Bright wrote:

 I'm still naively hoping for both of "version (Unix)"

DMD supports Windows and Linux; Unix is neither. For a compiler which targets the Unix operating system, it should set the Unix version.

It does... I was just hoping to be able to use the same code for both ? GDC has chosen "Unix" as the name for all of them, while Ares uses "Posix". The naming doesn't matter as much, as long as it is defined.

For what it's worth, I chose "Posix" because it refers to the API rather than to a subset of systems that support that API. But I agree that both are sufficiently general that they could be considered equivalent.

Are they (equivalent)? How about Cygwin which "is a DLL implementing most of the POSIX API on top of Windows". Does it count as Unix? How can this fit into D's (current or alternative) versioning scheme of things?

I suppose that depends what "Unix" means to you. Windows also has a Posix subsystem, Interix, which should definately classify as Unix. So you could theoretically have Windows, Win32, Unix, and Interix all defined for a Windows platform. Personally, I find Posix to be more meaningful here, but it's splitting hairs. Sean
May 12 2006
parent Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
Sean Kelly wrote:
 Bruno Medeiros wrote:
 Sean Kelly wrote:
 Anders F Björklund wrote:
 Walter Bright wrote:

 I'm still naively hoping for both of "version (Unix)"

DMD supports Windows and Linux; Unix is neither. For a compiler which targets the Unix operating system, it should set the Unix version.

It does... I was just hoping to be able to use the same code for both ? GDC has chosen "Unix" as the name for all of them, while Ares uses "Posix". The naming doesn't matter as much, as long as it is defined.

For what it's worth, I chose "Posix" because it refers to the API rather than to a subset of systems that support that API. But I agree that both are sufficiently general that they could be considered equivalent.

Are they (equivalent)? How about Cygwin which "is a DLL implementing most of the POSIX API on top of Windows". Does it count as Unix? How can this fit into D's (current or alternative) versioning scheme of things?

I suppose that depends what "Unix" means to you.

I don't know exactly what it means. My knowledge of what exactly is "Posix" is also very dim. I just wanted to mention this detail, I'll leave the thinking on this subject to you[plural you]. -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
May 12 2006
prev sibling parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Bruno Medeiros wrote:

 For what it's worth, I chose "Posix" because it refers to the API 
 rather than to a subset of systems that support that API.  But I agree 
 that both are sufficiently general that they could be considered 
 equivalent.

Are they (equivalent)? How about Cygwin which "is a DLL implementing most of the POSIX API on top of Windows". Does it count as Unix? How can this fit into D's (current or alternative) versioning scheme of things?

For GDC, Cygwin is being auto-generated just like the other "Unix" ones. i.e. Unix = Linux | Darwin/Mac OS X | FreeBSD | Cygwin/MinGW | AIX | ... But as far as I know Cygwin is a Linux API emulation, and thus not Unix. It's just bundled under that version(Unix) in GDC, along with the other. --anders
May 12 2006
prev sibling parent reply Walter Bright <newshound digitalmars.com> writes:
Anders F Björklund wrote:
 Walter Bright wrote:
 
 I'm still naively hoping for both of "version (Unix)"

DMD supports Windows and Linux; Unix is neither. For a compiler which targets the Unix operating system, it should set the Unix version.

It does... I was just hoping to be able to use the same code for both ?

I know it seems like the right thing to do to use the same code for both operating systems. I'm going to argue that this is a case where copy/paste might be better. Operating systems change all the time, but developers rarely test on all supported systems. So if there's common OS code, chances are good that improving support for, say, linux, will break existing support for, say, bsdunix. If the two are in separate source trees, the linux expert can keep the linux stuff maintained without worrying about breaking bsdunix, about which he may know nothing. For example, look at the os support in the Hans Boehm gc. It's such a convoluted mess of #ifdef's, I don't see how anyone can modify it for one OS without trashing the other OS support. I'm also sure it didn't start out that way, it just evolved that way by accretion.
May 11 2006
next sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Walter Bright wrote:

 It does... I was just hoping to be able to use the same code for both ?

I know it seems like the right thing to do to use the same code for both operating systems. I'm going to argue that this is a case where copy/paste might be better. Operating systems change all the time, but developers rarely test on all supported systems.

I should mention here that std.c.unix.unix is being *autogenerated*... module std.c.unix.unix; /* This module imports the unix module for the currect target system. Currently, all targets can be handled with the autoconf'd version. */ import gcc.configunix; That is, all the values for the different constants and such are being provided by GNU Autotools, for the current operating system / platform. There is one such for each target, in my case "powerpc-apple-darwin7", just as there is one compiler for each target (for cross-compilation)
 So if there's common OS 
 code, chances are good that improving support for, say, linux, will 
 break existing support for, say, bsdunix. If the two are in separate 
 source trees, the linux expert can keep the linux stuff maintained 
 without worrying about breaking bsdunix, about which he may know nothing.

Oh, version(linux) is NOT going away. If it is needed, you can still write special code for specific operating systems. But for 90% of the time, the same code can be used for all these "Unix-like" systems... But if I understand you correctly, it is *better* to do an "assert(0);" on those other systems than to try the generic code and hope it works ? I must say I prefer autotools then, even if they have their wrinkles. If have to patch it manually anyway, "darwin" or "Unix" doesn't matter. --anders PS. See "autobook" for autotools info http://sourceware.org/autobook/
May 11 2006
parent reply Walter Bright <newshound digitalmars.com> writes:
Anders F Björklund wrote:

 But if I understand you correctly, it is *better* to do an "assert(0);"
 on those other systems than to try the generic code and hope it works ?
 I must say I prefer autotools then, even if they have their wrinkles.

Shipping production code for an OS that has never been even tried on that OS is not a good idea. In that case, having an assert in it *is* better because it's a red flag for the maintainer of that OS that he's got some work to do folding in new capability, and most importantly testing it. I know from long and bitter experience that if you ship code that isn't tested, it's *guaranteed* to not work.
May 11 2006
parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Walter Bright wrote:

 Shipping production code for an OS that has never been even tried on 
 that OS is not a good idea. In that case, having an assert in it *is* 
 better because it's a red flag for the maintainer of that OS that he's 
 got some work to do folding in new capability, and most importantly 
 testing it.

Hmm, that sounds like a lot of work... So, basically, if I want portable code I should stick to C and Java ? (C with autotools for feature detection, that is. For GNU platforms) --anders
May 12 2006
prev sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Walter Bright wrote:

 DMD supports Windows and Linux; Unix is neither. For a compiler which 
 targets the Unix operating system, it should set the Unix version.

It does... I was just hoping to be able to use the same code for both ?

I know it seems like the right thing to do to use the same code for both operating systems. I'm going to argue that this is a case where copy/paste might be better.

I began copying/pasting, then. It's going to be three active versions: * version (Windows) // for all * version (linux) // for DMD * version (Unix) // for GDC version(Unix) should probably come before version(linux), since older GDC versions came with a non-existent or incomplete std.c.linux.linux. version (Windows) { private import std.c.windows.windows; } else version (Unix) { private import std.c.unix.unix; } else version (linux) { private import std.c.linux.linux; } else static assert(0); It will end up in a LOT of duplicated code, though. Previously it was being shared with the Unix version by using alias and setting version: else version (Unix) { private import std.c.unix.unix; alias std.c.unix.unix unix; } else version (linux) { version = Unix; private import std.c.linux.linux; alias std.c.linux.linux unix; } That way both DMD and GDC could share the "Unix" section of the code ? (I'm not going to use "darwin" here, that'll be way too many versions) --anders
May 12 2006
parent reply "Derek Parnell" <derek psych.ward> writes:
On Sat, 13 May 2006 09:11:36 +1000, Anders F Björklund <afb algonet.se>  
wrote:

 Walter Bright wrote:

 DMD supports Windows and Linux; Unix is neither. For a compiler which  
 targets the Unix operating system, it should set the Unix version.

It does... I was just hoping to be able to use the same code for both ?

both operating systems. I'm going to argue that this is a case where copy/paste might be better.

I began copying/pasting, then. It's going to be three active versions: * version (Windows) // for all * version (linux) // for DMD * version (Unix) // for GDC

This is one of the reasons why Build will have text-processing functionality in it...to automate the copy/paste mechanism in such cases. -- Derek Parnell Melbourne, Australia
May 10 2006
parent =?UTF-8?B?QW5kZXJzIEYgQmrDtnJrbHVuZA==?= <afb algonet.se> writes:
Derek Parnell wrote:

 I began copying/pasting, then. It's going to be three active versions:

 * version (Windows) // for all
 * version (linux)   // for DMD
 * version (Unix)    // for GDC

This is one of the reasons why Build will have text-processing functionality in it...to automate the copy/paste mechanism in such cases.

But then I could just as well use "alias", in this particular case ? The only reason that it is done manually in the first place - and not automated, is that Walter declared he preferred the copy and paste... --anders
May 12 2006
prev sibling next sibling parent reply Sean Kelly <sean f4.ca> writes:
Walter Bright wrote:
 Anders F Björklund wrote:
 I'm still naively hoping for both of "version (Unix)"

DMD supports Windows and Linux; Unix is neither. For a compiler which targets the Unix operating system, it should set the Unix version.

For what it's worth, I think it would be useful for the 'Posix' version to be added, so any system supporting POSIX would have version 'Posix' automatically specified in addition to any OS version identifier. This would be similar to how Windows platforms also have either 'Win32' or 'Win64' defined. While a good bit of POSIX declarations are indeed implementation dependent, an equally large amount are not, and I believe it would be useful for a version identifier to reflect this.
 and "version (!Windows)" to be defined and legal in D.

In C and C++, I often see: #if !WIN32 when what is really meant is: #if linux i.e. the former is almost always a bug waiting to happen (when someone tries to compile for a third operating system). Versions should be "this build is for this configuration" rather than "this build is not for that configuration."

As much as I like the version idea, I'm beginning to feel that the C/C++ #ifdef method may actually be preferable in some situations. For example, some portions of Posix are common and others are not, so I am faced with a few options: - Define a separate set of Posix headers for each OS and have the user import the proper set manually. - Define a separate set of Posix headers for each OS and do some fancy versioning in a common area to publicly import the proper set automatically. - Define a common set of modules, each of which contains version blocks for each OS and may potentially result in multiple declarations of the same symbol occuring in the file (this is what I'm doing now for the Ares Posix headers as it's the most readable, but I think it may become difficult to deal with when support for more OSes is added) - Define a common set of modules with centralized logic for determining various things and use 'static if' in place of 'version' in a manner similar to #ifdef in C/C++ - Define a common set of modules but specify version identifiers in the makefile or via other means and move the complicated logic out of code and into a configure script or something similar While preprocessor logic has proven to be an aboslute nightmare in terms of readability and maintainability in some cases, I truly believe that this is more attributable to a lack of programmer skill than anything else. And while I love that D encourages 'good' style in many cases, I'm still undecided whether the current version scheme will prove to be sufficiently robust for large cross-platform projects. Currently, I think the last option may be the best compromise (and would require no change to the language spec), but I'm still not certain whether it will prove more readable to do version checking outside of code as opposed to inside.
 One can also write:
     version (ThisFeature)
     {
     }
     else
     {
         version = ThatFeature;
     }
 
 ...
 
     version (ThatFeature)
     ...
 
 For an example of why D is this way, see the sources to the Hans Boehm 
 garbage collector, where the complex thicket of #if's makes it extremely 
 difficult to see exactly what is being compiled.

Yup, but doing this in every module isn't particularly desirable if such settings may be common for an entire package. I'll admit I'm not entirely sure what the best approach is in this case. I mentioned the options above mostly in hopes that doing so would help me think through the ideas a bit. Sean
May 11 2006
next sibling parent =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Sean Kelly wrote:

 For what it's worth, I think it would be useful for the 'Posix' version 
 to be added, so any system supporting POSIX would have version 'Posix' 
 automatically specified in addition to any OS version identifier.  This 
 would be similar to how Windows platforms also have either 'Win32' or 
 'Win64' defined.  While a good bit of POSIX declarations are indeed 
 implementation dependent, an equally large amount are not, and I believe 
 it would be useful for a version identifier to reflect this.

GDC already uses (as in: actively, currently, in use) "Unix" for this: Windows - Win32 - Win64 Unix - linux - darwin - freebsd - cygwin - solaris Most if not all code currently including "std.c.linux.linux" with DMD, can be compiled by using the portable "std.c.unix.unix" in GDC instead. I was just hoping to avoid a fair amount of the needed copy and paste... --anders PS. See also http://www.digitalmars.com/d/archives/D/gnu/1208.html "I'm not planning on changing Unix to Posix." -- David Friedman
May 11 2006
prev sibling parent reply Walter Bright <newshound digitalmars.com> writes:
Sean Kelly wrote:
 For what it's worth, I think it would be useful for the 'Posix' version 
 to be added, so any system supporting POSIX would have version 'Posix' 
 automatically specified in addition to any OS version identifier.  This 
 would be similar to how Windows platforms also have either 'Win32' or 
 'Win64' defined.  While a good bit of POSIX declarations are indeed 
 implementation dependent, an equally large amount are not, and I believe 
 it would be useful for a version identifier to reflect this.

Having large parts of Posix be implementation dependent kinda shoots the whole idea of a standard in the foot.
 As much as I like the version idea, I'm beginning to feel that the C/C++ 
 #ifdef method may actually be preferable in some situations.  For 
 example, some portions of Posix are common and others are not, so I am 
 faced with a few options:
 
 - Define a separate set of Posix headers for each OS and have the user 
 import the proper set manually.
 
 - Define a separate set of Posix headers for each OS and do some fancy 
 versioning in a common area to publicly import the proper set 
 automatically.
 
 - Define a common set of modules, each of which contains version blocks 
 for each OS and may potentially result in multiple declarations of the 
 same symbol occuring in the file (this is what I'm doing now for the 
 Ares Posix headers as it's  the most readable, but I think it may become 
 difficult to deal with when support for more OSes is added)
 
 - Define a common set of modules with centralized logic for determining 
 various things and use 'static if' in place of 'version' in a manner 
 similar to #ifdef in C/C++
 
 - Define a common set of modules but specify version identifiers in the 
 makefile or via other means and move the complicated logic out of code 
 and into a configure script or something similar

I suggest another possibility: - Define a set of modules for each operating system, each in its own package - Define an "os configuration module" that is edited by the user to import the correct os modules I.e.: windows.foo.bar; linux.foo.bar; bsdunix.foo.bar; and: foo.bar the contents of foo.bar.d are: import windows.foo.bar; //import linux.foo.bar; //import bsdunix.foo.bar; No version statements needed.
 While preprocessor logic has proven to be an aboslute nightmare in terms 
 of readability and maintainability in some cases, I truly believe that 
 this is more attributable to a lack of programmer skill than anything 
 else.

Over time, I've been rewriting my use of #ifdef's in C++ to use the D style, and the results are worth it.
 Yup, but doing this in every module isn't particularly desirable if such 
 settings may be common for an entire package.

True, but the way to do that is to create an import such as foo.bar above that imports or aliases the correct configuration. I think these will work out better than the usual C technique of having gobs of command line #defines. Just today, I have been having a miserable time attempting to compile the Boost test suite, and am being stymied trying to figure out which wretched set of #define's have to go on the command line just to get the freakin' default to work. <flame on> C++ was supposed to reduce the use of the preprocessor. Boost is peer-reviewed and written by the best and the brightest C++ developers. So why does even the simplest Boost code *heavily* rely on complex, obtuse, layer after layer of preprocessor macros? <flame off>
 I'll admit I'm not 
 entirely sure what the best approach is in this case.  I mentioned the 
 options above mostly in hopes that doing so would help me think through 
 the ideas a bit.

I agree that this has to be thought through very carefully.
May 11 2006
next sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Brad Roberts wrote:

Having large parts of Posix be implementation dependent kinda shoots the whole
idea of a standard in the foot.

I feel the need to cry foul here, a little. Which parts are implementation defined? How widely used are those parts? In my experience, the vast majority of the parts that are used with any major frequency are identical between the various posix compliant operating systems.

And say 10% varies and 90% is the same as the standard, isn't it better then to "reuse" those parts that are the same and only conditionalize the parts that actually differ ? Instead of copy/paste the whole thing ? Even if it's 50-50, we're still talking 5 platforms (and it's growing!) --anders
May 11 2006
parent reply Sean Kelly <sean f4.ca> writes:
Anders F Björklund wrote:
 Brad Roberts wrote:
 
 Having large parts of Posix be implementation dependent kinda shoots 
 the whole
 idea of a standard in the foot.

I feel the need to cry foul here, a little. Which parts are implementation defined? How widely used are those parts? In my experience, the vast majority of the parts that are used with any major frequency are identical between the various posix compliant operating systems.

And say 10% varies and 90% is the same as the standard, isn't it better then to "reuse" those parts that are the same and only conditionalize the parts that actually differ ? Instead of copy/paste the whole thing ?

This is what I've been doing in Ares, though it remains to be seen whether this is the correct approach or not. I've been sticking to the 'required' bits and any additional features needed for D and so far probably 50% of it is platform-specific. I know you've seen the Ares Posix headers, but for anyone that hasn't, they are accessible here: http://svn.dsource.org/projects/ares/trunk/src/ares/std/c/posix/ Note that I precede each section of declarations with a comment block listing whatever the spec says should be defined for that segment, so the files are probably twice as long as they should be. The comments also aren't terribly easy to spot in a browser, but they show up quite nicely in a code editor :-) By the way, please note that only the "Required" and "C Extension" segments are actually necessary. The others are all optional for one reason or another. Sean
May 11 2006
parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Sean Kelly wrote:

 And say 10% varies and 90% is the same as the standard, isn't it better
 then to "reuse" those parts that are the same and only conditionalize
 the parts that actually differ ? Instead of copy/paste the whole thing ?

This is what I've been doing in Ares, though it remains to be seen whether this is the correct approach or not. I've been sticking to the 'required' bits and any additional features needed for D and so far probably 50% of it is platform-specific.

Does Ares use any auto-detection or auto-generation for the headers ? (like GPhobos does) --anders
May 11 2006
parent Sean Kelly <sean f4.ca> writes:
Anders F Björklund wrote:
 Sean Kelly wrote:
 
 And say 10% varies and 90% is the same as the standard, isn't it better
 then to "reuse" those parts that are the same and only conditionalize
 the parts that actually differ ? Instead of copy/paste the whole thing ?

This is what I've been doing in Ares, though it remains to be seen whether this is the correct approach or not. I've been sticking to the 'required' bits and any additional features needed for D and so far probably 50% of it is platform-specific.

Does Ares use any auto-detection or auto-generation for the headers ?

Nope. I've done everything manually so far (though Kashia submitted the darwin bits). This is obviously a mainenance concern for long-term support, but if it comes to that I'll approach it as I've done for DMD updates: diff the new Linux include directory against the old one and determine what needs fixing. Automated processing would be nice, but I haven't explored that option yet. I'll also admit to being somewhat of a novice with things like 'configure' so it didn't occur to me to use them. Sean
May 11 2006
prev sibling next sibling parent reply pragma <pragma_member pathlink.com> writes:
In article <e404lr$29ri$1 digitaldaemon.com>, Walter Bright says...
Sean Kelly wrote:
 While preprocessor logic has proven to be an aboslute nightmare in terms 
 of readability and maintainability in some cases, I truly believe that 
 this is more attributable to a lack of programmer skill than anything 
 else.

Over time, I've been rewriting my use of #ifdef's in C++ to use the D style, and the results are worth it.

Walter, I mean no disrespect here, but I simply must ask: Are you talking about a literal interpretation of version() and debug(), including the lack of an #ifndef equivalent? Like this: #ifdef FOOBAR #else /*** code ***/ #endif Or like this (using ifndef): #ifndef FOOBAR /*** code ***/ #endif I don't think that version() and debug() need to be tangled up with all kinds of boolean expressions, but maybe a short-and-sweet concession to allow an equivalent to #ifndef is in order? Sure its just "one line more readable" but it *is* more readable after all. - EricAnderton at yahoo
May 11 2006
parent reply Walter Bright <newshound digitalmars.com> writes:
pragma wrote:

 Walter, I mean no disrespect here, but I simply must ask: Are you talking about
 a literal interpretation of version() and debug(), including the lack of an
 #ifndef equivalent?  
 
 Like this:
 
 #ifdef FOOBAR
 #else
 /*** code ***/
 #endif
 
 Or like this (using ifndef):
 
 #ifndef FOOBAR
 /*** code ***/
 #endif
 
 I don't think that version() and debug() need to be tangled up with all kinds
of
 boolean expressions, but maybe a short-and-sweet concession to allow an
 equivalent to #ifndef is in order?  Sure its just "one line more readable" but
 it *is* more readable after all. 

Consider another perspective: when a version of the code is being built, one thinks about a version being build, not a "not version". If you find that you're writing: version (FOOBAR) else { ... } I suggest that perhaps FOOBAR is the wrong name for the version being compiled. For example, I would red flag code that looked like: version (Windows) else { ... } I also have a particular dislike for the execrable double negative style often seen in C: #ifndef NO_FOO ... #endif There is some psychobabble research on this, suggesting that people tend to skip nots, and even more often miss double negatives. I know that in airplane pilot jargon, considerable effort has been made to purge negations and replace them with positive statements, as they are less prone to misinterpretation. Some more examples: 1) Don't build a "NOTFULL" version, build a "DEMO" version. 2) Don't build a "NOTDEMO" version, build a "FULL" version. 3) Don't build a "NOHARDTABS" version, build a "SOFTTABS" version. etc. If there are some specifics cases you feel just don't fit with this, can you post them?
May 11 2006
next sibling parent reply James Pelcis <jpelcis gmail.com> writes:
If you are writing a program that will only work on Windows, it would be 
necessary to use this...

version (Windows)
else
{
     static assert (0);
}

Same with any other requirements.

I do agree with you about the double negative style though.

 etc. If there are some specifics cases you feel just don't fit with 
 this, can you post them?

May 11 2006
parent reply Walter Bright <newshound digitalmars.com> writes:
James Pelcis wrote:
 If you are writing a program that will only work on Windows, it would be 
 necessary to use this...
 
 version (Windows)
 else
 {
     static assert (0);
 }

Instead of: ... windows code ... version (Windows) else static assert(0); I suggest: version (Windows) ... windows code ... else static assert(0);
May 11 2006
parent reply Derek Parnell <derek psych.ward> writes:
On Thu, 11 May 2006 18:24:17 -0700, Walter Bright wrote:

 James Pelcis wrote:
 If you are writing a program that will only work on Windows, it would be 
 necessary to use this...
 
 version (Windows)
 else
 {
     static assert (0);
 }

Instead of: ... windows code ... version (Windows) else static assert(0); I suggest: version (Windows) ... windows code ... else static assert(0);

However, the important thing is to convey information to code maintainers. And the most direct and simplest way is to have this at the TOP of your source code ... version (Windows) else { pragma(msg, "Only compilable in Windows environment."); static assert(0); } ... windows code ... -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 12/05/2006 11:53:48 AM
May 11 2006
parent Walter Bright <newshound digitalmars.com> writes:
Derek Parnell wrote:
 On Thu, 11 May 2006 18:24:17 -0700, Walter Bright wrote:
 I suggest:

 	version (Windows)
 		... windows code ...
 	else
 		static assert(0);

However, the important thing is to convey information to code maintainers. And the most direct and simplest way is to have this at the TOP of your source code ... version (Windows) else { pragma(msg, "Only compilable in Windows environment."); static assert(0); } ... windows code ...

I suggest that if the entire module was windows only, put it under a windows package.
May 11 2006
prev sibling parent pragma <pragma_member pathlink.com> writes:
In article <e40ehq$2pgs$1 digitaldaemon.com>, Walter Bright says...
pragma wrote:

 Walter, I mean no disrespect here, but I simply must ask: Are you talking about
 a literal interpretation of version() and debug(), including the lack of an
 #ifndef equivalent?  
 
 Like this:
 
 #ifdef FOOBAR
 #else
 /*** code ***/
 #endif
 
 Or like this (using ifndef):
 
 #ifndef FOOBAR
 /*** code ***/
 #endif
 
 I don't think that version() and debug() need to be tangled up with all kinds
of
 boolean expressions, but maybe a short-and-sweet concession to allow an
 equivalent to #ifndef is in order?  Sure its just "one line more readable" but
 it *is* more readable after all. 

Consider another perspective: when a version of the code is being built, one thinks about a version being build, not a "not version". If you find that you're writing: version (FOOBAR) else { ... } I suggest that perhaps FOOBAR is the wrong name for the version being compiled. For example, I would red flag code that looked like: version (Windows) else { ... } I also have a particular dislike for the execrable double negative style often seen in C: #ifndef NO_FOO ... #endif There is some psychobabble research on this, suggesting that people tend to skip nots, and even more often miss double negatives. I know that in airplane pilot jargon, considerable effort has been made to purge negations and replace them with positive statements, as they are less prone to misinterpretation. Some more examples: 1) Don't build a "NOTFULL" version, build a "DEMO" version. 2) Don't build a "NOTDEMO" version, build a "FULL" version. 3) Don't build a "NOHARDTABS" version, build a "SOFTTABS" version. etc. If there are some specifics cases you feel just don't fit with this, can you post them?

Actually I don't have anything to cite that would be contrary to this - especially after your explaination, thank you. :) I never thought to look at versioning that way, and I'm glad that you took the time to explain it all out. Perhaps we've all been flipping bits back and forth too much to realize that "false" and "!true", while semantically the same thing, may lead to different uses and interpretations (and mis-interpretations). You've given me much to think about. - EricAnderton at yahoo
May 11 2006
prev sibling next sibling parent reply Sean Kelly <sean f4.ca> writes:
Walter Bright wrote:
 Sean Kelly wrote:
 For what it's worth, I think it would be useful for the 'Posix' 
 version to be added, so any system supporting POSIX would have version 
 'Posix' automatically specified in addition to any OS version 
 identifier.  This would be similar to how Windows platforms also have 
 either 'Win32' or 'Win64' defined.  While a good bit of POSIX 
 declarations are indeed implementation dependent, an equally large 
 amount are not, and I believe it would be useful for a version 
 identifier to reflect this.

Having large parts of Posix be implementation dependent kinda shoots the whole idea of a standard in the foot.

It's kind of silly, but I think the reason was to allow basically any system to be Posix compliant, so a good portion of Posix is broken into individually optional subsets of features, such as threading. For the required stuff, function declarations will obviously be consistent, but the contents and layout of structs and the value of constants is likely to change from OS to OS. For what it's worth, I've found it's far simpler to work completely from the spec for determining what should be defined and then looking for those definitions in the header files than to simply try and convert the headers en masse. This made implementing the C99 headers a breeze and is really the only workable option for Posix support.
 As much as I like the version idea, I'm beginning to feel that the 
 C/C++ #ifdef method may actually be preferable in some situations.  
 For example, some portions of Posix are common and others are not, so 
 I am faced with a few options:

 - Define a separate set of Posix headers for each OS and have the user 
 import the proper set manually.

 - Define a separate set of Posix headers for each OS and do some fancy 
 versioning in a common area to publicly import the proper set 
 automatically.

 - Define a common set of modules, each of which contains version 
 blocks for each OS and may potentially result in multiple declarations 
 of the same symbol occuring in the file (this is what I'm doing now 
 for the Ares Posix headers as it's  the most readable, but I think it 
 may become difficult to deal with when support for more OSes is added)

 - Define a common set of modules with centralized logic for 
 determining various things and use 'static if' in place of 'version' 
 in a manner similar to #ifdef in C/C++

 - Define a common set of modules but specify version identifiers in 
 the makefile or via other means and move the complicated logic out of 
 code and into a configure script or something similar

I suggest another possibility: - Define a set of modules for each operating system, each in its own package - Define an "os configuration module" that is edited by the user to import the correct os modules I.e.: windows.foo.bar; linux.foo.bar; bsdunix.foo.bar; and: foo.bar the contents of foo.bar.d are: import windows.foo.bar; //import linux.foo.bar; //import bsdunix.foo.bar; No version statements needed.

Hrm, so similar to option 2, but with the user manually choosing which set of headers to use. That works, I suppose.
 While preprocessor logic has proven to be an aboslute nightmare in 
 terms of readability and maintainability in some cases, I truly 
 believe that this is more attributable to a lack of programmer skill 
 than anything else.

Over time, I've been rewriting my use of #ifdef's in C++ to use the D style, and the results are worth it.

I'll trust you on this. I simply haven't had enough need for them yet to have formed a solid opinion.
 Yup, but doing this in every module isn't particularly desirable if 
 such settings may be common for an entire package.

True, but the way to do that is to create an import such as foo.bar above that imports or aliases the correct configuration. I think these will work out better than the usual C technique of having gobs of command line #defines. Just today, I have been having a miserable time attempting to compile the Boost test suite, and am being stymied trying to figure out which wretched set of #define's have to go on the command line just to get the freakin' default to work.

Boost is an absolute nightmare of preprocessor code and workarounds for compiler support. Between this and the complexity of implementation for some of the utilities, I'm not terribly inclined to use much of Boost in production applications. Regarding the import idea, I think it's a good one. I did recently have reason to need something akin to #ifdef in D (to have the value of an assignment contingent on whether a constant was defined--darned Posix), but I suspect this is a rare case. And I suppose an alternative would be to declare this constant on non-supporting platforms to a "safe" default value.
 <flame on>
 C++ was supposed to reduce the use of the preprocessor. Boost is 
 peer-reviewed and written by the best and the brightest C++ developers. 
 So why does even the simplest Boost code *heavily* rely on complex, 
 obtuse, layer after layer of preprocessor macros?
 <flame off>

It's interesting to see how Boost components have evolved over time. For example, the implementation of shared_ptr used to be extremely straightforward--it comprised maybe 100 lines of code with nary a macro to be seen. Now it's spread across multiple files, contains dense and complicated code, and has more features than I care to list. In some respects this reminds me of what I call the "Microsoft Word" syndrome. That being that everyone wants a very small subset of features in a product, but all of those people want *different* features. Another factor may be that while it's quite difficult to write an easily usable library, it's far more difficult to do so using simple, straightforward code or to maintain this simplicity across maintenance cycles. shared_ptr started out clean and compact, but it certainly didn't stay that way. Perhaps there's simply more pressure to get improvements done than to do so in a clearly readable manner, or perhaps it's an issue of too many fingers spoiling the soup? I suppose it also doesn't help that the best and brightest may occasionally lack perspective on what's understandable to the average person, or perhaps there's simply no perceived need for users to be able to make sense of the code. Sean
May 11 2006
parent Walter Bright <newshound digitalmars.com> writes:
Sean Kelly wrote:
 Walter Bright wrote:
 <flame on>
 C++ was supposed to reduce the use of the preprocessor. Boost is 
 peer-reviewed and written by the best and the brightest C++ 
 developers. So why does even the simplest Boost code *heavily* rely on 
 complex, obtuse, layer after layer of preprocessor macros?
 <flame off>

It's interesting to see how Boost components have evolved over time. For example, the implementation of shared_ptr used to be extremely straightforward--it comprised maybe 100 lines of code with nary a macro to be seen. Now it's spread across multiple files, contains dense and complicated code, and has more features than I care to list. In some respects this reminds me of what I call the "Microsoft Word" syndrome. That being that everyone wants a very small subset of features in a product, but all of those people want *different* features.

Frankly, I find boost to be unusable. If you're lucky, it works right out of the box. The slightest thing going wrong, however, and you're faced with an incomprehensible error message, #include's spread over several directories, the layers of macros, layers of templates, and no clue as to what is relevant and what is puffery.
 Another factor may be that while it's quite difficult to write an easily 
 usable library, it's far more difficult to do so using simple, 
 straightforward code or to maintain this simplicity across maintenance 
 cycles.  shared_ptr started out clean and compact, but it certainly 
 didn't stay that way.  Perhaps there's simply more pressure to get 
 improvements done than to do so in a clearly readable manner, or perhaps 
 it's an issue of too many fingers spoiling the soup?  I suppose it also 
 doesn't help that the best and brightest may occasionally lack 
 perspective on what's understandable to the average person, or perhaps 
 there's simply no perceived need for users to be able to make sense of 
 the code.

True genius is being able to find the underlying simplicity of something. Anyone can make something complicated. It takes a genius to make something so simple that everyone else says "of course, why didn't I think of that myself?" An airplane, for example, is a simple and obvious device. But it took a (pair) of geniuses to figure that out.
May 11 2006
prev sibling parent Sean Kelly <sean f4.ca> writes:
Brad Roberts wrote:
 On Thu, 11 May 2006, Walter Bright wrote:
 
 Sean Kelly wrote:
 For what it's worth, I think it would be useful for the 'Posix' version to
 be added, so any system supporting POSIX would have version 'Posix'
 automatically specified in addition to any OS version identifier.  This
 would be similar to how Windows platforms also have either 'Win32' or
 'Win64' defined.  While a good bit of POSIX declarations are indeed
 implementation dependent, an equally large amount are not, and I believe it
 would be useful for a version identifier to reflect this.

idea of a standard in the foot.

I feel the need to cry foul here, a little. Which parts are implementation defined? How widely used are those parts? In my experience, the vast majority of the parts that are used with any major frequency are identical between the various posix compliant operating systems.

For what it's worth, when I refer to Posix I mean the spec defined here: http://www.opengroup.org/onlinepubs/009695399/ From a user perspective, the parts are all identical and support for common features is quite broad. For example, threading support is optional, but you'd be hard pressed to find a Posix-compliant OS that didn't support it. Beyond this issue of optional components (which again isn't much of an issue in practice), the things you'd expect to be implementation-defined are: struct layout, const values, etc. None of this is visible to the user, but it's obviously an issue for someone porting Posix headers to D. Sean
May 11 2006
prev sibling next sibling parent reply "Ameer Armaly" <ameer_armaly hotmail.com> writes:
"Walter Bright" <newshound digitalmars.com> wrote in message 
news:e3vple$1rp5$1 digitaldaemon.com...
 Anders F Björklund wrote:
 I'm still naively hoping for both of "version (Unix)"

DMD supports Windows and Linux; Unix is neither. For a compiler which targets the Unix operating system, it should set the Unix version.
 and "version (!Windows)" to be defined and legal in D.

In C and C++, I often see: #if !WIN32 when what is really meant is: #if linux i.e. the former is almost always a bug waiting to happen (when someone tries to compile for a third operating system). Versions should be "this build is for this configuration" rather than "this build is not for that configuration." One can also write: version (ThisFeature) { } else { version = ThatFeature; } ... version (ThatFeature) ... For an example of why D is this way, see the sources to the Hans Boehm garbage collector, where the complex thicket of #if's makes it extremely difficult to see exactly what is being compiled.

where you want the default compiled behavior to execute a given block of code, but with a given version switch you want it taken out. Rather than wrapping your prefered behavior in a version block, or putting in an empty version block which raises all sorts of questions, you could just say "Unless a given version specifier is defined, do this."
May 11 2006
parent reply Walter Bright <newshound digitalmars.com> writes:
Ameer Armaly wrote:
 One situation I can see where this kind of functionality could be useful is 
 where you want the default compiled behavior to execute a given block of 
 code, but with a given version switch you want it taken out.  Rather than 
 wrapping your prefered behavior in a version block, or putting in an empty 
 version block which raises all sorts of questions, you could just say 
 "Unless a given version specifier is defined, do this." 

I understand that point of view, but I suggest instead thinking about the "default compiled behavior" as a "Feature", rather than a not "NotFeature". You can make it the default by putting: version = Feature; at the top of the module.
May 11 2006
parent reply "Ameer Armaly" <ameer_armaly hotmail.com> writes:
"Walter Bright" <newshound digitalmars.com> wrote in message 
news:e40g2t$2r6h$1 digitaldaemon.com...
 Ameer Armaly wrote:
 One situation I can see where this kind of functionality could be useful 
 is where you want the default compiled behavior to execute a given block 
 of code, but with a given version switch you want it taken out.  Rather 
 than wrapping your prefered behavior in a version block, or putting in an 
 empty version block which raises all sorts of questions, you could just 
 say "Unless a given version specifier is defined, do this."

I understand that point of view, but I suggest instead thinking about the "default compiled behavior" as a "Feature", rather than a not "NotFeature". You can make it the default by putting: version = Feature; at the top of the module.

modular project; I'm not saying it couldn't be done, only that it looks bloated. I agree with you that multiple bool operators might be pushing things a bit, but a simple not operator would IMO make things efficient enough to where the rest of that wouldn't matter as much.
May 11 2006
parent reply Walter Bright <newshound digitalmars.com> writes:
Ameer Armaly wrote:
 What if it were across multiple files, or some other particularly large but 
 modular project; I'm not saying it couldn't be done, only that it looks 
 bloated.  I agree with you that multiple bool operators might be pushing 
 things a bit, but a simple not operator would IMO make things efficient 
 enough to where the rest of that wouldn't matter as much. 

For multiple files, the idea is to abstract the feature out into its own module rather than embedding it.
May 11 2006
parent Tom <ihate spam.com> writes:
Walter Bright escribió:
 Ameer Armaly wrote:
 What if it were across multiple files, or some other particularly 
 large but modular project; I'm not saying it couldn't be done, only 
 that it looks bloated.  I agree with you that multiple bool operators 
 might be pushing things a bit, but a simple not operator would IMO 
 make things efficient enough to where the rest of that wouldn't matter 
 as much. 

For multiple files, the idea is to abstract the feature out into its own module rather than embedding it.

My 2 cents: it's not about being a good programming practice, it's about enough flexibility. I'm for the "version (!VERSION)". It'll not kill anyone though you can discourage the misuse of it. JMHO -- Tom;
May 11 2006
prev sibling parent BCS <BCS pathlink.com> writes:
Walter Bright wrote:
[...]
 In C and C++, I often see:
 
     #if !WIN32
 
 when what is really meant is:
 
     #if linux
 
 i.e. the former is almost always a bug waiting to happen (when someone 
 tries to compile for a third operating system). Versions should be "this 
 build is for this configuration" rather than "this build is not for that 
 configuration."
 

what about the case where feature A is incompatible with configuration B (example: this feature is usually part of the config but doesn't work under win32) but then again I'd do this instead version(WIN32) { pragma(msg,">"__FILE__":" ~ itoa!(__LINE__) ~ "Sorry this doesn't work with win32"); } else { // win32 incompatible code }
May 11 2006
prev sibling parent "Ameer Armaly" <ameer_armaly hotmail.com> writes:
"Daniel Keep" <daniel.keep.lists gmail.com> wrote in message 
news:e3ul8t$ag8$2 digitaldaemon.com...
 Anders F Björklund wrote:
 maxter wrote:

 i've noticed code like this:

 version (foo)
 {}
 else
 {
     do something...
 }

Usually written as: version (foo) {} else { .... }

Yeah, I've had to do that a few times myself; very annoying.
 would it be more natural to be able to write:

 version (!foo)
 {
     do something...
 }
 the same applies to the debug statement. thanks

Yes it would, and Thomas patched this in bug #2522 digitalmars.D.bugs/2522 But I don't think that they ever caught on with W. digitalmars.D/11946 digitalmars.D/11995 --anders

That's odd, given that D is more or less designed to avoid silly hacks like this...

inefficient and doesn't support code readability.
 -- Daniel

 -- 

 v1sw5+8Yhw5ln4+5pr6OFma8u6+7Lw4Tm6+7l6+7D
 a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP    http://hackerkey.com/ 

May 11 2006
prev sibling parent Brad Roberts <braddr puremagic.com> writes:
On Thu, 11 May 2006, Walter Bright wrote:

 Sean Kelly wrote:
 For what it's worth, I think it would be useful for the 'Posix' version to
 be added, so any system supporting POSIX would have version 'Posix'
 automatically specified in addition to any OS version identifier.  This
 would be similar to how Windows platforms also have either 'Win32' or
 'Win64' defined.  While a good bit of POSIX declarations are indeed
 implementation dependent, an equally large amount are not, and I believe it
 would be useful for a version identifier to reflect this.

Having large parts of Posix be implementation dependent kinda shoots the whole idea of a standard in the foot.

I feel the need to cry foul here, a little. Which parts are implementation defined? How widely used are those parts? In my experience, the vast majority of the parts that are used with any major frequency are identical between the various posix compliant operating systems. It's also worth pointing out, though I suspect you're already well aware but many others probably aren't, that Posix isn't _a_ standard. It's a collection of layered standards. Some good reading: http://en.wikipedia.org/wiki/POSIX http://www.unix.org/what_is_unix/single_unix_specification.html Later, Brad
May 11 2006