View mode: basic / threaded / horizontal-split · Log in · Help
December 09, 2006
Re: DMD 0.177 release - Clearifications Please?
"Hasan Aljudy" <hasan.aljudy@gmail.com> wrote in message 
news:elfcgr$v45$1@digitaldaemon.com...

> Why is everyone talking about opAssign? I don't see it mentioned in the 
> change log.

Have a look on the "Operator Overloading" page of the spec.
December 09, 2006
Re: DMD 0.177 release
Jarrett Billingsley wrote:
>> It turns out that static opCall() and this() are equivalent. C++ has some 
>> obscure rules to try to disambiguate them. I wished to avoid that problem, 
>> and since static opCall() is routinely in use, picked them.
> For classes they're not.  Why should structs be any different?  And even if 
> static opCalls are routinely in use, are they the best solution?

I've found they work well.

> And are they _really_ equivalent?

Not perfectly, but the differences are small.

> Where's the 'this' pointer in a static 
> opCall()?

It's in your return value.

>> The optimizer removes the redundant copy, and builds the result directly 
>> into the target.
> Wouldn't it be easier to just have ctors, so implementations don't have to 
> worry about writing an optimizer just to support this behavior?

You have to have the optimization anyway. My C++ compiler has had it 
since 1991 or so. It's oooold technology.

>>> And I also can't figure out how to make the implicit opCall work with 
>>> more than one parameter.  :P
>> S(1,2,3)
> 
> Oh.  I was thinking more along the lines of being able to do "S s(1, 2, 
> 3);".

I prefer:
	auto s = S(1,2,3);
to C++ style. static opCall fits right in.

> Though as was mentioned elsewhere, it's not commutative, so it's still not 
> possible to do
> 
> RangedInt!(m, n) r;
> r = 5;
> int x = r; // error

That's implicit casting from a struct. It'll probably wind up getting 
supported in one form or another.
December 10, 2006
Re: DMD 0.177 release
Walter Bright wrote:
> Jarrett Billingsley wrote:
>>> It turns out that static opCall() and this() are equivalent. C++ has 
>>> some obscure rules to try to disambiguate them. I wished to avoid 
>>> that problem, and since static opCall() is routinely in use, picked 
>>> them.
>> For classes they're not.  Why should structs be any different?  And 
>> even if static opCalls are routinely in use, are they the best solution?
> 
> I've found they work well.

Do you have a single instance of a static opCall being used for 
construction where you don't just create a variable on the stack, build 
it, and return it? Because that's all I've ever done. Hundreds of times. 
Nothing else, and it just ends up being useless fluff making code harder 
to read than it should be.

The opposite end of this would be so easy - if classes didn't have 
constructors. They don't actually need them after all - you just need to 
have the ability to create a blank instance. But can you see how much of 
a pointless pain in the ass that would be? That's exactly how it is in 
structs right now.

>>>> And I also can't figure out how to make the implicit opCall work 
>>>> with more than one parameter.  :P
>>> S(1,2,3)
>>
>> Oh.  I was thinking more along the lines of being able to do "S s(1, 
>> 2, 3);".
> 
> I prefer:
>     auto s = S(1,2,3);
> to C++ style. static opCall fits right in.

Yeah, I've never liked C++'s handling of this, it looks way too much 
like a function call.
December 10, 2006
Re: DMD 0.177 release
Burton Radons wrote:
> Do you have a single instance of a static opCall being used for 
> construction where you don't just create a variable on the stack, build 
> it, and return it? Because that's all I've ever done. Hundreds of times. 
> Nothing else, and it just ends up being useless fluff making code harder 
> to read than it should be.

Given:

     auto s = S(1,2,3);

I'm not sure what you mean?
December 10, 2006
Re: DMD 0.177 release
"Walter Bright" <newshound@digitalmars.com> wrote in message 
news:elfg41$139h$1@digitaldaemon.com...

> I've found they work well.
>
>> And are they _really_ equivalent?
>
> Not perfectly, but the differences are small.
>
>> Where's the 'this' pointer in a static opCall()?
>
> It's in your return value.

Okay, this obviously isn't working.  Let's go at this from another angle.

