www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Template pattern delegate?

reply frame <frame86 live.com> writes:
Is there a possibility to write templated code / custom trait 
pattern with usage like a delegate?

I have a try-catch block with different types and don't want to 
repeat myself in every method again. It's always the same, just 
what's tried changes, eg.:

pseudo code:

template myStuff(mixin code)
{
     try {
         code();
     }
     catch (X e) {
         ...
     }
     catch (Y e) {
         ...
     }
     ...
}

static myStuff!({
    writeln("...");
});
Oct 25 2020
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 10/25/20 4:30 AM, frame wrote:
 Is there a possibility to write templated code / custom trait pattern=20
 with usage like a delegate?
=20
 I have a try-catch block with different types and don't want to repeat =
 myself in every method again. It's always the same, just what's tried=20
 changes, eg.:
=20
 pseudo code:
=20
 template myStuff(mixin code)
 {
  =C2=A0=C2=A0=C2=A0 try {
  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 code();
  =C2=A0=C2=A0=C2=A0 }
  =C2=A0=C2=A0=C2=A0 catch (X e) {
  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ...
  =C2=A0=C2=A0=C2=A0 }
  =C2=A0=C2=A0=C2=A0 catch (Y e) {
  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ...
  =C2=A0=C2=A0=C2=A0 }
  =C2=A0=C2=A0=C2=A0 ...
 }
=20
 static myStuff!({
  =C2=A0=C2=A0 writeln("...");
 });
=20
That's one of my DConf Onlide slides but for a limited use case! :) int tried(Func, string functionName =3D __FUNCTION__, string file =3D=20 __FILE__, size_t line =3D __LINE__)(Func func) { static if (!is (ReturnType!Func =3D=3D int)) { pragma(msg, format!"\n%s(%s): Error: %s must return int error=20 code"(file, line, functionName)); static assert(false); } void printError(T)(T err) { stderr.writefln!"\n%s(%s): Failed to execute %s: %s"(file, line,=20 functionName, err); } try { return func(); } catch (Exception exc) { printError(exc.msg); return 1; } catch (Error err) { printError(err); import core.stdc.stdlib : abort; abort(); } assert(false); } Then, all extern(C) functions would be written the same way: extern(C) int foo() { return tried({ // ... return 0; }); } Ali
Oct 25 2020
parent reply frame <frame86 live.com> writes:
On Sunday, 25 October 2020 at 12:02:10 UTC, Ali Çehreli wrote:
 On 10/25/20 4:30 AM, frame wrote:
 Is there a possibility to write templated code / custom trait 
 pattern with usage like a delegate?
 
 I have a try-catch block with different types and don't want 
 to repeat myself in every method again. It's always the same, 
 just what's tried changes, eg.:
 
 pseudo code:
 
 template myStuff(mixin code)
 {
      try {
          code();
      }
      catch (X e) {
          ...
      }
      catch (Y e) {
          ...
      }
      ...
 }
 
 static myStuff!({
     writeln("...");
 });
 
That's one of my DConf Onlide slides but for a limited use case! :) int tried(Func, string functionName = __FUNCTION__, string file = __FILE__, size_t line = __LINE__)(Func func) { static if (!is (ReturnType!Func == int)) { pragma(msg, format!"\n%s(%s): Error: %s must return int error code"(file, line, functionName)); static assert(false); } void printError(T)(T err) { stderr.writefln!"\n%s(%s): Failed to execute %s: %s"(file, line, functionName, err); } try { return func(); } catch (Exception exc) { printError(exc.msg); return 1; } catch (Error err) { printError(err); import core.stdc.stdlib : abort; abort(); } assert(false); } Then, all extern(C) functions would be written the same way: extern(C) int foo() { return tried({ // ... return 0; }); } Ali
I see that your approach can handle functions and delegates but isn't that not equivalent like this template for a function? auto myStuff(T)(T function() fn) { try { return fn(); } catch (Exception e) { // } } I wonder if I could use such a template as static variant and the compiler just expands the code? Just thinking that using a function or delegate is an overhead. Maybe not a function but a delegate will allocate GC memory I think.
Oct 25 2020
parent reply Jacob Carlborg <doob me.com> writes:
On Monday, 26 October 2020 at 00:56:26 UTC, frame wrote:

 I see that your approach can handle functions and delegates but 
 isn't that not equivalent like this template for a function?

 auto myStuff(T)(T function() fn) {
     try {
         return fn();
     }
     catch (Exception e) {
         //
     }
 }
You cannot pass a delegate to something that expects a function pointer.
 I wonder if I could use such a template as static variant and 
 the compiler just expands the code? Just thinking that using a 
 function or delegate is an overhead. Maybe not a function but a 
 delegate will allocate GC memory I think.
If you pass the delegate as a template parameter/alias parameter, it's more likely to be inlined: auto myStuff(alias fn)() { try return fn(); catch (Exception e) { } } myStuff!( { /* some code */ } ); -- /Jacob Carlborg
Oct 26 2020
parent frame <frame86 live.com> writes:
On Monday, 26 October 2020 at 09:25:03 UTC, Jacob Carlborg wrote:
 On Monday, 26 October 2020 at 00:56:26 UTC, frame wrote:


 If you pass the delegate as a template parameter/alias 
 parameter, it's more likely to be inlined:

 auto myStuff(alias fn)() {
     try return fn();
     catch (Exception e) { }
 }

 myStuff!( { /* some code */ } );

 --
 /Jacob Carlborg
Does not work in my case. Seems to conflict with overloads, but thanks for the hint.
Oct 26 2020