www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - object oriented value type

reply Ender KaShae <astrothayne gmail.com> writes:
I find it a little disappointing that D does not have any support for the C++
way of object oriented value types, both c# and D have structs that pass by
value but do not support inheritance and classes passed by reference that do
support inheritance, D adds injury to insult by prohibiting hidden members in
structs.  But what about when you need a type that passes by value and supports
inheritance, I don't think that the structs necessarily need to be changed,
rathe I think that a new type should be created as a combination of a struct
and a class.  This would be particularly useful in inheriting from primitave
types.  Another example is having a mixedFraction inherit from fraction.
Jun 25 2007
parent reply Robert Fraser <fraserofthenight gmail.com> writes:
What's the point? There's no way to refer to a subtype by the supertype (since
the compiler wouldn't know what size the struct would be), so the only OO
feature you'd get is mere aggregation, which should be explicit anyway.

You can have private struct functions/members - all the privacy concerns are at
the module level, so a private struct member is module-private, just as a
private class member is.

I do think having a syntax to add properties to primitive types is a good idea,
though, in the same way as the funky array syntax works now.

Ender KaShae Wrote:

 I find it a little disappointing that D does not have any support for the C++
way of object oriented value types, both c# and D have structs that pass by
value but do not support inheritance and classes passed by reference that do
support inheritance, D adds injury to insult by prohibiting hidden members in
structs.  But what about when you need a type that passes by value and supports
inheritance, I don't think that the structs necessarily need to be changed,
rathe I think that a new type should be created as a combination of a struct
and a class.  This would be particularly useful in inheriting from primitave
types.  Another example is having a mixedFraction inherit from fraction.

Jun 25 2007
next sibling parent reply BCS <ao pathlink.com> writes:
Reply to Robert,

 I do think having a syntax to add properties to primitive types is a
 good idea, though, in the same way as the funky array syntax works
 now.

how about |typedef int myInt |{ | static addCount=0; // static members? why not? | | myInt opAdd(myInt that) | { | addCount++; | return this+that; // this is int | } | private opMod(); // forbid mod on myInt |} added in template typedefs: |typedef real SIuint(int dist, int mass, int time) |{ | SIuint!(dist+T.dist, mass+T.mass, time+T.time) opMull(T)(T p) // in-lining reduces to same as normal mul | { | return this*p; | } |} and some really cool stuff starts happening
Jun 25 2007
parent Robert Fraser <fraserofthenight gmail.com> writes:
Interesting, interesting... There are more than a few places I've used a struct
to wrap a single primitive value/enum so that I could make it typesafe and add
methods to it, so I guess that isn't too fundamentally different, though it's
much cleaner.

Still, the advantage of giving array-function-style syntax can be seen when
it's used on a literal. Consider something like:

void times(int n, void delegate() action)
{
    for(int i = 0; i < n; i++)
        action();
}

3.times({writefln("Why, hello there!");});

...or, perhaps more useful

Very Ruby-esque, but clean in its own way. It reads quite like English,
actually. Well, except for all those funky brackets & semicolons...

BCS Wrote:

 how about 
 
 |typedef int myInt
 |{
 |  static addCount=0; // static members? why not?
 |
 |  myInt opAdd(myInt that)
 |  {
 |     addCount++;
 |     return this+that; // this is int
 |  }
 |  private opMod(); // forbid mod on myInt
 |}
 
 added in template typedefs:
 
 |typedef real SIuint(int dist, int mass, int time)
 |{
 |   SIuint!(dist+T.dist, mass+T.mass, time+T.time) opMull(T)(T p)  //
in-lining 
 reduces to same as normal mul
 |   {
 |      return this*p;
 |   }
 |}
 
 and  some really cool stuff starts happening
 
 

Jun 26 2007
prev sibling parent reply Henning Hasemann <hhasemann web.de> writes:
BCS <ao pathlink.com> schrieb (Mon, 25 Jun 2007 19:10:54 +0000 (UTC)):
 Reply to Robert,
 
 I do think having a syntax to add properties to primitive types is a
 good idea, though, in the same way as the funky array syntax works
 now.


Wouldnt it be more straigtforward if there were no basic types at all? Ok, you then run into the OO-value-type question again, but somithing like (to follow the example below) // No special syntax needed to declare that this is a value type as it // inherits from one (int) class MyInt : int { static addCount = 0; MyInt opAdd(MyInt that) { addCount++; return this.value + that.value; } }
 how about 
 
 |typedef int myInt
 |{
 |  static addCount=0; // static members? why not?
 |
 |  myInt opAdd(myInt that)
 |  {
 |     addCount++;
 |     return this+that; // this is int

That would be a bit confusing at it looks like recursion.
 |  }
 |  private opMod(); // forbid mod on myInt
 |}
 
 added in template typedefs:
 
 |typedef real SIuint(int dist, int mass, int time)
 |{
 |   SIuint!(dist+T.dist, mass+T.mass, time+T.time) opMull(T)(T p)  //
 in-lining reduces to same as normal mul
 |   {
 |      return this*p;
 |   }
 |}

I must confess I dont think that I understand your example. Would that allow multiplying integers with units? Henning -- GPG Public Key: http://keyserver.ganneff.de:11371/pks/lookup?op=get&search=0xDDD6D36D41911851 Fingerprint: 344F 4072 F038 BB9E B35D E6AB DDD6 D36D 4191 1851
Jun 25 2007
parent BCS <ao pathlink.com> writes:
Reply to Henning,

 BCS <ao pathlink.com> schrieb (Mon, 25 Jun 2007 19:10:54 +0000 (UTC)):
 
 Reply to Robert,
 
 I do think having a syntax to add properties to primitive types is a
 good idea, though, in the same way as the funky array syntax works
 now.
 


Ok, you then run into the OO-value-type question again, but somithing like (to follow the example below) // No special syntax needed to declare that this is a value type as it // inherits from one (int) class MyInt : int { static addCount = 0; MyInt opAdd(MyInt that) { addCount++; return this.value + that.value; } }

that would be vary hard to make work well in a systems language. the point of the typedef I J {...} would be to let the user change (at compile time) the semantics of the the built in types.
 how about
 
 |typedef int myInt
 |{
 |  static addCount=0; // static members? why not?
 |
 |  myInt opAdd(myInt that)
 |  {
 |     addCount++;
 |     return this+that; // this is int

That would be a bit confusing as it looks like recursion.

okay make it: return cast(int)this+cast(int)that;
 |  }
 |  private opMod(); // forbid mod on myInt
 |}
 added in template typedefs:
 
 |typedef real SIuint(int dist, int mass, int time)
 |{
 |   SIuint!(dist+T.dist, mass+T.mass, time+T.time) opMull(T)(T p)
 |      // in-lining reduces to same as normal mul
 |   {
 |      return this*p;
 |   }
 |}

I must confess I dont think that I understand your example. Would that allow multiplying integers with units?

Oh please don't nit pick <g> I just slaped that togehter. SIuint!(dist+Tdist, mass+Tmass, time+Ttime) opMull(int Tdist, int Tmass, int Ttime)(SIunit!(Tdist, Tmass, Ttime) p) some sort of int == SIUnit!(0,0,0) would be needed to.
Jun 25 2007