Jump to page: 1 2 3
Thread overview
Three improvements for constructor syntax
May 19, 2004
arcanejill
May 19, 2004
Norbert Nemec
May 19, 2004
arcanejill
May 19, 2004
Ivan Senji
May 19, 2004
Arcane Jill
May 19, 2004
Ivan Senji
May 19, 2004
Ant
May 19, 2004
Ivan Senji
May 20, 2004
Arcane Jill
May 20, 2004
Arcane Jill
May 20, 2004
Bent Rasmussen
May 21, 2004
vanh
May 21, 2004
vanh
May 21, 2004
vanh
May 19, 2004
Juan C
May 19, 2004
Pablo Aguilar
May 20, 2004
Juan C
May 19, 2004
Ant
May 19, 2004
Harvey
May 20, 2004
J Anderson
May 20, 2004
Arcane Jill
May 20, 2004
J Anderson
May 19, 2004
Hi guys,
My first suggestions for this forum - three improvements for constructor syntax.



1. The reserved word "new" is superfluous. It should be made optional. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In C++, the following two statements are both legal, but do different things:

(i)     T * a = new T(parameters);  // C++
(ii)    T b = T(parameters);        // C++

In case (i), the object is constructed on the heap (as in D), and the variable a
is assigned a pointer to it. In case (ii), the object is constructed on the
stack, and the variable b is assigned a reference to it. This distinction is
apparent in the way that member variables are later accessed:

(i)     x = a->memberVariable;      // C++
(ii)    y = b.memberVariable;       // C++

Now, NEITHER of these distinctions are relevant in D. Class objects are ALWAYS allocated on the heap, never on the stack, so there is no need for the "new" keyword to be present to distinguish the two cases. Further, D does not distinguish between the . operator and the -> operator, It would therefore be both syntactically elegant, and reasonable, to allow the following syntax:

T a = T(parameters);        // my suggestion: should be exactly equivalent to T
a = new T(parameters);
x = a.memberVariable;       // member variable access

I suggest, therefore, that the keyword "new" is superfluous, and should be made optional - required ONLY if some ambiguity I haven't thought of requires disambiguation.




2. Construction declaration statements ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In C++, the following statement:

T a(parameters);

is equivalent to:

T a = T(parameters);

I suggest that this syntax should also be allowable in D. It is aesthetically much more pleasing, as there is no needless duplication of the class name. To give a real world example, you only have to compare:

(i)     MultiPrecisionDecimal z = new MultiPrecisionDecimal(5.2);       // as
now
(ii)    MultiPrecisionDecimal z(5.2);                                   // what
I'm suggesting

Observe how much neater and cleaner version (ii) is. Further, there is (so far
as I can tell) no possibility of ambiguity here. Syntactic elegance favors
allowing the simpler syntax.




3. Assignment by value
~~~~~~~~~~~~~~~~~~~~~~

