Boost logo

Boost :

From: William Kempf (sirwillard_at_[hidden])
Date: 2000-12-01 10:34:31

--- In boost_at_[hidden], Kevlin Henney <kevlin_at_c...> wrote:
> In message <906dmn+bo7q_at_e...>, William Kempf <sirwillard_at_my-
>> writes
> >> As an aside, if you take this from a function object perspective
> >then
> >> proper copying semantics are the ones that make immediate sense.
> >> question of reference counting for sharing semantics becomes
> >unasked.
> >
> >I'm not sure I follow this. Taken at face value here I'd have to
> >disagree with you because this is a very specific class of
> >objects, aka a polymorphic function object used to wrap generic
> >function objects for use in code that can't be rely on template
> >typing. As such I don't know if ref-counting semantics aren't
> >appropriate.
> Ah, but I _do_ know they aren't appropriate ;->

Well, that's an AWFULLY strong statement, considering that until now
you've barely tried to address this, especially since it's been the
core part of the discussions to date here.

> The design principles involved are cohesion, orthogonality and
> and we can come at this from three different perspectives:
> (1) A polymorphic function object that wraps generic function
> does not imply sharing. By its very description it is intended to be
> like a function object. These things don't share (or appear to
> their representation unless they are explicitly written to do so.
> is the function object authors responsibility, not the default
> abstraction's.

It also doesn't imply that sharing isn't used. Frankly, it doesn't
speak to this issue at all, and is left as a decision to be based on
other criteria. A very valid case can be made that this concept acts
more like a function pointer than a function object, so the copies
are shallow copies that reference the same entity. Nothing about the
concept at this high level indicates that either view point
is "right".
> (2) There is a misconception that we are wrapping a given instance
of a
> function or function object, which is not the case. We are
> a copy. Given that reference counting is used for one of two
reasons --
> optimisation or explicit sharing semantics -- visibly reference
> something that is a copy rather than the original seems a little
odd. It
> is neither fish nor fowl: neither proper sharing semantics nor
> copying semantics.

This point is valid when applied to the implementations given so
far. But there are two problems with the argument that I see: (1)
Nothing says that there's something fundemantally wrong with the
initial copy that would invalidate the idea of ref-counting after
that point, even though it may seem so at first. After all, the
initial "copy" is part of the construction of the callback object.
(2) The implementation can be changed to eliminate this initial

> (3) The problem we are solving is precisely the one that you
> so let us look at it from the function object perspective. Imagine
> what I want is:
> class X
> {
> public:
> template<typename unary_function>
> virtual void f(unary_function) = 0;
> ...
> };
> Clearly I can't have this, so the two forms of polymorphism --
> parametric and inclusion -- are in tension. The resolution is to
> detemplatise the pure virtual by allowing an adapter of some kind,
> unary_polyfunction (just to be neutral on names), that handles the
> template->inheritance adaptation for us, retaining the semantics of
> desired design as much as possible:
> class X
> {
> public:
> virtual void f(unary_polyfunction<A, B>) = 0;
> ...
> };
> This is exactly the kind of animal we are talking about. The idea of
> throwing in reference counting messes this up: It is a change in the
> original semantics outside the requirements of the design. This is
> polymorphism not about sharing. Sure, we can have sharing as a
> feature -- another proxy or an adapted version, eg
> shared_unary_polyfunction -- but we don't want to mess up the core
> concept. If sharing were part of it, the first thing we'd need is an
> unshare member function of some kind just so we could get back the
> proper semantics! This is the kind of retrofit, interface-level
hack we
> should be avoiding.

Now this I totally agree with, and has been the one argument made
from the begininning that most of us have accepted.
> In summary, including reference counting as part of the core
concept is
> undesirable:
> (i) It combines two separate responsibilities into the same class,
> disallowing their separate use. Because I obviously have not
repeated it
> enough, I will say it again: express independent ideas
independently ;-)

*sigh* You've not gotten any arguments here from anyone. I believe
the debate continues only because some people think that the higher
level concept is more important and see little need for the lower
level concept. Sometimes this IS a valid stance. Personally, I'm no
longer convinced of this and feel as you do. The problem is, you've
kept throwing thread safety into the equation, which drastically
changes things here, since cloning can't be made thread safe
explicitly by the library.
> (ii) It is inconsistent in that it is not like other uses of
> counting for explicit sharing. These reference count an original
> known to the user, whereas the proposed reference counting
> implementations count a copy generated by the implementation. So the
> semantics are halfway between the full copying model and a proper
> sharing implementation.

I really don't agree with this.
> (iii) Much of the discussion of reference counting hinged around the
> idea of optimisation. This proved to be a Red Herring as it was not
> demonstrably an optimisation and, without changing to visible
> semantics, cannot be implemented practically. True optimisations
> on reference counting require either COW (which does not work well
> this case) or immutability (which is too restrictive).

I also don't agree with this, but we both know it's because we come
from very different view points. COW is not appropriate here, and
was never suggested by anyone.

Bill Kempf

Boost list run by bdawes at, gregod at, cpdaniel at, john at