What is the TRUE reason you don't want to give structs ctors?  I don't want 
to know why static opCalls are good, but why ctors are bad.
December 10, 2006
Re: DMD 0.177 release
Jarrett Billingsley wrote:
> What is the TRUE reason you don't want to give structs ctors?  I don't want 
> to know why static opCalls are good, but why ctors are bad. 

Constructor:

	S(v);

static opCall:

	S(v)

What's the difference? I just don't see the point for adding constructors.
December 10, 2006
Re: DMD 0.177 release
Walter Bright wrote:
> Jarrett Billingsley wrote:
>> What is the TRUE reason you don't want to give structs ctors?  I don't 
>> want to know why static opCalls are good, but why ctors are bad. 
> 
> Constructor:
> 
>     S(v);
> 
> static opCall:
> 
>     S(v)
> 
> What's the difference? I just don't see the point for adding constructors.

Here's the difference:

    struct S
    {
        this (int x)
        {
            w = calculate_something (x);
        }

        this (int x, int y)
        {
            this (x);
            z = calculate (y);
        }
    }

    struct S
    {
        static S opCall (int x)
        {
            S result;
            result.build (x);
            return result;
        }

        static S opCall (int x, int y)
        {
            S result;
            result.build (x, y);
            return result;
        }

        private void build (int x)
        {
            w = calculate (x);
        }

        private void build (int x, int y)
        {
            build (x);
            z = calculate (y);
        }
    }

Look at all that waste! More than 50% of the code there is just 
restating things. This was much harder to write, is harder to maintain, 
and has granted us no benefits whatsoever.
December 10, 2006
Re: DMD 0.177 release
"Walter Bright" <newshound@digitalmars.com> wrote in message 
news:elfreq$1dvs$1@digitaldaemon.com...
>
> Constructor:
>
> S(v);
>
> static opCall:
>
> S(v)
>
> What's the difference? I just don't see the point for adding constructors.

In addition to what Burton posted, class:

class C
{
   this()
   {

   }
}

Struct:

struct S
{
   static S opCall()
   {
       S s;
       return s;
   }
}

It's completely un-orthogonal.  Wouldn't it be so much cleaner and make so 
much more sense to allow ctors for structs?  Isn't this the _purpose_ of 
ctors, to initialize members to useful values?  Why have static opCall mean 
something completely different for structs and classes?
December 10, 2006
Re: DMD 0.177 release
Burton Radons wrote:
> Here's the difference:
> 
>     struct S
>     {
>         this (int x)
>         {
>             w = calculate_something (x);
>         }
> 
>         this (int x, int y)
>         {
>             this (x);
>             z = calculate (y);
>         }
>     }

struct S
{
    static S opCall(int x)
    {
	S result;
	result.w = calculate_something(x);
	return result;
    }

    static S opCall(int x, int y)
    {
	auto result = S(x);
	result.z = calculate(y);
	return result;
    }
}

It's 3 more lines of code. The two styles almost completely overlap, and 
since the latter is already in use, adding ctors just seems redundant.
December 10, 2006
Re: DMD 0.177 release
Walter Bright wrote:
> Jarrett Billingsley wrote:
>> What is the TRUE reason you don't want to give structs ctors?  I don't 
>> want to know why static opCalls are good, but why ctors are bad. 
> 
> Constructor:
> 
>     S(v);
> 
> static opCall:
> 
>     S(v)
> 
> What's the difference? I just don't see the point for adding constructors.

The difference is that a ctor initializes an already-existing instance, 
while static opCall returns one, which is then copied. A static opCall 
won't handle the following case:

----

void delegate() globalDG;


struct Foo {
	void func() {
		printf("myVal = %d\n", myVal);
	}

	static Foo opCall(int v) {
		Foo res;
		res.myVal = v;
		globalDG = &res.func;
		return res;
	}

	int myVal;
}


void main() {
	Foo f = Foo(5);
	globalDG();  // prints garbage instead of '5'
}

----

The Foo instance returned from static opCall is copied, thus the 'ctor 
hack' doesn't have real access to the object it's constructing, not to 
mention the overhead of copying the struct to another place on stack...

Also,  new Foo(5)  isn't going to work without real ctors or more hacks.



--
Tomasz Stachowiak
1 2 3 4 5 6 7 8 9
Top | Discussion index | About this forum | D home