Topic: syntax suggestion for concepts


Author: "W Karas" <wkaras@yahoo.com>
Date: Wed, 21 Mar 2007 11:57:18 CST
Raw View
[Note: either groups.google.com or the comp.std.c++ moderation SW
appears to be eating messages, so this may wind up being a
repetitive posting.]

On Mar 20, 4:30 pm, d...@boost-consulting.com (David Abrahams) wrote:
> on Tue Mar 20 2007, "W Karas" <wkaras-AT-yahoo.com> wrote:
.
> > If you look at an algorithm like find, yes, it does have two
> > type parameters.  But the only possible multiple dispatch case
> > is the call to operator != (RT a, T b) where RT is the return
> > type of the iterator's 'operator *' and T is the type of the
> > sought value.  I would guess that, in the great majority
> > of situations where 'find' is used, T is the same as RT, or
> > an instance of T implicitly converts to RT, so there is no
> > true multiple dispatch.
>
> I don't really see what that proves.  T is not always the same as RT.
> And then there's find_if, transform, accumulate, lower_bound, and a
> whole slew of other algorithms with more complicated type
> relationships.

I can only say this doesn't seem to jive with the usage of
templates that I personally have seen.  Not much point in
arguing about guesstimates of statistical frequency of
patterns in the "general population" of code.

> > Maybe multiple dispatch does occur frequently when using
> > templates. But if GP is just OO with multiple dispatch and earlier
> > bindings,
>
> It isn't.  Did somebody claim it was?

I did.  I tend to use the term "OO polymorphism" to cover
the idea of writing code that is only bound to a class
interface subset, regardless of whether the interface
subset is explicit or implicit.  I realize that's
different for how this term in normally used in
the C++ realm, but then, what term should be used
for the more general idea?

>
> > that doesn't justify viewing GP and OO as being in some
> > huge all-important cage-match dichotomy in my opinion.
>
> Whoosh! That went right over my head; I have no clue what you're
> trying to say here.

