Thread overview
Re: nice library workaround for lack of version boolean operations, would be nice to have in phobos
Jun 05, 2013
Timothee Cour
Jun 05, 2013
Manu
Jun 05, 2013
Jonathan M Davis
Jun 05, 2013
Timothee Cour
June 05, 2013
Actually I can improve syntax a bit as follows:


user code:
----
void main(){
static if(versions.OSX&& versions.D_NoBoundsChecks || !versions.has!"assert)
  writeln("special code");
}
----

(note the alternate syntax with 'has' to support special keyword versions
such as assert).
The only drawback is that I'd like to have instead:
static if(versions.OSX&& versions.D_NoBoundsChecks || !versions["assert"] )
any idea to support that?

library code:
---
//in std.compiler
enum versions=(){
struct versions_{
bool has(alias a)(){
mixin(`
version(`~a~`){
return true;
}
else
return false;
`);
}

alias has this;

auto opDispatch(string a)(){
mixin(`
version(`~a~`){
return true;
}
else
return false;
`);
}
}
return versions_.init;
}();
---




On Wed, Jun 5, 2013 at 2:28 AM, Timothee Cour <thelastmammoth@gmail.com>wrote:

> Just figured out we can do this. Could this be added to phobos?
>
> ----
> //in std.compiler (or std.traits?)
> template Version(alias V){
> mixin(`
>  version(`~V~`){
> enum Version=true;
> }
>  else
> enum Version=false;
> `);
> }
> ----
>
> usage:
>
> ----
> import std.compiler;
> void main(){
> static if(!Version!"assert")
>  writeln("not assert");
>
> static if(Version!"OSX" && !Version!"D_NoBoundsChecks" ||
> !Version!"assert")
>         {
> writeln("special code");
> }
> }
> ----
>
> without this, we have to resort to something ugly, not dry, error prone:
>
> ----
> //pollutes namespace, as we can't define version=temp inside a function
> version(OSX)
> {
> version(D_NoBoundsChecks)
>         {
> }
>  else
>         {
> version=temp;//need to make sure temp doesn't clash with other version
> identifiers / symbols
>  }
> }
> else
> {
> version(assert)
>         {
>  }
> else
>         {
> version=temp;//NOT DRY: repeats temp
>  }
> }
>
> void main()
> {
> version(assert)
>         {
> }
> else
>         {
> writeln("not assert");
>  }
>
> version(temp) // here we use it
>         {
> writeln("special code");
>  }
> }
> ----
>
>
> Likewise, with debug:
> ----
> template Debug(alias V){
>  import std.traits:isIntegral;
> static if(!isIntegral!(typeof(V))){
> mixin(`
>  debug(`~V~`){
> enum Debug=true;
> }
>  else
> enum Debug=false;
> `);
> }
>  else{
> import std.conv:to;
> mixin(`
>  debug(`~V.to!string~`){
> enum Debug=true;
> }
>  else
> enum Debug=false;
> `);
> /+
>  //NOTE:maybe a dmd bug but this didn't work
>  debug(V)
>    enum Debug=true;
>  else
>    enum Debug=false;
>  +/
>  }
> }
> ----
>
>
> usage:
> ----
> void main(){
>         import std.compiler;
> static if(Debug!2){
> writeln("debug>=2");
>  }
> static if(Debug!"foo"){
> writeln("debug=foo");
>  }
> }
> ----
>
>


June 05, 2013
Great idea. I've had lots of problems wrangling versions.
I find a numeric version number in conjunction with a platform version
and/or an architecture version too, are the most common logical
combinations I encounter, and D version syntax makes it a pain.
I almost exclusively set some bools at the top and use static of throughout.
This is a nice alternative, opDispatch is clever :)
On 5 Jun 2013 20:34, "Timothee Cour" <thelastmammoth@gmail.com> wrote:

