December 11, 2006
Pragma wrote:
<snip>
> But I'd like to echo the other comments in this thread regarding structs.  IMO, we're not there yet.  I think folks are looking for a solution that does this:
> 
> - A ctor like syntax for creating a new struct
> - No more forced copy of the entire struct on creation

What do you mean by this?

> - Something that is disambiguated from static opCall
<snip>

Do you mean that constructors for structs should have a notation
distinct from S(...)?

Stewart.
December 11, 2006
== Quote from Kirk McDonald (kirklin.mcdonald@gmail.com)'s article
> Bill Baxter wrote:
> One issue I have with allowing struct constructors is that the existence
> of struct constructors implies the existence of struct destructors. Do
> we really want to go that far?

I certainly do :) Since struct types are always known at compile-time, structs without destructors should not be affected. I think struct destructors will be very useful (RIAA, custom allocation/deallocation strategies).
December 11, 2006
Andrei Alexandrescu (See Website For Email) wrote:
> 
> Classes are different from structs in two essential ways:
> 
> 1. Polymorphism
> 2. Referential semantics
> 
> The two are actually interdependent, as you can't have polymorphism
> comfortably unless you have reference semantics.

Certainly.

> That's the important distinction. Other than that, it's good that they
> share a number of valuable properties. Take private state for example.
> structs as sheer unchecked aggregates would provide too little value to
> be useful. Most of the time, aggregating some state together (date,
> time, etc.) comes together with some desirable invariant that the aggregate should hold, meaning that not all possible bit patterns of the aggregate can be meaningful. So it's useful that struct has private state. Consequently, they should have member functions (setters, getters) and the such. They also should have constructors so they can put themselves in a meaningful initial state, and should have opAssign so they allow controlled overwriting of their state. (It's an accident that opAssign from the same type has not been implemented yet; it can be safely allowed.)

Point made.  And I suppose opAssign isn't truly linked to the idea of object copy semantics--I've just gotten used to associating the two because of my experience with C++.

> So my point was, as attractive the simple mantra "structs should be
> aggregates" is, it turns out it's not that useful. So it's great that D
> supports efficient and safe user-defined values.

structs as aggregates do come in quite handy for a few specific situations, but I agree that they aren't tremendously useful in the general sense.  It's beginning to seem, then, that common value types in D will be represented as structs, with classes reserved for those types with copy requirements.  Once implicit cast support is added, it seems we'll be in pretty good shape for UDTs in D.  And here I'd come to accept that we'd never have them :-)


Sean
December 11, 2006
John Reimer wrote:
> 
>  From the perspective of setting initial state, classes in the OOP context use constructors to do that.  Structs were never intended to have OOP like syntax (or so it seems to me).  Why can't structs just use an initializer like constants or statics?  I notice that Walter has added the struct initialization using S(x) syntax.  I think it is somewhat strange, but I suppose that was designed to be an alternative to constructor initialization?   What happened to something like a struct literal intializer (which only works for static structs and constant values)?  Why can't such initialization be extended to local structs?
> 
> ....
> struct S
> {
>    int i;
>    bool b;
> }
> 
> static S t = { 5, true };  // must be "static" or initialization won't work

I think the problem here is that such initializers would not apply to private data, and more to the point, a ctor can do more than simply assign a constant to each member of the struct.  But it would be nice if this syntax worked for non-static structs anyway.

> But I guess as soon as we start adding "methods" to the struct that are responsible for changing state in the struct, a whole new set of principles comes to work.  Adding constructor funtionality via "this()" is only one way to fix it.  opCall, the current way, is a rather ugly default.  If it is important to keep structs distinct from classes, then structs need to adopt a alternate way of doing initialization (but please not opCall).  I don't think "this()" really is the optimal way, though perhaps the most familiar due to the influence of classes.  I think there should remain a strong distinction between class and struct.

As do I.  And I suppose the presence or lack of polymorphism is a sufficient distinction--the underpinnings for polymorphism do have a fairly significant impact on how an object is represented internally, etc.

> If, nevertheless, Walter decides to implement a "this" constructor for struct, I really hope he doesn't feel the need to go with a destructor and more class-like functionality as well.

The idea of a dtor for structs doesn't make much sense to me because of the bit-copy semantics.  When would the dtor for a struct used as a return value be called?


