July 12, 2004
In article <ccu6cn$1uu9$1@digitaldaemon.com>, C. Sauls says...

>     DBVerb opCall(int idx) {

That's an opCall, not a static opCall. I can think of squillions of uses for opCall. But the only use I can think of for /static/ opCall is emulating constructors.

Jill


July 12, 2004
Arcane Jill wrote:
> In article <ccu6cn$1uu9$1@digitaldaemon.com>, C. Sauls says...
>>    DBVerb opCall(int idx) {
> 
> That's an opCall, not a static opCall. I can think of squillions of uses for
> opCall. But the only use I can think of for /static/ opCall is emulating
> constructors.

Its amazing what a difference one word can make.  Point taken.  But still, there's no reason to disallow a static opCall, and another recently reply has me thinking of it as a useful thing for singletons now.  Its a thing to ponder.  And I recently got informed that struct literals don't work for non-static structs, which changes my view a bit as well.  I say, make the literals work for non-statics, and then the need for struct constructors will likely diminish.

-Chris S.
-Invironz
July 12, 2004
a good case for this would be when you make a template class that must construct it's template argument but does not *know* if that argument is a struct or  a class

Arcane Jill wrote:
> In article <cctj4p$115q$1@digitaldaemon.com>, Mike Parker says...
> 
> 
>>struct Foo
>>{
>>   int x;
>>   static Foo opCall(int i)
>>   {
>>       Foo f;
>>       f.x = i;
>>       return f;
>>   }
>>}
>>
>>Foo foo = Foo(5);
> 
> 
> See, Walter. I told you - people are using static opCall to simulate
> constructors. You can do this for both structs and classes. For structs, the
> advantage is, you GET constructor-like calls. For classes, the advantage is, you
> get to dispense with the unnecessary word "new".
> 
> I have suggested this before (though I gather you didn't like the suggestion)
> that (1) structs should be allowed constructors; (2) the keyword "new" should be
> ditched, or at least made optional, in constructor calls; and (3) static opCall
> be deprecated in favor of constructors. The language would be SO much neater and
> cleaner with these changes built in.
> 
> I find it hard to believe, after all, that the use of static opCall as
> demonstrated above was a DESIGN FEATURE of D. I mean - I've never seen static
> opCall used for any purpose OTHER than emulating constructors. I find it more
> believable that someone simply discovered that the compiler lets you get away
> with it, and started using it because structs don't have constructors. It would
> be really nice to tidy this up - even if only for syntactic consistency.
> 
> Arcane Jill
> 
> 
> 
July 12, 2004
"Daniel Horn" <hellcatv@hotmail.com> wrote in message news:ccubqd$2823$1@digitaldaemon.com...
> a good case for this would be when you make a template class that must construct it's template argument but does not *know* if that argument is a struct or  a class

But then you might make a static opCall for both. That doesn't appeal to me though. The optional "new" might be nice, at least for structs.


July 12, 2004
Matthias Becker wrote:

> Could anybody explain me, in which I you'd want to overload opMul on classes?

class Matrix
{
	// snip
}

Cheers,
Sigbjørn Lund Olsen
July 12, 2004
Matthias Becker wrote:
> So is it realy that stupid that this works:
> 
> class Baz (T) {
> Baz!(T) recursive;
> }
> 
> Everytime I try to code anything in D I get such behavior that I don't expect
> and often I don't find a workaround. But "D is so great". So are my ideas so
> strange that nobody else wants to do the things I want to? Why does nobody else
> say D is strange with a lot of unexpected behaviors?

I agree that something needs to be done here, but I'm not sure what.

The whole class Baz(T) notation is shorthand for creating two symbols. (a template and a class of the same name).

A solution that comes to mind is to make internal references to the symbol resolve to the template, not the enclosed class.  It seems like a weird contradiction in the rules, but I can't think of any case where it might become an issue.

> BTW: Why structs don't have constructors? I get crazy about this!
> 
> Foo foo;
> foo.x = bla;
> foo.y = blub;
> // start using foo
> // *ARGH!!!*
> 
> It's so messy.

The static opCall idiom is a pretty good hack around this, but there's no reason the 'this()' syntax shouldn't be supported.

> Even experienced programmers like Andy F. are fooled by the language. We wanted
> to simulate the simple ML-line
> 
> fun mul x y = x * y
> 
> So he wrote:
> 
> [... terrible code ...]
> 
> Of course this doesn't work, as you can overload opMul and structs and classes
> don't have an init-property. So you have to use an even more clumsy workaround:
> 
> [... code ...]
> 
> And this is needed only for one very simple line of ML!

Agreed: Deducing types is something D isn't so hot at. :)

> OK, perhaps Andy just expected other programmers to be smart enough to write a
> init-property for types that should be useable in istuations like this?

Nope. :)  You bring up a good point: T.init should exist for all types.  (null would be sufficient for classes)

Looking back, I could have just written this:

    template mul(U, V) {
        typeof(U.init * V.init) mul(T x, T y) {
            return x * y;
        }
    }

Which doesn't seem so bad. (aside from the Class.init thing)

> The more I use D the less I like it. But it's defently me, as "D is so great!".

I think it is. :)  It's not perfect, but it's pretty nice.  I can write code like it was Java, except I don't have to give up pointers, and I get tiny little binaries like C++.

 -- andy
July 12, 2004
Arcane Jill wrote:

> In article <cctj4p$115q$1@digitaldaemon.com>, Mike Parker says...
> 
> 
>>struct Foo
>>{
>>   int x;
>>   static Foo opCall(int i)
>>   {
>>       Foo f;
>>       f.x = i;
>>       return f;
>>   }
>>}
>>
>>Foo foo = Foo(5);
> 
> 
> See, Walter. I told you - people are using static opCall to simulate
> constructors. You can do this for both structs and classes. For structs, the
> advantage is, you GET constructor-like calls. For classes, the advantage is, you
> get to dispense with the unnecessary word "new".

Wroar. I just realized, static opCall is way better than a constructor since it allows for the construction of the most appropriate subclass in a class hierarchy. Neat.

Cheers,
Sigbjørn Lund Olsen
July 12, 2004
> Wroar. I just realized, static opCall is way better than a constructor since it allows for the construction of the most appropriate subclass in a class hierarchy. Neat.

No biggie, you can do that with any static method just as well, i.e. a named constructor.

> Cheers,
> Sigbjørn Lund Olsen


July 12, 2004
>I've never seen static
>opCall used for any purpose OTHER than emulating constructors

Ive used for functors before.

>even if only for syntactic consistency.

Consistent to what ? C++ ?

In article <cctrk2$1e1t$1@digitaldaemon.com>, Arcane Jill says...
>
>In article <cctj4p$115q$1@digitaldaemon.com>, Mike Parker says...
>
>>struct Foo
>>{
>>    int x;
>>    static Foo opCall(int i)
>>    {
>>        Foo f;
>>        f.x = i;
>>        return f;
>>    }
>>}
>>
>>Foo foo = Foo(5);
>
>See, Walter. I told you - people are using static opCall to simulate constructors. You can do this for both structs and classes. For structs, the advantage is, you GET constructor-like calls. For classes, the advantage is, you get to dispense with the unnecessary word "new".
>
>I have suggested this before (though I gather you didn't like the suggestion)
>that (1) structs should be allowed constructors; (2) the keyword "new" should be
>ditched, or at least made optional, in constructor calls; and (3) static opCall
>be deprecated in favor of constructors. The language would be SO much neater and
>cleaner with these changes built in.
>
>I find it hard to believe, after all, that the use of static opCall as demonstrated above was a DESIGN FEATURE of D. I mean - I've never seen static opCall used for any purpose OTHER than emulating constructors. I find it more believable that someone simply discovered that the compiler lets you get away with it, and started using it because structs don't have constructors. It would be really nice to tidy this up - even if only for syntactic consistency.
>
>Arcane Jill
>
>
>


July 12, 2004
Arcane Jill wrote:
> In article <cctj4p$115q$1@digitaldaemon.com>, Mike Parker says...
> 
> 
>>struct Foo
>>{
>>   int x;
>>   static Foo opCall(int i)
>>   {
>>       Foo f;
>>       f.x = i;
>>       return f;
>>   }
>>}
>>
>>Foo foo = Foo(5);
> 
> 
> See, Walter. I told you - people are using static opCall to simulate
> constructors. You can do this for both structs and classes. For structs, the
> advantage is, you GET constructor-like calls. For classes, the advantage is, you
> get to dispense with the unnecessary word "new".
> 
> I have suggested this before (though I gather you didn't like the suggestion)
> that (1) structs should be allowed constructors; (2) the keyword "new" should be
> ditched, or at least made optional, in constructor calls; and (3) static opCall
> be deprecated in favor of constructors. The language would be SO much neater and
> cleaner with these changes built in.
> 
> I find it hard to believe, after all, that the use of static opCall as
> demonstrated above was a DESIGN FEATURE of D. I mean - I've never seen static
> opCall used for any purpose OTHER than emulating constructors. I find it more
> believable that someone simply discovered that the compiler lets you get away
> with it, and started using it because structs don't have constructors. It would
> be really nice to tidy this up - even if only for syntactic consistency.

'this' syntax for struct constructors is definitely a good idea: programmers try it first when they need the functionality, so it stands to reason that they are right and D is (currently) wrong.

Playing with 'new' isn't a good idea, though.  As it stands, 'new' always means allocating something on the heap.  This must always be the case for objects, but there are still structs and other value types which can be on the stack or heap.

This should do it:

    struct Rectangle {
        int x, y, w, h;
        this(int x, int y, int w, int h) { ... }
    }

    Rectangle r = Rectangle(...); // initialized stack variable
    Rectangle* p = new Rectangle(...); // heap allocated instance

 -- andy