July 26, 2006
Regan Heath schrieb:
> I don't use "var" specifically but I have been known to use tmp, x, y, i, j, p, s, n, .. for all my temporary and/or meaningless variables. They typically have a short scope life and I can't see a problem with this practice.
I don't either as there will never be a one letter keyword. As for "tmp" it is a lot more descriptive than "var". Not all variables are holding temporary values but all are "variable" as their name already implies. Even i(=index) or n(=number of) bear a meaning in a mathematical context. I'm not all against short variable names (though I try to usually be more expressive) but their name should hint at their content or use. "var" doesn't hint at anything.


> I think Kris's point is that of the two choices 'var' and 'auto' the latter is less likely to annoy someone by colliding with existing user variables. The point is valid so long as the group of 'var' users is bigger than the group of 'auto' users, even if both groups are small.
One should also consider future users of D since we haven't even reached 1.0 yet. Since no one else already uses "auto" for this purpose but a lot of languages use "var" I believe it to be the more intuitive option.


> C++ may be an abomination but it does have 'market' dominance. You have to ask 'why'. You should learn from your 'enemies' ;)
But those reasons are mainly historical and may be summed up by "it's the least of all evils". This does not even hold true anymore. At least not when you look at language constructs and elegance. It's clearly "grown" not designed.


Regards,
Nils
July 26, 2006
Nils Hensel wrote:
> kris schrieb:
>> Don has a good point: changing to "var" would cause conflict with existing variable-names.
> 
> I'm sorry but I don't believe there are many programmers out there actually using something as undescriptive as "var" as a regular identifier. 

Maybe my first impression of the google search yourself -- the data is there.

I also strongly believe that no one should. It's the
> implication of a maintenance nightmare.

> I don't intend to insult Don in any way but it's a horrible practice IMNSHO that should not be preserved.

I don't understand. I can't see the difference between 'var' and 'x'.
Do you also dislike use of 'i' as a counter variable in a for loop?
(And if not, what is the difference?)

> So let's not focus on some odd minority but rather on the wide use of "var" in the context of type inference and dynamic typing.

'var' is inappropriate in a statically typed language. Remember that 'static's are variables too. Note that 'auto' was one of the original C keywords, and was chosen without any constraint (no legacy code whatsoever, they could have chosen any name, including 'var'). Every variable was classed into either:

static
auto
register

> Also I don't think that it's a good habit to be looking at how C++ does something unless one is looking for a bad example. My main reason for interest in D is because personally I'm fed up with C++ and consider it an abomination and a major PITA.

Agreed, but the 'auto' thing ultimately comes from C, not C++.
July 26, 2006
Regan Heath wrote:
> On Tue, 25 Jul 2006 23:28:24 -0400, Chad J  <gamerChad@_spamIsBad_gmail.com> wrote:
> 
>> Regan Heath wrote:
>>
>>>   I say lets keep 'auto' for auto type inference (for the reasons you  and  Don mention)
>>>  I like the use of scope at class decl. But, I prefer the no keyword   approach at instantiation. So, allow me to suggest this as a 3rd option.
>>>  - 'scope' at class decl.
>>> - no keyword at instatiation.
>>>  Reasoning:
>>>  'new' implies heap allocation to me. It would be beneficial to allow  the  compiler to allocate an RAII type in any way it wants, perhaps  stack  allocating it. Removing 'new' removes the implied heap  allocation allowing  the compiler to allocate however it likes.
>>>
>>
>> I disagree.
>>
>> If you want the compiler to be able to optimize by using stack  allocation instead of heap allocation, then let it do that with the new  keyword.
> 
> 
> You miss-understand. I don't want stack allocation at all. I'm saying 2  things:
> 
> 1. 'new' implies heap allocation
> 2. lack of 'new' implies _nothing_ about allocation.
> 
> The result of which is that the compiler is not _required_ to heap  allocate but can allocate in some other fashion.
> 

That's actually what I thought you meant, though I am probably creating a false dichotomy - stack vs heap.

