View mode: basic / threaded / horizontal-split · Log in · Help
December 13, 2006
Re: DMD 0.177 release
"Walter Bright" <newshound@digitalmars.com> wrote in message 
news:elnv14$r2d$1@digitaldaemon.com...

> For whatever the merits of opCall vs this(), efficiency is NOT a problem 
> with either, and is not a reason to choose one or the other. The generated 
> code is the same.
>
> Under the hood, they are the same. Both take a hidden pointer to where the 
> result is stored. The rest is window dressing.

Alright then.  All I've got then is the orthogonality argument.  But you 
won't listen to that either.

People will come to D from C++ and C# and ask "where are constructors in 
structs?" and we'll say "you have to use static opCall."  And they'll ask 
"why?"  And all we'll be able to do is shake our heads, sigh, and say "I 
don't know."

For the last time, even though you don't care: we have been using static 
opCall as a WORKAROUND.  As in *we never intended for that to be the 
canonical method of constructing a struct*.  I don't think anyone would 
complain if they were given a consistent, logical method of initializing any 
aggregate type.
December 13, 2006
Re: DMD 0.177 release
On Wed, 13 Dec 2006 12:02:37 -0500, Jarrett Billingsley  
<kb3ctd2@yahoo.com> wrote:

> "Walter Bright" <newshound@digitalmars.com> wrote in message
> news:elnv14$r2d$1@digitaldaemon.com...
>
>> For whatever the merits of opCall vs this(), efficiency is NOT a problem
>> with either, and is not a reason to choose one or the other. The  
>> generated
>> code is the same.
>>
>> Under the hood, they are the same. Both take a hidden pointer to where  
>> the
>> result is stored. The rest is window dressing.
>
> Alright then.  All I've got then is the orthogonality argument.  But you
> won't listen to that either.
>
> People will come to D from C++ and C# and ask "where are constructors in
> structs?" and we'll say "you have to use static opCall."  And they'll ask
> "why?"  And all we'll be able to do is shake our heads, sigh, and say "I
> don't know."
>
> For the last time, even though you don't care: we have been using static
> opCall as a WORKAROUND.  As in *we never intended for that to be the
> canonical method of constructing a struct*.  I don't think anyone would
> complain if they were given a consistent, logical method of initializing  
> any
> aggregate type.
>

