June 08, 2015
On Mon, 08 Jun 2015 14:28:06 +0200, Timon Gehr wrote:

> On 06/08/2015 09:28 AM, ketmar wrote:
>> On Sun, 07 Jun 2015 18:49:24 +0200, Timon Gehr wrote:
>>
>>> On 06/06/2015 08:06 AM, ketmar wrote:
>>>> On Sat, 06 Jun 2015 00:28:51 +0200, Timon Gehr wrote:
>>>>
>>>>> On 06/05/2015 02:33 PM, ketmar wrote:
>>>>>> i agree, i think it was a keyword used 'cause it was already used
>>>>>> in C.
>>>>>> but it's meaning is completely redefined in D.
>>>>>
>>>>> The meaning is exactly the same. It's the default storage class.
>>>>
>>>> then i'll fill a bug about `auto auto` and will reopen it until it's fixed.
>>>>
>>>>
>>> This is valid C:
>>>
>>> int main(){
>>>     const auto int x=2;
>>>     return 0;
>>> }
>>>
>>> This is not valid C:
>>>
>>> int main(){
>>>     auto auto int x=2; return 0;
>>> }
>>>
>>> What is the problem?
>>
>> sorry, i didn't realized that this is NG for C language.
>>
>>
> This is valid D, but it is pointless:
> 
> int main(){
>      const auto x=2; return 0;
> }
> 
> int main(){
>      auto const x=2; return 0;
> }
> 
> 
> This is valid D:
> 
> int main(){
>      const x=2;
>      return 0;
> }
> 
> This is not valid D:
> 
> int main(){
>      auto auto x=2; return 0;
> }
> 
> int main(){
>      int const x=2; return 0;
> }
> 
> 
> This could be valid D, but isn't (assuming DMD behaves correctly here, I don't think this is documented), because it is pointless, and the compiler is now arbitrarily trying to be helpful:
> 
> int main(){
>      const auto int x=2;
>      return 0;
> }
> 
> The error message:
> tt.d(2): Error: variable tt.main.x storage class 'auto' has no effect if
> type is not inferred, did you mean 'scope'?
> 
> Note "storage class".
> 
> 
> Ditto:
> 
> int main(){
>      auto const int x=2;
>      return 0;
> }

so specifying two storage classes are sometimes valid and sometimes invalid. a perfect consistency!

June 08, 2015
On Mon, 08 Jun 2015 13:38:08 +0200, Timon Gehr wrote:

> On 06/08/2015 09:30 AM, ketmar wrote:
>> On Sun, 07 Jun 2015 18:50:07 +0200, Timon Gehr wrote:
>>
>>> On 06/06/2015 08:10 AM, ketmar wrote:
>>>> if `auto` can play a role of type placeholder
>>>
>>> There is no such thing as a type placeholder.
>>
>> there is:
>>
>> `immutable auto` -- ok `immutable const` -- not ok
>>
>> ergo, `auto` is not a storage class, but type placeholder.
>>
>>
> This analogy does not work. 'immutable' and 'automatic storage' do not conflict. 'immutable' and 'const' do conflict.
> 
> 'immutable auto' is exactly the same as 'auto immutable'. There is no 'int immutable'.

ok. what that "automatic storage" means after all? except being a placeholder.

June 08, 2015
On Mon, 08 Jun 2015 13:47:09 +0200, Timon Gehr wrote:

