int S(int x) { return x+1; }
int twice(int f(int), int y) { return f(f(y)); }
int twice_S(int y) { return twice(S,y); }
slide: Types in C++
Nevertheless, the type system of C++ imposes
some severe restrictions.
For example, functions may not be returned
as a value from functions.
(Although we may provide a workaround, when we employ
the function for objects.)
The absence of function subtyping becomes clear
when, for example, we call the function twice
with the function SD, which is defined as:
int SD(double x) { return x+1; }
slide: SD example
According to the subtyping rules and in accordance
with the substitutability requirement,
we employ SD whenever we may employ S.
But not so in C++.
We run into similar limitations when we try
to refine an object class descriptions following
the object subtype refinement rules.
class P { P
public:
P() { _self = 0; }
virtual P* self() {
return _self?_self->self():this;
}
virtual void attach(C* p) {
_self = p;
}
private:
P* _self;
};
class C : public P {
public:
C() : P(this) { }
C* self() { ANSI/ISO
return _self?_self->self():this;
}
void attach(P* p) { rejected
p->attach(self());
}
void redirect(C* c) { _self = c; }
private:
C* _self;
};
slide: Subtyping in C++
Suppose we have a parent class P which offers
the member functions self and attach,
as in slide [9-cc-sub].
The meaning of the function self is that
it de-references the _self variable if
it is non-zero and delivers this otherwise.
(See section [hush] for an example of its use.)
The function attach may be used to connect an
instance of C to the _self variable.
The class C in its turn inherits from P
and redefines self and attach.
Syntactically, both refinements are allowed,
due to the function subtype refinements rules.
The function self is redefined to deliver
a more tightly specified result,
and the attach function is allowed to take a wider
range of arguments.
In a number of compilers for C++,
both redefinitions are considered illegal.
However, in the ANSI/ISO standard of C++,
redefining a member function to deliver
a subtype (that is, derived class) pointer will be allowed.
Redefining attach, as has been done for C
is probably not a wise thing to do,
since it changes the semantics of attach
as defined for the parent class P.
In effect, it allows us to write
instead of
, for and .
Nevertheless, from a type theoretical perspective,
there seem to be no grounds for forbidding it.