Topic: GNU Signatures


Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/04/06
Raw View
inkari@finsun.csc.fi (Juha Inkari) writes:

>maxtal@Physics.usyd.edu.au (John Max Skaller) writes:
>
>>    // SMART MACRO
>>    template <class T> void increment(T& t, int n) { t.inc(n); }
>
>>    // works if t _looks_ like it is incrementable
>>    // "inc" might take an argument of float type and an implicit
>>    // conversion is performed: it might then do anything,
>>    // rather than increment
>
>Ok, but how about using a helper class which explicitly tells what
>conversions are ok or forbidden. For example:
>
>class pure_int
>{
>  int h;
>// List all the conversions you dont want to happen as private.
>  operator double() { }
>  operator long() { }
>  operator float() { }

But there's an unbounded number of them!
You can't list them all.

>The point is, that the existing syntax can be used for this type of
>argument checking, IMHO.  It may not be so pretty, though.

Well, I think YHO is simply wrong.  Even if it were right though,
doing so would be so ugly that it would be impractical.

--
Fergus Henderson - fjh@munta.cs.mu.oz.au





Author: inkari@finsun.csc.fi (Juha Inkari)
Date: 28 Mar 1995 22:58:58 GMT
Raw View
In article <D61D8x.3Lo@ucc.su.OZ.AU> maxtal@Physics.usyd.edu.au (John Max Skaller) writes:

>   Date: Sun, 26 Mar 1995 07:10:09 GMT
>   Lines: 57

>    // SMART MACRO
>    template <class T> void increment(T& t, int n) { t.inc(n); }

>    // works if t _looks_ like it is incrementable
>    // "inc" might take an argument of float type and an implicit
>    // conversion is performed: it might then do anything,
>    // rather than increment

Ok, but how about using a helper class which explicitly tells what
conversions are ok or forbidden. For example:

class pure_int
{
  int h;
// List all the conversions you dont want to happen as private.
  operator double() { }
  operator long() { }
  operator float() { }
public:
  pure_int(int i): h(i)  { }
  operator int() { return h; }
};

template <class T>
void increment(T& t, int n)
{
  pure_int help(n);
  t.inc(help);
}

If you want, the helper class could be buried inside the template
function, too.

>    // GENERICITY
>    sig has_increment { void inc(int); }
>    void increment(has_increment &t, int n) { t.inc(n); }

>    // t not only has to look incrementable, but the
>    // signature of "inc" has to have an int argument
>    // stronger checking than the template

The point is, that the existing syntax can be used for this type of
argument checking, IMHO. It may not be so pretty, though.

--
/* Juha.Inkari@hut.fi */




Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: Sun, 26 Mar 1995 07:10:09 GMT
Raw View
In article <GIROD.95Mar24135110@dshp01.trs.ntc.nokia.com>,
Marc Girod <girod@trshp.trs.ntc.nokia.com> wrote:
>>>>>> "max" == John Max Skaller <maxtal@Physics.usyd.edu.au> writes:
>In article <D5I341.Bwo@ucc.su.OZ.AU> maxtal@Physics.usyd.edu.au (John Max Skaller) writes:
>
>>> I hope there is no serious attempt to have signatures adopted at any
>>> stage into C++.
>
>max>  Boy, am I confused. C++ already has a form of signatures
>max> which is far WEAKER than the
>
>max>  sig signame { .. }
>
>max> construction. Its called "templates".
>
>Well, I am not less confused!

 // DUMB MACRO
 #define increment(t,n) t.inc(n)
 // works if t looks incrementable

 // SMART MACRO
 template <class T> void increment(T& t, int n) { t.inc(n); }

 // works if t _looks_ like it is incrementable
 // "inc" might take an argument of float type and an implicit
 // conversion is performed: it might then do anything,
 // rather than increment

 // GENERICITY
 sig has_increment { void inc(int); }
 void increment(has_increment &t, int n) { t.inc(n); }

 // t not only has to look incrementable, but the
 // signature of "inc" has to have an int argument
 // stronger checking than the template

 // POLYMORPHISM
 struct incrementable { void inc(int n)=0;};
 void increment(incrementable &t, int n) { t.inc(n); }

 // t has to be named specifically as an incrementable
 // type by being of a type derived from "incrementable"
 // very strong checking because if it doesn't work,
 // the error is the responsibility of the class deriver,
 // not the client

I hope the above comparison demonstrates increasing order of static
checking. In particular the template (in this case) is no
better than a macro.

Needless to say, as the guarrantees get stronger, flexibility is lost.
--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189




Author: girod@dshp01.trs.ntc.nokia.com (Marc Girod)
Date: 24 Mar 1995 11:51:10 GMT
Raw View
>>>>> "max" == John Max Skaller <maxtal@Physics.usyd.edu.au> writes:
In article <D5I341.Bwo@ucc.su.OZ.AU> maxtal@Physics.usyd.edu.au (John Max Skaller) writes:

>> I hope there is no serious attempt to have signatures adopted at any
>> stage into C++.

max>  Boy, am I confused. C++ already has a form of signatures
max> which is far WEAKER than the

max>  sig signame { .. }

max> construction. Its called "templates".

Well, I am not less confused!
Apart for the interesting and pragmatic point made lately by Cay
Horstmann in this group, I believed templates were a way to enforce
strong typing...

To me, you did not quite answer my arguments (but that's probably
where both of us are confused).

max>  The problem with the strong name based typing of
max> C++ classes with inheritance is that you have to name
max> everything, and you end up binding _specific_ instances
max> of what should be more general notions. For example:

But... this is the intention! And the beauty of the thing! I want a
real direct support from the language for arbitrary concepts of mine.
I want that a Cat be a cat and not a Dog, although I have them both
run and eat, and don't bother to prescribe in what way they differ:
they differ, I tell you (animals, there's nothing like animals :-)!

[...]

max> Signatures are half way between, allowing code reusability
max> and strong checking because they denote explicit
max> interface requirements -- classes go too far, requiring
max> exact layout and name equality, whereas templates don't
max> go far enough, because they have parameters which are
max> not explicitly specified.

After you convinced me to use mixins, I am amazed that you speak of
layout: abstract, dataless classes have few layout constraints.

I rephrase my point. Once you split your interfaces and
implementations along abstract and concrete classes, you are left with
two uses of access protection (private and protected) in the abstract
classes:

- dedicated interfaces through friendship;
- binding your specializations to support a protocol defined as a
  public non virtual member, itself calling (pure) virtual and
  protected (or private) members (the "Template Method" pattern,
  according to the GOF book terminology).

Both aim at providing "behaviour specification", instead of plain
"signature compatibility" (the first because you usually provide the
friend class, therefore binding you clients through the second
pattern).

Signatures are a sad withdrawal from such attempts. I am ready to
agree on improvements to templates (some kinds of constraints, better
checking...), but this is clearly the wrong direction to develop C++!

max> It may well be that there is no space in C++ for the
max> intermediate notion of "signatures".

This is hopefully true, making our discussion "academic".
--
+---------------------------------------------------------------------------+
| Marc Girod - Nokia Telecommunications     Phone: +358-0-511 27703         |
| TL4E - P.O. Box 12                          Fax: +358-0-511 27432         |
| SF-02611 Espoo 61 - Finland            Internet: marc.girod@ntc.nokia.com |
|        X.400: C=FI, A=Elisa, P=Nokia Telecom, SUR=Girod, GIV=Marc         |
+---------------------------------------------------------------------------+




Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Fri, 17 Mar 1995 02:20:56 GMT
Raw View
girod@dshp01.trs.ntc.nokia.com (Marc Girod) writes:

>'Signatures' suppose a separation between interface and implementation
>based on access control, instead of on abstract classes.
>
>These are two incompatible policies.
>
>The second is much stronger, leads to cleaner interfaces, describing
>the actual dependencies.

Huh?  Why are the interfaces cleaner?  What do you mean about describing
the actual dependencies?

>It allows to some extend to constrain
>specializations to support protocols, using non-virtual public member
>functions calling pure virtual protected ones, thus offering an embryo
>of 'behaviour specification' instead of plain 'signature
>specification'.

I don't quite see what you're getting at here.
I think you can do the same sort of thing with signatures.
Perhaps you could give an example?

--
Fergus Henderson - fjh@munta.cs.mu.oz.au




Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: Wed, 15 Mar 1995 21:16:49 GMT
Raw View
In article <GIROD.95Mar10163459@dshp01.trs.ntc.nokia.com>,
Marc Girod <girod@trshp.trs.ntc.nokia.com> wrote:
>'Signatures' suppose a separation between interface and implementation
>based on access control, instead of on abstract classes.
>
>These are two incompatible policies.
>
>The second is much stronger, leads to cleaner interfaces, describing
>the actual dependencies. It allows to some extend to constrain
>specializations to support protocols, using non-virtual public member
>functions calling pure virtual protected ones, thus offering an embryo
>of 'behaviour specification' instead of plain 'signature
>specification'.
>
>I hope there is no serious attempt to have signatures adopted at any
>stage into C++.

 Boy, am I confused. C++ already has a form of signatures
which is far WEAKER than the

 sig signame { .. }

construction. Its called "templates".

 The problem with the strong name based typing of
C++ classes with inheritance is that you have to name
everything, and you end up binding _specific_ instances
of what should be more general notions. For example:

 class AB : A, B {};

is distinct from

 class BA : B, A {};

and indeed from

 class AB2 : A, B {};

Because the number of possible _functionally equivalent_
types are much smaller than the number of ways of naming
them or the irrelevent details of their particular
construction, reusability suffers and systems tend to
be monolithic and will not interoperate with others.

Templates have the opposite problem -- the binding is
so weak they implement without diagnostic completely
bogus notions.

Signatures are half way between, allowing code reusability
and strong checking because they denote explicit
interface requirements -- classes go too far, requiring
exact layout and name equality, whereas templates don't
go far enough, because they have parameters which are
not explicitly specified.

It may well be that there is no space in C++ for the
intermediate notion of "signatures". On the other hand,
they might be just the right form of constraint to
add to templates to bridge the gap to classes.

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189




Author: girod@dshp01.trs.ntc.nokia.com (Marc Girod)
Date: 10 Mar 1995 14:34:59 GMT
Raw View
'Signatures' suppose a separation between interface and implementation
based on access control, instead of on abstract classes.

These are two incompatible policies.

The second is much stronger, leads to cleaner interfaces, describing
the actual dependencies. It allows to some extend to constrain
specializations to support protocols, using non-virtual public member
functions calling pure virtual protected ones, thus offering an embryo
of 'behaviour specification' instead of plain 'signature
specification'.

I hope there is no serious attempt to have signatures adopted at any
stage into C++.
--
+---------------------------------------------------------------------------+
| Marc Girod - Nokia Telecommunications     Phone: +358-0-511 27703         |
| TL4E - P.O. Box 12                          Fax: +358-0-511 27432         |
| SF-02611 Espoo 61 - Finland            Internet: marc.girod@ntc.nokia.com |
|        X.400: C=FI, A=Elisa, P=Nokia Telecom, SUR=Girod, GIV=Marc         |
+---------------------------------------------------------------------------+




Author: jrichard@jupiter.cs.uml.edu (John Richardson)
Date: 07 Mar 1995 13:17:32 GMT
Raw View
   Signatures a la GNU C++.

      The GNU C++ compiler provides an new and extremely useful method
   of run-time polymorphism called "signatures".  Signatures are described
   in the info/TeX documentation for GCC available in, e.g., gcc-2.6.3.tar.gz
   which may be downloaded from, e.g., prep.at.mit.edu or gatekeeper.dec.com.

   [...]
      Signatures provide an easily understood, easily implemented means of
   polymorphism outside the often claustrophobic mechanism of inheritance and,
   as such, deserve to be seriously considered for inclusion in the language
   standard.


I agree 100%.  My question is, does anyone in the ARM committee read
this group.

--
John Richardson
jrichard@cs.uml.edu




Author: tmurphy@panix.com (Timothy Murphy)
Date: 6 Mar 1995 13:02:10 -0500
Raw View
Signatures a la GNU C++.

   The GNU C++ compiler provides an new and extremely useful method
of run-time polymorphism called "signatures".  Signatures are described
in the info/TeX documentation for GCC available in, e.g., gcc-2.6.3.tar.gz
which may be downloaded from, e.g., prep.at.mit.edu or gatekeeper.dec.com.

   A signature looks like the declaration of a class; pointers and references
to signatures are valid types and may be used as function arguments, but
signatures are not classes and do not have constructors.  One binds an object
to a signature using a pointer (or reference) to a class (or signature)
already satisfied by the object; the compiler simply "weaves" a vtable
using the declarations of the signature on the left and the class
(or signature) on the right.

   Signatures provide an easily understood, easily implemented means of
polymorphism outside the often claustrophobic mechanism of inheritance and,
as such, deserve to be seriously considered for inclusion in the language
standard.


-- Timothy S. Murphy: A serious user and admirer of C++.
   tmurphy@panix.com