www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: Proposal: new variable definition operator

reply renoX <renosky free.fr> writes:
jovo Wrote:

 
 Hi,
 as type inference going to be norm I think we need reconsider
 diferentiate variable definition and variable assignment operator.
 
 Obvious choice is ':=' for variable definition. It's terse and explicit.
 Look at this:
 
 for(i := 0, i < 10; ++i)
 
 jovo

I've already tried to suggest ':=' for type inference (before the implementation), without much success obviously.. Worse, D use 'auto' instead of 'var' like Scala does. Well at least D has local type inference.. But for the syntax, being better than C++ is different from being good (compared to Scala or F#).. renoX
Apr 20 2007
parent reply jovo <jovo at.home> writes:
renoX Wrote:
 
 I've already tried to suggest ':=' for type inference (before the
implementation), without much success obviously..

It's so logical next step. It goes sooner or later. Perhaps Java will bring it into mainstream first.
 Worse, D use 'auto' instead of 'var' like Scala does.

Yes, auto looks arhaick even now. It's so verbose: "Type inference goes on!". Who cares. Wrong emphasis. It is actually needed even without type inference. We need way to say loudly: "here new variable goes in!" when it can be mixed with other code. Nothing better then an operator can do, C proved that. Interestingly enough, here are Strustrup's words: "It cannot be overemphasized that assignment and initialization are different operations" (The C++ Programing Language, Special 3rd Edition, page 283) And it can be introduced without any code breakage. Just allow for now. jovo
Apr 20 2007
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
jovo wrote:
 renoX Wrote:
 I've already tried to suggest ':=' for type inference (before the
implementation), without much success obviously..

It's so logical next step. It goes sooner or later. Perhaps Java will bring it into mainstream first.
 Worse, D use 'auto' instead of 'var' like Scala does.

Yes, auto looks arhaick even now. It's so verbose: "Type inference goes on!". Who cares. Wrong emphasis. It is actually needed even without type inference. We need way to say loudly: "here new variable goes in!" when it can be mixed with other code. Nothing better then an operator can do, C proved that. Interestingly enough, here are Strustrup's words: "It cannot be overemphasized that assignment and initialization are different operations" (The C++ Programing Language, Special 3rd Edition, page 283) And it can be introduced without any code breakage. Just allow for now. jovo

