September 04, 2008
Walter Bright, el  4 de septiembre a las 10:26 me escribiste:
> Tomas Lindquist Olsen wrote:
> >This is one of those things I really dislike about D :(
> >It's really nice that we can override struct initialization, but the fact that
> >it eliminates the possibility to override it (with a nice syntax) makes it much
> >less appealing IMHO.
> >The most important point to me, is that old thing about static struct
> >initializer and struct literals have different syntaxes, and that the static
> >variant is much more flexible.
> >I would have loved to see the static struct initializer syntax become an
> >expression. If the problem is ambiguity, why not just prefix the {} braces with
> >the struct name?
> 
> The static struct initializers more or less are inherited from C. I'd eventually like to abandon them and go completely to the S(args) syntax.

But they are much more flexible than constructor, it's like a constructor with named arguments! =)

If you add support to named arguments, then I'll agree ;)

-- 
Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/
----------------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------------
PROTESTA EN PLAZA DE MAYO: MUSICO SE COSIO LA BOCA
	-- Crónica TV
September 04, 2008
On Thu, Sep 4, 2008 at 2:09 PM, Leandro Lucarella <llucax@gmail.com> wrote:
> Walter Bright, el  4 de septiembre a las 10:26 me escribiste:
>> Tomas Lindquist Olsen wrote:
>> >This is one of those things I really dislike about D :(
>> >It's really nice that we can override struct initialization, but the fact that
>> >it eliminates the possibility to override it (with a nice syntax) makes it much
>> >less appealing IMHO.
>> >The most important point to me, is that old thing about static struct
>> >initializer and struct literals have different syntaxes, and that the static
>> >variant is much more flexible.
>> >I would have loved to see the static struct initializer syntax become an
>> >expression. If the problem is ambiguity, why not just prefix the {} braces with
>> >the struct name?
>>
>> The static struct initializers more or less are inherited from C. I'd eventually like to abandon them and go completely to the S(args) syntax.
>
> But they are much more flexible than constructor, it's like a constructor with named arguments! =)
>
> If you add support to named arguments, then I'll agree ;)
>

Ah, now there's a compromise I'd be more than willing to accept.  If we didn't get S{} style struct literals, but were able to do S(x: 5, y: 10), that would be just as good.

Named parameters are sooo easy!  Please implement them!
September 04, 2008
Walter Bright Wrote:

> Pablo Ripolles wrote:
> > little typo: writefln("f(%1$s) = %2$%", x, y);      --->
> > writefln("f(%1$s) = %2$s", x, y);
> > 
> > it doesn't compile anyway!
> > 
> > Walter, don't you think that the ctor overloading should be on "static opCall" better than *any* opCall?
> 
> That would make opCall overload unlike anything else.

Ok, sorry again, I didn't mean overloading, I did mean *override* or substitute as there is no inheritance for the structs.  does it change your answer?

Walter, please, correct me where I'm wrong.

* ctors are somehow static operations (UML parlance), they construct the instance when the struct identifier is invoked with the corresponding arguments through the "()" operator.

* static ctors, being the keyword "static" not an "Attribute" but a "StorageClass" (in D parlance), are something different.

* static member functions, being the keyword "static" an "Attribute" (in D parlance), are static operations (UML parlance) as they don't need an instance to be invoked on.

* opCall is the member function that is invoked when the calling-function-operator "()" is applied to an instance as if it were a function

* static opCall is the static member function that is invoked when the calling-function-operator "()" is applied to a struct identifier as if it were a function.

Hence, since there is a clear connection between the first point and the last point, why should the ctor substitute (or *override* as it has been used by you before) other than the static opCall mentioned in the last point?

My experiments with real code and the last compiler version show that once there is present a ctor it even invalidates the possibility of accessing the *non-static* opCall to use a plain instance of that struct as if it were a function.  Is that the expected behavior?

I would understand if that the preference would take place between the ctor and the static opCall (both use the same syntactic expression on the struct), but I sincerely don't see the symmetry when the preference takes place between the ctor and the non-static opCall.

Thanks!

September 04, 2008
On Fri, Sep 5, 2008 at 6:20 AM, Pablo Ripolles <in-call@gmx.net> wrote:
> Walter Bright Wrote:
>
> Hence, since there is a clear connection between the first point and the last point, why should the ctor substitute (or *override* as it has been used by you before) other than the static opCall mentioned in the last point?
>
> My experiments with real code and the last compiler version show that once there is present a ctor it even invalidates the possibility of accessing the *non-static* opCall to use a plain instance of that struct as if it were a function.  Is that the expected behavior?

If that's really the case with the latest D2 then that is odd.  In C++ there isn't even a static opCall, only the non-static variety, but it works just fine in conjunction with constructors. Functor  structs and structs with constructors should not be mutually exclusive.  Kill off static opCall, fine, but don't kill instance opCall.  That's one step forward one step back.

--bb
September 04, 2008
Bill Baxter wrote:
> On Fri, Sep 5, 2008 at 6:20 AM, Pablo Ripolles <in-call@gmx.net> wrote:
>> Walter Bright Wrote:
>>
>> Hence, since there is a clear connection between the first point and the last point, why should the ctor substitute (or *override* as it has been used by you before) other than the static opCall mentioned in the last point?
>>
>> My experiments with real code and the last compiler version show that once there is present a ctor it even invalidates the possibility of accessing the *non-static* opCall to use a plain instance of that struct as if it were a function.  Is that the expected behavior?
> 
> If that's really the case with the latest D2 then that is odd.  In C++
> there isn't even a static opCall, only the non-static variety, but it
> works just fine in conjunction with constructors. Functor  structs and
> structs with constructors should not be mutually exclusive.  Kill off
> static opCall, fine, but don't kill instance opCall.  That's one step
> forward one step back.

The non-static opCall should work fine.
September 04, 2008
On Fri, Sep 5, 2008 at 6:37 AM, Walter Bright <newshound1@digitalmars.com> wrote:
> Bill Baxter wrote:
>>
>> If that's really the case with the latest D2 then that is odd.  In C++ there isn't even a static opCall, only the non-static variety, but it works just fine in conjunction with constructors. Functor  structs and structs with constructors should not be mutually exclusive.  Kill off static opCall, fine, but don't kill instance opCall.  That's one step forward one step back.
>
> The non-static opCall should work fine.

Ok.  Groovy then.

--bb
September 04, 2008
Walter Bright wrote:
> Matti Niemenmaa wrote:
> 
>> Nice release, thanks! One nit: running "dmd" still says "Digital Mars D Compiler
>> v1.034".
> 
> 
> Fixed!

Congrats, etc., you know!  :-)

An idea:

On www.digitalmars.com you currently replace the Current Version link with the, ehhh, Current Version, right?

Now, would it be a better idea to announce here the existence of DMD X.0xx /without/ changing the default link on the web site? Point being, you'd want to get feedback for at least a week from this NG, before "publishing to the world at large" the new version.

This might be handy for "real errors", because then you could have some comment next to the link about, well, caveats or whatever.

Even better, you'd get rid of the most trivial, and embarrassing, erros (of the kind I make all the time, like "says v1.034") before the regular downloaders hear of them.

georg

PS, think about those who don't read this NG, who just happen to download the obvious choice, the current version, and then there's some embarrassing or downright dangerous thing with it, and he never gets the wiser -- because we can't mandate that everyone reads this NG.

/At least 1.xx/ should do this.
September 04, 2008
Walter Bright wrote:
> Jarrett Billingsley wrote:
> 
>> Speaking of syntactical ambiguity, the expression
>>
>> S(1, 2, 3)
>>
>> can, right now, have one of three meanings:
>>
>> 1. A struct literal for struct S
>> 2. A call to S's static opCall
>> 3. An instantiation of S and a call to its ctor
>>
>> Even if opCall goes away, we'll still be left with the ambiguity of struct literal vs. ctor.  I'd really, really like to hear Walter's view on this but he has responded neither to the thread I posted on digitalmars.D nor the bugzilla ticket (http://d.puremagic.com/issues/show_bug.cgi?id=2170).
> 
> 
> If there's any constructor defined for S, then S(args) is a constructor call.
> 
> If there's any opCall defined for S, then S(args) is an opCall call.
> 
> Otherwise, it's a struct literal.

This might be fluent for the "people in the know", but for everybody else (which is /everybody else/, until they become "people in the know") it is just distracting, ambiguous, and prone to misinterpretation. And this simply makes it take more time when debuggin the works of your team.

Something ought to be done here.

September 05, 2008
Walter Bright wrote:
> bearophile wrote:
>> Walter Bright:
>>> If there's any constructor defined for S, then S(args) is a
>>> constructor call. If there's any opCall defined for S, then S(args)
>>> is an opCall call. Otherwise, it's a struct literal.
>>
>> I haven't tried that in real code, so I can't be sure, but while it
>> may work for the compiler, it sounds a bit too much complex for the
>> person that later reads the code. Too many alternative possibilities
>> may make the code more complex to follow.
>>
>> To reduce such ambiguity (ambiguity for the person, not for the
>> compiler) may be to change the syntax of struct literals...
> 
> I disagree, I think just the reverse. The S(args) syntax means that it's entirely up to the struct designer to say how it should work. The user needn't know or care, and the struct designer can change the design without affecting user code.

This helps a lot with future proofing your structs.

I'm trying to think of a downside...
It's a method call, which is a small performance hit. But it's a very small one, considering that it's a final method.

It's a method call, so it could throw an exception. That's just a bug in your code, and easier to find than some random error way down the line.

You might be doing something dangerous with leaving stuff on an old stack frame and still accessing it. Then you're in the realm of undefined behavior.
September 05, 2008
On Thu, 04 Sep 2008 14:37:27 -0700, Walter Bright <newshound1@digitalmars.com> wrote:

>Bill Baxter wrote:
>> On Fri, Sep 5, 2008 at 6:20 AM, Pablo Ripolles <in-call@gmx.net> wrote:
>>> Walter Bright Wrote:
>>>
>>> Hence, since there is a clear connection between the first point and the last point, why should the ctor substitute (or *override* as it has been used by you before) other than the static opCall mentioned in the last point?
>>>
>>> My experiments with real code and the last compiler version show that once there is present a ctor it even invalidates the possibility of accessing the *non-static* opCall to use a plain instance of that struct as if it were a function.  Is that the expected behavior?
>> 
>> If that's really the case with the latest D2 then that is odd.  In C++ there isn't even a static opCall, only the non-static variety, but it works just fine in conjunction with constructors. Functor  structs and structs with constructors should not be mutually exclusive.  Kill off static opCall, fine, but don't kill instance opCall.  That's one step forward one step back.
>
>The non-static opCall should work fine.

Only the parameterless non-static opCall seem to work:

    struct S
    {
        this(int x)
        {
        }

        void opCall()
        {
        }
    }

    auto s = S(1);
    s(); // ok

In other cases the compiler ignores the opCall and tries to use the constructor:

    struct S
    {
        this(int x)
        {
        }

        void opCall(int y)
        {
        }
    }

    auto s = S(1);
    s(1); //  Error: * has no effect in expression


Also, when opCall is a better match:

    struct S
    {
        this(int x)
        {
        }

        void opCall(int y, int z)
        {
        }
    }

    auto s = S(1);
    s(1, 2); //  Error: this(int x) does not match parameter types