www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Is this possible in D?

reply "Jonathan Marler" <johnnymarler gmail.com> writes:
I am having a heck of a time trying to figure out how to do this. 
  How do I change the attributes of a function based on the 
version without copying the function body?  For example:

version(StaticVersion) {
     static void myLongFunction()
     {
         // long body ...
     }
} else {
     void myLongFunction()
     {
         // same long body copied...
     }
}

In one version I want the function to be static and in another I 
don't want it to be static.  I cannot figure out how to do this 
without copy/pasting the entire function body to both versions.
Feb 19 2015
next sibling parent "tcak" <tcak gmail.com> writes:
On Thursday, 19 February 2015 at 08:24:08 UTC, Jonathan Marler 
wrote:
 I am having a heck of a time trying to figure out how to do 
 this.
  How do I change the attributes of a function based on the 
 version without copying the function body?  For example:

 version(StaticVersion) {
     static void myLongFunction()
     {
         // long body ...
     }
 } else {
     void myLongFunction()
     {
         // same long body copied...
     }
 }

 In one version I want the function to be static and in another 
 I don't want it to be static.  I cannot figure out how to do 
 this without copy/pasting the entire function body to both 
 versions.
Same problem is seen with "shared" and "non-shared" class methods as well. I hope there is a good solution for it. If it was C, by using #ifdef #else #endif, just the name line of function could be changed, but I am not sure whether that works with "version()" expression.
Feb 19 2015
prev sibling next sibling parent reply "Mike Parker" <aldacron gmail.com> writes:
On Thursday, 19 February 2015 at 08:24:08 UTC, Jonathan Marler 
wrote:
 I am having a heck of a time trying to figure out how to do 
 this.
  How do I change the attributes of a function based on the 
 version without copying the function body?  For example:

 version(StaticVersion) {
     static void myLongFunction()
     {
         // long body ...
     }
 } else {
     void myLongFunction()
     {
         // same long body copied...
     }
 }

 In one version I want the function to be static and in another 
 I don't want it to be static.  I cannot figure out how to do 
 this without copy/pasting the entire function body to both 
 versions.
You should be able to cobble something together with string mixins.
Feb 19 2015
parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Thursday, 19 February 2015 at 09:38:48 UTC, Mike Parker wrote:
 On Thursday, 19 February 2015 at 08:24:08 UTC, Jonathan Marler 
 wrote:
 I am having a heck of a time trying to figure out how to do 
 this.
 How do I change the attributes of a function based on the 
 version without copying the function body?  For example:

 version(StaticVersion) {
    static void myLongFunction()
    {
        // long body ...
    }
 } else {
    void myLongFunction()
    {
        // same long body copied...
    }
 }

 In one version I want the function to be static and in another 
 I don't want it to be static.  I cannot figure out how to do 
 this without copy/pasting the entire function body to both 
 versions.
You should be able to cobble something together with string mixins.
I'm still holding out hope for some sort of .codeof
Feb 19 2015
prev sibling next sibling parent reply "Dicebot" <public dicebot.lv> writes:
Most practical approach I am currently aware of is wrapping 
actual implementation (in most restrictive version):

class Test {

private static void foo_() {}

version (Static)
{
      static void foo() { foo_(); }
}
else
{
      void foo() { foo_(); }
}

private void bar_() shared
{
}

version (Shared)
{
     void bar() shared { bar_(); }
}
else
{
     void bar() { (cast(shared Test)this).bar_(); }
}

}

But this relies on very careful code review because of casual 
casts for certain attributes (static and public/private are easy 
in that regard)
Feb 19 2015
parent reply "Mike Parker" <aldacron gmail.com> writes:
On Thursday, 19 February 2015 at 10:17:47 UTC, Dicebot wrote:
 Most practical approach I am currently aware of is wrapping 
 actual implementation (in most restrictive version):
I really like mixins for this sort of thing. ``` enum signature = "void longFunction()"; version( Static ) enum sig = "static " ~ signature; else alias sig = signature; enum funcBody = q{{ import std.stdio : writeln; writeln( "Hi there!" ); version( Static ) writeln( "I'm static!" ); }}; struct Mixed { mixin(sig ~ funcBody); } void main() { version( Static ) Mixed.longFunction(); else { Mixed m; m.longFunction(); } } ``` OP: By using a token string (q{}) for funcBody rather than a WYSIWYG string (r"" or ``), you can still get syntax highlighting in your editor.
Feb 19 2015
parent reply "tcak" <tcak gmail.com> writes:
On Thursday, 19 February 2015 at 12:16:18 UTC, Mike Parker wrote:
 On Thursday, 19 February 2015 at 10:17:47 UTC, Dicebot wrote:
 Most practical approach I am currently aware of is wrapping 
 actual implementation (in most restrictive version):
I really like mixins for this sort of thing. ``` enum signature = "void longFunction()"; version( Static ) enum sig = "static " ~ signature; else alias sig = signature; enum funcBody = q{{ import std.stdio : writeln; writeln( "Hi there!" ); version( Static ) writeln( "I'm static!" ); }}; struct Mixed { mixin(sig ~ funcBody); } void main() { version( Static ) Mixed.longFunction(); else { Mixed m; m.longFunction(); } } ``` OP: By using a token string (q{}) for funcBody rather than a WYSIWYG string (r"" or ``), you can still get syntax highlighting in your editor.
Based on your example, bye bye readibility. It is like writing rocket taking off procedures. People are complaining about different parts of D languages some structures (there are good ones, there are bad ones), but unfortunately, bad ones are continuously ignored in the name of trying to reach the language a stability.
Feb 19 2015
parent reply Mike Parker <aldacron gmail.com> writes:
On 2/20/2015 1:06 AM, tcak wrote:

  OP: By using a token string (q{}) for funcBody rather than a WYSIWYG
 string (r"" or ``), you can still get syntax highlighting in your editor.
Based on your example, bye bye readibility. It is like writing rocket taking off procedures. People are complaining about different parts of D languages some structures (there are good ones, there are bad ones), but unfortunately, bad ones are continuously ignored in the name of trying to reach the language a stability.
I agree that string mixins can kill readability. I encountered that when I used them to support both D1 and D2 in Derelict 2 years ago. But I think that when they are kept small and local as in cases like this, they aren't bad at all.
Feb 19 2015
parent "Jonathan Marler" <johnnymarler gmail.com> writes:
On Thursday, 19 February 2015 at 17:23:47 UTC, Mike Parker wrote:
 I agree that string mixins can kill readability. I encountered 
 that when I used them to support both D1 and D2 in Derelict 2 
 years ago. But I think that when they are kept small and local 
 as in cases like this, they aren't bad at all.
Thanks for your example. It's ugly but it's the only solution I've seen that gives me what I'm looking for. I hadn't thought about putting the function body inside a q{ string }
Feb 19 2015
prev sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
On Thu, 19 Feb 2015 08:24:06 +0000, Jonathan Marler wrote:

 I am having a heck of a time trying to figure out how to do this.
   How do I change the attributes of a function based on the
 version without copying the function body?  For example:
=20
 version(StaticVersion) {
      static void myLongFunction()
      {
          // long body ...
      }
 } else {
      void myLongFunction()
      {
          // same long body copied...
      }
 }
=20
 In one version I want the function to be static and in another I don't
 want it to be static.  I cannot figure out how to do this without
 copy/pasting the entire function body to both versions.
you can turn `myLongFunction()` to a template `myLongFunctionImlp()()`,=20 and then simply declare `myLongFunction()` with required attributes,=20 simply instantiating template in it's body.=
Feb 19 2015