>> I'm assuming the program's behaviour would be the same in either case,  so it wouldn't matter to me.
>>
>> If you want stack allocation then how about
>> scope A a = A();
>>
>> It keeps the concepts of scope and allocation seperate.
> 
> 
> It's no different to this:
> 
> A a = A();
> 
> which says _nothing_ about allocation. It implies only that 'a' will be  collected at the end of scope.
> The compiler is FREE to allocate however it wants. That _may_ be stack  allocation, it _may_ not.
> 
> In comparison this:
> 
> A a = new A();
> 
> currently 'implies' heap allocation.
> 
> That's all I was saying. I'm not suggesting stack allocation, I'm  suggesting that removing 'new' allows the compiler to allocate however it  wants.
> 
> You're suggesting 'new' could allocate on the stack, I think that would be  unexpected to say the least.
> 

I did intend to convey that the 'new' keyword could have this ambiguity, but under one condition - that it not change the behaviour of the program.

If you need something more hardcore than that, something that causes undefined behaviour, I ask that it not be at the expense of current features.

>> Scope is not allocation.
> 
> 
> Correct. I never said it was. The ability to stack allocate is a by  product of removing 'new' nothing else.
> 
>>> I don't see the utility in static opCall, I say abolish/remove it.   Non-static opCall on the other hand can be quite useful.
>>>  Regan
>>
>>
>> Please don't abolish/remove it.  At least not until you have convinced  me that it is totally useless.
> 
> 
> Convince you.. I don't have to convince you, only Walter.
> Likewise you have to convince Walter.
> ;0)
> 

True, you are not required to convince me of anything.  It was a request.  You seem to have some good reasons for prefering this syntax, so please enlighten me.  It's kind of a helpfulness thing; saves me some grief from having a feature removed that I like.  If I agree with you, there is no grief, only joy :).

>> I really don't like the idea of dropping a language feature just for the  sake of having a particular syntax that, IMO, is not intuitive.
> 
> 
> It's the same syntax you see in C++ for a class that has it's destructor  called at the end of the scope. That, to me, makes it intuitive. For what  reason do you find it un-intuitive?
> 

I do not originate from C++, more like C#/Java.  I do know some C++ though, and most of my experiences with it have been frustrating bad ones.  Anyhow, before I go on that tangent, not everyone is a C++ programmer.

I say it's unintuitive because it is implicit - it provides no explicit information to the reader.  Since the absence of anything explicit gives no information, you might as well use the keyword asdfqwertok.  Even that gives more information than a blank space.  For a D newbie reading code, having a keyword is good because it gives them a keyword to search the spec for.  Better yet if it is 'scope', because that gives them an idea of where to look.  This is also one of those things that is used seldom enough that the succinctness gained from implicit things is only slightly helpful.

In a nutshell: assume a programmer of undefined language background, and I believe 'scope' will be much more informative (and therefore intuitive) than a blank space.

>>  From my previous post about this:
>>
>>> I like being able to use types as functions.
>>> Here's one example where I do something similar to what you'd use  nested functions for, but better - my forward referencing woes go away.
>>>  class F
>>> {
>>>     int result;
>>>     int tempVar1;
>>>      static int opCall( int x )
>>>     {
>>>         F f = new F(x);
>>>         int result = f.result;
>>>         delete f;
>>>         return result;
>>>     }
>>>      this( int x )
>>>     {
>>>         internalFunc1();
>>>         // do stuff
>>>     }
>>>      private void internalFunc1()
>>>     {
>>>         if ( maybe )
>>>             internalFunc2();
>>>         else return;
>>>     }
>>>      private void internalFunc2()
>>>     {
>>>         if ( maybe )
>>>             internalFunc1();
>>>         else return;
>>>     }
>>> }
>>>  void main()
>>> {
>>>     int x = 42;
>>>     x = F(x);
>>> }
>>>  Under the hood, it may also behave differently than nested functions,  which could be advantageous.  I'm not sure that it is advantageous, but  options are always nice.
>>>  That and you can make nice syntax sugars for alternative memory  management methods like freelists, without messing with overriding  'new()'.
> 
> 
> What's the point of using static opCall here, as opposed to a normal  static method or even a free function?

Why not a normal static method? - implementation hiding.
Why not a free function? - I'm assuming you mean a normal function declared at module scope.  It allows you to have multiple functions with access to the same non-static variables (member variables).  I suppose this is usually accomplished with nested functions, or OOP that can't do implementation hiding.  Doing it this way allows me to avoid forward referencing issues and also gives me more options about how my code behaves.

> What problem does it solve?

Annoyance from forward referencing in nested functions, but that's just one.  Maybe a small degree of implementation hiding for memory management, though I haven't tried this enough to demonstrate it.  It is not really a solution.  It is a technique, a syntax sugar, or just an easy way to get D to do things you would not ordinarily make it do.

