digitalmars.D - proposal: allow 'with(Foo):' in addition to 'with(Foo){..}'
- Timothee Cour via Digitalmars-d (3/3) Aug 09 2014 See email: 'with(Foo):' not allowed, why? in '
- Walter Bright (3/6) Aug 10 2014 No other statement construct works like that, there doesn't seem to be m...
- Brian Schott (12/19) Aug 10 2014 ---
- Daniel Murphy (3/10) Aug 10 2014 'statement'
- Idan Arye (2/23) Aug 10 2014 Stop trying to turn D into Python. It's not gonna happen.
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (4/29) Aug 10 2014 I think you misunderstand him: The examples he gave _are_ already
- Walter Bright (11/25) Aug 10 2014 C:\cbx>type foo.d
- Era Scarecrow (20/24) Aug 10 2014 Guess it depends on the type. with(): would act a lot like
- safety0ff (4/9) Aug 10 2014 For that specific case, put it outside the switch and drop the
- Era Scarecrow (14/16) Aug 10 2014 True, although if you repeat having to work with the type of Foo
- Andrei Alexandrescu (2/13) Aug 10 2014 We use this idiom a lot in a project at Facebook. -- Andrei
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (7/14) Aug 10 2014 It's possible to add this syntax for any statement, then `with`
- Rikki Cattermole (13/29) Aug 10 2014 I've had a need before for it in the past.
- Walter Bright (14/15) Aug 10 2014 The reason for the : syntax for declarations is that modules can be quit...
- Era Scarecrow (12/19) Aug 10 2014 5. Access permissions (public/private/protected).
- Timon Gehr (2/4) Aug 10 2014 It is a trivial change in the parser.
- Era Scarecrow (7/11) Aug 10 2014 Then I'd say give it a try on a branch and see how it performs
- Walter Bright (2/12) Aug 10 2014 Again, that is for declarations, not statements.
- Era Scarecrow (65/69) Aug 10 2014 Does with have to be only for statements?
- Walter Bright (4/22) Aug 10 2014 I'd suggest simply:
- Era Scarecrow (29/32) Aug 10 2014 The source code has 400 lines (955-1376) where it uses flags of
- Walter Bright (7/33) Aug 10 2014 It's not ideal, but it gets the job done. Keep in mind that you are prop...
- Era Scarecrow (36/44) Aug 11 2014 I suppose... Except where i'm using them is in a very controlled
- Artur Skawina via Digitalmars-d (24/33) Aug 11 2014 [...]
- Era Scarecrow (14/20) Aug 11 2014 I hoped i could give a relative use case for with(): that could
- Dicebot (7/10) Aug 10 2014 If this is going to be accepted I will most likely resort to
- Era Scarecrow (3/8) Aug 10 2014 Yeah i guess extra complexity for assisting tools
- Dicebot (5/13) Aug 10 2014 I did not mean that extra overhead for tools is a deal breaker -
See email: 'with(Foo):' not allowed, why? in ' digitalmars-d-learn puremagic.com' forum There's already an implementation proposed.
Aug 09 2014
On 8/9/2014 1:04 PM, Timothee Cour via Digitalmars-d wrote:See email: 'with(Foo):' not allowed, why? in 'digitalmars-d-learn puremagic.com <mailto:digitalmars-d-learn puremagic.com>' forum There's already an implementation proposed.No other statement construct works like that, there doesn't seem to be much point to adding such a special case.
Aug 10 2014
On Sunday, 10 August 2014 at 08:12:05 UTC, Walter Bright wrote:On 8/9/2014 1:04 PM, Timothee Cour via Digitalmars-d wrote:--- static if (true): alias A = B; --- --- static if (true) alias A = B; else: alias A = C; alias D = E; ---See email: 'with(Foo):' not allowed, why? in 'digitalmars-d-learn puremagic.com <mailto:digitalmars-d-learn puremagic.com>' forum There's already an implementation proposed.No other statement construct works like that, there doesn't seem to be much point to adding such a special case.
Aug 10 2014
"Brian Schott" wrote in message news:rvypuokvvvoeamrybnnn forum.dlang.org...--- static if (true) alias A = B; else: alias A = C; alias D = E; ---'statement'
Aug 10 2014
On Sunday, 10 August 2014 at 08:29:14 UTC, Brian Schott wrote:On Sunday, 10 August 2014 at 08:12:05 UTC, Walter Bright wrote:Stop trying to turn D into Python. It's not gonna happen.On 8/9/2014 1:04 PM, Timothee Cour via Digitalmars-d wrote:--- static if (true): alias A = B; --- --- static if (true) alias A = B; else: alias A = C; alias D = E; ---See email: 'with(Foo):' not allowed, why? in 'digitalmars-d-learn puremagic.com <mailto:digitalmars-d-learn puremagic.com>' forum There's already an implementation proposed.No other statement construct works like that, there doesn't seem to be much point to adding such a special case.
Aug 10 2014
On Sunday, 10 August 2014 at 12:34:47 UTC, Idan Arye wrote:On Sunday, 10 August 2014 at 08:29:14 UTC, Brian Schott wrote:I think you misunderstand him: The examples he gave _are_ already valid in D, he's not proposing them. They work because `static if` is an attribute.On Sunday, 10 August 2014 at 08:12:05 UTC, Walter Bright wrote:Stop trying to turn D into Python. It's not gonna happen.On 8/9/2014 1:04 PM, Timothee Cour via Digitalmars-d wrote:--- static if (true): alias A = B; --- --- static if (true) alias A = B; else: alias A = C; alias D = E; ---See email: 'with(Foo):' not allowed, why? in 'digitalmars-d-learn puremagic.com <mailto:digitalmars-d-learn puremagic.com>' forum There's already an implementation proposed.No other statement construct works like that, there doesn't seem to be much point to adding such a special case.
Aug 10 2014
On 8/10/2014 1:29 AM, Brian Schott wrote:On Sunday, 10 August 2014 at 08:12:05 UTC, Walter Bright wrote:C:\cbx>type foo.d void foo(int B, int C, int E) { static if (true) alias A = B; else: alias A = C; alias D = E; } C:\cbx>dmd -c foo foo.d(4): Error: found ':' instead of statementNo other statement construct works like that, there doesn't seem to be much point to adding such a special case.--- static if (true): alias A = B; --- --- static if (true) alias A = B; else: alias A = C; alias D = E; ---
Aug 10 2014
On Sunday, 10 August 2014 at 08:12:05 UTC, Walter Bright wrote:On 8/9/2014 1:04 PM, Timothee Cour via Digitalmars-d wrote:See email: 'with(Foo):' not allowed, why? inNo other statement construct works like that, there doesn't seem to be much point to adding such a special case.Guess it depends on the type. with(): would act a lot like private/public labels. I can see uses; Although it would mostly be to keep code cleaner rather than adding more functionality. Depends on how many pesky extra braces you want to avoid... enum Flags {a,b,c,readonly,write,etc} void func(Flags f){ switch(f) { with(Flags): //or put this outside the switch... case a: //Flags.a: case b: //Flags.b: case c: //Flags.c: case readonly: //Flags.readonly: case write: //Flags.write: } } Honestly i'd probably want to use multiple enum types at the same time, so it would be with(type1,type2,type3, etc):. This assumes it doesn't clash in the following code. However i don't NEED it to work...
Aug 10 2014
On Sunday, 10 August 2014 at 08:34:40 UTC, Era Scarecrow wrote:Depends on how many pesky extra braces you want to avoid... enum Flags {a,b,c,readonly,write,etc} void func(Flags f){ switch(f) { with(Flags): //or put this outside the switch...For that specific case, put it outside the switch and drop the colon: http://dpaste.dzfl.pl/f3e78f3265a7
Aug 10 2014
On Sunday, 10 August 2014 at 08:45:00 UTC, safety0ff wrote:For that specific case, put it outside the switch and drop the colon:True, although if you repeat having to work with the type of Foo (or Flags or something) multiple times then the with(): would let you avoid having multiple extra levels of braces. In one of my projects i recall having something like 2-3 levels of with mostly carrying around flags for various enum types and it was quite ugly. with(a) with(b) with(c){ //code } I forget, but it wasn't very pretty... And there were several functions like that, as well as static data outside of functions that needed it. I might have ended up using aliasing, but it wasn't a good solution, more a patch on the problem than a fix.
Aug 10 2014
On 8/10/14, 1:44 AM, safety0ff wrote:On Sunday, 10 August 2014 at 08:34:40 UTC, Era Scarecrow wrote:We use this idiom a lot in a project at Facebook. -- AndreiDepends on how many pesky extra braces you want to avoid... enum Flags {a,b,c,readonly,write,etc} void func(Flags f){ switch(f) { with(Flags): //or put this outside the switch...For that specific case, put it outside the switch and drop the colon: http://dpaste.dzfl.pl/f3e78f3265a7
Aug 10 2014
On Sunday, 10 August 2014 at 08:12:05 UTC, Walter Bright wrote:On 8/9/2014 1:04 PM, Timothee Cour via Digitalmars-d wrote:It's possible to add this syntax for any statement, then `with` wouldn't be a special case :-P But this wouldn't be a good idea IMO. With `if` and loops, it would hurt readability. On the other hand, `with` might be useful. It would be used similar to `using namespace` in C++, and it would (almost) always appear at the start of a scope.See email: 'with(Foo):' not allowed, why? in 'digitalmars-d-learn puremagic.com <mailto:digitalmars-d-learn puremagic.com>' forum There's already an implementation proposed.No other statement construct works like that, there doesn't seem to be much point to adding such a special case.
Aug 10 2014
On 10/08/2014 9:34 p.m., "Marc Schütz" <schuetzm gmx.net>" wrote:On Sunday, 10 August 2014 at 08:12:05 UTC, Walter Bright wrote:I've had a need before for it in the past. But I think a better idea might be: void func(MyClass clasz) with(clasz) { } If you're using with as funcdecl { with(value): with(value2): body } I'd be surprised. But its mostly for /faking/ methods outside of class.On 8/9/2014 1:04 PM, Timothee Cour via Digitalmars-d wrote:It's possible to add this syntax for any statement, then `with` wouldn't be a special case :-P But this wouldn't be a good idea IMO. With `if` and loops, it would hurt readability. On the other hand, `with` might be useful. It would be used similar to `using namespace` in C++, and it would (almost) always appear at the start of a scope.See email: 'with(Foo):' not allowed, why? in 'digitalmars-d-learn puremagic.com <mailto:digitalmars-d-learn puremagic.com>' forum There's already an implementation proposed.No other statement construct works like that, there doesn't seem to be much point to adding such a special case.
Aug 10 2014
On 8/10/2014 2:34 AM, "Marc Schütz" <schuetzm gmx.net>" wrote:It's possible to add this syntax for any statement,The reason for the : syntax for declarations is that modules can be quite long, and it: 1. avoids a lonely } that might be 3000-10,000 lines of code away 2. avoids requiring indentation of 3000-10,000 lines of code that makes change diff's harder On the other hand, functions tend to be short, and so these are not issues for statements. Furthermore, : has other meanings in statements, such as: 1. labels 2. case statements 3. default statements 4. ?: expressions and overloading this with more meanings is, in my not-so-humble-opinion, not a good idea given the very marginal benefit it might have.
Aug 10 2014
On Sunday, 10 August 2014 at 17:29:24 UTC, Walter Bright wrote:1. labels 2. case statements 3. default statements 4. ?: expressions and overloading this with more meanings is, in my not-so-humble-opinion, not a good idea given the very marginal benefit it might have.5. Access permissions (public/private/protected). 6. File length attributes ( safe: system: trusted:) But in all cases (except 4), the final symbol is the colon, and it's effect lasts for that scope unless overridden. I don't see how it would be making things all that much more complex. Unlike with templates in C++ where the <>'s were overloaded for a new (and completely unrelated) confusing purpose, the :'s use wouldn't really change, and it would remain the last symbol for it's declaration. Although I'm not sure how much it adds for complexity to the compiler (if any).
Aug 10 2014
On 08/10/2014 08:34 PM, Era Scarecrow wrote:Although I'm not sure how much it adds for complexity to the compiler (if any).It is a trivial change in the parser.
Aug 10 2014
On Sunday, 10 August 2014 at 18:56:40 UTC, Timon Gehr wrote:On 08/10/2014 08:34 PM, Era Scarecrow wrote:Then I'd say give it a try on a branch and see how it performs and some examples to show it's benefits. How does the quote go? There are some features that are complex and/or hard to use, and most of the time you won't need them. But when you really need them, you're glad you have them.Although I'm not sure how much it adds for complexity to the compiler (if any).It is a trivial change in the parser.
Aug 10 2014
On 8/10/2014 11:34 AM, Era Scarecrow wrote:On Sunday, 10 August 2014 at 17:29:24 UTC, Walter Bright wrote:Again, that is for declarations, not statements.1. labels 2. case statements 3. default statements 4. ?: expressions and overloading this with more meanings is, in my not-so-humble-opinion, not a good idea given the very marginal benefit it might have.5. Access permissions (public/private/protected). 6. File length attributes ( safe: system: trusted:)
Aug 10 2014
On Sunday, 10 August 2014 at 20:12:56 UTC, Walter Bright wrote:On 8/10/2014 11:34 AM, Era Scarecrow wrote:Does with have to be only for statements? Real example. In my code somewhere i have a large list of enum types that specify a type of formatting and visibility options. enum FlagStates { def = 0x0, //Default Value. changed = 1, ///Has changed (From original state) readOnly = 1 << 1, ///This field/subrecord/record is readonly isOriginal = 1 << 2, ///when loaded except when marked deleted/invisible invisible = 1 << 3, /// deleted = 1 << 4, /// //29 out of 32 flags are defined } next i'll have a struct that holds this as part of it's declaration... ///Details for specific parts/fields struct NotePart { ValueType type; ///type of value (string, etc. See flags.d) string id; ///specific output/identifier to print (If any) int _size; Flags flags; ///default flags used. Relies on FlagStates //etc... } alias immutable(char)[4] NString; struct SubRecordParts { NString name; ///specific subrecord NString requ; ///must be within record (or base subrecord) int size; ///how big (Helps identify, TES3 header is 300 for example. NotePart[] notes; ///Specify all the individual fields //etc } Now since i can't use with(): I'm forced to do aliases, and a lot of them... private alias NotePart NP; private alias ValueType VT; private alias FlagStates.noPrint noPrint; private alias FlagStates.noChange noChange; private alias FlagStates.hashPrint hashPrint; private alias FlagStates.noPrintClashes noPrintClashes; private alias FlagStates.noPrintNull noPrintNull; //there's at least like 200 entries in here. immutable SubRecordParts subParts[] = [ {"DATA", "INFO", 12, [ {VT.raw, "Unknown", 4, Flags(noPrint, noChange)}, {VT.i_32, "Disposition"}, {VT.i_8, "Rank"}, {VT.ranged_8, "Gender"}, {VT.i_8, "PCRank"}, {VT.raw, "Unknown", 1, Flags(noPrint, noChange)}]}, {"VHGT", "LAND", 4232, [ {VT.float_32, "Base Height"}, {VT.raw, "Height Data", 4228, Flags(noChange, noPrintClashes, hashPrint)}]}, //etc etc. This is a more verbose section than most of the rest. Most include the noPrintNull flag ]; Had i been able to use with() i could have avoided the aliases above and probably just done a single line before using it heavily. with(FlagStates, ValueType): There wouldn't have been clashing because they each hold different types of data, and it's all immutable static values anyways.5. Access permissions (public/private/protected). 6. File length attributes ( safe: system: trusted:)Again, that is for declarations, not statements.
Aug 10 2014
On 8/10/2014 2:01 PM, Era Scarecrow wrote:On Sunday, 10 August 2014 at 20:12:56 UTC, Walter Bright wrote:I'd suggest simply: private alias FlagStates FS; then use FS.def, etc.On 8/10/2014 11:34 AM, Era Scarecrow wrote:Does with have to be only for statements? Real example. In my code somewhere i have a large list of enum types that specify a type of formatting and visibility options. enum FlagStates { def = 0x0, //Default Value. changed = 1, ///Has changed (From original state) readOnly = 1 << 1, ///This field/subrecord/record is readonly isOriginal = 1 << 2, ///when loaded except when marked deleted/invisible invisible = 1 << 3, /// deleted = 1 << 4, /// //29 out of 32 flags are defined }5. Access permissions (public/private/protected). 6. File length attributes ( safe: system: trusted:)Again, that is for declarations, not statements.
Aug 10 2014
On Monday, 11 August 2014 at 00:23:36 UTC, Walter Bright wrote:I'd suggest simply: private alias FlagStates FS; then use FS.def, etc.The source code has 400 lines (955-1376) where it uses flags of one kind or another. Constantly having to add that type of thing in just fills up space without telling a lot of information. Aliasing makes it smaller, but the problem is still there. Feels like backtracking to hungarian notation. In a large bulk data I know the data type is of certain types because I need to throw them in a templated/static constructor that handles them anyways. Having to do it a second or third time just bets uselessly verbose. It's why auto is so nice where you don't have to explicitly state everything when you really don't need it to be there. It just clutters it, like 1,000 times at least... There's no mystery of what data goes where, and the enums can only enter in certain formats so having lots of (this boilerplate) code to describe what it is and where it's from. Mind you this is a public statically declared global known at compile-time... Maybe i'm hoping for too much... Original: {ValueType.raw, "Height Data", 4228, Flags(FlagStates.noChange, FlagStates.noPrintClashes, FlagStates.hashPrint)}]}, //2 shorthand aliases as you suggest, a bit better Becomes: {VT.raw, "Height Data", 4228, Flags(FS.noChange, FS.noPrintClashes, FS.hashPrint)}]}, //a dozen private aliases, only the most common that clutter code currently: {VT.raw, "Height Data", 4228, Flags(noChange, noPrintClashes, hashPrint)}]}, preferable:{raw, "Height Data", 4228, Flags(noChange, noPrintClashes, hashPrint)}]},
Aug 10 2014
On 8/10/2014 6:52 PM, Era Scarecrow wrote:On Monday, 11 August 2014 at 00:23:36 UTC, Walter Bright wrote:It's not ideal, but it gets the job done. Keep in mind that you are proposing to use withs to mix up multiple enums with lots of members - name clashes are very possible, and there's no visual clue which enum a name belongs to. It merges multiple scopes together without collision detection. I'm not so sure it is desirable. It does save some typing, but at another increase in language complexity, which has costs as well.I'd suggest simply: private alias FlagStates FS; then use FS.def, etc.The source code has 400 lines (955-1376) where it uses flags of one kind or another. Constantly having to add that type of thing in just fills up space without telling a lot of information. Aliasing makes it smaller, but the problem is still there. Feels like backtracking to hungarian notation. In a large bulk data I know the data type is of certain types because I need to throw them in a templated/static constructor that handles them anyways. Having to do it a second or third time just bets uselessly verbose. It's why auto is so nice where you don't have to explicitly state everything when you really don't need it to be there. It just clutters it, like 1,000 times at least... There's no mystery of what data goes where, and the enums can only enter in certain formats so having lots of (this boilerplate) code to describe what it is and where it's from. Mind you this is a public statically declared global known at compile-time... Maybe i'm hoping for too much... Original: {ValueType.raw, "Height Data", 4228, Flags(FlagStates.noChange, FlagStates.noPrintClashes, FlagStates.hashPrint)}]}, //2 shorthand aliases as you suggest, a bit better Becomes: {VT.raw, "Height Data", 4228, Flags(FS.noChange, FS.noPrintClashes, FS.hashPrint)}]},
Aug 10 2014
On Monday, 11 August 2014 at 06:29:55 UTC, Walter Bright wrote:It's not ideal, but it gets the job done. Keep in mind that you are proposing to use withs to mix up multiple enums with lots of members - name clashes are very possible, and there's no visual clue which enum a name belongs to. It merges multiple scopes together without collision detection. I'm not so sure it is desirable. It does save some typing, but at another increase in language complexity, which has costs as well.I suppose... Except where i'm using them is in a very controlled manner, and the likelihood of two having the same enum name is very very very low. If we assume the enums had a specific meaning for a specific field, even then it would be fairly obvious which one they came from unless they reused similar generic messages. enum FSErrors { isReadOnly, fileLocked, isNetworkFile, fileCurrupted } enum NetoworkErrors { packedDeliveryFailed, failedCRC, unreachableHost, packetSizeMismatch } enum ZlibCompressionErrors { outsideMemoryRange, crcMismatch, missingDictionary, compressionTypeMissing, unableToAllocateMemory } In most of these it's context as part of it's message type identifies what it belongs to. Regardless the enum won't transfer blindly to an incompatible one, so the failedCRC and crcMismatch are easy to fix and swap. Even if one did duplicate/shadow it, only if you actually attempted a call did you need to be more specific to resolve the conflict like you do using with(){} (or multiple chained withs) Much like gotos, the feature can easily cause major headaches, but that's if it's used incorrectly. If there's going to be lots of name clashing obviously using with is a bad choice, but for a static declaration of items that has several types in them and each type has specific fields seems like a perfect example of how to shrink and clean up code for what's very obvious, easy to look up, and follows a pattern that doesn't need a huge amount of verifying to know it's correct. For a couple lines obviously being highly verbose makes sense. But when you exceed a certain number, the verboseness just clutters the screen. Naturally including the feature could be a very bad thing in the long run, i really don't know. But there could be some good from it too. How many cases are similar to mine where with(): would be a heaven-sent? Yeah i can get around it, You can get around arrays without having the length attached to the pointer too. C's & C++ are proof it can be done! (just an example).
Aug 11 2014
On 08/10/14 23:01, Era Scarecrow via Digitalmars-d wrote:Does with have to be only for statements? Real example. In my code somewhere i have a large list of enum types that specify a type of formatting and visibility options.[...]Now since i can't use with(): I'm forced to do aliases, and a lot of them...[...]Had i been able to use with() i could have avoided the aliases above and probably just done a single line before using it heavily. with(FlagStates, ValueType): There wouldn't have been clashing because they each hold different types of data, and it's all immutable static values anyways.What you're really looking for is context dependent access to the target scope. That would work for statics and enums, but would probably require a new syntax (it becomes too misleading and/or ambiguous otherwise). Right now, you can emulate declaration-with using hacks like: enum E1 { A, B, C } enum E2 { A, B, C, D, E, F } struct S { E1 e1; E2 e2; } immutable S[] d = { with (E2) with (E1) { mixin(q{ immutable S[] r = [ { E1.A, E2.D }, { A, D }, { B, E }, { C, E2.C }, ]; return r; });}}(); Not pretty, but sometimes useful when you have a lot of such elements and/or when they are generated from DSLs. artur
Aug 11 2014
On Monday, 11 August 2014 at 12:25:52 UTC, Artur Skawina via Digitalmars-d wrote:What you're really looking for is context dependent access to the target scope. That would work for statics and enums, but would probably require a new syntax (it becomes too misleading and/or ambiguous otherwise).Not pretty, but sometimes useful when you have a lot of such elements and/or when they are generated from DSLs.I hoped i could give a relative use case for with(): that could avoid using lots of braces to get the data across without heavy verbose duplication. With the bulk static data that has to be entered manually, it quickly gets ugly that it's F.A F.B F.C F.D every few lines when you know A, B C & D's presence is enough to describe what it's doing. Honestly i can live without with():, but after it's been presented and i consider what it could mean, i can't help but want it. Yeah it's probably limited of when it's actually useful, but for static data and constants and enums that literally removes 10-20k from my source file dropping it from 60-70k to 50k or smaller, that means a lot to me.
Aug 11 2014
On Saturday, 9 August 2014 at 20:04:13 UTC, Timothee Cour via Digitalmars-d wrote:See email: 'with(Foo):' not allowed, why? in ' digitalmars-d-learn puremagic.com' forum There's already an implementation proposed.If this is going to be accepted I will most likely resort to DScanner rule that statically prohibits it, don't like such features. Even "attribute:" syntax can easily result in code obfuscation and should be used with caution - and this one is worse.
Aug 10 2014
On Sunday, 10 August 2014 at 23:16:57 UTC, Dicebot wrote:If this is going to be accepted I will most likely resort to DScanner rule that statically prohibits it, don't like such features. Even "attribute:" syntax can easily result in code obfuscation and should be used with caution - and this one is worse.Yeah i guess extra complexity for assisting tools (auto-completion and the like) need to be considered as well...
Aug 10 2014
On Sunday, 10 August 2014 at 23:29:17 UTC, Era Scarecrow wrote:On Sunday, 10 August 2014 at 23:16:57 UTC, Dicebot wrote:I did not mean that extra overhead for tools is a deal breaker - just that I don't like proposed feature itself strong enough to resort to external tools to define language subset that prohibits it, even if it gets accepted upstream.If this is going to be accepted I will most likely resort to DScanner rule that statically prohibits it, don't like such features. Even "attribute:" syntax can easily result in code obfuscation and should be used with caution - and this one is worse.Yeah i guess extra complexity for assisting tools (auto-completion and the like) need to be considered as well...
Aug 10 2014