> Actually I can improve syntax a bit as follows:
>
>
> user code:
> ----
> void main(){
> static if(versions.OSX&& versions.D_NoBoundsChecks ||
> !versions.has!"assert)
>   writeln("special code");
> }
> ----
>
> (note the alternate syntax with 'has' to support special keyword versions
> such as assert).
> The only drawback is that I'd like to have instead:
> static if(versions.OSX&& versions.D_NoBoundsChecks || !versions["assert"] )
> any idea to support that?
>
> library code:
> ---
> //in std.compiler
> enum versions=(){
> struct versions_{
> bool has(alias a)(){
> mixin(`
>  version(`~a~`){
> return true;
> }
>  else
> return false;
> `);
> }
>
> alias has this;
>
> auto opDispatch(string a)(){
>  mixin(`
> version(`~a~`){
> return true;
>  }
> else
> return false;
> `);
> }
> }
> return versions_.init;
> }();
> ---
>
>
>
>
> On Wed, Jun 5, 2013 at 2:28 AM, Timothee Cour <thelastmammoth@gmail.com>wrote:
>
>> Just figured out we can do this. Could this be added to phobos?
>>
>> ----
>> //in std.compiler (or std.traits?)
>> template Version(alias V){
>> mixin(`
>>  version(`~V~`){
>> enum Version=true;
>> }
>>  else
>> enum Version=false;
>> `);
>> }
>> ----
>>
>> usage:
>>
>> ----
>> import std.compiler;
>> void main(){
>> static if(!Version!"assert")
>>  writeln("not assert");
>>
>> static if(Version!"OSX" && !Version!"D_NoBoundsChecks" ||
>> !Version!"assert")
>>         {
>> writeln("special code");
>> }
>> }
>> ----
>>
>> without this, we have to resort to something ugly, not dry, error prone:
>>
>> ----
>> //pollutes namespace, as we can't define version=temp inside a function
>> version(OSX)
>> {
>> version(D_NoBoundsChecks)
>>         {
>> }
>>  else
>>         {
>> version=temp;//need to make sure temp doesn't clash with other version
>> identifiers / symbols
>>  }
>> }
>> else
>> {
>> version(assert)
>>         {
>>  }
>> else
>>         {
>> version=temp;//NOT DRY: repeats temp
>>  }
>> }
>>
>> void main()
>> {
>> version(assert)
>>         {
>> }
>> else
>>         {
>> writeln("not assert");
>>  }
>>
>> version(temp) // here we use it
>>         {
>> writeln("special code");
>>  }
>> }
>> ----
>>
>>
>> Likewise, with debug:
>> ----
>> template Debug(alias V){
>>  import std.traits:isIntegral;
>> static if(!isIntegral!(typeof(V))){
>> mixin(`
>>  debug(`~V~`){
>> enum Debug=true;
>> }
>>  else
>> enum Debug=false;
>> `);
>> }
>>  else{
>> import std.conv:to;
>> mixin(`
>>  debug(`~V.to!string~`){
>> enum Debug=true;
>> }
>>  else
>> enum Debug=false;
>> `);
>> /+
>>  //NOTE:maybe a dmd bug but this didn't work
>>  debug(V)
>>    enum Debug=true;
>>  else
>>    enum Debug=false;
>>  +/
>>  }
>> }
>> ----
>>
>>
>> usage:
>> ----
>> void main(){
>>         import std.compiler;
>> static if(Debug!2){
>> writeln("debug>=2");
>>  }
>> static if(Debug!"foo"){
>> writeln("debug=foo");
>>  }
>> }
>> ----
>>
>>
>


June 05, 2013
On Wednesday, June 05, 2013 02:28:16 Timothee Cour wrote:
> Just figured out we can do this. Could this be added to phobos?
[snip]

Walter is flat-out against anything which involves &&ing or ||ing version identifiers. It's not like it would be hard to add to the language, but he thinks that it's outright bad practice. If we were going to add this, I would expect us to just add it to the language, not to the library. So, I'd be surprised if anything like this ended up in Phobos.

- Jonathan M Davis
June 05, 2013
On Wed, Jun 5, 2013 at 10:04 AM, Jonathan M Davis <jmdavisProg@gmx.com>wrote:

> On Wednesday, June 05, 2013 02:28:16 Timothee Cour wrote:
> > Just figured out we can do this. Could this be added to phobos?
> [snip]
>
> Walter is flat-out against anything which involves &&ing or ||ing version identifiers. It's not like it would be hard to add to the language, but he thinks that it's outright bad practice.


DRY and clarity is more important (look at the horrible contorsions one has to do, eg in the example I provided above). This has been asked for many times. Once more, it would be great to have a voting system to see if there's clear majority on either side.



> If we were going to add this, I would
> expect us to just add it to the language, not to the library. So, I'd be
> surprised if anything like this ended up in Phobos.
>


What i described fits more with the rest of the language (and doesn't
require language change).
It allows:

static if( condition && versions.OSX){ ...}
//or:
auto foo = condition && versions.OSX;

(where condition is arbitrary).
A language proposal (eg version(OSX || Windows) ) would not allow it.