www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - const int vs. int const

reply "John" <john.joyus gmail.com> writes:
This may be a silly issue, but I recently read the better 
practice is to begin with the variable type followed by const 
keyword, but that order doesn't work in D. Is that intentional?

   int const minWage = 11; //Error: no identifier for declarator 
int
   //const int minWage = 11; //works
Aug 15 2014
next sibling parent reply "Sean Kelly" <sean invisibleduck.org> writes:
On Friday, 15 August 2014 at 17:05:55 UTC, John wrote:
 This may be a silly issue, but I recently read the better 
 practice is to begin with the variable type followed by const 
 keyword, but that order doesn't work in D. Is that intentional?

   int const minWage = 11; //Error: no identifier for declarator 
 int
   //const int minWage = 11; //works
It is intentional, and I think this "best practice" idea doesn't apply to D in the same was as C/C++. The reason this is an issue in C/C++ is because "const char *" is equivalent to "char const *", but once typedefs and templates enter the picture things start to get confusing. Since D allows the const qualifier to use parens to specify what part of the type it applies to, we don't need to support the C style syntax.
Aug 15 2014
parent "John" <john.joyus gmail.com> writes:
On Friday, 15 August 2014 at 17:16:45 UTC, Sean Kelly wrote:
 On Friday, 15 August 2014 at 17:05:55 UTC, John wrote:
 This may be a silly issue, but I recently read the better 
 practice is to begin with the variable type followed by const 
 keyword, but that order doesn't work in D. Is that intentional?

  int const minWage = 11; //Error: no identifier for declarator 
 int
  //const int minWage = 11; //works
It is intentional, and I think this "best practice" idea doesn't apply to D in the same was as C/C++. The reason this is an issue in C/C++ is because "const char *" is equivalent to "char const *", but once typedefs and templates enter the picture things start to get confusing. Since D allows the const qualifier to use parens to specify what part of the type it applies to, we don't need to support the C style syntax.
Ok, thanks for reply.
Aug 15 2014
prev sibling next sibling parent reply "John" <john.joyus gmail.com> writes:
On Friday, 15 August 2014 at 17:05:55 UTC, John wrote:
 This may be a silly issue, but I recently read the better 
 practice is to begin with the variable type followed by const 
 keyword, but that order doesn't work in D. Is that intentional?

   int const minWage = 11; //Error: no identifier for declarator 
 int
   //const int minWage = 11; //works
btw, it works either way if I use auto auto const minWage = 11; //works const auto minWage = 11; //works The same flexibility is missing when the actual type is used.
Aug 15 2014
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 08/15/2014 07:18 PM, John wrote:
 btw, it works either way if I use auto

 auto const minWage = 11; //works
 const auto minWage = 11; //works
 ...
auto does not serve any purpose here.
 The same flexibility is missing when the actual type is used.
In particular, auto is not a wild-card type in that example. const minWage = 11;
Aug 15 2014
parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, 15 August 2014 at 18:23:47 UTC, Timon Gehr wrote:
 On 08/15/2014 07:18 PM, John wrote:
 btw, it works either way if I use auto

 auto const minWage = 11; //works
 const auto minWage = 11; //works
 ...
auto does not serve any purpose here.
 The same flexibility is missing when the actual type is used.
In particular, auto is not a wild-card type in that example. const minWage = 11;
Yeah, aside from auto ref, auto is pretty much just a placeholder when you don't want to put the type. Arguably, it shouldn't be allowed when attributes like const or static are used, but it is unfortunately allowed and essentially ignored in those cases. Much as it first seems like auto tells the compiler to infer the type, the reality of the matter is that the compiler will infer the type unless you tell it the type and that auto is just for the cases where you don't want to use attributes and you need to indicate that you're declaring a variable rather than doing an assignment. - Jonathan M Davis
Aug 15 2014
prev sibling parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Fri, Aug 15, 2014 at 05:05:53PM +0000, John via Digitalmars-d wrote:
 This may be a silly issue, but I recently read the better practice is
 to begin with the variable type followed by const keyword, but that
 order doesn't work in D. Is that intentional?
 
   int const minWage = 11; //Error: no identifier for declarator int
   //const int minWage = 11; //works