Finally, I propose a new operator, := (that's a colon followed by an equals). It should be used like this:

a := b;

Whenever it occurs, it should be rewritten by the compiler as:

a = new T(b);   // where T is the type of A

It could be declared in the obvious way, like this (and multiply overloaded for different types of b):

class T
{
this(U b)
{
// do stuff
}
}

To make life easier, it should be a syntax error to use the assignment-by-value operator on an auto class. Of course, it is ALREADY possible to assign structs (but not classes) by value. In the case of a struct, I propose that the two statements following shall have identical behavior:

a = b;      // as now
a := b;     // rewritten as a = b;

Thus, the existing syntax for both structs and classes is preserved, with its current behaviour, but new, simpler syntaxes also exist to make code smaller, neater, and cleaner.



Well, just my suggestions. Please feel free to consider, accept, or reject. Jill


May 19, 2004
Currently

        T a = T(arguments);

would call a static opCall defined in the class T.



arcanejill@ramonsky.com wrote:

> 
> Hi guys,
> My first suggestions for this forum - three improvements for constructor
> syntax.
> 
> 
> 
> 1. The reserved word "new" is superfluous. It should be made optional. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> In C++, the following two statements are both legal, but do different things:
> 
> (i)     T * a = new T(parameters);  // C++
> (ii)    T b = T(parameters);        // C++
> 
> In case (i), the object is constructed on the heap (as in D), and the
> variable a is assigned a pointer to it. In case (ii), the object is
> constructed on the stack, and the variable b is assigned a reference to
> it. This distinction is apparent in the way that member variables are
> later accessed:
> 
> (i)     x = a->memberVariable;      // C++
> (ii)    y = b.memberVariable;       // C++
> 
> Now, NEITHER of these distinctions are relevant in D. Class objects are ALWAYS allocated on the heap, never on the stack, so there is no need for the "new" keyword to be present to distinguish the two cases. Further, D does not distinguish between the . operator and the -> operator, It would therefore be both syntactically elegant, and reasonable, to allow the following syntax:
> 
> T a = T(parameters);        // my suggestion: should be exactly equivalent
> to T a = new T(parameters);
> x = a.memberVariable;       // member variable access
> 
> I suggest, therefore, that the keyword "new" is superfluous, and should be made optional - required ONLY if some ambiguity I haven't thought of requires disambiguation.
> 
> 
> 
> 
> 2. Construction declaration statements ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> In C++, the following statement:
> 
> T a(parameters);
> 
> is equivalent to:
> 
> T a = T(parameters);
> 
> I suggest that this syntax should also be allowable in D. It is aesthetically much more pleasing, as there is no needless duplication of the class name. To give a real world example, you only have to compare:
> 
> (i)     MultiPrecisionDecimal z = new MultiPrecisionDecimal(5.2);       //
> as now
> (ii)    MultiPrecisionDecimal z(5.2);                                   //
> what I'm suggesting
> 
> Observe how much neater and cleaner version (ii) is. Further, there is (so
> far as I can tell) no possibility of ambiguity here. Syntactic elegance
> favors allowing the simpler syntax.
> 
> 
> 
> 
> 3. Assignment by value
> ~~~~~~~~~~~~~~~~~~~~~~
> 
> Finally, I propose a new operator, := (that's a colon followed by an equals). It should be used like this:
> 
> a := b;
> 
> Whenever it occurs, it should be rewritten by the compiler as:
> 
> a = new T(b);   // where T is the type of A
> 
> It could be declared in the obvious way, like this (and multiply overloaded for different types of b):
> 
> class T
> {
> this(U b)
> {
> // do stuff
> }
> }
> 
> To make life easier, it should be a syntax error to use the assignment-by-value operator on an auto class. Of course, it is ALREADY possible to assign structs (but not classes) by value. In the case of a struct, I propose that the two statements following shall have identical behavior:
> 
> a = b;      // as now
> a := b;     // rewritten as a = b;
> 
> Thus, the existing syntax for both structs and classes is preserved, with its current behaviour, but new, simpler syntaxes also exist to make code smaller, neater, and cleaner.
> 
> 
> 
> Well, just my suggestions. Please feel free to consider, accept, or reject. Jill

May 19, 2004
Hear, hear!  (see 'clumsy class instantiation quibble' thread).


<arcanejill@ramonsky.com> wrote in message news:c8f0sa$tqk$1@digitaldaemon.com...
>
> Hi guys,
> My first suggestions for this forum - three improvements for constructor
syntax.
>
>
>
> 1. The reserved word "new" is superfluous. It should be made optional. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> In C++, the following two statements are both legal, but do different
things:
>
> (i)     T * a = new T(parameters);  // C++
> (ii)    T b = T(parameters);        // C++
>
> In case (i), the object is constructed on the heap (as in D), and the
variable a
> is assigned a pointer to it. In case (ii), the object is constructed on
the
> stack, and the variable b is assigned a reference to it. This distinction
is
> apparent in the way that member variables are later accessed:
>
> (i)     x = a->memberVariable;      // C++
> (ii)    y = b.memberVariable;       // C++
>
> Now, NEITHER of these distinctions are relevant in D. Class objects are
ALWAYS
> allocated on the heap, never on the stack, so there is no need for the
"new"
> keyword to be present to distinguish the two cases. Further, D does not distinguish between the . operator and the -> operator, It would therefore
be
> both syntactically elegant, and reasonable, to allow the following syntax:
>
> T a = T(parameters);        // my suggestion: should be exactly equivalent
to T
> a = new T(parameters);
> x = a.memberVariable;       // member variable access
>
> I suggest, therefore, that the keyword "new" is superfluous, and should be
made
> optional - required ONLY if some ambiguity I haven't thought of requires disambiguation.
>
>
>
>
> 2. Construction declaration statements ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> In C++, the following statement:
>
> T a(parameters);
>
> is equivalent to:
>
> T a = T(parameters);
>
> I suggest that this syntax should also be allowable in D. It is
aesthetically
> much more pleasing, as there is no needless duplication of the class name.
To
> give a real world example, you only have to compare:
>
> (i)     MultiPrecisionDecimal z = new MultiPrecisionDecimal(5.2);       //
as
> now
> (ii)    MultiPrecisionDecimal z(5.2);                                   //
what
> I'm suggesting
>
> Observe how much neater and cleaner version (ii) is. Further, there is (so
far
> as I can tell) no possibility of ambiguity here. Syntactic elegance favors allowing the simpler syntax.
>
>
>
>
> 3. Assignment by value
> ~~~~~~~~~~~~~~~~~~~~~~
>
> Finally, I propose a new operator, := (that's a colon followed by an
equals). It
> should be used like this:
>
> a := b;
>
> Whenever it occurs, it should be rewritten by the compiler as:
>
> a = new T(b);   // where T is the type of A
>
> It could be declared in the obvious way, like this (and multiply
overloaded for
> different types of b):
>
> class T
> {
> this(U b)
> {
> // do stuff
> }
> }
>
> To make life easier, it should be a syntax error to use the
assignment-by-value
> operator on an auto class. Of course, it is ALREADY possible to assign
structs
> (but not classes) by value. In the case of a struct, I propose that the
two
> statements following shall have identical behavior:
>
> a = b;      // as now
> a := b;     // rewritten as a = b;
>
> Thus, the existing syntax for both structs and classes is preserved, with
its
> current behaviour, but new, simpler syntaxes also exist to make code
smaller,
> neater, and cleaner.
>
>
>
> Well, just my suggestions. Please feel free to consider, accept, or
reject.
> Jill
>
>


May 19, 2004
In article <c8f2rl$11af$1@digitaldaemon.com>, Norbert Nemec says...
>
>Currently
>
>        T a = T(arguments);
>
>would call a static opCall defined in the class T.


Yes, it would. That's something I hadn't thought of. Well, here are my thoughts on that, for what they're worth....

It occurs to me that the whole POINT of overloading operator () using opCall() is to create an object which behaves like a function - kinda like a modern day version of the old-fashioned callback routine you used to get in C. There's even a word for them - "functors" - and they are very useful.

However, a STATIC functor? Surely a static functor is just a FUNCTION?

To put it another way, instead of declaring:

       class A
       {
           int opCall(int x, int y)
           {
                // function body
           }
       }

you could just as easily do this:

       int A(int x, int y)
       {
           // function body
       }

which would achieve exactly the same effect. The static functor version does have the ability to access static members of A, which the function version can't, but frankly there are other ways of achieving this effect.

Moreover, the static functor version violates the D style guide in that you now have a function (or at least, a function-like-object) whose name starts with an upper case letter.

If there is a real need for a CLASS (as opposed to an instance of a class) to be callable, then I can't think of any circumstance where simply providing a named member function won't do. That is, instead of calling:

       A(parameters);

we would have to call:

       A.namedFunction(parameters);

So - I can see NO NEED for static functors, and I humbly suggest that the syntax:

       A a = A(parameters)

SHOULD call a constructor, and should NOT call static opCall(). In fact, I would argue further that static opCall should be a compile error, as it is a completely pointless thing to do, and yields code which looks ... unintuitive.

Now, I'm arguing in favor of removing  a feature, so I don't expect everyone to agree with me. But this forum is for discussion, so let's discuss. I'd be really interested to know what others think about this.


May 19, 2004
<arcanejill@ramonsky.com> wrote in message news:c8fk7j$1s6d$1@digitaldaemon.com...
> In article <c8f2rl$11af$1@digitaldaemon.com>, Norbert Nemec says...
> >
> >Currently
> >
> >        T a = T(arguments);
> >
> >would call a static opCall defined in the class T.
>
>
> Yes, it would. That's something I hadn't thought of. Well, here are my
thoughts
> on that, for what they're worth....
>
> It occurs to me that the whole POINT of overloading operator () using
opCall()
> is to create an object which behaves like a function - kinda like a modern
day
> version of the old-fashioned callback routine you used to get in C.
There's even
> a word for them - "functors" - and they are very useful.
>
> However, a STATIC functor? Surely a static functor is just a FUNCTION?
>
> To put it another way, instead of declaring:
>
>        class A
>        {
>            int opCall(int x, int y)
>            {
>                 // function body
>            }
>        }
>
> you could just as easily do this:
>
>        int A(int x, int y)
>        {
>            // function body
>        }
>
> which would achieve exactly the same effect. The static functor version
does
> have the ability to access static members of A, which the function version can't, but frankly there are other ways of achieving this effect.
>
> Moreover, the static functor version violates the D style guide in that
you now
> have a function (or at least, a function-like-object) whose name starts
with an
> upper case letter.
>
> If there is a real need for a CLASS (as opposed to an instance of a class)
to be
> callable, then I can't think of any circumstance where simply providing a
named
> member function won't do. That is, instead of calling:
>
>        A(parameters);
>
> we would have to call:
>
>        A.namedFunction(parameters);
>
> So - I can see NO NEED for static functors, and I humbly suggest that the syntax:
>
>        A a = A(parameters)
>
> SHOULD call a constructor, and should NOT call static opCall(). In fact, I
would
> argue further that static opCall should be a compile error, as it is a completely pointless thing to do, and yields code which looks ...
unintuitive.
>
> Now, I'm arguing in favor of removing  a feature, so I don't expect
everyone to
> agree with me. But this forum is for discussion, so let's discuss. I'd be
really
> interested to know what others think about this.
>


But static opCall enables you to do exactly what you want!

class A
{
    this(int x){...}
    static A opCall(int x)
    {
        return new A(x);
    }
}

and you can create class objects the in a c++ syntax
A a = A(5);



May 19, 2004
>But static opCall enables you to do exactly what you want!
>
>class A
>{
>    this(int x){...}
>    static A opCall(int x)
>    {
>        return new A(x);
>    }
>}
>
>and you can create class objects the in a c++ syntax
>A a = A(5);
>
>
>

I had thought of that, but in fact that isn't what I'm suggesting. I don't merely want to be able to create classes which callers can call without "new". I want to be able to construct ANY class without using "new". For example:

OutBuffer a = OutBuffer();

or, better still,

Outbuffer a();

To implement "don't need new" in some classes but not in others would be silly. It would lead to less clarity, not more.

Please understand - this is purely an AESTHETIC consideration. There is no deficiency in the language which needs a workaround. But ... the guys who wrote D are very proud of the fact that D has a simple syntax - see the stuff about complex numbers, for example. If they can implement a simple syntax for something which is so common a task as constructing a class, then, why wouldn't they? Unless it's a hard problem - but I suspect it isn't.

Arcane Jill


May 19, 2004
"Arcane Jill" <Arcane_member@pathlink.com> wrote in message news:c8g72s$2pko$1@digitaldaemon.com...
>
> >But static opCall enables you to do exactly what you want!
> >
> >class A
> >{
> >    this(int x){...}
> >    static A opCall(int x)
> >    {
> >        return new A(x);
> >    }
> >}
> >
> >and you can create class objects the in a c++ syntax
> >A a = A(5);
> >
> >
> >
>
> I had thought of that, but in fact that isn't what I'm suggesting. I don't merely want to be able to create classes which callers can call without
"new". I
> want to be able to construct ANY class without using "new". For example:
>
> OutBuffer a = OutBuffer();
>
> or, better still,
>
> Outbuffer a();
>
> To implement "don't need new" in some classes but not in others would be
silly.
> It would lead to less clarity, not more.
>
> Please understand - this is purely an AESTHETIC consideration. There is no deficiency in the language which needs a workaround. But ... the guys who
wrote
> D are very proud of the fact that D has a simple syntax - see the stuff
about
> complex numbers, for example. If they can implement a simple syntax for something which is so common a task as constructing a class, then, why
wouldn't
> they? Unless it's a hard problem - but I suspect it isn't.
>

I think the way it is now is much clearer and it is very clear from the code
that
a "new" object is being instantiated. And in my opinion this synatx is very
simple
and those three letters "new" aren't that hard to type.


> Arcane Jill
>
>


May 19, 2004
In article <c8g72s$2pko$1@digitaldaemon.com>, Arcane Jill says...
>
>
>want to be able to construct ANY class without using "new". For example:
>
>OutBuffer a = OutBuffer();
>
>or, better still,
>
>Outbuffer a();

but, isn't that an abstract function declaration
that returns an object of type Outbuffer?

Ant


May 19, 2004
In article <c8g87d$2rht$1@digitaldaemon.com>, Ivan Senji says...
>
>and those three letters "new" aren't that hard to type.
>

(I've said this before, I promisse it's the last time.)

It isn't the how hard is to type that matters
it's how easy is to read.

Ant


May 19, 2004
"Ant" <Ant_member@pathlink.com> wrote in message news:c8g9om$2toq$1@digitaldaemon.com...
> In article <c8g87d$2rht$1@digitaldaemon.com>, Ivan Senji says...
> >
> >and those three letters "new" aren't that hard to type.
> >
>
> (I've said this before, I promisse it's the last time.)
>
> It isn't the how hard is to type that matters
> it's how easy is to read.

What i wanted to write was:
A a = new A();
is much easier to read than
A a();

The first one just shouts "instantiating object here"
and the second one doesn't


> Ant
>
>


« First   ‹ Prev
1 2 3