digitalmars.D.learn - Using . notation abstractly
- James Japherson (53/53) Oct 10 2018 struct Dispatcher(Base...)
- Simen =?UTF-8?B?S2rDpnLDpXM=?= (29/33) Oct 11 2018 My first idea is to have Dispatch take an alias parameter, and
- Paul Backus (4/16) Oct 12 2018 You can use a mixin template to introduce a new namespace:
- Simen =?UTF-8?B?S2rDpnLDpXM=?= (29/58) Oct 12 2018 True, but D has namespaces elsewhere, which don't require you to
struct Dispatcher(Base...) { static auto opDispatch(string name, T...)(T vals) { pragma(msg, " - ", name); return Dispatcher!(Base, name).init; } } struct Dispatch { alias X = Dispatcher!void; alias X this; } pragma(msg, Dispatch.A.B.C, " - ", typeof(Dispatch.A.B.C)); CT Output: - A - B - C Dispatcher() - Dispatcher!(void, "A", "B", "C") The idea is one can do Dispatch.Left.Right.A.B.C; and it will sequentially handle all the indirections regardless of how many and return an object that encodes the path. (which then can be collapsed down to a single string). Ultimately some action can then be taken on the path. The point of all this is because D does not allow nesting of enums which allows for nice use of . to separate hiearchies: enum A { enum B { X, } } A.B.X, rather than having to have one large flat enum and do things like A_B_X. I know one can use structs but it is messy and not general enough. Dispatch.A.B.X can be used such as struct A { alias Dispatch this; } A.B.X but it requires more machinery to setup. The purpose is mainly to be able to hijack the `.` notation to create nice separations visually like we do for indirection but allow it to mean many different things. One of the problems is connecting it with actual code that does something depending on the path in a way that is general enough to be used for a wide variety of problems. Any ideas on how this could be done?
Oct 10 2018
On Wednesday, 10 October 2018 at 22:56:14 UTC, James Japherson wrote:One of the problems is connecting it with actual code that does something depending on the path in a way that is general enough to be used for a wide variety of problems. Any ideas on how this could be done?My first idea is to have Dispatch take an alias parameter, and see if it's useful for anything: struct Dispatch(alias Fn, Base...) { static auto opDispatch(string name, T...)(T vals) { return Dispatch!(Fn, Base, name).init; } alias _get = Fn!Base; alias _get this; } // join a list of stuff with _ between each element. template join(T...) { import std.conv : to; static if (T.length == 0) { enum join = ""; } else static if (T.length == 1) { enum join = T[0].to!string; } else { enum join = T[0].to!string ~"_"~join!(T[1..$]); } } unittest { assert(Dispatch!join.A.B.C == "A_B_C"); } No idea what to use it for, but it's kinda nice, I guess. Very generic, too. -- Simen
Oct 11 2018
On Wednesday, 10 October 2018 at 22:56:14 UTC, James Japherson wrote:The point of all this is because D does not allow nesting of enums which allows for nice use of . to separate hiearchies: enum A { enum B { X, } } A.B.X, rather than having to have one large flat enum and do things like A_B_X.You can use a mixin template to introduce a new namespace: https://run.dlang.io/is/K0kJJl
Oct 12 2018
On Friday, 12 October 2018 at 12:43:53 UTC, Paul Backus wrote:On Wednesday, 10 October 2018 at 22:56:14 UTC, James Japherson wrote:True, but D has namespaces elsewhere, which don't require you to clutter some other namespace with your enums: struct A { enum B { X, } } final abstract class C { enum D { Y, } } This has the added benefits of 1) being more obvious, and 2) you can put other stuff in there. On Wednesday, 10 October 2018 at 22:56:14 UTC, James Japherson wrote:The point of all this is because D does not allow nesting of enums which allows for nice use of . to separate hiearchies: enum A { enum B { X, } } A.B.X, rather than having to have one large flat enum and do things like A_B_X.You can use a mixin template to introduce a new namespace: https://run.dlang.io/is/K0kJJlI know one can use structs but it is messy and not general enough.Please do elucidate - what do you mean not general enough? When is a struct less general than an enum?struct A { alias Dispatch this; } A.B.X but it requires more machinery to setup.Also: alias A = Dispatch; A.B.X; Note that this results in Dispatcher!("B", "X"), so you'll have to pass the "A" manually (the same problem exists in your code above): alias A = Dispatcher!"A"; A.B.X; // Dispatcher!("A", "B", "X") -- Simen
Oct 12 2018