Nah, the better practice is to write const(int) instead of const int, which is ambiguous when used to specify a function's return value. For example, const int func(); is *not* the same as: const(int) func(); which can be quite a nasty surprise for the unwary. My personal practice is to always write const(int) everywhere, thus eliminating the ambiguity. T -- "No, John. I want formats that are actually useful, rather than over-featured megaliths that address all questions by piling on ridiculous internal links in forms which are hideously over-complex." -- Simon St. Laurent on xml-dev
Aug 15 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 8/15/2014 10:45 AM, H. S. Teoh via Digitalmars-d wrote:
 Nah, the better practice is to write const(int) instead of const int,
 which is ambiguous when used to specify a function's return value.

 For example,

 	const int func();

 is *not* the same as:

 	const(int) func();

 which can be quite a nasty surprise for the unwary. My personal practice
 is to always write const(int) everywhere, thus eliminating the
 ambiguity.
const without parentheses is a 'storage class'. const with parentheses is a 'type constructor'. Storage classes apply to the symbol being declared, and hence the type of the symbol. Type constructors apply to the type in the ( ). It is not ambiguous from a semantic or syntactic point of view, but it appears to be ambiguous for those coming from C++. This was discussed at length a few years ago, but no solution emerged that didn't make things much worse.
Aug 15 2014
next sibling parent reply "eles" <eles215 gzk.dot> writes:
On Friday, 15 August 2014 at 18:47:49 UTC, Walter Bright wrote:
 On 8/15/2014 10:45 AM, H. S. Teoh via Digitalmars-d wrote:
 It is not ambiguous from a semantic or syntactic point of view, 
 but it appears to be ambiguous for those coming from C++. This
I like this example from the C world: http://stackoverflow.com/a/5503661/1284631 But, I agree, I am a follower of the rule: const is written after and applies to everything that comes left of it.
Aug 15 2014
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 8/15/2014 12:06 PM, eles wrote:
 But, I agree, I am a follower of the rule:

 const is written after and applies to everything that comes left of it.
That rule can never work for D. Remember, D's const is transitive.
Aug 15 2014
parent "eles" <eles eles.com> writes:
On Friday, 15 August 2014 at 19:14:10 UTC, Walter Bright wrote:
 On 8/15/2014 12:06 PM, eles wrote:
 That rule can never work for D. Remember, D's const is 
 transitive.
Thank you. I was aware. I was speaking about my C-style.
Aug 15 2014
prev sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, 15 August 2014 at 18:47:49 UTC, Walter Bright wrote:
 It is not ambiguous from a semantic or syntactic point of view, 
 but it appears to be ambiguous for those coming from C++. This 
 was discussed at length a few years ago, but no solution 
 emerged that didn't make things much worse.
I still think that we'd be far better off if all attributes which could apply to a function's return type were illegal on the left-hand side of the function. All allowing it on the left does is cause confusion and bugs. It's already best practice to put it those attributes on the right, because if you don't, everyone who reads the code ends up asking whether the attribute was supposed to apply to the return type, and the parens were forgotten, or whether it was supposed to apply to the function. It was my understanding that the whole reason that attributes like const or immutable are allowed on the left-hand side is because all of the attributes are allowed on both sides, and it would be inconsistent to not allow const on the left. But as it turns out, several aren't allowed on the right - https://issues.dlang.org/show_bug.cgi?id=12930 - making what we have already inconsistent - and since it's bad practice to put it on the left anyway, I think that it's well worth it to have the inconsistency of not allowing const, immutable, inout, or shared on the left-hand side. It would cost us pretty much nothing and will just avoid confusion and bugs. And IMHO, the fact that we're _already_ inconsistent with where the attributes can go makes it so that the argument that const should be allowed on the left for constistency's sake isn't particularly valid. https://issues.dlang.org/show_bug.cgi?id=12931 - Jonathan M Davis
Aug 15 2014
next sibling parent ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Fri, 15 Aug 2014 21:08:08 +0000
Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 I still think that we'd be far better off if all attributes which=20
 could apply to a function's return type were illegal on the=20
 left-hand side of the function.
i completely agree. even if this change will break some code, i'm still sure that it should be done. i'm constantly beaten by writing 'const FooBar func()' (ah, pun unintended ;-) and i can't understant why compiler is silent about it, while it can tell me that '1 > 0 must be parenthesized when next to operator &' in 'if (a&1 > 0)'. please, make compiler emit at least warning about 'stray const/immutable/etc'! and then deprecate it, and then make compiler emit error.
Aug 15 2014
prev sibling next sibling parent "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Fri, Aug 15, 2014 at 09:08:08PM +0000, Jonathan M Davis via Digitalmars-d
wrote:
 On Friday, 15 August 2014 at 18:47:49 UTC, Walter Bright wrote:
