November 12, 2006
Walter Bright wrote:
> The auto storage class currently is a little fuzzy in meaning, it can mean "infer the type" and/or "destruct at end of scope". The latter only has meaning for class objects, so let's look at the syntax. There are 4 cases:
> 
> class Class { }
> 
> 1) auto c = new Class();
> 2) auto Class c = new Class();
> 3) auto c = some_expression();
> 4) auto Class c = some_expression();
> 
> The ambiguity can be resolved by saying that if auto is used for type inference, i.e. cases (1) and (3), then it does not mean RAII. If it is not used for type inference, i.e. cases (2) and (4), then it does mean RAII.
> 
> In the future, I'd like the following to work:
> 
> 5) auto c = Class();
> 
> which would mean type inference *and* RAII.

No, I don't like it, it's awful.

As others, I think two different keywords should be added to separate concepts (I do specially agree with Derek).

The 'scope' keyword would be nice for raii ('local' could also work but not so clearly with raii classes).

For type inference I like 'infer' as it has been suggested.

Regards,
--
Tom;
November 12, 2006

Walter Bright wrote:
> The auto storage class currently is a little fuzzy in meaning, it can mean "infer the type" and/or "destruct at end of scope". The latter only has meaning for class objects, so let's look at the syntax. There are 4 cases:
> 
> class Class { }
> 
> 1) auto c = new Class();
> 2) auto Class c = new Class();
> 3) auto c = some_expression();
> 4) auto Class c = some_expression();
> 
> The ambiguity can be resolved by saying that if auto is used for type inference, i.e. cases (1) and (3), then it does not mean RAII. If it is not used for type inference, i.e. cases (2) and (4), then it does mean RAII.

C'mon man, just introduce the "var" keyword and make everyone happy! <g>

> 
> In the future, I'd like the following to work:
> 
> 5) auto c = Class();
> 
> which would mean type inference *and* RAII.

eeeh .. ?
no no, that's awful!!
why would a RAII declaration have no "new"? Is it because it's going to be on the stack?
Why don't you instead introduce a special case for "new" to make it allocate on the stack, i.e.

var c = new(stack) Class(); //or newStack Class(); //or something else

which is a clean straight-forward version of:
http://digitalmars.com/d/memory.html#stackclass
November 12, 2006
Sean Kelly wrote:
> Walter Bright wrote:
> 
>> The auto storage class currently is a little fuzzy in meaning, it can mean "infer the type" and/or "destruct at end of scope".
> 
> As Don explained to me, 'auto' is a storage class in D and in C along with 'const' and 'static', so type inference doesn't occur because 'auto' is present so much as because a type is omitted.  The presence of 'auto' merely serves to indicate that the statement is a declaration (since 'auto' is the default storage class and therefore otherwise optional).  

Interesting.  That does kinda make sense when seen in that light.  So it does just mean 'an automatic variable' in the traditional K&R sense.

Still don't like it.  I can understand that there is some logic behind the madness now, but the logic still doesn't seem like a good justification for confusing special cases.   I mean given that meaning of auto,  "auto Class c = foo()" should have no more implications than than that of "auto int c = foo()".  It should mean stack memory is automatic.  If you want to clean up the object too, then you need something else, like another 'auto'.  So that would be

   int c = foo(); // automatic stack (normal)
   Class c = foo(); // automatic stack (normal)
   auto int c = foo() // automatic statck (normal)
   auto Class c = foo() // automatic stack (normal)
   auto c = foo() // automatic stack, type omitted so inferred
   auto auto Class c = foo() // automatic stack *and* automatic heap
   auto auto c = foo() // auto stack *and* auto heap *and* type omitted

Throwing in the special case rule 'if the thing is an object then you can leave off one auto' just creates confusion.

>> In the future, I'd like the following to work:
>>
>> 5) auto c = Class();
>>
>> which would mean type inference *and* RAII.
> 
> 
> I like this.  It is consistent with the declaration of other types in D ('new' means dynamic, otherwise scoped), and it associates scoped destruction with the data rather than with the reference which is exactly as it should be.  

But it is ambiguous with static opCall.  That doesn't bother you?

This works now, but I don't see how it could with the above:
------
import std.stdio:writefln;

class Class {
    static bool opCall() { return true;  }
    this() { }
}
void main()
{
    auto a = Class();
    auto b = new Class();

    writefln("typeof a: ", typeid(typeof(a)));
    writefln("typeof b: ", typeid(typeof(b)));
}
------

