digitalmars.D - remove keywords
- mandel (14/14) Dec 07 2007 A proposal in a nutshell:
- Denton Cockburn (6/29) Dec 07 2007 seems like a rather big change.
- mandel (21/28) Dec 07 2007 Yes, it would be a big change.
- Janice Caron (3/4) Dec 07 2007 presumably you mean
- mandel (2/8) Dec 07 2007 right. :)
- Walter Bright (14/30) Dec 07 2007 The version statement is limited in that you cannot do !foo or
- mandel (5/21) Dec 07 2007 I'am aware of that problem and understand the design decision.
- Jarrett Billingsley (20/33) Dec 07 2007 You tell me which is more readable:
- Sean Kelly (3/44) Dec 07 2007 There's always static if.
- Steven Schveighoffer (10/24) Dec 07 2007 First one is more readable.
- Walter Bright (10/31) Dec 07 2007 I'm going to say the latter is more readable, especially when under each...
- Christopher Wright (24/65) Dec 07 2007 I've dealt with production code -- a mere 5k line project -- that was
- Michel Fortin (58/62) Dec 07 2007 I've come into a situation where I'll probably have to take the bloat
- Lutger (9/25) Dec 07 2007 There are two things I like in the current system that will be lost with...
- Walter Bright (16/20) Dec 07 2007 You're quite right in your assessment of the debug conditional. It stems...
- bearophile (4/6) Dec 07 2007 Some built-in restraints can be *really* useful to avoid bugs.
- Christopher Wright (3/6) Dec 07 2007 Maybe. And it would be EXTREMELY hairy to read.
- Robby (13/36) Dec 07 2007 Please please don't. From my standpoint, and converting over 70k lines
- Robby (2/43) Dec 07 2007 is null*, thinking one thing, writing another. sigh
A proposal in a nutshell: - removal of the keywords "unittest, "version" and similar. - replaced by global compile time variables. - "dmd -<name>=<value>" to set them. Variables not found result in compiler warnings - "dmd -list version*" or similar to list all global variable names with prefix "version" -> less keywords, more powerfull control (use in boolean expressions), more native syntax, easier to understand Ideas? Problems? Objections? btw.: bool enableXYZ; if(enableXFZ) import foo.Bar; ..might be hairy to implement?
Dec 07 2007
On Fri, 07 Dec 2007 08:55:45 +0000, mandel wrote:A proposal in a nutshell: - removal of the keywords "unittest, "version" and similar. - replaced by global compile time variables. - "dmd -<name>=<value>" to set them. Variables not found result in compiler warnings - "dmd -list version*" or similar to list all global variable names with prefix "version" -> less keywords, more powerfull control (use in boolean expressions), more native syntax, easier to understand Ideas? Problems? Objections? btw.: bool enableXYZ; if(enableXFZ) import foo.Bar; ..might be hairy to implement?seems like a rather big change. Do you really have a big problem with the current method? or you just think this is better? I'd rather forgo a big change if the current method isn't painful (it's not).
Dec 07 2007
Yes, it would be a big change. But the code changes would be trivial imho. I just think it's better (consinstent) to do it this way for the mentioned reasons. For example, one of the motivations was: if(bar) { version(Foo) { /**/ } } I would rather like to write: if(bar && Foo) { /**/ } There are workarounds, but none of them is as nice as the native/proposed solution above. On Fri, 07 Dec 2007 09:16:02 +0000, Denton Cockburn wrote:On Fri, 07 Dec 2007 08:55:45 +0000, mandel wrote:[..]seems like a rather big change. Do you really have a big problem with the current method? or you just think this is better? I'd rather forgo a big change if the current method isn't painful (it's not).
Dec 07 2007
On Dec 7, 2007 9:45 AM, mandel <oh no.es> wrote:if(bar && Foo)presumably you mean static if (bar && foo)
Dec 07 2007
On Fri, 07 Dec 2007 10:40:01 +0000, Janice Caron wrote:On Dec 7, 2007 9:45 AM, mandel <oh no.es> wrote:right. :)if(bar && Foo)presumably you mean static if (bar && foo)
Dec 07 2007
mandel wrote:For example, one of the motivations was: if(bar) { version(Foo) { /**/ } } I would rather like to write: if(bar && Foo) { /**/ }The version statement is limited in that you cannot do !foo or foo&&bar||baz. Rather than a bug, that is deliberate. I've seen a lot of code that, over the years, accumulated detritus like: #if FOO || BAR>0x1234 && BAZ && !HACK These tend to snarl themselves into such a rat's nest of conditionals the only way to figure out which lines actually got compiled was to examine the preprocessor output. (Another consequence of these is that, inevitably, the various conditionals were WRONG as they were layered on by people who didn't really understand the code.) So, by limiting the version statement, the idea is to encourage the programmer to think in terms of distinct versions being generated, and then code in terms of those distinct versions - each of those versions having a name.
Dec 07 2007
On Fri, 07 Dec 2007 02:47:36 -0800, Walter Bright wrote:The version statement is limited in that you cannot do !foo or foo&&bar||baz. Rather than a bug, that is deliberate. I've seen a lot of code that, over the years, accumulated detritus like: #if FOO || BAR>0x1234 && BAZ && !HACK These tend to snarl themselves into such a rat's nest of conditionals the only way to figure out which lines actually got compiled was to examine the preprocessor output. (Another consequence of these is that, inevitably, the various conditionals were WRONG as they were layered on by people who didn't really understand the code.) So, by limiting the version statement, the idea is to encourage the programmer to think in terms of distinct versions being generated, and then code in terms of those distinct versions - each of those versions having a name.I'am aware of that problem and understand the design decision. Still, I can't get rid of the desire to give more power to the programmer by simplifying stuff. :> But I can code with the way it is.
Dec 07 2007
"Walter Bright" <newshound1 digitalmars.com> wrote in message news:fjb8c6$2nqs$1 digitalmars.com...The version statement is limited in that you cannot do !foo or foo&&bar||baz. Rather than a bug, that is deliberate. I've seen a lot of code that, over the years, accumulated detritus like: #if FOO || BAR>0x1234 && BAZ && !HACK These tend to snarl themselves into such a rat's nest of conditionals the only way to figure out which lines actually got compiled was to examine the preprocessor output. (Another consequence of these is that, inevitably, the various conditionals were WRONG as they were layered on by people who didn't really understand the code.) So, by limiting the version statement, the idea is to encourage the programmer to think in terms of distinct versions being generated, and then code in terms of those distinct versions - each of those versions having a name.You tell me which is more readable: version(linux || darwin || bsd) version = UseDlfcn; else version = UseDLLs; vs. version(linux) version = UseDlfcn; else version(darwin) version = UseDlfcn; else version(bsd) version = UseDlfcn; else version = UseDLLs; It only gets worse when you actually *need* complex versioning, and when the contents of those version blocks become more than trivial. Yes, you can define intermediate versions like I've done here, but even that becomes tedious and hard to read.
Dec 07 2007
Jarrett Billingsley wrote:"Walter Bright" <newshound1 digitalmars.com> wrote in message news:fjb8c6$2nqs$1 digitalmars.com...There's always static if. SeanThe version statement is limited in that you cannot do !foo or foo&&bar||baz. Rather than a bug, that is deliberate. I've seen a lot of code that, over the years, accumulated detritus like: #if FOO || BAR>0x1234 && BAZ && !HACK These tend to snarl themselves into such a rat's nest of conditionals the only way to figure out which lines actually got compiled was to examine the preprocessor output. (Another consequence of these is that, inevitably, the various conditionals were WRONG as they were layered on by people who didn't really understand the code.) So, by limiting the version statement, the idea is to encourage the programmer to think in terms of distinct versions being generated, and then code in terms of those distinct versions - each of those versions having a name.You tell me which is more readable: version(linux || darwin || bsd) version = UseDlfcn; else version = UseDLLs; vs. version(linux) version = UseDlfcn; else version(darwin) version = UseDlfcn; else version(bsd) version = UseDlfcn; else version = UseDLLs; It only gets worse when you actually *need* complex versioning, and when the contents of those version blocks become more than trivial. Yes, you can define intermediate versions like I've done here, but even that becomes tedious and hard to read.
Dec 07 2007
"Jarrett Billingsley" wroteYou tell me which is more readable: version(linux || darwin || bsd) version = UseDlfcn; else version = UseDLLs; vs. version(linux) version = UseDlfcn; else version(darwin) version = UseDlfcn; else version(bsd) version = UseDlfcn; else version = UseDLLs;First one is more readable. I think maybe the version syntax could be expanded to mean 'or' with commas. i.e. version(linux, darwin, bsd) And forget any other logic syntax (ands, less than, etc). I believe the current method does a good job of preventing convoluted version statements, but I think the 'or' is a very common requirement, and does not detract from the readability. -Steve
Dec 07 2007
Jarrett Billingsley wrote:You tell me which is more readable: version(linux || darwin || bsd) version = UseDlfcn; else version = UseDLLs; vs. version(linux) version = UseDlfcn; else version(darwin) version = UseDlfcn; else version(bsd) version = UseDlfcn; else version = UseDLLs;I'm going to say the latter is more readable, especially when under each os there are a series of version declarations. The former approach is used by, for example, the Hans Boehm garbage collector, and I have found it very difficult to follow.It only gets worse when you actually *need* complex versioning, and when the contents of those version blocks become more than trivial. Yes, you can define intermediate versions like I've done here, but even that becomes tedious and hard to read.When the versioning becomes complex, there are alternative ways of managing it. One way that works well is to factor out version differences into version specific modules, with a general purpose api to those modules. Yes, this is more work, but when I've done it the results have been well worthwhile.
Dec 07 2007
Jarrett Billingsley wrote:"Walter Bright" <newshound1 digitalmars.com> wrote in message news:fjb8c6$2nqs$1 digitalmars.com...I've dealt with production code -- a mere 5k line project -- that was ported manually to four operating systems (Linux, HPUX, Darwin, and I think FreeBSD). My task was to convert it to use autotools. Ugly. Horrible. Terrible. I wanted to find the coders and shoot them. You're recommending an autoconf-like system, basically. Which I commend. But then you just code for version(has_feature). And your config file might be relatively large, with several entries for each OS. So you'd have: // dll stuff version(linux || darwin || bsd) version = UseDlfcn; else version = UseDll; // socket stuff ... I would prefer: version(linux) version = UseDlfcn; // ... version(darwin)... It works with the current syntax, and it is equally organized. It's easier to see, given a platform, what versions you have defined. On the other hand, it's a bit harder to see whether a particular version is defined.The version statement is limited in that you cannot do !foo or foo&&bar||baz. Rather than a bug, that is deliberate. I've seen a lot of code that, over the years, accumulated detritus like: #if FOO || BAR>0x1234 && BAZ && !HACK These tend to snarl themselves into such a rat's nest of conditionals the only way to figure out which lines actually got compiled was to examine the preprocessor output. (Another consequence of these is that, inevitably, the various conditionals were WRONG as they were layered on by people who didn't really understand the code.) So, by limiting the version statement, the idea is to encourage the programmer to think in terms of distinct versions being generated, and then code in terms of those distinct versions - each of those versions having a name.You tell me which is more readable: version(linux || darwin || bsd) version = UseDlfcn; else version = UseDLLs; vs. version(linux) version = UseDlfcn; else version(darwin) version = UseDlfcn; else version(bsd) version = UseDlfcn; else version = UseDLLs; It only gets worse when you actually *need* complex versioning, and when the contents of those version blocks become more than trivial. Yes, you can define intermediate versions like I've done here, but even that becomes tedious and hard to read.
Dec 07 2007
On 2007-12-07 05:47:36 -0500, Walter Bright <newshound1 digitalmars.com> said:So, by limiting the version statement, the idea is to encourage the programmer to think in terms of distinct versions being generated, and then code in terms of those distinct versions - each of those versions having a name.I've come into a situation where I'll probably have to take the bloat from the code and transfer it to the build process because of this limitation. Apple's C/C++/Obj-C headers all use the following idiom to create single header files adapted to the target version of Mac OS X you wish to use: #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 // Mac OS X 10.3 specific functions prototypes #endif #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 // Mac OS X 10.4 specific functions prototypes #endif #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 // Mac OS X 10.5 specific functions prototypes #endif Then you only need to set MAC_OS_X_VERSION_MAX_ALLOWED to the actual version number and you instantly have headers limited to the version your application is targeting. (Or if you don't you get headers for the latest version.) The only way I see to replicate that in D when converting Apple headers is to use: version (MAC_OS_X_VERSION_10_3) { // Mac OS X 10.3 specific functions prototypes. } version (MAC_OS_X_VERSION_10_4) { // Mac OS X 10.4 specific functions prototypes. } version (MAC_OS_X_VERSION_10_5) { // Mac OS X 10.5 specific functions prototypes. } This is inconvenient (and error prone) because if you're going to import a module with these version flags in your program, you then need to define when version flags for each previous version of the OS; and the number of symbols to define will always go in increasing. If you could just write: version (MAC_OS_X_VERSION >= 10.3) it'd make things much easier. Even better would be: version (MAC_OS_X_VERSION <= 10.1 && MAC_OS_X_VERSION > 10.4) to indicate a function added at version 10.1 and removed in 10.4. To do that with my current system, it'd read: version (MAC_OS_X_VERSION_10_3) { } else version (MAC_OS_X_VERSION_10_1) { // some functions added in Mac OS X 10.1 but removed in 10.4. } which isn't that clear either. By the way, I know I could use simply a version number flag and write: version (1) { } version (2) { } version (3) { } But then it'll prevent anyone from using version numbers for their own application when using ported headers. Now that I'm thinking about it, the simplest solution probably lies in using version to declare some constants in a module mimicking AvailabilityMacros.h, then using those constants with static ifs.=. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Dec 07 2007
mandel wrote:A proposal in a nutshell: - removal of the keywords "unittest, "version" and similar. - replaced by global compile time variables. - "dmd -<name>=<value>" to set them. Variables not found result in compiler warnings - "dmd -list version*" or similar to list all global variable names with prefix "version" -> less keywords, more powerfull control (use in boolean expressions), more native syntax, easier to understand Ideas? Problems? Objections?There are two things I like in the current system that will be lost with this proposal: 1. Distinction between conditional compilation as in different versions of the software and use of static if for meta- and generic programming 2. A standardized naming scheme. For example, there's nothing magical about the debug keyword as far as I know, it could just be replaced with version(Debug). But it's nice that everybody uses the same thing for the same purpose.
Dec 07 2007
Lutger wrote:For example, there's nothing magical about the debug keyword as far as I know, it could just be replaced with version(Debug). But it's nice that everybody uses the same thing for the same purpose.You're quite right in your assessment of the debug conditional. It stems from my experience (and that of some managers who begged me for this) that every C/C++ project has their own, unique, way of building for debug. It's not that any of them are wrong, it's just that they're all different. No standardized convention has ever emerged, yet all these debug schemes essentially do the same thing. Providing a standard means of debug compilation means: 1) Projects developed by different groups will naturally gravitate towards using it, rather than invent their own, aiding source code portability. 2) Programmers can move from project to project with one less coding convention they must relearn. 3) Standardized tools can be developed to manipulate the debug compilations. 4) A standardized scheme is something that can be enforced by larger organizations.
Dec 07 2007
mandel:Still, I can't get rid of the desire to give more power to the programmer by simplifying stuff. :>Some built-in restraints can be *really* useful to avoid bugs. Bye, bearophile
Dec 07 2007
mandel wrote:Ideas? Problems? Objections? ...might be hairy to implement?Maybe. And it would be EXTREMELY hairy to read. ...what would happen if you compiled with '-if=false' ?
Dec 07 2007
mandel wrote:A proposal in a nutshell: - removal of the keywords "unittest, "version" and similar. - replaced by global compile time variables. - "dmd -<name>=<value>" to set them. Variables not found result in compiler warnings - "dmd -list version*" or similar to list all global variable names with prefix "version" -> less keywords, more powerfull control (use in boolean expressions), more native syntax, easier to understand Ideas? Problems? Objections? btw.: bool enableXYZ; if(enableXFZ) import foo.Bar; ...might be hairy to implement?Please please don't. From my standpoint, and converting over 70k lines of code over to D I can attest how easy the simplistic way of how D handles versions is so nice in the long run. I do like the idea of version (a,b,c) though, oddly enough. Now if I could get a way to enforce a type can't be null by the language itself, it would save a lot of if(whatever == null) cruft I have lined throughout from the *other* language port we're doing:(. yanno, something that says I expect class Whatever, I want class Whatever and don't you damn well give me null. I have noticed a push for changing adding complication for unittest as well, but I hope it stays quite similar, though I really would like a lil more fine tuning of how it's ran.
Dec 07 2007
Robby wrote:mandel wrote:is null*, thinking one thing, writing another. sighA proposal in a nutshell: - removal of the keywords "unittest, "version" and similar. - replaced by global compile time variables. - "dmd -<name>=<value>" to set them. Variables not found result in compiler warnings - "dmd -list version*" or similar to list all global variable names with prefix "version" -> less keywords, more powerfull control (use in boolean expressions), more native syntax, easier to understand Ideas? Problems? Objections? btw.: bool enableXYZ; if(enableXFZ) import foo.Bar; ...might be hairy to implement?Please please don't. From my standpoint, and converting over 70k lines of code over to D I can attest how easy the simplistic way of how D handles versions is so nice in the long run. I do like the idea of version (a,b,c) though, oddly enough. Now if I could get a way to enforce a type can't be null by the language itself, it would save a lot of if(whatever == null) cruft I have lined throughout from the *other* language port we're doing:(. yanno, something that says I expect class Whatever, I want class Whatever and don't you damn well give me null. I have noticed a push for changing adding complication for unittest as well, but I hope it stays quite similar, though I really would like a lil more fine tuning of how it's ran.
Dec 07 2007