It is not ambiguous from a semantic or syntactic point of view, but
it appears to be ambiguous for those coming from C++. This was
discussed at length a few years ago, but no solution emerged that
didn't make things much worse.
I still think that we'd be far better off if all attributes which could apply to a function's return type were illegal on the left-hand side of the function. All allowing it on the left does is cause confusion and bugs. It's already best practice to put it those attributes on the right, because if you don't, everyone who reads the code ends up asking whether the attribute was supposed to apply to the return type, and the parens were forgotten, or whether it was supposed to apply to the function.
+1. T -- Be in denial for long enough, and one day you'll deny yourself of things you wish you hadn't.
Aug 15 2014
prev sibling parent reply "Mike" <none none.com> writes:
On Friday, 15 August 2014 at 21:08:10 UTC, Jonathan M Davis wrote:
 I still think that we'd be far better off if all attributes 
 which could apply to a function's return type were illegal on 
 the left-hand side of the function. All allowing it on the left 
 does is cause confusion and bugs. It's already best practice to 
 put it those attributes on the right, because if you don't, 
 everyone who reads the code ends up asking whether the 
 attribute was supposed to apply to the return type, and the 
 parens were forgotten, or whether it was supposed to apply to 
 the function.
Sounds like a worthwhile impromement to me. Mike
Aug 15 2014
parent reply Jacob Carlborg <doob me.com> writes:
On 2014-08-16 01:33, Mike wrote:

 Sounds like a worthwhile impromement to me.
Sounds like a breaking change to me. Which will include the usual complains. -- /Jacob Carlborg
Aug 16 2014
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 8/16/2014 11:50 AM, Jacob Carlborg wrote:
 On 2014-08-16 01:33, Mike wrote:

 Sounds like a worthwhile impromement to me.
Sounds like a breaking change to me. Which will include the usual complains.
Yes, and for this case it is not worth it.
Aug 16 2014
next sibling parent reply "Fool" <fool dlang.org> writes:
On Saturday, 16 August 2014 at 19:23:48 UTC, Walter Bright wrote:
 Yes, and for this case it is not worth it.
This shows one more time that D needs a tool (similar to gofix) that allows automatic conversion of source code compatible with version x to code compatible with version x + 1.
Aug 16 2014
parent "Mike" <none none.com> writes:
On Saturday, 16 August 2014 at 19:43:36 UTC, Fool wrote:
 On Saturday, 16 August 2014 at 19:23:48 UTC, Walter Bright 
 wrote:
 Yes, and for this case it is not worth it.
