From: mailbox@dmitry-kazakov.de   
      
   On Sat, 03 Feb 2007 01:08:39 +0100, Seweryn Habdank-Wojewódzki wrote:   
      
   > Dmitry A. Kazakov wrote:   
   >   
   >>> If you call Bar(T X0), what was called default ctor or copy-ctor?   
   >>   
   >> Bar in my question was a function   
   >   
   > For the function there is automatic type identification.   
   > so definition is:   
   >   
   > template < typename T >   
   > void Bar ( T x ) {   
   > // do some things   
   > }   
   >   
   > and you can call function:   
   >   
   > Bar ( 1.0 );   
   >   
   > or   
   >   
   > double x;   
   > Bar ( x );   
   >   
   > The exception is when you are using types not explicit so:   
   >   
   > template < typename T >   
   > T Bar ( double x )   
   >   
   > then you have to use:   
   >   
   > Bar(x), because compiler do not know what type you want to have in   
   > output of the function when you type Bar(x).   
   >   
   > The tricky solution of that is:   
   >   
   > template < typename T >   
   > T Bar ( double x, T init_value);   
   >   
   > and usage:   
   >   
   > int i = 0;   
   > i = Bar (x, i) ;   
   >   
   > or just pass result as an reference   
   >   
   > template < typename T >   
   > void Bar ( double x, T & result_value);   
   >   
   > int i;   
   > Bar (x, i);   
      
   And what was the problem? To make Bar working for numeric types? You don't   
   need generics for that:   
      
   procedure Bar (X : Numeric'Class); -- Done   
      
   >>>>>> No you cannot, templates don't allow that. Formally you could have:   
   >>>>>>   
   >>>>>> * : T x T -> T   
   >>>>>>   
   >>>>>> But what is needed is   
   >>>>>>   
   >>>>>> * : T1 x T1 -> T2   
   >>>   
   >>> I do not understand the problem.   
   >> [...]   
   >>   
   >> The problem is that the result type is a function of the types of the   
   >> arguments. Overloading cannot solve this. Templates cannot anything beyond   
   >> overloading.   
   >   
   > I do not understand. Do you want to force the compiler to know if you   
   > multiplying   
   >   
   > type_A * type_B then it has to have magic mirror and compiler will know that   
   > the result is type_C?   
      
   Yes, this is how it works. Because type_C is replaced by a class of types.   
   So the signature of * is:   
      
   * : T'Class x T'Class -> T'Class   
      
   where T'Class = {T, T1, T2, T3, ...}   
      
   This is a sufficiently more powerful type system than generics.   
      
   >> In C++ the formal parameters of templates lack contracts and violate both   
   >> positions. The position 1 is violated because the template formal   
   >> parameter specification does not limit the allowed classes in any way.   
   >   
   > This is feature not a problem, this what you write here is present in Java,   
      
   Yes, generics can be made contracted. In Java and Ada the language of   
   generics is typed. In C++ it is weakly/untyped. There is no language I knew   
   where generics would have ADTs, though that should be doable. But all that   
   does not solve the fundamental weakness of generics, as they are a meta   
   language. Please observe, it is not C++ vs. Ada, it is generic vs. not.   
      
   >> The   
   >> position 2 is violated because there exist classes for which a template   
   >> instantiation with these classes as actual parameters would fail. For   
   >> exactly this reason separate checks of template bodies are impossible.   
   >> Templates cannot be compiled (they are parsed as all macros), their bodies   
   >> cannot be shared.   
   >   
   > Show me the example why it is bad.   
      
   In short it prevents quality software design. The contracts are used in   
   large/complex software projects for independent developing and   
   verification. For the latter consider code review. Is template a code? Can   
   you compile it? Can you say if it contains errors before instantiating it?   
   Can you warranty that the template does X and does not Y?   
      
   > I will rather show why this what you say   
   > bad is good - just consider type like int this is not a class,   
      
   (For each given type T there exists a corresponding class of. This class of   
   T is the set of all types derived from T, including T itself.)   
      
   > and you can   
   > parametrize template with it, I do not know what is in Ada,   
      
   It can.   
      
   > but in Java POD   
   > can not be a parameter, so this is good or bad - in my opinion it is bad,   
   > at the very beginning because of performance.   
      
   We have discussed this, it is wrong. Nothing in dynamic polymorphism   
   require *any* performance loss. There exist broken implementations of, like   
   in C++ and Java. That is the problem of those implementations.   
      
   > I understand that in C++ all is bad, because in Ada all what is different is   
   > good. But the difference is that all topics what you rise I can more less   
   > implement in C++, but there are many that you can not do in Ada.   
      
   No. There are advantages and disadvantages of both languages. To discuss   
   them we should clearly understand the language design problems, goals of   
   each particular design and the issues common to all languages.   
      
   [Because I feel your disbelief. (:-)) Here is a short list. One true   
   advantage of C++ is that user-defined constructor parts are enforced on the   
   derived types. In Ada one can override there parts of the constructor. This   
   is clear Ada design fault. However in both languages the construction model   
   is badly broken. Another advantage of C++ is that it has abstract array   
   interfaces, poorly implemented, but still there. A third advantage is that   
   C++ has rudimentary interface inheritance from concrete types represented   
   by user-defined conversions, Ada does not have this. A fourth advantage is   
   multiple implementation inheritance. Should I continue?]   
      
   > Did you try to compile my example of fuzzy sets?   
      
   I don't see how it solves the problem:   
      
   Given:   
      
   1. Set representation described by OP   
   2. The set A = { (1.0, 1.0) }   
      
   Required:   
      
   Compute the set B = ~A, where ~ is defined as forall x ~A(x)=1-A(x).   
      
   You didn't explain how to represent an infinite set by a finite map without   
   changing the representation from a set of singletons to anything else.   
      
   --   
   Regards,   
   Dmitry A. Kazakov   
   http://www.dmitry-kazakov.de   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|