> What new technique or method does it allow?

Multiple functions using the same non-static variables with no need for forward referencing and possible code behaviour tweaks, etc yadda yadda.  I admit it's not horribly important, but I don't think that this choice of syntax is either.  Most of all, I like it.

*sigh* those were long winded answers, sorry about that.

> 
>> I do like using the scope keyword for this btw.  It seems quite  consistant with D's meaning of 'scope'.
> 
> 
> It's not bad but it's my 2nd choice currently.
> 
> Regan

Care to explain why static opCall is a hack and/or not useful outside of RAII or struct constructors?
July 26, 2006
vote++;
//me likes

kris wrote:
> Don has a good point: changing to "var" would cause conflict with existing variable-names.
> 
> Chad et. al. also have a good point about the conflict regarding static opCall() (via the lack of a "new" keyword). I suspect many people find the use of "new" to be indicative of allocation, and breaking this consistency may have a detrimental effect? Further, it was noted that a missing "new" can only be used at the instantiation site -- not at the class decl -- thus, D would be losing an existing feature.
> 
> I suspect you could count the current number of raii-class uses on a few hands, whereas the use of "auto" for implied-type is pretty darned popular -- and rightly so, since it's really very, very useful. Changing the raii style to use a different keyword, whilst retaining implied-type "auto" would be an almost imperceptible change?
> 
> Thus, it would appear to make sense to retain "auto" for implied-type, and introduce something *else* for automatic cleanup at end-of-scope (and also as a class attribute). how about reusing the "scope" keyword?
> 
> void main()
> {
>   auto i = 10;
>   auto foo = new Foo;
>   auto scope bar = new Bar;
>   auto scope wumpus = new Wumpus;
> }
> 
> class Foo {}
> 
> class Bar {}
> 
> scope class Wumpus {}
> 
> 
> 
> 
> 
> 
July 26, 2006
> I say lets keep 'auto' for auto type inference (for the reasons you and Don mention)

agreed.

> I like the use of scope at class decl. But, I prefer the no keyword approach at instantiation. So, allow me to suggest this as a 3rd option.
> 
> - 'scope' at class decl.
> - no keyword at instatiation.
> 
> Reasoning:
> 
> 'new' implies heap allocation to me. It would be beneficial to allow the compiler to allocate an RAII type in any way it wants, perhaps stack allocating it. Removing 'new' removes the implied heap allocation allowing the compiler to allocate however it likes.

Why would you want to deal with where the object is allocated? Besides speed, is there any reason at all to allocate on the stack?

If you always type the same thing, the compiler is always free to choose the best location. If you restrict "new" to allocating on the heap, you prevent the compiler from optimizing (by allocating on the stack) whenever it determines it's safe to do so (scoped variables are not the only such case).

Imho, "scope" is a perfect keyword for scoped variables/classes, for reasons already stated (already exists, good meaning, explicit). A missing "new" is not a good keyword ;)

By the way, I think it would be wise to require references to scope-classes also be tagged with scope, so it'd be harder to miss that not-so-insignificant detail about them..

> I don't see the utility in static opCall, I say abolish/remove it. Non-static opCall on the other hand can be quite useful.

But there is utility in static opCall in structs; having them there but not in classes doesn't sound to cool/consistent..


xs0
July 26, 2006
>>> Please don't abolish/remove it.  At least not until you have convinced  me that it is totally useless.
>>   Convince you.. I don't have to convince you, only Walter.
>> Likewise you have to convince Walter.
>> ;0)
>>
>
> True, you are not required to convince me of anything.  It was a request.  You seem to have some good reasons for prefering this syntax, so please enlighten me.

I've already said.. I think it's intuitive because it 'looks' like a class declared on the stack, as in C++ and like those it will be destroyed at the end of scope. Your counter argument is that not everyone is a C++ programmer, correct? In which case, read on..

>>> I really don't like the idea of dropping a language feature just for the  sake of having a particular syntax that, IMO, is not intuitive.
>>   It's the same syntax you see in C++ for a class that has it's destructor  called at the end of the scope. That, to me, makes it intuitive. For what  reason do you find it un-intuitive?
>>
>
> I do not originate from C++, more like C#/Java.  I do know some C++ though, and most of my experiences with it have been frustrating bad ones.  Anyhow, before I go on that tangent, not everyone is a C++ programmer.