For the record, I'm fine with static opCall. Structs don't have  
constructors and destructors, but the language just so happens to allow us  
to have something that looks like a constructor. We could use Foo.create()  
to initialize new Foo`s but since opCall is available and looks nice to  
us, we can go with it. If opCall didn't exist, would we even be having  
this argument? We would know structs weren't meant to have true  
constructors and destructors. We have an aesthetically pleasing way to  
initialize structs, so what's the problem. If your friend asks if structs  
have constructors, you say no, but since the langauge is so expressive,  
you have this feature called opCall that makes it just as nice to  
initialize.

P.S.  I actually don't want a defensive response to this, I'm just stating  
my view; thanks.
December 13, 2006
Re: DMD 0.177 release
On Wed, 13 Dec 2006 12:21:37 -0500, Chris Miller wrote:

"We know structs weren't meant to have true constructors and destructors.
We have an aesthetically pleasing way to initialize structs, so what's the
problem. If your friend asks if structs have constructors, you say no, but
since the langauge is so expressive, you have this feature called opCall
that makes it just as nice to initialize."

*Amen*
December 13, 2006
Re: DMD 0.177 release
Mark Wrenn wrote:
> On Wed, 13 Dec 2006 12:21:37 -0500, Chris Miller wrote:
> 
> "We know structs weren't meant to have true constructors and destructors.
> We have an aesthetically pleasing way to initialize structs, so what's the
> problem. If your friend asks if structs have constructors, you say no, but
> since the langauge is so expressive, you have this feature called opCall
> that makes it just as nice to initialize."
> 
> *Amen*

If structs do add destructors, this can will be reopened - and by that 
time it will be much more smellier.

Andrei
December 13, 2006
Re: DMD 0.177 release
Stewart Gordon wrote:
> Walter Bright wrote:
>> Stewart Gordon wrote:
>>> Walter Bright wrote:
>>>> I don't think that'll work. He'll wind up being forced to set all 
>>>> the fields.
>>> Doesn't follow - there might not be any to set other than those that are
>>> an inherent part of the assignment operation.
>>
>> But if there *are* other fields that shouldn't be set, a rule to 
>> preclude those cases would be a problem.
> 
> Exactly.  *If* there are other fields that shouldn't be set.  Do you 
> even understand a word of what Chris is proposing?
> 
> The programmer would have a choice - opAssign returning void to modify 
> in-place the object referenced by the lvalue, or returning a new object 
> that will be assigned to the lvalue.  What is this precluding?

Just a few thoughts.  If this change is implemented, it should apply to 
all assign ops, not just opAssign itself.  So opAddAssign, opMulAssign, 
etc.  Also, it seems like this could give rise to some interesting behavior:

    class MyClass
    {
        int val;

        this( int x )
        {
            val = x;
        }

        MyClass opAssign( int x )
        {
            return new MyClass( x );
        }
    }

    void fn( MyClass c )
    {
        c = 42;
    }

    MyClass c = new MyClass( 0 );
    fn( c );
    writefln( c.val );

Based on this suggestion, the above will print '0', not '42'.  This is 
actually kind of an interesting situation, as it offers the possibility 
of making non-inout reference parameters immutable with respect to 
assign operations.  The other consequence being that assign operations 
could change the address of a class reference as a side-effect, which 
may have an impact on optimization.  It also may interact somewhat oddly 
with associative arrays and such, depending on how the compiler 
generates code.  ie.

    MyClass[int] aa;
    aa[0] = new MyClass( 0 );
    aa[0] = 42;
    writefln( aa[0].val );

What will the above print?  This sort of behavior would need to be 
defined in the spec.


Sean
December 14, 2006
Re: DMD 0.177 release
Stewart Gordon wrote:
> Walter Bright wrote:
>> Stewart Gordon wrote:
>>> Walter Bright wrote:
>>>> I don't think that'll work. He'll wind up being forced to set all 
>>>> the fields.
>>> Doesn't follow - there might not be any to set other than those that are
>>> an inherent part of the assignment operation.
>>
>> But if there *are* other fields that shouldn't be set, a rule to 
>> preclude those cases would be a problem.
> 
> Exactly.  *If* there are other fields that shouldn't be set.  Do you 
> even understand a word of what Chris is proposing?
> 
> The programmer would have a choice - opAssign returning void to modify 
> in-place the object referenced by the lvalue, or returning a new object 
> that will be assigned to the lvalue.  What is this precluding?

opAssign has 3 externally visible characteristics:

1) the parameter
2) the 'this' pointer
3) the return value

Your proposal mixes up 2 and 3. opAssign works like:

	a = b
becomes:
	a.opAssign(b)

The return value is not assigned to a, it is the value of the expression 
(a = b). Mixing up the return value and the assignment to a will cause 
problems, as the two are different things, and should be independent.
December 14, 2006
Re: DMD 0.177 release
Don Clugston wrote:
> Intriguing. Evidently the ideas barrel is far from empty. <g>

No chance of that happening <g>.
December 14, 2006
Re: DMD 0.177 release
BCS wrote:
> With constructors, it is not only simpler code, but looks like what is 
> happening.
> 
> struct S
> {
>     static S err;
>     int k, l;
> 
>     this(int i, int j)
>     {
>         k=i;
>         l=j;
> 
>         if(!ret.test) this = err;
>     }
> 
>     bool test(){...}
> }

Assignment to this inside a constructor is a mistake as it breaks the 
assumptions the language makes about constructors.
December 14, 2006
Re: DMD 0.177 release
Andrei Alexandrescu (See Website For Email) wrote:
> Walter Bright wrote:
>> Under the hood, they are the same. Both take a hidden pointer to where 
>> the result is stored. The rest is window dressing.
> 
> That means you can't return the result in a register :o).

Actually, it does return it in a register if it fits in one. Try it!
December 14, 2006
Re: DMD 0.177 release
Walter Bright wrote:
> opAssign has 3 externally visible characteristics:
> 
> 1) the parameter
> 2) the 'this' pointer
> 3) the return value
> 
> Your proposal mixes up 2 and 3. opAssign works like:
> 
>     a = b
> becomes:
>     a.opAssign(b)
> 
> The return value is not assigned to a, it is the value of the expression 
> (a = b). Mixing up the return value and the assignment to a will cause 
> problems, as the two are different things, and should be independent.

That makes me wonder - if a = b is used without picking up its result 
(the usual case), and if opAssign() returns an S, will the compiler 
optimize away the extra copy at zero cost?

What I think happens is that the function will take a pointer to the 
destination which is zero, so a comparison will be made. But perhaps the 
optimizer will take care of eliminating that?


Andrei
8 9 10 11 12 13 14 15 16
Top | Discussion index | About this forum | D home