Re: emulate with
On Friday, 31 May 2019 at 08:35:23 UTC, Simen Kjærås wrote: With 1), 2) and 3) fixed, the code would look like this (only changed code included): unittest { with (Dispatcher.X) { A(1); A("a"); B(2); C_Q(3); } } struct Dispatcher { struct opDispatch(string prefix, alias context = __CONTEXT__) { static auto opDispatch(string name, Args...)(Args args) { return getMethod!(context, prefix~"_"~name)(args); } } } Actually, Dispatcher could look like this: struct Dispatcher { struct opDispatch(string prefix, alias context = __CONTEXT__) { alias opDispatch(string name) = getMethod!(context, prefix~"_"~name); } } -- Simen
Re: emulate with
On Friday, 31 May 2019 at 08:35:23 UTC, Simen Kjærås wrote: On Friday, 31 May 2019 at 07:17:22 UTC, Amex wrote: What I'm talking about is that if A would be dispatched to, say, W!X where W handles the special dispatching by returning X_A rather than X.A. I don't know if D can do this kinda stuff even though it would be rather simple as it would depend on with. Of course D can! However, it's not really pretty, and I think I found a bug in the process. This is my code that compiles and runs: void X_A(int i) {} void X_A(string s) {} void X_B(int i) {} void X_C_Q(int i) {} unittest { with (Dispatcher.X!({})) { A(1); A("a"); B(2); C_Q(3); } } template getMethod(alias x, string name) { static if (__traits(hasMember, x, name)) { alias getMethod = __traits(getMember, x, name); } else static if (x.stringof[0..7] == "module ") { import std.meta : AliasSeq; alias getMethod = AliasSeq!(); } else { alias getMethod = getMethod!(__traits(parent, x), name); } } struct Dispatcher { template opDispatch(string prefix) { static auto opDispatch(alias context)() { struct WithObject { auto opDispatch(string name, A...)(A a) { struct OverloadCaller { auto opCall(Args...)(Args args) { return getMethod!(context, prefix~"_"~name)(args); } } OverloadCaller result; return result; } } return WithObject(); } } } So, the ugly: 1) Instead of just Dispatcher.X, we need to give Dispatcher a context from where to look for X_. That's the curly brackets in Dispatcher.X!({}). 2) The bug I mentioned. The whole OverloadCaller deal is a silly workaround for WithObject's opDispatch not being called correctly by DMD. That's also why WithObject's opDispatch takes (A...)(A a). I'll be filing this, of course. 3) with doesn't correctly handle static opDispatch. I'll be filing a bug for that as well. We could fix 1) by introducing a new magic identifier - something like __CONTEXT__, which would work somewhat like __FUNCTION__, but be useful for reflection with __traits. I've played a little with this idea, but I'm not ready to make a PR with it. With 1), 2) and 3) fixed, the code would look like this (only changed code included): unittest { with (Dispatcher.X) { A(1); A("a"); B(2); C_Q(3); } } struct Dispatcher { struct opDispatch(string prefix, alias context = __CONTEXT__) { static auto opDispatch(string name, Args...)(Args args) { return getMethod!(context, prefix~"_"~name)(args); } } } I think that's kinda neat, TBH. -- Simen Thanks, I haven't messed with it but it by your examples it should do what I want... I actually probably need the use of .'s turned in to _'s... so I can write stuff like A.B.C.D and it all goes to X.A_B_C_D. I'm not sure if A.B.C.D would get dispatched as a whole or just in part though(e.g., is it treated as A.(B.(C.D)) or (A.B).C).D or A.B.C.D) which would require some type of chaining dispatcher I guess). In any case it helps with my specific problem. I like the idea of _CONTEXT_ and it might be usable in other areas. Thanks.
Re: emulate with
On Friday, 31 May 2019 at 07:17:22 UTC, Amex wrote: What I'm talking about is that if A would be dispatched to, say, W!X where W handles the special dispatching by returning X_A rather than X.A. I don't know if D can do this kinda stuff even though it would be rather simple as it would depend on with. Of course D can! However, it's not really pretty, and I think I found a bug in the process. This is my code that compiles and runs: void X_A(int i) {} void X_A(string s) {} void X_B(int i) {} void X_C_Q(int i) {} unittest { with (Dispatcher.X!({})) { A(1); A("a"); B(2); C_Q(3); } } template getMethod(alias x, string name) { static if (__traits(hasMember, x, name)) { alias getMethod = __traits(getMember, x, name); } else static if (x.stringof[0..7] == "module ") { import std.meta : AliasSeq; alias getMethod = AliasSeq!(); } else { alias getMethod = getMethod!(__traits(parent, x), name); } } struct Dispatcher { template opDispatch(string prefix) { static auto opDispatch(alias context)() { struct WithObject { auto opDispatch(string name, A...)(A a) { struct OverloadCaller { auto opCall(Args...)(Args args) { return getMethod!(context, prefix~"_"~name)(args); } } OverloadCaller result; return result; } } return WithObject(); } } } So, the ugly: 1) Instead of just Dispatcher.X, we need to give Dispatcher a context from where to look for X_. That's the curly brackets in Dispatcher.X!({}). 2) The bug I mentioned. The whole OverloadCaller deal is a silly workaround for WithObject's opDispatch not being called correctly by DMD. That's also why WithObject's opDispatch takes (A...)(A a). I'll be filing this, of course. 3) with doesn't correctly handle static opDispatch. I'll be filing a bug for that as well. We could fix 1) by introducing a new magic identifier - something like __CONTEXT__, which would work somewhat like __FUNCTION__, but be useful for reflection with __traits. I've played a little with this idea, but I'm not ready to make a PR with it. With 1), 2) and 3) fixed, the code would look like this (only changed code included): unittest { with (Dispatcher.X) { A(1); A("a"); B(2); C_Q(3); } } struct Dispatcher { struct opDispatch(string prefix, alias context = __CONTEXT__) { static auto opDispatch(string name, Args...)(Args args) { return getMethod!(context, prefix~"_"~name)(args); } } } I think that's kinda neat, TBH. -- Simen
Re: emulate with
imo for parts of names such things will never appear.. names, subnames, overloading.. hell no but I want Kotlin lambdas https://kotlinlang.org/docs/reference/lambdas.html I want more: Function literals with receiver it: implicit name of a single parameter Passing a lambda to the last parameter than will appear https://ask.ericlin.info/post/2017/06/subtle-differences-between-kotlins-with-apply-let-also-and-run/ https://medium.com/tompee/idiomatic-kotlin-lambdas-with-receiver-and-dsl-3cd3348e1235
emulate with
with lets one remove a direct reference... The problem is the things I want to access are not part of a single object but have a common naming structure: X_A X_B X_C_Q (rather than X.A, X.B, X.C.Q) it would be very helpful(since X is long) to be able to do something like with(X) { A; B; C_Q; } or even with(X) { A; B; with(C) { Q; } } I imagine this can actually be done with dispatching because one could use opDispatch to redirect. The problem is that this requires filling out the info which sorta defeated the purpose(unless it's used often). What I'm talking about is that if A would be dispatched to, say, W!X where W handles the special dispatching by returning X_A rather than X.A. I don't know if D can do this kinda stuff even though it would be rather simple as it would depend on with. e.g., would be cool if there was an opWith ;)
Re: need to emulate scope(failure) with struct destructor
On Sunday, 28 May 2017 at 20:06:42 UTC, piotrklos wrote: I need to perform an action, in multiple separate functions, if scope exits with an exception. The trouble is I don't want to litter my code with scope(failure) everywhere. I already create an instance of a struct at each location, with the sole purpose of doing things at the end of scope. So my code looks like: function1() { RAIIType transactionHandler; scope(failure) action; //code } function2() { RAIIType transactionHandler; scope(failure) action; //code } function3() { RAIIType transactionHandler; scope(failure) action; //code } etc. Ideally I would put the statement from scope(failure) in the struct's destructor and delete the scope(failure) statements. I would need something like c++'s std::uncaught_exceptions() to check if an exception is in flight. Is there something like this in D? PS I think that we have here a more general problem, because dlang is missing a feature for composition of scope(...) statements. Hard to do that way, only mixins come to mind. However, if you want to do the same thing anywhere the failure happens, most likely you want to do that at where you catch the exception. Another less likely, but possible, way is to have the struct destructor to do the scope(exit) part only if it gets destroyed in some certain state. For example, if the transaction receiver is null.
need to emulate scope(failure) with struct destructor
I need to perform an action, in multiple separate functions, if scope exits with an exception. The trouble is I don't want to litter my code with scope(failure) everywhere. I already create an instance of a struct at each location, with the sole purpose of doing things at the end of scope. So my code looks like: function1() { RAIIType transactionHandler; scope(failure) action; //code } function2() { RAIIType transactionHandler; scope(failure) action; //code } function3() { RAIIType transactionHandler; scope(failure) action; //code } etc. Ideally I would put the statement from scope(failure) in the struct's destructor and delete the scope(failure) statements. I would need something like c++'s std::uncaught_exceptions() to check if an exception is in flight. Is there something like this in D? PS I think that we have here a more general problem, because dlang is missing a feature for composition of scope(...) statements.
Re: Emulate C's (polymorphic) NULL type
On Monday, 6 June 2016 at 18:33:36 UTC, ParticlePeter wrote: On Monday, 6 June 2016 at 16:19:02 UTC, Alex Parrill wrote: On Monday, 6 June 2016 at 09:43:23 UTC, ParticlePeter wrote: In C NULL can be used as integer as well as null pointer. Is there a way to create such a type in D? The type should have only one value which is obviously (0/null). A extern( C ) function should be able to take it as either one. Overloaded enum pops into my mind as example: enum NULL = 0; enum NULL = null; Is this possible somehow? I already asked about this: https://forum.dlang.org/post/bnkqevhyxwdjjxsct...@forum.dlang.org Tldr; doesn't seem to be possible without multiple alias this or using ABI hacks. O.k., my web search didn't find that topic. The last reply looks promising, wouldn't that work? That's the ABI hack I mentioned. It abuses the fact that on most hardware and compiled, a pointer and a structure containing a single pointer have the same binary representation. It will likely work, but it isn't guarenteed.
Re: Emulate C's (polymorphic) NULL type
On Monday, 6 June 2016 at 18:33:36 UTC, ParticlePeter wrote: On Monday, 6 June 2016 at 16:19:02 UTC, Alex Parrill wrote: On Monday, 6 June 2016 at 09:43:23 UTC, ParticlePeter wrote: In C NULL can be used as integer as well as null pointer. Is there a way to create such a type in D? The type should have only one value which is obviously (0/null). A extern( C ) function should be able to take it as either one. Overloaded enum pops into my mind as example: enum NULL = 0; enum NULL = null; Is this possible somehow? I already asked about this: https://forum.dlang.org/post/bnkqevhyxwdjjxsct...@forum.dlang.org Tldr; doesn't seem to be possible without multiple alias this or using ABI hacks. O.k., my web search didn't find that topic. The last reply looks promising, wouldn't that work? Lets bump it and discuss there.
Re: Emulate C's (polymorphic) NULL type
On Monday, 6 June 2016 at 16:19:02 UTC, Alex Parrill wrote: On Monday, 6 June 2016 at 09:43:23 UTC, ParticlePeter wrote: In C NULL can be used as integer as well as null pointer. Is there a way to create such a type in D? The type should have only one value which is obviously (0/null). A extern( C ) function should be able to take it as either one. Overloaded enum pops into my mind as example: enum NULL = 0; enum NULL = null; Is this possible somehow? I already asked about this: https://forum.dlang.org/post/bnkqevhyxwdjjxsct...@forum.dlang.org Tldr; doesn't seem to be possible without multiple alias this or using ABI hacks. O.k., my web search didn't find that topic. The last reply looks promising, wouldn't that work?
Re: Emulate C's (polymorphic) NULL type
On Monday, 6 June 2016 at 09:43:23 UTC, ParticlePeter wrote: In C NULL can be used as integer as well as null pointer. Is there a way to create such a type in D? The type should have only one value which is obviously (0/null). A extern( C ) function should be able to take it as either one. Overloaded enum pops into my mind as example: enum NULL = 0; enum NULL = null; Is this possible somehow? I already asked about this: https://forum.dlang.org/post/bnkqevhyxwdjjxsct...@forum.dlang.org Tldr; doesn't seem to be possible without multiple alias this or using ABI hacks.
Re: Emulate C's (polymorphic) NULL type
On Monday, 6 June 2016 at 12:09:33 UTC, ParticlePeter wrote: I don't see the connection here, you introduced two symbols with two different types. I want one symbol which can pose as two different (constant) types. Ah, my apologies, I misunderstood the question.
Re: Emulate C's (polymorphic) NULL type
On Monday, 6 June 2016 at 11:40:11 UTC, Anonymouse wrote: On Monday, 6 June 2016 at 09:43:23 UTC, ParticlePeter wrote: In C NULL can be used as integer as well as null pointer. Is there a way to create such a type in D? The type should have only one value which is obviously (0/null). A extern( C ) function should be able to take it as either one. Overloaded enum pops into my mind as example: enum NULL = 0; enum NULL = null; Is this possible somehow? If you want it for use in logical expressions then implicit boolean conversion will treat them as the same. https://dpaste.dzfl.pl/d82f60657c37 I don't see the connection here, you introduced two symbols with two different types. I want one symbol which can pose as two different (constant) types.
Re: Emulate C's (polymorphic) NULL type
On Monday, 6 June 2016 at 09:43:23 UTC, ParticlePeter wrote: In C NULL can be used as integer as well as null pointer. Is there a way to create such a type in D? The type should have only one value which is obviously (0/null). A extern( C ) function should be able to take it as either one. Overloaded enum pops into my mind as example: enum NULL = 0; enum NULL = null; Is this possible somehow? If you want it for use in logical expressions then implicit boolean conversion will treat them as the same. https://dpaste.dzfl.pl/d82f60657c37
Re: Emulate C's (polymorphic) NULL type
On Monday, 6 June 2016 at 09:43:23 UTC, ParticlePeter wrote: A extern( C ) function should be able to take it as either one. Missed this bit. Not sure about that one.
Emulate C's (polymorphic) NULL type
In C NULL can be used as integer as well as null pointer. Is there a way to create such a type in D? The type should have only one value which is obviously (0/null). A extern( C ) function should be able to take it as either one. Overloaded enum pops into my mind as example: enum NULL = 0; enum NULL = null; Is this possible somehow?