digitalmars.D - Version declaration proposal
- Don (41/41) Feb 11 2009 I think I have a solution to the versioning problems.
- Daniel Keep (5/5) Feb 11 2009 I actually quite like the idea of being able to specify which versions
- Don (9/15) Feb 11 2009 I reckon those integer versions are a misfeature to drop.
- Michel Fortin (47/52) Feb 11 2009 This makes me think of something I tried to do when I started the Cocoa
- Sergey Gromov (3/7) Feb 14 2009 I've proposed this some time ago. Maybe voting can help.
- Nick Sabalausky (5/13) Feb 11 2009 {snip: great proposal}
- Chris Nicholson-Sauls (3/53) Feb 11 2009 Looks good to me.
- Steve Schveighoffer (9/24) Feb 11 2009 I like this idea. I had one similar last night, but you beat me to it ;...
- Don (3/34) Feb 11 2009 Me neither. Of the two options I presented, I've decided I prefer
- Nick Sabalausky (36/70) Feb 11 2009 But there should be a way to specify a default value. I propose this:
- Don (14/54) Feb 11 2009 But only existence can be set on the command line, exactly as now.
- Nick Sabalausky (4/10) Feb 11 2009 True. I hereby propose that gets changed too. That's really an easy prob...
- Steve Schveighoffer (13/19) Feb 11 2009 This won't work. This means that older compilers will fail to compile
I think I have a solution to the versioning problems. My belief is that version statements are fine, and Walter's 'rats nest' argument is valid. Instead, I believe that version declarations limited to "version = XXX;" are too weak. They also have syntax which is subtly different to the rest of the language. (version = A; version = B; looks as though you're changing the value of the 'version' variable). My proposal is therefore: -------- * Keep version statements unchanged. * Change version declarations to make them almost identical to bool declarations: version _versionidentifier_ = _versionexpression_; where _versionexpression_ is a boolean expression involving only true, false, or other version identifiers, and standard boolean operators. * If, in addition, we allow: version _versionidentifier_ = extern; for versions which are supplied from the command line, it can then become illegal to have a version statement referring to an undeclared version identifier. (Any version identifier beginning with D_ is implicitly an "= extern;" identifier, so does not need to be declared). Another possibile syntax is extern version _versionidentifier_; to make the syntax identical to normal declarations. -------- This addresses a few problems: * typos in version identifiers. * Comprehensibility. When you see something like: version (UseLargeSize) { } you have no idea if that version identifier declaration is buried in the code somewhere, or whether it is a command-line option. It could even be both! * The effect of this would be to encourage you to create a block of version declarations at the start of the module, where they are easy to analyze and refactor. * A lint tool could even enforce this, by disallowing any version declarations after the first normal declaration is encountered. I believe this would reduce rats-nest versioning, and also eliminate the rats-nesting we have in version declarations right now. Is there anything wrong with it?
Feb 11 2009
I actually quite like the idea of being able to specify which versions you're allowed to set from the command-line. The only thing I can think of which this doesn't cover is how this affects (if indeed it does) integer versions. -- Daniel
Feb 11 2009
Daniel Keep wrote:I actually quite like the idea of being able to specify which versions you're allowed to set from the command-line. The only thing I can think of which this doesn't cover is how this affects (if indeed it does) integer versions. -- DanielI reckon those integer versions are a misfeature to drop. Compile this with version=3. --- version(2) { pragma(msg, "surprise!"); } else version(3) { pragma(msg, "I bet you were expecting this."); }
Feb 11 2009
On 2009-02-11 05:11:26 -0500, Don <nospam nospam.com> said:version(2) { pragma(msg, "surprise!"); } else version(3) { pragma(msg, "I bet you were expecting this."); }This makes me think of something I tried to do when I started the Cocoa wrappers D/Objective-C bridge. Apple uses a couple of macros to make their headers work accross different versions of Mac OS X. If, for instance, a function has been added in Mac OS X version 10.4, it'll look like this: #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 ... new stuff ... #endif While compiling on a Mac, you can define MAC_OS_X_VERSION_MAX_ALLOWED to control the availability of functions in the headers you include and thus be sure you're keeping yourself to what's available for the OS you're targeting, even if you're targetting an older OS. I could have gone the way Don demonstrate, using a version number which fortunately includes everything below it, but then I'd be taking that number, preventing others from using it in their own applications. So I though of defining versions flags for each successive release of Mac OS X and ask everyone to define the version flags for all the releases up to what they're targeting... that's not very elegant either. My conclusion is that the only way to do such fine-grained versionning in D is to use static ifs. If there were more than one version number allowed (so I don't eat up the only one available which someone else might want), this would mostly solve the problem. The other variable you can set is MAC_OS_X_VERSION_MIN_REQUIRED and this one isn't likely to be possible in D in the current version of the language. It causes every function not available in the minimum required version to be weak-linked (so you can test for its existance and then use it). It also allow deprecated warnings when you are using functions that were deprecated, done this way: DEPRECATED_IN_MAC_OS_X_VERSION_10_2_AND_LATER void myFunction(); And any use of that function when MAC_OS_X_VERSION_MIN_REQUIRED is higher than 10.2 will give you a deprecation warning. The above is difficult to do in D: static if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_2) deprecated void myFunction() { ... } else void myFunction() { ... } Which forces you to duplciate the code. I'd have liked to port that versionning system to by D wrappers, but it seems more trouble than it's worth, so I've just dropped the idea. (Another related problem is that adding/removing functions like this in a class changes the virtual table and makes the library incompatible with any program compiled with different version settings.) -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Feb 11 2009
Wed, 11 Feb 2009 07:24:31 -0500, Michel Fortin wrote:My conclusion is that the only way to do such fine-grained versionning in D is to use static ifs. If there were more than one version number allowed (so I don't eat up the only one available which someone else might want), this would mostly solve the problem.I've proposed this some time ago. Maybe voting can help. http://d.puremagic.com/issues/show_bug.cgi?id=2370
Feb 14 2009
"Don" <nospam nospam.com> wrote in message news:gmu0lt$2agm$1 digitalmars.com...I think I have a solution to the versioning problems. My belief is that version statements are fine, and Walter's 'rats nest' argument is valid. Instead, I believe that version declarations limited to "version = XXX;" are too weak. They also have syntax which is subtly different to the rest of the language. (version = A; version = B; looks as though you're changing the value of the 'version' variable). My proposal is therefore:{snip: great proposal} We can quibble over details of this, but I'm absolutely in full support of this general approach.
Feb 11 2009
Don wrote:I think I have a solution to the versioning problems. My belief is that version statements are fine, and Walter's 'rats nest' argument is valid. Instead, I believe that version declarations limited to "version = XXX;" are too weak. They also have syntax which is subtly different to the rest of the language. (version = A; version = B; looks as though you're changing the value of the 'version' variable). My proposal is therefore: -------- * Keep version statements unchanged. * Change version declarations to make them almost identical to bool declarations: version _versionidentifier_ = _versionexpression_; where _versionexpression_ is a boolean expression involving only true, false, or other version identifiers, and standard boolean operators. * If, in addition, we allow: version _versionidentifier_ = extern; for versions which are supplied from the command line, it can then become illegal to have a version statement referring to an undeclared version identifier. (Any version identifier beginning with D_ is implicitly an "= extern;" identifier, so does not need to be declared). Another possibile syntax is extern version _versionidentifier_; to make the syntax identical to normal declarations. -------- This addresses a few problems: * typos in version identifiers. * Comprehensibility. When you see something like: version (UseLargeSize) { } you have no idea if that version identifier declaration is buried in the code somewhere, or whether it is a command-line option. It could even be both! * The effect of this would be to encourage you to create a block of version declarations at the start of the module, where they are easy to analyze and refactor. * A lint tool could even enforce this, by disallowing any version declarations after the first normal declaration is encountered. I believe this would reduce rats-nest versioning, and also eliminate the rats-nesting we have in version declarations right now. Is there anything wrong with it?Looks good to me. -- Chris Nicholson-Sauls
Feb 11 2009
On Wed, 11 Feb 2009 09:01:29 +0100, Don wrote:I think I have a solution to the versioning problems. My belief is that version statements are fine, and Walter's 'rats nest' argument is valid. Instead, I believe that version declarations limited to "version = XXX;" are too weak. They also have syntax which is subtly different to the rest of the language. (version = A; version = B; looks as though you're changing the value of the 'version' variable). My proposal is therefore: -------- * Keep version statements unchanged. * Change version declarations to make them almost identical to bool declarations: version _versionidentifier_ = _versionexpression_;I like this idea. I had one similar last night, but you beat me to it ;) My idea was going to be something that is similar to the current version statements: version = _expression_ ? _identifier_ [ : _elseidentifier_ ] Where the [...] is optional. But your way looks cleaner. Not in love with the version x = extern notation ... -Steve
Feb 11 2009
Steve Schveighoffer wrote:On Wed, 11 Feb 2009 09:01:29 +0100, Don wrote:Me neither. Of the two options I presented, I've decided I prefer extern version x;I think I have a solution to the versioning problems. My belief is that version statements are fine, and Walter's 'rats nest' argument is valid. Instead, I believe that version declarations limited to "version = XXX;" are too weak. They also have syntax which is subtly different to the rest of the language. (version = A; version = B; looks as though you're changing the value of the 'version' variable). My proposal is therefore: -------- * Keep version statements unchanged. * Change version declarations to make them almost identical to bool declarations: version _versionidentifier_ = _versionexpression_;I like this idea. I had one similar last night, but you beat me to it ;) My idea was going to be something that is similar to the current version statements: version = _expression_ ? _identifier_ [ : _elseidentifier_ ] Where the [...] is optional. But your way looks cleaner. Not in love with the version x = extern notation ...
Feb 11 2009
"Don" <nospam nospam.com> wrote in message news:gmvg64$1v99$1 digitalmars.com...Steve Schveighoffer wrote:But there should be a way to specify a default value. I propose this: // FeatureX *must* be specified on cmd line. extern version FeatureX; version(FeatureX)... // Ok // FeatureX *can* be specified on cmd line, default is true. extern version FeatureX = true; version(FeatureX)... // Ok // FeatureX is true and *cannot* be specified on cmd line version FeatureX = true; version(FeatureX)... // Ok // Same as above. FeatureX is true and *cannot* be specified on cmd line. version FeatureX; version(FeatureX)... // Ok // Boolean expressions with other versions are Ok version FeatureX = (FeatureA || !FeatureB) && Windows; version(FeatureX)... // Ok // FeatureX *can* be specified on cmd line, default is complex. extern version FeatureX = (FeatureA || !FeatureB) && Windows; version(FeatureX)... // Ok // Illegal, FeatureX hasn't been declared version(FeatureX)... // Ok, Windows is a built-in version declared by the language or compiler. // Note that on non-Windows platforms, // the "Windows" version would still exist, // but it would just be set to false. version(Windows)... // Illegal, redefinition of FeatureX version FeatureX = false; // Ok so far... version FeatureX = true; // Illegal redefinition version FeatureX = false; // Also Illegal: same original value, but still a redefinition // Not sure about this version(FeatureX)... version FeatureX;On Wed, 11 Feb 2009 09:01:29 +0100, Don wrote:Me neither. Of the two options I presented, I've decided I prefer extern version x;I think I have a solution to the versioning problems. My belief is that version statements are fine, and Walter's 'rats nest' argument is valid. Instead, I believe that version declarations limited to "version = XXX;" are too weak. They also have syntax which is subtly different to the rest of the language. (version = A; version = B; looks as though you're changing the value of the 'version' variable). My proposal is therefore: -------- * Keep version statements unchanged. * Change version declarations to make them almost identical to bool declarations: version _versionidentifier_ = _versionexpression_;I like this idea. I had one similar last night, but you beat me to it ;) My idea was going to be something that is similar to the current version statements: version = _expression_ ? _identifier_ [ : _elseidentifier_ ] Where the [...] is optional. But your way looks cleaner. Not in love with the version x = extern notation ...
Feb 11 2009
Nick Sabalausky wrote:"Don" <nospam nospam.com> wrote in message news:gmvg64$1v99$1 digitalmars.com...But only existence can be set on the command line, exactly as now. So default is always false. For an extern identifier, true = it was specified on command line, false = it was not specified. Considering your worst case:Steve Schveighoffer wrote:But there should be a way to specify a default value.On Wed, 11 Feb 2009 09:01:29 +0100, Don wrote:Me neither. Of the two options I presented, I've decided I prefer extern version x;I think I have a solution to the versioning problems. My belief is that version statements are fine, and Walter's 'rats nest' argument is valid. Instead, I believe that version declarations limited to "version = XXX;" are too weak. They also have syntax which is subtly different to the rest of the language. (version = A; version = B; looks as though you're changing the value of the 'version' variable). My proposal is therefore: -------- * Keep version statements unchanged. * Change version declarations to make them almost identical to bool declarations: version _versionidentifier_ = _versionexpression_;I like this idea. I had one similar last night, but you beat me to it ;) My idea was going to be something that is similar to the current version statements: version = _expression_ ? _identifier_ [ : _elseidentifier_ ] Where the [...] is optional. But your way looks cleaner. Not in love with the version x = extern notation ...// FeatureX *can* be specified on cmd line, default is complex. extern version FeatureX = (FeatureA || !FeatureB) && Windows; version(FeatureX)... // OkYou could only do this with TWO extern features, one to enable it, one to disable. extern version EnableFeatureX; extern version DisableFeatureX; version FeatureX = (((FeatureA || !FeatureB) && Windows) || EnableFeatureX ) && ! DisableFeatureX; With what you're proposing, you'd need to change the command line syntax too.
Feb 11 2009
"Don" <nospam nospam.com> wrote in message news:gmviju$24va$1 digitalmars.com...Nick Sabalausky wrote:True. I hereby propose that gets changed too. That's really an easy problem to solve anyway.But there should be a way to specify a default value.But only existence can be set on the command line, exactly as now. With what you're proposing, you'd need to change the command line syntax too.
Feb 11 2009
On Wed, 11 Feb 2009 16:58:38 -0500, Nick Sabalausky wrote:// Ok, Windows is a built-in version declared by the language or compiler. // Note that on non-Windows platforms, // the "Windows" version would still exist, // but it would just be set to false. version(Windows)...This won't work. This means that older compilers will fail to compile newer code just because of version statements. In addition, a release of a new platform means a release of all the compilers on the other platforms. This essentially is a language change every time you add a new compiler- defined version. I think there should be some prefix for 'compiler- defined' versions, which are always extern. like D_Windows (As Don suggested), or maybe even adopt hierarchy style identifiers, kind of like java properties: version(Compiler.Windows) Any Compiler.* version is assumed to be extern. -Steve
Feb 11 2009