digitalmars.D.learn - Template pattern delegate?
- frame (22/22) Oct 25 2020 Is there a possibility to write templated code / custom trait
- =?UTF-8?Q?Ali_=c3=87ehreli?= (33/60) Oct 25 2020 That's one of my DConf Onlide slides but for a limited use case! :)
- frame (15/76) Oct 25 2020 I see that your approach can handle functions and delegates but
- Jacob Carlborg (12/26) Oct 26 2020 You cannot pass a delegate to something that expects a function
- frame (3/13) Oct 26 2020 Does not work in my case. Seems to conflict with overloads, but
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
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("..."); }); =20That'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
On Sunday, 25 October 2020 at 12:02:10 UTC, Ali Çehreli wrote:On 10/25/20 4:30 AM, 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) { // } } 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.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
Oct 25 2020
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
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 CarlborgDoes not work in my case. Seems to conflict with overloads, but thanks for the hint.
Oct 26 2020