www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - (emulating) weak typing and some other things

reply "seany" <seany uni-bonn.de> writes:
I am sorry, perhaps the question could be answered with already 
available information, but I did not manage to figure it 
completely

I realize that D is a strongly typed language. But in certain 
scenarios i may want to use a weak typing, especially when 
handling structs which are very close to each other in content, 
but not equal, it would be nice to use to redefine the type while 
preserving the name.

So for example consider
struct S_A { //many contents};
and
struct S_B { //all contents of S_A +
int SomeExtra};

//do something
S_A o1;
S_B o2;
//do some morething
if(someCondition)
{
    S_A temp;
    S_B o1;
    o1 = o2;

    //set other stuff of temp in o1
    //do the extra processing on the SomeExtra integer
}

//continue processing o1


For this very particular simple example it is possible to do the 
same thing without bothering about type conversion. However, in 
general - although i can not strictly prove it - weak typing 
could be used to avoid too much branching, while I could, for 
EACH variation fo the struct possibly (or not) write a if-else 
braching, I would prefer some easier approach.

One approach would be to somehow make the comipler to ignore the 
shadowing definition, where o1 is redefined as S_B, and another 
approach can be to dynamically allocate elements to a stack

so if(someCondition)
{
//dynamically allocate the element int SomeExtra
//to S_A o1,

And then the next question is how to resolve the conflict that o1 
WAS a S_A, now has an extra element ..

Perhaps tuples would be an approach, but what are the differences 
between such a dynamic struct and a tuple?

thank you for your patience
Dec 20 2013
next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Dec 20, 2013 at 06:30:53PM +0100, seany wrote:
 I am sorry, perhaps the question could be answered with already
 available information, but I did not manage to figure it completely
 
 I realize that D is a strongly typed language. But in certain
 scenarios i may want to use a weak typing, especially when handling
 structs which are very close to each other in content, but not equal,
 it would be nice to use to redefine the type while preserving the
 name.
[...] See std.typecons.Variant. T -- The volume of a pizza of thickness a and radius z can be described by the following formula: pi zz a. -- Wouter Verhelst
Dec 20 2013
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
seany:

 thank you for your patience
Beside using Variant or Alebraic, some of your cases can be handled with a "alias this" plus some manual code. struct Foo1 { int x; } struct Foo2 { Foo1 f; int y; alias f this; } Bye, bearophile
Dec 20 2013
prev sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Dec 20, 2013 at 09:40:47AM -0800, H. S. Teoh wrote:
 On Fri, Dec 20, 2013 at 06:30:53PM +0100, seany wrote:
 I am sorry, perhaps the question could be answered with already
 available information, but I did not manage to figure it completely
 
 I realize that D is a strongly typed language. But in certain
 scenarios i may want to use a weak typing, especially when handling
 structs which are very close to each other in content, but not equal,
 it would be nice to use to redefine the type while preserving the
 name.
[...] See std.typecons.Variant.
[...] Another way is to use alias this: struct B { int x, y, z; // common fields } struct C { B _common; alias _common this; float p, q, r; } struct D { B _common; alias _common this; string a, b, c; } C c; c.x = 1; // same as c._common.x = 1 c.p = 1.0; D d; d.x = 1; // same as d._common.x = 1 d.a = "abc"; void fun(B b) { ... } fun(c); // OK, same as fun(c._common) fun(d); // OK, same as fun(d._common) Basically, this is the struct equivalent of class inheritance, except without the dynamic polymorphism. If this is not good enough, you can use casts to force structs into each other: struct S { int x; string y; } struct T { int a; float b; } T t; S* ptr = cast(S*) &t; ptr.x = 1; // effectively does t.a = 1. But this is dangerous, since it relies on programming by convention: if the definitions of S and T don't match, the above code will corrupt data instead. Using alias this or std.typecons.Variant is a much better, type-safe solution. T -- Claiming that your operating system is the best in the world because more people use it is like saying McDonalds makes the best food in the world. -- Carl B. Constantine
Dec 20 2013