> On 06/08/2015 11:33 AM, ketmar wrote:
>> On Mon, 08 Jun 2015 09:27:34 +0000, Marc Schütz wrote:
>>
>>>> ergo, `auto` is not a storage class, but type placeholder.
>>>
>>> No.
>>
>> and it's not a storage class too. `foreach (auto i; 0..42)` doesn't
>> work,
>> white `foreach (immutable i; 0..42)` works ok.
>>
>>
> foreach(static i;0..42) doesn't work either, and 'static' is a storage
> class.
> 
> 'immutable' is a type constructor besides being a storage class.
> 
> The attributes allowed in `foreach' are those that are considered to make sense, and they are specified in the grammar: http://dlang.org/statement.html#ForeachTypeAttributes
> 
> Furthermore, both of those declarations are valid:
> 
> static i = 2;
> immutable j = 3;
> 
> What is important is that the type was left out, not that it was replaced by 'auto'.

i tried to explain to some people why `foreach (i; 0..42)` doesn't reuse previously declared `i` and failed. it doesn't look like variable declaration at all, and there is no way to make it look like variable declaration without specifying a type or `const/immutable/etc.`. so "default storage class" doesn't make sense in `foreach`? now i'm REALLY puzzled about what "default storage class" means at all. seems that it's "random storage class that means anything /dev/urandom returns".

June 08, 2015
On 06/08/2015 03:12 PM, ketmar wrote:
> On Mon, 08 Jun 2015 13:38:08 +0200, Timon Gehr wrote:
>
>> On 06/08/2015 09:30 AM, ketmar wrote:
>>> On Sun, 07 Jun 2015 18:50:07 +0200, Timon Gehr wrote:
>>>
>>>> On 06/06/2015 08:10 AM, ketmar wrote:
>>>>> if `auto` can play a role of type placeholder
>>>>
>>>> There is no such thing as a type placeholder.
>>>
>>> there is:
>>>
>>> `immutable auto` -- ok `immutable const` -- not ok
>>>
>>> ergo, `auto` is not a storage class, but type placeholder.
>>>
>>>
>> This analogy does not work. 'immutable' and 'automatic storage' do not
>> conflict. 'immutable' and 'const' do conflict.
>>
>> 'immutable auto' is exactly the same as 'auto immutable'. There is no
>> 'int immutable'.
>
> ok. what that "automatic storage" means after all?


For all practical and theoretical purposes, it means absolutely nothing.

> except being a placeholder.
>

It indicates to the parser that what follows is a declaration. Nothing more. It does not hold the place of anything else.
June 08, 2015
On 06/08/2015 03:11 PM, ketmar wrote:
> so specifying two storage classes are sometimes valid and sometimes
> invalid. a perfect consistency!

The compiler sometimes compiles the program and sometimes terminates with an error message instead. That's life.
June 08, 2015
On 06/08/2015 03:17 PM, ketmar wrote:
> ...
>
> i tried to explain to some people why `foreach (i; 0..42)` doesn't reuse
> previously declared `i` and failed.

The reason is that it wouldn't make any sense.

> it doesn't look like variable declaration at all,

It looks like a variable declaration because it is a variable declaration. It declares the foreach loop variable.

> and there is no way to make it look like variable
> declaration without specifying a type or `const/immutable/etc.`. so
> "default storage class" doesn't make sense in `foreach`?

I didn't make the decision, but it is redundant.


June 08, 2015
On Mon, 08 Jun 2015 15:47:33 +0200, Timon Gehr wrote:

> On 06/08/2015 03:11 PM, ketmar wrote:
>> so specifying two storage classes are sometimes valid and sometimes invalid. a perfect consistency!
> 
> The compiler sometimes compiles the program and sometimes terminates with an error message instead. That's life.

yeah. "you can't logically deduce it, you have to remember it!" that's the way to success.

June 08, 2015
On Mon, 08 Jun 2015 15:54:23 +0200, Timon Gehr wrote:

> On 06/08/2015 03:17 PM, ketmar wrote:
>> ...
>>
>> i tried to explain to some people why `foreach (i; 0..42)` doesn't reuse previously declared `i` and failed.
> 
> The reason is that it wouldn't make any sense.
> 
>> it doesn't look like variable declaration at all,
> 
> It looks like a variable declaration because it is a variable declaration. It declares the foreach loop variable.

no. it looks like "let's use our previously declared `i` as a counter". there is no single sign of variable declaration here. like `while (i)` will not declare a new variable, or `foo(i, n)`, or `if (i)`.

>> and there is no way to make it look like variable declaration without specifying a type or `const/immutable/etc.`. so "default storage class" doesn't make sense in `foreach`?
> 
> I didn't make the decision, but it is redundant.

only if D doesn't meant to be a language which is easily readable by humans. declaring new variable by simply specifying it's name isn't used anywhere else. oh, well, another exception to remember. another good step to success. the more exceptions, the more steps...

June 08, 2015
On Mon, 08 Jun 2015 15:46:22 +0200, Timon Gehr wrote:

> It indicates to the parser that what follows is a declaration. Nothing more. It does not hold the place of anything else.

so it's not a "default storage type", but simply "a mark for a parser". well, the third definition.

June 08, 2015
On Monday, 8 June 2015 at 15:09:21 UTC, ketmar wrote:
> On Mon, 08 Jun 2015 15:47:33 +0200, Timon Gehr wrote:
>
>> On 06/08/2015 03:11 PM, ketmar wrote:
>>> so specifying two storage classes are sometimes valid and sometimes
>>> invalid. a perfect consistency!
>> 
>> The compiler sometimes compiles the program and sometimes terminates
>> with an error message instead. That's life.
>
> yeah. "you can't logically deduce it, you have to remember it!" that's
> the way to success.

That's only if you're talking about the details of the grammar. But for everyday use (even advanced use!) of the language, these are not important. You _don't_ "have to remember it", because you simply don't need it. Noone forces you to write `auto const`, and it gives you no advantages over just `const`. But if you really feel an urge to use strange combinations of storage classes and type modifiers, just do it, and the compiler will tell you whether it's good or not. No need to remember anything. OTOH, if you encounter such a combination in someone else's code, it's still pretty obvious what it means. No problem there either.