Just want to nitpick one thing: you seem to think that "auto" is the type inference keyword. It isn't. In D, a declaration is made up of four parts: the storage class, the type, the identifier and the initialiser. Obviously the identifier always needs to be there. If omitted, the initialiser is just type.init. Storage class and type are the interesting ones. In C, you could always omit the storage class if it was just a regular variable, but always had to specify the type. D allows you to omit the type if and only if you specify the storage class. Guess what the default storage class is? auto. Type inference in D isn't "type inference triggered by keyword", it's "type inference by omission." "auto" is only required so that the D grammar can tell it's supposed to be an declaration. -- Daniel -- int getRandomNumber() { return 4; // chosen by fair dice roll. // guaranteed to be random. } http://xkcd.com/ v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
Apr 20 2007
parent reply jovo <jovo at.home> writes:
Daniel Keep Wrote:
 
 Just want to nitpick one thing: you seem to think that "auto" is the
 type inference keyword.  It isn't.  In D, a declaration is made up of
 four parts: the storage class, the type, the identifier and the initialiser.
 
 Obviously the identifier always needs to be there.  If omitted, the
 initialiser is just type.init.
 
 Storage class and type are the interesting ones.  In C, you could always
 omit the storage class if it was just a regular variable, but always had
 to specify the type.  D allows you to omit the type if and only if you
 specify the storage class.  Guess what the default storage class is?
 
 auto.
 
 Type inference in D isn't "type inference triggered by keyword", it's
 "type inference by omission."  "auto" is only required so that the D
 grammar can tell it's supposed to be an declaration.
 

What is a meaning of auto as storage class specifier in D? In C it signifyes an automatic variable (hence auto) with clear definition. C++ faces similar problem introducing type inference via auto. They will clear auto from list of storage class specifiers. Just reusing old keyword with new meaning. jovo
Apr 21 2007
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
jovo wrote:
 Daniel Keep Wrote:
 Just want to nitpick one thing: you seem to think that "auto" is the
 type inference keyword.  It isn't.  In D, a declaration is made up of
 four parts: the storage class, the type, the identifier and the initialiser.

 Obviously the identifier always needs to be there.  If omitted, the
 initialiser is just type.init.

 Storage class and type are the interesting ones.  In C, you could always
 omit the storage class if it was just a regular variable, but always had
 to specify the type.  D allows you to omit the type if and only if you
 specify the storage class.  Guess what the default storage class is?

 auto.

 Type inference in D isn't "type inference triggered by keyword", it's
 "type inference by omission."  "auto" is only required so that the D
 grammar can tell it's supposed to be an declaration.

What is a meaning of auto as storage class specifier in D? In C it signifyes an automatic variable (hence auto) with clear definition. C++ faces similar problem introducing type inference via auto. They will clear auto from list of storage class specifiers. Just reusing old keyword with new meaning. jovo

The auto storage class simply means that it's a "normal" variable: it's not constant, not final, not static and not scope-destroyed. If it's at module-level, it's a global variable at a fixed memory location. If it's in a function, it's allocated on the stack. If it's in a struct or class, it's allocated as part of the containing type. AFAIK, D's auto is the same as C's auto. Just to reiterate: auto has *nothing* to do with type inference. It's just that it happens to be the default storage class, and specifying the storage class allows you to omit the type. Any storage class can be used to trigger type inference. -- Daniel -- int getRandomNumber() { return 4; // chosen by fair dice roll. // guaranteed to be random. } http://xkcd.com/ v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
Apr 21 2007
next sibling parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Daniel Keep wrote:
 
 jovo wrote:
 Daniel Keep Wrote:
 Just want to nitpick one thing: you seem to think that "auto" is the
 type inference keyword.  It isn't.  In D, a declaration is made up of
 four parts: the storage class, the type, the identifier and the initialiser.

 Obviously the identifier always needs to be there.  If omitted, the
 initialiser is just type.init.

 Storage class and type are the interesting ones.  In C, you could always
 omit the storage class if it was just a regular variable, but always had
 to specify the type.  D allows you to omit the type if and only if you
 specify the storage class.  Guess what the default storage class is?

 auto.

 Type inference in D isn't "type inference triggered by keyword", it's
 "type inference by omission."  "auto" is only required so that the D
 grammar can tell it's supposed to be an declaration.

In C it signifyes an automatic variable (hence auto) with clear definition. C++ faces similar problem introducing type inference via auto. They will clear auto from list of storage class specifiers. Just reusing old keyword with new meaning. jovo

The auto storage class simply means that it's a "normal" variable: it's not constant, not final, not static and not scope-destroyed. If it's at module-level, it's a global variable at a fixed memory location. If it's in a function, it's allocated on the stack. If it's in a struct or class, it's allocated as part of the containing type. AFAIK, D's auto is the same as C's auto. Just to reiterate: auto has *nothing* to do with type inference. It's just that it happens to be the default storage class, and specifying the storage class allows you to omit the type. Any storage class can be used to trigger type inference. -- Daniel

Auto is for "automatic" variables which (at least in C) are just another way to say local variables on the stack. Here's a particularly pathetic Wikipedia article about it: http://en.wikipedia.org/wiki/Automatic_memory_allocation --bb
Apr 21 2007
prev sibling parent reply jovo <jovo at.home> writes:
Daniel Keep Wrote:
 
 The auto storage class simply means that it's a "normal" variable: it's
 not constant, not final, not static and not scope-destroyed.  If it's at
 module-level, it's a global variable at a fixed memory location.  If
 it's in a function, it's allocated on the stack.  If it's in a struct or
 class, it's allocated as part of the containing type.
 

From the D docs (Attributes): "The auto attribute is used when there are no other attributes and type inference is desired." OK, it's simple and clear, but difficult to say: "auto has *nothing* to do with type inference".
 AFAIK, D's auto is the same as C's auto.
 

Maybe it _was_ initially. But not now. "Automatic variables are internal to a function; they come into existence when the function is entered, and disappear when it is left." (The C Programming Language, Kernighan and Ritchie) jovo
Apr 21 2007
parent reply Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
jovo wrote:
 Daniel Keep Wrote:
 The auto storage class simply means that it's a "normal" variable: it's
 not constant, not final, not static and not scope-destroyed.  If it's at
 module-level, it's a global variable at a fixed memory location.  If
 it's in a function, it's allocated on the stack.  If it's in a struct or
 class, it's allocated as part of the containing type.

From the D docs (Attributes): "The auto attribute is used when there are no other attributes and type inference is desired."

Same meaning, slightly different words, to this: "If type inference is desired, and there is no special storage class, you may specify the explicit default storage class attribute 'auto' to trigger inference."
 OK, it's simple and clear, but difficult to say:
 "auto has *nothing* to do with type inference".

But it *does* have nothing to do with it. The following two declerations are, for example, completely identical in result: final auto foo = 123 ; final foo = 123 ; The point is: I get type inference from just omitting the type in the presence of a storage class, which is needed to make the statement I'm issuing have the grammar of a variable decleration in the first place. `(storage | (storage? type)) ident ('=' init)? ';'` All of the following declerations experience type inference: # auto alpha = 1; # const beta = 2; # final gamma = 3; # invariant delta = 4; # scope epsilon = 5; # static zeta = 6; The key item in the documentation is on http://digitalmars.com/d/declaration.html under the heading 'Implicit Type Inference' and reads: """If a declaration starts with a StorageClass and has a NonVoidInitializer from which the type can be inferred, the type on the declaration can be omitted.""" The docs for 'auto' on the attributes page is, frankly, a stub and should be replaced with something a bit more clear.
 AFAIK, D's auto is the same as C's auto.

Maybe it _was_ initially. But not now.

Well see this is the quirky thing. It /was/, and then it actually /wasn't/ for a while... but now it /is/ again. The history of D has a few such loops in it. (And warts. I'm so glad the 'instance' keyword for template expansion went bye-bye.)
 "Automatic variables are internal to a function; they come into
 existence when the function is entered, and disappear when it is
 left." (The C Programming Language, Kernighan and Ritchie)
 