--bb
November 12, 2006
On Sat, 11 Nov 2006 14:22:19 -0500, Chris Miller <chris@dprogramming.com> wrote:

> On Sat, 11 Nov 2006 13:48:00 -0500, Walter Bright <newshound@digitalmars.com> wrote:
>
>> The auto storage class currently is a little fuzzy in meaning, it can mean "infer the type" and/or "destruct at end of scope". The latter only has meaning for class objects, so let's look at the syntax. There are 4 cases:
>>
>
> Choosing from your list I guess "auto" for auto destruction and "infer" for auto type deduction.
>
> However, I tend to prefer "scope" (without parentheses following) for auto destruction, which frees up "auto" for auto type deduction:
>
>     scope Object o = new Object(); // Destructed at end of scope.
>     scope auto q = new Foo(); // Auto type deduction and end-of-scope destruction.

Actually, could probably also reuse "typeof" for auto type deduction:

   typeof x = new X;
November 12, 2006
Tydr Schnubbis wrote:
> Chris Nicholson-Sauls wrote:
> 
>>> Considering that scope already exists as a keyword, I find this an excellent
>>> suggestion that is also very much clearer in meaning (I find auto to miss
>>> the target for both cases really :P ).
>>>
>>
>> I've already said it before, but it bears repeating yet again.  I also prefer 'scope' for this.  Although 'infer' wouldn't be bad -- but please, please, please, not 'var'!  It smells too much like a scripting language construct, and besides, my Bovis code is overflowing with actual variables named var.  (Probably because of the BVar struct that it passes most values around as.  Go figure.)
>>
> 
> 'scope' and 'infer' sound good to me, very to-the-point and unambiguous.  No need to make people wonder if 'auto' works like in C or not, etc. Just drop it.

"scope" seems a pretty popular suggestion.
I find it not so bad myself, but I would prefer "scoped" because it's less ambiguious.  "scope" makes sense if you think of scope as a verb (scope this variable), but just seeing it outside of a sentence it looks like a noun (this variable is a scope -- huh?), simply because 'scope' isn't used as a verb very often in English.

'scoped' is clearly an adjective, as in 'this variable is scoped'.  And being an adjective puts it in good company with most of the other storage classes which are also adjectives: (abstract, auto(matic), const(ant), deprecated, extern(al), final, static, synchronized).  The only non-adjective storage class is 'override'.  I have no idea why it's not "overridden".  It should be.  At least override reads clearly, whether you take it to be a noun (this is an override) or a verb (override the method).  "Scope" does not have this property.  "This is a scope" does not make sense.

--bb
November 12, 2006
Bill Baxter wrote:
> Sean Kelly wrote:
>> Walter Bright wrote:
>>
>>> The auto storage class currently is a little fuzzy in meaning, it can mean "infer the type" and/or "destruct at end of scope".
>>
>> As Don explained to me, 'auto' is a storage class in D and in C along with 'const' and 'static', so type inference doesn't occur because 'auto' is present so much as because a type is omitted.  The presence of 'auto' merely serves to indicate that the statement is a declaration (since 'auto' is the default storage class and therefore otherwise optional).  
> 
> Interesting.  That does kinda make sense when seen in that light.  So it does just mean 'an automatic variable' in the traditional K&R sense.
> 
> Still don't like it.  I can understand that there is some logic behind the madness now, but the logic still doesn't seem like a good justification for confusing special cases.   I mean given that meaning of auto,  "auto Class c = foo()" should have no more implications than than that of "auto int c = foo()".  It should mean stack memory is automatic.  If you want to clean up the object too, then you need something else, like another 'auto'.

Agreed.

>>> In the future, I'd like the following to work:
>>>
>>> 5) auto c = Class();
>>>
>>> which would mean type inference *and* RAII.
>>
>>
>> I like this.  It is consistent with the declaration of other types in D ('new' means dynamic, otherwise scoped), and it associates scoped destruction with the data rather than with the reference which is exactly as it should be.  
> 
> But it is ambiguous with static opCall.  That doesn't bother you?

It does.  But I'm not sure I prefer the only viable alternative in my mind:

MyClass c = scoped MyClass();

(ie. replace 'new' with something else)


Sean
November 12, 2006

