November 12, 2006
Walter Bright escribió:
> 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.

Is backward compatibility the main restriction that stops you from selecting two keywords distinct from "auto" (and a lot of other unclear stuff)?

If it's that, what you can do is propose a final, clean syntax for version 1.0 and get the programmers to update their codes to v1.0. I guess they will do that, at least active projects: old, abandoned projects sure will fail, as probably they fail now with some last language modifications.

I think no one but you want's to keep the "auto" keyword.

--
Ary
November 12, 2006
On Sun, 12 Nov 2006 10:44:37 +1100, Derek Parnell wrote:

> On Sat, 11 Nov 2006 10:48:00 -0800, Walter Bright wrote:
> 
>> The auto storage class currently is a little fuzzy in meaning

By the way, I refuse to use the current 'auto' nowadays precicely because it adds to the cost of code maintenance, due to its ability to confuse and/or mislead code readers.

-- 
Derek Parnell
November 12, 2006

Derek Parnell wrote:
> On Sun, 12 Nov 2006 10:44:37 +1100, Derek Parnell wrote:
> 
>> On Sat, 11 Nov 2006 10:48:00 -0800, Walter Bright wrote:
>>
>>> The auto storage class currently is a little fuzzy in meaning
> 
> By the way, I refuse to use the current 'auto' nowadays precicely because
> it adds to the cost of code maintenance, due to its ability to confuse
> and/or mislead code readers.
> 

I do use auto, but only because I never use RAII, so there's no room for confusion (for me) when I read my code.
November 12, 2006
Derek Parnell wrote:
> On Sun, 12 Nov 2006 10:44:37 +1100, Derek Parnell wrote:
> 
> 
>>On Sat, 11 Nov 2006 10:48:00 -0800, Walter Bright wrote:
>>
>>
>>>The auto storage class currently is a little fuzzy in meaning
>>>class Class { }
>>>
>>>1) auto c = new Class();
>>>2) auto Class c = new Class();
>>>3) auto c = some_expression();
>>>4) auto Class c = some_expression(); 

>>>5) auto c = Class(); 

At least the first 4 have some consistent logic behind them, but #5 is just pure special casing for something that's not all that common or special.  It should just be

    auto auto c = new Class();

Besides Class may have a static opCall, no?

Anyway, to me, all these things look harder to disinguish than even the a..b vs a...b thing, which you didn't like, so I'm baffled as to why you are so resistant to make 'auto' usages easier to distinguish.

> By the way, I refuse to use the current 'auto' nowadays precicely because
> it adds to the cost of code maintenance, due to its ability to confuse
> and/or mislead code readers.

Agreed.  I stick with auto for auto-type inference, but I don't go near the other usage because it's just too confusing to have two different kinds of auto's in my code that can appear in such similar syntactic situations.  I have my preferences as already stated, but I would be satisfied, if not overjoyed, with any solution that
  A) makes the keywords for RAII and ATI distinct, and
  B) doesn't make the ATI keyword any longer than it already is.