Sean
December 12, 2006
On Mon, 11 Dec 2006 15:57:51 -0800, Sean Kelly <sean@f4.ca> wrote:

> John Reimer wrote:
>>   From the perspective of setting initial state, classes in the OOP context use constructors to do that.  Structs were never intended to have OOP like syntax (or so it seems to me).  Why can't structs just use an initializer like constants or statics?  I notice that Walter has added the struct initialization using S(x) syntax.  I think it is somewhat strange, but I suppose that was designed to be an alternative to constructor initialization?   What happened to something like a struct literal intializer (which only works for static structs and constant values)?  Why can't such initialization be extended to local structs?
>>  ....
>> struct S
>> {
>>    int i;
>>    bool b;
>> }
>>  static S t = { 5, true };  // must be "static" or initialization won't work
>
> I think the problem here is that such initializers would not apply to private data, and more to the point, a ctor can do more than simply assign a constant to each member of the struct.  But it would be nice if this syntax worked for non-static structs anyway.
>

Ah true.  But then, maybe there shouldn't be private data in a struct either. :)

I still see structs as a fairly basic non-OOP entity.

-JJR
December 12, 2006
To Andrei Alexandrescu:

 - Voiam doar sa salut prezenta dvs aici.
 - I greet your presence here.

December 12, 2006
http://digitalmars.com/d/attribute.html#align

--
AlignAttribute:
	align
	align ) Integer )
--

I guess this was meant to be:

--
AlignAttribute:
	align
	align ( Integer )
--


Apart from that .. I just found several new things in the documentation, scary. :P
December 12, 2006
Andrei Alexandrescu (See Website For Email) wrote:
> Classes are different from structs in two essential ways:
> 
> 1. Polymorphism
> 2. Referential semantics
> 
> The two are actually interdependent, as you can't have polymorphism
> comfortably unless you have reference semantics.

That's one of the things I felt in my bones, but was unable to put my finger on it.
December 12, 2006
== Quote from Walter Bright (newshound@digitalmars.com)'s article
> Andrei Alexandrescu (See Website For Email) wrote:
> > Classes are different from structs in two essential ways:
> >
> > 1. Polymorphism
> > 2. Referential semantics
> >
> > The two are actually interdependent, as you can't have polymorphism comfortably unless you have reference semantics.
> That's one of the things I felt in my bones, but was unable to put my finger on it.

Actually, polymorphism does not imply referential semantics (nor does referential semantics imply polymorphism, of course).

1) Value sematics can be achieved with references as well, by using copy-on-write strategy (or by making classes immutable). All that without sacrificing polymorphism.

2) Polymorphism can be achieved without references as well, but then the size of struct could no longer be determined at comile-time. In other words, function 'sizeof' could no longer be parameterless. Or, alternatively, every such 'polymorphic struct' would have to contain two pointers: VMT and additional 'data' pointer (which is actually pretty close to using references anyway).

I'm in favour of allowing programmer to mark special semantics, such
as value class, or pure function (without side effects). Many additional
optimizations can be performed under such assumptions. Most notably:
value classes could be destroyed predictably (without causing arbitrary
long GC pauses) and calls to pure functions with unchanged parameters
can be cached (for example, foo.name().length()...). Also, it would be
interesting to mark some functions as compile-time, requiring that
they only interact with values that are known in compile-time. This
would make metaprogramming much more similar to normal programming.
One additional nice thing: you can support such declarations even
before optimizer takes advantage of them.

Also, I would suggest issuing a compile-time warning when polymorphism is used without explicit 'override' directive. Perhaps coupled with a pragma or something to turn such warning off.

PS: I really appreciate all the work that has been put in D. D is going to be a much needed successor of C++. I don't see D as competitor to Java or C# (I think that when using .NET or JVM is an option, D would be a terrible choice), but it sure can rock the non-VM world!
December 12, 2006
Boris Kolar wrote:
> PS: I really appreciate all the work that has been put in D. D is going to be a much needed successor of C++. I don't see D as competitor to Java or C# (I think that when using .NET or JVM is an option, D would be a terrible choice), but it sure can rock the non-VM world!

Why not? I think that D could rock the .NET world too. I always wished (and still do) for a d.net implementation.