I come from a C background. I have done a little C++, a little Java and very little C#.

> I say it's unintuitive because it is implicit - it provides no explicit information to the reader.  Since the absence of anything explicit gives no information, you might as well use the keyword asdfqwertok.  Even that gives more information than a blank space.

The absence of 'new' gives us the required information. You are required to know what the absense of 'new' _means_ just like you are required to know what keyword X means in any given context. In short, some knowledge of programming in D is required to program in D.

To expand on why I think it's intuitive let look at 2 scenarios, first the C++ programmer trying D. Likely their first program involving classes will look like this:

class A {
  int a;
}

void main() {
  A a = A();
  writefln(a.a);
}

currently, this crashes with an access violation. Add the new RAII syntax and not only does it not crash, but it behaves just like a C++ program would with A being destroyed at the end of scope.

Now, take a Java/C# programmer, their first program with classes will be:

class A {
  int a;
}

void main() {
  A a = new A();
  writefln(a.a);
}

No crash, and the behaviour they expect.

Then imagine the same programmers looking at each others code, the C++ programmer will understand 'new' to indicate heap allocation and the Java/C# programmer will need to ask the C++ programmer what the absense of 'new' means, he'll reply that the class is destroyed at the end of scope. He might also say it's stack allocated, but that's fine, both of them have something to learn, and it has no effect on the way the program behaves.

Simple, intuitive and elegant no matter what your background. Of course, if you're a Java/C# programmer you have to 'learn' what the absense of 'new' means. Both have to learn that D might not stack allocate the RAII class instance.

If we use a 'scope' keyword then both sets of programmers have some learning to do. It's not much worse, but this makes it my 2nd choice.

> For a D newbie reading code, having a keyword is good because it gives them a keyword to search the spec for. Better yet if it is 'scope', because that gives them an idea of where to look.  This is also one of those things that is used seldom enough that the succinctness gained from implicit things is only slightly helpful.

