Re: Code behaves incorrectly if it is compiled in std.functional
On Mon, 08 Jun 2015 15:30:24 +, Marc Schütz wrote: 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. i'll keep citing `foreach (auto i)` thingy. it can't be deduced by using the knowledge of other language constructs, it can be only remembered. the less things one can't deduce language has, the better. signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
On 06/09/2015 11:11 AM, ketmar wrote: On Mon, 08 Jun 2015 15:30:24 +, Marc Schütz wrote: 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. i'll keep citing `foreach (auto i)` thingy. it can't be deduced by using the knowledge of other language constructs, it can be only remembered. the less things one can't deduce language has, the better. http://en.wikipedia.org/wiki/Lambda_calculus
Re: Code behaves incorrectly if it is compiled in std.functional
On Tue, 09 Jun 2015 13:09:22 +0200, Timon Gehr wrote: i'll keep citing `foreach (auto i)` thingy. it can't be deduced by using the knowledge of other language constructs, it can be only remembered. the less things one can't deduce language has, the better. http://en.wikipedia.org/wiki/Lambda_calculus what i should see there? will it explain to me why `while (i)` doesn't introduce new variable? ah, there is no ; after it! ok, well, it's very human-friendly. signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
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. signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
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. signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
On Monday, 8 June 2015 at 09:33:56 UTC, ketmar wrote: On Mon, 08 Jun 2015 09:27:34 +, 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. That's a bug ;-)
Re: Code behaves incorrectly if it is compiled in std.functional
Auto was a storage class in C, but in D it's a type placeholder.
Re: Code behaves incorrectly if it is compiled in std.functional
On Mon, 08 Jun 2015 09:27:34 +, 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. signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
On Monday, 8 June 2015 at 07:30:06 UTC, 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 Allocate a variable on the stack, and make it immutable = OK `immutable const` -- not ok Make the variable immutable, and make it const = nonsense ergo, `auto` is not a storage class, but type placeholder. No.
Re: Code behaves incorrectly if it is compiled in std.functional
On Mon, 08 Jun 2015 10:21:25 + Temtaime via Digitalmars-d digitalmars-d@puremagic.com wrote: Auto was a storage class in C, but in D it's a type placeholder. It is still a storage class in D too. http://dlang.org/grammar.html#StorageClasses
Re: Code behaves incorrectly if it is compiled in std.functional
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.
Re: Code behaves incorrectly if it is compiled in std.functional
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.
Re: Code behaves incorrectly if it is compiled in std.functional
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.
Re: Code behaves incorrectly if it is compiled in std.functional
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; }
Re: Code behaves incorrectly if it is compiled in std.functional
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! signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
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. signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
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'.
Re: Code behaves incorrectly if it is compiled in std.functional
On 06/08/2015 11:33 AM, ketmar wrote: On Mon, 08 Jun 2015 09:27:34 +, 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'.
Re: Code behaves incorrectly if it is compiled in std.functional
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 +, 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. signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
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. signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
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... signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
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. signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
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.
Re: Code behaves incorrectly if it is compiled in std.functional
On 06/08/2015 05:15 PM, ketmar wrote: 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. That's not a definition. It is a rationale.
Re: Code behaves incorrectly if it is compiled in std.functional
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.
Re: Code behaves incorrectly if it is compiled in std.functional
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?
Re: Code behaves incorrectly if it is compiled in std.functional
On 06/07/15 18:49, Timon Gehr via Digitalmars-d wrote: 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? The problem is the apparently common misunderstanding that 'auto' is a thing in D. It is not; it's just a grammar hack. The (very simplified) rule for declarations in C/C++/D is storage_class type lhs = rhs In C, you can omit the /storage_class/ and it then defaults to 'auto'. Obviously, the 'auto' keyword is redundant and nobody actually uses it. In D, you can omit the /type/ and it's then propagated from the /rhs/ expression. The compiler already knows the type that 'rhs' evaluates to. But you can not omit both the /type/ and the /storage_class/ as 'lhs=rhs' would be indistinguishable from an assignment. In some contexts for the compiler, but, more importantly, for the human. Hence 'auto lhs = rhs'. [The exceptions are either because of backward C compatibility (function args) or no need for such compatibility (foreach)] Still, 'auto' isn't as bad as 'static', which D redefined to mean something different than in C/C++, and did this so subtly that the C version will still compile, giving unexpected results without even a warning. artur
Re: Code behaves incorrectly if it is compiled in std.functional
On Sunday, 7 June 2015 at 05:02:47 UTC, ketmar wrote: On Sat, 06 Jun 2015 18:49:00 +, Marc Schütz wrote: On Saturday, 6 June 2015 at 15:12:38 UTC, ketmar wrote: what should i check to see what is *really* allowed, why two storage classes allowed with one combination and not allowed with another? Well, you can look at the compiler's source... But I'm sure this is not the answer you wanted ;-) sure. now i'm completely lost. i shouldn't use DMD to find out things, yet i have to use DMD to find out things. Im my defense, you asked what _is_ really allowed, not what _should_ be allowed... ok, let's be serious. what i'm trying to say is that there should be not only grammar with comments inside it here and there, but the document that explains what is what, what's compatible with what and so on. the specs in the meaning that one can point to it and say: this is how it is supposed to be. now fix your code. or now let's fix the compiler. the specs where no undefined behavior words are used, and no it's left to compiler implementer to decide. (but look at DMDFE source is allowed ;-). Brian Schott did a lot of work finding inconsistencies and ambiguities in the grammar, and I believe his DConf talk was partially about it.
Re: Code behaves incorrectly if it is compiled in std.functional
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. signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
On Fri, 05 Jun 2015 18:35:49 +, Marc Schütz wrote: On Friday, 5 June 2015 at 17:50:55 UTC, ketmar wrote: `const int` works, so i can't see why `auto auto` is failing. Wrong analogy. Try `const const`, and it will fail with the same error as `auto auto`: redundant attribute. nope. in `auto auto` one `auto` is storage type, and another `auto` is a type placeholder. see, `const auto` works, so `auto` can play role of a type placeholder. so `auto auto` should be accepted, if you insists that it can play a role of storage class. signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
On Fri, 05 Jun 2015 20:36:19 +, Mafi wrote: On Friday, 5 June 2015 at 10:56:36 UTC, ketmar wrote: p.s. if auto is a storage class, the following code should be accepted (while it isn't): int foo () { return 42; } void main () { auto auto i = foo(); } as it's logically an auto-typed var with auto storage class. Here lies your mistake. There is no such thing as auto-typed (leaving aside function signatures, which might be special-cased and are different beast altogether). Auto is not a type. auto* or auto[] aren't valied either. Auto is just a storage class, no more, no less. You use it if the grammar needs a storage class but you don't want to give special attributes to the variable (like const or static). To make a declaration with inferred type you need at least one storage class. To make it work with normal variables you use auto. p.s. even more samples: `foreach (auto n; 0..10)`. this doesn't work at all. why? `foreach (immutable n; 0..10)` works perfectly. so `auto` clearly is not a storage class, as it is forbidden where storage classes are allowed. signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
On Fri, 05 Jun 2015 20:36:19 +, Mafi wrote: On Friday, 5 June 2015 at 10:56:36 UTC, ketmar wrote: p.s. if auto is a storage class, the following code should be accepted (while it isn't): int foo () { return 42; } void main () { auto auto i = foo(); } as it's logically an auto-typed var with auto storage class. Here lies your mistake. There is no such thing as auto-typed (leaving aside function signatures, which might be special-cased and are different beast altogether). Auto is not a type. auto* or auto[] aren't valied either. Auto is just a storage class, no more, no less. You use it if the grammar needs a storage class but you don't want to give special attributes to the variable (like const or static). To make a declaration with inferred type you need at least one storage class. To make it work with normal variables you use auto. so either `const auto` should not be accepted, or `auto auto` should be accepted. if `auto` plays a role of default storage class, the `const auto` should trigger the error about redundant storage specifier. if `auto` can play a role of type placeholder, then `auto auto` should be accepted, as it's clearly the default storage class with type placeholder. current situation is inconsistent and that inconsistency must be fixed. signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
On Saturday, 6 June 2015 at 06:05:46 UTC, ketmar wrote: On Fri, 05 Jun 2015 18:35:49 +, Marc Schütz wrote: On Friday, 5 June 2015 at 17:50:55 UTC, ketmar wrote: `const int` works, so i can't see why `auto auto` is failing. Wrong analogy. Try `const const`, and it will fail with the same error as `auto auto`: redundant attribute. nope. in `auto auto` one `auto` is storage type, and another `auto` is a type placeholder. No, as others have explained. see, `const auto` works, so `auto` can play role of a type placeholder. so `auto auto` should be accepted, if you insists that it can play a role of storage class. `const auto` isn't contradictory. It's simply two storage classes, one of which is the default. Besides, there's not much sense in doing experiments with DMD to find out the true nature of auto. DMD is clearly inconsistent, as seen from your observation about foreach().
Re: Code behaves incorrectly if it is compiled in std.functional
On Sat, 06 Jun 2015 12:36:09 +, Marc Schütz wrote: `const auto` isn't contradictory. It's simply two storage classes, one of which is the default. but it is! ok, how about `shared auto i = 42;`? what the $#^# `auto` means here? what is that default storage class then, and why it doesn't apply here? Besides, there's not much sense in doing experiments with DMD to find out the true nature of auto. DMD is clearly inconsistent, as seen from your observation about foreach(). ok, but what i should consult then? specs? but specs clearly allows `const immutable shared auto scope inout __gshared int i = 42;`. yes, specs clearly says that `auto` is a storage class. specs also allowing `auto auto auto auto auto int i = 42;`. what should i check to see what is *really* allowed, why two storage classes allowed with one combination and not allowed with another? signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
On Sat, 06 Jun 2015 18:49:00 +, Marc Schütz wrote: On Saturday, 6 June 2015 at 15:12:38 UTC, ketmar wrote: what should i check to see what is *really* allowed, why two storage classes allowed with one combination and not allowed with another? Well, you can look at the compiler's source... But I'm sure this is not the answer you wanted ;-) sure. now i'm completely lost. i shouldn't use DMD to find out things, yet i have to use DMD to find out things. ok, let's be serious. what i'm trying to say is that there should be not only grammar with comments inside it here and there, but the document that explains what is what, what's compatible with what and so on. the specs in the meaning that one can point to it and say: this is how it is supposed to be. now fix your code. or now let's fix the compiler. the specs where no undefined behavior words are used, and no it's left to compiler implementer to decide. (but look at DMDFE source is allowed ;-). signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
On Saturday, 6 June 2015 at 15:12:38 UTC, ketmar wrote: what should i check to see what is *really* allowed, why two storage classes allowed with one combination and not allowed with another? Well, you can look at the compiler's source... But I'm sure this is not the answer you wanted ;-)
Re: Code behaves incorrectly if it is compiled in std.functional
On Fri, 05 Jun 2015 09:44:09 +, Marc Schütz wrote: On Friday, 5 June 2015 at 04:39:28 UTC, ketmar wrote: On Fri, 05 Jun 2015 03:56:05 +, anonymous wrote: On Friday, 5 June 2015 at 03:45:18 UTC, ketmar wrote: `auto int a`?! it shouldn't be accepted at all! Yeah, but it's the same with auto ref. `auto ref` has a well-defined meaning. yet `auto int` is nonsence. it's definitely a compiler bug. ;-) I don't think so. `auto` is a valid storage class like `const`, `immutable` and `shared`. `auto` is not a storage class, but a `type placeholder`. at least this is what i've been told by W or A (sorry, i can't remember the link; i think it was somewhere in NG... or in bugzilla...). there is one exception to this rule, though: `auto ref`. signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
On Friday, 5 June 2015 at 03:15:46 UTC, anonymous wrote: On Friday, 5 June 2015 at 02:38:39 UTC, ketmar wrote: here's dustmited source: Further reduced: void unaryFun()(auto int a) pure nothrow @safe @nogc {} alias Identity(F) = F; void main() { unaryFun!()(41); static void fun(int n) pure nothrow @safe @nogc {} alias F = typeof(fun); pragma(msg, F); /* ...(int n) */ pragma(msg, Identity!F); /* ...(auto int) */ } 'auto int' doesn't compile with 2.067.1. I know because this is blocking a PR I'm working on.
Re: Code behaves incorrectly if it is compiled in std.functional
On Friday, 5 June 2015 at 10:54:36 UTC, ketmar wrote: On Fri, 05 Jun 2015 09:44:09 +, Marc Schütz wrote: On Friday, 5 June 2015 at 04:39:28 UTC, ketmar wrote: On Fri, 05 Jun 2015 03:56:05 +, anonymous wrote: On Friday, 5 June 2015 at 03:45:18 UTC, ketmar wrote: `auto int a`?! it shouldn't be accepted at all! Yeah, but it's the same with auto ref. `auto ref` has a well-defined meaning. yet `auto int` is nonsence. it's definitely a compiler bug. ;-) I don't think so. `auto` is a valid storage class like `const`, `immutable` and `shared`. `auto` is not a storage class, but a `type placeholder`. at least this is what i've been told by W or A (sorry, i can't remember the link; i think it was somewhere in NG... or in bugzilla...). there is one exception to this rule, though: `auto ref`. My understanding is that `auto` is just C legacy, and originally had the same meaning as in C. But apparently the language has moved away from that over time.
Re: Code behaves incorrectly if it is compiled in std.functional
On Friday, 5 June 2015 at 04:39:28 UTC, ketmar wrote: On Fri, 05 Jun 2015 03:56:05 +, anonymous wrote: On Friday, 5 June 2015 at 03:45:18 UTC, ketmar wrote: `auto int a`?! it shouldn't be accepted at all! Yeah, but it's the same with auto ref. `auto ref` has a well-defined meaning. yet `auto int` is nonsence. it's definitely a compiler bug. ;-) I don't think so. `auto` is a valid storage class like `const`, `immutable` and `shared`.
Re: Code behaves incorrectly if it is compiled in std.functional
On Fri, 05 Jun 2015 11:53:29 +, Marc Schütz wrote: My understanding is that `auto` is just C legacy, and originally had the same meaning as in C. But apparently the language has moved away from that over time. 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. signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
On Fri, 05 Jun 2015 11:07:19 +, Meta wrote: On Friday, 5 June 2015 at 03:15:46 UTC, anonymous wrote: On Friday, 5 June 2015 at 02:38:39 UTC, ketmar wrote: here's dustmited source: Further reduced: void unaryFun()(auto int a) pure nothrow @safe @nogc {} alias Identity(F) = F; void main() { unaryFun!()(41); static void fun(int n) pure nothrow @safe @nogc {} alias F = typeof(fun); pragma(msg, F); /* ...(int n) */ pragma(msg, Identity!F); /* ...(auto int) */ } 'auto int' doesn't compile with 2.067.1. I know because this is blocking a PR I'm working on. but it does! both with 2.067.1 downloaded from dlang.org and with git HEAD. it may not do what you expect it to do (i don't know what it should do anyway), but dmd happily accepts that code. signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
On Friday, 5 June 2015 at 17:50:55 UTC, ketmar wrote: `const int` works, so i can't see why `auto auto` is failing. Wrong analogy. Try `const const`, and it will fail with the same error as `auto auto`: redundant attribute.
Re: Code behaves incorrectly if it is compiled in std.functional
On Fri, 05 Jun 2015 16:42:25 +, Mafi wrote: On Friday, 5 June 2015 at 16:26:34 UTC, ketmar wrote: On Fri, 05 Jun 2015 15:17:50 +, Mafi wrote: auto int x = 10; should work. It's just consistent. then `auto auto` should work too. it's a declaration mark + storage class. Well, no. Any storage class marks a declaration just by itself. You don't use it as a declaration mark or storage class, just use a storage class which definitely declares something new. See also http://dlang.org/declaration.html A declaration is either StorageClasses(opt) BasicType Declarators or AutoDeclaration. An AutoDeclaration is the one with type inference. And it is marked by any storage class, not just auto (http://dlang.org/declaration.html#AutoDeclaration): StorageClasses AutoDeclarationX. Well admittently http://dlang.org/declaration.html#StorageClass does not feature 'auto' as a storage class but this must be an error because the description of AutoDeclaration uses 'auto' in the place of StorageClasses. It is just about grammar. A declaration needs a type, a storage class or both to not be mistaken for a statement with an assign expression. You use the 'auto' storage class so the statement cannot possibly be an expression when leaving out the type and not using any meaningful storage class. `const int` works, so i can't see why `auto auto` is failing. signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
On Friday, 5 June 2015 at 12:32:03 UTC, ketmar wrote: but it does! both with 2.067.1 downloaded from dlang.org and with git HEAD. it may not do what you expect it to do (i don't know what it should do anyway), but dmd happily accepts that code. Hmm, maybe I'm only on 2.070 then. I'll upgrade and see if it still fails to compile.
Re: Code behaves incorrectly if it is compiled in std.functional
On Fri, 05 Jun 2015 15:17:50 +, Mafi wrote: auto int x = 10; should work. It's just consistent. then `auto auto` should work too. it's a declaration mark + storage class. signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
On Friday, 5 June 2015 at 16:26:34 UTC, ketmar wrote: On Fri, 05 Jun 2015 15:17:50 +, Mafi wrote: auto int x = 10; should work. It's just consistent. then `auto auto` should work too. it's a declaration mark + storage class. Well, no. Any storage class marks a declaration just by itself. You don't use it as a declaration mark or storage class, just use a storage class which definitely declares something new. See also http://dlang.org/declaration.html A declaration is either StorageClasses(opt) BasicType Declarators or AutoDeclaration. An AutoDeclaration is the one with type inference. And it is marked by any storage class, not just auto (http://dlang.org/declaration.html#AutoDeclaration): StorageClasses AutoDeclarationX. Well admittently http://dlang.org/declaration.html#StorageClass does not feature 'auto' as a storage class but this must be an error because the description of AutoDeclaration uses 'auto' in the place of StorageClasses. It is just about grammar. A declaration needs a type, a storage class or both to not be mistaken for a statement with an assign expression. You use the 'auto' storage class so the statement cannot possibly be an expression when leaving out the type and not using any meaningful storage class.
Re: Code behaves incorrectly if it is compiled in std.functional
On Fri, 05 Jun 2015 09:44:09 +, Marc Schütz wrote: On Friday, 5 June 2015 at 04:39:28 UTC, ketmar wrote: On Fri, 05 Jun 2015 03:56:05 +, anonymous wrote: On Friday, 5 June 2015 at 03:45:18 UTC, ketmar wrote: `auto int a`?! it shouldn't be accepted at all! Yeah, but it's the same with auto ref. `auto ref` has a well-defined meaning. yet `auto int` is nonsence. it's definitely a compiler bug. ;-) I don't think so. `auto` is a valid storage class like `const`, `immutable` and `shared`. p.s. if auto is a storage class, the following code should be accepted (while it isn't): int foo () { return 42; } void main () { auto auto i = foo(); } as it's logically an auto-typed var with auto storage class. signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
On Friday, 5 June 2015 at 12:33:35 UTC, ketmar wrote: On Fri, 05 Jun 2015 11:53:29 +, Marc Schütz wrote: My understanding is that `auto` is just C legacy, and originally had the same meaning as in C. But apparently the language has moved away from that over time. 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. AFAIK auto is a stotage class (like in C). It is the no-op storage and therefore does not not change the stotage or type etc. But in a statement it definitely marks as a declaration because only those can contain storage classes. In D any declaration can omit the type so let it be inferred. That's why this also works: const x = 10; static y = 20; enum z = 30; Auto is only needed to unambigiously mark a statement as declaration when the lack of type would make it look like an ExpressionStatement. But still auto int x = 10; should work. It's just consistent.
Re: Code behaves incorrectly if it is compiled in std.functional
On Friday, 5 June 2015 at 19:45:18 UTC, krzaq wrote: const auto ans = 42; compiles fine for me, so auto clearly can be used as a type. So does auto immutable or auto pure or pure a. They're all storage classes and any storage class can kick off a declaration: @nogc a = 10; // compiles! dmd is just not really consistent on when it issues errors on redundant, conflicting, or useless storage classes.
Re: Code behaves incorrectly if it is compiled in std.functional
On Friday, 5 June 2015 at 19:38:06 UTC, Steven Schveighoffer wrote: On 6/5/15 12:19 PM, Meta wrote: On Friday, 5 June 2015 at 12:32:03 UTC, ketmar wrote: but it does! both with 2.067.1 downloaded from dlang.org and with git HEAD. it may not do what you expect it to do (i don't know what it should do anyway), but dmd happily accepts that code. Hmm, maybe I'm only on 2.070 then. I'll upgrade and see if it still fails to compile. Hello from the future!!! When I use auto int a in a normal function, I get this: Error: auto can only be used for template function parameters But unaryFun()(auto int a) is a template. Perhaps your blocker is for non-templates? -Steve Yes, this is a non-template function that is auto-generated.
Re: Code behaves incorrectly if it is compiled in std.functional
On Friday, 5 June 2015 at 03:15:46 UTC, anonymous wrote: On Friday, 5 June 2015 at 02:38:39 UTC, ketmar wrote: here's dustmited source: Further reduced: void unaryFun()(auto int a) pure nothrow @safe @nogc {} alias Identity(F) = F; void main() { unaryFun!()(41); static void fun(int n) pure nothrow @safe @nogc {} alias F = typeof(fun); pragma(msg, F); /* ...(int n) */ pragma(msg, Identity!F); /* ...(auto int) */ } Filed two issues: https://issues.dlang.org/show_bug.cgi?id=14656 https://issues.dlang.org/show_bug.cgi?id=14657
Re: Code behaves incorrectly if it is compiled in std.functional
On 6/5/15 12:19 PM, Meta wrote: On Friday, 5 June 2015 at 12:32:03 UTC, ketmar wrote: but it does! both with 2.067.1 downloaded from dlang.org and with git HEAD. it may not do what you expect it to do (i don't know what it should do anyway), but dmd happily accepts that code. Hmm, maybe I'm only on 2.070 then. I'll upgrade and see if it still fails to compile. Hello from the future!!! When I use auto int a in a normal function, I get this: Error: auto can only be used for template function parameters But unaryFun()(auto int a) is a template. Perhaps your blocker is for non-templates? -Steve
Re: Code behaves incorrectly if it is compiled in std.functional
On Friday, 5 June 2015 at 18:35:51 UTC, Marc Schütz wrote: On Friday, 5 June 2015 at 17:50:55 UTC, ketmar wrote: `const int` works, so i can't see why `auto auto` is failing. Wrong analogy. Try `const const`, and it will fail with the same error as `auto auto`: redundant attribute. const auto ans = 42; compiles fine for me, so auto clearly can be used as a type.
Re: Code behaves incorrectly if it is compiled in std.functional
On Friday, 5 June 2015 at 10:56:36 UTC, ketmar wrote: p.s. if auto is a storage class, the following code should be accepted (while it isn't): int foo () { return 42; } void main () { auto auto i = foo(); } as it's logically an auto-typed var with auto storage class. Here lies your mistake. There is no such thing as auto-typed (leaving aside function signatures, which might be special-cased and are different beast altogether). Auto is not a type. auto* or auto[] aren't valied either. Auto is just a storage class, no more, no less. You use it if the grammar needs a storage class but you don't want to give special attributes to the variable (like const or static). To make a declaration with inferred type you need at least one storage class. To make it work with normal variables you use auto.
Re: Code behaves incorrectly if it is compiled in std.functional
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.
Re: Code behaves incorrectly if it is compiled in std.functional
I reproduced this bug on my arch linux with DMD 2.067 and git phobos (4cea8f1e4dd839568cc9e581bc15ee84f02e7135)
Re: Code behaves incorrectly if it is compiled in std.functional
On Friday, 5 June 2015 at 02:38:39 UTC, ketmar wrote: here's dustmited source: Further reduced: void unaryFun()(auto int a) pure nothrow @safe @nogc {} alias Identity(F) = F; void main() { unaryFun!()(41); static void fun(int n) pure nothrow @safe @nogc {} alias F = typeof(fun); pragma(msg, F); /* ...(int n) */ pragma(msg, Identity!F); /* ...(auto int) */ }
Re: Code behaves incorrectly if it is compiled in std.functional
On Fri, 05 Jun 2015 03:15:45 +, anonymous wrote: On Friday, 5 June 2015 at 02:38:39 UTC, ketmar wrote: here's dustmited source: Further reduced: void unaryFun()(auto int a) pure nothrow @safe @nogc {} alias Identity(F) = F; void main() { unaryFun!()(41); static void fun(int n) pure nothrow @safe @nogc {} alias F = typeof(fun); pragma(msg, F); /* ...(int n) */ pragma(msg, Identity!F); /* ...(auto int) */ } `auto int a`?! it shouldn't be accepted at all! O_O signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
here's dustmited source: template unaryFun(alias fun, string parmName=a) { static if (is(typeof(fun))) auto unaryFun(ElementType) (auto ElementType __a) { mixin(alias ~ parmName ~ = __a ;); return mixin(fun); } else static if (needOpCallAlias) { unaryFun fun; } } unittest { cast(void)unaryFun!a+1(41); // silence warning } unittest { struct Foo2 { int fun (int n) pure nothrow @safe @nogc { return n; } } import std.traits; pragma(msg, ParameterTypeTuple!(typeof(Foo2.fun))); } # dmd -c -o- -unittest test.d to see `(auto int)` note that after removing any attribute from `Foo2.foo` will emit correct `(int)`.
Re: Code behaves incorrectly if it is compiled in std.functional
On Friday, 5 June 2015 at 03:45:18 UTC, ketmar wrote: `auto int a`?! it shouldn't be accepted at all! Yeah, but it's the same with auto ref.
Re: Code behaves incorrectly if it is compiled in std.functional
On Fri, 05 Jun 2015 03:56:05 +, anonymous wrote: On Friday, 5 June 2015 at 03:45:18 UTC, ketmar wrote: `auto int a`?! it shouldn't be accepted at all! Yeah, but it's the same with auto ref. `auto ref` has a well-defined meaning. yet `auto int` is nonsence. it's definitely a compiler bug. ;-) signature.asc Description: PGP signature
Re: Code behaves incorrectly if it is compiled in std.functional
On Fri, 05 Jun 2015 04:39:28 +, ketmar wrote: On Fri, 05 Jun 2015 03:56:05 +, anonymous wrote: On Friday, 5 June 2015 at 03:45:18 UTC, ketmar wrote: `auto int a`?! it shouldn't be accepted at all! Yeah, but it's the same with auto ref. `auto ref` has a well-defined meaning. yet `auto int` is nonsence. it's definitely a compiler bug. ;-) i mean there are at least two different things in that code, and they triggers two different compiler bugs. signature.asc Description: PGP signature