Part of why I want auto for ATI to be short is that will get a lot of use.  There are already 50 or so uses of auto in phobos/std/*.d.  It looks like maybe 2 are RAII things but the rest are all ATI.

So ATI is more common than RAII.  Maybe ATI is common enough that it even warrants special syntax?  If so then I think the at-sign makes sense for that. "AuTo"->"at" -- close enough for a mnemonic.  That would mean "auto foo" could be compressed to "@foo".

Some examples of what it would look like:

   @ foo = some_expression();
   @bar = other_thing();

   for (@v = start; v<end; v++) {...}

   if (@m = std.regexp.search("abcdef", "c()"))

   @dim = this.dim();

   sort(list, @(@a,@b){ return a.val-b.val; }
     // though I think in this case it should be allowable to omit the
     // auto's/@'s and just have sort(list, (a,b){...});

--bb
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.

Well, you know my view here: we need two separate keywords.

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

Maybe, when both autotyping and scoped variables are commonplace, we'll eventually start wanting a single word to denote both. That word could be "auto".

But in the meantime, two separate words, none of which is auto.
November 12, 2006
Bill Baxter wrote:
> Derek Parnell wrote:
> 
> So ATI is more common than RAII.  Maybe ATI is common enough that it even warrants special syntax?  If so then I think the at-sign makes sense for that. "AuTo"->"at" -- close enough for a mnemonic.  That would mean "auto foo" could be compressed to "@foo".
> 
> Some examples of what it would look like:
> 
>    @ foo = some_expression();
>    @bar = other_thing();
> 
>    for (@v = start; v<end; v++) {...}
> 
>    if (@m = std.regexp.search("abcdef", "c()"))
> 
>    @dim = this.dim();
> 
>    sort(list, @(@a,@b){ return a.val-b.val; }
>      // though I think in this case it should be allowable to omit the
>      // auto's/@'s and just have sort(list, (a,b){...});

Addendum:

I personally find the implicit 'auto' in foreach to be a little jarring.  Every time I see

    foreach(e; elements) {}

I find myself looking around for where e is declared.   Especially since foreach looks so much like a variation on a for loop, but 'auto' isn't automatic in a for loop in D (though after I learned about foreach, I assumed incorrectly it would work in D's for-loop too.).

Additionally I keep getting bitten by things like
    int i;
    for (i=1; i<10; i++) {
    }
    ...
    foreach(i,elem; elements) {
       if (...) break;
    }
    writefln("last i was", i)

Which using 'foreach-is-like-for' mentality seems perfectly natural but causes the compiler to complain.

Anyway, @e might be short enough that there wouldn't be any need to special case the foreach.  Just use

    foreach(@i,@e; elements) { ... }

--bb
November 12, 2006
"Walter Bright" <newshound@digitalmars.com> wrote in message news:ej55ss$1g6m$1@digitaldaemon.com...
> 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();

No effing way, period.  That is unclear as sin.  That's like copy constructors in C++.

My preference would be a separate keyword which would take the place of the type entirely.  It would be treated by the compiler as a type, albeit one which is unknown until the initializer has been semantic'ed.  For example, let's call it 'var':

var x = 5;
var y = "hello";

typeof(x) yields int and typeof(y) yields char[].

This has the nice property of being forward-compatible with more interesting things down the road.  How about ATI specialization?

var[] x = someFunc();

where x must be an array of any type, which is automatically inferred.  It's probably not something that would be that necessary, but it's nice that something like this is possible.

Failing a change for ATI, I'll stick with my previously-proposed change for RAII: to use 'scope' as a storage class for a declaration to indicate that it's RAII.

scope A a = new A();
scope a2 = new A(); // use ATI since 'scope' functions as a storage class

That, or both:

scope var a2 = new A(); // RAII and ATI

In any case, I think the replies to this thread (and, well, just about every other thread that has EVER been started about this topic) show that you are in a very, very small minority when it comes to ideas about how ATI and RAII should be represented by the syntax.  Please do not pull a "just because C++ uses auto for ATI, D should too".  D is not going to become a unique language by taking (mis)features from C++ just to appease the nitpicky C++ crowd (which, by now, you should know full well can NEVER be pleased).


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".

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.

> 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.

This is how I currently understand the syntax to work, and once understood it seems fairly clear.  However, I don't like overloading the meaning of keywords if it can be avoided, particularly when both meanings apply to the same keyword used in the same context.  Also, I'm not sure I like specifying scoped destruction by modifying the reference variable instead of the data.  First, this confuses the idea of reference types in that the references themselves are scoped.  Second, this doesn't allow for compilers to create referenced data on the stack as a QOI feature because the auto-destruction quality is attached to the reference, not the data.  For example:

    class MyClass
    {
        this( char[] s )
        {
            label = s;
        }

        ~this()
        {
            printf( "dtor: %.*s\n", label );
        }

        char[] label;
    }

    void main()
    {
        {
            auto MyClass c = new MyClass( "a" );
            c = new MyClass( "b" );
        }
        printf( "done\n" );
    }

prints:

    dtor: b
    done
    dtor: a

If the current syntax is to be preserved, I would suggest that auto references at least not be reassignable to prevent this behavior.

> 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.  In fact, if I had any request related to this syntax it would be that the ctor aspect eventually be available for concrete types as well.  Not an urgent request as it would be a new feature, but I thought I'd mention it anyway.  Also, I don't see any reason to tie stack vs. heap construction to this new syntax.  It could remain a QOI feature for compilers as far as I'm concerned.

By the way, I assume this change would do away with:

    auto class MyClass {}

as a valid declaration syntax as well?  Just wanted to be clear on this.


Sean
November 12, 2006
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.
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.

It just occurred to me that since it's not the keyword itself that makes type inference happen, but the lack of a type specifier, maybe 'var' is better than 'infer' after all.  I mean, since it doesn't really do anything, per se.