The C++ programmer will already know what it does.
The Java/C++ programmer will search for 'new' (because it's absent).
In either case they'll find the docs on RAII at the same time as they find the docs on 'new'.

> In a nutshell: assume a programmer of undefined language background, and I believe 'scope' will be much more informative (and therefore intuitive) than a blank space.

I've assumed programmers from 2 types of background above, I still think removing 'new' is better than adding 'scope'.

>>>  From my previous post about this:
>>>
>>>> I like being able to use types as functions.
>>>> Here's one example where I do something similar to what you'd use  nested functions for, but better - my forward referencing woes go away.
>>>>  class F
>>>> {
>>>>     int result;
>>>>     int tempVar1;
>>>>      static int opCall( int x )
>>>>     {
>>>>         F f = new F(x);
>>>>         int result = f.result;
>>>>         delete f;
>>>>         return result;
>>>>     }
>>>>      this( int x )
>>>>     {
>>>>         internalFunc1();
>>>>         // do stuff
>>>>     }
>>>>      private void internalFunc1()
>>>>     {
>>>>         if ( maybe )
>>>>             internalFunc2();
>>>>         else return;
>>>>     }
>>>>      private void internalFunc2()
>>>>     {
>>>>         if ( maybe )
>>>>             internalFunc1();
>>>>         else return;
>>>>     }
>>>> }
>>>>  void main()
>>>> {
>>>>     int x = 42;
>>>>     x = F(x);
>>>> }
>>>>  Under the hood, it may also behave differently than nested functions,  which could be advantageous.  I'm not sure that it is advantageous, but  options are always nice.
>>>>  That and you can make nice syntax sugars for alternative memory  management methods like freelists, without messing with overriding  'new()'.
>>   What's the point of using static opCall here, as opposed to a normal  static method or even a free function?
>
> Why not a normal static method? - implementation hiding.

I'm assuming this defintion:
http://en.wikipedia.org/wiki/Information_hiding

I'm not sure I follow your logic, did you mean "encapsulation" instead?

If you did mean "information hiding" then it seems to me that using opCall is a design decision, just as using a method called "Bob" would be. The advantage to using "Bob" is that you can define an 'stable' interface eg.

interface MyImplementation {
  int Bob(int x);
}

and in that way protect your code against changes in implementation. In short, this is a better "information hiding" solution than using static opCall.

> Why not a free function? - I'm assuming you mean a normal function declared at module scope.

Yes.

> It allows you to have multiple functions with access to the same non-static variables (member variables).

What does?

_static_ opCall does *not* have access to non-static variables, it can only access static variables. Static methods and variables are very similar to module level variables. The difference being how to access them (class name prefix) and where they are declared (inside the class instead of at module level). You can replace static methods and variables with module level ones quite easily.

> I suppose this is usually accomplished with nested functions, or OOP that can't do implementation hiding.

I'm obviously not following your point here.. can you elaborate, perhaps another example?

> Doing it this way allows me to avoid forward referencing issues

What forward referencing issues does the code above have?

> and also gives me more options about how my code behaves.

What options? example?

>> What problem does it solve?
>
> Annoyance from forward referencing in nested functions, but that's just one.  Maybe a small degree of implementation hiding for memory management, though I haven't tried this enough to demonstrate it.  It is not really a solution.  It is a technique, a syntax sugar, or just an easy way to get D to do things you would not ordinarily make it do.

So far:
- I'm not seeing the forward reference issue(s)
- It seems like a worse way to implement information hiding (than an interface and method).

>> What new technique or method does it allow?
>
> Multiple functions using the same non-static variables with no need for forward referencing and possible code behaviour tweaks, etc yadda yadda.   I admit it's not horribly important, but I don't think that this choice of syntax is either.  Most of all, I like it.

I *like* non-static opCall, I can see benefits to that. But, so far, static opCall seems to be fairly useless to me.

> *sigh* those were long winded answers, sorry about that.

No worries. Long winded tends to imply more information and that's not a bad thing.

>>> I do like using the scope keyword for this btw.  It seems quite  consistant with D's meaning of 'scope'.
>>   It's not bad but it's my 2nd choice currently.
>>  Regan
>
> Care to explain why static opCall is a hack and/or not useful outside of RAII or struct constructors?

I'm trying, by learning when, where and why you use it. I can't think of a place where _I_ would use it (which is why I think it's not useful).

It's only a 'hack' when used with a struct to emulate a constructor. Strangely that 'hack' is the only vaguely good use I've seen for a *static* opCall.

Regan
July 26, 2006
On Wed, 26 Jul 2006 11:58:31 +0200, xs0 <xs0@xs0.com> wrote:
>> I say lets keep 'auto' for auto type inference (for the reasons you and Don mention)
>
> agreed.
>
>> I like the use of scope at class decl. But, I prefer the no keyword approach at instantiation. So, allow me to suggest this as a 3rd option.
>>  - 'scope' at class decl.
>> - no keyword at instatiation.
>>  Reasoning:
>>  'new' implies heap allocation to me. It would be beneficial to allow the compiler to allocate an RAII type in any way it wants, perhaps stack allocating it. Removing 'new' removes the implied heap allocation allowing the compiler to allocate however it likes.
>
> Why would you want to deal with where the object is allocated?

My post _must_ have been missleading (more than one person thinks I want stack allocation).

I don't want stack allocation. I was simply raising the possibility of stack allocation as a possibly beneficial side-effect of removing 'new' (which implies/required heap allocation, AFAICS)

> Besides speed, is there any reason at all to allocate on the stack?

Speed isn't a good enough reason?

> If you always type the same thing, the compiler is always free to choose the best location. If you restrict "new" to allocating on the heap, you prevent the compiler from optimizing (by allocating on the stack) whenever it determines it's safe to do so (scoped variables are not the only such case).

Is it even possible for 'new' to allocate on the stack? I mean the stack vanishes when the function exits, therefore isn't 'new' restricted to the heap?

> Imho, "scope" is a perfect keyword for scoped variables/classes, for reasons already stated (already exists, good meaning, explicit). A missing "new" is not a good keyword ;)

I disagree, see my recent reply to "Chad J", specifically the scenarios involving the C++ and Java programmers.

>> I don't see the utility in static opCall, I say abolish/remove it. Non-static opCall on the other hand can be quite useful.
>
> But there is utility in static opCall in structs; having them there but not in classes doesn't sound to cool/consistent..

The only utility in static opCall is to emulate a constructor. Why not replace them with a constructor (ie. rename "static opCall" to "this"). Then, remove static opCall altogether.

Regan
July 26, 2006
>>> I don't see the utility in static opCall, I say abolish/remove it. Non-static opCall on the other hand can be quite useful.
>>
>> But there is utility in static opCall in structs; having them there but not in classes doesn't sound to cool/consistent..
> 
> The only utility in static opCall is to emulate a constructor. Why not replace them with a constructor (ie. rename "static opCall" to "this"). Then, remove static opCall altogether.
> 

I haven't been following this, but static opCall sounds an awful lot like a function call to a function with static variables... I must join the "who would want such a thing"-side.

/T
July 26, 2006
Nils Hensel wrote:
> Regan Heath schrieb:
>> I don't use "var" specifically but I have been known to use tmp, x, y, i, j, p, s, n, .. for all my temporary and/or meaningless variables. They typically have a short scope life and I can't see a problem with this practice.
> I don't either as there will never be a one letter keyword. As for "tmp" it is a lot more descriptive than "var". Not all variables are holding temporary values but all are "variable" as their name already implies. Even i(=index) or n(=number of) bear a meaning in a mathematical context. I'm not all against short variable names (though I try to usually be more expressive) but their name should hint at their content or use. "var" doesn't hint at anything.

It does. When I use it, 'var' is not an abbreviation of 'variable', it's an abbreviation of 'variant'.

>> I think Kris's point is that of the two choices 'var' and 'auto' the latter is less likely to annoy someone by colliding with existing user variables. The point is valid so long as the group of 'var' users is bigger than the group of 'auto' users, even if both groups are small.
> One should also consider future users of D since we haven't even reached 1.0 yet. Since no one else already uses "auto" for this purpose but a lot of languages use "var" I believe it to be the more intuitive option.
> 
> 
>> C++ may be an abomination but it does have 'market' dominance. You have to ask 'why'. You should learn from your 'enemies' ;)
> But those reasons are mainly historical and may be summed up by "it's the least of all evils". This does not even hold true anymore. At least not when you look at language constructs and elegance. It's clearly "grown" not designed.
> 
> 
> Regards,
> Nils
July 27, 2006
Regan Heath wrote:
> On Wed, 26 Jul 2006 11:58:31 +0200, xs0 <xs0@xs0.com> wrote:
>>> I like the use of scope at class decl. But, I prefer the no keyword approach at instantiation. So, allow me to suggest this as a 3rd option.
>>>  - 'scope' at class decl.
>>> - no keyword at instatiation.
>>>  Reasoning:
>>>  'new' implies heap allocation to me. It would be beneficial to allow the compiler to allocate an RAII type in any way it wants, perhaps stack allocating it. Removing 'new' removes the implied heap allocation allowing the compiler to allocate however it likes.
>>
>> Why would you want to deal with where the object is allocated?
> 
> My post _must_ have been missleading (more than one person thinks I want stack allocation).
> 
> I don't want stack allocation. I was simply raising the possibility of stack allocation as a possibly beneficial side-effect of removing 'new' (which implies/required heap allocation, AFAICS)

