Walter's second axiom

Bill Baxter dnewsgroup at billbaxter.com
Sat Dec 8 05:05:16 PST 2007


Janice Caron wrote:
> As discussed elsewhere, Walter's second axiom states: for any type T,
> it should be possible to construct a struct S which behaves exactly
> like a T, by wrapping T inside a struct and adding extra member
> functions, like so:
> 
>     struct S
>     {
>         T t;
>         /* functions */
>     }
> 
> However, there is at least one violation of the axiom: inheritance. As follows:
> 
>     class C {}
>     struct S { C c; }
> 
> I can do
> 
>     class D : C {}
> 
> but I can't do
> 
>     class D : S {}
> 
> thus, S cannot be made to behave exactly like C, and so the axiom does not hold.

There are various other ones that have to do with return of lvalues (or 
lack thereof).
For instance, if T is int[], you can do t[0]++ but you can't do that for 
a struct that wraps an int[].

Also the thing about default initializers for struct wrappers.  Perhaps 
that's just a bug, though.  Walter hasn't commented whether he intends 
to make that work or not.  The example is wrap a numeric type and give 
it all the bells it needs to initialize it with a regular number, like 
MyInt x = 5.  Now try to use it as a paramter with default:
      void func(MyInt x = 5) // error

But I think axiom 2 is great and I'd love to see a solution for all of 
the holes that prevent making a wrapper behave exactly like another type.

> The solution is to provide structs with some mechanism that allows
> classes to inherit from them - such as, for example, opInherit()
> 
>     struct S
>     {
>         C c;
>         C opInherit() { return c; }
>     }
> 
> A class could then inherit from either a class, or from a struct which
> supplies opInherit(). opInherit() itself must, of course, return
> either a class, or a struct which supplies opInherit().
> 
> This is not a feature request as such. I'm just mentioning - from a
> purely theoretical standpoint - a violation of Walter's second axiom,
> and a possible remedy.
> 
> (And just to stir things up further, I think that interfaces violate
> the second axiom also) :-)

I think maybe that's going to far.  There are some places where you 
cannot and should not have a wrapper act like the type it wraps.  The 
main one that comes to mind is an 'is' check.   is(MyWrapper == 
RealClass).  Obviously that should fail.   But it stands to reason that 
there are perhaps some other operations that are so closely tied to the 
actual type that they shouldn't be expected to work with a wrapper.   I 
think inheritance is maybe one of those.

--bb



More information about the Digitalmars-d mailing list