August 04, 2005 Re: A solution to the keyword problem | ||||
---|---|---|---|---|
| ||||
Posted in reply to J C Calvarese | J C Calvarese wrote:
> I think keywords serve a purpose ("This identifier is off-limits"). It
> hurts my head to consider all of the possible pitfalls.
>
But off-limits *everywhere*? I can't have a module called 'mmedia.real.realaudio', simply because 'real' is a keyword and the parser would balk. If 'real' were a predefined identifier, this would work, and would not create a harmful redefinition of 'real'.
In my view, "This identifier is off-limits" is precisely the collateral damage *caused* by keywords, *not* their purpose. They serve to provide a set of readable punctuation marks to guide the parser, and the downside is that they are reserved in all possible contexts, whereas normal identifiers are scoped.
This is more of an issue when you consider the likely possibility that new built-in types will be added to the language in the future; if they are added as keywords, they will break existing code; but if they are added as predefined identifiers, they won't.
Yes, it's easy to laugh at silly examples where 'int' is used as a local variable of type 'char'. We could sit here all day writing dangerously misleading code, without having to propose language changes to make that possible. "alias wchar rea1;" comes to mind... You'd fill less silly, and more p-d off, if you had used 'rchar' as a perfectly good local variable name, or struct member name, and it later became a new built-in type (and a new keyword). And by the way, it's possible to redefine 'integer' in Pascal, and nobody has ever seemed to complain of their head hurting, or even notice, for that matter. They just don't do it. [Ada too, I think]. I have never once proposed that anybody should be encouraged to redefine int; in fact, this can be prohibited without making it a keyword.
There's IMHO an issue in D, arising from the fact that there are a lot of keywords; and while I believe that more than 20 of them are unnecessary (all the type names, and true/false), even if they are eliminated there will still be a problem as follows:
extern(C) int delegate( foo*p, int id ); // Can't do it!
I simply can't interface to this existing C function since its name is a D keyword. Almost 100 C identifiers are simply 'off-limits', and there is no real solution to this unless you can modify the C code.
I've previously proposed that a lexical convention be added
to escape identifiers from keyword recognition, e.g.
extern(C) int 'delegate'( foo*p, int id );
...
if( can_delegate ) 'delegate' ( foop, 0); // call C function
int 'if' = 0; 'if'++; // now possible, if you really want to.
char x = 'c'; // still a char constant if only 1 char
import commlib.'interface'.localapi; // interface is a keyword
Or, w"delegate".
This suggestion is separate from the suggestion that type names should not be keywords; either could be adopted without the other.
>
> So then we could call a method "this". Could we use the "this" of
> that method's class? :x
>
FWIW, if 'this' were converted from a D keyword to a predefined identifier, it would not be so simple, since 'this' in the class namespace would be the constructor. I don't know enough about all the details of D classes to comment further.
In C++, it would be possible to remove 'this' from the keyword table and implement as a predefined formal parameter of member funcs. And the answer to your question would be "Yes, and with no extra trouble than is already required in some cases".
It would work like this:
class CLS { // mutant C++, with 'this' not a keyword
int f1(CLS *); int f2(); int f3();
int this(); // this has no special meaning outside a mem func body
};
int CLS ::f1(CLS *f3)
// note: parameter named f3 hides CLS::f3 as per normal C++
// implicit parameter 'this' hides member 'this' in the same way
{
f2(); // member func call
this->f3(); // can't just use f3(), it's hidden by parameter
this->this(); // likewise, when calling CLS::this()
f3->this(); // call member func of other CLS object
f3->f3();
}
The call to 'CLS::this()' has the same issue, and solves it in the same way, as the call to CLS::f3. My rather convoluted point is that whatever difficulty is presented here is already present in the language and can be avoided in the same way you are already avoiding it. I.e., you probably try to avoid giving class mem func params the same name as class members, so don't go using 'this' as a member name just because you can.
But if you had some old C code that defined a struct member 'this', you wouldn't have to change that to convert it into our mutant C++, whereas with real C++, you do.
-- Greg
|
August 04, 2005 Re: A solution to the keyword problem | ||||
---|---|---|---|---|
| ||||
Posted in reply to Greg Smith | Hi, >> I think keywords serve a purpose ("This identifier is off-limits"). It hurts my head to consider all of the possible pitfalls. >> >But off-limits *everywhere*? I can't have a module called 'mmedia.real.realaudio', simply because 'real' is a keyword and the parser would balk. If 'real' were a predefined identifier, this would work, and would not create a harmful redefinition of 'real'. There are reasons for that. First of all, IMHO, it would be fairly confusing to allow such a thing. Second, what happens if you declare something like min or max in your new 'real' module: ulong m = real.max; // Is this your module's or the primitive's? >In my view, "This identifier is off-limits" is precisely the collateral damage *caused* by keywords, *not* their purpose. They serve to provide a set of readable punctuation marks to guide the parser, and the downside is that they are reserved in all possible contexts, whereas normal identifiers are scoped. Keywords are scoped too. Their scope is universal. Where, pray tell, would declaring a variable called "int" be a good idea? IMO nowhere, thus the scope of the keyword is universal for a good reason. >This is more of an issue when you consider the likely possibility that new built-in types will be added to the language in the future; if they are added as keywords, they will break existing code; but if they are added as predefined identifiers, they won't. You can't guarantee this. >Yes, it's easy to laugh at silly examples where 'int' is used as a local variable of type 'char'. We could sit here all day writing dangerously misleading code, without having to propose language changes to make that possible. One of the goals of any good language should be to reduce the possibility of writing such dangerous code. Just because you can use _other_ features to write dangerous code doesn't mean we need more such features. Two wrongs don't make a right. Declaring a variable named "int" or "char" is just plain wrong IMO. If the language prevents it, all the better. >"alias wchar rea1;" comes to mind... You'd fill less silly, and more p-d off, if you had used 'rchar' as a perfectly good local variable name, or struct member name, and it later became a new built-in type (and a new keyword). Since this is all about identifiers, you can very easily do a global search and replace. Normally, such replaces are not that simple if it's something like a string, or a construct, or what have you. But since it's an identifier, it's exceedingly simple to replace it. >And by the way, it's possible to redefine 'integer' in Pascal, and nobody has ever seemed to complain of their head hurting, or even notice, for that matter. They just don't do it. "Nobody" has ever complained? Is this a fact? "They" just don't do it? Can you guarantee this hasn't happened and caused bugs? >[Ada too, I think]. I have never once proposed that anybody should be encouraged to redefine int; in fact, this can be prohibited without making it a keyword. You are contradicting yourself here. Do you want "int" to be a valid variable name or not? If yes, then that's a bad idea. If no, then what's with all the "evidence" that this is not an abominable idea? >There's IMHO an issue in D, arising from the fact that there are a lot of keywords; and while I believe that more than 20 of them are unnecessary (all the type names, and true/false), even if they are eliminated there will still be a problem as follows: > > extern(C) int delegate( foo*p, int id ); // Can't do it! > >I simply can't interface to this existing C function since its name is a D keyword. Almost 100 C identifiers are simply 'off-limits', and there is no real solution to this unless you can modify the C code. A language has keywords. This is a fact of life. I understand your desire to reduce the number of keywords, but at what cost? I see a miniscule benefit (slightly higher compatibility with C), at a huge cost (ambiguity, Walter's time, potential for dangerous code, etc.). >I've previously proposed that a lexical convention be added to escape identifiers from keyword recognition, e.g. >This suggestion is separate from the suggestion that type names should not be keywords; either could be adopted without the other. This makes a _lot_ more sense than allowing people to name their functions "delegate". You should push for this suggestion instead. > > So then we could call a method "this". Could we use the "this" of that method's class? :x > > <snip> Allowing redefinition of "this" is insane IMO. >But if you had some old C code that defined a struct member 'this', you wouldn't have to change that to convert it into our mutant C++, whereas with real C++, you do. What about the simple suggestion to allow quoted identifiers? extern (C) 'this'(int foo); // for a function called 'this'. Cheers, --AJG. |
August 04, 2005 Re: A solution to the keyword problem | ||||
---|---|---|---|---|
| ||||
Posted in reply to Greg Smith | In article <dctfjq$gs3$1@digitaldaemon.com>, Greg Smith says... > >J C Calvarese wrote: > > >> I think keywords serve a purpose ("This identifier is off-limits"). It hurts my head to consider all of the possible pitfalls. >> >But off-limits *everywhere*? I can't have a module called 'mmedia.real.realaudio', simply because 'real' is a keyword and the parser would balk. If 'real' were a predefined identifier, this would work, and would not create a harmful redefinition of 'real'. It'd be nice if module names were more flexible, but all of kinds of practical effects of such a naming would either have to be specifically prohibited by the compiler or the programmer would have to watch out for any clashes (see my "real.max" discussion below). I think Walter has decided it's easier just to prohibit the name altogether and make it a keyword than come up with more complex rules about what happens to be barely allowed and barely disallowed. (You can compile a module "int.module.import.real.typeof.3d", but if you try to import it, you computer will crash.) >In my view, "This identifier is off-limits" is precisely the collateral damage *caused* by keywords, *not* their purpose. They serve to provide a set of readable punctuation marks to guide the parser, and the downside is that they are reserved in all possible contexts, whereas normal identifiers are scoped. Well, I'm not sure about the whole cause-and-effect issue, but the reality is we have to program with the allowable syntax of the language. If we want the benefit of having the functionality provided by a keyword, we can't use it an identifier, too. >This is more of an issue when you consider the likely possibility that new built-in types will be added to the language in the future; if they are added as keywords, they will break existing code; but if they are added as predefined identifiers, they won't. > >Yes, it's easy to laugh at silly examples where 'int' is used as a local variable of type 'char'. We could sit here all day writing dangerously misleading code, without having to propose language changes to make that I'm not trying to be humorous. I'm exploring the possible ramifications of your proposal. It's not a matter to be taken lightly. I'm getting a vibe from your many lengthy posts that you think this is definitely the way to go, but I see many downsides and not much (if any) upside. Throwing away all of those all-so-pesky rules would have real consequences. Even opening up module names could allow all kinds of disturbing code. If you have a module called real what would happen if you had a function called max. These days "real.max" means "largest representable value that's not infinity for a real type". Isn't it ambiguous with a "real.max" function thrown into the mix? >possible. "alias wchar rea1;" comes to mind... You'd fill less silly, Don't change the subject. ;) >and more p-d off, if you had used 'rchar' as a perfectly good local variable name, or struct member name, and it later became a new built-in type (and a new keyword). And by the way, it's possible to redefine I think Walter would agree that adding a new keyword after 1.0 is established would only be done after significant deliberation. That's why cent (signed 128 bits) and ucent (unsigned 128 bits) are already reserved for future use even though it's unclear when they'll be implemented. >'integer' in Pascal, and nobody has ever seemed to complain of their head hurting, or even notice, for that matter. They just don't do it. [Ada too, I think]. I have never once proposed that anybody should be encouraged to redefine int; in fact, this can be prohibited without making it a keyword. So why does it matter it's not technically a "keyword" if we should prohibit this anyway. >There's IMHO an issue in D, arising from the fact that there are a lot of keywords; and while I believe that more than 20 of them are unnecessary (all the type names, and true/false), even if they are eliminated there will still be a problem as follows: The true and false keywords are a different situation than the types, but I can see a reason to make them keywords: to compel consistancy. If they aren't keywords, one programmer can say "true = 0" and another can say "false = 99". If everyone got creative with defining their own true and false, it'd be that must harder to understand someone else's code. Someone can use True and False (or TRUE and FALSE) if a need arises. > > extern(C) int delegate( foo*p, int id ); // Can't do it! > >I simply can't interface to this existing C function since its name is a D keyword. Almost 100 C identifiers are simply 'off-limits', and there is no real solution to this unless you can modify the C code. Are they commonly used? (No hypotheticals, how often have you seen these actually used?) >I've previously proposed that a lexical convention be added to escape identifiers from keyword recognition, e.g. > > extern(C) int 'delegate'( foo*p, int id ); > > ... > if( can_delegate ) 'delegate' ( foop, 0); // call C function > > int 'if' = 0; 'if'++; // now possible, if you really want to. > char x = 'c'; // still a char constant if only 1 char > > import commlib.'interface'.localapi; // interface is a keyword > >Or, w"delegate". > >This suggestion is separate from the suggestion that type names should not be keywords; either could be adopted without the other. This is a whole other argument. I don't see a problem with this except that apostrophes are already used for character literals. I guess they could be reused here, but it might be worth it to use another symbol. Could we go to Unicode for a purpose such as this? > > So then we could call a method "this". Could we use the "this" of that method's class? :x > > >FWIW, if 'this' were converted from a D keyword to a predefined identifier, it would not be so simple, since 'this' in the class namespace would be the constructor. I don't know enough about all the details of D classes to comment further. I agree with this. Well, it seems we still mostly disagree and I don't expect you to suddenly agree with me on everything, so maybe we should just agree to disagree. jcc7 |
August 04, 2005 Re: A solution to the keyword problem | ||||
---|---|---|---|---|
| ||||
Posted in reply to AJG | AJG wrote: > Hi, > > >>>I think keywords serve a purpose ("This identifier is off-limits"). It >>>hurts my head to consider all of the possible pitfalls. >>> >> >>But off-limits *everywhere*? I can't have a module called 'mmedia.real.realaudio', simply because 'real' is a keyword and the parser would balk. If 'real' were a predefined identifier, this would work, and would not create a harmful redefinition of 'real'. > > > There are reasons for that. First of all, IMHO, it would be fairly confusing to > allow such a thing. Second, what happens if you declare something like min or > max in your new 'real' module: > > ulong m = real.max; // Is this your module's or the primitive's? > What's wrong with import mmedia.real.realaudio; ulong m = real.max; // Existing real ulong m2 = mmedia.real.realaudio.max; // from module or just "m2=max;", as I understand import to work. I have not redefined real in the global scope. This is what scopes are for. It's not confusing to *allow* something, what's confusing is what people do with it. Do you think this change is going to turn D from something in which no confusing code is possible into something which is a morass of unavoidable confusion? > >>In my view, "This identifier is off-limits" is precisely the collateral damage *caused* by keywords, *not* their purpose. They serve to provide a set of readable punctuation marks to guide the parser, and the downside is that they are reserved in all possible contexts, whereas normal identifiers are scoped. > > > Keywords are scoped too. Their scope is universal. Where, pray tell, would > declaring a variable called "int" be a good idea? IMO nowhere, thus the scope of > the keyword is universal for a good reason. > A keyword is actually scoped more universally than a variable. You can't do version(keyword){}, or extern(keyword) int foo();, whereas normal identifers can be used in those contexts without being defined or even mentioned anywhere else; and even if they are mentioned in other contexts there is no connection between a version tag 'xyz' and a language identifier (type, variable, etc) 'xyz'. I can't see how using version(real){ } version(emulation){ } ... should be particularly harmful. And again, it's not the existing keywords that are the issue, it's the new ones that will be defined later. > >>This is more of an issue when you consider the likely possibility that new built-in types will be added to the language in the future; if they are added as keywords, they will break existing code; but if they are added as predefined identifiers, they won't. > > > You can't guarantee this. > I think you can, for practical purposes. The user definition of the name will hide the predefined definition. This is what scoping was designed to do; to allow local namespaces to be protected from changes to global namespaces. > > >>Yes, it's easy to laugh at silly examples where 'int' is used as a local variable of type 'char'. We could sit here all day writing dangerously misleading code, without having to propose language changes to make that possible. > > > One of the goals of any good language should be to reduce the possibility of > writing such dangerous code. Just because you can use _other_ features to write > dangerous code doesn't mean we need more such features. Two wrongs don't make a > right. Declaring a variable named "int" or "char" is just plain wrong IMO. If > the language prevents it, all the better. > The *only* argument you are making is that this change adds the ability to do a few additional confusing things. Therefore it shouldn't be done, despite the benefits. That doesn't wash. Besides, you can still make it illegal to redefine 'int'. > > >>"alias wchar rea1;" comes to mind... You'd fill less silly, and more p-d off, if you had used 'rchar' as a perfectly good local variable name, or struct member name, and it later became a new built-in type (and a new keyword). > > > You are contradicting yourself here. Do you want "int" to be a valid variable > name or not? If yes, then that's a bad idea. If no, then what's with all the > "evidence" that this is not an abominable idea? I DON'T CARE if you can redefine int or not. I DON'T CARE. I would never do it. It's a very bad idea to redefine it. But if the language lets it be done, the language will still work. I have no evidence that it would be useful to redefine 'int'. I have presented evidence that it would be useful to redefine *less* *central* type names, which may not have even been in existence at the time you wrote your code. If you want it to be illegal to redefine int, you can *still* make int a predefined identifier, not a keyword, and make it illegal to redefine it, in whatever contexts you think it might be harmful, including all of them. I'm not going to repeat all the reasons why this is different from int being a keyword, you can go check out the other thread "Why are type names keywords". If you insist on using 'int' as an example and fail to recognize that the language has both a past (C code compatiblity) and a future (possible new types to be added) to deal with, then I am sure you will never understand my point. You seem to be assuming that keywords can never conflict with identifiers in any troublesome way. It would be great if that were true. Here's a worst-case scenario: (1) I have code like this: import commlib.rchar.api; (2) 'rchar' becomes a new type and a new keyword. (3) I have to change all my code, renaming 'rchar' to, say, 'rrchar'; and worse, my directory structure (possibly throwing my version control into havoc), then modify the build scripts, and rebuild the libraries. If the library came as object code from a 3rd party, I'm skunked, I need to get a new build of it with a different name, because I can't link with the old unless I can use 'rchar' as an identifier. If, on the other hand: (2a) 'rchar' becomes a new type and a new predefined identifier (3a) I don't have to do anything. (4a) At my leisure, I could rename things to avoid confusion. It could be a lot of work, since I'd have to rename the directories and possibly change the build scripts for the module. If I think the effort is worth it, I'll do it. But I'm not forced to do it. I don't know what else I can stay. Please stop talking about redefining 'int'. >>I've previously proposed that a lexical convention be added >>to escape identifiers from keyword recognition, e.g. > > >>This suggestion is separate from the suggestion that type names should not be keywords; either could be adopted without the other. > > > This makes a _lot_ more sense than allowing people to name their functions > "delegate". You should push for this suggestion instead. > Actually, I *am* exactly proposing that people be allowed to name their functions "delegate". I'm just proposing a method of doing it despite the presence of a keyword "delegate". Note that foo() and 'foo'() ...would be identical. This suggestion provides a method of dealing with keyword conflicts; the other suggestion reduces the likelihood of them happening in the first place. In the worst-case scenario discussed above, with import commlib.rchar.api; ... and 'rchar' becoming a new keyword, I wouldn't be nearly as screwed if I could use this quote thing. I would still need to edit the source, but I could keep the directory name. I could continue to use the 3rd-party compiled library. > >>>So then we could call a method "this". Could we use the "this" of >>>that method's class? :x >>> > > <snip> > > Allowing redefinition of "this" is insane IMO. > I agree that it's no huge improvement. 'Insane', no. In fact, 'this' in C++ (not D) is a perfect example of something that doesn't need to be a keyword. It is *only* meaningful in contexts where a member function parameter has scope, and has exactly the same grammar treatment as an identifier. Nothing is gained by making it a keyword. In D the 'this' keyword is doing more work, in constructor declarations, etc, so the situation is different. > >>But if you had some old C code that defined a struct member 'this', you wouldn't have to change that to convert it into our mutant C++, whereas with real C++, you do. > > > What about the simple suggestion to allow quoted identifiers? > > extern (C) 'this'(int foo); // for a function called 'this'. > I was discussing converting old C source code into C++, not linking old C code to D. If C++ 'this' were *not* a keyword, I wouldn't need to change any 'this' identifiers in the C code, since none of them could conflict with the C++ meaning. This is not a hypothetical example, by the way - I've run into this exact case. - Greg |
August 04, 2005 Re: A solution to the keyword problem | ||||
---|---|---|---|---|
| ||||
Posted in reply to Greg Smith | Hi, >>>>I think keywords serve a purpose ("This identifier is off-limits"). It hurts my head to consider all of the possible pitfalls. >>>> >>> >>>But off-limits *everywhere*? I can't have a module called 'mmedia.real.realaudio', simply because 'real' is a keyword and the parser would balk. If 'real' were a predefined identifier, this would work, and would not create a harmful redefinition of 'real'. >> >> >> There are reasons for that. First of all, IMHO, it would be fairly confusing to allow such a thing. Second, what happens if you declare something like min or max in your new 'real' module: >> >> ulong m = real.max; // Is this your module's or the primitive's? >> >What's wrong with > >import mmedia.real.realaudio; > >ulong m = real.max; // Existing real >ulong m2 = mmedia.real.realaudio.max; // from module My example did not use "realaudio.max," but rather "real.max." There's the difference. Do you not see a problem with that usage? >or just "m2=max;", as I understand import to work. I have not redefined real in the global scope. > >This is what scopes are for. > >It's not confusing to *allow* something, what's confusing is what people do with it. Do you think this change is going to turn D from something in which no confusing code is possible into something which is a morass of unavoidable confusion? No. Mere introduction of the "feature" would unlikely break havoc immediately. What I mean is that it creates the potential for confusion. In addition, the feature has _very_ _little_ _benefit_. In other words, it is not worth introducing the great potential for confusion for such a miniscule gain in functionality. The juice is not worth the squeeze. On the other hand, let me present to you another such potentially-abused feature: goto. Now, some will say goto is the source of all evil, but for all its evil, goto is a very powerful tool. So in that respect it is different, thus D allows goto. >> Keywords are scoped too. Their scope is universal. Where, pray tell, would declaring a variable called "int" be a good idea? IMO nowhere, thus the scope of the keyword is universal for a good reason. >A keyword is actually scoped more universally than a variable. You can't >do version(keyword){}, or extern(keyword) int foo();, whereas normal >identifers can be used in those contexts without being defined or even >mentioned anywhere else; and even if they are mentioned in other >contexts there is no connection between a version tag 'xyz' and a >language identifier (type, variable, etc) 'xyz'. > >I can't see how using > > version(real){ } > version(emulation){ } > >... should be particularly harmful. Well, this is all relative. Would it cause great physical harm to the user? Unlikely. Will it create confusion? Yes. If a user only knows the D language and sees: version (real) what is he supposed to think? It kinda looks like "use this version if D is compiled with real number support." Or perhaps "use this version if you want real number precision." >And again, it's not the existing keywords that are the issue, it's the new ones that will be defined later. Frankly, I don't see a flood of new primitive types and keywords. I'd speculate maybe a couple per year, since Walter likes to reuse his keywords. That's just a risk you're gonna have to take. Btw, perhaps you shouldn't be naming your things so close to already existing keywords. There's char, there's dchar, there's wchar. It doesn't take a genius to figure out the naming convention here. Therefore it also doesn't take a genius to figure out that rchar is particularly prone. Also, here's another quick tip: keywords in D are all lowercase. Hint, hint. >>>This is more of an issue when you consider the likely possibility that new built-in types will be added to the language in the future; if they are added as keywords, they will break existing code; but if they are added as predefined identifiers, they won't. >> You can't guarantee this. > > >I think you can, for practical purposes. The user definition of the name will hide the predefined definition. This is what scoping was designed to do; to allow local namespaces to be protected from changes to global namespaces. Hm... actually, it's the other way around. The purpose is to protect the global namespace from the local ones. A local namespace cannot override the global one: int x; { float x; //IIRC, error. } If a mere variable is prevented from redefinition, I think it's safe to say a predefined type/identifier/keyword would be too. And for good reason. I wouldn't want subtle redefinitions to happen in my code without so much as a warning. >The *only* argument you are making is that this change adds the ability to do a few additional confusing things. Therefore it shouldn't be done, despite the benefits. That doesn't wash. Besides, you can still make it illegal to redefine 'int'. No. You seem to ignore the costs of your little operation: it would probably take valuable time to implement. It would require complex scoping rules to be created. In addition to the potential for abuse. Moreover, what doesn't wash is that all that work is not worth it. The quotes proposal already takes care of that at a fraction of the cost. >If you want it to be illegal to redefine int, you can *still* make int a predefined identifier, not a keyword, and make it illegal to redefine it, in whatever contexts you think it might be harmful, including all of them. I'm not going to repeat all the reasons why this is different from int being a keyword, you can go check out the other thread "Why are type names keywords". So then you need to introduce complex scoping rules for predefined identifiers just so you can use language keywords in certain special scopes were they are not meaningful. Does this makes sense over a simple "no use" rule across the language? >If you insist on using 'int' as an example and fail to recognize that the language has both a past (C code compatiblity) D does not have C code compatibility. It would be hazardous to your mental health to keep believing that. If you fail to recognize that then you should work on it. >and a future (possible new types to be added) to deal with, then I am sure you will never understand my point. I understand your point very well, I just don't happen to agree with it. >>>This suggestion is separate from the suggestion that type names should not be keywords; either could be adopted without the other. >> >> This makes a _lot_ more sense than allowing people to name their functions "delegate". You should push for this suggestion instead. >> >Actually, I *am* exactly proposing that people be allowed to name their functions "delegate". I'm just proposing a method of doing it despite the presence of a keyword "delegate". Note that > foo() and 'foo'() >...would be identical. Well, no they wouldn't (if foo were a keyword), because you'd have to always use quotes to accesss foo. In other words, it's almost as if the quotes became part of the identifier and they were taken off only for C-compat. >This suggestion provides a method of dealing with keyword conflicts; the other suggestion reduces the likelihood of them happening in the first place. > >In the worst-case scenario discussed above, with > import commlib.rchar.api; >... and 'rchar' becoming a new keyword, I wouldn't be nearly as screwed >if I could use this quote thing. I would still need to edit the source, >but I could keep the directory name. I could continue to use the >3rd-party compiled library. I have already said that the quote suggestion is valid, and would (at little cost) bring about the benefit you suggest. That's what makes the feature good: It's a small cost. >> Allowing redefinition of "this" is insane IMO. >> >I agree that it's no huge improvement. 'Insane', no. In fact, 'this' in >C++ (not D) is a perfect example of something that doesn't need to be a >keyword. >It is *only* meaningful in contexts where a member function parameter >has scope, and has exactly the same grammar treatment as an identifier. >Nothing is gained by making it a keyword. >In D the 'this' keyword is doing more work, in constructor declarations, >etc, so the situation is different. Unfortunately, D is not C++ and in D, this has almost universal meaning. In fact, at the base scope (module-level, I assume), 'this' is relevant, due to static ctors/dtors. My suggestion that redefining 'this' is insane applies to D, not C++, or I would have said so. Since apparently you didn't like my redefining int that much, let me propose redefining this then ;) I suppose you would have no problem with the following: # module this; # this() { # version (this) { # debug (this) { # int this; # } # } # } Nope, no confusion in sight. >>>But if you had some old C code that defined a struct member 'this', you wouldn't have to change that to convert it into our mutant C++, whereas with real C++, you do. >> >> >> What about the simple suggestion to allow quoted identifiers? >> >> extern (C) 'this'(int foo); // for a function called 'this'. >> > >I was discussing converting old C source code into C++, not linking old C code to D. If C++ 'this' were *not* a keyword, I wouldn't need to change any 'this' identifiers in the C code, since none of them could conflict with the C++ meaning. If you are converting old C code to D chances are you are already doing some heavy lifting. I don't think ONE additional global search and replace will be particularly troublesome. Furthermore, with the quotes proposal the problem would be even less relevant. Finally, what is with all this C compat glorification? D is not C. D is not a superset of C. D already breaks all sorts of things that prevent C-code compat. Relatively speaking, the keywords are very small issue compared to the other things. Creating all sorts of complex keyword/predefined-identifier scoping rules just so you can have your almighty 'this' structure in C is horribly misguided, IMHO. Cheers, --AJG. |
August 04, 2005 Re: A solution to the keyword problem | ||||
---|---|---|---|---|
| ||||
Posted in reply to AJG | On Thu, 4 Aug 2005 21:00:29 +0000 (UTC), AJG wrote: [snip] > int x; > { > float x; //IIRC, error. > } Actually, this is only an error at the module level. The code below is quite okay ... void main() { int x; { float x; // okay } } This too is alright ... void x() { int x; { float x; //Okay too. } } [snip] > Unfortunately, D is not C++ LOL. And I think exactly the opposite. Thank Bob that D is not like C++! My take on this issue is that if people want to write stupid and confusing code, then they should be allowed to. They might not stay employed for very long in any of my teams but that's natural selection at work. -- Derek Parnell Melbourne, Australia 5/08/2005 7:26:30 AM |
August 05, 2005 Re: A solution to the keyword problem | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Hi, >[snip] > >> int x; >> { >> float x; //IIRC, error. >> } > >Actually, this is only an error at the module level. The code below is quite okay ... That's certainly not what the docs say...: "A block statement introduces a new scope for local symbols. A local symbol's name, however, must be unique within the function." http://www.digitalmars.com/d/statement.html The examples there contradict yours. I don't have a compiler at hand, though, so I can't say. I prefer what the docs say, frankly. >[snip] > >> Unfortunately, D is not C++ > >LOL. And I think exactly the opposite. Thank Bob that D is not like C++! Thank Bob indeed. You knew I was going for the sarcastic effect! ;) >My take on this issue is that if people want to write stupid and confusing code, then they should be allowed to. They might not stay employed for very long in any of my teams but that's natural selection at work. I don't agree. This kind of "remedial" attitude is no good. What we need (just like in real life) is preventative care. Take a proactive approach so that things don't become fatal. Having been assigned "maintenance" duties on occasion, I can say the ones burned ("skunked," to quote Greg) are not generally the original doofuses but the subsequent maintainers. <often quoted possibly completely wrong statistic> <take this with a grain of salt> Around 80% of the total cost of software is not the original development. </take this with a grain of salt> </often quoted possibly completely wrong statistic> Cheers, --AJG. |
August 05, 2005 Re: A solution to the keyword problem | ||||
---|---|---|---|---|
| ||||
Posted in reply to AJG | AJG wrote: >>> >>>ulong m = real.max; // Is this your module's or the primitive's? >>> > > My example did not use "realaudio.max," but rather "real.max." There's the > difference. Do you not see a problem with that usage? > Yes, you can construct cases where there is confusion. This does not change the fact that there are useful implications. > > No. Mere introduction of the "feature" would unlikely break havoc immediately. > What I mean is that it creates the potential for confusion. > Same comment. > > In addition, the feature has _very_ _little_ _benefit_. In other words, it is > not worth introducing the great potential for confusion for such a miniscule > gain in functionality. The juice is not worth the squeeze. We'll have to agree to differ on that. I keep bringing up C++, not because I'm confusing D with C++, but because, more than once, I've been bitten by C++ adding new keywords (either relative to C, or to its own former self). > > Well, this is all relative. Would it cause great physical harm to the user? > Unlikely. Will it create confusion? Yes. > > If a user only knows the D language and sees: > > version (real) > > what is he supposed to think? It kinda looks like "use this version if D is > compiled with real number support." Or perhaps "use this version if you want > real number precision." > Or you could read the manual. The relevant page is a google and about 3 clicks away :-). I had no idea at all how 'version' worked until I read the manual. > >>And again, it's not the existing keywords that are the issue, it's the new ones that will be defined later. > > > Frankly, I don't see a flood of new primitive types and keywords. I'd speculate > maybe a couple per year, since Walter likes to reuse his keywords. That's just a > risk you're gonna have to take. Btw, perhaps you shouldn't be naming your things > so close to already existing keywords. I had trouble with C++, at a much lower rate of keyword growth. > > There's char, there's dchar, there's wchar. It doesn't take a genius to figure > out the naming convention here. Therefore it also doesn't take a genius to > figure out that rchar is particularly prone. Also, here's another quick tip: > keywords in D are all lowercase. Hint, hint. > Right. But the problems I had with C++ were with code others had written. If you have full control over all of the code you work with, none of this matters nearly as much. Lucky you. I don't intend to stop using local variable names consisting entirely of lowercase letters. And, the set of likely new type names is (a) not quite as predictable as that and (b) not utterly disjoint from the set of likely names for local vars, parameter names, and member names, all of which are lowercase by many coding conventions. > ... >>I think you can, for practical purposes. The user definition of the name will hide the predefined definition. This is what scoping was designed to do; to allow local namespaces to be protected from changes to global namespaces. > > > Hm... actually, it's the other way around. The purpose is to protect the global > namespace from the local ones. A local namespace cannot override the global one: > > int x; > { > float x; //IIRC, error. > } I think you are mistaken, or just being evasive. I remember seeing something about how a D local isn't allowed to hide a local in an enclosing scope,which is fine; but a local variable *can* hide a global. I just tried it. I agree there is a risk of a global namespace being affected by modifications to the local namespace, but the effect of that is contained to the locality of the change, so it's reasonable to expect that to be addressed by diligence (and via variable naming conventions). > > If a mere variable is prevented from redefinition, I think it's safe to say a > predefined type/identifier/keyword would be too. And for good reason. I wouldn't > want subtle redefinitions to happen in my code without so much as a warning. > flawed premise, see above. The main point is, if you are redefining the new built-in type 'rchar', you are doing it because it wasn't there when you wrote the code. So, you want the new 'rchar' type to be hidden in all places where the user's 'rchar' is in scope. Which is what the existing scope rules do already. > >>The *only* argument you are making is that this change adds the ability to do a few additional confusing things. Therefore it shouldn't be done, despite the benefits. That doesn't wash. Besides, you can still make it illegal to redefine 'int'. > > > No. You seem to ignore the costs of your little operation: it would probably > take valuable time to implement. It would require complex scoping rules to be > created. In addition to the potential for abuse. > IMHO not as bad as you think, and will never be any easier to implement than now. D already has a bunch of predefined identifiers (Object, max, nan, infinity, sizeof...) - does that bother you? > >>If you want it to be illegal to redefine int, you can *still* make int a predefined identifier, not a keyword, and make it illegal to redefine it, in whatever contexts you think it might be harmful, including all of them. I'm not going to repeat all the reasons why this is different from int being a keyword, you can go check out the other thread "Why are type names keywords". > > > So then you need to introduce complex scoping rules for predefined identifiers > just so you can use language keywords in certain special scopes were they are > not meaningful. Does this makes sense over a simple "no use" rule across the > language? > The existing scope rules are fine. The 'no use' rule has the problems I have mentioned, it's not future-proof. > > >>If you insist on using 'int' as an example and fail to recognize that the language has both a past (C code compatiblity) > > > D does not have C code compatibility. It would be hazardous to your mental > health to keep believing that. If you fail to recognize that then you should > work on it. You can link to external C code. This is what I meant. This compatibility is degraded by having too many keywords. > > >>>>This suggestion is separate from the suggestion that type names should not be keywords; either could be adopted without the other. >>> >>>This makes a _lot_ more sense than allowing people to name their functions >>>"delegate". You should push for this suggestion instead. >>> >>Actually, I *am* exactly proposing that people be allowed to name their functions "delegate". I'm just proposing a method of doing it despite the presence of a keyword "delegate". Note that >> foo() and 'foo'() >>...would be identical. > > > Well, no they wouldn't (if foo were a keyword), because you'd have to always use > quotes to accesss foo. In other words, it's almost as if the quotes became part > of the identifier and they were taken off only for C-compat. > I'm just saying that by declaring " int 'delegate'(), you are naming a function "delegate", plain and simple. You said 'this makes more sense than allowing people to name their functions "delegate"' . I found that statement very confusing and hoped to clarify things. I see now what you were getting at; but I have never proposed removal of any keywords other than those which are manifestly unnecessary for parsing; 'delegate' isn't in that list. >>>Allowing redefinition of "this" is insane IMO. >>> >> >>I agree that it's no huge improvement. 'Insane', no. In fact, 'this' in C++ (not D) is a perfect example of something that doesn't need to be a keyword. >>It is *only* meaningful in contexts where a member function parameter has scope, and has exactly the same grammar treatment as an identifier. Nothing is gained by making it a keyword. >>In D the 'this' keyword is doing more work, in constructor declarations, etc, so the situation is different. > > Unfortunately, D is not C++ and in D, this has almost universal meaning. In > fact, at the base scope (module-level, I assume), 'this' is relevant, due to > static ctors/dtors. > > My suggestion that redefining 'this' is insane applies to D, not C++, or I would > have said so. Since apparently you didn't like my redefining int that much, let > me propose redefining this then ;) well that caused me a lot of confusion since I explicitly said I was talking about removing keyword 'this' in C++ and not D. The parallel is that 'wchar' in D, like 'this' in C++, and 'Object' in D, doesn't actually need to be a keyword. Of these three, only 'Object' has the benefit of being a predefined identifier rather than a keyword. > > I suppose you would have no problem with the following: > > # module this; > # this() { > # version (this) { > # debug (this) { > # int this; > # } > # } > # } > > Nope, no confusion in sight. Do you have a problem with # # module wombat; # import wiffle; # # wombat( wiffle.wombat w) { # version (wombat) { # debug (wombat) { # int wombat = w.wombat; # } # } # } ... because I think that's perfectly legal, and isn't any less confusing. Construct all the confusing examples you like. > > >>>>But if you had some old C code that defined a struct member 'this', you wouldn't have to change that to convert it into our mutant C++, whereas with real C++, you do. >>> >>> >>>What about the simple suggestion to allow quoted identifiers? >>> >>>extern (C) 'this'(int foo); // for a function called 'this'. >>> >> >>I was discussing converting old C source code into C++, not linking old C code to D. If C++ 'this' were *not* a keyword, I wouldn't need to change any 'this' identifiers in the C code, since none of them could conflict with the C++ meaning. > > > If you are converting old C code to D chances are you are already doing some > heavy lifting. Again, I'm not talking about converting C to D; I'm talking about the general effects of adding new keywords. The task of converting C source to C++ is just a real world example of where these effects show up. They will also show up if/when new keywords are added to D. -Greg |
August 05, 2005 Re: A solution to the keyword problem | ||||
---|---|---|---|---|
| ||||
Posted in reply to AJG | On Fri, 5 Aug 2005 00:01:30 +0000 (UTC), AJG wrote: > Hi, > >>[snip] >> >>> int x; >>> { >>> float x; //IIRC, error. >>> } >> >>Actually, this is only an error at the module level. The code below is quite okay ... > > That's certainly not what the docs say...: > > "A block statement introduces a new scope for local symbols. A local symbol's name, however, must be unique within the function." > > http://www.digitalmars.com/d/statement.html > > The examples there contradict yours. I don't have a compiler at hand, though, so I can't say. I prefer what the docs say, frankly. Yes, I knew about the docs, but I believe Walter has said that the docs are wrong in this case. The compiler does compile the examples I gave and this is the intended behaviour. I just can't find the Walter-quote right now. >>My take on this issue is that if people want to write stupid and confusing code, then they should be allowed to. They might not stay employed for very long in any of my teams but that's natural selection at work. > > I don't agree. This kind of "remedial" attitude is no good. What we need (just like in real life) is preventative care. Take a proactive approach so that things don't become fatal. > > Having been assigned "maintenance" duties on occasion, I can say the ones burned ("skunked," to quote Greg) are not generally the original doofuses but the subsequent maintainers. Yes, I can understand this. We have defined coding standards here and all code is peer-reviewed and non-standard code is identified and corrected before being allowed to go out into the world. But under more common development methodologies, I can understand that you'd like to have a mechanized method of enforcing coding decency - i.e. the compiler. > <often quoted possibly completely wrong statistic> > <take this with a grain of salt> > Around 80% of the total cost of software is not the original development. > </take this with a grain of salt> > </often quoted possibly completely wrong statistic> I think I heard once that 94.37% of all statistics are misused, and the remaining 84.12% are actually a bit suspect too. -- Derek Parnell Melbourne, Australia Download BUILD from ... http://www.dsource.org/projects/build/ v2.08 released 29/May/2005 http://www.prowiki.org/wiki4d/wiki.cgi?FrontPage 5/08/2005 11:04:09 AM |
August 05, 2005 Re: A solution to the keyword problem | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | In article <1l0oh1ebg8svr.13hqjnzi2kbus$.dlg@40tude.net>, Derek Parnell says... > >On Fri, 5 Aug 2005 00:01:30 +0000 (UTC), AJG wrote: > .. >> <often quoted possibly completely wrong statistic> >> <take this with a grain of salt> >> Around 80% of the total cost of software is not the original development. >> </take this with a grain of salt> >> </often quoted possibly completely wrong statistic> > >I think I heard once that 94.37% of all statistics are misused, and the remaining 84.12% are actually a bit suspect too. 8 out of 10 statistics are completely made up. ;) jcc7 |
Copyright © 1999-2021 by the D Language Foundation