This subthread was originally about whether the syntax
for Concepts should be very different from the
class declaration syntax, in order to emphasize
the difference between a Concept and a base class,
and the general difference between GP and OO.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "W Karas" <wkaras@yahoo.com>
Date: Tue, 20 Mar 2007 13:50:39 CST
Raw View
On Mar 19, 2:50 pm, d...@boost-consulting.com (David Abrahams) wrote:
> on Thu Mar 08 2007, "W Karas" <wkaras-AT-yahoo.com> wrote:
>
> > In SmallTalk, I can implement naturally any template with
> > one type parameter (that doesn't derive new types from the
> > type paramter, or where the derivation is only done to
> > take advantage of the empty member optimization).  That's
> > a big limitation, but it seems to me that the most commonly
> > used templates in the STL have only one type parameter.
> > The exception is map<>, but that is a case where no multiple
> > dispatch is needed even though there are two type parameters.
>
> You're focusing on class templates, which in STL are a bit of a
> distraction from its essential Generic Programming stuff: the
> algorithms (and concepts).  When looking at the STL through a Generic
> Programming lens, containers are best viewed as examples of some of
> the concepts... and not very strong concepts at that! (see item 2 ofhttp://tinyurl.com/34o9ks:http://tinyurl.com/39jpfh)
>
> If you look at the algorithms you'll find that nearly all of them have
> more than one template parameter.

You have a point, but I don't think that fully refutes my argument.

If you look at an algorithm like find, yes, it does have two
type parameters.  But the only possible multiple dispatch case
is the call to operator != (RT a, T b) where RT is the return
type of the iterator's 'operator *' and T is the type of the
sought value.  I would guess that, in the great majority
of situations where 'find' is used, T is the same as RT, or
an instance of T implicitly converts to RT, so there is no
true multiple dispatch.

Maybe multiple dispatch does occur frequently when using
templates. But if GP is just OO with
multiple dispatch and earlier bindings, that doesn't justify
viewing GP and OO as being in some huge all-important
cage-match dichotomy in my opinion.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: dave@boost-consulting.com (David Abrahams)
Date: Tue, 20 Mar 2007 20:30:00 GMT
Raw View
on Tue Mar 20 2007, "W Karas" <wkaras-AT-yahoo.com> wrote:

> On Mar 19, 2:50 pm, d...@boost-consulting.com (David Abrahams) wrote:
>> on Thu Mar 08 2007, "W Karas" <wkaras-AT-yahoo.com> wrote:
>>
>> > it seems to me that the most commonly used templates in the STL
>> > have only one type parameter.  The exception is map<>, but that
>> > is a case where no multiple dispatch is needed even though there
>> > are two type parameters.
>>
>> You're focusing on class templates, which in STL are a bit of a
>> distraction from its essential Generic Programming stuff: the
>> algorithms (and concepts).  When looking at the STL through a Generic
>> Programming lens, containers are best viewed as examples of some of
>> the concepts... and not very strong concepts at that! (see item 2 ofhttp://tinyurl.com/34o9ks:http://tinyurl.com/39jpfh)
>>
>> If you look at the algorithms you'll find that nearly all of them have
>> more than one template parameter.
>
> You have a point, but I don't think that fully refutes my argument.
>
> If you look at an algorithm like find, yes, it does have two
> type parameters.  But the only possible multiple dispatch case
> is the call to operator != (RT a, T b) where RT is the return
> type of the iterator's 'operator *' and T is the type of the
> sought value.  I would guess that, in the great majority
> of situations where 'find' is used, T is the same as RT, or
> an instance of T implicitly converts to RT, so there is no
> true multiple dispatch.

I don't really see what that proves.  T is not always the same as RT.
And then there's find_if, transform, accumulate, lower_bound, and a
whole slew of other algorithms with more complicated type
relationships.

> Maybe multiple dispatch does occur frequently when using
> templates. But if GP is just OO with multiple dispatch and earlier
> bindings,

It isn't.  Did somebody claim it was?

> that doesn't justify viewing GP and OO as being in some
> huge all-important cage-match dichotomy in my opinion.

Whoosh! That went right over my head; I have no clue what you're
trying to say here.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Douglas Gregor" <doug.gregor@gmail.com>
Date: Wed, 21 Mar 2007 00:36:37 CST
Raw View
On Mar 6, 1:41 pm, grizl...@yandex.ru ("Grizlyk") wrote:
> Where can one easy learn concept syntax and semantics?

The "Learning Concepts" section at the bottom of the following page
has some pointers:

  http://www.generic-programming.org/languages/conceptcpp/

  Cheers,
  Doug

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: dave@boost-consulting.com (David Abrahams)
Date: Mon, 19 Mar 2007 18:50:48 GMT
Raw View
on Thu Mar 08 2007, "W Karas" <wkaras-AT-yahoo.com> wrote:

> In SmallTalk, I can implement naturally any template with
> one type parameter (that doesn't derive new types from the
> type paramter, or where the derivation is only done to
> take advantage of the empty member optimization).  That's
> a big limitation, but it seems to me that the most commonly
> used templates in the STL have only one type parameter.
> The exception is map<>, but that is a case where no multiple
> dispatch is needed even though there are two type parameters.

You're focusing on class templates, which in STL are a bit of a
distraction from its essential Generic Programming stuff: the
algorithms (and concepts).  When looking at the STL through a Generic
Programming lens, containers are best viewed as examples of some of
the concepts... and not very strong concepts at that! (see item 2 of
http://tinyurl.com/34o9ks : http://tinyurl.com/39jpfh)

If you look at the algorithms you'll find that nearly all of them have
more than one template parameter.


--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Douglas Gregor" <doug.gregor@gmail.com>
Date: Wed, 7 Mar 2007 08:53:16 CST
Raw View
On Mar 6, 11:10 pm, "jam" <farid.mehr...@gmail.com> wrote:
> Do you mean that refinement syntax is not orignated from that of
> inheritance and will not confuse every one?

The refinement syntax is identical to the inheritance syntax. I
haven't seen any indication that this choice causes confusion. Rather,
once the audience has grasped the notion of concepts, it becomes
obvious what "inheritance" of concepts means, so I find the syntactic
equivalence to help.

With every feature, it's a judgement call whether to reuse syntax from
a similar feature or invent something new. We've tested most of these
decisions on various audiences, and we're pretty sure we have the
balance just about right.

> > -  It again mixes object-oriented and generic programming ideas in a
> >way that will lead to confusion. I guarantee that, after showing an
> >example like the above to an audience, I will get two questions: (1)
> >why can't I just use ':' to inherit from C? and (2) can I declare a
> >variable of type C*? Neither question would arise without the
> >assumption that concepts are just another take on object-oriented
> >programming (they aren't), and we need to be very careful not to give
> >the impression that they are.
>
> enerything has a price .For innovation yuo have to be braver than
> this. Is the fear that programers might misunderstand a reason for us
> not to do anything?.

No, the fear that programmers might misunderstand is a reason to
select one of several alternatives. In the case of the above, there is
already a way to say that a particular type meets the requirements of
a specific concept: it's called a concept map. It's more powerful and
more general than the alternative proposed above, and it also avoids
misunderstanding by not mimicking a different feature with different
limitations.

> but there exists one reason for not using concept keyword in that
> manor (if I am not mistaken) :concepts allow use of a type when
> afeature is available and accesible and ban otherwise but what we need
> here is that we want to remind ourselves not to forget to provide a
> specific interface for a class currently declared but not defined.I
> suggest the 'interface'  keyword  syntax similar to that of 'concept'
> for  this porpuse that unlike JAVA will not necessarily mean a runtime
> polymorphism.I would like to wrote:
>
> interface CC<typename T>{
> public:
>  T(T&);
> private:
>  void go();
>  virtual void gogo();
>
> };
>
> CC struct my_type{
> /*definition of  following functons is a must now and copy-ctor must
> not be banned(private or protected).
>  private: void go();
> private: virtual void gogo();
> */
>
> };

Concepts do exactly what you want, but with a slightly different
syntax:

  concept CC<typename T>{
   T::T(T&);
   void T::go();
   virtual void T::gogo();
  }

  struct my_type {
    my_type(my_type&);
    void go();
  private:
    virtual void gogo();
  };

  concept_map CC<my_type> {
  } // error: my_type::gogo is private!

Concept maps do three things:
  (1) Specify that a set of types (in this case, just my_type) meet
the requirements of a concept (here, CC).
  (2) Show how those types meet the requirements of a concept
(although we didn't do so here)
  (3) Ask the compiler to verify that all of the requirements of the
concept are, in fact, met (my_type doesn't meet the requirement for
"gogo", so the concept map is ill-formed).

  Cheers,
  Doug

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Douglas Gregor" <doug.gregor@gmail.com>
Date: Wed, 7 Mar 2007 11:23:04 CST
Raw View
On Mar 6, 11:09 pm, "W Karas" <wka...@yahoo.com> wrote:
> I feel what you are saying here can be summarized as:  When using
> templates, names are bound to specific types at compile time.  When
> using OO, names may not be bound to specific types until runtime.
> Unsurprisingly, any binding errors will occur when the binding occurs.

Yes, although I'd rephrase the template part slightly. Names are bound
to specific types or type *parameters* at compile time. Looking back
at a Shape concept...

  concept Shape<typename T> {
    bool isEqual(T, T);
  }

We don't need to know what T is to know that isEqual takes two T's of
exactly the same type, whereas with a Shape interface (again, Java)...

  interface Shape {
    boolean isEqual(Shape);
  }

We can't express that isEqual only accepts another shape of the same
exact type, be it a Triangle or a Square, because we don't have a
stand-in for the real type of 'this'. Note that some object-oriented
languages do have a "self" type that stands in for the real type of
"this", to overcome this particular instance of the problem.

> Late binding is generally bad for performance and (I and probably you
> and others would agree) for understandability.  But it's more
> flexible.
> Generic algorithms meant for heterogeneous types work better with late
> bindings, a benefit which is the mirror image of the "problem" you
> show above.

The reason I called out type parameters above is because late-binding
does not have to be a difference. One can compile type-parameterized
functions separately, using late binding to execute them. In this
case, even though we might not know what a type parameter 'T' will be
at run time, we still know what functions we can apply to 'T', e.g.,
we can call isEqual with two T's. For example, generic functions in
Haskell using "type classes"---which closely resemble concepts---are
separately compiled, as is Jeremy Siek's language 'G'. G's design was
the basis of concepts in C++, and provides almost the same feature
set.

> Another way to address multiple dispatch in a way more similar to
> C++ OO is to think of the function as a "member" of an implied
> class that is the tuple of the types of the function parameters.

Yes. This is typically called "dictionary passing", and is the
implementation technique used by both Haskell and G.
In a sense, this is the same way that C++ concepts are implemented,
but the dictionary is passed at compile time, not run time.

> Is ultimately the key difference between GP and OO the fact
> that member functions are central to OO but not to GP? To
> me, member functions seem more central to encapsulation than
> polymorphism.

One of the typical Generic Programming complaints about OO is that it
ties together the questions of "What can this type do?" and "How is
this type implemented?" into the same language mechanism: inheritance.
The first question is the more important question for someone writing
a polymorphic algorithm, because we don't care what the type is... we
just want to be sure that it will work with our algorithm. So, GP only
concerns itself with this first question: A concept describes what a
certain type needs to be able to do to work inside a polymorphic
algorithm. A concept map tells *how* a particular type meets the
requirements of a concept, allowing us to smooth over syntactic
differences and tie together independely-developed pieces.

> It seems easy to conceive of a programming
> language with runtime polymorphism but no membership, where
> vptrs are passed as hidden function paramaters rather than
> being hidden object data members.  With this approach,
> multiple dispatch becomes easy -- there is a vptr hidden
> parameter for each "polymorphic type tuple" rather than
> just for each polymorphic type.

Exactly!

  Cheers,
  Doug

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Andrei Polushin" <polushin@gmail.com>
Date: Wed, 7 Mar 2007 14:59:46 CST
Raw View
Douglas Gregor wrote:
> On Mar 6, 11:09 pm, "W Karas" <wka...@yahoo.com> wrote:
>> Another way to address multiple dispatch in a way more similar to
>> C++ OO is to think of the function as a "member" of an implied
>> class that is the tuple of the types of the function parameters.
>
> Yes. This is typically called "dictionary passing", and is the
> implementation technique used by both Haskell and G.
> In a sense, this is the same way that C++ concepts are implemented,
> but the dictionary is passed at compile time, not run time.

Interestingly, would we call it "generic programming" or whatever, it
is still implemented with an OO programming, as OO is the most generic
programming style :)

>
>> Is ultimately the key difference between GP and OO the fact
>> that member functions are central to OO but not to GP? To
>> me, member functions seem more central to encapsulation than
>> polymorphism.
>
> One of the typical Generic Programming complaints about OO is that it
> ties together the questions of "What can this type do?" and "How is
> this type implemented?" into the same language mechanism: inheritance.

Yes. And we have a notion of "interface" that doesn't deal with
implementation, and a "mixin class" that is implementation-only.

> The first question is the more important question for someone writing
> a polymorphic algorithm, because we don't care what the type is...

In OO programming, we also able to forget about the exact type, we can
just work with its "interface".

> we
> just want to be sure that it will work with our algorithm. So, GP only
> concerns itself with this first question: A concept describes what a
> certain type needs to be able to do to work inside a polymorphic
> algorithm. A concept map tells *how* a particular type meets the
> requirements of a concept, allowing us to smooth over syntactic
> differences and tie together independely-developed pieces.
>
>> It seems easy to conceive of a programming
>> language with runtime polymorphism but no membership, where
>> vptrs are passed as hidden function paramaters rather than
>> being hidden object data members.  With this approach,
>> multiple dispatch becomes easy -- there is a vptr hidden
>> parameter for each "polymorphic type tuple" rather than
>> just for each polymorphic type.
>
> Exactly!

I would have to recall the same solution mentioned in D&E 13.8
(Stroustrup says the idea was suggested by Doug Lea in 1991):

  bool intersect(virtual const Shape& , virtual const Shape& );

Was it the syntax for what you call a "parametric polymorphism"?
If yes, then I would say that multimethods problem are unrelated
to concepts proposal. Well, it might be convenient to introduce both
"concepts" and "parametric polymorphism" at once as a single unit,
but they are unrelated to each other and can be introduced separately.

In fact, if we would have the above syntax in 1991, we can now write:

  class Shape {
  public:
    virtual bool isEqual(virtual const Shape& ) const = 0;
  };

That could mean that "polymorphic tuple" passed as hidden parameter
or whatever: that was the problem that needs to be solved when we
discuss multimethods. That is a separate problem.

To this very time, there is no noticeable differences between the
OO interfaces and GP concepts, how you describe them.


--
Andrei Polushin

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Douglas Gregor" <doug.gregor@gmail.com>
Date: Thu, 8 Mar 2007 12:40:16 CST
Raw View
On Mar 7, 3:59 pm, "Andrei Polushin" <polus...@gmail.com> wrote:
> Douglas Gregor wrote:
> > Yes. This is typically called "dictionary passing", and is the
> > implementation technique used by both Haskell and G.
> > In a sense, this is the same way that C++ concepts are implemented,
> > but the dictionary is passed at compile time, not run time.
>
> Interestingly, would we call it "generic programming" or whatever, it
> is still implemented with an OO programming, as OO is the most generic
> programming style :)

By this logic, spaghetti code is the most generic programming style :)

What's OO turn implemented with? Procedural Programming.
What's Procedural Programming implemented with? Unstructured
Programming.
What's Unstructured Programming? Spaghetti!

On a more serious note, one can implement run-time dispatched GP code
using OO techniques, but the objects themselves essentially become
meaningless... th7re used only for the dynamic dispatching present in
their vtables, essentially just a bucket of function pointers. It's
not a very enlightened use of OO, but if OO is all you have to build
on...

> > One of the typical Generic Programming complaints about OO is that it
> > ties together the questions of "What can this type do?" and "How is
> > this type implemented?" into the same language mechanism: inheritance.
>
> Yes. And we have a notion of "interface" that doesn't deal with
> implementation, and a "mixin class" that is implementation-only.

Yes, mixins were mentioned in the blurb I linked to originally

  http://www.generic-programming.org/faq/?category=paradigms#object-oriented-programming

because they do address part of the problem.

Mixins still tie the questions "What can this type do?" and "How is
this type implemented?" together. Yes, they can be mixed in after the
type is created (and that's good!), but they still answer both
questions with the same answer, inheritance. Here's an example where
this begins to get in the way:

  interface Shape {
    void draw();
  }

  interface Gunslinger {
    void draw();
  }

Now, I want to have a class YosemiteSam (a gun-toting cartoontoon
character):

  class YosemiteSam { ... }

YosemiteSam is a shape, so we want to mix-in a subclass that makes
YosemiteSam implement Shape:

  mixin class YosemiteSamAsShape implements Shape {
    void draw() { /* see http://en.wikipedia.org/wiki/Yosemite_Sam
*/ }
  }
  // mix that into YosemiteSam, of course

Then we want YosemiteSam to be a Gunslinger, so he can participate in
the WildWildWest:

  mixin class YosemiteSamAsGunslinger implements Gunslinger {
    void draw() { /* pull out both of his pistols at once */ }
  }
  // mix that into YosemiteSam, of course

Now we have a YosemiteSam that inherits the mixins YosemiteSameAsShape
and YosemiteSamAsGunslinger, and therefore implements both the Shape
and Gunslinger interfaces. Do those interfaces each get the right
"draw" methods? If so, how are the mixins arranged to ensure that this
happens? If not, we've run into a problem with expressing everything
in terms of inheritance, because different mixins for completely
different purposes have now collided in the same class.

With Generic Programming, there is no such collision because the
various different ways of viewing YosemiteSam---as a Shape or as a
Gunslinger---are kept completely separate, in different concept maps:

  concept_mappe<YosemiteSam> { void draw() { ... } }
  concept_map Gunslinger<YosemiteSam> { void draw() { ... } }

Those draw() functions (not "methods") live in the concept map, not in
YosemiteSam. So the implementation of YosemiteSam is completely opaque
to all but the author. Generic/polymorphic functions only see the view
of YosemiteSam that they've asked for, e.g., as a Shape or as a
Gunslinger.

> > The first question is the more important question for someone writing
> > a polymorphic algorithm, because we don't care what the type is...
>
> In OO programming, we also able to forget about the exact type, we can
> just work with its "interface".

Right, but now you're working with two objects known only by their
common interface, say, Shape, and you have no idea whether those two
objects have the same actual type or are completely different, because
you've thrown away valuable type information. This is, again, the
binary method problem. Well-known, well-studied, and the typical
answers are either multi-methods or a "self" type.

> I would have to recall the same solution mentioned in D&E 13.8
> (Stroustrup says the idea was suggested by Doug Lea in 1991):
>
>   bool intersect(virtual const Shape& , virtual const Shape& );

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "W Karas" <wkaras@yahoo.com>
Date: Thu, 8 Mar 2007 16:23:39 CST
Raw View
On Mar 8, 1:40 pm, "Douglas Gregor" <doug.gre...@gmail.com> wrote:
.
> On a more serious note, one can implement run-time dispatched GP code
> using OO techniques, but the objects themselves essentially become
> meaningless... th7re used only for the dynamic dispatching present in
> their vtables, essentially just a bucket of function pointers. It's
> not a very enlightened use of OO, but if OO is all you have to build
> on...
.

In languages like SmallTalk, which have names that can be bound
to any member function before being bound to a type, you can
write generic algorithms that only deal with one unbound type.
Having just one unbound type insures that multiple dispatch
is not required.

In SmallTalk, I can implement naturally any template with
one type parameter (that doesn't derive new types from the
type paramter, or where the derivation is only done to
take advantage of the empty member optimization).  That's
a big limitation, but it seems to me that the most commonly
used templates in the STL have only one type parameter.
The exception is map<>, but that is a case where no multiple
dispatch is needed even though there are two type parameters.
The SmallTalk version of map<> would have the advantage of
being a heterogenous rather than homogeneous container.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "terminator" <farid.mehrabi@gmail.com>
Date: Fri, 9 Mar 2007 14:22:03 CST
Raw View
> Concepts do exactly what you want, but with a slightly different
> syntax:
>
>   concept CC<typename T>{
>    T::T(T&);
>    void T::go();
>    virtual void T::gogo();
>   }
>
>   struct my_type {
>     my_type(my_type&);
>     void go();
>   private:
>     virtual void gogo();
>   };
>
>   concept_map CC<my_type> {
>   } // error: my_type::gogo is private!
>
> Concept maps do three things:
>   (1) Specify that a set of types (in this case, just my_type) meet
> the requirements of a concept (here, CC).
>   (2) Show how those types meet the requirements of a concept
> (although we didn't do so here)
>   (3) Ask the compiler to verify that all of the requirements of the
> concept are, in fact, met (my_type doesn't meet the requirement for
> "gogo", so the concept map is ill-formed).
>

That is not what I meant.I wrote that we need some construct to
specify part of a class`s interface in an exact manor(including access
specifiers) before the type is defined.I guess that cocepts generate
problems with access rules for example dose this compile?:

concept C<typename T>{
 void T::go();
};

template <C T>struct A{};

class B{
protected:
  void go();
  void use(){
     A<B> a;//right? void go() is accessible here.
  };
};




---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "W Karas" <wkaras@yahoo.com>
Date: Mon, 5 Mar 2007 08:12:57 CST
Raw View
On Feb 25, 9:57 am, "W Karas" <wka...@yahoo.com> wrote:
> Would the fear factor for concepts be slightly reduced if,
> instead of:
>
> concept C<typename T>
>   {
>     typename T::S;
>     int T::mem();
>     int nonmem();
>   };
>
> a new usage of :: was added to make concepts/
> concept maps more consistent with class interfaces:
>
> concept C<typename T>
>   {
>     typename S
>     int mem();
>     int ::nonmem();
>   };
>
> A perhaps bad aspect of this is that multi-type
> concepts could ONLY specify names prefixed with ::,
> that is, this under the existing proposal:
>
> concept D<typename U, typename V>
>   {
>     int U::umem();
>     int uandv(U u, V v);
>   };
>
> would have to be changed to something like:
>
> concept DD<typename U>
>   {
>     int umem();
>   };
> concept D<typename U, typename V> : DD<U>
>   {
>     int ::uandv();
>   };
>
> (Or, the one reserve word "concept" could be
> replaced with two:  "algebra" for single-type
> concepts, and "geometry" for multi-type
> concepts.  This would avoid the ubiquitous
> :: in geometries.)
>
> For orthogonality, this use of :: could be allowed in
> class interfaces as well.   Concepts and class interfaces
> are both ways of describing type usage, so it seems
> more intuitive to me that they be as similar as
> possible.

Another thought, not necessarily depedent on the
above, would be to allow class interfaces to
be defined using existing concepts.  If C is
a concept, one possible sytax could be:

class X using C
  {
    // ... additional stuff not declared
    // by C ...
  };

But since this does indirectly introduce a
way of defining things in namespace-scope
as a part of a class interface declaration,
this seems another reason to allow the
:: prefix on defined names in a class
interface, for direct definition in
namespace scope within the class
interface.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Douglas Gregor" <doug.gregor@gmail.com>
Date: Mon, 5 Mar 2007 12:02:48 CST
Raw View
On Mar 5, 9:12 am, "W Karas" <wka...@yahoo.com> wrote:
> > Would the fear factor for concepts be slightly reduced if,
> > instead of:
[snip example of existing syntax]
> > a new usage of :: was added to make concepts/
> > concept maps more consistent with class interfaces:
>
> > concept C<typename T>
> >   {
> >     typename S
> >     int mem();
> >     int ::nonmem();
> >   };
[snip]

I never saw the original message, so I'll reply to this part first.

Making concept syntax more consistent with class interfaces would not
help programmers understand concepts any better. It may reduce initial
anxiety, because concepts would look like object-oriented interfaces,
but the resemblance would only be skin-deep. Concepts support a
different programming paradigm---Generic Programming---and much of the
confusion I've seen about concepts comes from attempts to think of
them in object-oriented terms. New ideas and constructs should have
new syntax, to emphasize that they are different from existing ideas/
constructs. Sometimes syntactic similarity can be a good thing, but
not when it leads to many incorrect assumptions.

> > (Or, the one reserve word "concept" could be
> > replaced with two:  "algebra" for single-type
> > concepts, and "geometry" for multi-type
> > concepts.  This would avoid the ubiquitous
> > :: in geometries.)

My impression is that many programmers would react badly to "algebra"
and "geometry" as keywords for specific entities. Concepts are,
theoretically speaking, "multi-sorted algebras," but we've been banned
from saying that phrase in public :)

> Another thought, not necessarily depedent on the
> above, would be to allow class interfaces to
> be defined using existing concepts.  If C is
> a concept, one possible sytax could be:
>
> class X using C
>   {
>     // ... additional stuff not declared
>     // by C ...
>   };

We've thought about something like this, but there are two reasons we
did not include it:

  -  It again mixes object-oriented and generic programming ideas in a
way that will lead to confusion. I guarantee that, after showing an
example like the above to an audience, I will get two questions: (1)
why can't I just use ':' to inherit from C? and (2) can I declare a
variable of type C*? Neither question would arise without the
assumption that concepts are just another take on object-oriented
programming (they aren't), and we need to be very careful not to give
the impression that they are.

  - If you want X to meet the requirements of C, write a concept_map
C<X>. Then, you cleanly separate what X "is" (i.e., it's data members,
member functions, superclasses, etc.) from how X maps onto a C.

  Cheers,
  Doug

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "W Karas" <wkaras@yahoo.com>
Date: Mon, 5 Mar 2007 18:55:22 CST
Raw View
On Mar 5, 1:02 pm, "Douglas Gregor" <doug.gre...@gmail.com> wrote:
> On Mar 5, 9:12 am, "W Karas" <wka...@yahoo.com> wrote:
.
> Making concept syntax more consistent with class interfaces would not
> help programmers understand concepts any better. It may reduce initial
> anxiety, because concepts would look like object-oriented interfaces,
> but the resemblance would only be skin-deep. Concepts support a
> different programming paradigm---Generic Programming---and much of the
> confusion I've seen about concepts comes from attempts to think of
> them in object-oriented terms. New ideas and constructs should have
> new syntax, to emphasize that they are different from existing ideas/
> constructs. Sometimes syntactic similarity can be a good thing, but
> not when it leads to many incorrect assumptions.
.

You have made this argument repeatedly, but without a reference or
explaination as to why GP and OO are so distinct that it's
necessary to add otherwise unnecessary complexity to the syntax of
C++ to play up the difference.

SmallTalk, unlike C++, does not have specific features to support
GP.  But I have not seen or heard of a C++ template which cannot
be written in SmallTalk in an equally general way.  Do you know
of such an example, or why this is not relevant?

If the premise that OO and GP are "merged" in SmallTalk cannot
be refuted, that would indicate the choice between
class hierarchies with virtual functions and templates in
C++ has more to do with practical issues like "do I want
to reuse object as well as source?", "is it reasonable
to add a new base class to classes I want to use this
code with?", "does the code need to create non-dynamic
instances of objects of non-specific type?".

Of course, SmallTalk does not need to deal with the
issue of non-dynamic objects (there aren't any).  But
that seems pretty lame as a significant reason
we need an entirely distinct programming "paradigm"
in C++.

(If I need to understand exactly what the word
"paradigm" means in order to understand the
distinction between GP and OO, you all can give
up on me right now.)

If the distinction between OO and GP is only
meaningful in a certain type of programming
language, that would seem a reason to play
down rather than up the difference.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Douglas Gregor" <doug.gregor@gmail.com>
Date: Tue, 6 Mar 2007 08:38:23 CST
Raw View
On Mar 5, 7:55 pm, "W Karas" <wka...@yahoo.com> wrote:
> On Mar 5, 1:02 pm, "Douglas Gregor" <doug.gre...@gmail.com> wrote:> On Mar 5, 9:12 am, "W Karas" <wka...@yahoo.com> wrote:
> .
> > Making concept syntax more consistent with class interfaces would not
> > help programmers understand concepts any better. It may reduce initial
> > anxiety, because concepts would look like object-oriented interfaces,
> > but the resemblance would only be skin-deep. Concepts support a
> > different programming paradigm---Generic Programming---and much of the
> > confusion I've seen about concepts comes from attempts to think of
> > them in object-oriented terms. New ideas and constructs should have
> > new syntax, to emphasize that they are different from existing ideas/
> > constructs. Sometimes syntactic similarity can be a good thing, but
> > not when it leads to many incorrect assumptions.
>
> .
>
> You have made this argument repeatedly, but without a reference or
> explaination as to why GP and OO are so distinct that it's
> necessary to add otherwise unnecessary complexity to the syntax of
> C++ to play up the difference.

There is a short write-up of the differences (at a feature level)
here:

  http://www.generic-programming.org/faq/?category=paradigms#object-oriented-programming

> SmallTalk, unlike C++, does not have specific features to support
> GP.  But I have not seen or heard of a C++ template which cannot
> be written in SmallTalk in an equally general way.  Do you know
> of such an example, or why this is not relevant?

Well, one obvious answer is any example of the Binary Method Problem.
Say you have some Shape interface and you want to be able to compare
Shapes with an isEqual method... I'll write it in Java, because I'm
less likely to mangle the syntax:

  interface Shape {
    boolean isEqual(Shape other);
  }

Now, a Triangle is a Shape:

  class Triangle implements Shape {
      private int base;
      private int height;

      public boolean isEqual(Triangle other)
      {
          return base == other.base && height == other.height;
      }
  }

In Java, this doesn't work and the compiler will complain because
Triangle's isEqual takes a Triangle whereas Shape's isEqual accepts a
shape. To get around Java's static type system, we use explicit casts
and write Triangle's isEqual like this:

    public boolean isEqual(Shape other_shape)
    {
        Triangle other = (Triangle)other_shape;
        return base == other.base && height == other.height;
    }

Similarly, we can define a Circle that also implements Shape and has
its own isEqual method. We can then trigger a run-time error by trying
to compare a Circle to a Triangle:

  Shape a = new Triangle(...);
  Shape b = new Circle(...);
  a.isEqual(b); // exception: run-time cast failed

Here's one of the earlier discussions of the binary method problem in
Smalltalk, which focuses on the double-dispatching issue: if you have
different kinds of graphical objects, and different kinds of display
ports, how can you write methods that display each kind of graphical
objects differently on each display port?

  http://portal.acm.org/citation.cfm?id=28732

In the concepts world, Shape would be a concept with an isEqual
function, e.g.,

  concept Shape<typename T> {
    bool isEqual(T, T);
  }

Note that we're using parametric polymorphism to describe concepts,
not subtype polymorphism: that's problem the single, most important
theoretical difference between OO and GP.

To say that Triangle is a Shape, we write an externally-defined
concept map:

  concept map Shape<Triangle> {
    bool isEqual(Triangle a, Triangle b) {
      return a.base == b.base && a.height == b.height;
    }
  }

We would do the same for Circle.


The static type system prevents us from ever getting into trouble with
isEqual: Triangle meets the requirements of Shape, and Circle meets
the requirements of Shape, but that does not imply anything about the
relationship between Triangle and Circle. For example:

  template<typename T>
  where Shape<T>
  bool equal_shapes(T a, T b) {
    return isEqual(a, b);
  }

  Triangle a;
  Circle b;
  equal_shapes(a, b); // compile-time error: T=Triangle in first arg,
T=Circle in second arg.

Parametric polymorphism, as in templates, retains the identity of
types. Subtype polymorphism, as in object-oriented languages, loses
type identity. To write the equivalent of the Java Shape's isEqual
method with parametric polymorphism in a constrained template, we'd
effectively be saying:

  template<typename T, typename U>
  where Shape<T> && Shape<U>
  bool equal_shapes2(T a, U b) {
    return isEqual(a, b);
  }

The real types T and U vary independently, but both are Shapes. When
this is done in a OO world, the type-checking is pushed to run time,
inside the body of isEqual (whose interface says that *any* two shapes
can be compared). In a GP world (and with C++ concepts), the isEqual
call inside equal_shapes2 would fail at compile time: the Shape
concept says that a T can be compared with itself, rather than saying
that it can be compared against any Shape.

If you want to say that any Shape can be compared against any other
Shape (say, in a hasSameArea function), you would use more parametric
polymorphism:

  concept ShapeWithArea<typename T> : Shape<T> {
    double area(T);

    template<typename U> where Shape<U> bool hasSameArea(T, U);
  }

  Cheers,
  Doug

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: grizlyk1@yandex.ru ("Grizlyk")
Date: Tue, 6 Mar 2007 17:41:34 GMT
Raw View
Douglas Gregor wrote:
>
> Making concept syntax more consistent with class interfaces would not
> help programmers understand concepts any better. It may reduce initial
> anxiety, because concepts would look like object-oriented interfaces,
> but the resemblance would only be skin-deep. Concepts support a
> different programming paradigm---Generic Programming---and much of the
> confusion I've seen about concepts comes from attempts to think of
> them in object-oriented terms. New ideas and constructs should have
> new syntax, to emphasize that they are different from existing ideas/
> constructs. Sometimes syntactic similarity can be a good thing, but
> not when it leads to many incorrect assumptions.

Where can one easy learn concept syntax and semantics?


--
Maksim A. Polyanin
http://grizlyk1.narod.ru/cpp_new

"In thi world of fairy tales rolls are liked olso"
                               /Gnume/


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Douglas Gregor" <doug.gregor@gmail.com>
Date: Tue, 6 Mar 2007 13:10:20 CST
Raw View
On Mar 6, 12:41 pm, grizl...@yandex.ru ("Grizlyk") wrote:
> Douglas Gregor wrote:
>
> > Making concept syntax more consistent with class interfaces would not
> > help programmers understand concepts any better. It may reduce initial
> > anxiety, because concepts would look like object-oriented interfaces,
> > but the resemblance would only be skin-deep. Concepts support a
> > different programming paradigm---Generic Programming---and much of the
> > confusion I've seen about concepts comes from attempts to think of
> > them in object-oriented terms. New ideas and constructs should have
> > new syntax, to emphasize that they are different from existing ideas/
> > constructs. Sometimes syntactic similarity can be a good thing, but
> > not when it leads to many incorrect assumptions.
>
> Where can one easy learn concept syntax and semantics?

There are a few ways to learn about concepts. The latest concepts
proposal provides an introduction to concepts:

  http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2081.pdf

Or, you can watch a Google Tech Talk I gave a few weeks ago that
provides yet another introduction to concepts:

  http://video.google.com/videoplay?docid=-1790714981047186825

Finally, since there is no substitute for trying out a feature
yourself, you can take what you've learned from one of the above and
try it with ConceptGCC, our prototype implementation:

  http://www.generic-programming.org/software/ConceptGCC/

  Cheers,
  Doug

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "W Karas" <wkaras@yahoo.com>
Date: Tue, 6 Mar 2007 22:09:38 CST
Raw View
On Mar 6, 9:38 am, "Douglas Gregor" <doug.gre...@gmail.com> wrote:
> On Mar 5, 7:55 pm, "W Karas" <wka...@yahoo.com> wrote:
>
>
>
>
>
> > On Mar 5, 1:02 pm, "Douglas Gregor" <doug.gre...@gmail.com> wrote:> On Mar 5, 9:12 am, "W Karas" <wka...@yahoo.com> wrote:
> > .
> > > Making concept syntax more consistent with class interfaces would not
> > > help programmers understand concepts any better. It may reduce initial
> > > anxiety, because concepts would look like object-oriented interfaces,
> > > but the resemblance would only be skin-deep. Concepts support a
> > > different programming paradigm---Generic Programming---and much of the
> > > confusion I've seen about concepts comes from attempts to think of
> > > them in object-oriented terms. New ideas and constructs should have
> > > new syntax, to emphasize that they are different from existing ideas/
> > > constructs. Sometimes syntactic similarity can be a good thing, but
> > > not when it leads to many incorrect assumptions.
>
> > .
>
> > You have made this argument repeatedly, but without a reference or
> > explaination as to why GP and OO are so distinct that it's
> > necessary to add otherwise unnecessary complexity to the syntax of
> > C++ to play up the difference.
>
> There is a short write-up of the differences (at a feature level)
> here:
>
>  http://www.generic-programming.org/faq/?category=paradigms#object-ori...
>
> > SmallTalk, unlike C++, does not have specific features to support
> > GP.  But I have not seen or heard of a C++ template which cannot
> > be written in SmallTalk in an equally general way.  Do you know
> > of such an example, or why this is not relevant?
>
> Well, one obvious answer is any example of the Binary Method Problem.
> Say you have some Shape interface and you want to be able to compare
> Shapes with an isEqual method... I'll write it in Java, because I'm
> less likely to mangle the syntax:
>
>   interface Shape {
>     boolean isEqual(Shape other);
>   }
>
> Now, a Triangle is a Shape:
>
>   class Triangle implements Shape {
>       private int base;
>       private int height;
>
>       public boolean isEqual(Triangle other)
>       {
>           return base == other.base && height == other.height;
>       }
>   }
>
> In Java, this doesn't work and the compiler will complain because
> Triangle's isEqual takes a Triangle whereas Shape's isEqual accepts a
> shape. To get around Java's static type system, we use explicit casts
> and write Triangle's isEqual like this:
>
>     public boolean isEqual(Shape other_shape)
>     {
>         Triangle other = (Triangle)other_shape;
>         return base == other.base && height == other.height;
>     }
>
> Similarly, we can define a Circle that also implements Shape and has
> its own isEqual method. We can then trigger a run-time error by trying
> to compare a Circle to a Triangle:
>
>   Shape a = new Triangle(...);
>   Shape b = new Circle(...);
>   a.isEqual(b); // exception: run-time cast failed
>
> Here's one of the earlier discussions of the binary method problem in
> Smalltalk, which focuses on the double-dispatching issue: if you have
> different kinds of graphical objects, and different kinds of display
> ports, how can you write methods that display each kind of graphical
> objects differently on each display port?
>
>  http://portal.acm.org/citation.cfm?id=28732
>
> In the concepts world, Shape would be a concept with an isEqual
> function, e.g.,
>
>   concept Shape<typename T> {
>     bool isEqual(T, T);
>   }
>
> Note that we're using parametric polymorphism to describe concepts,
> not subtype polymorphism: that's problem the single, most important
> theoretical difference between OO and GP.
>
> To say that Triangle is a Shape, we write an externally-defined
> concept map:
>
>   concept map Shape<Triangle> {
>     bool isEqual(Triangle a, Triangle b) {
>       return a.base == b.base && a.height == b.height;
>     }
>   }
>
> We would do the same for Circle.
>
> The static type system prevents us from ever getting into trouble with
> isEqual: Triangle meets the requirements of Shape, and Circle meets
> the requirements of Shape, but that does not imply anything about the
> relationship between Triangle and Circle. For example:
>
>   template<typename T>
>   where Shape<T>
>   bool equal_shapes(T a, T b) {
>     return isEqual(a, b);
>   }
>
>   Triangle a;
>   Circle b;
>   equal_shapes(a, b); // compile-time error: T=Triangle in first arg,
> T=Circle in second arg.
>
> Parametric polymorphism, as in templates, retains the identity of
> types. Subtype polymorphism, as in object-oriented languages, loses
> type identity. To write the equivalent of the Java Shape's isEqual
> method with parametric polymorphism in a constrained template, we'd
> effectively be saying:
>
>   template<typename T, typename U>
>   where Shape<T> && Shape<U>
>   bool equal_shapes2(T a, U b) {
>     return isEqual(a, b);
>   }
>
> The real types T and U vary independently, but both are Shapes. When
> this is done in a OO world, the type-checking is pushed to run time,
> inside the body of isEqual (whose interface says that *any* two shapes
> can be compared). In a GP world (and with C++ concepts), the isEqual
> call inside equal_shapes2 would fail at compile time: the Shape
> concept says that a T can be compared with itself, rather than saying
> that it can be compared against any Shape.
>
> If you want to say that any Shape can be compared against any other
> Shape (say, in a hasSameArea function), you would use more parametric
> polymorphism:
>
>   concept ShapeWithArea<typename T> : Shape<T> {
>     double area(T);
>
>     template<typename U> where Shape<U> bool hasSameArea(T, U);
>   }
>
>   Cheers,
>   Doug

I feel what you are saying here can be summarized as:  When using
templates, names are bound to specific types at compile time.  When
using OO, names may not be bound to specific types until runtime.
Unsurprisingly, any binding errors will occur when the binding occurs.

Late binding is generally bad for performance and (I and probably you
and others would agree) for understandability.  But it's more
flexible.
Generic algorithms meant for heterogeneous types work better with late
bindings, a benefit which is the mirror image of the "problem" you
show above.

Another way to address multiple dispatch in a way more similar to
C++ OO is to think of the function as a "member" of an implied
class that is the tuple of the types of the function parameters.

Is ultimately the key difference between GP and OO the fact
that member functions are central to OO but not to GP?  To
me, member functions seem more central to encapsulation than
polymorphism.  It seems easy to conceive of a programming
language with runtime polymorphism but no membership, where
vptrs are passed as hidden function paramaters rather than
being hidden object data members.  With this approach,
multiple dispatch becomes easy -- there is a vptr hidden
parameter for each "polymorphic type tuple" rather than
just for each polymorphic type.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "jam" <farid.mehrabi@gmail.com>
Date: Tue, 6 Mar 2007 22:10:15 CST
Raw View
On Mar 6, 6:38 pm, "Douglas Gregor" <doug.gre...@gmail.com> wrote:
> On Mar 5, 7:55 pm, "W Karas" <wka...@yahoo.com> wrote:
>
>
>
>
>
> > On Mar 5, 1:02 pm, "Douglas Gregor" <doug.gre...@gmail.com> wrote:> On Mar 5, 9:12 am, "W Karas" <wka...@yahoo.com> wrote:
> > .
> > > Making concept syntax more consistent with class interfaces would not
> > > help programmers understand concepts any better. It may reduce initial
> > > anxiety, because concepts would look like object-oriented interfaces,
> > > but the resemblance would only be skin-deep. Concepts support a
> > > different programming paradigm---Generic Programming---and much of the
> > > confusion I've seen about concepts comes from attempts to think of
> > > them in object-oriented terms. New ideas and constructs should have
> > > new syntax, to emphasize that they are different from existing ideas/
> > > constructs. Sometimes syntactic similarity can be a good thing, but
> > > not when it leads to many incorrect assumptions.
>
> > .
>
> > You have made this argument repeatedly, but without a reference or
> > explaination as to why GP and OO are so distinct that it's
> > necessary to add otherwise unnecessary complexity to the syntax of
> > C++ to play up the difference.
>
> There is a short write-up of the differences (at a feature level)
> here:
>
>  http://www.generic-programming.org/faq/?category=paradigms#object-ori...
>
> > SmallTalk, unlike C++, does not have specific features to support
> > GP.  But I have not seen or heard of a C++ template which cannot
> > be written in SmallTalk in an equally general way.  Do you know
> > of such an example, or why this is not relevant?
>
> Well, one obvious answer is any example of the Binary Method Problem.
> Say you have some Shape interface and you want to be able to compare
> Shapes with an isEqual method... I'll write it in Java, because I'm
> less likely to mangle the syntax:
>
>   interface Shape {
>     boolean isEqual(Shape other);
>   }
>
> Now, a Triangle is a Shape:
>
>   class Triangle implements Shape {
>       private int base;
>       private int height;
>
>       public boolean isEqual(Triangle other)
>       {
>           return base == other.base && height == other.height;
>       }
>   }
>
> In Java, this doesn't work and the compiler will complain because
> Triangle's isEqual takes a Triangle whereas Shape's isEqual accepts a
> shape. To get around Java's static type system, we use explicit casts
> and write Triangle's isEqual like this:
>
>     public boolean isEqual(Shape other_shape)
>     {
>         Triangle other = (Triangle)other_shape;
>         return base == other.base && height == other.height;
>     }
>
> Similarly, we can define a Circle that also implements Shape and has
> its own isEqual method. We can then trigger a run-time error by trying
> to compare a Circle to a Triangle:
>
>   Shape a = new Triangle(...);
>   Shape b = new Circle(...);
>   a.isEqual(b); // exception: run-time cast failed
>
> Here's one of the earlier discussions of the binary method problem in
> Smalltalk, which focuses on the double-dispatching issue: if you have
> different kinds of graphical objects, and different kinds of display
> ports, how can you write methods that display each kind of graphical
> objects differently on each display port?
>
>  http://portal.acm.org/citation.cfm?id=28732
>
> In the concepts world, Shape would be a concept with an isEqual
> function, e.g.,
>
>   concept Shape<typename T> {
>     bool isEqual(T, T);
>   }
>
> Note that we're using parametric polymorphism to describe concepts,
> not subtype polymorphism: that's problem the single, most important
> theoretical difference between OO and GP.
>
> To say that Triangle is a Shape, we write an externally-defined
> concept map:
>
>   concept map Shape<Triangle> {
>     bool isEqual(Triangle a, Triangle b) {
>       return a.base == b.base && a.height == b.height;
>     }
>   }
>
> We would do the same for Circle.
>
> The static type system prevents us from ever getting into trouble with
> isEqual: Triangle meets the requirements of Shape, and Circle meets
> the requirements of Shape, but that does not imply anything about the
> relationship between Triangle and Circle. For example:
>
>   template<typename T>
>   where Shape<T>
>   bool equal_shapes(T a, T b) {
>     return isEqual(a, b);
>   }
>
>   Triangle a;
>   Circle b;
>   equal_shapes(a, b); // compile-time error: T=Triangle in first arg,
> T=Circle in second arg.
>
> Parametric polymorphism, as in templates, retains the identity of
> types. Subtype polymorphism, as in object-oriented languages, loses
> type identity. To write the equivalent of the Java Shape's isEqual
> method with parametric polymorphism in a constrained template, we'd
> effectively be saying:
>
>   template<typename T, typename U>
>   where Shape<T> && Shape<U>
>   bool equal_shapes2(T a, U b) {
>     return isEqual(a, b);
>   }
>
> The real types T and U vary independently, but both are Shapes. When
> this is done in a OO world, the type-checking is pushed to run time,
> inside the body of isEqual (whose interface says that *any* two shapes
> can be compared). In a GP world (and with C++ concepts), the isEqual
> call inside equal_shapes2 would fail at compile time: the Shape
> concept says that a T can be compared with itself, rather than saying
> that it can be compared against any Shape.
>
> If you want to say that any Shape can be compared against any other
> Shape (say, in a hasSameArea function), you would use more parametric
> polymorphism:
>
>   concept ShapeWithArea<typename T> : Shape<T> {
>     double area(T);
>
>     template<typename U> where Shape<U> bool hasSameArea(T, U);
>   }
>
>   Cheers,
>   Doug
>
> ---
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-...@ncar.ucar.edu    ]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ:http://www.comeaucomputing.com/csc/faq.html                     ]- Hide quoted text -
>
> - Show quoted text -

Do you mean that refinement syntax is not orignated from that of
inheritance and will not confuse every one?

> -  It again mixes object-oriented and generic programming ideas in a
>way that will lead to confusion. I guarantee that, after showing an
>example like the above to an audience, I will get two questions: (1)
>why can't I just use ':' to inherit from C? and (2) can I declare a
>variable of type C*? Neither question would arise without the
>assumption that concepts are just another take on object-oriented
>programming (they aren't), and we need to be very careful not to give
>the impression that they are.

enerything has a price .For innovation yuo have to be braver than
this. Is the fear that programers might misunderstand a reason for us
not to do anything?.
but there exists one reason for not using concept keyword in that
manor (if I am not mistaken) :concepts allow use of a type when
afeature is available and accesible and ban otherwise but what we need
here is that we want to remind ourselves not to forget to provide a
specific interface for a class currently declared but not defined.I
suggest the 'interface'  keyword  syntax similar to that of 'concept'
for  this porpuse that unlike JAVA will not necessarily mean a runtime
polymorphism.I would like to wrote:

interface CC<typename T>{
public:
 T(T&);
private:
 void go();
 virtual void gogo();
};

CC struct my_type{
/*definition of  following functons is a must now and copy-ctor must
not be banned(private or protected).
 private: void go();
private: virtual void gogo();
*/
};


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]