July 12, 2004
Daniel Horn wrote:
> the point is that then you have to jump through hoops to get templates that should work for both structs and classes working... I think there needs to be some work to add transparency to types... making them all act different, construct different and copy different makes it next-to-impossible to make a template class that works for all (case in point see my float1,2,3,4 structs that need to accept integers, classes (i.e. BigInt) or other floatX structs

I agree that it would beegood for structs and classes to have the same semantics.  However, I thikn that perhaps mucking around with 'new' is the wrong way to solve it.

I've thought, right from the very beginning, that classes should use explicit pointer syntax.  That is, a class refernce should be declared as a pointer, just like a pointer to a struct.  Likewise, it should be possible to 'new' a struct.  So, in my opinion, you should write this code:

	MyClass *ref; // this should be a class refernce
	MyStruct *ptr; // this is a struct pointer
	MyClass val; // this would be a syntax error

Then, you could write your templates like this:

	T *ref = new T(foo,bar,baz);

Assuming that structs had constructors, and that new was possible on structs, this would work just fine with both structs and classes.

July 12, 2004
the point of structs is to be able to remain on the stack
:-)
otherwise I'd just hack up a class :-)
and that doesn't solve the int problem, does it?

int * i = new int (1); isn't valid

Russ Lewis wrote:
> Daniel Horn wrote:
> 
>> the point is that then you have to jump through hoops to get templates that should work for both structs and classes working... I think there needs to be some work to add transparency to types... making them all act different, construct different and copy different makes it next-to-impossible to make a template class that works for all (case in point see my float1,2,3,4 structs that need to accept integers, classes (i.e. BigInt) or other floatX structs
> 
> 
> I agree that it would beegood for structs and classes to have the same semantics.  However, I thikn that perhaps mucking around with 'new' is the wrong way to solve it.
> 
> I've thought, right from the very beginning, that classes should use explicit pointer syntax.  That is, a class refernce should be declared as a pointer, just like a pointer to a struct.  Likewise, it should be possible to 'new' a struct.  So, in my opinion, you should write this code:
> 
>     MyClass *ref; // this should be a class refernce
>     MyStruct *ptr; // this is a struct pointer
>     MyClass val; // this would be a syntax error
> 
> Then, you could write your templates like this:
> 
>     T *ref = new T(foo,bar,baz);
> 
> Assuming that structs had constructors, and that new was possible on structs, this would work just fine with both structs and classes.
> 
July 13, 2004
In article <opsa1n9i1k5a2sq9@digitalmars.com>, Regan Heath says...

>> and (3) static opCall
>> be deprecated in favor of constructors.
>
>I don't agree. opCall has more uses than simply simulating a constructor. I have used a C++ class with the STL as a comparisson 'function' using operator() overloads. This allows you to pack a bunch of stuff that you require for the comparrison into the class and then use it in the operator() method.

Aaaaargh!!

Well, I'll bet that not even you have done this in C++. I certainly haven't:

#    class A
#    {
#        static T operator()(parameters);
#      //^^^^^^//
#    }

Do correct me if I'm wrong.

What is it with people not seeing what I wrote. Was the word "static" invisible or something?

For what it's worth, I actually think that *STATIC* opEVERYTHING should be deprecated. Currently, we can override *static* opAdd(), *static* opMul(), and so on, allowing us to write truly mad expressions like:

#    // A and B are classes or structs, not necessarily related:
#
#    dchar c = A + 0.1;  // dchar c = /*static*/ A.opAdd(0.1);
#    A a = B * new A();  // A a = /*static*/ B.opMul(new A());

This is utterly pointless. And before anyone says "we might think of use for it one day", yes, we might, but there is nothing that the above achieves that can't be equally well achieved with a straightforward named static function.

But it gets worse. static opCall is currently used to simulate constructors. But the language permits you to define static A.opCall() to return a value of /any/ type, not just an A. It could return a double, for example. So if you EXPECT it to act like a constructor, you might get surprised one day.

What's more, if you initialize a struct with something like:

#    A a = A(parameters);

then what actually happens is this (1) the struct "a" is constructed on the
stack; (2) all of a's member variables are initialized to their .init values;
(3) _static_ A.opCall() is evaluated, which constructs ANOTHER object of type A
on the stack, also with all of its member variables initialized to their .init
values; (4) during execution of static A.opCall(), the member variables of the
second A are overwritten with new values derived from the function parameters;
(5) on return from static opCall(), the second A is bitwise-copied onto a; and
finally (6) the second copy is discarded.

I would hope that having constructors for structs would eliminate all this needless copying.

Jill


July 13, 2004
In article <opsa1oztn45a2sq9@digitalmars.com>, Regan Heath says...

>>>> Could anybody explain me, in which I you'd want to overload opMul on classes?
>>>
>> Also the Int class (unlimited precision integer) in etc.bigint.bigint.
>
>Shouldn't these all be structs, not classes, they're 'value' types, not 'reference' types aren't they?

No.

It is an absolute and unchangeable requirement that my Ints ***MUST*** have destructors, for reasons of security. Therefore they cannot be structs.

They are immutable reference types.
#        ^^^^^^^^^

Jill


July 13, 2004
Daniel Horn wrote:
> well an int is no different than a struct
> not sure why you can't just do
> 
> int x = int(5);
> float y= float(2.5);

In article <ccv6te$g7l$1@digitaldaemon.com>, Andy Friesen says...
>
>  Requiring a opCall(int) leaves inheritance as the only option, which
>is somewhat frail.

Of course, you mean /static/ int.opCall() here. Otherwise the syntax would end
up as:

#    int x = 5(5);

"static" may be just one little word, but things get awfully confusing when people ignore it or imagine it to be meaningless.

Jill



July 13, 2004
On Tue, 13 Jul 2004 07:22:05 +0000 (UTC), Arcane Jill wrote:

> In article <opsa1n9i1k5a2sq9@digitalmars.com>, Regan Heath says...
> 
>>> and (3) static opCall
>>> be deprecated in favor of constructors.
>>
>>I don't agree. opCall has more uses than simply simulating a constructor. I have used a C++ class with the STL as a comparisson 'function' using operator() overloads. This allows you to pack a bunch of stuff that you require for the comparrison into the class and then use it in the operator() method.
> 
> Aaaaargh!!
> 
> Well, I'll bet that not even you have done this in C++. I certainly haven't:
> 
> #    class A
> #    {
> #        static T operator()(parameters);
> #      //^^^^^^//
> #    }
> 
> Do correct me if I'm wrong.
> 
> What is it with people not seeing what I wrote. Was the word "static" invisible or something?
> 
> For what it's worth, I actually think that *STATIC* opEVERYTHING should be deprecated. Currently, we can override *static* opAdd(), *static* opMul(), and so on, allowing us to write truly mad expressions like:
> 
> #    // A and B are classes or structs, not necessarily related:
> #
> #    dchar c = A + 0.1;  // dchar c = /*static*/ A.opAdd(0.1);
> #    A a = B * new A();  // A a = /*static*/ B.opMul(new A());
> 
> This is utterly pointless. And before anyone says "we might think of use for it one day", yes, we might, but there is nothing that the above achieves that can't be equally well achieved with a straightforward named static function.
> 
> But it gets worse. static opCall is currently used to simulate constructors. But the language permits you to define static A.opCall() to return a value of /any/ type, not just an A. It could return a double, for example. So if you EXPECT it to act like a constructor, you might get surprised one day.
> 
> What's more, if you initialize a struct with something like:
> 
> #    A a = A(parameters);
> 
> then what actually happens is this (1) the struct "a" is constructed on the
> stack; (2) all of a's member variables are initialized to their .init values;
> (3) _static_ A.opCall() is evaluated, which constructs ANOTHER object of type A
> on the stack, also with all of its member variables initialized to their .init
> values; (4) during execution of static A.opCall(), the member variables of the
> second A are overwritten with new values derived from the function parameters;
> (5) on return from static opCall(), the second A is bitwise-copied onto a; and
> finally (6) the second copy is discarded.
> 
> I would hope that having constructors for structs would eliminate all this needless copying.
> 
> Jill

I'm wondering if I've been doing something really stupid then. I have a this sort of thing happening...

struct Foo {
   . . . whatever . . .
   void opCall(size_t x) { .... }
   void opCall(double x) { .... }
   void opCall(char[] x) { .... }
   void opCall(char  x) { .... }

}

void main()
{
   Foo a;
   Foo b;
   Foo c;
   Foo d;

   a(3.4);  // Initialize this one to 3.4
   b(17);  // Initialize this one to 17
   c("happy me");  // Initialize this one to "happy me"
   d('?'); // Initialize this one to '?'
}

Actually, I didn't like the look of this in code, so I overloaded "<<=" so I could also write ...

  a <<= 3.4;
  b <<= 17;
  c <<= "happy me";
  d <<= '?';

to set the value of these structures. I know to the mathematical purists this is 'evil'. Presumably because they can only see "<<=" as shifting bits to the left and assigning the result to itself. But I see "<<=" as a way of saying 'copy the value on the right-side to the thing that's on the left-side'.  Gee, much like I see "=" really. Sure wish I could overload "=", 'cos that would make a lot of sense to me.

I want to set the value of these structures but I don't want to deal with the internal repesentation all the time. That's why we have method's, right?


Am I doing things the kosher 'D' way or am I way off base?


-- 
Derek
Melbourne, Australia
13/Jul/04 6:02:33 PM
July 13, 2004
Arcane Jill" <Arcane_member@pathlink.com> wrote in message news:cd02it$1vc4$1@digitaldaemon.com...
> In article <opsa1n9i1k5a2sq9@digitalmars.com>, Regan Heath says...
>
> >> and (3) static opCall
> >> be deprecated in favor of constructors.
> >
> >I don't agree. opCall has more uses than simply simulating a constructor. I have used a C++ class with the STL as a comparisson 'function' using operator() overloads. This allows you to pack a bunch of stuff that you require for the comparrison into the class and then use it in the operator() method.
>
> Aaaaargh!!
>
> Well, I'll bet that not even you have done this in C++. I certainly
haven't:
>
> #    class A
> #    {
> #        static T operator()(parameters);
> #      //^^^^^^//
> #    }
>
> Do correct me if I'm wrong.
>
> What is it with people not seeing what I wrote. Was the word "static"
invisible
> or something?
>
> For what it's worth, I actually think that *STATIC* opEVERYTHING should be

I must disagree, i think static operators will prove to be usefull!

> deprecated. Currently, we can override *static* opAdd(), *static* opMul(),
and
> so on, allowing us to write truly mad expressions like:
>
> #    // A and B are classes or structs, not necessarily related:
> #
> #    dchar c = A + 0.1;  // dchar c = /*static*/ A.opAdd(0.1);
> #    A a = B * new A();  // A a = /*static*/ B.opMul(new A());
>
> This is utterly pointless. And before anyone says "we might think of use
for it
> one day", yes, we might, but there is nothing that the above achieves that
can't
> be equally well achieved with a straightforward named static function.
>
> But it gets worse. static opCall is currently used to simulate
constructors. But
> the language permits you to define static A.opCall() to return a value of
/any/
> type, not just an A. It could return a double, for example. So if you
EXPECT it
> to act like a constructor, you might get surprised one day.
>
> What's more, if you initialize a struct with something like:
>
> #    A a = A(parameters);
>
> then what actually happens is this (1) the struct "a" is constructed on
the
> stack; (2) all of a's member variables are initialized to their .init
values;
> (3) _static_ A.opCall() is evaluated, which constructs ANOTHER object of
type A
> on the stack, also with all of its member variables initialized to their
.init
> values; (4) during execution of static A.opCall(), the member variables of
the
> second A are overwritten with new values derived from the function
parameters;
> (5) on return from static opCall(), the second A is bitwise-copied onto a;
and
> finally (6) the second copy is discarded.
>
> I would hope that having constructors for structs would eliminate all this needless copying.

With this i agree. Constructors for structs would be great!

>
> Jill
>
>


July 13, 2004
"Derek Parnell" <derek@psych.ward> wrote in message news:cd05k8$25b0$1@digitaldaemon.com...
> On Tue, 13 Jul 2004 07:22:05 +0000 (UTC), Arcane Jill wrote:
>
> > In article <opsa1n9i1k5a2sq9@digitalmars.com>, Regan Heath says...
> >
> >>> and (3) static opCall
> >>> be deprecated in favor of constructors.
> >>
> >>I don't agree. opCall has more uses than simply simulating a
constructor.
> >>I have used a C++ class with the STL as a comparisson 'function' using operator() overloads. This allows you to pack a bunch of stuff that you require for the comparrison into the class and then use it in the operator() method.
> >
> > Aaaaargh!!
> >
> > Well, I'll bet that not even you have done this in C++. I certainly
haven't:
> >
> > #    class A
> > #    {
> > #        static T operator()(parameters);
> > #      //^^^^^^//
> > #    }
> >
> > Do correct me if I'm wrong.
> >
> > What is it with people not seeing what I wrote. Was the word "static"
invisible
> > or something?
> >
> > For what it's worth, I actually think that *STATIC* opEVERYTHING should
be
> > deprecated. Currently, we can override *static* opAdd(), *static*
opMul(), and
> > so on, allowing us to write truly mad expressions like:
> >
> > #    // A and B are classes or structs, not necessarily related:
> > #
> > #    dchar c = A + 0.1;  // dchar c = /*static*/ A.opAdd(0.1);
> > #    A a = B * new A();  // A a = /*static*/ B.opMul(new A());
> >
> > This is utterly pointless. And before anyone says "we might think of use
for it
> > one day", yes, we might, but there is nothing that the above achieves
that can't
> > be equally well achieved with a straightforward named static function.
> >
> > But it gets worse. static opCall is currently used to simulate
constructors. But
> > the language permits you to define static A.opCall() to return a value
of /any/
> > type, not just an A. It could return a double, for example. So if you
EXPECT it
> > to act like a constructor, you might get surprised one day.
> >
> > What's more, if you initialize a struct with something like:
> >
> > #    A a = A(parameters);
> >
> > then what actually happens is this (1) the struct "a" is constructed on
the
> > stack; (2) all of a's member variables are initialized to their .init
values;
> > (3) _static_ A.opCall() is evaluated, which constructs ANOTHER object of
type A
> > on the stack, also with all of its member variables initialized to their
.init
> > values; (4) during execution of static A.opCall(), the member variables
of the
> > second A are overwritten with new values derived from the function
parameters;
> > (5) on return from static opCall(), the second A is bitwise-copied onto
a; and
> > finally (6) the second copy is discarded.
> >
> > I would hope that having constructors for structs would eliminate all
this
> > needless copying.
> >
> > Jill
>
> I'm wondering if I've been doing something really stupid then. I have a this sort of thing happening...
>
> struct Foo {
>    . . . whatever . . .
>    void opCall(size_t x) { .... }
>    void opCall(double x) { .... }
>    void opCall(char[] x) { .... }
>    void opCall(char  x) { .... }
>
> }
>
> void main()
> {
>    Foo a;
>    Foo b;
>    Foo c;
>    Foo d;
>
>    a(3.4);  // Initialize this one to 3.4
>    b(17);  // Initialize this one to 17
>    c("happy me");  // Initialize this one to "happy me"
>    d('?'); // Initialize this one to '?'
> }
>
> Actually, I didn't like the look of this in code, so I overloaded "<<=" so I could also write ...
>
>   a <<= 3.4;
>   b <<= 17;
>   c <<= "happy me";
>   d <<= '?';
>
> to set the value of these structures. I know to the mathematical purists this is 'evil'. Presumably because they can only see "<<=" as shifting
bits
> to the left and assigning the result to itself. But I see "<<=" as a way
of
> saying 'copy the value on the right-side to the thing that's on the left-side'.  Gee, much like I see "=" really. Sure wish I could overload "=", 'cos that would make a lot of sense to me.
>
> I want to set the value of these structures but I don't want to deal with the internal repesentation all the time. That's why we have method's, right?
>
>
> Am I doing things the kosher 'D' way or am I way off base?

It seems like one of these things that is convenient to its author (at the time of writing - you'll be confused by it in six months' time) but is likely to lead to a host of inconsistent behaviours amongst the practitioners.

So I'd say "way off base", I'm afraid

;/




July 13, 2004
On Tue, 13 Jul 2004 18:21:23 +1000, Matthew Wilson wrote:


[snip]

>> But I see "<<=" as a way of
>> saying 'copy the value on the right-side to the thing that's on the
>> left-side'.  Gee, much like I see "=" really. Sure wish I could overload
>> "=", 'cos that would make a lot of sense to me.
>>
>> I want to set the value of these structures but I don't want to deal with the internal repesentation all the time. That's why we have method's, right?
>>
>>
>> Am I doing things the kosher 'D' way or am I way off base?
> 
> It seems like one of these things that is convenient to its author (at the time of writing - you'll be confused by it in six months' time) but is likely to lead to a host of inconsistent behaviours amongst the practitioners.
> 
> So I'd say "way off base", I'm afraid

Thanks mate. I sorta suspected so. Now if only I could overload '=' so my INTENTIONS to the code reader were a bit more obvious.

So what's a better way? An explicit function call to assign a value?

eg.

   a.opAssign("hello")

It sort of seems stupid to resort to doing this when the language already has an operator to do it...

-- 
Derek
Melbourne, Australia
13/Jul/04 7:01:45 PM
July 13, 2004
I think you'll find if you read *my* reply to *my* post to which you are replying below you'll find that I rescinded my comment as I realised I had indeed missed the word 'static'.

You make a good point about what goes on when someone uses a static opCall to emulate a constructor. I agree structs should have constructors. If they have constructors I think they should also have destructors. Thus allowing you to write your BigInt stuff with structs, which IMO they should be, as they're value types, not reference types.

I also think structs should have inheritance. NOT in the same way as classes, NOT with any virtual function overhead, simply inherit methods and members. Sure, you can do this with mixins, but IMO they are messy, whereas struct inheritance could be quite clean.

My 2c yet again.

Regan

On Tue, 13 Jul 2004 07:22:05 +0000 (UTC), Arcane Jill <Arcane_member@pathlink.com> wrote:

> In article <opsa1n9i1k5a2sq9@digitalmars.com>, Regan Heath says...
>
>>> and (3) static opCall
>>> be deprecated in favor of constructors.
>>
>> I don't agree. opCall has more uses than simply simulating a constructor.
>> I have used a C++ class with the STL as a comparisson 'function' using
>> operator() overloads. This allows you to pack a bunch of stuff that you
>> require for the comparrison into the class and then use it in the
>> operator() method.
>
> Aaaaargh!!
>
> Well, I'll bet that not even you have done this in C++. I certainly haven't:
>
> #    class A
> #    {
> #        static T operator()(parameters);
> #      //^^^^^^//
> #    }
>
> Do correct me if I'm wrong.
>
> What is it with people not seeing what I wrote. Was the word "static" invisible
> or something?
>
> For what it's worth, I actually think that *STATIC* opEVERYTHING should be
> deprecated. Currently, we can override *static* opAdd(), *static* opMul(), and
> so on, allowing us to write truly mad expressions like:
>
> #    // A and B are classes or structs, not necessarily related:
> #
> #    dchar c = A + 0.1;  // dchar c = /*static*/ A.opAdd(0.1);
> #    A a = B * new A();  // A a = /*static*/ B.opMul(new A());
>
> This is utterly pointless. And before anyone says "we might think of use for it
> one day", yes, we might, but there is nothing that the above achieves that can't
> be equally well achieved with a straightforward named static function.
>
> But it gets worse. static opCall is currently used to simulate constructors. But
> the language permits you to define static A.opCall() to return a value of /any/
> type, not just an A. It could return a double, for example. So if you EXPECT it
> to act like a constructor, you might get surprised one day.
>
> What's more, if you initialize a struct with something like:
>
> #    A a = A(parameters);
>
> then what actually happens is this (1) the struct "a" is constructed on the
> stack; (2) all of a's member variables are initialized to their .init values;
> (3) _static_ A.opCall() is evaluated, which constructs ANOTHER object of type A
> on the stack, also with all of its member variables initialized to their .init
> values; (4) during execution of static A.opCall(), the member variables of the
> second A are overwritten with new values derived from the function parameters;
> (5) on return from static opCall(), the second A is bitwise-copied onto a; and
> finally (6) the second copy is discarded.
>
> I would hope that having constructors for structs would eliminate all this
> needless copying.
>
> Jill
>
>



-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/