digitalmars.D - allMembers broke for __
- DigitalDesigns (6/6) Jun 15 2018 When an identifier starts with __, allMembers does not return it.
- Jonathan M Davis (5/11) Jun 15 2018 I would point out that identifiers that start with two underscores are
- rikki cattermole (6/20) Jun 15 2018 We discussed this on IRC yesterday.
- DigitalDesigns (6/19) Jun 16 2018 So, you are saying that it's ok to beat me over the head and
- Jonathan M Davis (16/38) Jun 16 2018 There's no need to be melodramatic. All I'm saying is that identifiers
- DigitalDesigns (20/64) Jun 16 2018 If this was a sane language constraint then any identifiers
- Adam D. Ruppe (3/7) Jun 16 2018 It is undefined behavior to use ANY identifier with __ leading. C
- angel (11/18) Jun 17 2018 I'm sure there are naive C programmers who use "__" prefix for
- Jonathan M Davis (42/111) Jun 16 2018 Identifiers that start with two underscores should be very uncommon, bec...
- Walter Bright (6/9) Jun 17 2018 It's not a bug, it's quite deliberate:
- DigitalDesigns (11/23) Jun 17 2018 If you don't want me to use it then why not give an error instead
- Russel Winder (13/19) Jun 18 2018 In delegates I have found I have to use _ and __ (and ___, ____, etc.,bu...
- bauss (8/23) Jun 18 2018 Well you can use identifiers that uses __, but certain names that
- Steven Schveighoffer (8/31) Jun 18 2018 For names that won't be used, it doesn't matter what the name is. In
- Timon Gehr (2/18) Jun 18 2018 The code you linked to does it. :)
- Walter Bright (2/3) Jun 18 2018 I know. But it shouldn't. Do as I say, not as I do :-)
- Steven Schveighoffer (7/11) Jun 18 2018 I don't see how you misuse the symbols.
- DigitalDesigns (30/43) Jun 18 2018 The complaint is not that, the complaint is that when one does
- Steven Schveighoffer (14/62) Jun 19 2018 This is pretty similar to what I said, but I misunderstood that your
- dayllenger (6/7) Jun 26 2018 Done:
- aliak (6/18) Jun 18 2018 Holy cyclomatic complexity batman!
- Walter Bright (2/3) Jun 19 2018 No, it's to be callable from the 3 non-D back ends.
When an identifier starts with __, allMembers does not return it. This is very bad behavior! It can silently create huge problems if the programmer is not aware of the bug. Instead, if you want to keep the current behavior at least create an error or warning rather than silently create a bug to waste the users time tracking it down.
Jun 15 2018
On Saturday, June 16, 2018 06:08:17 DigitalDesigns via Digitalmars-d wrote:When an identifier starts with __, allMembers does not return it. This is very bad behavior! It can silently create huge problems if the programmer is not aware of the bug. Instead, if you want to keep the current behavior at least create an error or warning rather than silently create a bug to waste the users time tracking it down.I would point out that identifiers that start with two underscores are supposed to be reserved for the compiler. Declaring them yourself is begging for trouble in general. - Jonathan M Davis
Jun 15 2018
On 16/06/2018 6:47 PM, Jonathan M Davis wrote:On Saturday, June 16, 2018 06:08:17 DigitalDesigns via Digitalmars-d wrote:We discussed this on IRC yesterday. What we decided that we thought was correct was to emit a warning if __* was used for an identifier outside of core.*. But make things like allMembers not check for it. Simple, but effective.When an identifier starts with __, allMembers does not return it. This is very bad behavior! It can silently create huge problems if the programmer is not aware of the bug. Instead, if you want to keep the current behavior at least create an error or warning rather than silently create a bug to waste the users time tracking it down.I would point out that identifiers that start with two underscores are supposed to be reserved for the compiler. Declaring them yourself is begging for trouble in general. - Jonathan M Davis
Jun 15 2018
On Saturday, 16 June 2018 at 06:47:59 UTC, Jonathan M Davis wrote:On Saturday, June 16, 2018 06:08:17 DigitalDesigns via Digitalmars-d wrote:So, you are saying that it's ok to beat me over the head and cause me trouble simply because I used __? Seriously? I thought D was all about making the programmers life easier and not more difficult! Thanks for letting me know! I guess it's time to goWhen an identifier starts with __, allMembers does not return it. This is very bad behavior! It can silently create huge problems if the programmer is not aware of the bug. Instead, if you want to keep the current behavior at least create an error or warning rather than silently create a bug to waste the users time tracking it down.I would point out that identifiers that start with two underscores are supposed to be reserved for the compiler. Declaring them yourself is begging for trouble in general. - Jonathan M Davis
Jun 16 2018
On Saturday, June 16, 2018 22:59:24 DigitalDesigns via Digitalmars-d wrote:On Saturday, 16 June 2018 at 06:47:59 UTC, Jonathan M Davis wrote:There's no need to be melodramatic. All I'm saying is that identifiers starting with __ are reserved by the language - just like they are in many though I don't know for sure if they are). Whether __traits stuff should ignore such attributes, I don't know (I wouldn't have expected them to be ignored, and that does seem weird), but either way, if you have any variable names that start with two underscores (be they member variables or local variables or whatever), you're potentially declaring variables that are in conflict with stuff that druntime or the compiler itself declare, and you risk bugs by doing so. Even if __traits shouldn't just ignore those identifiers, you shouldn't be declaring any variables that start with two underscores. If you didn't know that before, then I'm sorry, but the spec mentions it, and now you know. https://dlang.org/spec/lex.html#identifiers - Jonathan M DavisOn Saturday, June 16, 2018 06:08:17 DigitalDesigns via Digitalmars-d wrote:So, you are saying that it's ok to beat me over the head and cause me trouble simply because I used __? Seriously? I thought D was all about making the programmers life easier and not more difficult! Thanks for letting me know! I guess it's time to goWhen an identifier starts with __, allMembers does not return it. This is very bad behavior! It can silently create huge problems if the programmer is not aware of the bug. Instead, if you want to keep the current behavior at least create an error or warning rather than silently create a bug to waste the users time tracking it down.I would point out that identifiers that start with two underscores are supposed to be reserved for the compiler. Declaring them yourself is begging for trouble in general. - Jonathan M Davis
Jun 16 2018
On Saturday, 16 June 2018 at 23:33:13 UTC, Jonathan M Davis wrote:On Saturday, June 16, 2018 22:59:24 DigitalDesigns via Digitalmars-d wrote:If this was a sane language constraint then any identifiers starting with __ that were not reserved would at least give a warning but particularly give an error! Not fail silently and break code in ways that cannot be determined otherwise. It's bad enough that the whole template system cannot be properly debugged but to silently ignore user identities that start with __ just because is ignorant, and it's not being melodramatic. I've seen you state several times that D does certain things to "protect" the user... and now you are justifying it attacking the user. You can't have it both ways, which is it? __ is not an uncommon identifier prefix and to reserve it then have code break in ways that are nearly undetectable and could cause major bugs in complex programs is not sane. How about reserve a special character for special identifiers and do a full rename on the master branch and simply do away with the arbitrary __ constraint? There are correct ways to solve the problem and incorrect. Justifying incorrect ways when they are clearly incorrect is not sane(but it is typical practice).On Saturday, 16 June 2018 at 06:47:59 UTC, Jonathan M Davis wrote:There's no need to be melodramatic. All I'm saying is that identifiers starting with __ are reserved by the language - just like they are in many C-derived languages (I would expect if they are). Whether __traits stuff should ignore such attributes, I don't know (I wouldn't have expected them to be ignored, and that does seem weird), but either way, if you have any variable names that start with two underscores (be they member variables or local variables or whatever), you're potentially declaring variables that are in conflict with stuff that druntime or the compiler itself declare, and you risk bugs by doing so. Even if __traits shouldn't just ignore those identifiers, you shouldn't be declaring any variables that start with two underscores. If you didn't know that before, then I'm sorry, but the spec mentions it, and now you know. https://dlang.org/spec/lex.html#identifiers - Jonathan M DavisOn Saturday, June 16, 2018 06:08:17 DigitalDesigns via Digitalmars-d wrote:So, you are saying that it's ok to beat me over the head and cause me trouble simply because I used __? Seriously? I thought D was all about making the programmers life easier and not more difficult! Thanks for letting me know! I guess it'sWhen an identifier starts with __, allMembers does not return it. This is very bad behavior! It can silently create huge problems if the programmer is not aware of the bug. Instead, if you want to keep the current behavior at least create an error or warning rather than silently create a bug to waste the users time tracking it down.I would point out that identifiers that start with two underscores are supposed to be reserved for the compiler. Declaring them yourself is begging for trouble in general. - Jonathan M Davis
Jun 16 2018
On Sunday, 17 June 2018 at 01:02:17 UTC, DigitalDesigns wrote:If this was a sane language constraint then any identifiers starting with __ that were not reserved would at least give a warning but particularly give an error! Not fail silently and break code in ways that cannot be determined otherwise.It is undefined behavior to use ANY identifier with __ leading. C works exactly the same way.
Jun 16 2018
On Sunday, 17 June 2018 at 02:25:59 UTC, Adam D. Ruppe wrote:On Sunday, 17 June 2018 at 01:02:17 UTC, DigitalDesigns wrote:I'm sure there are naive C programmers who use "__" prefix for their own purposes. Maybe it would be cleaner to create more special syntax for "internal" functions/methods, e.g require some kind of UDA in addition to the "__" prefix: Dinternal void __someMethod() ... Then disallow "__" prefix altogether (with the exception above). Now, if someone still uses both the UDA and the prefix, he really cannot say he didn't know.If this was a sane language constraint then any identifiers starting with __ that were not reserved would at least give a warning but particularly give an error! Not fail silently and break code in ways that cannot be determined otherwise.It is undefined behavior to use ANY identifier with __ leading. C works exactly the same way.
Jun 17 2018
On Sunday, June 17, 2018 01:02:17 DigitalDesigns via Digitalmars-d wrote:On Saturday, 16 June 2018 at 23:33:13 UTC, Jonathan M Davis wrote:Identifiers that start with two underscores should be very uncommon, because they're usually reserved in C-derived languages (though for better or worse, most such languages don't actually flag them as errors even though they're technically illegal). There's really nothing unique about D in that respect. I suspect the reason that it's not a compiler error in D to start an identifier with two underscores is because it would make it a pain for druntime, because - being the runtime for the language - there are a number of identifiers that it declares which start with two underscores, and if the compiler tried to make that an error in general, it would either have to know all of the identifiers that druntime used or somehow know that it was compiling druntime (and at least some of those identifiers are extern(C) so that they're not mangled based on the module they're in, making detecting that something is part of druntime more complicated). It also may be that it needs to be possible to declare identifiers that start with two underscores in order to link against code from C's runtime. I don't know. I don't disagree that it would be nice if the compiler made it an error if anyone tries to do that in their program, but given how that would affect druntime, I'm not sure how reasonable that really would be in practice even if it really should happen in principle. And in practice, programs that have identifiers that start with two underscores should be pretty rare anyway. Outside of something like druntime or the compiler, I don't think that I've ever seen it. So, I honestly would have expected this to be a completely theoretical problem, though clearly, you weren't aware that identifiers that start with two underscores are typically reserved by the language and used them anyway and ran into problems as a result, so apparently, the problem isn't completely theoretical. I do expect it to be pretty uncommon though. Regardless, unless there's a reasonable way to have the compiler detect when it's druntime that's declaring the variable that starts with two underscores, it's going to be difficult to make it an error for anyone doing it outside of druntime, and I have no clue how easy that is to do. It could be that there are technical hurdles that prevent it, and it could be simply that it was going to be enough of a pain that no one bothered on the principle that it was highly unlikely to come up in practice. I don't know. Feel free to create a bug report for it, and maybe the compiler can be improved to actually treat it as illegal in the cases where it should be illegal while letting druntime do its thing. Now, whether __traits should be ignoring identifiers that start with two underscores is another matter entirely, and I have no idea why that's happening, but no user code should be being written that has identifiers that start with two underscores (and that's far from unique to D). - Jonathan M DavisOn Saturday, June 16, 2018 22:59:24 DigitalDesigns via Digitalmars-d wrote:If this was a sane language constraint then any identifiers starting with __ that were not reserved would at least give a warning but particularly give an error! Not fail silently and break code in ways that cannot be determined otherwise. It's bad enough that the whole template system cannot be properly debugged but to silently ignore user identities that start with __ just because is ignorant, and it's not being melodramatic. I've seen you state several times that D does certain things to "protect" the user... and now you are justifying it attacking the user. You can't have it both ways, which is it? __ is not an uncommon identifier prefix and to reserve it then have code break in ways that are nearly undetectable and could cause major bugs in complex programs is not sane. How about reserve a special character for special identifiers and do a full rename on the master branch and simply do away with the arbitrary __ constraint? There are correct ways to solve the problem and incorrect. Justifying incorrect ways when they are clearly incorrect is not sane(but it is typical practice).On Saturday, 16 June 2018 at 06:47:59 UTC, Jonathan M Davis wrote:There's no need to be melodramatic. All I'm saying is that identifiers starting with __ are reserved by the language - just like they are in many C-derived languages (I would expect if they are). Whether __traits stuff should ignore such attributes, I don't know (I wouldn't have expected them to be ignored, and that does seem weird), but either way, if you have any variable names that start with two underscores (be they member variables or local variables or whatever), you're potentially declaring variables that are in conflict with stuff that druntime or the compiler itself declare, and you risk bugs by doing so. Even if __traits shouldn't just ignore those identifiers, you shouldn't be declaring any variables that start with two underscores. If you didn't know that before, then I'm sorry, but the spec mentions it, and now you know. https://dlang.org/spec/lex.html#identifiers - Jonathan M DavisOn Saturday, June 16, 2018 06:08:17 DigitalDesigns via Digitalmars-d wrote:So, you are saying that it's ok to beat me over the head and cause me trouble simply because I used __? Seriously? I thought D was all about making the programmers life easier and not more difficult! Thanks for letting me know! I guess it'sWhen an identifier starts with __, allMembers does not return it. This is very bad behavior! It can silently create huge problems if the programmer is not aware of the bug. Instead, if you want to keep the current behavior at least create an error or warning rather than silently create a bug to waste the users time tracking it down.I would point out that identifiers that start with two underscores are supposed to be reserved for the compiler. Declaring them yourself is begging for trouble in general. - Jonathan M Davis
Jun 16 2018
On 6/15/2018 11:08 PM, DigitalDesigns wrote:When an identifier starts with __, allMembers does not return it. This is very bad behavior! It can silently create huge problems if the programmer is not aware of the bug.It's not a bug, it's quite deliberate: https://github.com/dlang/dmd/blob/master/src/dmd/traits.d#L1385 Identifiers starting with __ are reserved for the implementation: https://dlang.org/spec/lex.html#identifiers They have implementation-defined behavior. Do not use them in user code.
Jun 17 2018
On Sunday, 17 June 2018 at 22:55:57 UTC, Walter Bright wrote:On 6/15/2018 11:08 PM, DigitalDesigns wrote:If you don't want me to use it then why not give an error instead of punishing me by introducing very difficult bugs to detect? Do you really think that everyone that starts using D will automatically know the traps of __ and avoid it like the plague just because you said so(even though they probably never actually seen you say it)? How about instead of __, you guys use ____ in your code? That would be more sane than breaking my code because I used an extra _. Again, you can justify all you want... it doesn't make it right.When an identifier starts with __, allMembers does not return it. This is very bad behavior! It can silently create huge problems if the programmer is not aware of the bug.It's not a bug, it's quite deliberate: https://github.com/dlang/dmd/blob/master/src/dmd/traits.d#L1385 Identifiers starting with __ are reserved for the implementation: https://dlang.org/spec/lex.html#identifiers They have implementation-defined behavior. Do not use them in user code.
Jun 17 2018
On Sun, 2018-06-17 at 15:55 -0700, Walter Bright via Digitalmars-d wrote:=20[=E2=80=A6]Identifiers starting with __ are reserved for the implementation: =20 https://dlang.org/spec/lex.html#identifiers =20 They have implementation-defined behavior. Do not use them in user code.In delegates I have found I have to use _ and __ (and ___, ____, etc.,but I have only had to use two to date) for delegate parameters that are to be unused and unnamed. Are these treated differently because they are all underscores? --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Dr Russel Winder t: +44 20 7585 2200 41 Buckmaster Road m: +44 7770 465 077 London SW11 1EN, UK w: www.russel.org.uk
Jun 18 2018
On Monday, 18 June 2018 at 08:25:46 UTC, Russel Winder wrote:On Sun, 2018-06-17 at 15:55 -0700, Walter Bright via Digitalmars-d wrote:Well you can use identifiers that uses __, but certain names that uses __ as a prefix will have implementation defined behavior. I guess for parameters that are strictly __ etc. they're just behaving "normal" because there are no implementation behavior for said identifiers and thus defaults to "normal behavior". I also guess it's mostly an issue with function names, field names etc. and not really paramters, but I could be wrong.[…]Identifiers starting with __ are reserved for the implementation: https://dlang.org/spec/lex.html#identifiers They have implementation-defined behavior. Do not use them in user code.In delegates I have found I have to use _ and __ (and ___, ____, etc.,but I have only had to use two to date) for delegate parameters that are to be unused and unnamed. Are these treated differently because they are all underscores?
Jun 18 2018
On 6/18/18 12:57 PM, bauss wrote:On Monday, 18 June 2018 at 08:25:46 UTC, Russel Winder wrote:You can just not give them names.On Sun, 2018-06-17 at 15:55 -0700, Walter Bright via Digitalmars-d wrote:[…]Identifiers starting with __ are reserved for the implementation: https://dlang.org/spec/lex.html#identifiers They have implementation-defined behavior. Do not use them in user code.In delegates I have found I have to use _ and __ (and ___, ____, etc.,but I have only had to use two to date) for delegate parameters that are to be unused and unnamed. Are these treated differently because they are all underscores?Well you can use identifiers that uses __, but certain names that uses __ as a prefix will have implementation defined behavior. I guess for parameters that are strictly __ etc. they're just behaving "normal" because there are no implementation behavior for said identifiers and thus defaults to "normal behavior". I also guess it's mostly an issue with function names, field names etc. and not really paramters, but I could be wrong.For names that won't be used, it doesn't matter what the name is. In some languages, the single underscore symbol is reserved for names that won't be used. So when porting to D, perhaps there is the case where you might feel they need other non-standard names. However, in this case, D does not require names, so it's a moot point. -Steve
Jun 18 2018
On 18.06.2018 00:55, Walter Bright wrote:On 6/15/2018 11:08 PM, DigitalDesigns wrote:The code you linked to does it. :)When an identifier starts with __, allMembers does not return it. This is very bad behavior! It can silently create huge problems if the programmer is not aware of the bug.It's not a bug, it's quite deliberate: https://github.com/dlang/dmd/blob/master/src/dmd/traits.d#L1385 Identifiers starting with __ are reserved for the implementation: https://dlang.org/spec/lex.html#identifiers They have implementation-defined behavior. Do not use them in user code.
Jun 18 2018
On 6/18/2018 3:54 AM, Timon Gehr wrote:The code you linked to does it. :)I know. But it shouldn't. Do as I say, not as I do :-)
Jun 18 2018
On 6/18/18 5:27 PM, Walter Bright wrote:On 6/18/2018 3:54 AM, Timon Gehr wrote:I don't see how you misuse the symbols. I think it's more that you shouldn't *define* these symbols, not that you can't use the language-defined symbols in the intended way. The complaint here is that they are treated differently from normal symbols. The answer is, they are special, so don't assume they aren't. -SteveThe code you linked to does it. :)I know. But it shouldn't. Do as I say, not as I do :-)
Jun 18 2018
On Monday, 18 June 2018 at 21:47:01 UTC, Steven Schveighoffer wrote:On 6/18/18 5:27 PM, Walter Bright wrote:The complaint is not that, the complaint is that when one does use these symbols, which they are allowed to use because the compiler permits it, then __traits hides those symbols instead of returning them. This means if one uses such a symbol name then template code can silently fail to work as intended and there is no way to determine the problem except know that the leading __ is causing it. This type of behavior would rarely be suspect causing the programmer to waste many hours trying to figure out the problem. In some cases the bug may never be solved and occur rarely and in production. The compiler/traits is treating identifiers that begin with __ differently than those that done but they should be treated uniformly the same since technically __ in front of an identifier does not change anything. struct X { int __a = 0; int a = 0; } are totally different with respect to allMembers when few would expect it to be so except. What I'm saying is that if you guys don't want users to use __ then make it an error! That simple. You can allow it in internal code and phobos but restrict it in user code, it's really that simple... or fix traits to return those values. It would be better to let the users check if they want to process them or not instead of doing it internally and potential breaking code.On 6/18/2018 3:54 AM, Timon Gehr wrote:I don't see how you misuse the symbols. I think it's more that you shouldn't *define* these symbols, not that you can't use the language-defined symbols in the intended way. The complaint here is that they are treated differently from normal symbols. The answer is, they are special, so don't assume they aren't. -SteveThe code you linked to does it. :)I know. But it shouldn't. Do as I say, not as I do :-)
Jun 18 2018
On 6/19/18 2:23 AM, DigitalDesigns wrote:On Monday, 18 June 2018 at 21:47:01 UTC, Steven Schveighoffer wrote:This is pretty similar to what I said, but I misunderstood that your beef is not with the fact that __symbols are special, but that the compiler let's mere mortals use them. Which is a good point.On 6/18/18 5:27 PM, Walter Bright wrote:The complaint is not that, the complaint is that when one does use these symbols, which they are allowed to use because the compiler permits it, then __traits hides those symbols instead of returning them.On 6/18/2018 3:54 AM, Timon Gehr wrote:I don't see how you misuse the symbols. I think it's more that you shouldn't *define* these symbols, not that you can't use the language-defined symbols in the intended way. The complaint here is that they are treated differently from normal symbols. The answer is, they are special, so don't assume they aren't.The code you linked to does it. :)I know. But it shouldn't. Do as I say, not as I do :-)This means if one uses such a symbol name then template code can silently fail to work as intended and there is no way to determine the problem except know that the leading __ is causing it. This type of behavior would rarely be suspect causing the programmer to waste many hours trying to figure out the problem. In some cases the bug may never be solved and occur rarely and in production. The compiler/traits is treating identifiers that begin with __ differently than those that done but they should be treated uniformly the same since technically __ in front of an identifier does not change anything.There are a few things in D like this, for example operator overloads. They are normal functions but add compiler recognition for some things. One of the things I'm concerned about with this is that people may (ab)use this knowledge to add "hidden" pieces to structs on purpose.struct X { int __a = 0; int a = 0; } are totally different with respect to allMembers when few would expect it to be so except. What I'm saying is that if you guys don't want users to use __ then make it an error! That simple. You can allow it in internal code and phobos but restrict it in user code, it's really that simple... or fix traits to return those values. It would be better to let the users check if they want to process them or not instead of doing it internally and potential breaking code.This is a pretty reasonable request, and it makes sense. It could be done pretty simply -- if a type is defined with __someSymbol and it's not in std, core, or rt, give an error. If we are reserving these symbols for the language, there's no reason to not enforce that requirement. I'd recommend putting in an enhancement request in bugzilla. -Steve
Jun 19 2018
On Tuesday, 19 June 2018 at 12:59:00 UTC, Steven Schveighoffer wrote:I'd recommend putting in an enhancement request in bugzilla.Done: https://issues.dlang.org/show_bug.cgi?id=19028 Really, this behaviour at least should be reflected in `allMembers` and `derivedMembers` documentation.
Jun 26 2018
On Sunday, 17 June 2018 at 22:55:57 UTC, Walter Bright wrote:On 6/15/2018 11:08 PM, DigitalDesigns wrote:Holy cyclomatic complexity batman! Is the extern(C++) on semanticTraits remnants from converting dmd to d? Cheers - AliWhen an identifier starts with __, allMembers does not return it. This is very bad behavior! It can silently create huge problems if the programmer is not aware of the bug.It's not a bug, it's quite deliberate: https://github.com/dlang/dmd/blob/master/src/dmd/traits.d#L1385 Identifiers starting with __ are reserved for the implementation: https://dlang.org/spec/lex.html#identifiers They have implementation-defined behavior. Do not use them in user code.
Jun 18 2018
On 6/18/2018 11:42 PM, aliak wrote:Is the extern(C++) on semanticTraits remnants from converting dmd to d?No, it's to be callable from the 3 non-D back ends.
Jun 19 2018