'new' doesn't imply/require that heap allocation actually be done, it just requires the result to behave as if it was (look up "escape analysis")

>> Besides speed, is there any reason at all to allocate on the stack?
> 
> Speed isn't a good enough reason?

Speed is a good reason to use stack allocation. But that is also a good reason to let the compiler determine where to place an object, not the programmer.


>> If you always type the same thing, the compiler is always free to choose the best location. If you restrict "new" to allocating on the heap, you prevent the compiler from optimizing (by allocating on the stack) whenever it determines it's safe to do so (scoped variables are not the only such case).
> 
> Is it even possible for 'new' to allocate on the stack? I mean the stack vanishes when the function exits, therefore isn't 'new' restricted to the heap?

No. There are many cases where the object is not actually required to be on the heap.

>> Imho, "scope" is a perfect keyword for scoped variables/classes, for reasons already stated (already exists, good meaning, explicit). A missing "new" is not a good keyword ;)
> 
> I disagree, see my recent reply to "Chad J", specifically the scenarios involving the C++ and Java programmers.

Well, I'm a Java programmer and if I see

A a = A();

I see a function call that returns something of type A. If I see

auto a = A();

I definitely see a function call. You'll never convince me that the lack of "new" is a good indication of anything, much less of the fact that it's a scoped variable.

> The only utility in static opCall is to emulate a constructor. Why not replace them with a constructor (ie. rename "static opCall" to "this"). Then, remove static opCall altogether.

Emulating a constructor is not the only utility, it's emulating an arbitrary function.


xs0