Walter Bright wrote:
> The auto storage class currently is a little fuzzy in meaning, it can mean "infer the type" and/or "destruct at end of scope". The latter only has meaning for class objects, so let's look at the syntax. There are 4 cases:
> 
> class Class { }
> 
> 1) auto c = new Class();
> 2) auto Class c = new Class();
> 3) auto c = some_expression();
> 4) auto Class c = some_expression();
> 
> The ambiguity can be resolved by saying that if auto is used for type
> inference, i.e. cases (1) and (3), then it does not mean RAII. If it is
> not used for type inference, i.e. cases (2) and (4), then it does mean
> RAII.

What I would prefer is if you introduced a new keyword that meant "declare".  Just that.  auto is currently used for type inference not because it MEANS "infer the type" but because it's the default storage class.  Currently, declarations look like this:

  [storage class] [type] [name]

We can omit the type if we supply the storage class, or we can omit the storage class if we supply the type.  But there's no way to omit both. So I propose that you add a new keyword so that declarations become the following:

  [declaration] [storage class] [type] [name]

This way, we can omit [declaration] if we supply either [storage class] or [type], omit [storage class] if we supply [declaration] or [type], and can omit [type] if we supply [declaration] or [storage type].

Let's say the keyword is chosen to be "def" (being short for "define").
 This gives us:

> Class c = new Class();	// normal decl.
> def Class c = new Class();	// as above
>
> auto Class c = new Class();	// RAII decl.
> def auto Class c = new Class(); // as above
>
> auto c = new Class();		// RAII with type inference
> def auto c = new Class();	// as above
>
> def c = new Class();		// type inference with no RAII

Another keyword choice could be "let" (which allows you to "read" the declaration out loud).  "var" makes no sense since you could conceivably put it before a "const", and that doesn't make any sense:

> var const x = foo;  // Is it a constant or a variable??

This will let you keep the "auto" keyword, whilst still giving us what we want -- everybody wins!

> In the future, I'd like the following to work:
> 
> 5) auto c = Class();
> 
> which would mean type inference *and* RAII.

Please, no.  It breaks static opCall (which I *do* use), and makes no sense.  Everywhere else in D requires the "new" keyword; why not for this one particular case?

On a related note, I don't suppose I could ask you to take a second look at my old proposal on allowing auto objects to be returned from functions, could I? :P  It is one of the very, very few things I'd still like to see in D 1.0.

<http://www.digitalmars.com/d/archives/digitalmars/D/38329.html>

	-- Daniel

-- 
Unlike Knuth, I have neither proven or tried the above; it may not even make sense.

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/
November 12, 2006
> Please excuse my bash and amateur crashing in here ... but Walter, for a very intelligent person, why is it that you just don't get it?

Didn't you mean "bright person" ? :P

> (a) Get rid of 'auto'.
I completely agree. The current "auto" can then be tagged as deprecated and removed Jan 1st!

> (b) Create a new keyword that is more obviously read as 'type inference'.
I like "var".

> (c) Create a new keyword that is more obviously read as 'resource
> destruction at end of scope'.
I like "scope"

L.


November 12, 2006
Sean Kelly wrote:
> Walter Bright wrote:
>> The auto storage class currently is a little fuzzy in meaning, it can mean "infer the type" and/or "destruct at end of scope".
> 
> As Don explained to me, 'auto' is a storage class in D and in C along with 'const' and 'static', so type inference doesn't occur because 'auto' is present so much as because a type is omitted.  The presence of 'auto' merely serves to indicate that the statement is a declaration (since 'auto' is the default storage class and therefore otherwise optional).  Type inference occurs with the other storage classes as well.  I think this is an important distinction because it seems to be a common misconception that 'auto' means 'infer the type of this expression' and that a specific label is necessary for this feature.

True. Consider that type inference works in these cases:

	static a = 3;	// a is an int
	const b = '3';	// b is a char

So auto doesn't actually ever mean "infer the type", it's just needed because one of the other storage class keywords isn't there.
November 12, 2006
Daniel Keep wrote:
> On a related note, I don't suppose I could ask you to take a second look
> at my old proposal on allowing auto objects to be returned from
> functions, could I? :P  It is one of the very, very few things I'd still
> like to see in D 1.0.
> 
> <http://www.digitalmars.com/d/archives/digitalmars/D/38329.html>

It's an interesting proposal. What I was thinking of eventually for 'auto' is to generalize that it means that the value cannot escape its scope. An auto class member could then be destructed when the class was destructed; an auto function parameter cannot escape the function call, etc. But I haven't really thought about it very far.