just means 'default' in D, and that behavior happens to be the default. -- Chris Nicholson-Sauls
Apr 21 2007
parent reply jovo <jovo at.home> writes:
Chris Nicholson-Sauls Wrote:
 
 From the D docs (Attributes):
 "The auto attribute is used when there are no other attributes
 and type inference is desired."

Same meaning, slightly different words, to this: "If type inference is desired, and there is no special storage class, you may specify the explicit default storage class attribute 'auto' to trigger inference."

I read this sentence as is: The auto attribute is _only_ used when there are no other attributes and type inference is desired. Auto has not other meaning. And _all_ implementation is consistent. Compiler just ignores auto in any other place. Look at: auto int x; // global, auto is ignored void f() { auto static int x = 12; // static, auto is ignored ... auto SomeClass x = new SomeClass(); // sole exception I suspect this exception is needed for backward compatibility. It is reminiscence of old auto. From Changelog for D 0.174: "scope can now be used for RAII declarations; use auto for type inference"
 
 All of the following declerations experience type inference:
 # auto      alpha   = 1;
 # const     beta    = 2;
 # final     gamma   = 3;
 # invariant delta   = 4;
 # scope     epsilon = 5;
 # static    zeta    = 6;
 

OK I know that. It's exactly as it is stated in docs. jovo
Apr 21 2007
parent Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
jovo wrote:
 Chris Nicholson-Sauls Wrote:
 From the D docs (Attributes):
 "The auto attribute is used when there are no other attributes
 and type inference is desired."

is no special storage class, you may specify the explicit default storage class attribute 'auto' to trigger inference."

I read this sentence as is: The auto attribute is _only_ used when there are no other attributes and type inference is desired. Auto has not other meaning. And _all_ implementation is consistent. Compiler just ignores auto in any other place. Look at: auto int x; // global, auto is ignored void f() { auto static int x = 12; // static, auto is ignored ... auto SomeClass x = new SomeClass(); // sole exception I suspect this exception is needed for backward compatibility. It is reminiscence of old auto.

A reasonable and likely suspicion. This back-compat should really be /removed/ and soon, I feel. Your examples don't so much illustrate that 'auto' is being ignored -- although I will relent insofar as 'auto' has little real use beside type inference and insanely verbose code styles -- but rather illustrate what has always been a quietly uneasy thing for me: DMD's choice to silently accept and discard any attributes in a decleration where they make no sense or have no meaning. For example, in the 'auto static int x' decleration, I would prefer a compile-time error to the effect of "variable x may have only one storage class" rather than it just tossing the former to run with the latter. I'd even like to see errors on things like "static class Foo" at module scope, unless and until this was given some meaning (such as "FQN required for this class"). -- Chris Nicholson-Sauls
Apr 22 2007