auto, var, raii,scope, banana

Regan Heath regan at netwin.co.nz
Wed Jul 26 03:34:00 PDT 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



More information about the Digitalmars-d mailing list