This shows one more time that D needs a tool (similar to gofix) that allows automatic conversion of source code compatible with version x to code compatible with version x + 1.
I agree, but it's going to take you, I, or another motivated individual to build it. It's existence might help influence the attitude towards breaking changes. I'm considering working on it, embarking on yet another tangent of my tangent. A good start would be to create a utility in the https://github.com/D-Programming-Language/tools, and add the ability to change `alias existingSymbol newSymbol` to 'alias newSymbol = existingSymbol`. With this in place, it could set a precedent for adding more language upgrades. Brian, if you have this code (or a start) in your short-term memory, please share. The D gatekeepers could help by putting some (non)verbal support behind such a tool. Mike
Aug 16 2014
prev sibling next sibling parent "Mike" <none none.com> writes:
On Saturday, 16 August 2014 at 19:23:48 UTC, Walter Bright wrote:
 On 8/16/2014 11:50 AM, Jacob Carlborg wrote:
 On 2014-08-16 01:33, Mike wrote:

 Sounds like a worthwhile impromement to me.
Sounds like a breaking change to me. Which will include the usual complains.
Yes, and for this case it is not worth it.
It is worth it. There are going to be consequences either way. However, if it is addressed, the consequences on one side will be temporary. Not addressing it will ensure the consequences on the other side remain indefinitely. Following a well-managed, gradual, deprecation procedure will make the change tolerable. Mike
Aug 16 2014
prev sibling parent ketmar via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Sat, 16 Aug 2014 12:23:49 -0700
Walter Bright via Digitalmars-d <digitalmars-d puremagic.com> wrote:

 Yes, and for this case it is not worth it.
it worth it. we can fix alot of such things while our userbase is relatively small. we will be doomed to live with this legacy when userbase becomes huge. heh, i know the language which suffers from the legacy: C++. if i want C++, i know where to download the compiler. ;-)
Aug 16 2014
prev sibling next sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Saturday, 16 August 2014 at 18:50:08 UTC, Jacob Carlborg wrote:
 On 2014-08-16 01:33, Mike wrote:

 Sounds like a worthwhile impromement to me.
Sounds like a breaking change to me. Which will include the usual complains.
Yes, but it's either that or have people running into this problem and complaining about it and the bugs that it causes for years to come. And it's _already_ bad practice to put const, immutable, inout, or shared on the left-hand side without parens, and pretty much everyone has run into the problem at one time or another when trying to return const from a function and would know to avoid putting those atributes on the left. So, the vast majority of code wouldn't be affected. And of course, we'd do it via deprecation, so it wouldn't immediately break code. So, yes, I can see why "it's a breaking change" would be given as a reason not to do it, but given that this is a definite wart in the language that is consistently giving problems to D newbies and just outright avoided by D veterans, most code that would be affected is probably wrong anyway, and it's not a feature that's at all desirable to have, so I _definitely_ think that the change is worth it. Certainly, I would want to know every line of code that I have that has any of these attributes no the left-hand side of a function without parens, because that would mean that there's a bug in my code that I didn't catch. - Jonathan M Davis
Aug 16 2014
parent "Francesco Cattoglio" <francesco.cattoglio gmail.com> writes:
On Saturday, 16 August 2014 at 21:42:59 UTC, Jonathan M Davis 
wrote:
 On Saturday, 16 August 2014 at 18:50:08 UTC, Jacob Carlborg 
 wrote:
 On 2014-08-16 01:33, Mike wrote:

 Sounds like a worthwhile impromement to me.
Sounds like a breaking change to me. Which will include the usual complains.
Yes, but it's either that or have people running into this problem and complaining about it and the bugs that it causes for years to come. And it's _already_ bad practice to put const, immutable, inout, or shared on the left-hand side without parens, and pretty much everyone has run into the problem at one time or another when trying to return const from a function and would know to avoid putting those atributes on the left. So, the vast majority of code wouldn't be affected. And of course, we'd do it via deprecation, so it wouldn't immediately break code.
For what it is worth, I can confirm this bit me and a coworker of mine. Deprecation of this makes sense. IIRC there's a bunch of C valid code that are rejected by dmd because the semantic is different. This seems to be one of those cases.
Aug 17 2014
prev sibling parent reply "Mike" <none none.com> writes:
On Saturday, 16 August 2014 at 18:50:08 UTC, Jacob Carlborg wrote:
 On 2014-08-16 01:33, Mike wrote:

 Sounds like a worthwhile impromement to me.
Sounds like a breaking change to me. Which will include the usual complains.
... and not breaking it will include the same complaints years from now for not fixing it. Mike
Aug 16 2014
parent reply "Mike" <none none.com> writes:
On Saturday, 16 August 2014 at 23:39:59 UTC, Mike wrote:
 On Saturday, 16 August 2014 at 18:50:08 UTC, Jacob Carlborg 
 wrote:
 On 2014-08-16 01:33, Mike wrote:

 Sounds like a worthwhile impromement to me.
Sounds like a breaking change to me. Which will include the usual complains.
... and not breaking it will include the same complaints years from now for not fixing it. Mike
Clarification: I realize nothing is broken, so no "fixing" is needed. But it seems like a nice improvement. Mike
Aug 16 2014
parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Sunday, 17 August 2014 at 02:44:26 UTC, Mike wrote:
 On Saturday, 16 August 2014 at 23:39:59 UTC, Mike wrote:
 On Saturday, 16 August 2014 at 18:50:08 UTC, Jacob Carlborg 
 wrote:
 On 2014-08-16 01:33, Mike wrote:

 Sounds like a worthwhile impromement to me.
Sounds like a breaking change to me. Which will include the usual complains.
... and not breaking it will include the same complaints years from now for not fixing it. Mike
Clarification: I realize nothing is broken, so no "fixing" is needed. But it seems like a nice improvement.
Well, it _does_ follow the language spec, so it's not broken in that sense, but it's a broken design IMHO in that it causes confusion and bugs, and it has resulted in complaints in the past and will continue to do so until it's changed. So, I do think that it's true that there will ultimately be fewer complaints if we make the change than there will be if we don't. - Jonathan M Davis
Aug 16 2014
parent "bearophile" <bearophileHUGS lycos.com> writes:
Jonathan M Davis:

 Well, it _does_ follow the language spec, so it's not broken in
 that sense, but it's a broken design IMHO in that it causes
 confusion and bugs, and it has resulted in complaints in the 
 past
 and will continue to do so until it's changed. So, I do think
 that it's true that there will ultimately be fewer complaints if
 we make the change than there will be if we don't.
+1 It's a worthwhile overdue little breaking change. Bye, bearophile
Aug 17 2014