|
Archives
D Programming
D
D.gnu
digitalmars.D
digitalmars.D.bugs
digitalmars.D.dtl
digitalmars.D.dwt
digitalmars.D.announce
digitalmars.D.learn
digitalmars.D.debugger
C/C++ Programming
c++
c++.announce
c++.atl
c++.beta
c++.chat
c++.command-line
c++.dos
c++.dos.16-bits
c++.dos.32-bits
c++.idde
c++.mfc
c++.rtl
c++.stl
c++.stl.hp
c++.stl.port
c++.stl.sgi
c++.stlsoft
c++.windows
c++.windows.16-bits
c++.windows.32-bits
c++.wxwindows
digitalmars.empire
digitalmars.DMDScript
|
digitalmars.D - version and debug statements
↑ ↓ ← → 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
↑ ↓ ← → =?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
↑ ↓ ← → 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/
↑ ↓ ← → =?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
↑ ↓ ← → 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/
↑ ↓ ← → =?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
↑ ↓ ← → 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).
↑ ↓ ← → "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
↑ ↓ ← → 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
↑ ↓ ← → "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
↑ ↓ ← → 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
↑ ↓ ← → 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
↑ ↓ ← → "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
↑ ↓ ← → 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
↑ ↓ ← → "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
↑ ↓ ← → 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
↑ ↓ ← → "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
↑ ↓ ← → "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
↑ ↓ ← → "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
↑ ↓ ← → 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.
↑ ↓ ← → "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.
↑ ↓ ← → 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.
↑ ↓ ← → "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
↑ ↓ ← → "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
↑ ↓ ← → 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)
...
↑ ↓ ← → 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.
↑ ↓ ← → =?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
↑ ↓ ← → 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
↑ ↓ ← → 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.
↑ ↓ ← → 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
↑ ↓ ← → 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
↑ ↓ ← → 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
↑ ↓ ← → =?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
↑ ↓ ← → 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.
↑ ↓ ← → =?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/
↑ ↓ ← → 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.
↑ ↓ ← → =?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
↑ ↓ ← → =?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
↑ ↓ ← → "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
↑ ↓ ← → =?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
↑ ↓ ← → 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
↑ ↓ ← → =?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
↑ ↓ ← → 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.
↑ ↓ ← → =?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
↑ ↓ ← → 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
↑ ↓ ← → =?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
↑ ↓ ← → 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
↑ ↓ ← → 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
↑ ↓ ← → 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?
↑ ↓ ← → 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?
↑ ↓ ← → 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);
↑ ↓ ← → 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
↑ ↓ ← → 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.
↑ ↓ ← → 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
↑ ↓ ← → 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
↑ ↓ ← → 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.
↑ ↓ ← → 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
↑ ↓ ← → "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."
↑ ↓ ← → 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.
↑ ↓ ← → "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.
↑ ↓ ← → 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.
↑ ↓ ← → 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;
↑ ↓ ← → 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
}
↑ ↓ ← → "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/
↑ ↓ ← → 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
|
|