digitalmars.D - Defining a version after it's tested for
- Robert Clipsham (31/31) May 21 2009 I recently came across this:
- Tim Matthews (5/7) May 21 2009 I think versions are powerfull enough so I created a wrapper around whic...
- Steven Schveighoffer (17/48) May 21 2009 Versions are intended to be predefined before usage. It's the same thin...
- Robert Clipsham (2/22) May 21 2009 Unfortunately I thought this might be the case. Thanks.
- Tim Matthews (32/50) May 21 2009 I think this would be less ugly:
- Robert Clipsham (3/37) May 22 2009 This still doesn't solve my problem though, all it does is remove the
- Tim Matthews (10/43) May 22 2009 From what can I see you have a few different posssible versions but whe...
- Robert Clipsham (5/13) May 22 2009 Ah, I see what you mean now, you don't mean to use this on its own, but
- Don (8/35) May 22 2009 Versions are like in functional programming, they are NOT variables.
- Jason House (2/40) May 22 2009 I wonder if a compiler patch to loosen the restrictions would be accepte...
- Robert Clipsham (4/5) May 22 2009 I doubt it's trivial to support... depending on when it's evaluated the
I recently came across this: version( BackendFoo ) {} else version( BackendBar ) {} else version( BackendCar ) {} else { pragma( msg, "Warning: backend version undefined" ); pragma( msg, "Attempting to guess backend" ); version( Windows ) { version = BackendFoo; pragma( msg, "Selected the Foo backend." ); } else version(...) { /* You get the idea */ } } However, when trying to compile I get the following error: Error: version BackendFoo defined after use What is the reasoning behind this? It could be extremely useful to have this functionality. The only reason I can think of for doing this is that this code could be evaluated after modules that depend on the version being defined, causing it not to work. Surely there would be a way around that? If it's not possible to fix this, what way would you recommend I get around this? The only idea I've come up with so far is to do: else { static assert( false, "Please compile with -version=Backend(Foo|Bar|Bar)" ); } Which is less than optimal.
May 21 2009
On Fri, 22 May 2009 02:45:24 +1200, Robert Clipsham <robert octarineparrot.com> wrote:If it's not possible to fix this, what way would you recommend I get around this?I think versions are powerfull enough so I created a wrapper around which makes best use of static asserts (attached) I think the reason behind this is to discourage version usage.
May 21 2009
On Thu, 21 May 2009 10:45:24 -0400, Robert Clipsham <robert octarineparrot.com> wrote:I recently came across this: version( BackendFoo ) {} else version( BackendBar ) {} else version( BackendCar ) {} else { pragma( msg, "Warning: backend version undefined" ); pragma( msg, "Attempting to guess backend" ); version( Windows ) { version = BackendFoo; pragma( msg, "Selected the Foo backend." ); } else version(...) { /* You get the idea */ } } However, when trying to compile I get the following error: Error: version BackendFoo defined after use What is the reasoning behind this? It could be extremely useful to have this functionality. The only reason I can think of for doing this is that this code could be evaluated after modules that depend on the version being defined, causing it not to work. Surely there would be a way around that? If it's not possible to fix this, what way would you recommend I get around this? The only idea I've come up with so far is to do: else { static assert( false, "Please compile with -version=Backend(Foo|Bar|Bar)" ); } Which is less than optimal.Versions are intended to be predefined before usage. It's the same thing as using a variable before it's defined. The rational is, to flag errors to the user where he thinks forward referencing of versions works. Unfortunately, you have to do the following workaround: version(BackendFoo) { version=BackendFoo_;} else version(BackendBar) { version=BackendBar_;} else version(BackendCar) { version=BackendCar_;} else { version(Windows) {version=BackendFoo_;} } And now, you must use Backend*_ in your code. It should work, but it's ugly. Maybe Walter has a better method. -Steve
May 21 2009
Steven Schveighoffer wrote:Versions are intended to be predefined before usage. It's the same thing as using a variable before it's defined. The rational is, to flag errors to the user where he thinks forward referencing of versions works. Unfortunately, you have to do the following workaround: version(BackendFoo) { version=BackendFoo_;} else version(BackendBar) { version=BackendBar_;} else version(BackendCar) { version=BackendCar_;} else { version(Windows) {version=BackendFoo_;} } And now, you must use Backend*_ in your code. It should work, but it's ugly. Maybe Walter has a better method. -SteveUnfortunately I thought this might be the case. Thanks.
May 21 2009
On Fri, 22 May 2009 07:54:07 +1200, Robert Clipsham <robert octarineparrot.com> wrote:Steven Schveighoffer wrote:I think this would be less ugly: template vers(char[] V) { mixin("version(" ~ V ~ ") { const bool vers = true; } else { const bool vers = false; }"); } static if(vers!("BackendFoo") || vers!("Windows")) { // } else static if(vers!("BackendBar")) { // } else static if (vers!("BackendCar")) { // } else { // } I would prefer the normal version statement to work like that directly though.Versions are intended to be predefined before usage. It's the same thing as using a variable before it's defined. The rational is, to flag errors to the user where he thinks forward referencing of versions works. Unfortunately, you have to do the following workaround: version(BackendFoo) { version=BackendFoo_;} else version(BackendBar) { version=BackendBar_;} else version(BackendCar) { version=BackendCar_;} else { version(Windows) {version=BackendFoo_;} } And now, you must use Backend*_ in your code. It should work, but it's ugly. Maybe Walter has a better method. -SteveUnfortunately I thought this might be the case. Thanks.
May 21 2009
Tim Matthews wrote:I think this would be less ugly: template vers(char[] V) { mixin("version(" ~ V ~ ") { const bool vers = true; } else { const bool vers = false; }"); } static if(vers!("BackendFoo") || vers!("Windows")) { // } else static if(vers!("BackendBar")) { // } else static if (vers!("BackendCar")) { // } else { // } I would prefer the normal version statement to work like that directly though.This still doesn't solve my problem though, all it does is remove the usage of the version statement, which seems... pointless :S
May 22 2009
On Fri, 22 May 2009 20:29:03 +1200, Robert Clipsham <robert octarineparrot.com> wrote:Tim Matthews wrote:From what can I see you have a few different posssible versions but when no version is defined you can select a default version based on other stuff like windows operating system. Rather than modify the versions or add aditional to match the system you can create complex 'static if' statements which also are a compile time feature but can have other static ifs and logical comparisons like '&&' and '||'. When you have put the right checks in you can match your select target systems all within a single static if.I think this would be less ugly: template vers(char[] V) { mixin("version(" ~ V ~ ") { const bool vers = true; } else { const bool vers = false; }"); } static if(vers!("BackendFoo") || vers!("Windows")) { // } else static if(vers!("BackendBar")) { // } else static if (vers!("BackendCar")) { // } else { // } I would prefer the normal version statement to work like that directly though.This still doesn't solve my problem though, all it does is remove the usage of the version statement, which seems... pointless :S
May 22 2009
Tim Matthews wrote:From what can I see you have a few different posssible versions but when no version is defined you can select a default version based on other stuff like windows operating system. Rather than modify the versions or add aditional to match the system you can create complex 'static if' statements which also are a compile time feature but can have other static ifs and logical comparisons like '&&' and '||'. When you have put the right checks in you can match your select target systems all within a single static if.Ah, I see what you mean now, you don't mean to use this on its own, but rather use it along with other tests, so rather than using a version identifier it would resolve to something internally which could be tested in a static if... this would work nicely actually, thanks!
May 22 2009
Robert Clipsham wrote:I recently came across this: version( BackendFoo ) {} else version( BackendBar ) {} else version( BackendCar ) {} else { pragma( msg, "Warning: backend version undefined" ); pragma( msg, "Attempting to guess backend" ); version( Windows ) { version = BackendFoo; pragma( msg, "Selected the Foo backend." ); } else version(...) { /* You get the idea */ } } However, when trying to compile I get the following error: Error: version BackendFoo defined after use What is the reasoning behind this? It could be extremely useful to have this functionality. The only reason I can think of for doing this is that this code could be evaluated after modules that depend on the version being defined, causing it not to work. Surely there would be a way around that?Versions are like in functional programming, they are NOT variables. Once you've tested the existence of a non-existent version identifier, you've implicitly declared it. When there was a discussion about 'version' some time back, I made a proposal which (among other things) would require you to explicitly state that a particular version identifier is set from the command line; that would make this case clearer.
May 22 2009
Robert Clipsham Wrote:I recently came across this: version( BackendFoo ) {} else version( BackendBar ) {} else version( BackendCar ) {} else { pragma( msg, "Warning: backend version undefined" ); pragma( msg, "Attempting to guess backend" ); version( Windows ) { version = BackendFoo; pragma( msg, "Selected the Foo backend." ); } else version(...) { /* You get the idea */ } } However, when trying to compile I get the following error: Error: version BackendFoo defined after use What is the reasoning behind this? It could be extremely useful to have this functionality. The only reason I can think of for doing this is that this code could be evaluated after modules that depend on the version being defined, causing it not to work. Surely there would be a way around that? If it's not possible to fix this, what way would you recommend I get around this? The only idea I've come up with so far is to do: else { static assert( false, "Please compile with -version=Backend(Foo|Bar|Bar)" ); } Which is less than optimal.I wonder if a compiler patch to loosen the restrictions would be accepted. Something like what you tried should be trivial to support.
May 22 2009
Jason House wrote:I wonder if a compiler patch to loosen the restrictions would be accepted. Something like what you tried should be trivial to support.I doubt it's trivial to support... depending on when it's evaluated the version may or may not be set when it's checked, which is likely to cause confusion later on.
May 22 2009